Skip to content

Commit

Permalink
Add minimal option to chart component
Browse files Browse the repository at this point in the history
  • Loading branch information
andysellick committed Oct 22, 2024
1 parent 8ee0658 commit 5ade6be
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 69 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
@import "govuk_publishing_components/individual_component_support";

.gem-c-chart {
position: relative;

// 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) {
Expand Down Expand Up @@ -39,6 +41,14 @@
}
}

.gem-c-chart__accessibility-message {
@include govuk-visually-hidden;
.gem-c-chart__minimal-link {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;

&:focus {
background: transparent; // overrides govuk-link background, which obscures the graph
}
}
146 changes: 84 additions & 62 deletions app/views/govuk_publishing_components/components/_chart.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
rows ||= []
keys ||= []
chart_overview ||= nil
hide_legend ||= false
minimal ||= false
minimal_link ||= nil
hide_legend ||= minimal
link ||= false

chart_id = "chart-id-#{SecureRandom.hex(4)}"
Expand All @@ -22,6 +24,7 @@
component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(local_assigns)
component_helper.add_class("gem-c-chart")
component_helper.add_class(shared_helper.get_margin_bottom)
component_helper.add_class("gem-c-chart--minimal") if minimal

require "chartkick"
Chartkick.options[:html] = '<div id="%{id}"><noscript><p class="govuk-body">Our charts are built using JavaScript but all the data is also available in the table below.</p></noscript></div>'
Expand All @@ -30,26 +33,37 @@
font_19 = { color: '#000', fontName: 'GDS Transport', fontSize: '19', italic: false }
legend = 'none'
legend = { position: 'top', textStyle: font_16 } unless hide_legend
pointSize = 10
pointSize = 0 if minimal
enableInteractivity = true
enableInteractivity = false if minimal
textPosition = nil
textPosition = 'none' if minimal
valid_minimal = true
valid_minimal = false if minimal && !minimal_link # minimal version must include a link

chart_library_options = {
chartArea: { width: '80%', height: '60%' },
crosshair: { orientation: 'vertical', trigger: 'both', color: '#ccc' },
curveType: 'none',
enableInteractivity: enableInteractivity,
legend: legend,
pointSize: 10,
pointSize: pointSize,
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,
textPosition: textPosition,
},
vAxis: {
format: '#,###,###',
textStyle: font_16,
title: v_axis_title,
titleTextStyle: font_19,
textPosition: textPosition,
},
}

