Skip to content

Commit

Permalink
Merge pull request #4301 from alphagov/add-chart-component
Browse files Browse the repository at this point in the history
Add chart component
  • Loading branch information
andysellick authored Oct 17, 2024
2 parents 33e31e9 + 5645d4a commit 76702a0
Show file tree
Hide file tree
Showing 75 changed files with 770 additions and 1 deletion.
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 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))

Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ PATH
remote: .
specs:
govuk_publishing_components (44.3.0)
chartkick
govuk_app_config
govuk_personalisation (>= 0.7.0)
kramdown
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//= require chartkick
Original file line number Diff line number Diff line change
@@ -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;
}
151 changes: 151 additions & 0 deletions app/views/govuk_publishing_components/components/_chart.html.erb
Original file line number Diff line number Diff line change
@@ -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] = '<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>'
# 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 %>

<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>
<%= 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| %>
<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 %>
</tbody>
<% else %>
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<td class="govuk-table__cell"></td>
<% rows.each do |row| %>
<th class="govuk-table__header govuk-table__header--stacked" scope="row">
<%= row[:label] %>
</th>
<% 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>
<% 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>
<% end %>
<% end %>
<% end %>
Loading

0 comments on commit 76702a0

Please sign in to comment.