govuk_publishing_components icon indicating copy to clipboard operation
govuk_publishing_components copied to clipboard

Chart component JS doesn't use our modules system

Open andysellick opened this issue 4 months ago • 0 comments

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?)

andysellick avatar Oct 21 '24 11:10 andysellick