diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dd1f8ef28..8ff715b56f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ## Unreleased +* Add chart component ([PR #4301](https://github.com/alphagov/govuk_publishing_components/pull/4301)) * Add inverse option for organisation logo ([PR #4284](https://github.com/alphagov/govuk_publishing_components/pull/4284)) * New options for contents-list component ([PR #4305](https://github.com/alphagov/govuk_publishing_components/pull/4305)) diff --git a/Gemfile.lock b/Gemfile.lock index e25748bf33..738915a32d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,6 +2,7 @@ PATH remote: . specs: govuk_publishing_components (44.3.0) + chartkick govuk_app_config govuk_personalisation (>= 0.7.0) kramdown @@ -103,6 +104,7 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) + chartkick (5.1.0) coderay (1.1.3) concurrent-ruby (1.3.4) connection_pool (2.4.1) diff --git a/app/assets/javascripts/govuk_publishing_components/components/chart.js b/app/assets/javascripts/govuk_publishing_components/components/chart.js new file mode 100644 index 0000000000..3d6a6c49b1 --- /dev/null +++ b/app/assets/javascripts/govuk_publishing_components/components/chart.js @@ -0,0 +1 @@ +//= require chartkick diff --git a/app/assets/stylesheets/govuk_publishing_components/components/_chart.scss b/app/assets/stylesheets/govuk_publishing_components/components/_chart.scss new file mode 100644 index 0000000000..16d6c4aa73 --- /dev/null +++ b/app/assets/stylesheets/govuk_publishing_components/components/_chart.scss @@ -0,0 +1,44 @@ +@import "govuk_publishing_components/individual_component_support"; + +.gem-c-chart { + // slight hack to hide the table automatically added by the charts JS + // not needed as we already output the table manually in the component + svg + div:has(table) { + display: none; + } + + .google-visualization-tooltip { + background-color: govuk-colour("black"); + box-shadow: none; + border: 0; + + span { + color: govuk-colour("white"); + @include govuk-font($size: 16, $weight: bold); + } + } +} + +.gem-c-chart__table-wrapper { + overflow: auto; +} + +.gem-c-chart__table { + margin-top: govuk-spacing(3); + + .govuk-table { + margin: 0; + } + + .govuk-table .govuk-table__header { + text-align: center; + } + + .govuk-table .govuk-table__cell { + text-align: center; + } +} + +.gem-c-chart__accessibility-message { + @include govuk-visually-hidden; +} diff --git a/app/views/govuk_publishing_components/components/_chart.html.erb b/app/views/govuk_publishing_components/components/_chart.html.erb new file mode 100644 index 0000000000..a4d4aea814 --- /dev/null +++ b/app/views/govuk_publishing_components/components/_chart.html.erb @@ -0,0 +1,151 @@ +<% + add_gem_component_stylesheet("chart") + add_gem_component_stylesheet("table") + add_gem_component_stylesheet("details") + add_gem_component_stylesheet("heading") + + chart_heading ||= nil + chart_heading_level ||= 2 + table_direction ||= "horizontal" + h_axis_title ||= nil + v_axis_title ||= nil + rows ||= [] + keys ||= [] + chart_overview ||= nil + hide_legend ||= false + link ||= false + + chart_id = "chart-id-#{SecureRandom.hex(4)}" + table_id = "table-id-#{SecureRandom.hex(4)}" + + shared_helper = GovukPublishingComponents::Presenters::SharedHelper.new(local_assigns) + component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(local_assigns) + component_helper.add_class("gem-c-chart") + component_helper.add_class(shared_helper.get_margin_bottom) + + require "chartkick" + Chartkick.options[:html] = '
' + # config options are here: https://developers.google.com/chart/interactive/docs/gallery/linechart + font_16 = { color: '#000', fontName: 'GDS Transport', fontSize: '16', italic: false } + font_19 = { color: '#000', fontName: 'GDS Transport', fontSize: '19', italic: false } + legend = 'none' + legend = { position: 'top', textStyle: font_16 } unless hide_legend + + chart_library_options = { + chartArea: { width: '80%', height: '60%' }, + crosshair: { orientation: 'vertical', trigger: 'both', color: '#ccc' }, + curveType: 'none', + legend: legend, + pointSize: 10, + height: 400, + tooltip: { isHtml: true }, + hAxis: { + textStyle: font_16, + format: 'd MMM Y', # https://developers.google.com/chart/interactive/docs/reference#dateformatter + title: h_axis_title, + titleTextStyle: font_19, + }, + vAxis: { + format: '#,###,###', + textStyle: font_16, + title: v_axis_title, + titleTextStyle: font_19, + }, + } + + if rows.length > 0 && keys.length > 0 + chart_format_data = rows.map do |row| + { + name: row[:label], + linewidth: 10, + data: keys.zip(row[:values]) + } + end + end +%> +<% if rows.length > 0 && keys.length > 0 %> + <%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %> + <%= tag.div(**component_helper.all_attributes) do %> + <% if chart_heading %> + <%= render "govuk_publishing_components/components/heading", { + text: chart_heading, + heading_level: chart_heading_level, + margin_bottom: 2, + } %> + <% end %> + +
+
+ <%= t("components.chart.accessibility_html", table_id: table_id) %> + <%= content_tag :span, chart_overview, class: "gem-c-chart__overview" if chart_overview %> +
+ <%= line_chart(chart_format_data, library: chart_library_options) %> +
+ +
+ <%= render("govuk_publishing_components/components/details", + title: t("components.chart.table_dropdown") + ) do %> +
+ + <% if table_direction == "horizontal" %> + + + + <% keys.each do |key| %> + + <% end %> + + + + <% rows.each do |row| %> + + + <% row[:values].each do |value| %> + + <% end %> + + <% end %> + + <% else %> + + + + <% rows.each do |row| %> + + <% end %> + + + + <% keys.each_with_index do |key, index| %> + + + <% rows.each do |row| %> + + <% end %> + + <% end %> + + <% end %> +
+ <%= key %> +
<%= row[:label] %> + <%= number_with_delimiter value %> +
+ <%= row[:label] %> +
+ <%= key %> + + <%= number_with_delimiter row[:values][index] %> +
+
+ <% end %> +
+ + <% if link %> +

