@ons/design-system 72.4.0 → 72.6.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 (62) 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 +80 -0
  8. package/components/chart/_macro.njk +125 -0
  9. package/components/chart/_macro.spec.js +825 -0
  10. package/components/chart/annotations-options.js +78 -0
  11. package/components/chart/bar-chart.js +164 -0
  12. package/components/chart/chart-constants.js +21 -0
  13. package/components/chart/chart.dom.js +8 -0
  14. package/components/chart/chart.js +242 -0
  15. package/components/chart/column-chart.js +48 -0
  16. package/components/chart/common-chart-options.js +247 -0
  17. package/components/chart/example-bar-chart-with-annotations.njk +62 -0
  18. package/components/chart/example-bar-chart.njk +55 -0
  19. package/components/chart/example-bar-with-line-chart.njk +64 -0
  20. package/components/chart/example-clustered-bar-chart.njk +60 -0
  21. package/components/chart/example-clustered-column-chart.njk +74 -0
  22. package/components/chart/example-column-chart-with-annotations.njk +62 -0
  23. package/components/chart/example-column-chart.njk +54 -0
  24. package/components/chart/example-column-with-line-chart.njk +62 -0
  25. package/components/chart/example-line-chart-with-annotations.njk +235 -0
  26. package/components/chart/example-line-chart.njk +221 -0
  27. package/components/chart/example-stacked-bar-chart.njk +60 -0
  28. package/components/chart/example-stacked-column-chart.njk +67 -0
  29. package/components/chart/line-chart.js +42 -0
  30. package/components/chart/specific-chart-options.js +22 -0
  31. package/components/footer/_footer.scss +12 -0
  32. package/components/footer/_macro.njk +38 -17
  33. package/components/header/_header.scss +18 -2
  34. package/components/header/_macro.njk +81 -8
  35. package/components/header/_macro.spec.js +97 -0
  36. package/components/header/example-header-with-search-button.njk +190 -0
  37. package/components/header/header.spec.js +128 -0
  38. package/components/hero/_hero.scss +39 -7
  39. package/components/hero/_macro.njk +47 -17
  40. package/components/hero/_macro.spec.js +94 -0
  41. package/components/hero/example-hero-grey.njk +9 -0
  42. package/components/icon/_macro.njk +8 -8
  43. package/components/input/_input.scss +15 -0
  44. package/components/input/_macro.njk +3 -3
  45. package/components/navigation/navigation.dom.js +17 -0
  46. package/components/navigation/navigation.js +72 -2
  47. package/components/pagination/_pagination.scss +7 -1
  48. package/components/summary/_macro.njk +1 -1
  49. package/components/summary/_macro.spec.js +6 -0
  50. package/components/table-of-contents/_macro.njk +40 -0
  51. package/components/table-of-contents/_macro.spec.js +72 -0
  52. package/components/table-of-contents/_table-of-contents.scss +11 -0
  53. package/components/table-of-contents/example-table-of-contents-related-links-with-button.njk +60 -0
  54. package/css/main.css +1 -1
  55. package/js/cookies-functions.js +11 -6
  56. package/js/cookies-functions.spec.js +44 -0
  57. package/js/main.js +2 -0
  58. package/package.json +4 -1
  59. package/scripts/main.es5.js +1 -1
  60. package/scripts/main.js +1 -1
  61. package/scss/main.scss +1 -0
  62. package/scss/utilities/_grid.scss +13 -4
