@oliasoft-open-source/charts-library 2.17.6 → 2.18.0-beta-2
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/dist/index.js +40398 -0
- package/dist/style.css +177 -0
- package/package.json +26 -34
- package/index.js +0 -14
- package/release-notes.md +0 -310
- package/src/assets/icons/line-and-point.svg +0 -1
- package/src/assets/icons/line-only.svg +0 -1
- package/src/assets/icons/list-hide.svg +0 -1
- package/src/assets/icons/point-only.svg +0 -1
- package/src/components/bar-chart/bar-chart-prop-types.js +0 -209
- package/src/components/bar-chart/bar-chart.interface.ts +0 -91
- package/src/components/bar-chart/bar-chart.jsx +0 -247
- package/src/components/bar-chart/bar-chart.module.less +0 -61
- package/src/components/bar-chart/get-bar-chart-data-labels.js +0 -42
- package/src/components/bar-chart/get-bar-chart-scales.js +0 -123
- package/src/components/bar-chart/get-bar-chart-tooltips.js +0 -102
- package/src/components/controls/axes-options/axes-options.jsx +0 -270
- package/src/components/line-chart/constants/default-translations.js +0 -24
- package/src/components/line-chart/constants/line-chart-consts.js +0 -12
- package/src/components/line-chart/controls/axes-options/action-types.js +0 -5
- package/src/components/line-chart/controls/axes-options/axes-options-form-state.js +0 -97
- package/src/components/line-chart/controls/controls.jsx +0 -174
- package/src/components/line-chart/controls/controls.module.less +0 -12
- package/src/components/line-chart/controls/drag-options.jsx +0 -112
- package/src/components/line-chart/controls/legend-options.jsx +0 -36
- package/src/components/line-chart/controls/line-options.jsx +0 -64
- package/src/components/line-chart/hooks/use-chart-functions.js +0 -257
- package/src/components/line-chart/hooks/use-chart-options.js +0 -181
- package/src/components/line-chart/hooks/use-chart-plugins.js +0 -35
- package/src/components/line-chart/hooks/use-toggle-handler.js +0 -33
- package/src/components/line-chart/initialize/config.js +0 -23
- package/src/components/line-chart/initialize/initialize-line-chart.js +0 -25
- package/src/components/line-chart/line-chart-prop-types.js +0 -292
- package/src/components/line-chart/line-chart.interface.ts +0 -121
- package/src/components/line-chart/line-chart.jsx +0 -161
- package/src/components/line-chart/line-chart.module.less +0 -77
- package/src/components/line-chart/plugins/chart-area-text-plugin.js +0 -246
- package/src/components/line-chart/plugins/line-chart.minor-gridlines-plugin.js +0 -88
- package/src/components/line-chart/plugins/plugin-constants.js +0 -11
- package/src/components/line-chart/state/action-types.js +0 -12
- package/src/components/line-chart/state/initial-state.js +0 -89
- package/src/components/line-chart/state/line-chart-reducer.js +0 -100
- package/src/components/line-chart/state/manage-state-in-local-storage.js +0 -86
- package/src/components/line-chart/state/use-chart-state.js +0 -141
- package/src/components/line-chart/utils/axis-scales/axis-scales.js +0 -165
- package/src/components/line-chart/utils/datalabels-alignment/get-alignment-condition.js +0 -13
- package/src/components/line-chart/utils/datalabels-alignment/get-alignment-data.js +0 -20
- package/src/components/line-chart/utils/datalabels-alignment/get-datalabels-position.js +0 -25
- package/src/components/line-chart/utils/generate-line-chart-datasets.js +0 -114
- package/src/components/line-chart/utils/get-axes-ranges-from-chart.js +0 -13
- package/src/components/line-chart/utils/get-line-chart-data-labels.js +0 -21
- package/src/components/line-chart/utils/get-line-chart-scales.js +0 -120
- package/src/components/line-chart/utils/get-line-chart-tooltips.js +0 -94
- package/src/components/line-chart/utils/line-chart-utils.js +0 -77
- package/src/components/line-chart/utils/translations/get-translations.js +0 -17
- package/src/components/pie-chart/pie-chart-prop-types.js +0 -111
- package/src/components/pie-chart/pie-chart-utils.js +0 -32
- package/src/components/pie-chart/pie-chart.interface.ts +0 -61
- package/src/components/pie-chart/pie-chart.jsx +0 -450
- package/src/components/pie-chart/pie-chart.module.less +0 -61
- package/src/components/scatter-chart/scatter-chart.intefrace.ts +0 -33
- package/src/components/scatter-chart/scatter-chart.jsx +0 -21
- package/src/components/scatter-chart/scatter-chart.module.less +0 -4
- package/src/helpers/chart-border-plugin.js +0 -19
- package/src/helpers/chart-consts.js +0 -64
- package/src/helpers/chart-interface.ts +0 -94
- package/src/helpers/chart-utils.js +0 -182
- package/src/helpers/container.jsx +0 -60
- package/src/helpers/disabled-context.js +0 -8
- package/src/helpers/enums.js +0 -96
- package/src/helpers/get-chart-annotation.js +0 -106
- package/src/helpers/get-custom-legend-plugin-example.js +0 -80
- package/src/helpers/get-draggableData.js +0 -32
- package/src/helpers/range/estimate-data-series-have-close-values.js +0 -54
- package/src/helpers/range/range.js +0 -100
- package/src/helpers/text.js +0 -6
- package/src/style/external.less +0 -4
- 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 +0 -27
- package/src/style/global.less +0 -43
- package/src/style/reset/reset.less +0 -28
- package/src/style/shared.less +0 -11
- package/src/style/variables.less +0 -91
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export const TOGGLE_ZOOM = 'TOGGLE_ZOOM';
|
|
2
|
-
export const TOGGLE_PAN = 'TOGGLE_PAN';
|
|
3
|
-
export const TOGGLE_POINTS = 'TOGGLE_POINTS';
|
|
4
|
-
export const TOGGLE_LINE = 'TOGGLE_LINE';
|
|
5
|
-
export const TOGGLE_LEGEND = 'TOGGLE_LEGEND';
|
|
6
|
-
export const TOGGLE_ANNOTATION = 'TOGGLE_ANNOTATION';
|
|
7
|
-
export const TOGGLE_TABLE = 'TOGGLE_TABLE';
|
|
8
|
-
export const SAVE_INITIAL_AXES_RANGES = 'SAVE_INITIAL_AXES_RANGES';
|
|
9
|
-
export const RESET_AXES_RANGES = 'RESET_AXES_RANGES';
|
|
10
|
-
export const UPDATE_AXES_RANGES = 'UPDATE_AXES_RANGES';
|
|
11
|
-
export const TOGGLE_DRAG_POINTS = 'TOGGLE_DRAG_POINTS';
|
|
12
|
-
export const DISABLE_DRAG_OPTIONS = 'DISABLE_DRAG_OPTIONS';
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { AxisType } from '../../../helpers/enums';
|
|
2
|
-
import { setAnnotations } from '../../../helpers/chart-utils';
|
|
3
|
-
import { generateAxisId } from '../utils/line-chart-utils';
|
|
4
|
-
import { getChartStateFromStorage } from './manage-state-in-local-storage';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
Initial chart state for the line chart.
|
|
8
|
-
|
|
9
|
-
@param {Object} options - The chart options.
|
|
10
|
-
@return {Object} The initial chart state.
|
|
11
|
-
*/
|
|
12
|
-
const initialState = ({ options, persistenceId }) => {
|
|
13
|
-
const {
|
|
14
|
-
additionalAxesOptions: { range: customAxesRange },
|
|
15
|
-
annotations: { annotationsData },
|
|
16
|
-
axes,
|
|
17
|
-
chartOptions: { enableZoom, enablePan, showPoints, showLine },
|
|
18
|
-
legend: { display },
|
|
19
|
-
dragData,
|
|
20
|
-
} = options;
|
|
21
|
-
/**
|
|
22
|
-
* getStateAxesByType
|
|
23
|
-
* @param {'x'|'y'} axisType
|
|
24
|
-
* @param {Object} customAxesRange
|
|
25
|
-
* @return {{id: string}[] | []} returns array of objects describing all chart axis or empty array
|
|
26
|
-
*/
|
|
27
|
-
const getStateAxesByType = (axisType, customAxesRange) => {
|
|
28
|
-
if (!axes[axisType]) {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (axes[axisType]?.length > 1) {
|
|
33
|
-
return axes[axisType].map((axisObj, index) => {
|
|
34
|
-
const id = generateAxisId(axisType, index, axes[axisType].length > 1);
|
|
35
|
-
const customMin = customAxesRange?.[id]?.min;
|
|
36
|
-
const customMax = customAxesRange?.[id]?.max;
|
|
37
|
-
const { unit } = axisObj;
|
|
38
|
-
return {
|
|
39
|
-
id,
|
|
40
|
-
//only add custom axis ranges if defined:
|
|
41
|
-
...(customMin ? { min: customMin } : {}),
|
|
42
|
-
...(customMax ? { max: customMax } : {}),
|
|
43
|
-
...(unit ? { unit } : {}),
|
|
44
|
-
};
|
|
45
|
-
});
|
|
46
|
-
} else {
|
|
47
|
-
const id = generateAxisId(axisType);
|
|
48
|
-
const customMin = customAxesRange?.[id]?.min;
|
|
49
|
-
const customMax = customAxesRange?.[id]?.max;
|
|
50
|
-
const unit = axes?.[id][0].unit;
|
|
51
|
-
return [
|
|
52
|
-
{
|
|
53
|
-
id,
|
|
54
|
-
//only add custom axis ranges if defined:
|
|
55
|
-
...(customMin ? { min: customMin } : {}),
|
|
56
|
-
...(customMax ? { max: customMax } : {}),
|
|
57
|
-
...(unit ? { unit } : {}),
|
|
58
|
-
},
|
|
59
|
-
];
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const xStateAxes = getStateAxesByType(AxisType.X, customAxesRange);
|
|
64
|
-
const yStateAxes = getStateAxesByType(AxisType.Y, customAxesRange);
|
|
65
|
-
const stateAxes = [...xStateAxes, ...yStateAxes];
|
|
66
|
-
|
|
67
|
-
const {
|
|
68
|
-
zoomEnabled,
|
|
69
|
-
panEnabled,
|
|
70
|
-
pointsEnabled,
|
|
71
|
-
lineEnabled,
|
|
72
|
-
legendEnabled,
|
|
73
|
-
enableDragPoints,
|
|
74
|
-
} = getChartStateFromStorage(persistenceId) || {};
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
zoomEnabled: zoomEnabled ?? enableZoom,
|
|
78
|
-
panEnabled: panEnabled ?? enablePan,
|
|
79
|
-
pointsEnabled: pointsEnabled ?? showPoints,
|
|
80
|
-
lineEnabled: lineEnabled ?? showLine,
|
|
81
|
-
legendEnabled: legendEnabled ?? display,
|
|
82
|
-
axes: stateAxes,
|
|
83
|
-
showAnnotationLineIndex: setAnnotations(annotationsData),
|
|
84
|
-
showTable: false,
|
|
85
|
-
enableDragPoints: dragData.enableDragData && enableDragPoints,
|
|
86
|
-
};
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export default initialState;
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { produce } from 'immer';
|
|
2
|
-
import {
|
|
3
|
-
DISABLE_DRAG_OPTIONS,
|
|
4
|
-
RESET_AXES_RANGES,
|
|
5
|
-
SAVE_INITIAL_AXES_RANGES,
|
|
6
|
-
TOGGLE_ANNOTATION,
|
|
7
|
-
TOGGLE_DRAG_POINTS,
|
|
8
|
-
TOGGLE_LEGEND,
|
|
9
|
-
TOGGLE_LINE,
|
|
10
|
-
TOGGLE_PAN,
|
|
11
|
-
TOGGLE_POINTS,
|
|
12
|
-
TOGGLE_TABLE,
|
|
13
|
-
TOGGLE_ZOOM,
|
|
14
|
-
UPDATE_AXES_RANGES,
|
|
15
|
-
} from './action-types';
|
|
16
|
-
|
|
17
|
-
export const reducer = (state, action) => {
|
|
18
|
-
return produce(state, (draft) => {
|
|
19
|
-
switch (action.type) {
|
|
20
|
-
case TOGGLE_ZOOM: {
|
|
21
|
-
draft.zoomEnabled = !draft.zoomEnabled;
|
|
22
|
-
if (draft.panEnabled) {
|
|
23
|
-
draft.panEnabled = false;
|
|
24
|
-
}
|
|
25
|
-
if (draft.enableDragPoints) {
|
|
26
|
-
draft.enableDragPoints = false;
|
|
27
|
-
}
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
case TOGGLE_PAN: {
|
|
31
|
-
draft.panEnabled = !draft.panEnabled;
|
|
32
|
-
if (draft.zoomEnabled) {
|
|
33
|
-
draft.zoomEnabled = false;
|
|
34
|
-
}
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
case TOGGLE_POINTS: {
|
|
38
|
-
draft.pointsEnabled = !draft.pointsEnabled;
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
case TOGGLE_LINE: {
|
|
42
|
-
draft.lineEnabled = !draft.lineEnabled;
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
case TOGGLE_LEGEND: {
|
|
46
|
-
draft.legendEnabled = !draft.legendEnabled;
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
case TOGGLE_TABLE: {
|
|
50
|
-
draft.showTable = !draft.showTable;
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
case SAVE_INITIAL_AXES_RANGES: {
|
|
54
|
-
const { initialAxesRanges } = action.payload;
|
|
55
|
-
draft.initialAxesRanges = initialAxesRanges;
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
case UPDATE_AXES_RANGES: {
|
|
59
|
-
const { axes } = action.payload;
|
|
60
|
-
draft.axes = axes;
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
case RESET_AXES_RANGES: {
|
|
64
|
-
const { axes } = draft;
|
|
65
|
-
draft.axes = axes.map((axis) => ({
|
|
66
|
-
id: axis.id,
|
|
67
|
-
}));
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
case TOGGLE_ANNOTATION: {
|
|
71
|
-
const { annotationIndex } = action.payload;
|
|
72
|
-
const updatedIndexes = draft.showAnnotationLineIndex.includes(
|
|
73
|
-
annotationIndex,
|
|
74
|
-
)
|
|
75
|
-
? draft.showAnnotationLineIndex.filter((v) => v !== annotationIndex)
|
|
76
|
-
: [...draft.showAnnotationLineIndex, annotationIndex];
|
|
77
|
-
draft.showAnnotationLineIndex = updatedIndexes;
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
case TOGGLE_DRAG_POINTS: {
|
|
81
|
-
draft.enableDragPoints = !draft.enableDragPoints;
|
|
82
|
-
if (draft.panEnabled) {
|
|
83
|
-
draft.panEnabled = false;
|
|
84
|
-
}
|
|
85
|
-
if (draft.zoomEnabled) {
|
|
86
|
-
draft.zoomEnabled = false;
|
|
87
|
-
}
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
case DISABLE_DRAG_OPTIONS: {
|
|
91
|
-
if (draft.enableDragPoints || draft.panEnabled || draft.zoomEnabled) {
|
|
92
|
-
draft.enableDragPoints = false;
|
|
93
|
-
draft.panEnabled = false;
|
|
94
|
-
draft.zoomEnabled = false;
|
|
95
|
-
}
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
};
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Retrieves the chart state from local storage.
|
|
3
|
-
*
|
|
4
|
-
* @param {string|''} persistenceId - The chart persistenceId.
|
|
5
|
-
* @returns {object|null} The chart state object or null if not found.
|
|
6
|
-
*/
|
|
7
|
-
export const getChartStateFromStorage = (persistenceId) => {
|
|
8
|
-
if (!persistenceId) return null;
|
|
9
|
-
|
|
10
|
-
// Retrieve the chart state object from local storage
|
|
11
|
-
const chartStateKey = `line-chart-state-${persistenceId}`;
|
|
12
|
-
const chartStateObjectJSON = localStorage.getItem(chartStateKey);
|
|
13
|
-
|
|
14
|
-
if (chartStateObjectJSON) {
|
|
15
|
-
// If the chart state object was found, parse it
|
|
16
|
-
const chartStateObject = JSON.parse(chartStateObjectJSON);
|
|
17
|
-
|
|
18
|
-
// Return the state property of the parsed chart state object
|
|
19
|
-
return chartStateObject.state;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// If the chart state object was not found, return null
|
|
23
|
-
return null;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Remove expired chart states from local storage.
|
|
28
|
-
*
|
|
29
|
-
* @param {number} maxAgeInHours - The maximum age of chart states to keep in local storage (in hours). Default is 72 hours.
|
|
30
|
-
*/
|
|
31
|
-
const removeExpiredChartStates = (maxAgeInHours = 72) => {
|
|
32
|
-
const currentTime = new Date().getTime();
|
|
33
|
-
const maxAgeInMilliseconds = maxAgeInHours * 60 * 60 * 1000;
|
|
34
|
-
|
|
35
|
-
// Iterate through all keys in local storage
|
|
36
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
37
|
-
const key = localStorage.key(i);
|
|
38
|
-
|
|
39
|
-
// Check if the key is related to a line-chart-state
|
|
40
|
-
if (key.includes('line-chart-state-')) {
|
|
41
|
-
const chartStateObjectJSON = localStorage.getItem(key);
|
|
42
|
-
|
|
43
|
-
// If a valid chart state object JSON is found
|
|
44
|
-
if (chartStateObjectJSON) {
|
|
45
|
-
const chartStateObject = JSON.parse(chartStateObjectJSON);
|
|
46
|
-
const storedTime = chartStateObject.timestamp;
|
|
47
|
-
|
|
48
|
-
// If a valid timestamp is found
|
|
49
|
-
if (storedTime) {
|
|
50
|
-
const ageInMilliseconds = currentTime - storedTime;
|
|
51
|
-
|
|
52
|
-
// If the age of the chart state is older than the specified maxAgeInHours
|
|
53
|
-
if (ageInMilliseconds > maxAgeInMilliseconds) {
|
|
54
|
-
// Remove the expired chart state from local storage
|
|
55
|
-
localStorage.removeItem(key);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Stores the chart state in local storage.
|
|
65
|
-
*
|
|
66
|
-
* @param {object} state - The chart state object to store.
|
|
67
|
-
* @param {string|''} persistenceId - The chart persistenceId.
|
|
68
|
-
*/
|
|
69
|
-
export const storeChartStateInStorage = (state, persistenceId) => {
|
|
70
|
-
if (!persistenceId) return;
|
|
71
|
-
|
|
72
|
-
const currentTime = new Date().getTime();
|
|
73
|
-
const chartStateKey = `line-chart-state-${persistenceId}`;
|
|
74
|
-
|
|
75
|
-
// Create an object containing the chart state and the timestamp
|
|
76
|
-
const chartStateObject = {
|
|
77
|
-
state,
|
|
78
|
-
timestamp: currentTime,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
// Serialize the chart state object as a JSON string and store it in local storage
|
|
82
|
-
localStorage.setItem(chartStateKey, JSON.stringify(chartStateObject));
|
|
83
|
-
|
|
84
|
-
// Remove expired chart states from local storage
|
|
85
|
-
removeExpiredChartStates();
|
|
86
|
-
};
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
|
-
import { isEqual } from 'lodash';
|
|
3
|
-
import { storeChartStateInStorage } from './manage-state-in-local-storage';
|
|
4
|
-
import { SAVE_INITIAL_AXES_RANGES, UPDATE_AXES_RANGES } from './action-types';
|
|
5
|
-
import { getAxesRangesFromChart } from '../utils/get-axes-ranges-from-chart';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Hook for toggling the visibility of the custom legend.
|
|
9
|
-
*
|
|
10
|
-
* @param memoState - The memoized state object.
|
|
11
|
-
* @param memoOptions - The memoized options object.
|
|
12
|
-
*/
|
|
13
|
-
const useToggleCustomLegendVisibility = (memoState, memoOptions) => {
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (memoOptions.legend.customLegend.customLegendPlugin) {
|
|
16
|
-
// Get the parent element of the custom legend container and toggle its visibility based on the state.
|
|
17
|
-
const parent = document.getElementById(
|
|
18
|
-
memoOptions.legend.customLegend.customLegendContainerID,
|
|
19
|
-
);
|
|
20
|
-
parent.style.visibility = memoState.legendEnabled ? 'visible' : 'hidden';
|
|
21
|
-
}
|
|
22
|
-
}, [
|
|
23
|
-
memoOptions.legend.customLegend.customLegendPlugin,
|
|
24
|
-
memoState.legendEnabled,
|
|
25
|
-
]);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Hook for storing the chart state in local storage.
|
|
30
|
-
*
|
|
31
|
-
* @param memoState - The memoized state object.
|
|
32
|
-
* @param persistenceId - The chart persistenceId.
|
|
33
|
-
*/
|
|
34
|
-
const useStoreChartStateInStorage = (memoState, persistenceId) => {
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
// Store the chart state in local storage.
|
|
37
|
-
storeChartStateInStorage(memoState, persistenceId);
|
|
38
|
-
}, [
|
|
39
|
-
memoState.panEnabled,
|
|
40
|
-
memoState.lineEnabled,
|
|
41
|
-
memoState.pointsEnabled,
|
|
42
|
-
memoState.legendEnabled,
|
|
43
|
-
memoState.enableDragPoints,
|
|
44
|
-
memoState.zoomEnabled,
|
|
45
|
-
]);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Hook for updating the axes ranges in the chart state.
|
|
50
|
-
*
|
|
51
|
-
* @param range - The range to the chart.
|
|
52
|
-
* @param dispatch - The dispatch function for state management.
|
|
53
|
-
*/
|
|
54
|
-
const useUpdateAxesRanges = (range, dispatch) => {
|
|
55
|
-
const prevRange = useRef();
|
|
56
|
-
|
|
57
|
-
const updateAxesRanges = useCallback(() => {
|
|
58
|
-
if (range && range.x && range.y && !isEqual(range, prevRange.current)) {
|
|
59
|
-
const axes = Object.entries(range).map(([key, { min, max }]) => ({
|
|
60
|
-
id: key,
|
|
61
|
-
min: min ?? 0,
|
|
62
|
-
max: max ?? 0,
|
|
63
|
-
}));
|
|
64
|
-
dispatch({
|
|
65
|
-
type: UPDATE_AXES_RANGES,
|
|
66
|
-
payload: { axes },
|
|
67
|
-
});
|
|
68
|
-
prevRange.current = range;
|
|
69
|
-
}
|
|
70
|
-
}, [range]);
|
|
71
|
-
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
updateAxesRanges();
|
|
74
|
-
}, [updateAxesRanges]);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* A custom hook to save the initial axes ranges of a chart when the generated datasets change.
|
|
79
|
-
*
|
|
80
|
-
* @param {Object} chartRef - A reference to the chart object.
|
|
81
|
-
* @param {Array} axes - An array of axes configurations.
|
|
82
|
-
* @param {Array} generatedDatasets - An array of generated datasets for the chart.
|
|
83
|
-
* @param {Function} dispatch - A dispatch function from the useContext hook for managing the state.
|
|
84
|
-
*/
|
|
85
|
-
const useSaveInitialAxesRanges = (
|
|
86
|
-
chartRef,
|
|
87
|
-
axes,
|
|
88
|
-
generatedDatasets,
|
|
89
|
-
dispatch,
|
|
90
|
-
) => {
|
|
91
|
-
const prevGeneratedDatasets = useRef();
|
|
92
|
-
|
|
93
|
-
const saveInitialAxesRanges = useCallback(() => {
|
|
94
|
-
if (
|
|
95
|
-
chartRef &&
|
|
96
|
-
!isEqual(generatedDatasets, prevGeneratedDatasets.current)
|
|
97
|
-
) {
|
|
98
|
-
const initialAxesRanges = getAxesRangesFromChart(chartRef, axes);
|
|
99
|
-
dispatch({
|
|
100
|
-
type: SAVE_INITIAL_AXES_RANGES,
|
|
101
|
-
payload: { initialAxesRanges },
|
|
102
|
-
});
|
|
103
|
-
prevGeneratedDatasets.current = generatedDatasets;
|
|
104
|
-
}
|
|
105
|
-
}, [chartRef, generatedDatasets]);
|
|
106
|
-
|
|
107
|
-
useEffect(() => {
|
|
108
|
-
saveInitialAxesRanges();
|
|
109
|
-
}, [saveInitialAxesRanges, generatedDatasets]);
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Hook for managing the state of the chart.
|
|
114
|
-
*
|
|
115
|
-
* @param chartRef - The reference to the chart.
|
|
116
|
-
* @param options - The chart options.
|
|
117
|
-
* @param state - The chart state.
|
|
118
|
-
* @param {Array} generatedDatasets - An array of generated datasets for the chart.
|
|
119
|
-
* @param dispatch - The dispatch function for state management.
|
|
120
|
-
* @param persistenceId - The chart persistenceId.
|
|
121
|
-
*/
|
|
122
|
-
export const useChartState = ({
|
|
123
|
-
chartRef,
|
|
124
|
-
options,
|
|
125
|
-
state,
|
|
126
|
-
generatedDatasets,
|
|
127
|
-
dispatch,
|
|
128
|
-
persistenceId,
|
|
129
|
-
}) => {
|
|
130
|
-
const memoState = useMemo(() => state, [state]);
|
|
131
|
-
const memoOptions = useMemo(() => options, [options]);
|
|
132
|
-
const {
|
|
133
|
-
additionalAxesOptions: { range },
|
|
134
|
-
axes,
|
|
135
|
-
} = memoOptions;
|
|
136
|
-
|
|
137
|
-
useStoreChartStateInStorage(memoState, persistenceId);
|
|
138
|
-
useToggleCustomLegendVisibility(memoState, memoOptions);
|
|
139
|
-
useUpdateAxesRanges(range, dispatch);
|
|
140
|
-
useSaveInitialAxesRanges(chartRef, axes, generatedDatasets, dispatch);
|
|
141
|
-
};
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import getLineChartScales from '../get-line-chart-scales';
|
|
2
|
-
import { AxisType } from '../../../../helpers/enums';
|
|
3
|
-
import { getAxisTypeFromKey } from '../line-chart-utils';
|
|
4
|
-
import { estimateDataSeriesHaveCloseValues } from '../../../../helpers/range/estimate-data-series-have-close-values';
|
|
5
|
-
import { getSuggestedAxisRange } from '../../../../helpers/range/range';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
Function that counts the number of occurences of "x" and "y" in an array and returns the one with the highest count.
|
|
9
|
-
@param {Array} scalesKeys - An array of strings that may contain "x" or "y".
|
|
10
|
-
@return {string} - Returns "x" if "x" occurs more times, "y" if "y" occurs more times, or null if they occur the same number of times.
|
|
11
|
-
*/
|
|
12
|
-
const checkMultiAxis = (scalesKeys) => {
|
|
13
|
-
let counts = {
|
|
14
|
-
x: 0,
|
|
15
|
-
y: 0,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
scalesKeys.forEach((axeKey) => {
|
|
19
|
-
const key = getAxisTypeFromKey(axeKey);
|
|
20
|
-
counts[key]++;
|
|
21
|
-
});
|
|
22
|
-
const res =
|
|
23
|
-
(counts.x > counts.y && AxisType.X) ||
|
|
24
|
-
(counts.y > counts.x && AxisType.Y) ||
|
|
25
|
-
(counts.x === counts.y && null);
|
|
26
|
-
|
|
27
|
-
return res;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
Function that returns an object containing all the values for a specific key in an array of objects,
|
|
32
|
-
grouped by the unique values of another key in the same objects.
|
|
33
|
-
@param {Array} data - An array of objects to search for the keys.
|
|
34
|
-
@return {Object} - Returns an object with keys representing the unique values for the annotationAxis key in the data array,
|
|
35
|
-
and values representing an array of all values for the value key in the data array.
|
|
36
|
-
*/
|
|
37
|
-
const getAnnotationsData = (data) => {
|
|
38
|
-
return data.reduce((acc, obj) => {
|
|
39
|
-
return {
|
|
40
|
-
...acc,
|
|
41
|
-
[obj.annotationAxis]: [...(acc[obj.annotationAxis] || []), obj.value],
|
|
42
|
-
};
|
|
43
|
-
}, {});
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* return data for each axes
|
|
48
|
-
* @function getAxesData
|
|
49
|
-
* @return {object}
|
|
50
|
-
*/
|
|
51
|
-
const getAxesData = (scalesKeys, datasets, annotationsData) => {
|
|
52
|
-
const allData =
|
|
53
|
-
datasets?.reduce((acc, item) => [...acc, ...item.data], []) ?? [];
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* return data by key and depends on axes count
|
|
57
|
-
* @function getData
|
|
58
|
-
* @return {object}
|
|
59
|
-
*/
|
|
60
|
-
const getData = () => {
|
|
61
|
-
return scalesKeys.reduce((acc, axeKey) => {
|
|
62
|
-
const key = getAxisTypeFromKey(axeKey);
|
|
63
|
-
const data = getAnnotationsData(annotationsData);
|
|
64
|
-
const formData = allData
|
|
65
|
-
?.map((val) => val?.[key])
|
|
66
|
-
.concat(data[key] || []);
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
...acc,
|
|
70
|
-
[axeKey]: [...new Set(formData)],
|
|
71
|
-
};
|
|
72
|
-
}, {});
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
Function that returns an object containing the unique values for a multi axis key in an array of objects.
|
|
77
|
-
@return {Object} - Returns an object with key representing the found key in the scalesKeys array,
|
|
78
|
-
and values representing an array of unique values for that key in the datasets array. If no key is found, an empty object is returned.
|
|
79
|
-
*/
|
|
80
|
-
const getDataForMultiAxes = () => {
|
|
81
|
-
const multiAxesKey = checkMultiAxis(scalesKeys);
|
|
82
|
-
const axes = scalesKeys?.filter((key) => key?.includes(multiAxesKey)) ?? [];
|
|
83
|
-
const data = getAnnotationsData(annotationsData);
|
|
84
|
-
const [first, second] = axes;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Reduces an array of objects and returns an array of values from the specified key
|
|
88
|
-
* @param {Array} arr - The array of objects to be reduced
|
|
89
|
-
* @param {string} key - The key to extract the values from
|
|
90
|
-
* @returns {Array} - An array of values from the specified key
|
|
91
|
-
*/
|
|
92
|
-
const reduceData = (arr, key) =>
|
|
93
|
-
arr.reduce((acc, { [key]: value }) => [...acc, value], []);
|
|
94
|
-
|
|
95
|
-
return datasets.reduce(
|
|
96
|
-
(acc, obj) => {
|
|
97
|
-
const include = Object.values(obj).some((val) => axes.includes(val));
|
|
98
|
-
const key = include ? second : first;
|
|
99
|
-
|
|
100
|
-
return {
|
|
101
|
-
...acc,
|
|
102
|
-
[key]: [
|
|
103
|
-
...new Set([
|
|
104
|
-
...acc[key],
|
|
105
|
-
...reduceData(obj?.data, multiAxesKey),
|
|
106
|
-
...((!include && data?.[multiAxesKey]) || []),
|
|
107
|
-
]),
|
|
108
|
-
],
|
|
109
|
-
};
|
|
110
|
-
},
|
|
111
|
-
{ [first]: [], [second]: [] },
|
|
112
|
-
);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
...getData(),
|
|
117
|
-
...getDataForMultiAxes(),
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Auto scales axis ranges (mix, max) if no explicit range is set
|
|
123
|
-
* - overrides some edge cases not handled well by default chart.js
|
|
124
|
-
* - supports optional padding when `autoAxisPadding` is set
|
|
125
|
-
* - otherwise does not set min/max (falls back to chart.js default)
|
|
126
|
-
*
|
|
127
|
-
* @function autoScale
|
|
128
|
-
* @return {object} scales
|
|
129
|
-
*/
|
|
130
|
-
export const autoScale = (options, state, generatedDatasets) => {
|
|
131
|
-
const { additionalAxesOptions = {}, annotations = {} } = options || {};
|
|
132
|
-
const { annotationsData = [] } = annotations || {};
|
|
133
|
-
const scales = getLineChartScales(options, state) || {};
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
!additionalAxesOptions?.autoAxisPadding &&
|
|
137
|
-
!estimateDataSeriesHaveCloseValues(generatedDatasets)
|
|
138
|
-
) {
|
|
139
|
-
return scales;
|
|
140
|
-
}
|
|
141
|
-
const scalesKeys = Object.keys(scales) ?? [];
|
|
142
|
-
const data =
|
|
143
|
-
getAxesData(scalesKeys, generatedDatasets, annotationsData) ?? {};
|
|
144
|
-
|
|
145
|
-
const adjustedScales = scalesKeys?.reduce((acc, key) => {
|
|
146
|
-
const { min: propMin = undefined, max: propMax = undefined } = scales[key];
|
|
147
|
-
const { min, max } = getSuggestedAxisRange({
|
|
148
|
-
data: data[key],
|
|
149
|
-
beginAtZero: additionalAxesOptions?.beginAtZero,
|
|
150
|
-
autoAxisPadding: additionalAxesOptions?.autoAxisPadding,
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
const res = {
|
|
154
|
-
[key]: {
|
|
155
|
-
...scales[key],
|
|
156
|
-
min: propMin ?? min,
|
|
157
|
-
max: propMax ?? max,
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
return { ...acc, ...res };
|
|
162
|
-
}, {});
|
|
163
|
-
|
|
164
|
-
return adjustedScales ?? scales;
|
|
165
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/** returning boolean condition depends on label position and chart area
|
|
2
|
-
*
|
|
3
|
-
* @return {object} - returning object with boolean props
|
|
4
|
-
*/
|
|
5
|
-
export const getCondition = (x, y, left, right, bottom) => {
|
|
6
|
-
const threshold = 100;
|
|
7
|
-
const overLeftSide = x - threshold <= left;
|
|
8
|
-
const overRightSide = x + threshold >= right;
|
|
9
|
-
const overBottomSide =
|
|
10
|
-
x + threshold >= left && x + threshold < right && y + threshold >= bottom;
|
|
11
|
-
|
|
12
|
-
return { overLeftSide, overRightSide, overBottomSide };
|
|
13
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/** returning destructured data from context
|
|
2
|
-
*
|
|
3
|
-
* @return {object}
|
|
4
|
-
*/
|
|
5
|
-
export const getAlignmentData = (context) => {
|
|
6
|
-
const { chart = {}, dataIndex = 0, datasetIndex = 0 } = context || {};
|
|
7
|
-
const { chartArea = {} } = chart;
|
|
8
|
-
const { left = null, right = null, bottom = null } = chartArea;
|
|
9
|
-
|
|
10
|
-
const meta = chart.getDatasetMeta(datasetIndex);
|
|
11
|
-
const { x = null, y = null } = meta?.data?.[dataIndex] || {};
|
|
12
|
-
|
|
13
|
-
return {
|
|
14
|
-
x,
|
|
15
|
-
y,
|
|
16
|
-
left,
|
|
17
|
-
right,
|
|
18
|
-
bottom,
|
|
19
|
-
};
|
|
20
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { getCondition } from './get-alignment-condition';
|
|
2
|
-
import { getAlignmentData } from './get-alignment-data';
|
|
3
|
-
import { AlignOptions } from '../../../../helpers/enums';
|
|
4
|
-
|
|
5
|
-
/** returning position depends on condition
|
|
6
|
-
*
|
|
7
|
-
* @return {string} - position
|
|
8
|
-
*/
|
|
9
|
-
export const getPosition = () => {
|
|
10
|
-
return (context) => {
|
|
11
|
-
const { x, y, left, right, bottom } = getAlignmentData(context);
|
|
12
|
-
const {
|
|
13
|
-
overLeftSide = false,
|
|
14
|
-
overRightSide = false,
|
|
15
|
-
overBottomSide = false,
|
|
16
|
-
} = getCondition(x, y, left, right, bottom);
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
(overLeftSide && AlignOptions.Right) ||
|
|
20
|
-
(overRightSide && AlignOptions.Left) ||
|
|
21
|
-
(overBottomSide && AlignOptions.End) ||
|
|
22
|
-
AlignOptions.Start
|
|
23
|
-
);
|
|
24
|
-
};
|
|
25
|
-
};
|