@ons/design-system 72.10.6 → 72.10.8
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/char-check-limit/_macro.njk +5 -4
- package/components/char-check-limit/_macro.spec.js +167 -7
- package/components/char-check-limit/character-check.js +23 -17
- package/components/char-check-limit/character-check.spec.js +106 -1
- package/components/chart/_chart.scss +39 -5
- package/components/chart/_macro.njk +190 -152
- package/components/chart/_macro.spec.js +274 -21
- package/components/chart/annotations-options.js +1 -1
- package/components/chart/bar-chart.js +2 -0
- package/components/chart/chart-iframe-resize.dom.js +8 -0
- package/components/chart/chart-iframe-resize.js +16 -0
- package/components/chart/chart.dom.js +5 -3
- package/components/chart/chart.js +13 -2
- package/components/chart/example-area-chart.njk +2 -1
- package/components/chart/example-bar-chart.njk +4 -0
- package/components/chart/example-iframe-chart.njk +33 -0
- package/components/chart/example-line-chart-with-annotations.njk +3 -1
- package/components/chart/example-line-chart.njk +6 -1
- package/components/chart/example-scatter-chart.njk +4 -0
- package/components/chart/range-annotations-options.js +1 -1
- package/components/chart/reference-line-annotations-options.js +1 -1
- package/components/checkboxes/_macro.spec.js +3 -3
- package/components/input/_macro.njk +1 -2
- package/components/input/_macro.spec.js +2 -22
- package/components/input/example-input-search-with-character-check.njk +0 -1
- package/components/tabs/tabs.js +2 -2
- package/components/textarea/_macro.njk +19 -3
- package/components/textarea/_macro.spec.js +76 -3
- package/components/textarea/example-textarea-with-word-limit.njk +20 -0
- package/css/main.css +1 -1
- package/img/small/area-chart-screenshot.png +0 -0
- package/img/small/line-chart-screenshot.png +0 -0
- package/js/main.js +2 -0
- package/layout/_template.njk +4 -1
- package/package.json +6 -3
- package/scripts/main.es5.js +3 -1
- package/scripts/main.js +3 -1
- package/scss/objects/_page.scss +1 -1
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
EXAMPLE_LINE_CHART_WITH_RANGE_ANNOTATION_WITH_LABEL_INSIDE_PARAMS,
|
|
26
26
|
EXAMPLE_LINE_CHART_WITH_REFERENCE_LINE_ANNOTATIONS_PARAMS,
|
|
27
27
|
EXAMPLE_LINE_CHART_WITH_MIXED_ANNOTATION_TYPES_PARAMS,
|
|
28
|
+
EXAMPLE_IFRAME_CHART_PARAMS,
|
|
28
29
|
} from './_test-examples';
|
|
29
30
|
|
|
30
31
|
describe('Macro: Chart', () => {
|
|
@@ -192,6 +193,52 @@ describe('Macro: Chart', () => {
|
|
|
192
193
|
});
|
|
193
194
|
});
|
|
194
195
|
|
|
196
|
+
describe('GIVEN: Params: fallbackImageUrl', () => {
|
|
197
|
+
describe('WHEN: fallbackImageUrl is provided', () => {
|
|
198
|
+
const $ = cheerio.load(
|
|
199
|
+
renderComponent('chart', {
|
|
200
|
+
...EXAMPLE_LINE_CHART_WITH_CONFIG_PARAMS,
|
|
201
|
+
fallbackImageUrl: '/img/small/line-chart-screenshot.png',
|
|
202
|
+
}),
|
|
203
|
+
);
|
|
204
|
+
const noScriptFallbackImage = $(`#fallback-image--chart-456`).html();
|
|
205
|
+
test('THEN: it renders the fallback image', () => {
|
|
206
|
+
expect(noScriptFallbackImage).toContain('/img/small/line-chart-screenshot.png');
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe('GIVEN: Params: fallbackImageAlt', () => {
|
|
212
|
+
describe('WHEN: fallbackImageAlt is provided', () => {
|
|
213
|
+
const $ = cheerio.load(
|
|
214
|
+
renderComponent('chart', {
|
|
215
|
+
...EXAMPLE_LINE_CHART_WITH_CONFIG_PARAMS,
|
|
216
|
+
fallbackImageUrl: '/img/small/line-chart-screenshot.png',
|
|
217
|
+
fallbackImageAlt: 'A description of the fallback image for screen readers',
|
|
218
|
+
}),
|
|
219
|
+
);
|
|
220
|
+
const noScriptFallbackImage = $(`#fallback-image--chart-456`).html();
|
|
221
|
+
test('THEN: it renders the customised fallback image alt text', () => {
|
|
222
|
+
expect(noScriptFallbackImage).toContain('alt="A description of the fallback image for screen readers"');
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
describe('GIVEN: Params: no fallbackImageAlt', () => {
|
|
228
|
+
describe('WHEN: fallbackImageAlt is not provided', () => {
|
|
229
|
+
const $ = cheerio.load(
|
|
230
|
+
renderComponent('chart', {
|
|
231
|
+
...EXAMPLE_LINE_CHART_WITH_CONFIG_PARAMS,
|
|
232
|
+
fallbackImageUrl: '/img/small/line-chart-screenshot.png',
|
|
233
|
+
}),
|
|
234
|
+
);
|
|
235
|
+
const noScriptFallbackImage = $(`#fallback-image--chart-456`).html();
|
|
236
|
+
test('THEN: it renders the default fallback image alt text', () => {
|
|
237
|
+
expect(noScriptFallbackImage).toContain('alt="Fallback image for the chart as JavaScript is disabled"');
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
195
242
|
describe('GIVEN: Params: Caption', () => {
|
|
196
243
|
describe('WHEN: caption is provided', () => {
|
|
197
244
|
const $ = cheerio.load(
|
|
@@ -628,14 +675,14 @@ describe('Macro: Chart', () => {
|
|
|
628
675
|
});
|
|
629
676
|
|
|
630
677
|
test('THEN: it renders the footnotes', () => {
|
|
631
|
-
expect($('.ons-
|
|
632
|
-
expect($('.ons-
|
|
633
|
-
expect($('.ons-
|
|
634
|
-
expect($('.ons-
|
|
678
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('1');
|
|
679
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('A test annotation');
|
|
680
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('2');
|
|
681
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('Another test annotation');
|
|
635
682
|
});
|
|
636
683
|
|
|
637
684
|
test('THEN: the footnotes are hidden from screen readers', () => {
|
|
638
|
-
expect($('.ons-
|
|
685
|
+
expect($('.ons-chart__annotations-footnotes').attr('aria-hidden')).toBe('true');
|
|
639
686
|
});
|
|
640
687
|
|
|
641
688
|
test('THEN: it includes the Annotations JSON config', () => {
|
|
@@ -658,12 +705,12 @@ describe('Macro: Chart', () => {
|
|
|
658
705
|
});
|
|
659
706
|
|
|
660
707
|
test('THEN: it renders the footnotes', () => {
|
|
661
|
-
expect($('.ons-
|
|
662
|
-
expect($('.ons-
|
|
708
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('1');
|
|
709
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('A test annotation');
|
|
663
710
|
});
|
|
664
711
|
|
|
665
712
|
test('THEN: the footnotes are hidden from screen readers', () => {
|
|
666
|
-
expect($('.ons-
|
|
713
|
+
expect($('.ons-chart__annotations-footnotes').attr('aria-hidden')).toBe('true');
|
|
667
714
|
});
|
|
668
715
|
|
|
669
716
|
test('THEN: it includes the Annotations JSON config', () => {
|
|
@@ -687,12 +734,12 @@ describe('Macro: Chart', () => {
|
|
|
687
734
|
});
|
|
688
735
|
|
|
689
736
|
test('THEN: it renders the footnotes', () => {
|
|
690
|
-
expect($('.ons-
|
|
691
|
-
expect($('.ons-
|
|
737
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('1');
|
|
738
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('A test annotation');
|
|
692
739
|
});
|
|
693
740
|
|
|
694
741
|
test('THEN: the footnotes are hidden from screen readers', () => {
|
|
695
|
-
expect($('.ons-
|
|
742
|
+
expect($('.ons-chart__annotations-footnotes').attr('aria-hidden')).toBe('true');
|
|
696
743
|
});
|
|
697
744
|
|
|
698
745
|
test('THEN: it includes the Annotations JSON config', () => {
|
|
@@ -977,6 +1024,26 @@ describe('Macro: Chart', () => {
|
|
|
977
1024
|
});
|
|
978
1025
|
});
|
|
979
1026
|
});
|
|
1027
|
+
|
|
1028
|
+
describe('GIVEN: Params: Footnotes', () => {
|
|
1029
|
+
describe('WHEN: footnotes are provided', () => {
|
|
1030
|
+
const $ = cheerio.load(
|
|
1031
|
+
renderComponent('chart', {
|
|
1032
|
+
...EXAMPLE_AREA_CHART_PARAMS,
|
|
1033
|
+
footnotes: {
|
|
1034
|
+
title: 'Footnotes',
|
|
1035
|
+
content:
|
|
1036
|
+
'<ol><li>Non-store retailing refers to retailers that do not have a store presence. While the majority is made up of online retailers, it also includes other retailers, such as stalls and markets.</li><li>More data are available in our Retail Sales Index datasets.</li></ol>',
|
|
1037
|
+
},
|
|
1038
|
+
}),
|
|
1039
|
+
);
|
|
1040
|
+
test('THEN: it renders the footnotes', () => {
|
|
1041
|
+
expect($('#footnotes--area-chart-123').length).toBe(1);
|
|
1042
|
+
expect($('#footnotes--area-chart-123').find('ol').length).toBe(1);
|
|
1043
|
+
expect($('#footnotes--area-chart-123').text()).toContain('Footnotes');
|
|
1044
|
+
});
|
|
1045
|
+
});
|
|
1046
|
+
});
|
|
980
1047
|
});
|
|
981
1048
|
|
|
982
1049
|
describe('FOR: Boxplot Chart', () => {
|
|
@@ -1304,16 +1371,16 @@ describe('Macro: Chart', () => {
|
|
|
1304
1371
|
});
|
|
1305
1372
|
|
|
1306
1373
|
test('THEN: it renders the footnotes sequentially', () => {
|
|
1307
|
-
expect($('.ons-
|
|
1308
|
-
expect($('.ons-
|
|
1309
|
-
expect($('.ons-
|
|
1310
|
-
expect($('.ons-
|
|
1311
|
-
expect($('.ons-
|
|
1312
|
-
expect($('.ons-
|
|
1313
|
-
expect($('.ons-
|
|
1314
|
-
expect($('.ons-
|
|
1315
|
-
expect($('.ons-
|
|
1316
|
-
expect($('.ons-
|
|
1374
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('1');
|
|
1375
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('A test point annotation');
|
|
1376
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('2');
|
|
1377
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('A test x axis range annotation');
|
|
1378
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('3');
|
|
1379
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('A test y axis range annotation with the label inside');
|
|
1380
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('4');
|
|
1381
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('A test x axis reference line annotation');
|
|
1382
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('5');
|
|
1383
|
+
expect($('.ons-chart__annotations-footnotes').text()).toContain('A test y axis reference line annotation');
|
|
1317
1384
|
});
|
|
1318
1385
|
});
|
|
1319
1386
|
});
|
|
@@ -1456,4 +1523,190 @@ describe('Macro: Chart', () => {
|
|
|
1456
1523
|
});
|
|
1457
1524
|
});
|
|
1458
1525
|
});
|
|
1526
|
+
|
|
1527
|
+
describe('FOR: Iframe chart', () => {
|
|
1528
|
+
describe('GIVEN: Params: Iframe chart', () => {
|
|
1529
|
+
describe('WHEN: an iframe url param is provided', () => {
|
|
1530
|
+
const $ = cheerio.load(renderComponent('chart', EXAMPLE_IFRAME_CHART_PARAMS));
|
|
1531
|
+
|
|
1532
|
+
test('THEN: it passes jest-axe checks', async () => {
|
|
1533
|
+
const results = await axe($.html());
|
|
1534
|
+
expect(results).toHaveNoViolations();
|
|
1535
|
+
});
|
|
1536
|
+
|
|
1537
|
+
test('THEN: it renders the iframe', () => {
|
|
1538
|
+
expect($('.ons-chart__iframe-wrapper').length).toBe(1);
|
|
1539
|
+
});
|
|
1540
|
+
|
|
1541
|
+
test('THEN: it includes the iframe title as a data attribute', () => {
|
|
1542
|
+
const iframe = $('.ons-chart__iframe-wrapper');
|
|
1543
|
+
expect(iframe.attr('data-title')).toBe(EXAMPLE_IFRAME_CHART_PARAMS.title);
|
|
1544
|
+
});
|
|
1545
|
+
|
|
1546
|
+
test('THEN: the theme parameter is ignored', () => {
|
|
1547
|
+
const $ = cheerio.load(
|
|
1548
|
+
renderComponent('chart', {
|
|
1549
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1550
|
+
theme: 'secondary',
|
|
1551
|
+
}),
|
|
1552
|
+
);
|
|
1553
|
+
|
|
1554
|
+
expect($('[data-highcharts-theme]').length).toBe(0);
|
|
1555
|
+
});
|
|
1556
|
+
|
|
1557
|
+
test('THEN: the percentageHeightDesktop and percentageHeightMobile parameters are ignored', () => {
|
|
1558
|
+
const $ = cheerio.load(
|
|
1559
|
+
renderComponent('chart', {
|
|
1560
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1561
|
+
percentageHeightDesktop: 50,
|
|
1562
|
+
percentageHeightMobile: 10,
|
|
1563
|
+
}),
|
|
1564
|
+
);
|
|
1565
|
+
|
|
1566
|
+
expect($('[data-highcharts-percentage-height-desktop]').length).toBe(0);
|
|
1567
|
+
expect($('[data-highcharts-percentage-height-mobile]').length).toBe(0);
|
|
1568
|
+
});
|
|
1569
|
+
|
|
1570
|
+
test('THEN: the tickIntervalDesktop and tickIntervalMobile parameters are ignored', () => {
|
|
1571
|
+
const $ = cheerio.load(
|
|
1572
|
+
renderComponent('chart', {
|
|
1573
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1574
|
+
xAxis: {
|
|
1575
|
+
tickIntervalDesktop: 10,
|
|
1576
|
+
tickIntervalMobile: 5,
|
|
1577
|
+
},
|
|
1578
|
+
yAxis: {
|
|
1579
|
+
tickIntervalDesktop: 10,
|
|
1580
|
+
tickIntervalMobile: 5,
|
|
1581
|
+
},
|
|
1582
|
+
}),
|
|
1583
|
+
);
|
|
1584
|
+
|
|
1585
|
+
expect($('[data-highcharts-x-axis-tick-interval-desktop]').length).toBe(0);
|
|
1586
|
+
expect($('[data-highcharts-x-axis-tick-interval-mobile]').length).toBe(0);
|
|
1587
|
+
expect($('[data-highcharts-y-axis-tick-interval-desktop]').length).toBe(0);
|
|
1588
|
+
expect($('[data-highcharts-y-axis-tick-interval-mobile]').length).toBe(0);
|
|
1589
|
+
});
|
|
1590
|
+
|
|
1591
|
+
test('THEN: the tickIntervalDesktop and tickIntervalMobile parameters are ignored', () => {
|
|
1592
|
+
const $ = cheerio.load(
|
|
1593
|
+
renderComponent('chart', {
|
|
1594
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1595
|
+
estimateLineLabel: 'Estimated value',
|
|
1596
|
+
uncertaintyRangeLabel: '95% Confidence Interval',
|
|
1597
|
+
}),
|
|
1598
|
+
);
|
|
1599
|
+
|
|
1600
|
+
expect($('[data-highcharts-estimate-line-label]').length).toBe(0);
|
|
1601
|
+
expect($('[data-highcharts-uncertainty-range-label]').length).toBe(0);
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
test('THEN: the customReferenceLineValue parameter is ignored', () => {
|
|
1605
|
+
const $ = cheerio.load(
|
|
1606
|
+
renderComponent('chart', {
|
|
1607
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1608
|
+
yAxis: {
|
|
1609
|
+
customReferenceLineValue: 10,
|
|
1610
|
+
},
|
|
1611
|
+
}),
|
|
1612
|
+
);
|
|
1613
|
+
|
|
1614
|
+
expect($('[data-highcharts-custom-reference-line-value]').length).toBe(0);
|
|
1615
|
+
});
|
|
1616
|
+
|
|
1617
|
+
test('THEN: the legend for boxplot charts is not rendered', () => {
|
|
1618
|
+
const $ = cheerio.load(
|
|
1619
|
+
renderComponent('chart', {
|
|
1620
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1621
|
+
chartType: 'boxplot',
|
|
1622
|
+
legend: true,
|
|
1623
|
+
estimateLineLabel: 'Estimated value',
|
|
1624
|
+
uncertaintyRangeLabel: '95% Confidence Interval',
|
|
1625
|
+
}),
|
|
1626
|
+
);
|
|
1627
|
+
|
|
1628
|
+
expect($('.ons-chart__boxplot-legend').length).toBe(0);
|
|
1629
|
+
});
|
|
1630
|
+
|
|
1631
|
+
test('THEN: the Highcharts config is not included', () => {
|
|
1632
|
+
const configScript = $(`script[data-highcharts-config--iframe-chart-123]`).html();
|
|
1633
|
+
expect(configScript).toBeNull();
|
|
1634
|
+
});
|
|
1635
|
+
|
|
1636
|
+
test('THEN: the annotations footnotes and scripts are not rendered', () => {
|
|
1637
|
+
const $ = cheerio.load(
|
|
1638
|
+
renderComponent('chart', {
|
|
1639
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1640
|
+
annotations: [
|
|
1641
|
+
{
|
|
1642
|
+
text: 'A test point annotation',
|
|
1643
|
+
point: { x: 2, y: 3 },
|
|
1644
|
+
labelOffsetX: 10,
|
|
1645
|
+
labelOffsetY: -50,
|
|
1646
|
+
},
|
|
1647
|
+
],
|
|
1648
|
+
rangeAnnotations: [
|
|
1649
|
+
{
|
|
1650
|
+
text: 'A test x axis range annotation',
|
|
1651
|
+
range: { axisValue1: 10, axisValue2: 15 },
|
|
1652
|
+
axis: 'x',
|
|
1653
|
+
labelOffsetX: 150,
|
|
1654
|
+
labelOffsetY: 0,
|
|
1655
|
+
},
|
|
1656
|
+
{
|
|
1657
|
+
text: 'A test y axis range annotation with the label inside',
|
|
1658
|
+
range: { axisValue1: 5, axisValue2: 10 },
|
|
1659
|
+
axis: 'y',
|
|
1660
|
+
labelInside: true,
|
|
1661
|
+
labelWidth: 250,
|
|
1662
|
+
},
|
|
1663
|
+
],
|
|
1664
|
+
referenceLineAnnotations: [
|
|
1665
|
+
{
|
|
1666
|
+
text: 'A test x axis reference line annotation',
|
|
1667
|
+
value: 34,
|
|
1668
|
+
axis: 'x',
|
|
1669
|
+
},
|
|
1670
|
+
{
|
|
1671
|
+
text: 'A test y axis reference line annotation',
|
|
1672
|
+
value: 12,
|
|
1673
|
+
axis: 'y',
|
|
1674
|
+
labelWidth: 100,
|
|
1675
|
+
},
|
|
1676
|
+
],
|
|
1677
|
+
}),
|
|
1678
|
+
);
|
|
1679
|
+
|
|
1680
|
+
expect($('[data-annotations-footnotes]').length).toBe(0);
|
|
1681
|
+
expect($('[data-highcharts-annotations--iframe-chart-123]').length).toBe(0);
|
|
1682
|
+
expect($('[data-highcharts-range-annotations--iframe-chart-123]').length).toBe(0);
|
|
1683
|
+
expect($('[data-highcharts-reference-line-annotations--iframe-chart-123]').length).toBe(0);
|
|
1684
|
+
});
|
|
1685
|
+
|
|
1686
|
+
test('THEN: invalid chart type is ignored', () => {
|
|
1687
|
+
const $ = cheerio.load(
|
|
1688
|
+
renderComponent('chart', {
|
|
1689
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1690
|
+
chartType: 'foobar',
|
|
1691
|
+
}),
|
|
1692
|
+
);
|
|
1693
|
+
|
|
1694
|
+
expect($('[data-invalid-chart-type]').length).toBe(0);
|
|
1695
|
+
});
|
|
1696
|
+
});
|
|
1697
|
+
|
|
1698
|
+
describe('WHEN: Params: fallbackImageUrl is set', () => {
|
|
1699
|
+
const $ = cheerio.load(
|
|
1700
|
+
renderComponent('chart', {
|
|
1701
|
+
...EXAMPLE_IFRAME_CHART_PARAMS,
|
|
1702
|
+
fallbackImageUrl: '/img/small/line-chart-screenshot.png',
|
|
1703
|
+
}),
|
|
1704
|
+
);
|
|
1705
|
+
const iframe = $(`.ons-chart__iframe-wrapper`);
|
|
1706
|
+
test('THEN: the iframe is hidden when JavaScript is disabled', () => {
|
|
1707
|
+
expect(iframe.attr('class')).toContain('ons-chart__non-js-hide');
|
|
1708
|
+
});
|
|
1709
|
+
});
|
|
1710
|
+
});
|
|
1711
|
+
});
|
|
1459
1712
|
});
|
|
@@ -49,7 +49,7 @@ class AnnotationsOptions {
|
|
|
49
49
|
borderColor: 'transparent',
|
|
50
50
|
// We use css styling for the rounded number annotation at mobile
|
|
51
51
|
useHTML: true,
|
|
52
|
-
className: 'ons-
|
|
52
|
+
className: 'ons-chart__annotations-footnotes-number',
|
|
53
53
|
},
|
|
54
54
|
draggable: '',
|
|
55
55
|
},
|
|
@@ -38,6 +38,7 @@ class BarChart {
|
|
|
38
38
|
// Update the category label colours for bar charts
|
|
39
39
|
labels: {
|
|
40
40
|
style: {
|
|
41
|
+
textOverflow: 'ellipsis',
|
|
41
42
|
color: this.constants.categoryLabelColor,
|
|
42
43
|
},
|
|
43
44
|
useHTML: false,
|
|
@@ -70,6 +71,7 @@ class BarChart {
|
|
|
70
71
|
};
|
|
71
72
|
|
|
72
73
|
// Updates the config to move the data labels inside the bars, but only if the bar is wide enough
|
|
74
|
+
// See the checkHideDataLabels function in chart.js for more details about when this function is run
|
|
73
75
|
// This also runs when the chart is resized
|
|
74
76
|
postLoadDataLabels = (currentChart) => {
|
|
75
77
|
const insideOptions = this.getBarChartLabelsInsideOptions();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import ChartIframeResize from './chart-iframe-resize';
|
|
2
|
+
import domready from '../../js/domready';
|
|
3
|
+
|
|
4
|
+
domready(async () => {
|
|
5
|
+
[ChartIframeResize].forEach((Component) => {
|
|
6
|
+
document.querySelectorAll(Component.selector()).forEach((el) => new Component(el));
|
|
7
|
+
});
|
|
8
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import pym from 'pym.js';
|
|
2
|
+
|
|
3
|
+
class ChartIframeResize {
|
|
4
|
+
static selector() {
|
|
5
|
+
return '.ons-chart__iframe-wrapper';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
constructor(node) {
|
|
9
|
+
this.node = node;
|
|
10
|
+
new pym.Parent(this.node.getAttribute('id'), this.node.dataset.url, {
|
|
11
|
+
title: this.node.dataset.title,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default ChartIframeResize;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import HighchartsBaseChart from './chart';
|
|
2
2
|
import domready from '../../js/domready';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
document.fonts.ready.then(() => {
|
|
5
|
+
domready(async () => {
|
|
6
|
+
[HighchartsBaseChart].forEach((Component) => {
|
|
7
|
+
document.querySelectorAll(Component.selector()).forEach((el) => new Component(el));
|
|
8
|
+
});
|
|
7
9
|
});
|
|
8
10
|
});
|
|
@@ -31,6 +31,11 @@ class HighchartsBaseChart {
|
|
|
31
31
|
console.error('No chart node found');
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
// Add a CSS class to the chart based on the chart type (e.g., 'bar-chart-container', 'line-chart-container')
|
|
36
|
+
// This allows type-specific styling in CSS.
|
|
37
|
+
chartNode.classList.add(`${this.chartType}-chart-container`);
|
|
38
|
+
|
|
34
39
|
this.id = this.node.dataset.highchartsId;
|
|
35
40
|
this.useStackedLayout = this.node.hasAttribute('data-highcharts-use-stacked-layout');
|
|
36
41
|
this.config = JSON.parse(this.node.querySelector(`[data-highcharts-config--${this.id}]`).textContent);
|
|
@@ -187,9 +192,15 @@ class HighchartsBaseChart {
|
|
|
187
192
|
};
|
|
188
193
|
|
|
189
194
|
// Check if the data labels should be hidden
|
|
190
|
-
// They should be hidden for clustered bar charts with more than 2 series, and also for stacked bar charts
|
|
195
|
+
// They should be hidden where there are more than 20 data points in a series, for clustered bar charts with more than 2 series, and also for stacked bar charts
|
|
191
196
|
checkHideDataLabels = () => {
|
|
192
|
-
|
|
197
|
+
let hideDataLabels = (this.chartType === 'bar' && this.config.series.length > 2) || this.useStackedLayout === true;
|
|
198
|
+
this.config.series.forEach((series) => {
|
|
199
|
+
if (series.data.length > 20) {
|
|
200
|
+
hideDataLabels = true;
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
return hideDataLabels;
|
|
193
204
|
};
|
|
194
205
|
|
|
195
206
|
// Adjust font size and annotations for smaller width of chart
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
}
|
|
27
27
|
]
|
|
28
28
|
},
|
|
29
|
+
"footnotes": {
|
|
30
|
+
"title": "Footnotes",
|
|
31
|
+
"content": "<ol><li>Non-store retailing refers to retailers that do not have a store presence. While the majority is made up of online retailers, it also includes other retailers, such as stalls and markets.</li><li>More data are available in our Retail Sales Index datasets.</li></ol>"
|
|
32
|
+
},
|
|
29
33
|
"xAxis": {
|
|
30
34
|
"categories": [
|
|
31
35
|
"All retailing",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{% from "components/chart/_macro.njk" import onsChart %}
|
|
2
|
+
|
|
3
|
+
{# Important note: the example visualisation used here by the iframeUrl parameter
|
|
4
|
+
may not be available in the future once Florence is decommissioned. #}
|
|
5
|
+
|
|
6
|
+
{{
|
|
7
|
+
onsChart({
|
|
8
|
+
"description": "Volume sales, seasonally adjusted, Great Britain, January 2022 to January 2025",
|
|
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
|
+
"iframeUrl": "https://www.ons.gov.uk/visualisations/dvc3294/fig01/index.html",
|
|
31
|
+
"fallbackImageUrl": "/img/small/line-chart-screenshot.png"
|
|
32
|
+
})
|
|
33
|
+
}}
|
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
"url": "#"
|
|
28
28
|
}
|
|
29
29
|
]},
|
|
30
|
+
"footnotes": {
|
|
31
|
+
"title": "Footnotes",
|
|
32
|
+
"content": "<ol><li>Non-store retailing refers to retailers that do not have a store presence. While the majority is made up of online retailers, it also includes other retailers, such as stalls and markets.</li><li>More data are available in our Retail Sales Index datasets.</li></ol>"
|
|
33
|
+
},
|
|
30
34
|
"legend": true,
|
|
31
35
|
"xAxis": {
|
|
32
36
|
"title": "Year",
|
|
@@ -218,6 +222,7 @@
|
|
|
218
222
|
}
|
|
219
223
|
],
|
|
220
224
|
"percentageHeightDesktop": 35,
|
|
221
|
-
"percentageHeightMobile": 90
|
|
225
|
+
"percentageHeightMobile": 90,
|
|
226
|
+
"fallbackImageUrl": '/img/small/line-chart-screenshot.png'
|
|
222
227
|
})
|
|
223
228
|
}}
|
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
"url": "#"
|
|
28
28
|
}
|
|
29
29
|
]},
|
|
30
|
+
"footnotes": {
|
|
31
|
+
"title": "Footnotes",
|
|
32
|
+
"content": "<ol><li>Non-store retailing refers to retailers that do not have a store presence. While the majority is made up of online retailers, it also includes other retailers, such as stalls and markets.</li><li>More data are available in our Retail Sales Index datasets.</li></ol>"
|
|
33
|
+
},
|
|
30
34
|
"xAxis": {
|
|
31
35
|
"title": "Height"
|
|
32
36
|
},
|
|
@@ -65,7 +65,7 @@ class RangeAnnotationsOptions {
|
|
|
65
65
|
// So that if we have both types of annotations, the numbers will be sequential
|
|
66
66
|
text: `${annotationsLength + index + 1}`,
|
|
67
67
|
useHTML: true,
|
|
68
|
-
className: 'ons-
|
|
68
|
+
className: 'ons-chart__annotations-footnotes-number',
|
|
69
69
|
allowOverlap: true,
|
|
70
70
|
style: {
|
|
71
71
|
color: this.constants.labelColor,
|
|
@@ -58,7 +58,7 @@ class ReferenceLineAnnotationsOptions {
|
|
|
58
58
|
// So that if we have more than one type of annotations, the numbers will be sequential
|
|
59
59
|
text: `${annotationsLength + index + 1}`,
|
|
60
60
|
useHTML: true,
|
|
61
|
-
className: 'ons-
|
|
61
|
+
className: 'ons-chart__annotations-footnotes-number',
|
|
62
62
|
allowOverlap: true,
|
|
63
63
|
style: {
|
|
64
64
|
color: this.constants.labelColor,
|
|
@@ -164,9 +164,9 @@ describe('macro: checkboxes', () => {
|
|
|
164
164
|
it('renders the text area with expected parameters', () => {
|
|
165
165
|
const $ = cheerio.load(renderComponent('checkboxes', EXAMPLE_CHECKBOX_ITEM_CHECKBOXES_WITH_TEXTAREA));
|
|
166
166
|
expect($('.ons-input--textarea').attr('name')).toBe('other answer');
|
|
167
|
-
expect($('.ons-input--textarea').attr('data-
|
|
168
|
-
expect($('.ons-input__limit').attr('data-
|
|
169
|
-
expect($('.ons-input__limit').attr('data-
|
|
167
|
+
expect($('.ons-input--textarea').attr('data-message-check-num')).toBe('300');
|
|
168
|
+
expect($('.ons-input__limit').attr('data-message-singular')).toBe('You have {x} character remaining');
|
|
169
|
+
expect($('.ons-input__limit').attr('data-message-plural')).toBe('You have {x} characters remaining');
|
|
170
170
|
});
|
|
171
171
|
});
|
|
172
172
|
|
|
@@ -44,10 +44,9 @@
|
|
|
44
44
|
{% if params.autocomplete %}autocomplete="{{ params.autocomplete }}"{% endif %}
|
|
45
45
|
{% if params.accessiblePlaceholder %}placeholder="{{ params.label.text }}"{% endif %}
|
|
46
46
|
{% if params.charCheckLimit %}
|
|
47
|
-
data-
|
|
47
|
+
data-message-check-ref="{{ params.id }}-check" data-message-check-num="{{ params.charCheckLimit.limit }}"
|
|
48
48
|
aria-describedby="{{ params.id }}-check"
|
|
49
49
|
{% endif %}
|
|
50
|
-
{% if params.charCheckLimit and params.charCheckLimit.charcheckCountdown %}data-char-check-countdown="true"{% endif %}
|
|
51
50
|
{% if params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %}{{ ' ' }}{{ attribute }}{% if value %}="{{ value }}"{% endif %}{% endfor %}{% endif %}
|
|
52
51
|
{% if params.label and params.label.description %}{% if params.label.id %}aria-describedby="{{ params.label.id }}-description-hint"{% else %}aria-describedby="description-hint"{% endif %}{% endif %}
|
|
53
52
|
/>
|
|
@@ -570,36 +570,16 @@ describe('macro: input', () => {
|
|
|
570
570
|
expect($('.ons-input').attr('maxlength')).toBe('200');
|
|
571
571
|
});
|
|
572
572
|
|
|
573
|
-
it('does not have `data-char-check-countdown` attribute when `charcheckCountdown` is not provided', () => {
|
|
574
|
-
const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
|
|
575
|
-
|
|
576
|
-
expect($('.ons-input').attr('data-char-check-countdown')).toBe(undefined);
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
it('has `data-char-check-countdown` attribute when `charcheckCountdown` is true', () => {
|
|
580
|
-
const $ = cheerio.load(
|
|
581
|
-
renderComponent('input', {
|
|
582
|
-
...EXAMPLE_INPUT_WITH_CHARACTER_LIMIT,
|
|
583
|
-
charCheckLimit: {
|
|
584
|
-
...EXAMPLE_INPUT_WITH_CHARACTER_LIMIT.charCheckLimit,
|
|
585
|
-
charcheckCountdown: true,
|
|
586
|
-
},
|
|
587
|
-
}),
|
|
588
|
-
);
|
|
589
|
-
|
|
590
|
-
expect($('.ons-input').attr('data-char-check-countdown')).toBe('true');
|
|
591
|
-
});
|
|
592
|
-
|
|
593
573
|
it('has data attribute which references the character limit component', () => {
|
|
594
574
|
const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
|
|
595
575
|
|
|
596
|
-
expect($('.ons-input').attr('data-
|
|
576
|
+
expect($('.ons-input').attr('data-message-check-ref')).toBe('example-id-check');
|
|
597
577
|
});
|
|
598
578
|
|
|
599
579
|
it('has data attribute which defines limit for character check', () => {
|
|
600
580
|
const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
|
|
601
581
|
|
|
602
|
-
expect($('.ons-input').attr('data-
|
|
582
|
+
expect($('.ons-input').attr('data-message-check-num')).toBe('200');
|
|
603
583
|
});
|
|
604
584
|
|
|
605
585
|
it('has `aria-describedby` attribute which references the character limit component', () => {
|