@ons/design-system 72.3.0 → 72.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/components/button/_button.scss +171 -3
  2. package/components/button/_macro.njk +4 -0
  3. package/components/card/_card.scss +5 -0
  4. package/components/card/_macro.njk +10 -2
  5. package/components/card/_macro.spec.js +58 -0
  6. package/components/card/example-card-set-with-headline-figures.njk +62 -0
  7. package/components/chart/_chart.scss +29 -0
  8. package/components/chart/_macro.njk +101 -0
  9. package/components/chart/_macro.spec.js +437 -0
  10. package/components/chart/bar-chart.js +160 -0
  11. package/components/chart/chart-constants.js +21 -0
  12. package/components/chart/chart.dom.js +8 -0
  13. package/components/chart/chart.js +157 -0
  14. package/components/chart/column-chart.js +48 -0
  15. package/components/chart/common-chart-options.js +200 -0
  16. package/components/chart/example-bar-chart.njk +54 -0
  17. package/components/chart/example-clustered-bar-chart.njk +60 -0
  18. package/components/chart/example-clustered-column-chart.njk +72 -0
  19. package/components/chart/example-column-chart.njk +52 -0
  20. package/components/chart/example-line-chart.njk +219 -0
  21. package/components/chart/example-stacked-bar-chart.njk +60 -0
  22. package/components/chart/example-stacked-column-chart.njk +65 -0
  23. package/components/chart/line-chart.js +47 -0
  24. package/components/chart/specific-chart-options.js +22 -0
  25. package/components/description-list/_description-list.scss +2 -0
  26. package/components/footer/_footer.scss +12 -0
  27. package/components/footer/_macro.njk +38 -17
  28. package/components/header/_header.scss +18 -2
  29. package/components/header/_macro.njk +81 -8
  30. package/components/header/_macro.spec.js +97 -0
  31. package/components/header/example-header-with-search-button.njk +190 -0
  32. package/components/header/header.spec.js +128 -0
  33. package/components/hero/_hero.scss +13 -10
  34. package/components/hero/_macro.njk +49 -18
  35. package/components/hero/_macro.spec.js +21 -2
  36. package/components/hero/example-hero-grey.njk +10 -8
  37. package/components/icon/_macro.njk +41 -8
  38. package/components/input/_input.scss +15 -0
  39. package/components/input/_macro.njk +3 -3
  40. package/components/navigation/navigation.dom.js +17 -0
  41. package/components/navigation/navigation.js +72 -2
  42. package/css/main.css +1 -1
  43. package/js/main.js +2 -0
  44. package/package.json +4 -1
  45. package/scripts/main.es5.js +1 -1
  46. package/scripts/main.js +1 -1
  47. package/scss/main.scss +1 -0
  48. package/scss/utilities/_grid.scss +13 -4
