I have an svg
that is generated using pygal
library and I want to change the value of an array that is defined inside the script
tag of the svg
content. This is how I am able to read the content of the svg
svgContent = document.querySelector(".myChart").contentDocument
// under <defs>, the second child contains the script tag. Used eval to parse the js content
svgScriptContent = eval(svgContent.querySelector("defs").children[1].innerHTML)
Below is the content of the svg
< script xmlns = "http://www.w3.org/2000/svg"
type = "text/javascript" > window.pygal = window.pygal || {};
window.pygal.config = window.pygal.config || {};
window.pygal.config['f2a1b172-9f14-4f9a-aba9-eff7e05225a3'] = {
"dynamic_print_values": false,
"truncate_label": null,
"inner_radius": 0,
"print_values": false,
"xrange": [0, 100],
"box_mode": "extremes",
"title": "Correlate: income need (x) vs expenditure (y)",
"legend_at_bottom_columns": null,
"height": 560,
"legend_at_bottom": true,
"show_legend": false,
"show_dots": true,
"explicit_size": false,
"y_labels_major": [0, 60, 120],
"show_minor_x_labels": false,
"width": 900,
"force_uri_protocol": "https",
"half_pie": false,
"style": {
"major_label_font_family": "Roboto",
"title_font_family": "Roboto",
"stroke_opacity": ".8",
"legend_box_size": 19,
"legend_font_family": "Roboto",
"colors": ["#FF4A6E", "#58CABF", "#47A4D1", "#ca8658", "#FFA54D"],
"legend_font_size": 19,
"no_data_font_family": "Roboto",
"major_label_font_size": 19,
"value_background": "rgba(229, 229, 229, 1)",
"ci_colors": [],
"label_font_family": "Roboto",
"label_font_size": 19,
"tooltip_font_size": 25,
"value_font_size": 19,
"font_family": "Roboto",
"opacity": ".6",
"foreground": "rgba(0, 0, 0, .87)",
"plot_background": "#FFFFFF",
"x_labels_major_count": 3,
"value_label_font_size": 19,
"value_label_font_family": "Roboto",
"background": "#FFFFFF",
"no_data_font_size": 64,
"value_colors": [],
"guide_stroke_dasharray": "4,4",
"transition": "150ms",
"foreground_subtle": "rgba(0, 0, 0, .54)",
"value_font_family": "Roboto",
"tooltip_font_family": "Roboto",
"title_font_size": 25,
"y_labels_major_count": 3,
"stroke_opacity_hover": ".9",
"major_guide_stroke_dasharray": "6,6",
"opacity_hover": ".8",
"foreground_strong": "rgba(0, 0, 0, 1)"
},
"x_label_rotation": 0,
"fill": false,
"missing_value_fill_truncation": "x",
"zero": 0,
"margin_right": null,
"interpolation_parameters": {},
"x_labels_major": [0, 50, 100],
"rounded_bars": null,
"title_spacing": 7,
"show_y_labels": true,
"dots_size": 2.5,
"legend_spacing": 17,
"show_y_guides": true,
"show_minor_y_labels": false,
"x_labels": null,
"y_title": null,
"order_min": null,
"formatter": null,
"disable_xml_declaration": false,
"strict": false,
"css": ["file://style.css", "file://graph.css"],
"tooltip_fancy_mode": true,
"defs": [],
"show_only_major_dots": false,
"y_label_rotation": 0,
"show_x_labels": true,
"min_scale": 4,
"show_x_guides": true,
"spacing": 10,
"x_labels_major_count": null,
"pretty_print": false,
"tooltip_border_radius": 0,
"interpolate": null,
"js": ["//kozea.github.io/pygal.js/2.0.x/pygal-tooltips.min.js"],
"y_labels": null,
"stroke_style": {
"width": 2
},
"print_labels": false,
"interpolation_precision": 250,
"x_title": null,
"y_labels_major_every": null,
"logarithmic": false,
"legends": ["var1", "var2", "var3", "var4", "var5"],
"max_scale": 16,
"print_zeroes": true,
"no_data_text": "No data",
"truncate_legend": null,
"x_labels_major_every": null,
"secondary_range": null,
"legend_box_size": 12,
"no_prefix": false,
"stroke": false,
"stack_from_top": false,
"include_x_axis": false,
"range": [0, 120],
"classes": ["pygal-chart"],
"margin_top": null,
"margin_left": null,
"y_labels_major_count": null,
"margin_bottom": null,
"inverse_y_axis": false,
"margin": 20,
"allow_interruptions": false,
"print_values_position": "center"
} < /script>
As you can see (towards the end), there is an attribute called legend
which is an array containing certain values
"legends": ["var1", "var2", "var3", "var4", "var5"]
I can access the value of the existing key by doing something like this
tooltipLegends = svgScriptContent.legends
console.log(tooltipLegends)
Now I want to replace the array with another array of values and this is what I do
updatedTooltipLegends = ["var6", "var7", "var8", "var9", "var10"]
svgScriptContent.legends = updatedTooltipLegends
But the content of the script
tag doesn't get updated. What am I doing wrong?
Another idea is that the content can be read as text and regex
can be used to replace the array but not sure how do I do that and if that's a great idea.
The contents of the
script
tag are code. When thescript
tag is encountered, that code is executed and it creates an object (with nested objects and arrays) and assigns it towindow.pygal
.Your code reads the code of the
script
and runs it, which is almost certainly unnecessary and probably undesireable. The code has presumably already been run, and run in the correct context (it looks like your.myChart
element is anHTMLObjectElement
oriframe
or similar, given your use ofcontentDocument
). In contrats, youreval
runs it in your window, not the window it appears to be intended to run in.Instead, modify the object that the code created originally. The code's put it on the
pygal
property of the window in which it ran, so you should be able to do this:If you don't know what GUID will be used, and if there's always only one, you can do this: