@oliasoft-open-source/charts-library 2.13.4 → 2.14.0-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/package.json +2 -2
- package/release-notes.md +4 -0
- package/src/components/controls/axes-options/axes-options.jsx +43 -9
- package/src/components/line-chart/constants/default-translations.js +24 -0
- package/src/components/line-chart/{line-chart-consts.js → constants/line-chart-consts.js} +1 -0
- package/src/components/line-chart/controls/axes-options/action-types.js +5 -0
- package/src/components/{controls → line-chart/controls}/axes-options/axes-options-form-state.js +19 -20
- package/src/components/line-chart/controls/controls.jsx +174 -0
- package/src/components/line-chart/controls/drag-options.jsx +112 -0
- package/src/components/line-chart/controls/legend-options.jsx +36 -0
- package/src/components/{controls → line-chart/controls}/line-options.jsx +18 -8
- package/src/components/line-chart/hooks/use-chart-functions.js +257 -0
- package/src/components/line-chart/hooks/use-chart-options.js +155 -0
- package/src/components/line-chart/hooks/use-chart-plugins.js +26 -0
- package/src/components/line-chart/hooks/use-toggle-handler.js +33 -0
- package/src/components/line-chart/line-chart.jsx +54 -447
- package/src/components/line-chart/state/initial-state.js +7 -8
- package/src/components/line-chart/state/line-chart-reducer.js +68 -86
- package/src/components/line-chart/state/use-chart-state.js +73 -12
- package/src/components/line-chart/{axis-scales → utils/axis-scales}/axis-scales.js +3 -3
- package/src/components/line-chart/{datalabels-alignment → utils/datalabels-alignment}/get-datalabels-position.js +1 -1
- package/src/components/line-chart/utils/generate-line-chart-datasets.js +114 -0
- package/src/components/line-chart/{get-line-chart-data-labels.js → utils/get-line-chart-data-labels.js} +2 -2
- package/src/components/line-chart/{get-line-chart-scales.js → utils/get-line-chart-scales.js} +11 -11
- package/src/components/line-chart/{get-line-chart-tooltips.js → utils/get-line-chart-tooltips.js} +6 -3
- package/src/components/line-chart/utils/get-translations/get-translations.js +17 -0
- package/src/helpers/chart-utils.js +3 -5
- package/src/helpers/enums.js +9 -0
- package/src/components/controls/controls.jsx +0 -114
- package/src/components/controls/drag-options.jsx +0 -98
- package/src/components/controls/legend-options.jsx +0 -25
- /package/src/components/{controls → line-chart/controls}/controls.module.less +0 -0
- /package/src/components/line-chart/{datalabels-alignment → utils/datalabels-alignment}/get-alignment-condition.js +0 -0
- /package/src/components/line-chart/{datalabels-alignment → utils/datalabels-alignment}/get-alignment-data.js +0 -0
- /package/src/components/line-chart/{get-axes-ranges-from-chart.js → utils/get-axes-ranges-from-chart.js} +0 -0
- /package/src/components/line-chart/{line-chart-utils.js → utils/line-chart-utils.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oliasoft-open-source/charts-library",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0-beta-1",
|
|
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": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
]
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"chart.js": "^
|
|
36
|
+
"chart.js": "^4.2.1",
|
|
37
37
|
"chartjs-plugin-annotation": "^1.4.0",
|
|
38
38
|
"chartjs-plugin-datalabels": "^2.1.0",
|
|
39
39
|
"chartjs-plugin-dragdata": "^2.2.5",
|
package/release-notes.md
CHANGED
|
@@ -14,13 +14,14 @@ import {
|
|
|
14
14
|
Tooltip,
|
|
15
15
|
} from '@oliasoft-open-source/react-ui-library';
|
|
16
16
|
import { RiRuler2Line } from 'react-icons/ri';
|
|
17
|
-
import
|
|
17
|
+
import PropTypes from 'prop-types';
|
|
18
|
+
import { toNum } from '@oliasoft-open-source/units';
|
|
18
19
|
import {
|
|
19
|
-
actionTypes,
|
|
20
|
-
reducer,
|
|
21
20
|
initializeFormState,
|
|
21
|
+
reducer,
|
|
22
22
|
validateAxes,
|
|
23
|
-
} from '
|
|
23
|
+
} from '../../line-chart/controls/axes-options/axes-options-form-state';
|
|
24
|
+
import { actionTypes } from '../../line-chart/controls/axes-options/action-types';
|
|
24
25
|
|
|
25
26
|
const AxesOptionsPopover = ({
|
|
26
27
|
initialAxesRanges,
|
|
@@ -30,6 +31,7 @@ const AxesOptionsPopover = ({
|
|
|
30
31
|
onResetAxes,
|
|
31
32
|
close,
|
|
32
33
|
depthType,
|
|
34
|
+
translations,
|
|
33
35
|
}) => {
|
|
34
36
|
const [depthTypeState, setDepthTypeState] = useState(
|
|
35
37
|
depthType?.selectedDepthType,
|
|
@@ -43,7 +45,7 @@ const AxesOptionsPopover = ({
|
|
|
43
45
|
initializeFormState,
|
|
44
46
|
);
|
|
45
47
|
|
|
46
|
-
const { errors, valid } = validateAxes(formState);
|
|
48
|
+
const { errors, valid } = validateAxes(formState, translations);
|
|
47
49
|
|
|
48
50
|
const onEditValue = ({ name, value, id }) => {
|
|
49
51
|
dispatch({
|
|
@@ -189,16 +191,22 @@ const AxesOptionsPopover = ({
|
|
|
189
191
|
) : null}
|
|
190
192
|
|
|
191
193
|
<Flex gap="8px" alignItems="center">
|
|
192
|
-
<Button
|
|
194
|
+
<Button
|
|
195
|
+
type="submit"
|
|
196
|
+
small
|
|
197
|
+
colored
|
|
198
|
+
label={translations.done}
|
|
199
|
+
disabled={!valid}
|
|
200
|
+
/>
|
|
193
201
|
<Button
|
|
194
202
|
small
|
|
195
203
|
name="resetAxes"
|
|
196
|
-
label=
|
|
204
|
+
label={translations.resetAxes}
|
|
197
205
|
onClick={onReset}
|
|
198
206
|
disabled={!isCustomValue}
|
|
199
207
|
/>
|
|
200
208
|
<Text small muted>
|
|
201
|
-
|
|
209
|
+
{translations.orDoubleClickToCanvas}
|
|
202
210
|
</Text>
|
|
203
211
|
</Flex>
|
|
204
212
|
</form>
|
|
@@ -212,6 +220,7 @@ export const AxesOptions = ({
|
|
|
212
220
|
onUpdateAxes,
|
|
213
221
|
onResetAxes,
|
|
214
222
|
depthType,
|
|
223
|
+
translations,
|
|
215
224
|
}) => {
|
|
216
225
|
return (
|
|
217
226
|
<Popover
|
|
@@ -225,12 +234,37 @@ export const AxesOptions = ({
|
|
|
225
234
|
onUpdateAxes={onUpdateAxes}
|
|
226
235
|
onResetAxes={onResetAxes}
|
|
227
236
|
depthType={depthType}
|
|
237
|
+
translations={translations}
|
|
228
238
|
/>
|
|
229
239
|
}
|
|
230
240
|
>
|
|
231
|
-
<Tooltip
|
|
241
|
+
<Tooltip
|
|
242
|
+
text={translations.axesOptions}
|
|
243
|
+
placement="bottom"
|
|
244
|
+
display="flex"
|
|
245
|
+
>
|
|
232
246
|
<Button small basic colored="muted" round icon={<RiRuler2Line />} />
|
|
233
247
|
</Tooltip>
|
|
234
248
|
</Popover>
|
|
235
249
|
);
|
|
236
250
|
};
|
|
251
|
+
|
|
252
|
+
AxesOptionsPopover.defaultProps = {
|
|
253
|
+
depthType: null,
|
|
254
|
+
initialAxesRanges: [],
|
|
255
|
+
close: () => {},
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
AxesOptionsPopover.propTypes = {
|
|
259
|
+
initialAxesRanges: PropTypes.arrayOf(PropTypes.shape({})),
|
|
260
|
+
axes: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
|
|
261
|
+
controlsAxesLabels: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
|
|
262
|
+
onUpdateAxes: PropTypes.func.isRequired,
|
|
263
|
+
onResetAxes: PropTypes.func.isRequired,
|
|
264
|
+
close: PropTypes.func,
|
|
265
|
+
depthType: PropTypes.shape({
|
|
266
|
+
selectedDepthType: PropTypes.string,
|
|
267
|
+
setSelectedDepthType: PropTypes.func,
|
|
268
|
+
options: PropTypes.arrayOf(PropTypes.string),
|
|
269
|
+
}),
|
|
270
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
});
|
package/src/components/{controls → line-chart/controls}/axes-options/axes-options-form-state.js
RENAMED
|
@@ -3,13 +3,8 @@ import {
|
|
|
3
3
|
isGreaterThanMin,
|
|
4
4
|
isLessThanMax,
|
|
5
5
|
validNumber,
|
|
6
|
-
} from '../../
|
|
7
|
-
|
|
8
|
-
export const actionTypes = Object.freeze({
|
|
9
|
-
reset: 'reset',
|
|
10
|
-
valueUpdated: 'valueUpdated',
|
|
11
|
-
unitUpdated: 'unitUpdated',
|
|
12
|
-
});
|
|
6
|
+
} from '../../utils/line-chart-utils';
|
|
7
|
+
import { actionTypes } from './action-types';
|
|
13
8
|
|
|
14
9
|
/**
|
|
15
10
|
* Initialize local component form state for a custom loads density table
|
|
@@ -39,23 +34,27 @@ export const initializeFormState = ({ initialAxesRanges, axes = [] }) => {
|
|
|
39
34
|
|
|
40
35
|
const isEmptyString = (value) => value === '';
|
|
41
36
|
|
|
42
|
-
|
|
37
|
+
const createErrorMessages = (value, compareTo, type, translations) => {
|
|
38
|
+
const errors = [];
|
|
39
|
+
if (isEmptyString(value)) errors.push(translations.mustHaveAValue);
|
|
40
|
+
if (!validNumber(value)) errors.push(translations.mustBeANumber);
|
|
41
|
+
|
|
42
|
+
if (type === 'min' && !isLessThanMax(value, compareTo)) {
|
|
43
|
+
errors.push(translations.mustBeLessThanMax);
|
|
44
|
+
} else if (type === 'max' && !isGreaterThanMin(value, compareTo)) {
|
|
45
|
+
errors.push(translations.mustBeGreaterThanMin);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return errors;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const validateAxes = (formState, translations) => {
|
|
43
52
|
return formState.reduce(
|
|
44
53
|
(acc, { id, min, max }) => {
|
|
45
54
|
return produce(acc, (draft) => {
|
|
46
55
|
const errors = {
|
|
47
|
-
min:
|
|
48
|
-
|
|
49
|
-
...(!validNumber(min) ? ['Must be a number'] : []),
|
|
50
|
-
...(!isLessThanMax(min, max) ? ['Must be less than max'] : []),
|
|
51
|
-
],
|
|
52
|
-
max: [
|
|
53
|
-
...(isEmptyString(max) ? ['Must have a value'] : []),
|
|
54
|
-
...(!validNumber(max) ? ['Must be a number'] : []),
|
|
55
|
-
...(!isGreaterThanMin(max, min)
|
|
56
|
-
? ['Must be greater than min']
|
|
57
|
-
: []),
|
|
58
|
-
],
|
|
56
|
+
min: createErrorMessages(min, max, 'min', translations),
|
|
57
|
+
max: createErrorMessages(max, min, 'max', translations),
|
|
59
58
|
};
|
|
60
59
|
draft.errors.push({
|
|
61
60
|
id,
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button, Text, Tooltip } from '@oliasoft-open-source/react-ui-library';
|
|
3
|
+
import {
|
|
4
|
+
RiFileDownloadLine,
|
|
5
|
+
RiLineChartLine,
|
|
6
|
+
RiTableLine,
|
|
7
|
+
} from 'react-icons/ri';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
|
+
import { LineOptions } from './line-options';
|
|
10
|
+
import { DragOptions } from './drag-options';
|
|
11
|
+
import { LegendOptions } from './legend-options';
|
|
12
|
+
import styles from './controls.module.less';
|
|
13
|
+
import { useToggleHandlers } from '../hooks/use-toggle-handler';
|
|
14
|
+
import { useChartFunctions } from '../hooks/use-chart-functions';
|
|
15
|
+
import { AxesOptions } from '../../controls/axes-options/axes-options';
|
|
16
|
+
|
|
17
|
+
const Controls = ({
|
|
18
|
+
props: { headerComponent, subheaderComponent, table },
|
|
19
|
+
chartRef,
|
|
20
|
+
state,
|
|
21
|
+
options,
|
|
22
|
+
dispatch,
|
|
23
|
+
generatedDatasets,
|
|
24
|
+
translations,
|
|
25
|
+
}) => {
|
|
26
|
+
const {
|
|
27
|
+
enableDragPoints,
|
|
28
|
+
initialAxesRanges,
|
|
29
|
+
legendEnabled,
|
|
30
|
+
lineEnabled,
|
|
31
|
+
panEnabled,
|
|
32
|
+
pointsEnabled,
|
|
33
|
+
showTable,
|
|
34
|
+
zoomEnabled,
|
|
35
|
+
} = state;
|
|
36
|
+
const { dragData } = options;
|
|
37
|
+
const {
|
|
38
|
+
onToggleLegend,
|
|
39
|
+
onToggleLine,
|
|
40
|
+
onTogglePan,
|
|
41
|
+
onTogglePoints,
|
|
42
|
+
onToggleTable,
|
|
43
|
+
onToggleZoom,
|
|
44
|
+
onToggleDragPoints,
|
|
45
|
+
onDisableDragOptions,
|
|
46
|
+
} = useToggleHandlers(dispatch);
|
|
47
|
+
const {
|
|
48
|
+
handleDownload,
|
|
49
|
+
controlsAxes,
|
|
50
|
+
controlsAxesLabels,
|
|
51
|
+
onResetAxes,
|
|
52
|
+
onUpdateAxes,
|
|
53
|
+
} = useChartFunctions({
|
|
54
|
+
chartRef,
|
|
55
|
+
state,
|
|
56
|
+
options,
|
|
57
|
+
dispatch,
|
|
58
|
+
generatedDatasets,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<div className={styles.controls}>
|
|
64
|
+
{!!options.title && <Text bold>{options.title}</Text>}
|
|
65
|
+
{headerComponent}
|
|
66
|
+
<div className={styles.buttons}>
|
|
67
|
+
{!showTable && (
|
|
68
|
+
<>
|
|
69
|
+
<AxesOptions
|
|
70
|
+
initialAxesRanges={initialAxesRanges}
|
|
71
|
+
axes={controlsAxes}
|
|
72
|
+
controlsAxesLabels={controlsAxesLabels}
|
|
73
|
+
onUpdateAxes={onUpdateAxes}
|
|
74
|
+
onResetAxes={onResetAxes}
|
|
75
|
+
depthType={options.depthType}
|
|
76
|
+
translations={translations}
|
|
77
|
+
/>
|
|
78
|
+
<LineOptions
|
|
79
|
+
lineEnabled={lineEnabled}
|
|
80
|
+
pointsEnabled={pointsEnabled}
|
|
81
|
+
onToggleLine={onToggleLine}
|
|
82
|
+
onTogglePoints={onTogglePoints}
|
|
83
|
+
translations={translations}
|
|
84
|
+
/>
|
|
85
|
+
<LegendOptions
|
|
86
|
+
legendEnabled={legendEnabled}
|
|
87
|
+
onToggleLegend={onToggleLegend}
|
|
88
|
+
translations={translations}
|
|
89
|
+
/>
|
|
90
|
+
<Tooltip text={translations.downloadAsPNG} placement="bottom-end">
|
|
91
|
+
<Button
|
|
92
|
+
small
|
|
93
|
+
basic
|
|
94
|
+
colored="muted"
|
|
95
|
+
round
|
|
96
|
+
icon={<RiFileDownloadLine />}
|
|
97
|
+
onClick={handleDownload}
|
|
98
|
+
/>
|
|
99
|
+
</Tooltip>
|
|
100
|
+
<DragOptions
|
|
101
|
+
panEnabled={panEnabled}
|
|
102
|
+
zoomEnabled={zoomEnabled}
|
|
103
|
+
onTogglePan={onTogglePan}
|
|
104
|
+
onToggleZoom={onToggleZoom}
|
|
105
|
+
enableDragPoints={enableDragPoints}
|
|
106
|
+
isDragDataAllowed={dragData.enableDragData}
|
|
107
|
+
onToggleDragPoints={onToggleDragPoints}
|
|
108
|
+
onDisableDragOptions={onDisableDragOptions}
|
|
109
|
+
translations={translations}
|
|
110
|
+
/>
|
|
111
|
+
</>
|
|
112
|
+
)}
|
|
113
|
+
|
|
114
|
+
{table ? (
|
|
115
|
+
<Tooltip
|
|
116
|
+
text={showTable ? translations.showChart : translations.showTable}
|
|
117
|
+
placement="bottom-end"
|
|
118
|
+
>
|
|
119
|
+
<Button
|
|
120
|
+
small
|
|
121
|
+
basic
|
|
122
|
+
colored="muted"
|
|
123
|
+
round
|
|
124
|
+
icon={showTable ? <RiLineChartLine /> : <RiTableLine />}
|
|
125
|
+
onClick={onToggleTable}
|
|
126
|
+
/>
|
|
127
|
+
</Tooltip>
|
|
128
|
+
) : null}
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
{subheaderComponent}
|
|
132
|
+
</>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
Controls.defaultProps = {
|
|
137
|
+
props: {
|
|
138
|
+
headerComponent: null,
|
|
139
|
+
subheaderComponent: null,
|
|
140
|
+
table: null,
|
|
141
|
+
},
|
|
142
|
+
state: {
|
|
143
|
+
initialAxesRanges: [],
|
|
144
|
+
},
|
|
145
|
+
options: {},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
Controls.propTypes = {
|
|
149
|
+
props: PropTypes.shape({
|
|
150
|
+
headerComponent: PropTypes.node,
|
|
151
|
+
subheaderComponent: PropTypes.node,
|
|
152
|
+
table: PropTypes.node,
|
|
153
|
+
}),
|
|
154
|
+
chartRef: PropTypes.object.isRequired,
|
|
155
|
+
state: PropTypes.shape({
|
|
156
|
+
enableDragPoints: PropTypes.bool,
|
|
157
|
+
initialAxesRanges: PropTypes.arrayOf(PropTypes.shape({})),
|
|
158
|
+
legendEnabled: PropTypes.bool,
|
|
159
|
+
lineEnabled: PropTypes.bool,
|
|
160
|
+
panEnabled: PropTypes.bool,
|
|
161
|
+
pointsEnabled: PropTypes.bool,
|
|
162
|
+
showTable: PropTypes.bool,
|
|
163
|
+
zoomEnabled: PropTypes.bool,
|
|
164
|
+
}),
|
|
165
|
+
options: PropTypes.shape({
|
|
166
|
+
dragData: PropTypes.shape({
|
|
167
|
+
enableDragData: PropTypes.bool,
|
|
168
|
+
}),
|
|
169
|
+
}),
|
|
170
|
+
dispatch: PropTypes.func.isRequired,
|
|
171
|
+
generatedDatasets: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export default Controls;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Flex, Menu, Text } from '@oliasoft-open-source/react-ui-library';
|
|
4
|
+
import { RiDragMove2Line, RiForbidLine, RiZoomInLine } from 'react-icons/ri';
|
|
5
|
+
import { TbHandStop } from 'react-icons/tb';
|
|
6
|
+
|
|
7
|
+
export const DragOptions = ({
|
|
8
|
+
onTogglePan,
|
|
9
|
+
onToggleZoom,
|
|
10
|
+
panEnabled,
|
|
11
|
+
zoomEnabled,
|
|
12
|
+
enableDragPoints,
|
|
13
|
+
isDragDataAllowed,
|
|
14
|
+
onToggleDragPoints,
|
|
15
|
+
onDisableDragOptions,
|
|
16
|
+
translations: {
|
|
17
|
+
dragToZoom,
|
|
18
|
+
doubleClickToReset,
|
|
19
|
+
dragToPan,
|
|
20
|
+
orDoubleClickToCanvas,
|
|
21
|
+
dragToMovePoints,
|
|
22
|
+
dragDisabled,
|
|
23
|
+
},
|
|
24
|
+
}) => {
|
|
25
|
+
const options = useMemo(
|
|
26
|
+
() => [
|
|
27
|
+
{
|
|
28
|
+
buttonLabel: dragToZoom,
|
|
29
|
+
label: (
|
|
30
|
+
<Flex direction="column">
|
|
31
|
+
<Text>Drag to zoom</Text>
|
|
32
|
+
<Text small muted>
|
|
33
|
+
{doubleClickToReset}
|
|
34
|
+
</Text>
|
|
35
|
+
</Flex>
|
|
36
|
+
),
|
|
37
|
+
icon: <RiZoomInLine />,
|
|
38
|
+
selected: zoomEnabled,
|
|
39
|
+
onClick: onToggleZoom,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
buttonLabel: dragToPan,
|
|
43
|
+
label: (
|
|
44
|
+
<Flex direction="column">
|
|
45
|
+
<Text>Drag to pan</Text>
|
|
46
|
+
<Text small muted>
|
|
47
|
+
{orDoubleClickToCanvas}
|
|
48
|
+
</Text>
|
|
49
|
+
</Flex>
|
|
50
|
+
),
|
|
51
|
+
icon: <RiDragMove2Line />,
|
|
52
|
+
selected: panEnabled,
|
|
53
|
+
onClick: onTogglePan,
|
|
54
|
+
},
|
|
55
|
+
...(isDragDataAllowed
|
|
56
|
+
? [
|
|
57
|
+
{
|
|
58
|
+
label: dragToMovePoints,
|
|
59
|
+
icon: <TbHandStop />,
|
|
60
|
+
selected: enableDragPoints,
|
|
61
|
+
type: 'Option',
|
|
62
|
+
onClick: onToggleDragPoints,
|
|
63
|
+
},
|
|
64
|
+
]
|
|
65
|
+
: []),
|
|
66
|
+
{
|
|
67
|
+
label: dragDisabled,
|
|
68
|
+
icon: <RiForbidLine />,
|
|
69
|
+
selected: !zoomEnabled && !panEnabled && !enableDragPoints,
|
|
70
|
+
onClick: onDisableDragOptions,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
[zoomEnabled, panEnabled, enableDragPoints, isDragDataAllowed],
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const selectedOption = options.find((option) => option.selected);
|
|
77
|
+
const optionsWithDragPoints = options.map(
|
|
78
|
+
({ icon, label, onClick, selected }) => ({
|
|
79
|
+
icon,
|
|
80
|
+
label,
|
|
81
|
+
type: 'Option',
|
|
82
|
+
onClick,
|
|
83
|
+
disabled: selected,
|
|
84
|
+
}),
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<Menu
|
|
89
|
+
menu={{
|
|
90
|
+
label: selectedOption.buttonLabel || selectedOption.label,
|
|
91
|
+
sections: optionsWithDragPoints,
|
|
92
|
+
trigger: 'DropDownButton',
|
|
93
|
+
small: true,
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
DragOptions.defaultProps = {
|
|
100
|
+
enableDragPoints: false,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
DragOptions.propTypes = {
|
|
104
|
+
onTogglePan: PropTypes.func.isRequired,
|
|
105
|
+
onToggleZoom: PropTypes.func.isRequired,
|
|
106
|
+
panEnabled: PropTypes.bool.isRequired,
|
|
107
|
+
zoomEnabled: PropTypes.bool.isRequired,
|
|
108
|
+
enableDragPoints: PropTypes.bool,
|
|
109
|
+
isDragDataAllowed: PropTypes.bool.isRequired,
|
|
110
|
+
onToggleDragPoints: PropTypes.func.isRequired,
|
|
111
|
+
onDisableDragOptions: PropTypes.func.isRequired,
|
|
112
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Button, Icon, Tooltip } from '@oliasoft-open-source/react-ui-library';
|
|
4
|
+
import { RiListUnordered } from 'react-icons/ri';
|
|
5
|
+
import listHideIcon from '../../../assets/icons/list-hide.svg';
|
|
6
|
+
|
|
7
|
+
export const LegendOptions = ({
|
|
8
|
+
legendEnabled,
|
|
9
|
+
onToggleLegend,
|
|
10
|
+
translations: { hideLegend, showLegend },
|
|
11
|
+
}) => {
|
|
12
|
+
const tooltipText = legendEnabled ? hideLegend : showLegend;
|
|
13
|
+
const icon = legendEnabled ? (
|
|
14
|
+
<RiListUnordered />
|
|
15
|
+
) : (
|
|
16
|
+
<Icon icon={listHideIcon} />
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Tooltip text={tooltipText} placement="bottom">
|
|
21
|
+
<Button
|
|
22
|
+
small
|
|
23
|
+
basic
|
|
24
|
+
colored="muted"
|
|
25
|
+
round
|
|
26
|
+
icon={icon}
|
|
27
|
+
onClick={onToggleLegend}
|
|
28
|
+
/>
|
|
29
|
+
</Tooltip>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
LegendOptions.propTypes = {
|
|
34
|
+
legendEnabled: PropTypes.bool.isRequired,
|
|
35
|
+
onToggleLegend: PropTypes.func.isRequired,
|
|
36
|
+
};
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Button, Icon, Tooltip } from '@oliasoft-open-source/react-ui-library';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import lineOnlyIcon from '../../../assets/icons/line-only.svg';
|
|
5
|
+
import pointOnlyIcon from '../../../assets/icons/point-only.svg';
|
|
6
|
+
import lineAndPointIcon from '../../../assets/icons/line-and-point.svg';
|
|
6
7
|
|
|
7
8
|
export const LineOptions = ({
|
|
8
9
|
lineEnabled,
|
|
9
10
|
onToggleLine,
|
|
10
11
|
onTogglePoints,
|
|
11
12
|
pointsEnabled,
|
|
13
|
+
translations,
|
|
12
14
|
}) => {
|
|
13
|
-
// TODO: Translate strings
|
|
14
15
|
const options = [
|
|
15
16
|
{
|
|
16
|
-
label:
|
|
17
|
+
label: translations.pointsLines,
|
|
17
18
|
icon: <Icon icon={lineAndPointIcon} />,
|
|
18
19
|
selected: pointsEnabled && lineEnabled,
|
|
19
20
|
onClick: () => {
|
|
@@ -21,7 +22,7 @@ export const LineOptions = ({
|
|
|
21
22
|
},
|
|
22
23
|
},
|
|
23
24
|
{
|
|
24
|
-
label:
|
|
25
|
+
label: translations.linesOnly,
|
|
25
26
|
icon: <Icon icon={lineOnlyIcon} />,
|
|
26
27
|
selected: !pointsEnabled && lineEnabled,
|
|
27
28
|
onClick: () => {
|
|
@@ -30,7 +31,7 @@ export const LineOptions = ({
|
|
|
30
31
|
},
|
|
31
32
|
},
|
|
32
33
|
{
|
|
33
|
-
label:
|
|
34
|
+
label: translations.pointsOnly,
|
|
34
35
|
icon: <Icon icon={pointOnlyIcon} />,
|
|
35
36
|
selected: pointsEnabled && !lineEnabled,
|
|
36
37
|
onClick: () => {
|
|
@@ -38,7 +39,9 @@ export const LineOptions = ({
|
|
|
38
39
|
},
|
|
39
40
|
},
|
|
40
41
|
];
|
|
41
|
-
|
|
42
|
+
|
|
43
|
+
const selectedOption = options.find((option) => option.selected);
|
|
44
|
+
|
|
42
45
|
return (
|
|
43
46
|
<Tooltip text={selectedOption.label} placement="bottom">
|
|
44
47
|
<Button
|
|
@@ -52,3 +55,10 @@ export const LineOptions = ({
|
|
|
52
55
|
</Tooltip>
|
|
53
56
|
);
|
|
54
57
|
};
|
|
58
|
+
|
|
59
|
+
LineOptions.propTypes = {
|
|
60
|
+
lineEnabled: PropTypes.bool.isRequired,
|
|
61
|
+
onToggleLine: PropTypes.func.isRequired,
|
|
62
|
+
onTogglePoints: PropTypes.func.isRequired,
|
|
63
|
+
pointsEnabled: PropTypes.bool.isRequired,
|
|
64
|
+
};
|