@@ -0,0 +1,157 @@
1
+ import CommonChartOptions from './common-chart-options';
2
+ import SpecificChartOptions from './specific-chart-options';
3
+ import LineChart from './line-chart';
4
+ import BarChart from './bar-chart';
5
+ import ColumnChart from './column-chart';
6
+ import Highcharts from 'highcharts';
7
+ import 'highcharts/modules/accessibility';
8
+
9
+ class HighchartsBaseChart {
10
+ static selector() {
11
+ return '[data-highcharts-base-chart]';
12
+ }
13
+
14
+ constructor(node) {
15
+ this.node = node;
16
+ this.chartType = this.node.dataset.highchartsType;
17
+ this.theme = this.node.dataset.highchartsTheme;
18
+ const chartNode = this.node.querySelector('[data-highcharts-chart]');
19
+
20
+ this.id = this.node.dataset.highchartsId;
21
+ this.useStackedLayout = this.node.hasAttribute('data-highcharts-use-stacked-layout');
22
+ this.config = JSON.parse(this.node.querySelector(`[data-highcharts-config--${this.id}]`).textContent);
23
+
24
+ this.commonChartOptions = new CommonChartOptions();
25
+ this.specificChartOptions = new SpecificChartOptions(this.theme, this.chartType, this.config);
26
+ this.lineChart = new LineChart();
27
+ this.barChart = new BarChart();
28
+ this.columnChart = new ColumnChart();
29
+ if (window.isCommonChartOptionsDefined === undefined) {
30
+ this.setCommonChartOptions();
31
+ window.isCommonChartOptionsDefined = true;
32
+ }
33
+ this.hideDataLabels = this.checkHideDataLabels();
34
+ this.setSpecificChartOptions();
35
+ this.setLoadEvent();
36
+ this.setWindowResizeEvent();
37
+ this.chart = Highcharts.chart(chartNode, this.config);
38
+ }
39
+
40
+ // Set up the global Highcharts options which are used for all charts
41
+ setCommonChartOptions = () => {
42
+ const chartOptions = this.commonChartOptions.getOptions();
43
+ Highcharts.setOptions(chartOptions);
44
+ };
45
+
46
+ // Utility function to merge two configs together
47
+ mergeConfigs = (baseConfig, newConfig) => {
48
+ // If newConfig is null/undefined, return baseConfig
49
+ if (!newConfig) return baseConfig;
50
+
51
+ // Create a new object to store the merged result
52
+ const merged = { ...baseConfig };
53
+
54
+ // Iterate through all keys in newConfig
55
+ Object.keys(newConfig).forEach((key) => {
56
+ // Get values from both configs for this key
57
+ const baseValue = merged[key];
58
+ const newValue = newConfig[key];
59
+
60
+ // If both values are objects (and not null), recursively merge them
61
+ if (
62
+ baseValue &&
63
+ newValue &&
64
+ typeof baseValue === 'object' &&
65
+ typeof newValue === 'object' &&
66
+ !Array.isArray(baseValue) &&
67
+ !Array.isArray(newValue)
68
+ ) {
69
+ merged[key] = this.mergeConfigs(baseValue, newValue);
70
+ } else {
71
+ // For non-objects and arrays use the new value
72
+ // If the new value is null/undefined, use the base value
73
+ merged[key] = newValue ?? baseValue;
74
+ }
75
+ });
76
+
77
+ return merged;
78
+ };
79
+
80
+ // Set up options for specific charts and chart types
81
+ setSpecificChartOptions = () => {
82
+ const specificChartOptions = this.specificChartOptions.getOptions();
83
+ const lineChartOptions = this.lineChart.getLineChartOptions();
84
+ const barChartOptions = this.barChart.getBarChartOptions(this.useStackedLayout);
85
+ const columnChartOptions = this.columnChart.getColumnChartOptions(this.useStackedLayout);
86
+ // Merge specificChartOptions with the existing config
87
+ this.config = this.mergeConfigs(this.config, specificChartOptions);
88
+
89
+ if (this.chartType === 'line') {
90
+ // Merge the line chart options with the existing config
91
+ this.config = this.mergeConfigs(this.config, lineChartOptions);
92
+ }
93
+
94
+ if (this.chartType === 'bar') {
95
+ // Merge the bar chart options with the existing config
96
+ this.config = this.mergeConfigs(this.config, barChartOptions);
97
+ }
98
+ if (this.chartType === 'column') {
99
+ // Merge the column chart options with the existing config
100
+ this.config = this.mergeConfigs(this.config, columnChartOptions);
101
+ }
102
+ };
103
+
104
+ // Check if the data labels should be hidden
105
+ // They should be hidden for clustered bar charts with more than 2 series, and also for stacked bar charts
106
+ checkHideDataLabels = () => {
107
+ return (this.chartType === 'bar' && this.config.series.length > 2) || this.useStackedLayout === true;
108
+ };
109
+
110
+ // Create the load event for various chart types
111
+ setLoadEvent = () => {
112
+ if (!this.config.chart.events) {
113
+ this.config.chart.events = {};
114
+ }
115
+ this.config.chart.events.load = (event) => {
116
+ const currentChart = event.target;
117
+ // Disable the legend for single series charts
118
+ this.commonChartOptions.disableLegendForSingleSeries(currentChart);
119
+ if (this.chartType === 'line') {
120
+ this.lineChart.updateLastPointMarker(currentChart);
121
+ this.commonChartOptions.hideDataLabels(currentChart);
122
+ }
123
+ if (this.chartType === 'bar') {
124
+ this.barChart.updateBarChartHeight(this.config, currentChart, this.useStackedLayout);
125
+ if (!this.hideDataLabels) {
126
+ this.barChart.postLoadDataLabels(currentChart);
127
+ } else {
128
+ this.commonChartOptions.hideDataLabels(currentChart);
129
+ }
130
+ }
131
+ if (this.chartType === 'column') {
132
+ this.columnChart.updatePointPadding(this.config, currentChart, this.useStackedLayout);
133
+ this.commonChartOptions.hideDataLabels(currentChart);
134
+ }
135
+ currentChart.redraw(false);
136
+ };
137
+ };
138
+
139
+ // Set resize events - throttled to 100ms
140
+ setWindowResizeEvent = () => {
141
+ if (this.chartType === 'column' || this.chartType === 'bar') {
142
+ window.addEventListener('resize', () => {
143
+ clearTimeout(this.resizeTimeout);
144
+ this.resizeTimeout = setTimeout(() => {
145
+ // Get the current rendered chart instance
146
+ const currentChart = Highcharts.charts.find((chart) => chart && chart.container === this.chart.container);
147
+ // Update the data labels when the window is resized
148
+ if (this.chartType === 'bar' && !this.hideDataLabels) {
149
+ this.barChart.postLoadDataLabels(currentChart);
150
+ }
151
+ }, 100);
152
+ });
153
+ }
154
+ };
155
+ }
156
+
157
+ export default HighchartsBaseChart;
@@ -0,0 +1,48 @@
1
+ class ColumnChart {
2
+ getColumnChartOptions = (useStackedLayout) => {
3
+ return {
4
+ plotOptions: {
5
+ column: {
6
+ pointPadding: 0,
7
+ groupPadding: 0,
8
+ borderRadius: 0,
9
+ borderWidth: 0,
10
+ },
11
+ series: {
12
+ stacking: useStackedLayout ? 'normal' : null,
13
+ },
14
+ },
15
+ };
16
+ };
17
+
18
+ // Set the point padding between each bar to be 3% (an overall gap of 6%)
19
+ // For charts with fewer than 5 categories, we use a wider point padding of 4% (8% gap between bars)
20
+ // For cluster charts we use 0 for the point padding and a group padding of 4% (8% gap between bars)
21
+ updatePointPadding = (config, currentChart, stackedLayout) => {
22
+ const numberOfCategories = config.xAxis.categories.length;
23
+ const numberOfSeries = currentChart.series.length; // Get number of bar series
24
+ let pointPadding = 0;
25
+ let groupPadding = 0;
26
+ // non-clustered charts or stacked charts
27
+ if (numberOfSeries === 1 || stackedLayout === true) {
28
+ if (numberOfCategories > 5) {
29
+ pointPadding = 0.03;
30
+ } else {
31
+ pointPadding = 0.04;
32
+ }
33
+ } else {
34
+ // clustered charts
35
+ groupPadding = 0.04;
36
+ }
37
+
38
+ // update the point width and padding
39
+ currentChart.series.forEach((series) => {
40
+ series.update({
41
+ pointPadding: pointPadding,
42
+ groupPadding: groupPadding,
43
+ });
44
+ });
45
+ };
46
+ }
47
+
48
+ export default ColumnChart;
@@ -0,0 +1,200 @@
1
+ import ChartConstants from './chart-constants';
2
+
3
+ // Options that are common to all chart types - these are set once in the Highcharts.setOptions() method
4
+ class CommonChartOptions {
5
+ constructor() {
6
+ this.constants = ChartConstants.constants();
7
+
8
+ this.options = {
9
+ chart: {
10
+ backgroundColor: 'transparent',
11
+ style: {
12
+ fontFamily: '"OpenSans", "Helvetica Neue", arial, sans-serif',
13
+ color: '#222222',
14
+ },
15
+ },
16
+ legend: {
17
+ align: 'left',
18
+ verticalAlign: 'top',
19
+ layout: 'horizontal',
20
+ // Symbol width and height in the legend. May be overridden for individual chart types
21
+ symbolWidth: 12,
22
+ symbolHeight: 12,
23
+ margin: 50,
24
+ itemHoverStyle: {
25
+ color: this.constants.labelColor, // Prevents the text from changing color on hover
26
+ },
27
+ itemStyle: {
28
+ cursor: 'default', // ensures that it does not change to a hand (pointer) on hover.
29
+ color: this.constants.labelColor,
30
+ fontSize: this.constants.desktopFontSize,
31
+ fontWeight: 'normal',
32
+ },
33
+ // Disable click event on legend
34
+ // There is currently an issue because the legend items are still buttons
35
+ // and therefore the screen reader still announces that they can be clicked
36
+ events: {
37
+ itemClick: () => {
38
+ return false;
39
+ },
40
+ },
41
+ accessibility: {
42
+ keyboardNavigation: {
43
+ enabled: false, // Prevents focus on legend items while keeping screen reader support
44
+ },
45
+ },
46
+ },
47
+ // Remove the chart title as rendered by Highcharts, as this is rendered in the surrounding component
48
+ title: {
49
+ text: '',
50
+ },
51
+ credits: {
52
+ // Remove Highcharts watermark
53
+ enabled: false,
54
+ },
55
+ accessibility: {
56
+ enabled: true,
57
+ },
58
+ yAxis: {
59
+ labels: {
60
+ style: {
61
+ color: this.constants.axisLabelColor,
62
+ fontSize: this.constants.desktopFontSize,
63
+ },
64
+ },
65
+ title: {
66
+ text: '', // Remove the default title rendered by Highcharts if not provided
67
+ align: 'high',
68
+ textAlign: 'middle',
69
+ reserveSpace: false,
70
+ useHTML: true,
71
+ offset: 15,
72
+ rotation: 0,
73
+ y: -25,
74
+ style: {
75
+ color: this.constants.axisLabelColor,
76
+ fontSize: this.constants.desktopFontSize,
77
+ },
78
+ },
79
+ lineColor: this.constants.gridLineColor,
80
+ gridLineColor: this.constants.gridLineColor,
81
+ // Add zero line
82
+ plotLines: [
83
+ {
84
+ color: this.constants.zeroLineColor,
85
+ width: 1,
86
+ value: 0,
87
+ zIndex: 2,
88
+ },
89
+ ],
90
+ // Add tick marks
91
+ tickWidth: 1,
92
+ tickLength: 6,
93
+ tickColor: this.constants.gridLineColor,
94
+ },
95
+ xAxis: {
96
+ labels: {
97
+ style: {
98
+ color: this.constants.axisLabelColor,
99
+ fontSize: this.constants.desktopFontSize,
100
+ },
101
+ },
102
+ title: {
103
+ align: 'high',
104
+ style: {
105
+ color: this.constants.axisLabelColor,
106
+ fontSize: this.constants.desktopFontSize,
107
+ },
108
+ },
109
+ lineColor: this.constants.gridLineColor,
110
+ gridLineColor: this.constants.gridLineColor,
111
+ // Add tick marks
112
+ tickWidth: 1,
113
+ tickLength: 6,
114
+ tickColor: this.constants.gridLineColor,
115
+ },
116
+ plotOptions: {
117
+ series: {
118
+ // disables the tooltip on hover
119
+ enableMouseTracking: false,
120
+ animation: false,
121
+
122
+ // disables the legend item hover
123
+ states: {
124
+ inactive: {
125
+ opacity: 1, // Prevent dimming of other series
126
+ enabled: false,
127
+ },
128
+ hover: {
129
+ enabled: false, // Disable the hover effect
130
+ },
131
+ },
132
+ },
133
+ },
134
+ // Adjust font size for smaller width of chart
135
+ // Note this is not the same as the viewport width
136
+ responsive: {
137
+ rules: [
138
+ {
139
+ condition: {
140
+ maxWidth: 400,
141
+ },
142
+ chartOptions: {
143
+ legend: {
144
+ itemStyle: {
145
+ fontSize: this.constants.mobileFontSize,
146
+ },
147
+ },
148
+ xAxis: {
149
+ labels: {
150
+ style: {
151
+ fontSize: this.constants.mobileFontSize,
152
+ },
153
+ },
154
+ title: {
155
+ style: {
156
+ fontSize: this.constants.mobileFontSize,
157
+ },
158
+ },
159
+ },
160
+ yAxis: {
161
+ labels: {
162
+ style: {
163
+ fontSize: this.constants.mobileFontSize,
164
+ },
165
+ },
166
+ title: {
167
+ style: {
168
+ fontSize: this.constants.mobileFontSize,
169
+ },
170
+ },
171
+ },
172
+ },
173
+ },
174
+ ],
175
+ },
176
+ };
177
+ }
178
+
179
+ getOptions = () => this.options;
180
+
181
+ hideDataLabels = (currentChart) => {
182
+ currentChart.series.forEach((series) => {
183
+ series.update({
184
+ dataLabels: {
185
+ enabled: false,
186
+ },
187
+ });
188
+ });
189
+ };
190
+
191
+ disableLegendForSingleSeries = (currentChart) => {
192
+ if (currentChart.series.length === 1) {
193
+ currentChart.legend.update({
194
+ enabled: false,
195
+ });
196
+ }
197
+ };
198
+ }
199
+
200
+ export default CommonChartOptions;
@@ -0,0 +1,54 @@
1
+ {% from "components/chart/_macro.njk" import onsChart %}
2
+
3
+ {{
4
+ onsChart({
5
+ "chartType": "bar",
6
+ "description": "Volume sales, seasonally adjusted, Great Britain, January 2022 to January 2025",
7
+ "theme": "primary",
8
+ "title": "Food stores showed a strong rise on the month, while non-food stores fell",
9
+ "subtitle": "Figure 6: Upward contribution from housing and household services (including energy) saw the annual CPIH inflation rate rise",
10
+ "id": "uuid",
11
+ "caption": "Source: Monthly Business Survey, Retail Sales Inquiry from the Office for National Statistics",
12
+ "download": {
13
+ 'title': 'Download Figure 1 data',
14
+ 'itemsList': [
15
+ {
16
+ "text": "Excel spreadsheet (XLSX format, 18KB)",
17
+ "url": "#"
18
+ },
19
+ {
20
+ "text": "Simple text file (CSV format, 25KB)",
21
+ "url": "#"
22
+ },
23
+ {
24
+ "text": "Image (PNG format, 25KB)",
25
+ "url": "#"
26
+ }
27
+ ]
28
+ },
29
+ "xAxis": {
30
+ "categories": [
31
+ "All retailing",
32
+ "All retailing excluding Automotive fuel",
33
+ "Food stores",
34
+ "Department stores",
35
+ "Other non-food stores",
36
+ "Textile clothing \u0026 footwear stores",
37
+ "Household goods stores",
38
+ "Non-store retailing",
39
+ "Automotive fuel"
40
+ ],
41
+ "type": "linear"
42
+ },
43
+ "yAxis": {
44
+ "title": "Percent (%)"
45
+ },
46
+ "series": [
47
+ {
48
+ "data": [1.7, 2.1, 5.6, 0, -0.6, -2.7, -1.7, 2.4, -1.2],
49
+ "dataLabels": true,
50
+ "name": "Jan-25"
51
+ }
52
+ ]
53
+ })
54
+ }}
@@ -0,0 +1,60 @@
1
+ {% from "components/chart/_macro.njk" import onsChart %}
2
+
3
+ {{
4
+ onsChart({
5
+ "chartType": "bar",
6
+ "description": "Volume sales, seasonally adjusted, Great Britain, January 2022 to January 2025",
7
+ "theme": "primary",
8
+ "title": "Food stores showed a strong rise on the month, while non-food stores fell",
9
+ "subtitle": "Figure 6: Upward contribution from housing and household services (including energy) saw the annual CPIH inflation rate rise",
10
+ "id": "uuid",
11
+ "caption": "Source: Monthly Business Survey, Retail Sales Inquiry from the Office for National Statistics",
12
+ "download": {
13
+ 'title': 'Download Figure 1 data',
14
+ 'itemsList': [
15
+ {
16
+ "text": "Excel spreadsheet (XLSX format, 18KB)",
17
+ "url": "#"
18
+ },
19
+ {
20
+ "text": "Simple text file (CSV format, 25KB)",
21
+ "url": "#"
22
+ },
23
+ {
24
+ "text": "Image (PNG format, 25KB)",
25
+ "url": "#"
26
+ }
27
+ ]
28
+ },
29
+ "legend": true,
30
+ "series": [
31
+ {
32
+ "data": [-6.2, 1.5, -15.9, 1.7],
33
+ "dataLabels": false,
34
+ "name": "2022"
35
+ },
36
+ {
37
+ "data": [-2.9, -2.7, -2.9, -3.5],
38
+ "dataLabels": false,
39
+ "name": "2023"
40
+ },
41
+ {
42
+ "data": [-1.6, 1.2, 3.2, 3.8],
43
+ "dataLabels": false,
44
+ "name": "2024"
45
+ }
46
+ ],
47
+ "xAxis": {
48
+ "categories": [
49
+ "Food stores",
50
+ "Non-food stores",
51
+ "Non-store retailing ",
52
+ "Automotive fuel"
53
+ ],
54
+ "type": "linear"
55
+ },
56
+ "yAxis": {
57
+ "title": "Percent (%)"
58
+ }
59
+ })
60
+ }}
@@ -0,0 +1,72 @@
1
+ {% from "components/chart/_macro.njk" import onsChart %}
2
+
3
+ {{
4
+ onsChart({
5
+ "chartType": "column",
6
+ "description": "Volume sales, monthly percentage change, seasonally adjusted, Great Britain, October 2024",
7
+ "theme": "alternate",
8
+ "title": "Clothing stores fell back, following three months of growth",
9
+ "subtitle": "Volume sales, monthly percentage change, seasonally adjusted, Great Britain, October 2024",
10
+ "id": "uuid",
11
+ "caption": "Source: Monthly Business Survey, Retail Sales Inquiry from the Office for National Statistics",
12
+ "download": {
13
+ 'title': 'Download Figure 1 data',
14
+ 'itemsList': [
15
+ {
16
+ "text": "Excel spreadsheet (XLSX format, 18KB)",
17
+ "url": "#"
18
+ },
19
+ {
20
+ "text": "Simple text file (CSV format, 25KB)",
21
+ "url": "#"
22
+ },
23
+ {
24
+ "text": "Image (PNG format, 25KB)",
25
+ "url": "#"
26
+ }
27
+ ]
28
+ },
29
+ "legend": {
30
+ "enabled": true
31
+ },
32
+ "series": [
33
+ {
34
+ "data": [6.2, 1.5, 15.9, 1.7],
35
+ "dataLabels": false,
36
+ "name": "2022"
37
+ },
38
+ {
39
+ "data": [2.9, -2.7, 2.9, 3.5],
40
+ "dataLabels": false,
41
+ "name": "2023"
42
+ },
43
+ {
44
+ "data": [-1.6, 1.2, 3.2, 3.8],
45
+ "dataLabels": false,
46
+ "name": "2024"
47
+ },
48
+ {
49
+ "data": [3.0, 2, 5.6, 2.1],
50
+ "dataLabels": false,
51
+ "name": "2025"
52
+ },
53
+ {
54
+ "data": [2.0, 2, 3, 4],
55
+ "dataLabels": false,
56
+ "name": "2026"
57
+ }
58
+ ],
59
+ "xAxis": {
60
+ "categories": [
61
+ "Food stores",
62
+ "Non-food stores",
63
+ "Non-store retailing ",
64
+ "Automotive fuel"
65
+ ],
66
+ "type": "linear"
67
+ },
68
+ "yAxis": {
69
+ "title": "2022"
70
+ }
71
+ })
72
+ }}
@@ -0,0 +1,52 @@
1
+ {% from "components/chart/_macro.njk" import onsChart %}
2
+
3
+ {{
4
+ onsChart({
5
+ "chartType": "column",
6
+ "description": "Public sector net debt excluding public sector banks, percentage of gross domestic product (GDP), UK, financial year ending (FYE) 1901 to October 2024",
7
+ "theme": "primary",
8
+ "title": "Figure 6: Net debt as a percentage of GDP remains at levels last seen in the early 1960s",
9
+ "subtitle": "Public sector net debt excluding public sector banks, percentage of gross domestic product (GDP), UK, financial year ending (FYE) 1901 to October 2024",
10
+ "id": "uuid",
11
+ "caption": "Source: Public sector finances from the Office for Budget Responsibility (OBR) and the Office for National Statistics",
12
+ "download": {
13
+ 'title': 'Download Figure 1 data',
14
+ 'itemsList': [
15
+ {
16
+ "text": "Excel spreadsheet (XLSX format, 18KB)",
17
+ "url": "#"
18
+ },
19
+ {
20
+ "text": "Simple text file (CSV format, 25KB)",
21
+ "url": "#"
22
+ },
23
+ {
24
+ "text": "Image (PNG format, 25KB)",
25
+ "url": "#"
26
+ }
27
+ ]
28
+ },
29
+ "legend": false,
30
+ "series": [
31
+ {
32
+ "data": [
33
+ 37.8, 41.0, 43.0, 42.9, 41.8, 39.8, 37.9, 38.2, 37.6, 36.7,
34
+ 33.9, 31.8
35
+ ],
36
+ "dataLabels": false,
37
+ "name": "Public sector net debt as a % of GDP (PSND)"
38
+ }
39
+ ],
40
+ "xAxis": {
41
+ "categories": [
42
+ "Mar 1901", "Mar 1902", "Mar 1903", "Mar 1904", "Mar 1905", "Mar 1906", "Mar 1907", "Mar 1908", "Mar 1909", "Mar 1910",
43
+ "Mar 1911", "Mar 1912"
44
+ ],
45
+ "title": "Years",
46
+ "type": "linear"
47
+ },
48
+ "yAxis": {
49
+ "title": "Percentage of GDP"
50
+ }
51
+ })
52
+ }}