Expand All @@ -63,10 +77,10 @@
end
end
%>
<% if rows.length > 0 && keys.length > 0 %>
<% if rows.length > 0 && keys.length > 0 && valid_minimal %>
<%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %>
<%= tag.div(**component_helper.all_attributes) do %>
<% if chart_heading %>
<% if chart_heading && !minimal %>
<%= render "govuk_publishing_components/components/heading", {
text: chart_heading,
heading_level: chart_heading_level,
Expand All @@ -75,77 +89,85 @@
<% end %>

<div class="gem-c-chart__chart" id="<%= chart_id %>">
<div class="gem-c-chart__accessibility-message">
<%= t("components.chart.accessibility_html", table_id: table_id) %>
<%= content_tag :span, chart_overview, class: "gem-c-chart__overview" if chart_overview %>
<div class="govuk-visually-hidden">
<%= content_tag :div, chart_overview, class: "gem-c-chart__a11y-note-1" if chart_overview %>
<%= content_tag :div, t("components.chart.accessibility_html", table_id: table_id), class: "gem-c-chart__a11y-note-2" unless minimal %>
</div>

<%= line_chart(chart_format_data, library: chart_library_options) %>
</div>

<div class="gem-c-chart__table" id="<%= table_id %>">
<%= render("govuk_publishing_components/components/details",
title: t("components.chart.table_dropdown")
) do %>
<div tabindex="0" class="gem-c-chart__table-wrapper">
<table class="govuk-table">
<% if table_direction == "horizontal" %>
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<td class="govuk-table__cell"></td>
<% keys.each do |key| %>
<th class="govuk-table__header" scope="col">
<%= key %>
</th>
<% end %>
</tr>
</thead>
<tbody class="govuk-table__body">
<% rows.each do |row| %>
<% unless minimal %>
<div class="gem-c-chart__table" id="<%= table_id %>">
<%= render("govuk_publishing_components/components/details",
title: t("components.chart.table_dropdown")
) do %>
<div tabindex="0" class="gem-c-chart__table-wrapper">
<table class="govuk-table">
<% if table_direction == "horizontal" %>
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<th class="govuk-table__header" scope="row"><%= row[:label] %></th>
<% row[:values].each do |value| %>
<td class="govuk-table__cell govuk-table__cell--numeric">
<%= number_with_delimiter value %>
</td>
<td class="govuk-table__cell"></td>
<% keys.each do |key| %>
<th class="govuk-table__header" scope="col">
<%= key %>
</th>
<% end %>
</tr>
<% end %>
</tbody>
<% else %>
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<td class="govuk-table__cell"></td>
</thead>
<tbody class="govuk-table__body">
<% rows.each do |row| %>
<th class="govuk-table__header govuk-table__header--stacked" scope="row">
<%= row[:label] %>
</th>
<tr class="govuk-table__row">
<th class="govuk-table__header" scope="row"><%= row[:label] %></th>
<% row[:values].each do |value| %>
<td class="govuk-table__cell govuk-table__cell--numeric">
<%= number_with_delimiter value %>
</td>
<% end %>
</tr>
<% end %>
</tr>
</thead>
<tbody class="govuk-table__body">
<% keys.each_with_index do |key, index| %>
<tr>
<th class="govuk-table__header" scope="row">
<%= key %>
</th>
</tbody>
<% else %>
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<td class="govuk-table__cell"></td>
<% rows.each do |row| %>
<td class="govuk-table__cell govuk-table__cell--numeric">
<%= number_with_delimiter row[:values][index] %>
</td>
<th class="govuk-table__header govuk-table__header--stacked" scope="row">
<%= row[:label] %>
</th>
<% end %>
</tr>
<% end %>
</tbody>
<% end %>
</table>
</div>
<% end %>
</div>
</thead>
<tbody class="govuk-table__body">
<% keys.each_with_index do |key, index| %>
<tr>
<th class="govuk-table__header" scope="row">
<%= key %>
</th>
<% rows.each do |row| %>
<td class="govuk-table__cell govuk-table__cell--numeric">
<%= number_with_delimiter row[:values][index] %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
<% end %>
</table>
</div>
<% end %>
</div>

<% if link %>
<p class="govuk-body">
<%= link_to "Download chart data", link, class: "govuk-link" %>
</p>
<% if link %>
<p class="govuk-body">
<%= link_to "Download chart data", link, class: "govuk-link" %>
</p>
<% end %>
<% end %>
<% if minimal %>
<%= link_to(minimal_link, class: "govuk-link gem-c-chart__minimal-link") do %>
<span class="govuk-visually-hidden"><%= chart_heading %></span>
<% end %>
<% end %>
<% end %>
<% end %>
54 changes: 52 additions & 2 deletions app/views/govuk_publishing_components/components/docs/chart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ body: |
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.
The `chart_overview` option can be used to provide an explanation for screen reader users of what the graph shows.
accessibility_criteria: |
Charts must:
Expand All @@ -20,7 +20,7 @@ examples:
chart_heading: Page views chart
h_axis_title: Day
v_axis_title: Views
overview: This chart shows page views for January 2015.
chart_overview: This chart shows page views for January 2015.
hide_legend: true
keys:
- "2015-01-01"
Expand Down Expand Up @@ -52,6 +52,7 @@ examples:
chart_heading: Page views chart
h_axis_title: Day
v_axis_title: Views
chart_overview: This chart shows page views for January in different years.
keys:
- 1st
- 2nd
Expand Down Expand Up @@ -107,6 +108,7 @@ examples:
table_direction: vertical
h_axis_title: Day
v_axis_title: Views
chart_overview: This chart shows page views for January in different years.
keys:
- 1st
- 2nd
Expand Down Expand Up @@ -141,6 +143,7 @@ examples:
chart_heading_level: 4
h_axis_title: Day
v_axis_title: Views
chart_overview: This chart shows page views for January in different years.
keys:
- 1st
- 2nd
Expand Down Expand Up @@ -175,6 +178,7 @@ examples:
h_axis_title: Day
v_axis_title: Views
link: 'https://www.gov.uk'
chart_overview: This chart shows page views for January in different years.
keys:
- 1st
- 2nd
Expand Down Expand Up @@ -209,6 +213,52 @@ examples:
h_axis_title: Day
v_axis_title: Views
margin_bottom: 9
chart_overview: This chart shows page views for January in different years.
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
minimal_version:
description: |
The minimal version presents a simplified version of the chart and should only be used where the user is then directed to a more detailed view of the data. Specifically, minimal mode:
- turns the chart into a link that should point to a page with a full version of the chart with all data
- hides the chart heading, but uses the text as the text for the link
- removes the legend and X and Y axis values
- removes the data table and link to the data (if supplied) beneath the chart
- removes the part of the visually hidden accessibility message that links to the table
- removes the ability to interact with the chart (no hover popups or clicks)
- sets the size of the points on the chart to zero
data:
chart_heading: Page views
h_axis_title: Day
v_axis_title: Views
minimal: true
minimal_link: "https://www.gov.uk"
chart_overview: This is a graph of views per day
keys:
- 1st
- 2nd
Expand Down
26 changes: 23 additions & 3 deletions spec/components/chart_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ def component_name
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
overview = "This chart shows a gradual decline in the numbers of hedgehogs using social media since 2008."
data[:chart_overview] = overview
render_component(data)
assert_select ".gem-c-chart__overview", text:
assert_select ".gem-c-chart__a11y-note-1", text: overview
assert_select ".gem-c-chart__a11y-note-2", text: "This chart is a visual representation of the data available in the table."
end

it "can include a download link" do
Expand All @@ -104,4 +105,23 @@ def component_name

assert_select '.gem-c-chart.govuk-\!-margin-bottom-0'
end

it "renders a minimal version" do
data[:minimal] = true
data[:link] = "https://should.not.be.shown"
data[:minimal_link] = "https://www.gov.uk"
data[:chart_overview] = "This is a chart showing a rise in sea levels in the last ten years"
render_component(data)

assert_select ".gem-c-chart.gem-c-chart--minimal"
assert_select '.gem-c-chart .govuk-link[href="https://should.not.be.shown"]', false
assert_select '.gem-c-chart .gem-c-chart__minimal-link[href="https://www.gov.uk"]'
assert_select ".gem-c-chart__a11y-note-1", text: "This is a chart showing a rise in sea levels in the last ten years"
assert_select ".gem-c-chart__a11y-note-2", false
end

it "does not render a minimal version if a link is not supplied" do
data[:minimal] = true
assert_empty render_component(data)
end
end

0 comments on commit 5ade6be

Please sign in to comment.