@oliasoft-open-source/charts-library 2.14.0-beta-1 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/release-notes.md +3 -0
- package/src/components/controls/axes-options/axes-options.jsx +5 -18
- package/src/components/line-chart/controls/axes-options/axes-options-form-state.js +8 -8
- package/src/components/line-chart/controls/controls.jsx +2 -7
- package/src/components/line-chart/controls/drag-options.jsx +6 -14
- package/src/components/line-chart/controls/legend-options.jsx +2 -6
- package/src/components/line-chart/controls/line-options.jsx +3 -4
- package/src/components/line-chart/line-chart.jsx +2 -6
- package/src/components/line-chart/utils/generate-line-chart-datasets.js +2 -8
- package/src/components/line-chart/constants/default-translations.js +0 -24
- package/src/components/line-chart/utils/get-translations/get-translations.js +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oliasoft-open-source/charts-library",
|
|
3
|
-
"version": "2.14.0
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "React Chart Library (based on Chart.js and react-chart-js-2)",
|
|
5
5
|
"homepage": "https://gitlab.com/oliasoft-open-source/charts-library",
|
|
6
6
|
"bugs": {
|
package/release-notes.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Charts Library Release Notes
|
|
2
2
|
|
|
3
|
+
## 2.14.0
|
|
4
|
+
- Refactored line chart, for better performance, readable and reduce not needed re-renders
|
|
5
|
+
|
|
3
6
|
## 2.13.5
|
|
4
7
|
|
|
5
8
|
- Fixed reset range when subComponent update data, prevent extra re-renders when range have same deep values but different reference
|
|
@@ -31,7 +31,6 @@ const AxesOptionsPopover = ({
|
|
|
31
31
|
onResetAxes,
|
|
32
32
|
close,
|
|
33
33
|
depthType,
|
|
34
|
-
translations,
|
|
35
34
|
}) => {
|
|
36
35
|
const [depthTypeState, setDepthTypeState] = useState(
|
|
37
36
|
depthType?.selectedDepthType,
|
|
@@ -45,7 +44,7 @@ const AxesOptionsPopover = ({
|
|
|
45
44
|
initializeFormState,
|
|
46
45
|
);
|
|
47
46
|
|
|
48
|
-
const { errors, valid } = validateAxes(formState
|
|
47
|
+
const { errors, valid } = validateAxes(formState);
|
|
49
48
|
|
|
50
49
|
const onEditValue = ({ name, value, id }) => {
|
|
51
50
|
dispatch({
|
|
@@ -191,22 +190,16 @@ const AxesOptionsPopover = ({
|
|
|
191
190
|
) : null}
|
|
192
191
|
|
|
193
192
|
<Flex gap="8px" alignItems="center">
|
|
194
|
-
<Button
|
|
195
|
-
type="submit"
|
|
196
|
-
small
|
|
197
|
-
colored
|
|
198
|
-
label={translations.done}
|
|
199
|
-
disabled={!valid}
|
|
200
|
-
/>
|
|
193
|
+
<Button type="submit" small colored label="Done" disabled={!valid} />
|
|
201
194
|
<Button
|
|
202
195
|
small
|
|
203
196
|
name="resetAxes"
|
|
204
|
-
label=
|
|
197
|
+
label="Reset Axes"
|
|
205
198
|
onClick={onReset}
|
|
206
199
|
disabled={!isCustomValue}
|
|
207
200
|
/>
|
|
208
201
|
<Text small muted>
|
|
209
|
-
|
|
202
|
+
or double click on canvas
|
|
210
203
|
</Text>
|
|
211
204
|
</Flex>
|
|
212
205
|
</form>
|
|
@@ -220,7 +213,6 @@ export const AxesOptions = ({
|
|
|
220
213
|
onUpdateAxes,
|
|
221
214
|
onResetAxes,
|
|
222
215
|
depthType,
|
|
223
|
-
translations,
|
|
224
216
|
}) => {
|
|
225
217
|
return (
|
|
226
218
|
<Popover
|
|
@@ -234,15 +226,10 @@ export const AxesOptions = ({
|
|
|
234
226
|
onUpdateAxes={onUpdateAxes}
|
|
235
227
|
onResetAxes={onResetAxes}
|
|
236
228
|
depthType={depthType}
|
|
237
|
-
translations={translations}
|
|
238
229
|
/>
|
|
239
230
|
}
|
|
240
231
|
>
|
|
241
|
-
<Tooltip
|
|
242
|
-
text={translations.axesOptions}
|
|
243
|
-
placement="bottom"
|
|
244
|
-
display="flex"
|
|
245
|
-
>
|
|
232
|
+
<Tooltip text="Axes options" placement="bottom" display="flex">
|
|
246
233
|
<Button small basic colored="muted" round icon={<RiRuler2Line />} />
|
|
247
234
|
</Tooltip>
|
|
248
235
|
</Popover>
|
|
@@ -34,27 +34,27 @@ export const initializeFormState = ({ initialAxesRanges, axes = [] }) => {
|
|
|
34
34
|
|
|
35
35
|
const isEmptyString = (value) => value === '';
|
|
36
36
|
|
|
37
|
-
const createErrorMessages = (value, compareTo, type
|
|
37
|
+
const createErrorMessages = (value, compareTo, type) => {
|
|
38
38
|
const errors = [];
|
|
39
|
-
if (isEmptyString(value)) errors.push(
|
|
40
|
-
if (!validNumber(value)) errors.push(
|
|
39
|
+
if (isEmptyString(value)) errors.push('Must have a value');
|
|
40
|
+
if (!validNumber(value)) errors.push('Must be a number');
|
|
41
41
|
|
|
42
42
|
if (type === 'min' && !isLessThanMax(value, compareTo)) {
|
|
43
|
-
errors.push(
|
|
43
|
+
errors.push('Must be less than max');
|
|
44
44
|
} else if (type === 'max' && !isGreaterThanMin(value, compareTo)) {
|
|
45
|
-
errors.push(
|
|
45
|
+
errors.push('Must be greater than min');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
return errors;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
export const validateAxes = (formState
|
|
51
|
+
export const validateAxes = (formState) => {
|
|
52
52
|
return formState.reduce(
|
|
53
53
|
(acc, { id, min, max }) => {
|
|
54
54
|
return produce(acc, (draft) => {
|
|
55
55
|
const errors = {
|
|
56
|
-
min: createErrorMessages(min, max, 'min'
|
|
57
|
-
max: createErrorMessages(max, min, 'max'
|
|
56
|
+
min: createErrorMessages(min, max, 'min'),
|
|
57
|
+
max: createErrorMessages(max, min, 'max'),
|
|
58
58
|
};
|
|
59
59
|
draft.errors.push({
|
|
60
60
|
id,
|
|
@@ -21,7 +21,6 @@ const Controls = ({
|
|
|
21
21
|
options,
|
|
22
22
|
dispatch,
|
|
23
23
|
generatedDatasets,
|
|
24
|
-
translations,
|
|
25
24
|
}) => {
|
|
26
25
|
const {
|
|
27
26
|
enableDragPoints,
|
|
@@ -73,21 +72,18 @@ const Controls = ({
|
|
|
73
72
|
onUpdateAxes={onUpdateAxes}
|
|
74
73
|
onResetAxes={onResetAxes}
|
|
75
74
|
depthType={options.depthType}
|
|
76
|
-
translations={translations}
|
|
77
75
|
/>
|
|
78
76
|
<LineOptions
|
|
79
77
|
lineEnabled={lineEnabled}
|
|
80
78
|
pointsEnabled={pointsEnabled}
|
|
81
79
|
onToggleLine={onToggleLine}
|
|
82
80
|
onTogglePoints={onTogglePoints}
|
|
83
|
-
translations={translations}
|
|
84
81
|
/>
|
|
85
82
|
<LegendOptions
|
|
86
83
|
legendEnabled={legendEnabled}
|
|
87
84
|
onToggleLegend={onToggleLegend}
|
|
88
|
-
translations={translations}
|
|
89
85
|
/>
|
|
90
|
-
<Tooltip text=
|
|
86
|
+
<Tooltip text="Download as PNG" placement="bottom-end">
|
|
91
87
|
<Button
|
|
92
88
|
small
|
|
93
89
|
basic
|
|
@@ -106,14 +102,13 @@ const Controls = ({
|
|
|
106
102
|
isDragDataAllowed={dragData.enableDragData}
|
|
107
103
|
onToggleDragPoints={onToggleDragPoints}
|
|
108
104
|
onDisableDragOptions={onDisableDragOptions}
|
|
109
|
-
translations={translations}
|
|
110
105
|
/>
|
|
111
106
|
</>
|
|
112
107
|
)}
|
|
113
108
|
|
|
114
109
|
{table ? (
|
|
115
110
|
<Tooltip
|
|
116
|
-
text={showTable ?
|
|
111
|
+
text={showTable ? 'Show chart' : 'Show table'}
|
|
117
112
|
placement="bottom-end"
|
|
118
113
|
>
|
|
119
114
|
<Button
|
|
@@ -13,24 +13,16 @@ export const DragOptions = ({
|
|
|
13
13
|
isDragDataAllowed,
|
|
14
14
|
onToggleDragPoints,
|
|
15
15
|
onDisableDragOptions,
|
|
16
|
-
translations: {
|
|
17
|
-
dragToZoom,
|
|
18
|
-
doubleClickToReset,
|
|
19
|
-
dragToPan,
|
|
20
|
-
orDoubleClickToCanvas,
|
|
21
|
-
dragToMovePoints,
|
|
22
|
-
dragDisabled,
|
|
23
|
-
},
|
|
24
16
|
}) => {
|
|
25
17
|
const options = useMemo(
|
|
26
18
|
() => [
|
|
27
19
|
{
|
|
28
|
-
buttonLabel:
|
|
20
|
+
buttonLabel: 'Drag to zoom',
|
|
29
21
|
label: (
|
|
30
22
|
<Flex direction="column">
|
|
31
23
|
<Text>Drag to zoom</Text>
|
|
32
24
|
<Text small muted>
|
|
33
|
-
|
|
25
|
+
Double click on canvas to reset
|
|
34
26
|
</Text>
|
|
35
27
|
</Flex>
|
|
36
28
|
),
|
|
@@ -39,12 +31,12 @@ export const DragOptions = ({
|
|
|
39
31
|
onClick: onToggleZoom,
|
|
40
32
|
},
|
|
41
33
|
{
|
|
42
|
-
buttonLabel:
|
|
34
|
+
buttonLabel: 'Drag to pan',
|
|
43
35
|
label: (
|
|
44
36
|
<Flex direction="column">
|
|
45
37
|
<Text>Drag to pan</Text>
|
|
46
38
|
<Text small muted>
|
|
47
|
-
|
|
39
|
+
Double click on canvas to reset
|
|
48
40
|
</Text>
|
|
49
41
|
</Flex>
|
|
50
42
|
),
|
|
@@ -55,7 +47,7 @@ export const DragOptions = ({
|
|
|
55
47
|
...(isDragDataAllowed
|
|
56
48
|
? [
|
|
57
49
|
{
|
|
58
|
-
label:
|
|
50
|
+
label: 'Drag to move points',
|
|
59
51
|
icon: <TbHandStop />,
|
|
60
52
|
selected: enableDragPoints,
|
|
61
53
|
type: 'Option',
|
|
@@ -64,7 +56,7 @@ export const DragOptions = ({
|
|
|
64
56
|
]
|
|
65
57
|
: []),
|
|
66
58
|
{
|
|
67
|
-
label:
|
|
59
|
+
label: 'Drag disabled',
|
|
68
60
|
icon: <RiForbidLine />,
|
|
69
61
|
selected: !zoomEnabled && !panEnabled && !enableDragPoints,
|
|
70
62
|
onClick: onDisableDragOptions,
|
|
@@ -4,12 +4,8 @@ import { Button, Icon, Tooltip } from '@oliasoft-open-source/react-ui-library';
|
|
|
4
4
|
import { RiListUnordered } from 'react-icons/ri';
|
|
5
5
|
import listHideIcon from '../../../assets/icons/list-hide.svg';
|
|
6
6
|
|
|
7
|
-
export const LegendOptions = ({
|
|
8
|
-
legendEnabled
|
|
9
|
-
onToggleLegend,
|
|
10
|
-
translations: { hideLegend, showLegend },
|
|
11
|
-
}) => {
|
|
12
|
-
const tooltipText = legendEnabled ? hideLegend : showLegend;
|
|
7
|
+
export const LegendOptions = ({ legendEnabled, onToggleLegend }) => {
|
|
8
|
+
const tooltipText = legendEnabled ? 'Hide Legend' : 'Show Legend';
|
|
13
9
|
const icon = legendEnabled ? (
|
|
14
10
|
<RiListUnordered />
|
|
15
11
|
) : (
|
|
@@ -10,11 +10,10 @@ export const LineOptions = ({
|
|
|
10
10
|
onToggleLine,
|
|
11
11
|
onTogglePoints,
|
|
12
12
|
pointsEnabled,
|
|
13
|
-
translations,
|
|
14
13
|
}) => {
|
|
15
14
|
const options = [
|
|
16
15
|
{
|
|
17
|
-
label:
|
|
16
|
+
label: 'Points & lines',
|
|
18
17
|
icon: <Icon icon={lineAndPointIcon} />,
|
|
19
18
|
selected: pointsEnabled && lineEnabled,
|
|
20
19
|
onClick: () => {
|
|
@@ -22,7 +21,7 @@ export const LineOptions = ({
|
|
|
22
21
|
},
|
|
23
22
|
},
|
|
24
23
|
{
|
|
25
|
-
label:
|
|
24
|
+
label: 'Lines only',
|
|
26
25
|
icon: <Icon icon={lineOnlyIcon} />,
|
|
27
26
|
selected: !pointsEnabled && lineEnabled,
|
|
28
27
|
onClick: () => {
|
|
@@ -31,7 +30,7 @@ export const LineOptions = ({
|
|
|
31
30
|
},
|
|
32
31
|
},
|
|
33
32
|
{
|
|
34
|
-
label:
|
|
33
|
+
label: 'Points only',
|
|
35
34
|
icon: <Icon icon={pointOnlyIcon} />,
|
|
36
35
|
selected: pointsEnabled && !lineEnabled,
|
|
37
36
|
onClick: () => {
|
|
@@ -29,8 +29,6 @@ import { useChartOptions } from './hooks/use-chart-options';
|
|
|
29
29
|
import { useChartPlugins } from './hooks/use-chart-plugins';
|
|
30
30
|
import { generateKey } from './utils/line-chart-utils';
|
|
31
31
|
import { useChartState } from './state/use-chart-state';
|
|
32
|
-
import { defaultTranslations } from './constants/default-translations';
|
|
33
|
-
import { getTranslations } from './utils/get-translations/get-translations';
|
|
34
32
|
|
|
35
33
|
ChartJS.register(
|
|
36
34
|
LinearScale,
|
|
@@ -55,8 +53,7 @@ ChartJS.register(
|
|
|
55
53
|
const LineChart = (props) => {
|
|
56
54
|
setDefaultTheme();
|
|
57
55
|
const chartRef = useRef(null);
|
|
58
|
-
const { table
|
|
59
|
-
const translations = getTranslations(translationsRaw);
|
|
56
|
+
const { table } = props;
|
|
60
57
|
const chart = getDefaultProps(props);
|
|
61
58
|
const {
|
|
62
59
|
data: { datasets },
|
|
@@ -79,7 +76,7 @@ const LineChart = (props) => {
|
|
|
79
76
|
);
|
|
80
77
|
|
|
81
78
|
const generatedDatasets = useMemo(() => {
|
|
82
|
-
return generateLineChartDatasets(datasets, state, options
|
|
79
|
+
return generateLineChartDatasets(datasets, state, options);
|
|
83
80
|
}, [state.lineEnabled, state.pointsEnabled, axes, annotations, graph]);
|
|
84
81
|
|
|
85
82
|
// Call the custom hooks.
|
|
@@ -128,7 +125,6 @@ const LineChart = (props) => {
|
|
|
128
125
|
options={options}
|
|
129
126
|
dispatch={dispatch}
|
|
130
127
|
generatedDatasets={generatedDatasets}
|
|
131
|
-
translations={translations}
|
|
132
128
|
/>
|
|
133
129
|
{table && state.showTable ? (
|
|
134
130
|
<div className={styles.table}>{table}</div>
|
|
@@ -15,15 +15,9 @@ import { generateRandomColor } from '../../../helpers/chart-utils';
|
|
|
15
15
|
* @param {Array} datasets - The initial datasets for the line chart.
|
|
16
16
|
* @param {Object} state - The state object containing chart settings (e.g., lineEnabled, pointsEnabled, axes).
|
|
17
17
|
* @param {Object} options - The options object containing additional settings (e.g., annotations, graph).
|
|
18
|
-
* @param {Object} translations - The translations object containing translations string
|
|
19
18
|
* @returns {Array} - The generated line chart datasets with applied settings and configurations.
|
|
20
19
|
*/
|
|
21
|
-
export const generateLineChartDatasets = (
|
|
22
|
-
datasets,
|
|
23
|
-
state,
|
|
24
|
-
options,
|
|
25
|
-
translations,
|
|
26
|
-
) => {
|
|
20
|
+
export const generateLineChartDatasets = (datasets, state, options) => {
|
|
27
21
|
const copyDataset = [...datasets];
|
|
28
22
|
const { annotations, graph } = options;
|
|
29
23
|
const {
|
|
@@ -94,7 +88,7 @@ export const generateLineChartDatasets = (
|
|
|
94
88
|
// Return the dataset with applied settings and configurations
|
|
95
89
|
return {
|
|
96
90
|
...line,
|
|
97
|
-
label: line.label ||
|
|
91
|
+
label: line.label || `Label ${i + 1}`,
|
|
98
92
|
data: filteredData,
|
|
99
93
|
showLine: lineEnabled,
|
|
100
94
|
lineTension,
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export const defaultTranslations = Object.freeze({
|
|
2
|
-
label: 'Label',
|
|
3
|
-
pointsLines: 'Points & lines',
|
|
4
|
-
linesOnly: 'Lines only',
|
|
5
|
-
pointsOnly: 'Points only',
|
|
6
|
-
axesOptions: 'Axes options',
|
|
7
|
-
resetAxes: 'Reset Axes',
|
|
8
|
-
done: 'Done',
|
|
9
|
-
downloadAsPNG: 'Download as PNG',
|
|
10
|
-
showChart: 'Show chart',
|
|
11
|
-
showTable: 'Show table',
|
|
12
|
-
dragToZoom: 'Drag to zoom',
|
|
13
|
-
dragToPan: 'Drag to pan',
|
|
14
|
-
dragToMovePoints: 'Drag to move points',
|
|
15
|
-
dragDisabled: 'Drag disabled',
|
|
16
|
-
hideLegend: 'Hide Legend',
|
|
17
|
-
showLegend: 'Show Legend',
|
|
18
|
-
mustHaveAValue: 'Must have a value',
|
|
19
|
-
mustBeANumber: 'Must be a number',
|
|
20
|
-
mustBeLessThanMax: 'Must be less than max',
|
|
21
|
-
mustBeGreaterThanMin: 'Must be greater than min',
|
|
22
|
-
doubleClickToReset: 'Double click on canvas to reset',
|
|
23
|
-
orDoubleClickToCanvas: 'or double click on canvas',
|
|
24
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { defaultTranslations } from '../../constants/default-translations';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Merges custom translations with the default translations.
|
|
5
|
-
* If a custom translation is provided for a key, it will override the default one.
|
|
6
|
-
* @param {object} translations - Custom translations.
|
|
7
|
-
* @returns {object} - The resulting translations object, containing both default and custom translations.
|
|
8
|
-
*/
|
|
9
|
-
export const getTranslations = (translations = {}) => {
|
|
10
|
-
return Object.keys(defaultTranslations).reduce(
|
|
11
|
-
(acc, key) => ({
|
|
12
|
-
...acc,
|
|
13
|
-
[key]: translations[key] || defaultTranslations[key],
|
|
14
|
-
}),
|
|
15
|
-
{},
|
|
16
|
-
);
|
|
17
|
-
};
|