Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new chart component options #4318

Merged
merged 6 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

## Unreleased

* Add new chart component options ([PR #4318](https://github.com/alphagov/govuk_publishing_components/pull/4318))
* Add shared helper and component wrapper helper to govspeak component ([PR #4325](https://github.com/alphagov/govuk_publishing_components/pull/4325))

## 44.4.2
Expand Down
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,27 @@
}
}

.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

&::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-top: solid 1px $govuk-focus-colour;
border-left: solid 3px $govuk-focus-colour;
border-right: solid 3px $govuk-focus-colour;
box-sizing: border-box;
}
}
}
161 changes: 95 additions & 66 deletions app/views/govuk_publishing_components/components/_chart.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,22 @@
rows ||= []
keys ||= []
chart_overview ||= nil
hide_legend ||= false
minimal ||= false
minimal_link ||= nil
hide_legend ||= minimal
link ||= false
height ||= 400

chart_id = "chart-id-#{SecureRandom.hex(4)}"
table_id = "table-id-#{SecureRandom.hex(4)}"
@external_script ||= OpenStruct.new(loaded: 0)
@external_script[:loaded] += 1

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)
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 +36,38 @@
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
if minimal && !minimal_link
raise ArgumentError, "Minimal version must include a link"
end

chart_library_options = {
chartArea: { width: '80%', height: '60%' },
crosshair: { orientation: 'vertical', trigger: 'both', color: '#ccc' },
curveType: 'none',
enableInteractivity: enableInteractivity,
legend: legend,
pointSize: 10,
height: 400,
pointSize: pointSize,
height: height,
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 @@ -64,88 +82,99 @@
end
%>
<% if rows.length > 0 && keys.length > 0 %>
<%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %>
<%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" if @external_script[:loaded] == 1 %>
<%= 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,
margin_bottom: 2,
} %>
<% 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>
<% aria_attributes = { hidden: true } if minimal %>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we have aria-hidden i don't think it can be keyboard focusable as well, as the component guide is flagging this as an issue. Happy for you to pick between either having focus or having aria-hidden.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argh, good spot, thanks. Think I've fixed this now - since the chart is just a link, I've included some logic to simply not render the visually hidden text (it's the thing that contained a link).

<%= content_tag :div, id: chart_id, class: "gem-c-chart__chart", aria: aria_attributes do %>
<% unless minimal %>
<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" %>
</div>
<% end %>

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

<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 %>
Loading
Loading