govuk_publishing_components
govuk_publishing_components copied to clipboard
Chart component JS doesn't use our modules system
The chart component includes JavaScript but doesn't use our standard GOVUK JavaScript modules approach - there's no data-module
on the component and no custom written JS in our normal structure included with the component.
Instead, we include chartkick
, which enables us to do the following in the component template:
<%= line_chart(chart_format_data, library: chart_library_options) %>
This gets output as an inline script, something like the below. This relies upon the component having called a script from Google (https://www.gstatic.com/charts/loader.js) which then works with the below script to initialise the chart.
<script nonce="M5sfoTHnUXsThggOfFBK+Q==">
(function() {
if (document.documentElement.hasAttribute("data-turbolinks-preview")) return;
if (document.documentElement.hasAttribute("data-turbo-preview")) return;
var createChart = function() { new Chartkick["LineChart"]("chart-1", [{"name":"January 2015","linewidth":10,"data":[["2015-01-01",500],["2015-01-02",1190],["2015-01-03",740],["2015-01-04",820],["2015-01-05",270],["2015-01-06",450],["2015-01-07",110],["2015-01-08",210],["2015-01-09",670],["2015-01-10",430]]}], {"library":{"chartArea":{"width":"80%","height":"60%"},"crosshair":{"orientation":"vertical","trigger":"both","color":"#ccc"},"curveType":"none","enableInteractivity":true,"legend":"none","pointSize":10,"height":400,"tooltip":{"isHtml":true},"hAxis":{"textStyle":{"color":"#000","fontName":"GDS Transport","fontSize":"16","italic":false},"format":"d MMM Y","title":"Day","titleTextStyle":{"color":"#000","fontName":"GDS Transport","fontSize":"19","italic":false},"textPosition":null},"vAxis":{"format":"#,###,###","textStyle":{"color":"#000","fontName":"GDS Transport","fontSize":"16","italic":false},"title":"Views","titleTextStyle":{"color":"#000","fontName":"GDS Transport","fontSize":"19","italic":false},"textPosition":null}}}); };
if ("Chartkick" in window) {
createChart();
} else {
window.addEventListener("chartkick:load", createChart, true);
}
})();
</script>
This approach isn't ideal, because it makes it harder to use our normal approach for testing this component - normally we'd have a JS test that includes the markup and runs the data-module
code on it to test for expected results. Things we could potentially improve include:
- currently no test for the
height
option (this gets swallowed by the magic above to produce an inline CSS attribute that sets the height) - charts are currently not responsive (could have a listener to detect page resizes, and redraw the chart accordingly, thereby rendering the height option unnecessary)
I haven't thought this through completely, but if we wanted to change this we would probably:
- (drop the requirement for chartkick?)
- write our own module that worked in the normal
data-module
way, incorporating something like the script above - (include the Google charts code (from https://www.gstatic.com/charts/loader.js) either directly in our code or as a yarn dependency if possible?)