diff --git a/package.json b/package.json index 1d843290b9..b35642f5af 100644 --- a/package.json +++ b/package.json @@ -132,5 +132,8 @@ }, "publishConfig": { "access": "public" + }, + "dependencies": { + "highcharts": "^12.1.2" } } diff --git a/src/components/chart/_chart.scss b/src/components/chart/_chart.scss new file mode 100644 index 0000000000..0012c74876 --- /dev/null +++ b/src/components/chart/_chart.scss @@ -0,0 +1,7 @@ +.ons-chart { + margin: 0; + &__download-title { + @extend .ons-u-pt-l; + @extend .ons-u-fs-r--b; + } +} diff --git a/src/components/chart/_macro-options.md b/src/components/chart/_macro-options.md new file mode 100644 index 0000000000..5a3fdf7846 --- /dev/null +++ b/src/components/chart/_macro-options.md @@ -0,0 +1,109 @@ +| Name | Type | Required | Description | +| ----------- | ------ | -------- | ------------------------------------------------------------------------------------------ | +| chartType | string | true | The type of chart to render (e.g., 'line', 'bar', etc.). | +| theme | string | true | The theme to apply to the chart. Either `primary` or `alternate`. | +| title | string | true | The main title of the chart. | +| subtitle | string | true | A subtitle that appears under the main title. | +| uuid | string | true | A unique identifier for the chart instance. | +| caption | string | false | A caption providing additional context for the chart. | +| description | string | false | A textual description of the chart for screen readers. | +| download | object | false | Object for (download)[#download] options. | +| config | object | true | The full [configuration](#config) object passed to Highcharts, defining axes, series, etc. | + +### Download + +| Property | Type | Required | Description | +| --------- | ------ | -------- | -------------------------------------------------------------------------------------------- | +| title | string | false | The title displayed above the download options. | +| itemsList | array | false | An array of items available for download, each described by a (DownloadItem)[#DownloadItem]. | + +### DownloadItem + +| Property | Type | Required | Description | +| -------- | ------ | -------- | -------------------------------------------------- | +| `text` | string | true | The label or description of the downloadable item. | +| `url` | string | true | The URL to the downloadable resource. | + +### Config + +| Name | Type | Required | Description | +| ------ | ------ | -------- | ----------------------------------------------------------------------------------------- | +| chart | object | true | Defines the [chart's](#chart) overall behavior and appearance. | +| legend | object | false | Controls the appearance and behavior of the [legend](#legend). | +| yAxis | object | true | Defines the vertical axis [y-axis](#y_axis) properties, including labels and title. | +| xAxis | object | true | Defines the horizontal axis [x-axis](#x_axis) properties, including categories and title. | +| series | array | true | The data [series](#series) to be plotted, including labels and values. | + +### Chart + +| Name | Type | Required | Description | +| ---- | ------ | -------- | -------------------------------------------------------- | +| type | string | true | The type of chart (e.g., `'line'`, `'bar'`, `'column'`). | + +### Legend + +| Name | Type | Required | Description | +| ------------- | ------- | -------- | --------------------------------------------------------------- | +| enabled | boolean | false | Whether the legend is displayed. Defaults to `true`. | +| align | string | false | Horizontal alignment of the legend (`left`, `center`, `right`). | +| verticalAlign | string | false | Vertical alignment of the legend (`top`, `middle`, `bottom`). | +| layout | string | false | Legend layout (`horizontal` or `vertical`). | + +### Y_Axis + +| Name | Type | Required | Description | +| -------- | ------- | -------- | --------------------------------------------------------------------- | +| title | object | true | Defines the [title](#title) of the y-axis. | +| reversed | boolean | false | Sets the axis so that the highest number is closest to the origin. | +| labels | object | false | The axis [labels](#labels) show the number or category for each tick. | + +### X_Axis + +| Name | Type | Required | Description | +| ------------ | ------- | -------- | ---------------------------------------------------------------------------------- | +| title | object | true | Defines the [title](#title) of the x-axis. | +| categories | array | false | Labels for each tick mark along the x-axis. | +| reversed | boolean | false | Sets the axis so that the highest number is closest to the origin. | +| type | string | false | The type of axis. Can be one of `linear`, `logarithmic`, `datetime` or `category`. | +| labels | object | false | The axis [labels](#labels) show the number or category for each tick. | +| tickInterval | number | false | The interval of the tick marks in axis units | + +### Title + +| Name | Type | Required | Description | +| ---- | ------ | -------- | ------------------------------------------------- | +| text | string | true | The title text displayed on the y-axis or x-axis. | + +### Labels + +| Name | Type | Required | Description | +| ------ | ------ | -------- | ----------------------------------- | +| format | string | false | A format string for the axis label. | + +### Series + +| Name | Type | Required | Description | +| ---------- | ------ | -------- | ------------------------------------------------------------------------------------------- | +| name | string | true | The name of the series. | +| data | array | true | The data values for the series. Each value corresponds to a category on the x-axis. | +| dataLabels | object | false | Configuration options for displaying labels on the data points. | +| tooltip | object | false | Customization options for the (tooltip)[#tooltip] displayed when hovering over data points. | +| animation | object | false | Defines (animation)[#animation] options for rendering the series. Defaults to false. | + +### DataLabel + +| Name | Type | Required | Description | +| ------- | ------- | -------- | -------------------------------------------------------- | +| enabled | boolean | false | Whether the DataLabel is displayed. Defaults to `false`. | + +### Tooltip + +| Name | Type | Required | Description | +| ----------- | ------ | -------- | ----------------------------------------- | +| valueSuffix | string | false | A string to append to each tooltip value. | + +#### Animation + +| Name | Type | Required | Description | +| -------- | ------ | -------- | ------------------------------------------------------------- | +| duration | number | false | Duration of the animation in milliseconds. Default is `1000`. | diff --git a/src/components/chart/_macro.njk b/src/components/chart/_macro.njk new file mode 100644 index 0000000000..5cdd6cbd8a --- /dev/null +++ b/src/components/chart/_macro.njk @@ -0,0 +1,36 @@ +{% from "components/list/_macro.njk" import onsList %} + +{% macro onsChart(params) %} +
+
+

{{ params.title }}

+

{{ params.subtitle }}

+
{{ params.description }}
+
+ {% if params.caption %} +
{{ params.caption }}
+ {% endif %} +
+ + {% if params.download.title and params.download.itemsList | length > 0 %} +
{{ params.download.title }}
+ {{ + onsList({ + "element": "ol", + "itemsList": params.download.itemsList + }) + }} + {% endif %} + + + {# #} +
+{% endmacro %} diff --git a/src/components/chart/chart.dom.js b/src/components/chart/chart.dom.js new file mode 100644 index 0000000000..3236d37d0a --- /dev/null +++ b/src/components/chart/chart.dom.js @@ -0,0 +1,8 @@ +import HighchartsBaseChart from './chart'; +import domready from '../../js/domready'; + +domready(async () => { + [HighchartsBaseChart].forEach((Component) => { + document.querySelectorAll(Component.selector()).forEach((el) => new Component(el)); + }); +}); diff --git a/src/components/chart/chart.js b/src/components/chart/chart.js new file mode 100644 index 0000000000..e29afc20cc --- /dev/null +++ b/src/components/chart/chart.js @@ -0,0 +1,55 @@ +import CommonChartOptions from './common-chart-options'; +import SpecificChartOptions from './specific-chart-options'; +import LineChartPlotOptions from './line-chart'; +import Highcharts from 'highcharts'; + +class HighchartsBaseChart { + static selector() { + return '[data-highcharts-base-chart]'; + } + + constructor(node) { + this.node = node; + this.chartType = this.node.dataset.highchartsType; + this.theme = this.node.dataset.highchartsTheme; + this.title = this.node.dataset.highchartsTitle; + const chartNode = this.node.querySelector('[data-highcharts-chart]'); + + this.uuid = this.node.dataset.highchartsUuid; + + this.config = JSON.parse(this.node.querySelector(`[data-highcharts-config--${this.uuid}]`).textContent); + + this.commonChartOptions = new CommonChartOptions(); + this.specificChartOptions = new SpecificChartOptions(this.theme, this.chartType); + + if (window.isCommonChartOptionsDefined === undefined) { + this.setCommonChartOptions(); + window.isCommonChartOptionsDefined = true; + } + + this.setSpecificChartOptions(); + + Highcharts.chart(chartNode, this.config); + } + + // Set up the global Highcharts options + setCommonChartOptions = () => { + const chartOptions = this.commonChartOptions.getOptions(); + Highcharts.setOptions(chartOptions); + }; + + setSpecificChartOptions = () => { + const specificChartOptions = this.specificChartOptions.getOptions(); + for (const option in specificChartOptions) { + this.config[option] = specificChartOptions[option]; + } + // Add the line chart plotOptions to the config - merge with + // any existing plotOptions + this.config.plotOptions = { + ...(Highcharts.getOptions()?.plotOptions || {}), + line: new LineChartPlotOptions().plotOptions.line, + }; + }; +} + +export default HighchartsBaseChart; diff --git a/src/components/chart/common-chart-options.js b/src/components/chart/common-chart-options.js new file mode 100644 index 0000000000..80815270b2 --- /dev/null +++ b/src/components/chart/common-chart-options.js @@ -0,0 +1,128 @@ +class CommonChartOptions { + constructor() { + this.constants = { + axisLabelColor: '#707071', + gridLineColor: '#d9d9d9', + zeroLineColor: '#b3b3b3', + // Responsive font sizes + mobileFontSize: '0.875rem', + desktopFontSize: '1rem', + }; + + this.options = { + chart: { + backgroundColor: 'transparent', + style: { + fontFamily: '"OpenSans", "Helvetica Neue", arial, sans-serif', + color: '#222222', + }, + }, + // Remove the chart title as rendered by Highcharts, as this is rendered in the surrounding component + title: { + text: '', + }, + credits: { + // Remove Highcharts watermark + enabled: false, + }, + accessibility: { + enabled: true, + }, + yAxis: { + labels: { + style: { + color: this.constants.axisLabelColor, + fontSize: this.constants.desktopFontSize, + }, + }, + title: { + align: 'high', + offset: 15, + rotation: 0, + y: -25, + }, + lineColor: this.constants.gridLineColor, + gridLineColor: this.constants.gridLineColor, + zeroLineColor: this.constants.zeroLineColor, + }, + xAxis: { + labels: { + rotation: 0, + style: { + color: this.constants.axisLabelColor, + fontSize: this.constants.desktopFontSize, + }, + }, + title: { + align: 'high', + }, + lineColor: this.constants.gridLineColor, + gridLineColor: this.constants.gridLineColor, + zeroLineColor: this.constants.zeroLineColor, + // Add tick marks + tickWidth: 1, + tickLength: 6, + tickColor: this.constants.gridLineColor, + }, + plotOptions: { + series: { + // disabes the tooltip on hover + enableMouseTracking: false, + + // disables the legend item hover + states: { + inactive: { + enabled: false, + }, + }, + }, + }, + // Adjust font size for smaller width of chart + // Note this is not the same as the viewport width + responsive: { + rules: [ + { + condition: { + maxWidth: 400, + }, + chartOptions: { + legend: { + itemStyle: { + fontSize: this.constants.mobileFontSize, + }, + }, + xAxis: { + labels: { + style: { + fontSize: this.constants.mobileFontSize, + }, + }, + title: { + style: { + fontSize: this.constants.mobileFontSize, + }, + }, + }, + yAxis: { + labels: { + style: { + fontSize: this.constants.mobileFontSize, + }, + }, + title: { + style: { + fontSize: this.constants.mobileFontSize, + }, + }, + }, + }, + }, + ], + }, + }; + } + + getOptions = () => this.options; +} + +export default CommonChartOptions; diff --git a/src/components/chart/example-line-chart.njk b/src/components/chart/example-line-chart.njk new file mode 100644 index 0000000000..b28d812bf8 --- /dev/null +++ b/src/components/chart/example-line-chart.njk @@ -0,0 +1,232 @@ +{% from "components/chart/_macro.njk" import onsChart %} + +{{ + onsChart({ + "chartType": "line", + "description": "Line chart showing the annual rate of inflation for the Consumer Prices Index including owner occupiers’ housing costs (CPIH) and its components.", + "theme": "alternate", + "title": "Sales volumes and values saw moderate growth in July 2024", + "subtitle": "Figure 6: Upward contribution from housing and household services (including energy) saw the annual CPIH inflation rate rise", + "uuid": "uuid", + "caption": "Source: Monthly Business Survey, Retails Sales Inquiry from the Office for National Statistics", + "download": { + 'title': 'Download Figure 1 data', + 'itemsList': [ + { + "text": "Excel spreadsheet (XLSX format, 18KB)", + "url": "#" + }, + { + "text": "Simple text file (CSV format, 25KB)", + "url": "#" + }, + { + + "text": "Image (PNG format, 25KB)", + "url": "#" + } + ]}, + "config": { + "chart": { + "type": 'line' + }, + "legend": { + "enabled": false + }, + "yAxis": { + "title": { + "text": 'Sales' + }, + 'reversed': true, + "labels": { + "format": '{value:,.f}' + } + }, + "xAxis": { + "title": { + "text": 'Year' + }, + "categories": [ + 'Oct 2014', + 'Nov 2014', + 'Dec 2014', + 'Jan 2015', + 'Feb 2015', + 'Mar 2015', + 'Apr 2015', + 'May 2015', + 'Jun 2015', + 'Jul 2015', + 'Aug 2015', + 'Sep 2015', + 'Oct 2015', + 'Nov 2015', + 'Dec 2015', + 'Jan 2016', + 'Feb 2016', + 'Mar 2016', + 'Apr 2016', + 'May 2016', + 'Jun 2016', + 'Jul 2016', + 'Aug 2016', + 'Sep 2016', + 'Oct 2016', + 'Nov 2016', + 'Dec 2016', + 'Jan 2017', + 'Feb 2017', + 'Mar 2017', + 'Apr 2017', + 'May 2017', + 'Jun 2017', + 'Jul 2017', + 'Aug 2017', + 'Sep 2017', + 'Oct 2017', + 'Nov 2017', + 'Dec 2017', + 'Jan 2018', + 'Feb 2018', + 'Mar 2018', + 'Apr 2018', + 'May 2018', + 'Jun 2018', + 'Jul 2018', + 'Aug 2018', + 'Sep 2018', + 'Oct 2018', + 'Nov 2018', + 'Dec 2018', + 'Jan 2019', + 'Feb 2019', + 'Mar 2019', + 'Apr 2019', + 'May 2019', + 'Jun 2019', + 'Jul 2019', + 'Aug 2019', + 'Sep 2019', + 'Oct 2019', + 'Nov 2019', + 'Dec 2019', + 'Jan 2020', + 'Feb 2020', + 'Mar 2020', + 'Apr 2020', + 'May 2020', + 'Jun 2020', + 'Jul 2020', + 'Aug 2020', + 'Sep 2020', + 'Oct 2020', + 'Nov 2020', + 'Dec 2020', + 'Jan 2021', + 'Feb 2021', + 'Mar 2021', + 'Apr 2021', + 'May 2021', + 'Jun 2021', + 'Jul 2021', + 'Aug 2021', + 'Sep 2021', + 'Oct 2021', + 'Nov 2021', + 'Dec 2021', + 'Jan 2022', + 'Feb 2022', + 'Mar 2022', + 'Apr 2022', + 'May 2022', + 'Jun 2022', + 'Jul 2022', + 'Aug 2022', + 'Sep 2022', + 'Oct 2022', + 'Nov 2022', + 'Dec 2022', + 'Jan 2023', + 'Feb 2023', + 'Mar 2023', + 'Apr 2023', + 'May 2023', + 'Jun 2023', + 'Jul 2023', + 'Aug 2023', + 'Sep 2023', + 'Oct 2023', + 'Nov 2023', + 'Dec 2023', + 'Jan 2024', + 'Feb 2024', + 'Mar 2024', + 'Apr 2024', + 'May 2024', + 'Jun 2024', + 'Jul 2024', + 'Aug 2024', + 'Sep 2024', + 'Oct 2024' + ], + "tickInterval": 12, + 'type': 'linear' + }, + "series": [ + { + "name": 'CPIH', + "data": [ + 1.3, 1.1, 0.7, 0.5, 0.4, 0.3, 0.3, 0.4, 0.3, 0.5, 0.4, 0.2, 0.2, 0.4, 0.5, 0.6, + 0.6, 0.8, 0.7, 0.7, 0.8, 0.9, 1.0, 1.3, 1.3, 1.5, 1.8, 1.9, 2.3, 2.3, 2.6, 2.7, + 2.6, 2.6, 2.7, 2.8, 2.8, 2.8, 2.7, 2.7, 2.5, 2.3, 2.2, 2.3, 2.3, 2.3, 2.4, 2.2, + 2.2, 2.2, 2.0, 1.8, 1.8, 1.8, 2.0, 1.9, 1.9, 2.0, 1.7, 1.7, 1.5, 1.5, 1.4, 1.8, + 1.7, 1.5, 0.9, 0.7, 0.8, 1.1, 0.5, 0.7, 0.9, 0.6, 0.8, 0.9, 0.7, 1.0, 1.6, 2.1, + 2.4, 2.1, 3.0, 2.9, 3.8, 4.6, 4.8, 4.9, 5.5, 6.2, 7.8, 7.9, 8.2, 8.8, 8.6, 8.8, + 9.6, 9.3, 9.2, 8.8, 9.2, 8.9, 7.8, 7.9, 7.3, 6.4, 6.3, 6.3, 4.7, 4.2, 4.2, 4.2, + 3.8, 3.8, 3.0, 2.8, 2.8, 3.1, 3.1, 2.6, 3.2 + ] + }, + { + "name": 'Goods', + "data": [ + 0.3, -0.2, -1.0, -1.5, -2.0, -2.1, -1.9, -1.8, -2.0, -1.8, -2.0, -2.4, -2.1, + -1.9, -2.1, -1.5, -1.6, -1.7, -1.6, -1.8, -1.7, -1.5, -1.4, -0.5, -0.4, 0.2, + 0.7, 1.1, 1.9, 2.5, 2.4, 3.0, 2.6, 2.7, 3.1, 3.2, 3.3, 3.3, 3.4, 3.2, 3.0, 2.4, + 2.6, 2.5, 2.5, 2.6, 2.7, 2.5, 2.3, 2.1, 1.8, 1.2, 1.3, 1.3, 1.4, 1.5, 1.5, 1.7, + 1.2, 0.9, 0.4, 0.5, 0.6, 1.3, 1.0, 0.6, -0.4, -0.9, -0.5, 0.0, -0.2, -0.3, 0.1, + -0.7, -0.2, -0.2, -0.5, 0.1, 1.6, 2.3, 2.9, 2.5, 3.3, 3.5, 4.9, 6.5, 6.9, 7.2, + 8.3, 9.4, 12.4, 12.4, 12.7, 13.6, 13.0, 13.2, 14.8, 14.1, 13.4, 13.3, 13.4, + 12.7, 10.0, 9.7, 8.5, 6.1, 6.3, 6.2, 2.9, 2.0, 1.9, 1.8, 1.1, 0.9, -0.8, -1.3, + -1.4, -0.5, -0.9, -1.4, -0.3 + ] + }, + { + "name": 'Services', + "data": [ + 2.2, 2.1, 2.1, 2.1, 2.2, 2.2, 2.0, 2.1, 2.1, 2.2, 2.2, 2.2, 2.1, 2.2, 2.5, 2.2, + 2.3, 2.6, 2.4, 2.6, 2.7, 2.6, 2.7, 2.6, 2.5, 2.4, 2.5, 2.5, 2.6, 2.2, 2.8, 2.6, + 2.5, 2.4, 2.5, 2.5, 2.4, 2.4, 2.2, 2.3, 2.1, 2.1, 1.9, 2.1, 2.0, 2.0, 2.2, 2.0, + 2.1, 2.2, 2.1, 2.2, 2.2, 2.2, 2.5, 2.3, 2.2, 2.2, 2.0, 2.2, 2.2, 2.2, 1.9, 2.1, + 2.2, 2.2, 1.9, 1.8, 1.7, 2.0, 1.0, 1.5, 1.5, 1.5, 1.6, 1.7, 1.6, 1.6, 1.7, 1.9, + 2.1, 1.8, 2.7, 2.5, 2.9, 3.0, 3.1, 3.1, 3.2, 3.7, 4.1, 4.3, 4.5, 4.9, 5.1, 5.3, + 5.3, 5.4, 5.8, 5.2, 5.6, 5.7, 6.0, 6.3, 6.3, 6.5, 6.1, 6.3, 6.2, 6.0, 6.0, 6.1, + 6.0, 6.0, 6.0, 5.9, 6.0, 5.7, 5.9, 5.6, 5.6 + ] + }, + { + "name": 'CPIH excl energy, food, alcohol & tobacco', + "data": [ + 1.5, 1.3, 1.4, 1.5, 1.4, 1.2, 1.1, 1.2, 1.0, 1.3, 1.2, 1.2, 1.3, 1.4, 1.5, 1.4, + 1.4, 1.6, 1.5, 1.5, 1.6, 1.6, 1.5, 1.7, 1.6, 1.7, 1.8, 1.8, 2.1, 1.9, 2.4, 2.5, + 2.4, 2.4, 2.6, 2.5, 2.5, 2.5, 2.3, 2.4, 2.2, 2.1, 2.0, 2.0, 1.8, 1.8, 1.9, 1.8, + 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.7, 1.7, 1.7, 1.9, 1.5, 1.6, 1.7, 1.7, 1.4, 1.6, + 1.7, 1.6, 1.5, 1.3, 1.5, 1.8, 1.0, 1.4, 1.5, 1.2, 1.5, 1.5, 1.1, 1.3, 1.5, 2.0, + 2.3, 1.9, 2.9, 2.7, 3.1, 3.6, 3.8, 4.0, 4.6, 5.1, 5.4, 5.2, 5.2, 5.5, 5.6, 5.8, + 5.8, 5.7, 5.8, 5.3, 5.7, 5.7, 6.2, 6.5, 6.4, 6.4, 5.9, 5.9, 5.6, 5.2, 5.2, 5.1, + 4.8, 4.7, 4.4, 4.2, 4.2, 4.1, 4.3, 4.0, 4.1 + ] + } + ] + } + }) +}} diff --git a/src/components/chart/line-chart.js b/src/components/chart/line-chart.js new file mode 100644 index 0000000000..cc0267835f --- /dev/null +++ b/src/components/chart/line-chart.js @@ -0,0 +1,19 @@ +class LineChartPlotOptions { + static plotOptions() { + return this.plotOptions; + } + + constructor() { + this.plotOptions = { + line: { + lineWidth: 3, + linecap: 'round', + marker: { + enabled: false, + }, + }, + }; + } +} + +export default LineChartPlotOptions; diff --git a/src/components/chart/specific-chart-options.js b/src/components/chart/specific-chart-options.js new file mode 100644 index 0000000000..a0f5bba6ad --- /dev/null +++ b/src/components/chart/specific-chart-options.js @@ -0,0 +1,85 @@ +class SpecificChartOptions { + constructor(theme, type) { + this.constants = { + primaryTheme: ['#206095', '#27a0cc', '#003c57', '#118c7b', '#a8bd3a', '#871a5b', '#f66068', '#746cb1', '#22d0b6'], + // Alternate theme colours from https://service-manual.ons.gov.uk/data-visualisation/colours/using-colours-in-charts + alternateTheme: ['#206095', '#27A0CC', '#871A5B', '#A8BD3A', '#F66068'], + labelColor: '#414042', + desktopFontSize: '1rem', + }; + + this.options = { + colors: theme === 'primary' ? this.constants.primaryTheme : this.constants.alternateTheme, + legend: { + align: 'left', + verticalAlign: 'top', + layout: 'horizontal', + symbolWidth: type === 'line' ? 20 : 12, + symbolHeight: type === 'line' ? 3 : 12, + margin: 50, + itemStyle: { + color: this.constants.labelColor, + fontSize: this.constants.desktopFontSize, + fontWeight: 'normal', + }, + // Disable click event on legend + // There is currently an issue because the legend items are still buttons + // and therefore the screen reader still announces that they can be clicked + events: { + itemClick: () => { + return false; + }, + }, + }, + chart: { + //marginRight: 250, + events: { + load: (event) => { + if (type === 'line') { + const currentChart = event.target; + + currentChart.series.forEach((series) => { + const points = series.points; + console.log(series.name); + if (points && points.length > 0) { + // Show only the last point marker + const lastPoint = points[points.length - 1]; + lastPoint.update( + { + marker: { + enabled: true, + radius: 4, + symbol: 'circle', + fillColor: series.color, + lineWidth: 0, + }, + // dataLabels: { + // enabled: true, + // format: `{series.name}`, + // align: 'left', + // verticalAlign: 'center', + // color: series.color, + // x: 5, + // y: 2, + // allowOverlap: true, + // crop: false, + // overflow: 'none', + // }, + }, + false, + ); + } + }); + + currentChart.redraw(); + } + }, + }, + }, + }; + } + + getOptions = () => this.options; +} + +export default SpecificChartOptions; diff --git a/src/js/main.js b/src/js/main.js index 7466499222..30a239facb 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -30,3 +30,5 @@ import '../components/modal/modal.dom'; import '../components/timeout-modal/timeout-modal.dom'; import '../components/timeout-panel/timeout-panel.dom'; import '../components/video/video.dom'; +import '../components/chart/chart'; +import '../components/chart/chart.dom'; diff --git a/src/scss/main.scss b/src/scss/main.scss index 23817eae39..cd3b6eb8f1 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -11,6 +11,7 @@ @import '../components/browser-banner/browser-banner'; @import '../components/button/button'; @import '../components/card/card'; +@import '../components/chart/chart'; @import '../components/checkboxes/checkbox'; @import '../components/checkboxes/checkboxes'; @import '../components/details/details'; diff --git a/yarn.lock b/yarn.lock index 23e3b65ba1..0f24c68f63 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6176,6 +6176,11 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +highcharts@^12.1.2: + version "12.1.2" + resolved "https://registry.yarnpkg.com/highcharts/-/highcharts-12.1.2.tgz#826114935b3ffb6b99dc906da00f137667a67fbb" + integrity sha512-paZ72q1um0zZT1sS+O/3JfXVSOLPmZ0zlo8SgRc0rEplPFPQUPc4VpkgQS8IUTueeOBgIWwVpAWyC9tBYbQ0kg== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -11308,7 +11313,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -11326,15 +11331,6 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -11403,7 +11399,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -11424,13 +11420,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.0, strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -12811,7 +12800,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -12828,15 +12817,6 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"