+ <%= link_to "Download chart data", link, class: "govuk-link" %> +

+ <% end %> + <% end %> +<% end %> diff --git a/app/views/govuk_publishing_components/components/docs/chart.yml b/app/views/govuk_publishing_components/components/docs/chart.yml new file mode 100644 index 0000000000..60d16bf081 --- /dev/null +++ b/app/views/govuk_publishing_components/components/docs/chart.yml @@ -0,0 +1,238 @@ +name: Chart (experimental) +description: The chart component presents a data chart and a tabular version of the same data +part_of_admin_layout: true +body: | + This component takes a set of data and presents it as a line graph and a table with one or more rows and lines. + The chart relies upon chartkick and renders using JavaScript, so the table is provided as a fallback for a lack of JavaScript, + an accessible view on the data for screenreaders, and a simple view of the raw data for all users. + + The `overview` option can be used to provide an explanation for screen reader users of what the graph shows. +accessibility_criteria: | + Charts must: + + - use line colours with a contrast ratio higher than 4.5:1 against the background colour to meet WCAG AA +shared_accessibility_criteria: + - link +uses_component_wrapper_helper: true +examples: + default: + data: + chart_heading: Page views chart + h_axis_title: Day + v_axis_title: Views + overview: This chart shows page views for January 2015. + hide_legend: true + keys: + - "2015-01-01" + - "2015-01-02" + - "2015-01-03" + - "2015-01-04" + - "2015-01-05" + - "2015-01-06" + - "2015-01-07" + - "2015-01-08" + - "2015-01-09" + - "2015-01-10" + rows: + - label: January 2015 + values: + - 500 + - 1190 + - 740 + - 820 + - 270 + - 450 + - 110 + - 210 + - 670 + - 430 + multiple rows of data: + description: Where more than one series is shown on a chart, do not hide the legend. + data: + chart_heading: Page views chart + h_axis_title: Day + v_axis_title: Views + keys: + - 1st + - 2nd + - 3rd + - 4th + - 5th + - 6th + - 7th + - 8th + - 9th + - 10th + rows: + - label: January 2015 + values: + - 5 + - 119 + - 74 + - 82 + - 27 + - 45 + - 11 + - 21 + - 67 + - 43 + - label: January 2016 + values: + - 5 + - 8 + - 37 + - 50 + - 43 + - 29 + - 67 + - 61 + - 14 + - 91 + - label: January 2017 + values: + - 31 + - 81 + - 12 + - 15 + - 52 + - 61 + - 143 + - 27 + - 18 + - 34 + vertical table: + description: Reorient the table to better suit the output of some data sets. + data: + chart_heading: Page views chart + table_direction: vertical + h_axis_title: Day + v_axis_title: Views + keys: + - 1st + - 2nd + - 3rd + - 4th + - 5th + - 6th + - 7th + rows: + - label: January 2015 + values: + - 5 + - 119 + - 74 + - 117 + - 33 + - 89 + - 79 + - label: January 2016 + values: + - 3 + - 8 + - 37 + - 82 + - 118 + - 85 + - 80 + with_a_different_heading_level: + description: Use a different heading level for the chart heading. It defaults to a H2. + data: + chart_heading: Page views chart + chart_heading_level: 4 + h_axis_title: Day + v_axis_title: Views + keys: + - 1st + - 2nd + - 3rd + - 4th + - 5th + - 6th + - 7th + rows: + - label: January 2015 + values: + - 5 + - 119 + - 74 + - 117 + - 33 + - 89 + - 79 + - label: January 2016 + values: + - 3 + - 8 + - 37 + - 82 + - 118 + - 85 + - 80 + with_a_download_link: + description: Add a download link to the original data. Doesn't do anything clever, just creates a link to the URL passed. + data: + chart_heading: Page views chart + h_axis_title: Day + v_axis_title: Views + link: 'https://www.gov.uk' + keys: + - 1st + - 2nd + - 3rd + - 4th + - 5th + - 6th + - 7th + rows: + - label: January 2015 + values: + - 5 + - 119 + - 74 + - 117 + - 33 + - 89 + - 79 + - label: January 2016 + values: + - 3 + - 8 + - 37 + - 82 + - 118 + - 85 + - 80 + with_margin_bottom: + description: The component accepts a number for margin bottom from `0` to `9` (`0px` to `60px`) using the [GOV.UK Frontend spacing scale](https://design-system.service.gov.uk/styles/spacing/#the-responsive-spacing-scale). It defaults to having a bottom margin of 15px. + data: + chart_heading: Page views chart + h_axis_title: Day + v_axis_title: Views + margin_bottom: 9 + keys: + - 1st + - 2nd + - 3rd + - 4th + - 5th + - 6th + - 7th + rows: + - label: January 2015 + values: + - 5 + - 119 + - 74 + - 117 + - 33 + - 89 + - 79 + - label: January 2016 + values: + - 3 + - 8 + - 37 + - 82 + - 118 + - 85 + - 80 diff --git a/config/locales/ar.yml b/config/locales/ar.yml index e78b8a8ef7..151a4d03e9 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -36,6 +36,9 @@ ar: type: characters: أحرف words: كلمات + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/az.yml b/config/locales/az.yml index b68f147256..9abf4c1491 100644 --- a/config/locales/az.yml +++ b/config/locales/az.yml @@ -32,6 +32,9 @@ az: type: characters: simvol words: söz + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/be.yml b/config/locales/be.yml index 2632b72b5b..7bf50fd004 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -34,6 +34,9 @@ be: type: characters: знакаў words: словаў + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 0f97f59696..6e579ab218 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -32,6 +32,9 @@ bg: type: characters: символа words: думи + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/bn.yml b/config/locales/bn.yml index 0a4afc08d8..34044764c2 100644 --- a/config/locales/bn.yml +++ b/config/locales/bn.yml @@ -32,6 +32,9 @@ bn: type: characters: ক্যারেক্টার words: শব্দসমষ্টি + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/cs.yml b/config/locales/cs.yml index ffa5b375d0..5097223856 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -33,6 +33,9 @@ cs: type: characters: znaky words: slova + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 27628c7920..75c1f28b99 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -36,6 +36,9 @@ cy: type: characters: nodau words: geiriau + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/da.yml b/config/locales/da.yml index 7037d7c142..7aef6f2e1d 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -32,6 +32,9 @@ da: type: characters: Tegn words: ord + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/de.yml b/config/locales/de.yml index 5b8f77a022..ce38fef147 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -32,6 +32,9 @@ de: type: characters: Zeichen words: Wörter + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/dr.yml b/config/locales/dr.yml index 8cfd81268a..a526390d3e 100644 --- a/config/locales/dr.yml +++ b/config/locales/dr.yml @@ -35,6 +35,9 @@ dr: type: characters: ارقام words: کلمات + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/el.yml b/config/locales/el.yml index aeb8c5a9b7..01ed8006c3 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -32,6 +32,9 @@ el: type: characters: χαρακτήρες words: λέξεις + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/en.yml b/config/locales/en.yml index 3664b609bc..5dc2525e3e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -32,6 +32,9 @@ en: type: characters: characters words: words + chart: + table_dropdown: Data table + accessibility_html: This chart is a visual representation of the data available in the table. chat_entry: heading: Try GOV.UK Chat description: Sign up to GOV.UK’s experimental new AI tool and find answers to your business questions diff --git a/config/locales/es-419.yml b/config/locales/es-419.yml index b3ddbdf756..6dc3c3504d 100644 --- a/config/locales/es-419.yml +++ b/config/locales/es-419.yml @@ -32,6 +32,9 @@ es-419: type: characters: caracteres words: palabras + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/es.yml b/config/locales/es.yml index 219611586a..822a4ba4c9 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -32,6 +32,9 @@ es: type: characters: caracteres words: palabras + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/et.yml b/config/locales/et.yml index ebbfbce631..6d6892b95b 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -32,6 +32,9 @@ et: type: characters: tähemärki words: sõnu + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/fa.yml b/config/locales/fa.yml index f762e5a215..d378696c6b 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -32,6 +32,9 @@ fa: type: characters: کاراکتر words: کلمه + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 92a075cc20..e6aaa174b6 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -32,6 +32,9 @@ fi: type: characters: merkkejä words: sanoja + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 4f28f02e24..6d2f1ad2e6 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -32,6 +32,9 @@ fr: type: characters: caractères words: mots + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/gd.yml b/config/locales/gd.yml index d7fc407d96..e99cf73c27 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -34,6 +34,9 @@ gd: type: characters: Figiúr words: Carachtar + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/gu.yml b/config/locales/gu.yml index 91c4ec5c3d..364af3ef80 100644 --- a/config/locales/gu.yml +++ b/config/locales/gu.yml @@ -32,6 +32,9 @@ gu: type: characters: અક્ષરો words: શબ્દો + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/he.yml b/config/locales/he.yml index 678b070648..b3b967066c 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -32,6 +32,9 @@ he: type: characters: תווים words: מילים + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/hi.yml b/config/locales/hi.yml index d04e221209..5acf57b612 100644 --- a/config/locales/hi.yml +++ b/config/locales/hi.yml @@ -32,6 +32,9 @@ hi: type: characters: अक्षर words: शब्द + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 7ac4ea22e7..f738141c39 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -33,6 +33,9 @@ hr: type: characters: znakova words: riječi + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/hu.yml b/config/locales/hu.yml index aa9b3ddd34..0e08d8e4a8 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -32,6 +32,9 @@ hu: type: characters: karakterek words: szavak + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/hy.yml b/config/locales/hy.yml index 480f12fe97..58cfe6da0f 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -34,6 +34,9 @@ hy: type: characters: նիշ words: բառ + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/id.yml b/config/locales/id.yml index e2ba950c01..d1d7bf98f5 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -31,6 +31,9 @@ id: type: characters: karakter words: kata + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/is.yml b/config/locales/is.yml index 05118eeb2f..264fde27da 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -32,6 +32,9 @@ is: type: characters: stafi words: orð + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/it.yml b/config/locales/it.yml index 60d48b3696..4bbeba42dc 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -32,6 +32,9 @@ it: type: characters: caratteri words: parole + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 61d9aff6b8..af53abed10 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -31,6 +31,9 @@ ja: type: characters: 文字 words: 単語 + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ka.yml b/config/locales/ka.yml index 9d9cb69f22..eb946974a8 100644 --- a/config/locales/ka.yml +++ b/config/locales/ka.yml @@ -32,6 +32,9 @@ ka: type: characters: სიმბოლოები words: სიტყვები + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/kk.yml b/config/locales/kk.yml index f40c1a8cbf..e1aec6f918 100644 --- a/config/locales/kk.yml +++ b/config/locales/kk.yml @@ -32,6 +32,9 @@ kk: type: characters: таңба words: сөз + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 31f1670f3c..d81e94b817 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -31,6 +31,9 @@ ko: type: characters: words: + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 70ef90edf9..3d668af04d 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -33,6 +33,9 @@ lt: type: characters: spaudos ženklų words: žodžių + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/lv.yml b/config/locales/lv.yml index d6976377c2..b508b2d154 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -32,6 +32,9 @@ lv: type: characters: rakstzīmes words: vārdi + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ms.yml b/config/locales/ms.yml index 741e6d4c33..00ea0f447a 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -31,6 +31,9 @@ ms: type: characters: aksara words: perkataan + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/mt.yml b/config/locales/mt.yml index e82a2cfac9..0c9cd26c50 100644 --- a/config/locales/mt.yml +++ b/config/locales/mt.yml @@ -34,6 +34,9 @@ mt: type: characters: karattri words: kliem + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 487d48dc72..9cd9df6a50 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -32,6 +32,9 @@ nl: type: characters: karakters words: woorden + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/no.yml b/config/locales/no.yml index 0dbfce79f4..1fbdbac955 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -32,6 +32,9 @@ type: characters: tegn words: ord + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/pa-pk.yml b/config/locales/pa-pk.yml index 929d942017..36581156df 100644 --- a/config/locales/pa-pk.yml +++ b/config/locales/pa-pk.yml @@ -32,6 +32,9 @@ pa-pk: type: characters: کردار words: الفاظ + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/pa.yml b/config/locales/pa.yml index 8ccd73e6ab..a509106a79 100644 --- a/config/locales/pa.yml +++ b/config/locales/pa.yml @@ -32,6 +32,9 @@ pa: type: characters: ਅੱਖਰ words: ਸ਼ਬਦ + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 3197e32163..1fcc1e2e0d 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -34,6 +34,9 @@ pl: type: characters: znaków words: słów + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ps.yml b/config/locales/ps.yml index 87dba21423..737de936bb 100644 --- a/config/locales/ps.yml +++ b/config/locales/ps.yml @@ -32,6 +32,9 @@ ps: type: characters: کرکټرونه words: ټکي + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 8956f6d193..43e158fa3d 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -32,6 +32,9 @@ pt: type: characters: carateres words: palavras + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ro.yml b/config/locales/ro.yml index a8ac9cda14..31ff8411e9 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -33,6 +33,9 @@ ro: type: characters: caractere words: cuvinte + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index ac7f5f5cfc..3b769f4df3 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -34,6 +34,9 @@ ru: type: characters: символов words: слов + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/si.yml b/config/locales/si.yml index d136720f07..a169674524 100644 --- a/config/locales/si.yml +++ b/config/locales/si.yml @@ -32,6 +32,9 @@ si: type: characters: අක්ෂර words: වචන + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/sk.yml b/config/locales/sk.yml index b3c16fa7e8..285e065c28 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -33,6 +33,9 @@ sk: type: characters: znakov words: slov + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 91ca360f7b..479301a7fe 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -36,6 +36,9 @@ sl: type: characters: znaki words: besede + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/so.yml b/config/locales/so.yml index 239751f74e..1faf725393 100644 --- a/config/locales/so.yml +++ b/config/locales/so.yml @@ -32,6 +32,9 @@ so: type: characters: dabeecadaha words: kalmadaha + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 5378f3188e..10dbfe5f0f 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -32,6 +32,9 @@ sq: type: characters: karaktere words: fjalë + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 8a0f9f43d8..ee0bdbd9ec 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -33,6 +33,9 @@ sr: type: characters: znakova words: reči + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 24532c0ac1..a7284b3fc3 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -32,6 +32,9 @@ sv: type: characters: tecken words: ord + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/sw.yml b/config/locales/sw.yml index ee97d0c545..24a53ed00f 100644 --- a/config/locales/sw.yml +++ b/config/locales/sw.yml @@ -32,6 +32,9 @@ sw: type: characters: herufi words: maneno + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ta.yml b/config/locales/ta.yml index c6bee550ed..dc2b68bf43 100644 --- a/config/locales/ta.yml +++ b/config/locales/ta.yml @@ -32,6 +32,9 @@ ta: type: characters: எழுத்துருக்கள் words: சொற்கள் + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/th.yml b/config/locales/th.yml index 05d739c8cf..af1ccf1301 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -31,6 +31,9 @@ th: type: characters: ตัวอักษร words: คำ + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/tk.yml b/config/locales/tk.yml index f787b4fea4..8dc6448f57 100644 --- a/config/locales/tk.yml +++ b/config/locales/tk.yml @@ -32,6 +32,9 @@ tk: type: characters: şekiller words: sözler + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index e4fb367b52..66586139f0 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -32,6 +32,9 @@ tr: type: characters: karakter words: kelime + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 968c0caaff..4eb89be1a6 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -34,6 +34,9 @@ uk: type: characters: символів words: слів + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/ur.yml b/config/locales/ur.yml index e185067f6a..9b9b805375 100644 --- a/config/locales/ur.yml +++ b/config/locales/ur.yml @@ -32,6 +32,9 @@ ur: type: characters: حروف words: الفاظ + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/uz.yml b/config/locales/uz.yml index fb0f3008b0..8175f59ca9 100644 --- a/config/locales/uz.yml +++ b/config/locales/uz.yml @@ -32,6 +32,9 @@ uz: type: characters: белгилар words: сўзлар + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 0c0bb11ebd..f0d0dcdcb8 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -31,6 +31,9 @@ vi: type: characters: ký tự words: từ + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/zh-hk.yml b/config/locales/zh-hk.yml index 21f9533c8b..ec9ca4aae9 100644 --- a/config/locales/zh-hk.yml +++ b/config/locales/zh-hk.yml @@ -31,6 +31,9 @@ zh-hk: type: characters: 字元 words: 字彙 + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/zh-tw.yml b/config/locales/zh-tw.yml index 18e3931ad8..d41dc1b2e2 100644 --- a/config/locales/zh-tw.yml +++ b/config/locales/zh-tw.yml @@ -31,6 +31,9 @@ zh-tw: type: characters: 字元 words: 字 + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/config/locales/zh.yml b/config/locales/zh.yml index f3e480e89d..b4f8d77154 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -31,6 +31,9 @@ zh: type: characters: 字符 words: 单词 + chart: + accessibility_html: + table_dropdown: chat_entry: description: heading: diff --git a/govuk_publishing_components.gemspec b/govuk_publishing_components.gemspec index 5ba588b936..946bc56d0c 100644 --- a/govuk_publishing_components.gemspec +++ b/govuk_publishing_components.gemspec @@ -16,6 +16,7 @@ Gem::Specification.new do |s| s.files = Dir["{node_modules/accessible-autocomplete,node_modules/govuk-frontend,node_modules/axe-core,node_modules/sortablejs,node_modules/govuk-single-consent,app,config,db,lib}/**/*", "LICENCE.md", "README.md"] + s.add_dependency "chartkick" s.add_dependency "govuk_app_config" s.add_dependency "govuk_personalisation", ">= 0.7.0" s.add_dependency "kramdown" diff --git a/package.json b/package.json index 2df588dca7..8ccb5b4870 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "dependencies": { "accessible-autocomplete": "^3.0.1", "axe-core": "^4.10.0", + "chartkick": "^5.0.1", "govuk-frontend": "5.7.0", "govuk-single-consent": "^3.0.9", "sortablejs": "^1.15.3" diff --git a/spec/components/chart_spec.rb b/spec/components/chart_spec.rb new file mode 100644 index 0000000000..48427ef55e --- /dev/null +++ b/spec/components/chart_spec.rb @@ -0,0 +1,107 @@ +require "rails_helper" + +describe "Chart", type: :view do + def component_name + "chart" + end + + let(:data) do + { + chart_label: "Page views chart", + table_label: "Page views table", + keys: (Date.new(2017, 12, 1)..Date.new(2017, 12, 12)).to_a, + rows: [ + { + label: "2017", + values: [5, nil, nil, 119, 74, 117, 50, 119, 61, 110, 12, 21, 121, 67], + }, + { + label: "2018", + values: [3, 8, 37, 435, 78, 4, 9, 61, 110, 12, 21, 121], + }, + ], + } + end + + it "does not render when no data is given" do + assert_empty render_component({}) + end + + it "does not render if keys are missing" do + data[:keys] = [] + assert_empty render_component(data) + end + + it "does not render if row data is missing" do + data[:rows] = [] + assert_empty render_component(data) + end + + it "renders when given valid data" do + render_component(data) + assert_select '.gem-c-chart.govuk-\!-margin-bottom-3', 1 + end + + it "renders the correct table data horizontally" do + data[:table_direction] = "horizontal" + render_component(data) + assert_select ".govuk-table__body .govuk-table__header:nth-child(1)", text: "2017" + assert_select ".govuk-table__cell--numeric", 26 + assert_select ".govuk-table__header", 14 + assert_select "td:first", text: "5" + assert_select "td:last", text: "121" + end + + it "renders the correct table data vertically" do + data[:table_direction] = "vertical" + render_component(data) + assert_select ".govuk-table__body .govuk-table__header:nth-child(1)", text: "2017-12-01" + assert_select ".govuk-table__cell--numeric", 24 + assert_select ".govuk-table__header", 14 + + assert_select "td:first", text: "5" + assert_select ".govuk-table__body tr:nth-of-type(4) td:first", text: "119" + assert_select "td:last", text: "121" + end + + it "calls the chart library" do + render_component(data) + assert_select "script", text: /new Chartkick.["LineChart"]/ + end + + it "displays a heading" do + data[:chart_heading] = "hello" + render_component(data) + + assert_select "h2.gem-c-heading", text: "hello" + end + + it "displays a heading with a custom heading level" do + data[:chart_heading] = "hello" + data[:chart_heading_level] = 4 + render_component(data) + + assert_select "h4.gem-c-heading", text: "hello" + end + + it "can include an overview" do + text = "This chart shows a gradual decline in the numbers of hedgehogs using social media since 2008." + data[:chart_overview] = text + render_component(data) + assert_select ".gem-c-chart__overview", text: + end + + it "can include a download link" do + data[:link] = "https://www.gov.uk" + render_component(data) + + assert_select '.govuk-link[href="https://www.gov.uk"]', text: "Download chart data" + end + + it "can have a different bottom margin" do + data[:margin_bottom] = 0 + render_component(data) + + assert_select '.gem-c-chart.govuk-\!-margin-bottom-0' + end +end diff --git a/spec/lib/govuk_publishing_components/app_helpers/asset_helper_spec.rb b/spec/lib/govuk_publishing_components/app_helpers/asset_helper_spec.rb index 3b5fd776bb..2f2440763a 100644 --- a/spec/lib/govuk_publishing_components/app_helpers/asset_helper_spec.rb +++ b/spec/lib/govuk_publishing_components/app_helpers/asset_helper_spec.rb @@ -19,7 +19,7 @@ def request end it "detect the total number of stylesheet paths" do - expect(get_component_css_paths.count).to eql(79) + expect(get_component_css_paths.count).to eql(80) end it "initialize empty asset helper" do diff --git a/yarn.lock b/yarn.lock index 008034ae94..e26ab82d93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -71,6 +71,11 @@ wrap-ansi "^8.1.0" wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" +"@kurkle/color@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f" + integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw== + "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" @@ -553,6 +558,27 @@ chalk@^4.0.0, chalk@^4.0.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +chart.js@4: + version "4.4.4" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.4.tgz#b682d2e7249f7a0cbb1b1d31c840266ae9db64b7" + integrity sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA== + dependencies: + "@kurkle/color" "^0.3.0" + +chartjs-adapter-date-fns@>=3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-3.0.0.tgz#c25f63c7f317c1f96f9a7c44bd45eeedb8a478e5" + integrity sha512-Rs3iEB3Q5pJ973J93OBTpnP7qoGwvq3nUnoMdtxO+9aoJof7UFcRbWcIDteXuYd1fgAvct/32T9qaLyLuZVwCg== + +chartkick@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/chartkick/-/chartkick-5.0.1.tgz#f557ff8560f974343dc65c7fc34ce1e8326d8ee7" + integrity sha512-4F3tWI3eBQgnjCYZIZ+fHOaJuNyxeyhDE2Tm+voOWB19hDjSJceys/spzN52DOn8bWepNESGXvPVTGU1jeFsbA== + optionalDependencies: + chart.js "4" + chartjs-adapter-date-fns ">=3" + date-fns ">=2" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -661,6 +687,11 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +date-fns@>=2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14" + integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg== + debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"