@@ -0,0 +1,78 @@
1
+ import ChartConstants from './chart-constants';
2
+
3
+ class AnnotationsOptions {
4
+ constructor(annotations) {
5
+ this.constants = ChartConstants.constants();
6
+ this.annotations = annotations;
7
+ }
8
+
9
+ getAnnotationsOptionsDesktop = () => {
10
+ let annotations = [
11
+ {
12
+ labels: [],
13
+ labelOptions: {
14
+ shape: 'connector',
15
+ borderColor: this.constants.labelColor,
16
+ padding: 3,
17
+ style: {
18
+ color: this.constants.labelColor,
19
+ fontSize: this.constants.desktopFontSize,
20
+ width: 150,
21
+ textAlign: 'left',
22
+ },
23
+ },
24
+ draggable: '',
25
+ },
26
+ ];
27
+ this.annotations.forEach((annotation) => {
28
+ annotations[0].labels.push({
29
+ point: {
30
+ x: annotation.point.x,
31
+ y: annotation.point.y,
32
+ xAxis: 0,
33
+ yAxis: 0,
34
+ },
35
+ text: annotation.text,
36
+ x: annotation.labelOffsetX,
37
+ y: annotation.labelOffsetY,
38
+ });
39
+ });
40
+ return annotations;
41
+ };
42
+
43
+ getAnnotationsOptionsMobile = () => {
44
+ let annotations = [
45
+ {
46
+ labels: [],
47
+ labelOptions: {
48
+ backgroundColor: 'transparent',
49
+ borderColor: 'transparent',
50
+ // We use css styling for the rounded number annotation at mobile
51
+ useHTML: true,
52
+ className: 'ons-chart__footnote-number',
53
+ },
54
+ draggable: '',
55
+ },
56
+ ];
57
+ this.annotations.forEach((annotation, index) => {
58
+ annotations[0].labels.push({
59
+ point: {
60
+ x: annotation.point.x,
61
+ y: annotation.point.y,
62
+ xAxis: 0,
63
+ yAxis: 0,
64
+ },
65
+ text: index + 1,
66
+ x: 0,
67
+ y: 0,
68
+ // Ensures the full label is read out by screen readers
69
+ accessibility: {
70
+ description: annotation.text,
71
+ },
72
+ });
73
+ });
74
+ return annotations;
75
+ };
76
+ }
77
+
78
+ export default AnnotationsOptions;
@@ -0,0 +1,164 @@
1
+ import ChartConstants from './chart-constants';
2
+
3
+ class BarChart {
4
+ constructor() {
5
+ this.constants = ChartConstants.constants();
6
+ }
7
+
8
+ getBarChartOptions = (useStackedLayout) => {
9
+ return {
10
+ plotOptions: {
11
+ bar: {
12
+ // Set the width of the bars to be 30px
13
+ // The spacing is worked out in the specific-chart-options.js file
14
+ pointWidth: 30, // Fixed bar height
15
+ pointPadding: 0,
16
+ groupPadding: 0,
17
+ borderWidth: 0,
18
+ borderRadius: 0,
19
+ // Set the data labels to be enabled and positioned outside the bars
20
+ // We can add custom formatting on each chart to move the labels inside the bars if the bar is wide enough
21
+ dataLabels: {
22
+ enabled: true,
23
+ inside: false,
24
+ style: {
25
+ textOutline: 'none',
26
+ // The design system does not include a semibold font weight, so we use 700 (bold) as an alternative.
27
+ fontWeight: '700',
28
+ color: this.constants.labelColor,
29
+ fontSize: this.constants.mobileFontSize,
30
+ },
31
+ },
32
+ },
33
+ series: {
34
+ stacking: useStackedLayout ? 'normal' : null,
35
+ },
36
+ },
37
+ xAxis: {
38
+ // Update the category label colours for bar charts
39
+ labels: {
40
+ style: {
41
+ color: this.constants.categoryLabelColor,
42
+ },
43
+ },
44
+ // remove the tick marks for bar charts
45
+ tickWidth: 0,
46
+ tickLength: 0,
47
+ tickColor: 'transparent',
48
+ title: { align: 'high', textAlign: 'middle', reserveSpace: false, rotation: 0, y: -25, useHTML: true },
49
+ },
50
+ yAxis: {
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
+ };
61
+ };
62
+
63
+ // Updates the config to move the data labels inside the bars, but only if the bar is wide enough
64
+ // This may also need to run when the chart is resized
65
+ postLoadDataLabels = (currentChart) => {
66
+ const insideOptions = {
67
+ dataLabels: this.getBarChartLabelsInsideOptions(),
68
+ };
69
+ const outsideOptions = {
70
+ dataLabels: this.getBarChartLabelsOutsideOptions(),
71
+ };
72
+
73
+ currentChart.series.forEach((series) => {
74
+ const points = series.data;
75
+ points.forEach((point) => {
76
+ // Get the actual width of the data label
77
+ const labelWidth = point.dataLabel && point.dataLabel.getBBox().width;
78
+ // Move the data labels inside the bar if the bar is wider than the label plus some padding
79
+ if (series.type == 'line') {
80
+ // If we have a bar chart with an extra line, exit early for the line series
81
+ return;
82
+ }
83
+ if (point.shapeArgs.height > labelWidth + 20) {
84
+ point.update(insideOptions, false);
85
+ } else {
86
+ point.update(outsideOptions, false);
87
+ }
88
+ });
89
+ });
90
+
91
+ currentChart.redraw();
92
+ };
93
+
94
+ getBarChartLabelsInsideOptions = () => ({
95
+ inside: true,
96
+ align: 'right',
97
+ verticalAlign: 'middle',
98
+ style: {
99
+ color: 'white',
100
+ fontWeight: 'bold',
101
+ },
102
+ });
103
+
104
+ getBarChartLabelsOutsideOptions = () => ({
105
+ inside: false,
106
+ align: undefined,
107
+ verticalAlign: undefined,
108
+ style: {
109
+ textOutline: 'none',
110
+ // The design system does not include a semibold font weight, so we use 700 (bold) as an alternative.
111
+ fontWeight: '700',
112
+ color: this.constants.labelColor,
113
+ fontSize: this.constants.mobileFontSize,
114
+ },
115
+ });
116
+
117
+ // This updates the height of the vertical axis and overall chart to fit the number of categories
118
+ // Note that the vertical axis on a bar chart is the x axis
119
+ updateBarChartHeight = (config, currentChart, useStackedLayout, numberOfExtraLines) => {
120
+ const numberOfCategories = config.xAxis.categories.length;
121
+ const numberOfSeries = currentChart.series.length - numberOfExtraLines; // Get number of bar series
122
+ let barHeight = 30; // Height of each individual bar - set in bar-chart-plot-options
123
+ let groupSpacing = 0; // Space we want between category groups, or between series groups for cluster charts
124
+ let categoriesTotalHeight = 0;
125
+ let totalSpaceHeight = 0;
126
+ if (useStackedLayout == false && numberOfSeries > 1) {
127
+ // slightly lower bar height for cluster charts
128
+ barHeight = 28;
129
+ // for cluster charts there is no space between the bars within a series, and 14px between each series
130
+ groupSpacing = 14;
131
+ // lower barHeight for series with 3 categories or more
132
+ if (numberOfSeries >= 3) {
133
+ barHeight = 20;
134
+ }
135
+ categoriesTotalHeight = numberOfCategories * barHeight * numberOfSeries;
136
+
137
+ totalSpaceHeight = numberOfCategories * groupSpacing;
138
+ // work out the group padding for cluster charts which is measured in xAxis units.
139
+ const plotHeight = categoriesTotalHeight + totalSpaceHeight;
140
+ const xUnitHeight = plotHeight / numberOfCategories;
141
+ const groupPadding = groupSpacing / 2 / xUnitHeight;
142
+ currentChart.series.forEach((series) => {
143
+ series.update({
144
+ groupPadding: groupPadding,
145
+ pointWidth: barHeight,
146
+ });
147
+ });
148
+ } else {
149
+ groupSpacing = 10;
150
+ categoriesTotalHeight = numberOfCategories * barHeight;
151
+ totalSpaceHeight = (numberOfCategories - 1) * groupSpacing;
152
+ }
153
+
154
+ config.xAxis.height = categoriesTotalHeight + totalSpaceHeight;
155
+ const totalHeight = currentChart.plotTop + config.xAxis.height + currentChart.marginBottom;
156
+ if (totalHeight !== currentChart.chartHeight) {
157
+ currentChart.setSize(null, totalHeight, false);
158
+ }
159
+
160
+ currentChart.redraw();
161
+ };
162
+ }
163
+
164
+ export default BarChart;
@@ -0,0 +1,21 @@
1
+ class ChartConstants {
2
+ static constants() {
3
+ const constants = {
4
+ primaryTheme: ['#206095', '#27a0cc', '#003c57', '#118c7b', '#a8bd3a', '#871a5b', '#f66068', '#746cb1', '#22d0b6'],
5
+ // Alternate theme colours from https://service-manual.ons.gov.uk/data-visualisation/colours/using-colours-in-charts
6
+ alternateTheme: ['#206095', '#27A0CC', '#871A5B', '#A8BD3A', '#F66068'],
7
+ labelColor: '#414042',
8
+ axisLabelColor: '#707071',
9
+ categoryLabelColor: '#414042',
10
+ gridLineColor: '#d9d9d9',
11
+ zeroLineColor: '#b3b3b3',
12
+ // Responsive font sizes
13
+ mobileFontSize: '0.75rem', // 12px
14
+ desktopFontSize: '0.875rem', // 14px
15
+ };
16
+
17
+ return constants;
18
+ }
19
+ }
20
+
21
+ export default ChartConstants;
@@ -0,0 +1,8 @@
1
+ import HighchartsBaseChart from './chart';
2
+ import domready from '../../js/domready';
3
+
4
+ domready(async () => {
5
+ [HighchartsBaseChart].forEach((Component) => {
6
+ document.querySelectorAll(Component.selector()).forEach((el) => new Component(el));
7
+ });
8
+ });
@@ -0,0 +1,242 @@
1
+ import Highcharts from 'highcharts';
2
+ import 'highcharts/modules/accessibility';
3
+ import 'highcharts/modules/annotations';
4
+
5
+ import CommonChartOptions from './common-chart-options';
6
+ import SpecificChartOptions from './specific-chart-options';
7
+ import LineChart from './line-chart';
8
+ import BarChart from './bar-chart';
9
+ import ColumnChart from './column-chart';
10
+ import AnnotationsOptions from './annotations-options';
11
+
12
+ class HighchartsBaseChart {
13
+ static selector() {
14
+ return '[data-highcharts-base-chart]';
15
+ }
16
+
17
+ constructor(node) {
18
+ this.node = node;
19
+ this.chartType = this.node.dataset.highchartsType;
20
+ this.theme = this.node.dataset.highchartsTheme;
21
+ const chartNode = this.node.querySelector('[data-highcharts-chart]');
22
+ this.id = this.node.dataset.highchartsId;
23
+ this.useStackedLayout = this.node.hasAttribute('data-highcharts-use-stacked-layout');
24
+ this.config = JSON.parse(this.node.querySelector(`[data-highcharts-config--${this.id}]`).textContent);
25
+ if (this.node.querySelector(`[data-highcharts-annotations--${this.id}]`)) {
26
+ const annotations = JSON.parse(this.node.querySelector(`[data-highcharts-annotations--${this.id}]`).textContent);
27
+ this.annotationsOptions = new AnnotationsOptions(annotations);
28
+ }
29
+ this.percentageHeightDesktop = this.node.dataset.highchartsPercentageHeightDesktop;
30
+ this.percentageHeightMobile = this.node.dataset.highchartsPercentageHeightMobile;
31
+ this.commonChartOptions = new CommonChartOptions();
32
+ this.specificChartOptions = new SpecificChartOptions(this.theme, this.chartType, this.config);
33
+ this.lineChart = new LineChart();
34
+ this.barChart = new BarChart();
35
+ this.columnChart = new ColumnChart();
36
+ this.extraLines = this.checkForExtraLines();
37
+ if (window.isCommonChartOptionsDefined === undefined) {
38
+ this.setCommonChartOptions();
39
+ window.isCommonChartOptionsDefined = true;
40
+ }
41
+ this.hideDataLabels = this.checkHideDataLabels();
42
+ this.setSpecificChartOptions();
43
+ this.setResponsiveOptions();
44
+ this.setLoadEvent();
45
+ this.setWindowResizeEvent();
46
+ this.chart = Highcharts.chart(chartNode, this.config);
47
+ }
48
+
49
+ // Check for the number of extra line series in the config
50
+ checkForExtraLines = () => {
51
+ return this.chartType === 'line' ? 0 : this.config.series.filter((series) => series.type === 'line').length;
52
+ };
53
+
54
+ // Set up the global Highcharts options which are used for all charts
55
+ setCommonChartOptions = () => {
56
+ const chartOptions = this.commonChartOptions.getOptions();
57
+ Highcharts.setOptions(chartOptions);
58
+ };
59
+
60
+ // Utility function to merge two configs together
61
+ mergeConfigs = (baseConfig, newConfig) => {
62
+ // If newConfig is null/undefined, return baseConfig
63
+ if (!newConfig) return baseConfig;
64
+
65
+ // Create a new object to store the merged result
66
+ const merged = { ...baseConfig };
67
+
68
+ // Iterate through all keys in newConfig
69
+ Object.keys(newConfig).forEach((key) => {
70
+ // Get values from both configs for this key
71
+ const baseValue = merged[key];
72
+ const newValue = newConfig[key];
73
+
74
+ // If both values are objects (and not null), recursively merge them
75
+ if (
76
+ baseValue &&
77
+ newValue &&
78
+ typeof baseValue === 'object' &&
79
+ typeof newValue === 'object' &&
80
+ !Array.isArray(baseValue) &&
81
+ !Array.isArray(newValue)
82
+ ) {
83
+ merged[key] = this.mergeConfigs(baseValue, newValue);
84
+ } else {
85
+ // For non-objects and arrays use the new value
86
+ // If the new value is null/undefined, use the base value
87
+ merged[key] = newValue ?? baseValue;
88
+ }
89
+ });
90
+
91
+ return merged;
92
+ };
93
+
94
+ // Set up options for specific charts and chart types
95
+ setSpecificChartOptions = () => {
96
+ const specificChartOptions = this.specificChartOptions.getOptions();
97
+ const lineChartOptions = this.lineChart.getLineChartOptions();
98
+ const barChartOptions = this.barChart.getBarChartOptions(this.useStackedLayout);
99
+ const columnChartOptions = this.columnChart.getColumnChartOptions(this.useStackedLayout);
100
+ // Merge specificChartOptions with the existing config
101
+ this.config = this.mergeConfigs(this.config, specificChartOptions);
102
+
103
+ if (this.chartType === 'line') {
104
+ // Merge the line chart options with the existing config
105
+ this.config = this.mergeConfigs(this.config, lineChartOptions);
106
+ }
107
+
108
+ if (this.chartType === 'bar') {
109
+ // Merge the bar chart options with the existing config
110
+ this.config = this.mergeConfigs(this.config, barChartOptions);
111
+ }
112
+ if (this.chartType === 'column') {
113
+ // Merge the column chart options with the existing config
114
+ this.config = this.mergeConfigs(this.config, columnChartOptions);
115
+ }
116
+
117
+ if (this.extraLines > 0) {
118
+ this.config = this.mergeConfigs(this.config, this.lineChart.getLineChartOptions());
119
+ if (this.chartType === 'column') {
120
+ this.config = this.mergeConfigs(this.config, columnChartOptions);
121
+ }
122
+ if (this.chartType === 'bar') {
123
+ this.config = this.mergeConfigs(this.config, barChartOptions);
124
+ }
125
+ }
126
+
127
+ // Disable the legend for single series charts
128
+ this.commonChartOptions.disableLegendForSingleSeries(this.config);
129
+ };
130
+
131
+ // Check if the data labels should be hidden
132
+ // They should be hidden for clustered bar charts with more than 2 series, and also for stacked bar charts
133
+ checkHideDataLabels = () => {
134
+ return (this.chartType === 'bar' && this.config.series.length > 2) || this.useStackedLayout === true;
135
+ };
136
+
137
+ // Adjust font size and annotations for smaller width of chart
138
+ // Note this is not the same as the viewport width
139
+ // All responsive rules should be defined here to avoid overriding existing rules
140
+ setResponsiveOptions = () => {
141
+ const mobileCommonChartOptions = this.commonChartOptions.getMobileOptions();
142
+ if (!this.config.responsive) {
143
+ this.config.responsive = {};
144
+ }
145
+ // If these conditions change, the styling for the footnotes container query in _chart.scss needs to be updated
146
+ let rules = [
147
+ {
148
+ condition: {
149
+ maxWidth: 400,
150
+ },
151
+ chartOptions: {
152
+ ...mobileCommonChartOptions,
153
+ },
154
+ },
155
+ // We are using a slightly wider breakpoint for annotations
156
+ // to try and reduce the likelihood of them being automatically
157
+ // hidden by Highcharts
158
+ {
159
+ condition: {
160
+ maxWidth: 600,
161
+ },
162
+ chartOptions: {
163
+ annotations: this.annotationsOptions ? this.annotationsOptions.getAnnotationsOptionsMobile() : undefined,
164
+ },
165
+ },
166
+ {
167
+ condition: {
168
+ minWidth: 601,
169
+ },
170
+ chartOptions: {
171
+ annotations: this.annotationsOptions ? this.annotationsOptions.getAnnotationsOptionsDesktop() : undefined,
172
+ },
173
+ },
174
+ ];
175
+ this.config.responsive.rules = rules;
176
+ };
177
+
178
+ // Create the load event for various chart types
179
+ // All load events should be defined here to avoid overriding existing events
180
+ setLoadEvent = () => {
181
+ if (!this.config.chart.events) {
182
+ this.config.chart.events = {};
183
+ }
184
+ this.config.chart.events.load = (event) => {
185
+ const currentChart = event.target;
186
+ if (this.chartType === 'line') {
187
+ this.lineChart.updateLastPointMarker(currentChart.series);
188
+ this.commonChartOptions.hideDataLabels(currentChart.series);
189
+ }
190
+ if (this.chartType === 'bar') {
191
+ this.barChart.updateBarChartHeight(this.config, currentChart, this.useStackedLayout, this.extraLines);
192
+ if (!this.hideDataLabels) {
193
+ this.barChart.postLoadDataLabels(currentChart);
194
+ } else {
195
+ this.commonChartOptions.hideDataLabels(currentChart.series);
196
+ }
197
+ }
198
+ if (this.chartType === 'column') {
199
+ this.columnChart.updatePointPadding(this.config, currentChart, this.useStackedLayout, this.extraLines);
200
+ this.commonChartOptions.hideDataLabels(currentChart.series);
201
+ }
202
+ if (this.chartType != 'bar') {
203
+ this.commonChartOptions.adjustChartHeight(currentChart, this.percentageHeightDesktop, this.percentageHeightMobile);
204
+ }
205
+
206
+ // If the chart has an extra line or lines, hide the data labels for
207
+ // that series, update the last point marker
208
+ if (this.extraLines > 0) {
209
+ currentChart.series.forEach((series) => {
210
+ if (series.type === 'line') {
211
+ this.lineChart.updateLastPointMarker([series]);
212
+ this.commonChartOptions.hideDataLabels([series]);
213
+ }
214
+ });
215
+ }
216
+ // Update the legend items for all charts
217
+ this.commonChartOptions.updateLegendSymbols(currentChart);
218
+ currentChart.redraw(false);
219
+ };
220
+ };
221
+
222
+ // Set resize events - throttled to 50ms
223
+ // All resize events should be defined here to avoid overriding existing events
224
+ setWindowResizeEvent = () => {
225
+ window.addEventListener('resize', () => {
226
+ clearTimeout(this.resizeTimeout);
227
+ this.resizeTimeout = setTimeout(() => {
228
+ // Get the current rendered chart instance
229
+ const currentChart = Highcharts.charts.find((chart) => chart && chart.container === this.chart.container);
230
+ // Update the data labels when the window is resized
231
+ if (this.chartType === 'bar' && !this.hideDataLabels) {
232
+ this.barChart.postLoadDataLabels(currentChart);
233
+ }
234
+ if (this.chartType != 'bar') {
235
+ this.commonChartOptions.adjustChartHeight(currentChart, this.percentageHeightDesktop, this.percentageHeightMobile);
236
+ }
237
+ }, 50);
238
+ });
239
+ };
240
+ }
241
+
242
+ 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, numberOfExtraLines) => {
22
+ const numberOfCategories = config.xAxis.categories.length;
23
+ const numberOfSeries = currentChart.series.length - numberOfExtraLines; // Get number of column 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;