@ons/design-system 72.9.1 → 72.10.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.
- package/components/button/_button.scss +10 -0
- package/components/card/_macro.njk +3 -3
- package/components/card/_macro.spec.js +109 -252
- package/components/card/_test_examples.js +56 -0
- package/components/chart/_chart.scss +74 -1
- package/components/chart/_macro.njk +64 -5
- package/components/chart/_macro.spec.js +405 -0
- package/components/chart/bar-chart.js +2 -2
- package/components/chart/boxplot.js +37 -0
- package/components/chart/chart-constants.js +13 -0
- package/components/chart/chart.js +98 -50
- package/components/chart/columnrange-chart.js +94 -0
- package/components/chart/common-chart-options.js +28 -19
- package/components/chart/example-bar-chart-with-annotations.njk +1 -1
- package/components/chart/example-bar-chart-with-point-range-and-reference-line-annotations.njk +95 -0
- package/components/chart/example-bar-with-confidence-levels.njk +71 -0
- package/components/chart/example-clustered-column-chart.njk +1 -3
- package/components/chart/example-column-chart-with-annotations.njk +1 -1
- package/components/chart/example-column-chart-with-range-annotations.njk +64 -0
- package/components/chart/example-column-chart-with-reference-line-annotations.njk +64 -0
- package/components/chart/example-column-with-confidence-levels.njk +61 -0
- package/components/chart/example-line-chart-with-annotations.njk +3 -3
- package/components/chart/example-line-chart-with-markers.njk +1 -1
- package/components/chart/example-line-chart-with-range-annotations-inside.njk +238 -0
- package/components/chart/example-line-chart-with-range-annotations-outside-left-right.njk +240 -0
- package/components/chart/example-line-chart-with-range-annotations-outside-top-bottom.njk +239 -0
- package/components/chart/example-line-chart-with-reference-line-annotations.njk +236 -0
- package/components/chart/example-scatter-chart.njk +1 -1
- package/components/chart/range-annotations-options.js +216 -0
- package/components/chart/reference-line-annotations-options.js +93 -0
- package/components/chart/scatter-chart.js +15 -0
- package/components/chart/specific-chart-options.js +1 -1
- package/components/chart/utilities.js +96 -0
- package/components/details-panel/_macro.njk +5 -1
- package/components/details-panel/_macro.spec.js +22 -0
- package/components/document-list/_document-list.scss +5 -13
- package/components/document-list/_macro.njk +14 -17
- package/components/document-list/_macro.spec.js +3 -3
- package/components/fieldset/_macro.spec.js +200 -120
- package/components/fieldset/_test_examples.js +15 -0
- package/components/header/_header.scss +11 -0
- package/components/header/_macro.njk +11 -6
- package/components/header/_macro.spec.js +113 -3
- package/components/hero/_macro.spec.js +1 -1
- package/components/icon/_macro.njk +14 -24
- package/components/language-selector/_macro.njk +6 -3
- package/components/navigation/navigation.js +57 -58
- package/components/navigation/navigation.spec.js +6 -10
- package/components/summary/_macro.njk +4 -1
- package/components/table-of-contents/_macro.njk +1 -1
- package/components/table-of-contents/_macro.spec.js +7 -0
- package/components/table-of-contents/table-of-contents.js +43 -26
- package/css/main.css +1 -1
- package/package.json +1 -1
- package/scripts/main.es5.js +1 -1
- package/scripts/main.js +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Highcharts from 'highcharts';
|
|
2
2
|
import 'highcharts/modules/accessibility';
|
|
3
3
|
import 'highcharts/modules/annotations';
|
|
4
|
+
import 'highcharts/highcharts-more';
|
|
4
5
|
|
|
5
6
|
import CommonChartOptions from './common-chart-options';
|
|
6
7
|
import SpecificChartOptions from './specific-chart-options';
|
|
@@ -8,8 +9,13 @@ import LineChart from './line-chart';
|
|
|
8
9
|
import BarChart from './bar-chart';
|
|
9
10
|
import ColumnChart from './column-chart';
|
|
10
11
|
import ScatterChart from './scatter-chart';
|
|
12
|
+
import Boxplot from './boxplot';
|
|
11
13
|
import AnnotationsOptions from './annotations-options';
|
|
14
|
+
import RangeAnnotationsOptions from './range-annotations-options';
|
|
15
|
+
import ReferenceLineAnnotationsOptions from './reference-line-annotations-options';
|
|
16
|
+
import { preparePlotLinesAndBands, mergeConfigs } from './utilities';
|
|
12
17
|
import AreaChart from './area-chart';
|
|
18
|
+
import ColumnRangeChart from './columnrange-chart';
|
|
13
19
|
|
|
14
20
|
class HighchartsBaseChart {
|
|
15
21
|
static selector() {
|
|
@@ -29,23 +35,46 @@ class HighchartsBaseChart {
|
|
|
29
35
|
this.useStackedLayout = this.node.hasAttribute('data-highcharts-use-stacked-layout');
|
|
30
36
|
this.config = JSON.parse(this.node.querySelector(`[data-highcharts-config--${this.id}]`).textContent);
|
|
31
37
|
if (this.node.querySelector(`[data-highcharts-annotations--${this.id}]`)) {
|
|
32
|
-
|
|
33
|
-
this.annotationsOptions = new AnnotationsOptions(annotations);
|
|
38
|
+
this.annotations = JSON.parse(this.node.querySelector(`[data-highcharts-annotations--${this.id}]`).textContent);
|
|
39
|
+
this.annotationsOptions = new AnnotationsOptions(this.annotations);
|
|
40
|
+
}
|
|
41
|
+
if (this.node.querySelector(`[data-highcharts-range-annotations--${this.id}]`)) {
|
|
42
|
+
this.rangeAnnotations = JSON.parse(this.node.querySelector(`[data-highcharts-range-annotations--${this.id}]`).textContent);
|
|
43
|
+
this.rangeAnnotationsOptions = new RangeAnnotationsOptions(this.rangeAnnotations);
|
|
44
|
+
}
|
|
45
|
+
if (this.node.querySelector(`[data-highcharts-reference-line-annotations--${this.id}]`)) {
|
|
46
|
+
this.referenceLineAnnotations = JSON.parse(
|
|
47
|
+
this.node.querySelector(`[data-highcharts-reference-line-annotations--${this.id}]`).textContent,
|
|
48
|
+
);
|
|
49
|
+
this.referenceLineAnnotationsOptions = new ReferenceLineAnnotationsOptions(this.referenceLineAnnotations);
|
|
34
50
|
}
|
|
35
51
|
this.percentageHeightDesktop = this.node.dataset.highchartsPercentageHeightDesktop;
|
|
36
52
|
this.percentageHeightMobile = this.node.dataset.highchartsPercentageHeightMobile;
|
|
37
|
-
this.xAxisTickIntervalMobile =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this.
|
|
53
|
+
this.xAxisTickIntervalMobile = this.node.dataset.highchartsXAxisTickIntervalMobile
|
|
54
|
+
? parseInt(this.node.dataset.highchartsXAxisTickIntervalMobile)
|
|
55
|
+
: undefined;
|
|
56
|
+
this.xAxisTickIntervalDesktop = this.node.dataset.highchartsXAxisTickIntervalDesktop
|
|
57
|
+
? parseInt(this.node.dataset.highchartsXAxisTickIntervalDesktop)
|
|
58
|
+
: undefined;
|
|
59
|
+
this.yAxisTickIntervalMobile = this.node.dataset.highchartsYAxisTickIntervalMobile
|
|
60
|
+
? parseInt(this.node.dataset.highchartsYAxisTickIntervalMobile)
|
|
61
|
+
: undefined;
|
|
62
|
+
this.yAxisTickIntervalDesktop = this.node.dataset.highchartsYAxisTickIntervalDesktop
|
|
63
|
+
? parseInt(this.node.dataset.highchartsYAxisTickIntervalDesktop)
|
|
64
|
+
: undefined;
|
|
41
65
|
this.commonChartOptions = new CommonChartOptions(this.xAxisTickIntervalDesktop, this.yAxisTickIntervalDesktop);
|
|
66
|
+
this.estimateLineLabel = this.node.dataset.highchartsEstimateLineLabel;
|
|
67
|
+
this.uncertainyRangeLabel = this.node.dataset.highchartsUncertaintyRangeLabel;
|
|
42
68
|
this.specificChartOptions = new SpecificChartOptions(this.theme, this.chartType, this.config);
|
|
43
69
|
this.lineChart = new LineChart();
|
|
44
70
|
this.barChart = new BarChart();
|
|
45
71
|
this.columnChart = new ColumnChart();
|
|
46
72
|
this.areaChart = new AreaChart();
|
|
47
73
|
this.scatterChart = new ScatterChart();
|
|
74
|
+
this.columnRangeChart = new ColumnRangeChart();
|
|
75
|
+
this.boxplot = new Boxplot();
|
|
48
76
|
this.extraLines = this.checkForExtraLines();
|
|
77
|
+
this.extraScatter = this.checkForExtraScatter();
|
|
49
78
|
if (window.isCommonChartOptionsDefined === undefined) {
|
|
50
79
|
this.setCommonChartOptions();
|
|
51
80
|
window.isCommonChartOptionsDefined = true;
|
|
@@ -54,6 +83,7 @@ class HighchartsBaseChart {
|
|
|
54
83
|
this.setSpecificChartOptions();
|
|
55
84
|
this.setResponsiveOptions();
|
|
56
85
|
this.setLoadEvent();
|
|
86
|
+
this.setRenderEvent();
|
|
57
87
|
this.setWindowResizeEvent();
|
|
58
88
|
this.chart = Highcharts.chart(chartNode, this.config);
|
|
59
89
|
}
|
|
@@ -63,83 +93,69 @@ class HighchartsBaseChart {
|
|
|
63
93
|
return this.chartType === 'line' ? 0 : this.config.series.filter((series) => series.type === 'line').length;
|
|
64
94
|
};
|
|
65
95
|
|
|
96
|
+
// Check for the number of extra line series in the config
|
|
97
|
+
checkForExtraScatter = () => {
|
|
98
|
+
return this.chartType === 'scatter' ? 0 : this.config.series.filter((series) => series.type === 'scatter').length;
|
|
99
|
+
};
|
|
100
|
+
|
|
66
101
|
// Set up the global Highcharts options which are used for all charts
|
|
67
102
|
setCommonChartOptions = () => {
|
|
68
103
|
const chartOptions = this.commonChartOptions.getOptions();
|
|
69
104
|
Highcharts.setOptions(chartOptions);
|
|
70
105
|
};
|
|
71
106
|
|
|
72
|
-
// Utility function to merge two configs together
|
|
73
|
-
mergeConfigs = (baseConfig, newConfig) => {
|
|
74
|
-
// If newConfig is null/undefined, return baseConfig
|
|
75
|
-
if (!newConfig) return baseConfig;
|
|
76
|
-
|
|
77
|
-
// Create a new object to store the merged result
|
|
78
|
-
const merged = { ...baseConfig };
|
|
79
|
-
|
|
80
|
-
// Iterate through all keys in newConfig
|
|
81
|
-
Object.keys(newConfig).forEach((key) => {
|
|
82
|
-
// Get values from both configs for this key
|
|
83
|
-
const baseValue = merged[key];
|
|
84
|
-
const newValue = newConfig[key];
|
|
85
|
-
|
|
86
|
-
// If both values are objects (and not null), recursively merge them
|
|
87
|
-
if (
|
|
88
|
-
baseValue &&
|
|
89
|
-
newValue &&
|
|
90
|
-
typeof baseValue === 'object' &&
|
|
91
|
-
typeof newValue === 'object' &&
|
|
92
|
-
!Array.isArray(baseValue) &&
|
|
93
|
-
!Array.isArray(newValue)
|
|
94
|
-
) {
|
|
95
|
-
merged[key] = this.mergeConfigs(baseValue, newValue);
|
|
96
|
-
} else {
|
|
97
|
-
// For non-objects and arrays use the new value
|
|
98
|
-
// If the new value is null/undefined, use the base value
|
|
99
|
-
merged[key] = newValue ?? baseValue;
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
return merged;
|
|
104
|
-
};
|
|
105
|
-
|
|
106
107
|
// Set up options for specific charts and chart types
|
|
107
108
|
setSpecificChartOptions = () => {
|
|
108
109
|
const specificChartOptions = this.specificChartOptions.getOptions();
|
|
109
110
|
const lineChartOptions = this.lineChart.getLineChartOptions();
|
|
110
111
|
const barChartOptions = this.barChart.getBarChartOptions(this.useStackedLayout);
|
|
112
|
+
const columnRangeChartOptions = this.columnRangeChart.getColumnRangeChartOptions();
|
|
111
113
|
const columnChartOptions = this.columnChart.getColumnChartOptions(this.config, this.useStackedLayout, this.extraLines);
|
|
112
114
|
const areaChartOptions = this.areaChart.getAreaChartOptions();
|
|
113
115
|
const scatterChartOptions = this.scatterChart.getScatterChartOptions();
|
|
116
|
+
const boxplotOptions = this.boxplot.getBoxplotOptions(this.config, this.useStackedLayout, this.extraLines);
|
|
114
117
|
// Merge specificChartOptions with the existing config
|
|
115
|
-
this.config =
|
|
118
|
+
this.config = mergeConfigs(this.config, specificChartOptions);
|
|
116
119
|
|
|
117
120
|
if (this.chartType === 'line') {
|
|
118
121
|
// Merge the line chart options with the existing config
|
|
119
|
-
this.config =
|
|
122
|
+
this.config = mergeConfigs(this.config, lineChartOptions);
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
if (this.chartType === 'bar') {
|
|
123
126
|
// Merge the bar chart options with the existing config
|
|
124
|
-
this.config =
|
|
127
|
+
this.config = mergeConfigs(this.config, barChartOptions);
|
|
128
|
+
}
|
|
129
|
+
if (this.chartType === 'columnrange') {
|
|
130
|
+
// Merge the bar chart options with the existing config
|
|
131
|
+
this.config = mergeConfigs(this.config, columnRangeChartOptions);
|
|
125
132
|
}
|
|
126
133
|
if (this.chartType === 'column') {
|
|
127
134
|
// Merge the column chart options with the existing config
|
|
128
|
-
this.config =
|
|
135
|
+
this.config = mergeConfigs(this.config, columnChartOptions);
|
|
129
136
|
}
|
|
130
137
|
if (this.chartType === 'area') {
|
|
131
138
|
// Merge the area chart options with the existing config
|
|
132
|
-
this.config =
|
|
139
|
+
this.config = mergeConfigs(this.config, areaChartOptions);
|
|
133
140
|
}
|
|
134
141
|
if (this.chartType === 'scatter') {
|
|
135
142
|
// Merge the scatter chart options with the existing config
|
|
136
|
-
this.config =
|
|
143
|
+
this.config = mergeConfigs(this.config, scatterChartOptions);
|
|
144
|
+
}
|
|
145
|
+
if (this.chartType === 'boxplot') {
|
|
146
|
+
// Merge the boxplot chart options with the existing config
|
|
147
|
+
this.config = mergeConfigs(this.config, boxplotOptions);
|
|
137
148
|
}
|
|
138
149
|
|
|
139
150
|
if (this.extraLines > 0) {
|
|
140
|
-
this.config =
|
|
151
|
+
this.config = mergeConfigs(this.config, this.lineChart.getLineChartOptions());
|
|
141
152
|
if (this.chartType === 'column') {
|
|
142
|
-
this.config =
|
|
153
|
+
this.config = mergeConfigs(this.config, columnChartOptions);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (this.extraScatter > 0) {
|
|
157
|
+
if (this.chartType === 'columnrange') {
|
|
158
|
+
this.config = mergeConfigs(this.config, columnRangeChartOptions);
|
|
143
159
|
}
|
|
144
160
|
}
|
|
145
161
|
|
|
@@ -158,19 +174,28 @@ class HighchartsBaseChart {
|
|
|
158
174
|
// All responsive rules should be defined here to avoid overriding existing rules
|
|
159
175
|
setResponsiveOptions = () => {
|
|
160
176
|
let mobileChartOptions = this.commonChartOptions.getMobileOptions(this.xAxisTickIntervalMobile, this.yAxisTickIntervalMobile);
|
|
161
|
-
if (this.chartType === 'column') {
|
|
177
|
+
if (this.chartType === 'column' || this.chartType === 'boxplot') {
|
|
162
178
|
const mobileColumnChartOptions = this.columnChart.getColumnChartMobileOptions(
|
|
163
179
|
this.config,
|
|
164
180
|
this.useStackedLayout,
|
|
165
181
|
this.extraLines,
|
|
166
182
|
);
|
|
167
|
-
mobileChartOptions =
|
|
183
|
+
mobileChartOptions = mergeConfigs(mobileChartOptions, mobileColumnChartOptions);
|
|
168
184
|
}
|
|
169
185
|
|
|
170
186
|
if (!this.config.responsive) {
|
|
171
187
|
this.config.responsive = {};
|
|
172
188
|
}
|
|
173
189
|
|
|
190
|
+
const { desktopAllPlotLinesAndBands, mobileAllPlotLinesAndBands } = preparePlotLinesAndBands(
|
|
191
|
+
this.annotations,
|
|
192
|
+
this.rangeAnnotations,
|
|
193
|
+
this.rangeAnnotationsOptions,
|
|
194
|
+
this.referenceLineAnnotationsOptions,
|
|
195
|
+
this.commonChartOptions,
|
|
196
|
+
this.chartType,
|
|
197
|
+
);
|
|
198
|
+
|
|
174
199
|
let rules = [
|
|
175
200
|
{
|
|
176
201
|
condition: {
|
|
@@ -190,6 +215,7 @@ class HighchartsBaseChart {
|
|
|
190
215
|
},
|
|
191
216
|
chartOptions: {
|
|
192
217
|
annotations: this.annotationsOptions ? this.annotationsOptions.getAnnotationsOptionsMobile() : undefined,
|
|
218
|
+
...(mobileAllPlotLinesAndBands != {} ? mobileAllPlotLinesAndBands : null),
|
|
193
219
|
},
|
|
194
220
|
},
|
|
195
221
|
{
|
|
@@ -198,6 +224,7 @@ class HighchartsBaseChart {
|
|
|
198
224
|
},
|
|
199
225
|
chartOptions: {
|
|
200
226
|
annotations: this.annotationsOptions ? this.annotationsOptions.getAnnotationsOptionsDesktop() : undefined,
|
|
227
|
+
...(desktopAllPlotLinesAndBands != {} ? desktopAllPlotLinesAndBands : null),
|
|
201
228
|
},
|
|
202
229
|
},
|
|
203
230
|
];
|
|
@@ -230,6 +257,15 @@ class HighchartsBaseChart {
|
|
|
230
257
|
if (this.chartType === 'scatter') {
|
|
231
258
|
this.scatterChart.updateMarkers(currentChart);
|
|
232
259
|
}
|
|
260
|
+
if (this.chartType === 'columnrange') {
|
|
261
|
+
this.columnRangeChart.updateColumnRangeChartHeight(this.config, currentChart);
|
|
262
|
+
this.commonChartOptions.hideDataLabels(currentChart.series);
|
|
263
|
+
|
|
264
|
+
if (this.extraScatter > 0) {
|
|
265
|
+
const scatterSeries = currentChart.series.filter((series) => series.type === 'scatter');
|
|
266
|
+
this.scatterChart.updateMarkersForConfidenceLevels(scatterSeries);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
233
269
|
if (this.chartType != 'bar') {
|
|
234
270
|
this.commonChartOptions.adjustChartHeight(currentChart, this.percentageHeightDesktop, this.percentageHeightMobile);
|
|
235
271
|
}
|
|
@@ -249,6 +285,18 @@ class HighchartsBaseChart {
|
|
|
249
285
|
};
|
|
250
286
|
};
|
|
251
287
|
|
|
288
|
+
setRenderEvent = () => {
|
|
289
|
+
if (!this.config.chart.events) {
|
|
290
|
+
this.config.chart.events = {};
|
|
291
|
+
}
|
|
292
|
+
this.config.chart.events.render = (event) => {
|
|
293
|
+
const currentChart = event.target;
|
|
294
|
+
if (this.rangeAnnotationsOptions) {
|
|
295
|
+
this.rangeAnnotationsOptions.addLine(currentChart);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
|
|
252
300
|
// Set resize events - throttled to 50ms
|
|
253
301
|
// All resize events should be defined here to avoid overriding existing events
|
|
254
302
|
setWindowResizeEvent = () => {
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import ChartConstants from './chart-constants';
|
|
2
|
+
|
|
3
|
+
class ColumnRangeChart {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.constants = ChartConstants.constants();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
getColumnRangeChartOptions = () => {
|
|
9
|
+
return {
|
|
10
|
+
plotOptions: {
|
|
11
|
+
columnrange: {
|
|
12
|
+
color: this.constants.uncertaintyRangeColor, // Set the default color for the column range
|
|
13
|
+
pointWidth: 20, // Fixed bar height
|
|
14
|
+
pointPadding: 0,
|
|
15
|
+
groupPadding: 0,
|
|
16
|
+
borderWidth: 0,
|
|
17
|
+
borderRadius: 0,
|
|
18
|
+
dataLabels: {
|
|
19
|
+
enabled: false,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
xAxis: {
|
|
24
|
+
// Update the category label colours for bar charts
|
|
25
|
+
labels: {
|
|
26
|
+
style: {
|
|
27
|
+
color: this.constants.categoryLabelColor,
|
|
28
|
+
},
|
|
29
|
+
useHTML: false,
|
|
30
|
+
},
|
|
31
|
+
// remove the tick marks for bar charts
|
|
32
|
+
tickWidth: 0,
|
|
33
|
+
tickLength: 0,
|
|
34
|
+
gridlineWidth: 0,
|
|
35
|
+
tickColor: 'transparent',
|
|
36
|
+
title: { align: 'high', textAlign: 'middle', reserveSpace: false, rotation: 0, y: -25, useHTML: true },
|
|
37
|
+
},
|
|
38
|
+
yAxis: {
|
|
39
|
+
labels: {
|
|
40
|
+
rotation: 0,
|
|
41
|
+
useHTML: true,
|
|
42
|
+
style: {
|
|
43
|
+
whiteSpace: 'nowrap',
|
|
44
|
+
color: this.constants.categoryLabelColor,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
tickLength: 0,
|
|
48
|
+
tickWidth: 0,
|
|
49
|
+
tickColor: 'transparent',
|
|
50
|
+
gridlineWidth: 0,
|
|
51
|
+
title: {
|
|
52
|
+
// Override the y Axis title settings for bar charts where the y axis is horizontal
|
|
53
|
+
textAlign: 'right',
|
|
54
|
+
offset: undefined,
|
|
55
|
+
y: 0,
|
|
56
|
+
reserveSpace: true,
|
|
57
|
+
useHTML: false,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
legend: {
|
|
61
|
+
symbolRadius: 0,
|
|
62
|
+
itemStyle: {
|
|
63
|
+
fontSize: this.constants.defaultFontSize,
|
|
64
|
+
color: this.constants.legendLabelColor,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// This updates the height of the vertical axis and overall chart to fit the number of categories
|
|
71
|
+
// Note that the vertical axis on a bar chart is the x axis
|
|
72
|
+
updateColumnRangeChartHeight = (config, currentChart) => {
|
|
73
|
+
const numberOfCategories = config.xAxis.categories.length;
|
|
74
|
+
let barHeight = 20; // Height of each individual bar - set in bar-chart-plot-options
|
|
75
|
+
let groupSpacing = 0; // Space we want between category groups, or between series groups for cluster charts
|
|
76
|
+
let categoriesTotalHeight = 0;
|
|
77
|
+
let totalSpaceHeight = 0;
|
|
78
|
+
|
|
79
|
+
groupSpacing = 14;
|
|
80
|
+
categoriesTotalHeight = numberOfCategories * barHeight;
|
|
81
|
+
|
|
82
|
+
totalSpaceHeight = numberOfCategories * groupSpacing;
|
|
83
|
+
|
|
84
|
+
config.xAxis.height = categoriesTotalHeight + totalSpaceHeight;
|
|
85
|
+
const totalHeight = currentChart.plotTop + config.xAxis.height + currentChart.marginBottom;
|
|
86
|
+
if (totalHeight !== currentChart.chartHeight) {
|
|
87
|
+
currentChart.setSize(null, totalHeight, false);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
currentChart.redraw();
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default ColumnRangeChart;
|
|
@@ -81,15 +81,6 @@ class CommonChartOptions {
|
|
|
81
81
|
},
|
|
82
82
|
lineColor: this.constants.gridLineColor,
|
|
83
83
|
gridLineColor: this.constants.gridLineColor,
|
|
84
|
-
// Add zero line
|
|
85
|
-
plotLines: [
|
|
86
|
-
{
|
|
87
|
-
color: this.constants.zeroLineColor,
|
|
88
|
-
width: 1.5,
|
|
89
|
-
value: 0,
|
|
90
|
-
zIndex: 2,
|
|
91
|
-
},
|
|
92
|
-
],
|
|
93
84
|
// Add tick marks
|
|
94
85
|
tickWidth: 1,
|
|
95
86
|
tickLength: 6,
|
|
@@ -143,6 +134,25 @@ class CommonChartOptions {
|
|
|
143
134
|
|
|
144
135
|
getOptions = () => this.options;
|
|
145
136
|
|
|
137
|
+
// TODO: A future ticket will add support for other plot lines which are not
|
|
138
|
+
// reference line annotations, and will be styled like the zero line
|
|
139
|
+
// See ticket https://jira.ons.gov.uk/browse/CCB-63
|
|
140
|
+
getPlotLines = () => {
|
|
141
|
+
// Add zero line
|
|
142
|
+
return {
|
|
143
|
+
yAxis: {
|
|
144
|
+
plotLines: [
|
|
145
|
+
{
|
|
146
|
+
color: this.constants.zeroLineColor,
|
|
147
|
+
width: 1.5,
|
|
148
|
+
value: 0,
|
|
149
|
+
zIndex: 2,
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
|
|
146
156
|
getMobileOptions = (xAxisTickInterval, yAxisTickInterval) => {
|
|
147
157
|
return {
|
|
148
158
|
xAxis: {
|
|
@@ -165,7 +175,7 @@ class CommonChartOptions {
|
|
|
165
175
|
};
|
|
166
176
|
|
|
167
177
|
disableLegendForSingleSeries = (config) => {
|
|
168
|
-
if (config.series.length === 1) {
|
|
178
|
+
if (config.chart.type != 'boxplot' && config.series.length === 1) {
|
|
169
179
|
config.legend = {
|
|
170
180
|
enabled: false,
|
|
171
181
|
};
|
|
@@ -183,20 +193,19 @@ class CommonChartOptions {
|
|
|
183
193
|
const { label, symbol } = legendItem || {};
|
|
184
194
|
|
|
185
195
|
if (seriesType === 'line') {
|
|
186
|
-
symbol?.attr({
|
|
187
|
-
x: 16, // Position the marker to the right of the line
|
|
188
|
-
});
|
|
189
|
-
|
|
190
196
|
label?.attr({
|
|
191
197
|
x: 30, // Adjust label position to account for longer line
|
|
192
198
|
});
|
|
193
199
|
} else {
|
|
200
|
+
if (!symbol) return;
|
|
194
201
|
// Set the symbol size for bar / column series
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
202
|
+
else {
|
|
203
|
+
symbol.attr({
|
|
204
|
+
width: 12,
|
|
205
|
+
height: 12,
|
|
206
|
+
y: 8,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
200
209
|
}
|
|
201
210
|
});
|
|
202
211
|
}
|
package/components/chart/example-bar-chart-with-point-range-and-reference-line-annotations.njk
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
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": false,
|
|
50
|
+
"name": "Jan-25"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"annotations": [
|
|
54
|
+
{
|
|
55
|
+
"text": "A test point annotation",
|
|
56
|
+
"point": {"x": 2, "y": 3},
|
|
57
|
+
"labelOffsetX": 40,
|
|
58
|
+
"labelOffsetY": -30
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"rangeAnnotations": [
|
|
62
|
+
{
|
|
63
|
+
"text": "A test x axis range annotation",
|
|
64
|
+
"range": {"axisValue1": 1, "axisValue2": 2},
|
|
65
|
+
"axis": "x",
|
|
66
|
+
"labelOffsetX": 10,
|
|
67
|
+
"labelOffsetY": -60
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"text": "A test y axis range annotation with a width of 80px",
|
|
71
|
+
"range": {"axisValue1": 5, "axisValue2": 6},
|
|
72
|
+
"axis": "y",
|
|
73
|
+
"labelOffsetX": -80,
|
|
74
|
+
"labelOffsetY": 220,
|
|
75
|
+
"labelWidth": 80
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"referenceLineAnnotations": [
|
|
79
|
+
{
|
|
80
|
+
"text": "A test x axis reference line annotation",
|
|
81
|
+
"value": 8,
|
|
82
|
+
"axis": "x",
|
|
83
|
+
"labelOffsetY": -30
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"text": "A test y axis reference line annotation",
|
|
87
|
+
"value": 1.5,
|
|
88
|
+
"axis": "y",
|
|
89
|
+
"labelWidth": 100,
|
|
90
|
+
"labelOffsetX": 10,
|
|
91
|
+
"labelOffsetY": 140
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
})
|
|
95
|
+
}}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{% from "components/chart/_macro.njk" import onsChart %}
|
|
2
|
+
|
|
3
|
+
{{
|
|
4
|
+
onsChart({
|
|
5
|
+
"chartType": "columnrange",
|
|
6
|
+
"isChartInverted": true,
|
|
7
|
+
"description": "Volume sales, seasonally adjusted, Great Britain, January 2022 to January 2025",
|
|
8
|
+
"theme": "primary",
|
|
9
|
+
"title": "Food stores showed a strong rise on the month, while non-food stores fell",
|
|
10
|
+
"subtitle": "Figure 6: Upward contribution from housing and household services (including energy) saw the annual CPIH inflation rate rise",
|
|
11
|
+
"id": "uuid",
|
|
12
|
+
"caption": "Source: Monthly Business Survey, Retail Sales Inquiry from the Office for National Statistics",
|
|
13
|
+
"download": {
|
|
14
|
+
'title': 'Download Figure 1 data',
|
|
15
|
+
'itemsList': [
|
|
16
|
+
{
|
|
17
|
+
"text": "Excel spreadsheet (XLSX format, 18KB)",
|
|
18
|
+
"url": "#"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"text": "Simple text file (CSV format, 25KB)",
|
|
22
|
+
"url": "#"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"text": "Image (PNG format, 25KB)",
|
|
26
|
+
"url": "#"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"legend": true,
|
|
31
|
+
"xAxis": {
|
|
32
|
+
"categories": [
|
|
33
|
+
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
|
34
|
+
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
|
|
35
|
+
],
|
|
36
|
+
"type": "linear",
|
|
37
|
+
"title": "Categories"
|
|
38
|
+
},
|
|
39
|
+
"yAxis": {
|
|
40
|
+
"title": "Temperature ( °C )"
|
|
41
|
+
},
|
|
42
|
+
"series": [
|
|
43
|
+
{
|
|
44
|
+
"data": [
|
|
45
|
+
[-9.5, 8.0],
|
|
46
|
+
[-7.8, 8.3],
|
|
47
|
+
[-13.1, 9.2],
|
|
48
|
+
[-4.4, 15.7],
|
|
49
|
+
[-1.0, 20.8],
|
|
50
|
+
[3.1, 28.4],
|
|
51
|
+
[5.9, 27.0],
|
|
52
|
+
[4.6, 23.0],
|
|
53
|
+
[4.9, 19.3],
|
|
54
|
+
[-5.2, 11.6],
|
|
55
|
+
[],
|
|
56
|
+
[-10.5, 12.0],
|
|
57
|
+
[-12.1, 18.5]
|
|
58
|
+
],
|
|
59
|
+
"dataLabels": true,
|
|
60
|
+
"name": "Values"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"data": [1,2,3,4,5,6,7,8,9,10,3,11,12],
|
|
64
|
+
"marker": true,
|
|
65
|
+
"dataLabels": false,
|
|
66
|
+
"name": "Another test data source",
|
|
67
|
+
"type": "scatter"
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
})
|
|
71
|
+
}}
|