@oliasoft-open-source/charts-library 0.0.2-beta-1
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/LICENSE +21 -0
- package/README.md +3 -0
- package/index.js +13 -0
- package/package.json +100 -0
- package/release-notes.md +178 -0
- package/src/assets/icons/line-and-point.svg +1 -0
- package/src/assets/icons/line-only.svg +1 -0
- package/src/assets/icons/list-hide.svg +1 -0
- package/src/assets/icons/point-only.svg +1 -0
- package/src/components/bar-chart/bar-chart-prop-types.js +188 -0
- package/src/components/bar-chart/bar-chart.interface.ts +84 -0
- package/src/components/bar-chart/bar-chart.jsx +243 -0
- package/src/components/bar-chart/bar-chart.module.less +61 -0
- package/src/components/bar-chart/get-bar-chart-data-labels.js +42 -0
- package/src/components/bar-chart/get-bar-chart-scales.js +123 -0
- package/src/components/bar-chart/get-bar-chart-tooltips.js +100 -0
- package/src/components/controls/axes-options/axes-options-form-state.js +95 -0
- package/src/components/controls/axes-options/axes-options.jsx +166 -0
- package/src/components/controls/controls.jsx +104 -0
- package/src/components/controls/controls.module.less +12 -0
- package/src/components/controls/drag-options.jsx +77 -0
- package/src/components/controls/legend-options.jsx +25 -0
- package/src/components/controls/line-options.jsx +54 -0
- package/src/components/line-chart/axis-scales/axis-scales.js +165 -0
- package/src/components/line-chart/datalabels-alignment/get-alignment-condition.js +13 -0
- package/src/components/line-chart/datalabels-alignment/get-alignment-data.js +20 -0
- package/src/components/line-chart/datalabels-alignment/get-datalabels-position.js +25 -0
- package/src/components/line-chart/get-axes-ranges-from-chart.js +10 -0
- package/src/components/line-chart/get-line-chart-data-labels.js +21 -0
- package/src/components/line-chart/get-line-chart-scales.js +120 -0
- package/src/components/line-chart/get-line-chart-tooltips.js +91 -0
- package/src/components/line-chart/line-chart-consts.js +7 -0
- package/src/components/line-chart/line-chart-prop-types.js +212 -0
- package/src/components/line-chart/line-chart-utils.js +192 -0
- package/src/components/line-chart/line-chart.interface.ts +107 -0
- package/src/components/line-chart/line-chart.jsx +531 -0
- package/src/components/line-chart/line-chart.minor-gridlines-plugin.js +88 -0
- package/src/components/line-chart/line-chart.module.less +77 -0
- package/src/components/line-chart/state/action-types.js +11 -0
- package/src/components/line-chart/state/initial-state.js +69 -0
- package/src/components/line-chart/state/line-chart-reducer.js +101 -0
- package/src/components/pie-chart/pie-chart-prop-types.js +111 -0
- package/src/components/pie-chart/pie-chart-utils.js +32 -0
- package/src/components/pie-chart/pie-chart.interface.ts +61 -0
- package/src/components/pie-chart/pie-chart.jsx +450 -0
- package/src/components/pie-chart/pie-chart.module.less +61 -0
- package/src/components/scatter-chart/scatter-chart.intefrace.ts +33 -0
- package/src/components/scatter-chart/scatter-chart.jsx +21 -0
- package/src/components/scatter-chart/scatter-chart.module.less +4 -0
- package/src/helpers/chart-border-plugin.js +19 -0
- package/src/helpers/chart-consts.js +62 -0
- package/src/helpers/chart-interface.ts +76 -0
- package/src/helpers/chart-utils.js +183 -0
- package/src/helpers/container.jsx +60 -0
- package/src/helpers/disabled-context.js +8 -0
- package/src/helpers/enums.js +87 -0
- package/src/helpers/get-chart-annotation.js +143 -0
- package/src/helpers/get-custom-legend-plugin-example.js +80 -0
- package/src/helpers/numbers/numbers.js +44 -0
- package/src/helpers/range/estimate-data-series-have-close-values.js +54 -0
- package/src/helpers/range/range.js +95 -0
- package/src/helpers/styles.js +68 -0
- package/src/helpers/text.js +6 -0
- package/src/style/external.less +4 -0
- package/src/style/fonts/lato/Lato-Bold.woff2 +0 -0
- package/src/style/fonts/lato/Lato-BoldItalic.woff2 +0 -0
- package/src/style/fonts/lato/Lato-Italic.woff2 +0 -0
- package/src/style/fonts/lato/Lato-Regular.woff2 +0 -0
- package/src/style/fonts.less +27 -0
- package/src/style/global.less +43 -0
- package/src/style/reset/reset.less +28 -0
- package/src/style/shared.less +24 -0
- package/src/style/variables.less +91 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import {
|
|
4
|
+
ArcElement,
|
|
5
|
+
CategoryScale,
|
|
6
|
+
Chart as ChartJS,
|
|
7
|
+
Filler,
|
|
8
|
+
Legend,
|
|
9
|
+
LinearScale,
|
|
10
|
+
LogarithmicScale,
|
|
11
|
+
Title,
|
|
12
|
+
Tooltip,
|
|
13
|
+
} from 'chart.js';
|
|
14
|
+
import zoomPlugin from 'chartjs-plugin-zoom';
|
|
15
|
+
import dataLabelsPlugin from 'chartjs-plugin-datalabels';
|
|
16
|
+
import { Pie } from 'react-chartjs-2';
|
|
17
|
+
|
|
18
|
+
import { ANIMATION_DURATION } from '../../helpers/chart-consts';
|
|
19
|
+
import styles from './pie-chart.module.less';
|
|
20
|
+
import { colors, generateRandomColor } from './pie-chart-utils';
|
|
21
|
+
import { getDefaultProps, PieChartPropTypes } from './pie-chart-prop-types';
|
|
22
|
+
import { setDefaultTheme } from '../../helpers/chart-utils';
|
|
23
|
+
|
|
24
|
+
ChartJS.register(
|
|
25
|
+
LinearScale,
|
|
26
|
+
CategoryScale,
|
|
27
|
+
LogarithmicScale,
|
|
28
|
+
ArcElement,
|
|
29
|
+
Legend,
|
|
30
|
+
Tooltip,
|
|
31
|
+
Title,
|
|
32
|
+
Filler,
|
|
33
|
+
zoomPlugin,
|
|
34
|
+
dataLabelsPlugin,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* this is a pie chart component
|
|
39
|
+
* @param {} props
|
|
40
|
+
* @param {import('./pie-chart.interface').IPieChartProps} IPieChartProps
|
|
41
|
+
* ./pie-chart.interface
|
|
42
|
+
*/
|
|
43
|
+
const PieChart = (props) => {
|
|
44
|
+
setDefaultTheme();
|
|
45
|
+
const chart = getDefaultProps(props);
|
|
46
|
+
const chartRef = useRef(null);
|
|
47
|
+
const [pointHover, setPointHover] = useState(false);
|
|
48
|
+
const { data, options, testId } = chart;
|
|
49
|
+
|
|
50
|
+
const generateDatasets = (datasets) => {
|
|
51
|
+
const copyDataset = JSON.parse(JSON.stringify(datasets));
|
|
52
|
+
|
|
53
|
+
if (options.graph.stacked) {
|
|
54
|
+
const generatedDataset = {
|
|
55
|
+
label: copyDataset[0].label,
|
|
56
|
+
backgroundColor: [],
|
|
57
|
+
borderColor: [],
|
|
58
|
+
borderWidth: parseFloat(copyDataset[0].borderWidth) || '1',
|
|
59
|
+
data: [],
|
|
60
|
+
};
|
|
61
|
+
data.labels.map((label, labelIndex) => {
|
|
62
|
+
copyDataset.map((arc, arcIndex) => {
|
|
63
|
+
generatedDataset.data.push(arc.data[labelIndex]);
|
|
64
|
+
const { backgroundColor } = arc;
|
|
65
|
+
const { borderColor } = arc;
|
|
66
|
+
generatedDataset.backgroundColor.push(
|
|
67
|
+
(Array.isArray(backgroundColor)
|
|
68
|
+
? backgroundColor[labelIndex % borderColor.length]
|
|
69
|
+
: backgroundColor) ||
|
|
70
|
+
colors[labelIndex] + `${99 - 10 * arcIndex}`,
|
|
71
|
+
);
|
|
72
|
+
generatedDataset.borderColor.push(
|
|
73
|
+
(Array.isArray(borderColor)
|
|
74
|
+
? borderColor[labelIndex % borderColor.length]
|
|
75
|
+
: borderColor) || colors[labelIndex],
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
return [generatedDataset];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const generatedDatasets = copyDataset.map((pieDataset, index) => {
|
|
83
|
+
const borderWidth = parseFloat(pieDataset.borderWidth) || '1';
|
|
84
|
+
const color = pieDataset.data.map(
|
|
85
|
+
(pie, i) => colors[i] || generateRandomColor(),
|
|
86
|
+
);
|
|
87
|
+
const borderColor = pieDataset.borderColor || color;
|
|
88
|
+
const backgroundColor =
|
|
89
|
+
pieDataset.backgroundColor ||
|
|
90
|
+
color.map((col) => col + `${99 - 11 * index}`);
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
...pieDataset,
|
|
94
|
+
borderWidth,
|
|
95
|
+
borderColor,
|
|
96
|
+
backgroundColor,
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
return generatedDatasets;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const generatedDatasets = generateDatasets(data.datasets);
|
|
103
|
+
|
|
104
|
+
const getTitle = () => {
|
|
105
|
+
return options.title !== ''
|
|
106
|
+
? {
|
|
107
|
+
display: true,
|
|
108
|
+
text: chart.options.title,
|
|
109
|
+
}
|
|
110
|
+
: {};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const legendClick = (e, legendItem, legend) => {
|
|
114
|
+
const chartInstance = legend.chart;
|
|
115
|
+
const { datasets } = chartInstance.data;
|
|
116
|
+
const { index } = legendItem;
|
|
117
|
+
|
|
118
|
+
if (options.graph.stacked) {
|
|
119
|
+
if (options.legend.useDataset) {
|
|
120
|
+
for (
|
|
121
|
+
let i = 0;
|
|
122
|
+
i < chartInstance.config._config.data.datasets[0].data.length;
|
|
123
|
+
i++
|
|
124
|
+
) {
|
|
125
|
+
if (i % data.datasets.length === index) {
|
|
126
|
+
const meta = chartInstance.getDatasetMeta(0);
|
|
127
|
+
const arc = meta.data[i];
|
|
128
|
+
arc.hidden = !arc.hidden;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
for (
|
|
133
|
+
let i = 0;
|
|
134
|
+
i < chartInstance.config._config.data.datasets[0].data.length;
|
|
135
|
+
i++
|
|
136
|
+
) {
|
|
137
|
+
if (parseInt(i / data.datasets.length) === index) {
|
|
138
|
+
const meta = chartInstance.getDatasetMeta(0);
|
|
139
|
+
const arc = meta.data[i];
|
|
140
|
+
arc.hidden = !arc.hidden;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
if (options.legend.useDataset) {
|
|
146
|
+
const meta = chartInstance.getDatasetMeta(index);
|
|
147
|
+
meta.hidden = !meta.hidden;
|
|
148
|
+
} else {
|
|
149
|
+
if (datasets.length > 1) {
|
|
150
|
+
for (let i = 0; i < data.datasets.length; i++) {
|
|
151
|
+
const meta = chartInstance.getDatasetMeta(i);
|
|
152
|
+
|
|
153
|
+
const arc = meta.data[index];
|
|
154
|
+
arc.hidden = !arc.hidden;
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
const meta = chartInstance.getDatasetMeta(0);
|
|
158
|
+
const arc = meta.data[index];
|
|
159
|
+
arc.hidden = !arc.hidden;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (options.interactions.onLegendClick)
|
|
165
|
+
options.interactions.onLegendClick(legendItem?.text, legendItem.hidden);
|
|
166
|
+
|
|
167
|
+
chartInstance.update();
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const onClick = (evt, elements, chartInstance) => {
|
|
171
|
+
chartInstance.resetZoom();
|
|
172
|
+
// TODO: Restore redux-logic for zoom
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const onHover = (evt, hoveredItems) => {
|
|
176
|
+
if (pointHover && !hoveredItems?.length) {
|
|
177
|
+
setPointHover(false);
|
|
178
|
+
if (options.interactions.onPieUnhover) {
|
|
179
|
+
options.interactions.onPieUnhover(evt);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (!pointHover && hoveredItems?.length) {
|
|
183
|
+
setPointHover(true);
|
|
184
|
+
if (options.interactions.onPieHover) {
|
|
185
|
+
const { index, datasetIndex } = hoveredItems[0];
|
|
186
|
+
const generatedDataset = generatedDatasets;
|
|
187
|
+
options.interactions.onPieHover(
|
|
188
|
+
evt,
|
|
189
|
+
datasetIndex,
|
|
190
|
+
index,
|
|
191
|
+
generatedDataset,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const getDatalabels = () => {
|
|
198
|
+
return options.graph.showDataLabels
|
|
199
|
+
? {
|
|
200
|
+
display: 'auto',
|
|
201
|
+
align: 'center',
|
|
202
|
+
anchor: 'center',
|
|
203
|
+
formatter: (value, context) => {
|
|
204
|
+
if (
|
|
205
|
+
context.chart.getDatasetMeta(
|
|
206
|
+
options.graph.stacked ? 0 : context.datasetIndex,
|
|
207
|
+
).data[context.dataIndex].hidden
|
|
208
|
+
)
|
|
209
|
+
return '';
|
|
210
|
+
const dataElement = context.dataset.data[context.dataIndex];
|
|
211
|
+
const label =
|
|
212
|
+
dataElement?.label ||
|
|
213
|
+
(typeof dataElement === 'number'
|
|
214
|
+
? dataElement
|
|
215
|
+
: Array.isArray(dataElement)
|
|
216
|
+
? dataElement.reduce((acc, curr, i) => {
|
|
217
|
+
if (i === 0) return `${acc} ${curr}`;
|
|
218
|
+
return `${acc}, ${curr}`;
|
|
219
|
+
}, '')
|
|
220
|
+
: '');
|
|
221
|
+
const dataLabel =
|
|
222
|
+
typeof dataElement === 'number'
|
|
223
|
+
? Number.isInteger(label)
|
|
224
|
+
? label
|
|
225
|
+
: label.toFixed(2)
|
|
226
|
+
: label;
|
|
227
|
+
return dataLabel;
|
|
228
|
+
},
|
|
229
|
+
}
|
|
230
|
+
: {
|
|
231
|
+
display: false,
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const getLegend = () => {
|
|
236
|
+
return {
|
|
237
|
+
position: options.legend.position,
|
|
238
|
+
display: options.legend.display,
|
|
239
|
+
align: options.legend.align,
|
|
240
|
+
labels: {
|
|
241
|
+
generateLabels(chartInstance) {
|
|
242
|
+
if (options.graph.stacked) {
|
|
243
|
+
const meta = chartInstance.getDatasetMeta(0);
|
|
244
|
+
if (options.legend.useDataset) {
|
|
245
|
+
return data.datasets.map((data, i) => {
|
|
246
|
+
const { label } = data.datasets[i % data.datasets.length];
|
|
247
|
+
const arc = meta.data[i];
|
|
248
|
+
const text = arc.hidden
|
|
249
|
+
? label.split('').reduce((acc, curr) => acc + '-', '')
|
|
250
|
+
: label;
|
|
251
|
+
const backgroundColor = data.datasets[i]?.backgroundColor;
|
|
252
|
+
const borderColor = data.datasets[i]?.borderColor;
|
|
253
|
+
return {
|
|
254
|
+
text,
|
|
255
|
+
fillStyle:
|
|
256
|
+
(Array.isArray(backgroundColor)
|
|
257
|
+
? backgroundColor[0]
|
|
258
|
+
: backgroundColor) || colors[0] + `${99 - 20 * i}`,
|
|
259
|
+
strokeStyle:
|
|
260
|
+
(Array.isArray(borderColor)
|
|
261
|
+
? borderColor[0]
|
|
262
|
+
: borderColor) || colors[0],
|
|
263
|
+
index: i,
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
} else {
|
|
267
|
+
return data.labels.map((data, i) => {
|
|
268
|
+
const label = data.labels[i];
|
|
269
|
+
const arc = meta.data[parseInt(i * data.datasets.length)];
|
|
270
|
+
const text = arc.hidden
|
|
271
|
+
? label.split('').reduce((acc, curr) => acc + '-', '')
|
|
272
|
+
: label;
|
|
273
|
+
const backgroundColor = data.datasets[0]?.backgroundColor;
|
|
274
|
+
const borderColor = data.datasets[0]?.borderColor;
|
|
275
|
+
return {
|
|
276
|
+
text,
|
|
277
|
+
fillStyle:
|
|
278
|
+
(Array.isArray(backgroundColor)
|
|
279
|
+
? backgroundColor[i % backgroundColor.length]
|
|
280
|
+
: backgroundColor) || colors[i] + '99',
|
|
281
|
+
strokeStyle:
|
|
282
|
+
(Array.isArray(borderColor)
|
|
283
|
+
? borderColor[i % backgroundColor.length]
|
|
284
|
+
: borderColor) || colors[i],
|
|
285
|
+
index: i,
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (options.legend.useDataset) {
|
|
291
|
+
return data.datasets.map((dataset, i) => {
|
|
292
|
+
const meta = chartInstance.getDatasetMeta(i);
|
|
293
|
+
const text = meta.hidden
|
|
294
|
+
? dataset.label.split('').reduce((acc, curr) => acc + '-', '')
|
|
295
|
+
: dataset.label;
|
|
296
|
+
const backgroundColor = data.datasets[i]?.backgroundColor;
|
|
297
|
+
const borderColor = data.datasets[i]?.borderColor;
|
|
298
|
+
return {
|
|
299
|
+
text,
|
|
300
|
+
fillStyle:
|
|
301
|
+
(Array.isArray(backgroundColor)
|
|
302
|
+
? backgroundColor[0]
|
|
303
|
+
: backgroundColor) || colors[0] + `${99 - 20 * i}`,
|
|
304
|
+
strokeStyle:
|
|
305
|
+
(Array.isArray(borderColor) ? borderColor[0] : borderColor) ||
|
|
306
|
+
colors[0],
|
|
307
|
+
index: i,
|
|
308
|
+
};
|
|
309
|
+
});
|
|
310
|
+
} else {
|
|
311
|
+
return data.labels.map((label, i) => {
|
|
312
|
+
const meta = chartInstance.getDatasetMeta(0);
|
|
313
|
+
const arc = meta.data[i];
|
|
314
|
+
const text = arc.hidden
|
|
315
|
+
? label.split('').reduce((acc, curr) => acc + '-', '')
|
|
316
|
+
: label;
|
|
317
|
+
const backgroundColor = data.datasets[0]?.backgroundColor;
|
|
318
|
+
const borderColor = data.datasets[0]?.borderColor;
|
|
319
|
+
return {
|
|
320
|
+
text,
|
|
321
|
+
fillStyle:
|
|
322
|
+
(Array.isArray(backgroundColor)
|
|
323
|
+
? backgroundColor[i % backgroundColor.length]
|
|
324
|
+
: backgroundColor) || colors[i] + '99',
|
|
325
|
+
strokeStyle:
|
|
326
|
+
(Array.isArray(borderColor)
|
|
327
|
+
? borderColor[i % backgroundColor.length]
|
|
328
|
+
: borderColor) || colors[i],
|
|
329
|
+
index: i,
|
|
330
|
+
};
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
boxHeight: 6,
|
|
335
|
+
boxWidth: 6,
|
|
336
|
+
usePointStyle: true,
|
|
337
|
+
filter: (item, data) => {
|
|
338
|
+
if (!options.legend.useDataset) return true;
|
|
339
|
+
return !data.datasets[item.index]?.hideLegend;
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
onClick: legendClick,
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
const getToolTips = () => {
|
|
347
|
+
return {
|
|
348
|
+
callbacks: {
|
|
349
|
+
title: (tooltipItem) => {
|
|
350
|
+
const { dataIndex } = tooltipItem[0];
|
|
351
|
+
const index = options.graph.stacked
|
|
352
|
+
? parseInt(dataIndex / data.labels.length)
|
|
353
|
+
: dataIndex;
|
|
354
|
+
const label = data.labels[index];
|
|
355
|
+
return `${label}`;
|
|
356
|
+
},
|
|
357
|
+
label: (tooltipItem) => {
|
|
358
|
+
const { dataIndex } = tooltipItem;
|
|
359
|
+
const datasetIndex = options.graph.stacked
|
|
360
|
+
? dataIndex % data.datasets.length
|
|
361
|
+
: tooltipItem.datasetIndex;
|
|
362
|
+
const dataLabel =
|
|
363
|
+
data.datasets.length > 1
|
|
364
|
+
? `${data.datasets[datasetIndex]?.label}: `
|
|
365
|
+
: '';
|
|
366
|
+
const value = tooltipItem.dataset.data[dataIndex];
|
|
367
|
+
const labelValue =
|
|
368
|
+
typeof value === 'object'
|
|
369
|
+
? `${value.value || ''} ${
|
|
370
|
+
options.tooltip.showLabelsInTooltips && value.label
|
|
371
|
+
? '(' + value.label + ')'
|
|
372
|
+
: ''
|
|
373
|
+
}`
|
|
374
|
+
: value;
|
|
375
|
+
const unit = data?.yUnit ? `[${data?.yUnit}]` : '';
|
|
376
|
+
return `${dataLabel} ${labelValue} ${unit}`;
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
};
|
|
381
|
+
return (
|
|
382
|
+
<div
|
|
383
|
+
className={cx(
|
|
384
|
+
styles.chart,
|
|
385
|
+
!options.chartStyling.width || !options.chartStyling.height
|
|
386
|
+
? options.chartStyling.staticChartHeight
|
|
387
|
+
? styles.fixedHeight
|
|
388
|
+
: styles.stretchHeight
|
|
389
|
+
: '',
|
|
390
|
+
)}
|
|
391
|
+
style={{
|
|
392
|
+
width: options.chartStyling.width || 'auto',
|
|
393
|
+
height: options.chartStyling.height || 'auto',
|
|
394
|
+
}}
|
|
395
|
+
data-testid={testId}
|
|
396
|
+
>
|
|
397
|
+
<Pie
|
|
398
|
+
ref={chartRef}
|
|
399
|
+
data={{
|
|
400
|
+
datasets: generatedDatasets,
|
|
401
|
+
labels: options.graph.stacked ? undefined : data.labels,
|
|
402
|
+
}}
|
|
403
|
+
options={{
|
|
404
|
+
cutout: options.graph.cutout,
|
|
405
|
+
onClick,
|
|
406
|
+
responsive: true, // Defaults to true, should be removed
|
|
407
|
+
maintainAspectRatio: options.chartStyling.maintainAspectRatio,
|
|
408
|
+
animation: options.chartStyling.performanceMode
|
|
409
|
+
? false
|
|
410
|
+
: {
|
|
411
|
+
duration: ANIMATION_DURATION.FAST,
|
|
412
|
+
},
|
|
413
|
+
hover: {
|
|
414
|
+
mode: 'nearest',
|
|
415
|
+
intersect: 'true',
|
|
416
|
+
},
|
|
417
|
+
onHover,
|
|
418
|
+
elements: {
|
|
419
|
+
pie: {
|
|
420
|
+
pointStyle: 'circle',
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
plugins: {
|
|
424
|
+
title: getTitle(),
|
|
425
|
+
datalabels: getDatalabels(),
|
|
426
|
+
// zoom: {
|
|
427
|
+
// pan: {
|
|
428
|
+
// enabled: ,
|
|
429
|
+
// mode: ,
|
|
430
|
+
// },
|
|
431
|
+
// zoom: {
|
|
432
|
+
// drag: {
|
|
433
|
+
// enabled:,
|
|
434
|
+
// },
|
|
435
|
+
// mode: ,
|
|
436
|
+
// speed: ,
|
|
437
|
+
// },
|
|
438
|
+
// },
|
|
439
|
+
tooltip: getToolTips(),
|
|
440
|
+
legend: getLegend(),
|
|
441
|
+
},
|
|
442
|
+
}}
|
|
443
|
+
/>
|
|
444
|
+
</div>
|
|
445
|
+
);
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
PieChart.propTypes = PieChartPropTypes;
|
|
449
|
+
|
|
450
|
+
export { PieChart };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
html[data-theme='dark'] .chart canvas {
|
|
2
|
+
// Flip chart colors if dark mode enabled
|
|
3
|
+
filter: invert(1) hue-rotate(180deg);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.chart {
|
|
7
|
+
border: 1px solid rgba(255, 255, 255, 0);
|
|
8
|
+
padding-top: 10px;
|
|
9
|
+
position: relative;
|
|
10
|
+
|
|
11
|
+
canvas {
|
|
12
|
+
width: 100% !important; // Fix for resizing bug
|
|
13
|
+
height: 100% !important; // Remove if stretched when maintainAspectRatio=true
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&.fixedHeight {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: flex-start;
|
|
19
|
+
justify-content: flex-start;
|
|
20
|
+
height: auto;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&.stretchHeight {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: stretch;
|
|
26
|
+
justify-content: stretch;
|
|
27
|
+
height: 100%;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&:focus {
|
|
31
|
+
border: 1px solid #85b7d9;
|
|
32
|
+
outline: none; // Remove dotted outline on FF
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&::-moz-focus-inner {
|
|
36
|
+
border: 0; // Remove dotted outline on FF
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.zoomForm {
|
|
41
|
+
position: absolute;
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
top: 0;
|
|
46
|
+
right: 0;
|
|
47
|
+
|
|
48
|
+
.zoomReset {
|
|
49
|
+
margin-left: 10px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.help {
|
|
53
|
+
margin-left: 5px;
|
|
54
|
+
line-height: 0; // Strip whitespace from icon
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.autoWeight {
|
|
59
|
+
width: 'auto';
|
|
60
|
+
height: 'auto';
|
|
61
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { IChartPlugins } from "../../helpers/chart-interface";
|
|
2
|
+
|
|
3
|
+
export interface IScatterChartOptions {
|
|
4
|
+
responsive: boolean;
|
|
5
|
+
maintainAspectRatio: boolean;
|
|
6
|
+
plugins: IChartPlugins;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IScatterChartPoint {
|
|
10
|
+
x: number | string;
|
|
11
|
+
y: number | string;
|
|
12
|
+
label?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface IScatterChartDataset {
|
|
16
|
+
label: string;
|
|
17
|
+
data: IScatterChartPoint[];
|
|
18
|
+
borderColor: string;
|
|
19
|
+
backgroundColor: string;
|
|
20
|
+
showLine: Boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface IScatterChartData {
|
|
24
|
+
testId: string | null;
|
|
25
|
+
data: {
|
|
26
|
+
datasets: IScatterChartDataset[]
|
|
27
|
+
};
|
|
28
|
+
options: IScatterChartOptions;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface IScatterChartProps {
|
|
32
|
+
chart: IScatterChartData;
|
|
33
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Scatter } from 'react-chartjs-2';
|
|
3
|
+
|
|
4
|
+
import { setDefaultTheme } from '../../helpers/chart-utils';
|
|
5
|
+
import styles from './scatter-chart.module.less';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {import('./scatter-chart.intefrace').IScatterChartProps} props
|
|
10
|
+
*/
|
|
11
|
+
const ScatterChart = (props) => {
|
|
12
|
+
setDefaultTheme();
|
|
13
|
+
const { data, options, testId = null } = props.chart;
|
|
14
|
+
return (
|
|
15
|
+
<div className={styles.chart}>
|
|
16
|
+
<Scatter options={options} data={data} data-testid={testId} />
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default ScatterChart;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chart border plugin config
|
|
3
|
+
*/
|
|
4
|
+
export const chartAreaBorderPlugin = {
|
|
5
|
+
id: 'chartAreaBorder',
|
|
6
|
+
beforeDraw(chart, args, options) {
|
|
7
|
+
const {
|
|
8
|
+
ctx,
|
|
9
|
+
chartArea: { left, top, width, height },
|
|
10
|
+
} = chart;
|
|
11
|
+
ctx.save();
|
|
12
|
+
ctx.strokeStyle = options.borderColor;
|
|
13
|
+
ctx.lineWidth = options.borderWidth;
|
|
14
|
+
ctx.setLineDash(options.borderDash || []);
|
|
15
|
+
ctx.lineDashOffset = options.borderDashOffset;
|
|
16
|
+
ctx.strokeRect(left, top, width, height);
|
|
17
|
+
ctx.restore();
|
|
18
|
+
},
|
|
19
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const BORDER_WIDTH = {
|
|
2
|
+
INITIAL: 2,
|
|
3
|
+
HOVERED: 6,
|
|
4
|
+
};
|
|
5
|
+
export const BORDER_COLOR = 'rgba(0,0,0,0.1)';
|
|
6
|
+
|
|
7
|
+
export const ANNOTATION_DASH = [10, 2];
|
|
8
|
+
export const DEFAULT_FONT_SIZE = 13;
|
|
9
|
+
export const DEFAULT_FONT_FAMILY = '"Lato", sans-serif';
|
|
10
|
+
export const DEFAULT_COLOR = 'rgba(0,0,0,.87)';
|
|
11
|
+
export const LEGEND_LABEL_BOX_SIZE = 6;
|
|
12
|
+
|
|
13
|
+
export const LOGARITHMIC_STEPS = [1, 10, 100, 1000, 10000];
|
|
14
|
+
|
|
15
|
+
export const COLORS = [
|
|
16
|
+
'#3366cc',
|
|
17
|
+
'#dc3912',
|
|
18
|
+
'#ff9900',
|
|
19
|
+
'#109618',
|
|
20
|
+
'#990099',
|
|
21
|
+
'#0099c6',
|
|
22
|
+
'#dd4477',
|
|
23
|
+
'#66aa00',
|
|
24
|
+
'#b82e2e',
|
|
25
|
+
'#316395',
|
|
26
|
+
'#994499',
|
|
27
|
+
'#22aa99',
|
|
28
|
+
'#aaaa11',
|
|
29
|
+
'#6633cc',
|
|
30
|
+
'#e67300',
|
|
31
|
+
'#8b0707',
|
|
32
|
+
'#651067',
|
|
33
|
+
'#329262',
|
|
34
|
+
'#5574a6',
|
|
35
|
+
'#3b3eac',
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @type {string}
|
|
40
|
+
* @desc equivalent of 0.6 rgba alpha chanel
|
|
41
|
+
*/
|
|
42
|
+
export const ALPHA_CHANEL = '99';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @type {number}
|
|
46
|
+
* @desc #FFFFFF as decimal number
|
|
47
|
+
*/
|
|
48
|
+
export const WHITE_COLOR_AS_DECIMAL = 16777215;
|
|
49
|
+
|
|
50
|
+
export const AUTO = 'auto';
|
|
51
|
+
|
|
52
|
+
export const ANIMATION_DURATION = {
|
|
53
|
+
NO: 0,
|
|
54
|
+
SLOW: 400,
|
|
55
|
+
FAST: 1000,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const DEFAULT_CHART_NAME = 'new_chart';
|
|
59
|
+
|
|
60
|
+
export const CUSTOM_LEGEND_PLUGIN_NAME = 'htmlLegend';
|
|
61
|
+
|
|
62
|
+
export const DECIMAL_POINT_TOLERANCE = 9; //ignore decimal points beyond this
|