@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.
Files changed (36) hide show
  1. package/package.json +2 -2
  2. package/release-notes.md +4 -0
  3. package/src/components/controls/axes-options/axes-options.jsx +43 -9
  4. package/src/components/line-chart/constants/default-translations.js +24 -0
  5. package/src/components/line-chart/{line-chart-consts.js → constants/line-chart-consts.js} +1 -0
  6. package/src/components/line-chart/controls/axes-options/action-types.js +5 -0
  7. package/src/components/{controls → line-chart/controls}/axes-options/axes-options-form-state.js +19 -20
  8. package/src/components/line-chart/controls/controls.jsx +174 -0
  9. package/src/components/line-chart/controls/drag-options.jsx +112 -0
  10. package/src/components/line-chart/controls/legend-options.jsx +36 -0
  11. package/src/components/{controls → line-chart/controls}/line-options.jsx +18 -8
  12. package/src/components/line-chart/hooks/use-chart-functions.js +257 -0
  13. package/src/components/line-chart/hooks/use-chart-options.js +155 -0
  14. package/src/components/line-chart/hooks/use-chart-plugins.js +26 -0
  15. package/src/components/line-chart/hooks/use-toggle-handler.js +33 -0
  16. package/src/components/line-chart/line-chart.jsx +54 -447
  17. package/src/components/line-chart/state/initial-state.js +7 -8
  18. package/src/components/line-chart/state/line-chart-reducer.js +68 -86
  19. package/src/components/line-chart/state/use-chart-state.js +73 -12
  20. package/src/components/line-chart/{axis-scales → utils/axis-scales}/axis-scales.js +3 -3
  21. package/src/components/line-chart/{datalabels-alignment → utils/datalabels-alignment}/get-datalabels-position.js +1 -1
  22. package/src/components/line-chart/utils/generate-line-chart-datasets.js +114 -0
  23. package/src/components/line-chart/{get-line-chart-data-labels.js → utils/get-line-chart-data-labels.js} +2 -2
  24. package/src/components/line-chart/{get-line-chart-scales.js → utils/get-line-chart-scales.js} +11 -11
  25. package/src/components/line-chart/{get-line-chart-tooltips.js → utils/get-line-chart-tooltips.js} +6 -3
  26. package/src/components/line-chart/utils/get-translations/get-translations.js +17 -0
  27. package/src/helpers/chart-utils.js +3 -5
  28. package/src/helpers/enums.js +9 -0
  29. package/src/components/controls/controls.jsx +0 -114
  30. package/src/components/controls/drag-options.jsx +0 -98
  31. package/src/components/controls/legend-options.jsx +0 -25
  32. /package/src/components/{controls → line-chart/controls}/controls.module.less +0 -0
  33. /package/src/components/line-chart/{datalabels-alignment → utils/datalabels-alignment}/get-alignment-condition.js +0 -0
  34. /package/src/components/line-chart/{datalabels-alignment → utils/datalabels-alignment}/get-alignment-data.js +0 -0
  35. /package/src/components/line-chart/{get-axes-ranges-from-chart.js → utils/get-axes-ranges-from-chart.js} +0 -0
  36. /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.13.4",
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": "^3.9.1",
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
@@ -1,5 +1,9 @@
1
1
  # Charts Library Release Notes
2
2
 
3
+ ## 2.13.5
4
+
5
+ - Fixed reset range when subComponent update data, prevent extra re-renders when range have same deep values but different reference
6
+
3
7
  ## 2.13.4
4
8
 
5
9
  - Fixed legend state
@@ -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 { toNum } from '../../line-chart/line-chart-utils';
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 './axes-options-form-state';
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 type="submit" small colored label="Done" disabled={!valid} />
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="Reset Axes"
204
+ label={translations.resetAxes}
197
205
  onClick={onReset}
198
206
  disabled={!isCustomValue}
199
207
  />
200
208
  <Text small muted>
201
- or double click on canvas
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 text="Axes options" placement="bottom" display="flex">
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
+ });
@@ -5,3 +5,4 @@ export const BORDER_JOIN_STYLE = 'round';
5
5
  export const DEFAULT_LINE_POINT_RADIUS = 0;
6
6
  export const DEFAULT_BACKGROUND_COLOR = 'transparent';
7
7
  export const ZOOM_BOX_BACKGROUND_COLOR = 'rgba(0, 0, 0, 0.1)';
8
+ export const DOUBLE_CLICK = 'dblclick';
@@ -0,0 +1,5 @@
1
+ export const actionTypes = Object.freeze({
2
+ reset: 'reset',
3
+ valueUpdated: 'valueUpdated',
4
+ unitUpdated: 'unitUpdated',
5
+ });
@@ -3,13 +3,8 @@ import {
3
3
  isGreaterThanMin,
4
4
  isLessThanMax,
5
5
  validNumber,
6
- } from '../../line-chart/line-chart-utils';
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
- export const validateAxes = (formState) => {
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
- ...(isEmptyString(min) ? ['Must have a value'] : []),
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 lineOnlyIcon from '../../assets/icons/line-only.svg';
4
- import pointOnlyIcon from '../../assets/icons/point-only.svg';
5
- import lineAndPointIcon from '../../assets/icons/line-and-point.svg';
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: 'Points & lines',
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: 'Lines only',
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: 'Points only',
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
- const selectedOption = options.filter((option) => option.selected)[0];
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
+ };