@oliasoft-open-source/charts-library 2.11.2 → 2.12.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oliasoft-open-source/charts-library",
3
- "version": "2.11.2",
3
+ "version": "2.12.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": {
@@ -49,7 +49,7 @@
49
49
  "@babel/eslint-parser": "^7.18.9",
50
50
  "@babel/preset-env": "^7.18.10",
51
51
  "@babel/preset-react": "^7.18.6",
52
- "@oliasoft-open-source/react-ui-library": "3.3.11-beta-1",
52
+ "@oliasoft-open-source/react-ui-library": "3.3.12",
53
53
  "@oliasoft-open-source/units": "2.1.0",
54
54
  "@storybook/addon-actions": "^6.5.10",
55
55
  "@storybook/addon-docs": "^6.5.10",
package/release-notes.md CHANGED
@@ -1,9 +1,17 @@
1
1
  # Charts Library Release Notes
2
2
 
3
+ ## 2.12.0
4
+
5
+ - Add unit selector and depth selector to axes options ([OW-9496](https://oliasoft.atlassian.net/browse/OW-9496))
6
+
7
+ ## 2.11.3
8
+
9
+ - Submit Axes option on keyboard Enter ([OW-10995](https://oliasoft.atlassian.net/browse/OW-10995))
10
+
3
11
  ## 2.11.2
4
12
 
5
13
  - remove number handling functions that were duplicated from units package
6
- ([OW-11062](https://oliasoft.atlassian.net/browse/OW-11062))
14
+ ([OW-11062](https://oliasoft.atlassian.net/browse/OW-11062))
7
15
 
8
16
  ## 2.11.1
9
17
 
@@ -20,7 +28,7 @@
20
28
  ## 2.10.1
21
29
 
22
30
  - Use `peerDependencies` for common versions of shared packages like `units` and `react-ui-library` so reduce double
23
- installs and conflicting versions in parent apps ([OW-10974](https://oliasoft.atlassian.net/browse/OW-10974))
31
+ installs and conflicting versions in parent apps ([OW-10974](https://oliasoft.atlassian.net/browse/OW-10974))
24
32
 
25
33
  ## 2.10.0
26
34
 
@@ -8,6 +8,7 @@ import {
8
8
  export const actionTypes = Object.freeze({
9
9
  reset: 'reset',
10
10
  valueUpdated: 'valueUpdated',
11
+ unitUpdated: 'unitUpdated',
11
12
  });
12
13
 
13
14
  /**
@@ -25,6 +26,7 @@ export const initializeFormState = ({ initialAxesRanges, axes = [] }) => {
25
26
  id: initialAxisRange.id,
26
27
  min: currentAxisRange?.min ?? initialAxisRange?.min,
27
28
  max: currentAxisRange?.max ?? initialAxisRange?.max,
29
+ unit: currentAxisRange?.unit,
28
30
  };
29
31
  });
30
32
  };
@@ -80,8 +82,8 @@ export const validateAxes = (formState) => {
80
82
  export const reducer = (state, action) => {
81
83
  switch (action.type) {
82
84
  case actionTypes.reset: {
83
- const { initialAxesRanges } = action.payload;
84
- return initializeFormState({ initialAxesRanges });
85
+ const { initialAxesRanges, axes } = action.payload;
86
+ return initializeFormState({ initialAxesRanges, axes });
85
87
  }
86
88
  case actionTypes.valueUpdated:
87
89
  return produce(state, (draft) => {
@@ -89,6 +91,12 @@ export const reducer = (state, action) => {
89
91
  const axis = draft.find((a) => a.id === id);
90
92
  axis[name] = value;
91
93
  });
94
+ case actionTypes.unitUpdated:
95
+ return produce(state, (draft) => {
96
+ const { name, value, id } = action.payload;
97
+ const axis = draft.find((a) => a.id === id);
98
+ axis.unit[name] = value;
99
+ });
92
100
  default:
93
101
  return state;
94
102
  }
@@ -1,12 +1,15 @@
1
- import React, { useReducer } from 'react';
1
+ import React, { useReducer, useState } from 'react';
2
2
  import {
3
3
  Button,
4
+ ButtonGroup,
4
5
  Field,
5
6
  Flex,
6
7
  Input,
7
8
  InputGroup,
8
9
  InputGroupAddon,
9
10
  Popover,
11
+ Select,
12
+ Spacer,
10
13
  Text,
11
14
  Tooltip,
12
15
  } from '@oliasoft-open-source/react-ui-library';
@@ -26,7 +29,11 @@ const AxesOptionsPopover = ({
26
29
  onUpdateAxes,
27
30
  onResetAxes,
28
31
  close,
32
+ depthType,
29
33
  }) => {
34
+ const [depthTypeState, setDepthTypeState] = useState(
35
+ depthType?.selectedDepthType,
36
+ );
30
37
  const [formState, dispatch] = useReducer(
31
38
  reducer,
32
39
  {
@@ -45,7 +52,15 @@ const AxesOptionsPopover = ({
45
52
  });
46
53
  };
47
54
 
48
- const onDone = () => {
55
+ const onEditUnit = ({ name, value, id }) => {
56
+ dispatch({
57
+ type: actionTypes.unitUpdated,
58
+ payload: { name, value, id },
59
+ });
60
+ };
61
+
62
+ const onDone = (e) => {
63
+ e.preventDefault();
49
64
  if (valid) {
50
65
  const sanitizedFormState = formState.map((axis) => ({
51
66
  ...axis,
@@ -55,6 +70,17 @@ const AxesOptionsPopover = ({
55
70
  onUpdateAxes({
56
71
  axes: sanitizedFormState,
57
72
  });
73
+
74
+ //update units
75
+ sanitizedFormState.map((el, i) => {
76
+ if (el.unit?.selectedUnit) {
77
+ axes[i].unit.setSelectedUnit(el.unit.selectedUnit);
78
+ }
79
+ });
80
+ //update depthType
81
+ if (depthType) {
82
+ depthType.setSelectedDepthType(depthTypeState);
83
+ }
58
84
  }
59
85
  close();
60
86
  };
@@ -65,14 +91,22 @@ const AxesOptionsPopover = ({
65
91
  type: actionTypes.reset,
66
92
  payload: { axes, initialAxesRanges },
67
93
  });
94
+ //update units
95
+ initialAxesRanges.map((el, i) => {
96
+ if (el?.unit?.selectedUnit) {
97
+ axes[i].unit.setSelectedUnit(el.unit.selectedUnit);
98
+ }
99
+ });
100
+
68
101
  //reset parent state
69
102
  onResetAxes();
103
+ close();
70
104
  };
71
105
 
72
106
  const isCustomValue = axes.filter((axis) => axis.max || axis.min).length > 0;
73
107
  const handleInputFocus = (e) => e.target.select();
74
108
  return (
75
- <>
109
+ <form onSubmit={onDone}>
76
110
  {axes.map((axis, i) => {
77
111
  const axisLabel = controlsAxesLabels.find(
78
112
  (el) => el.id === axis.id,
@@ -82,6 +116,7 @@ const AxesOptionsPopover = ({
82
116
  const max = formState.find((a) => a.id === axis.id)?.max;
83
117
  const minError = errors?.find((a) => a.id === axis.id)?.min?.[0];
84
118
  const maxError = errors?.find((a) => a.id === axis.id)?.max?.[0];
119
+ const unit = formState.find((a) => a.id === axis.id)?.unit;
85
120
  return (
86
121
  <Field key={i} label={axisLabel || axis.id || ''}>
87
122
  <InputGroup small>
@@ -116,12 +151,45 @@ const AxesOptionsPopover = ({
116
151
  }
117
152
  onFocus={handleInputFocus}
118
153
  />
154
+ {axis.unit ? (
155
+ <Select
156
+ name="selectedUnit"
157
+ options={axis?.unit?.options}
158
+ value={unit?.selectedUnit}
159
+ onChange={(e) => {
160
+ onEditUnit({
161
+ name: e.target.name,
162
+ value: e.target.value,
163
+ id: axis.id,
164
+ });
165
+ }}
166
+ width="auto"
167
+ />
168
+ ) : null}
119
169
  </InputGroup>
120
170
  </Field>
121
171
  );
122
172
  })}
173
+
174
+ {depthType?.options?.length > 0 ? (
175
+ <>
176
+ <ButtonGroup
177
+ items={depthType.options.map((depth, i) => ({
178
+ key: i,
179
+ label: depth,
180
+ }))}
181
+ onSelected={(key) => {
182
+ setDepthTypeState(depthType.options[key]);
183
+ }}
184
+ small
185
+ value={depthType.options.indexOf(depthTypeState)}
186
+ />
187
+ <Spacer />
188
+ </>
189
+ ) : null}
190
+
123
191
  <Flex gap="8px" alignItems="center">
124
- <Button small colored label="Done" onClick={onDone} disabled={!valid} />
192
+ <Button type="submit" small colored label="Done" disabled={!valid} />
125
193
  <Button
126
194
  small
127
195
  name="resetAxes"
@@ -133,7 +201,7 @@ const AxesOptionsPopover = ({
133
201
  or double click on canvas
134
202
  </Text>
135
203
  </Flex>
136
- </>
204
+ </form>
137
205
  );
138
206
  };
139
207
 
@@ -143,6 +211,7 @@ export const AxesOptions = ({
143
211
  controlsAxesLabels,
144
212
  onUpdateAxes,
145
213
  onResetAxes,
214
+ depthType,
146
215
  }) => {
147
216
  return (
148
217
  <Popover
@@ -155,6 +224,7 @@ export const AxesOptions = ({
155
224
  controlsAxesLabels={controlsAxesLabels}
156
225
  onUpdateAxes={onUpdateAxes}
157
226
  onResetAxes={onResetAxes}
227
+ depthType={depthType}
158
228
  />
159
229
  }
160
230
  >
@@ -34,6 +34,7 @@ const Controls = ({
34
34
  subheaderComponent,
35
35
  table,
36
36
  zoomEnabled,
37
+ depthType,
37
38
  enableDragPoints,
38
39
  isDragDataAllowed,
39
40
  onToggleDragPoints,
@@ -53,6 +54,7 @@ const Controls = ({
53
54
  controlsAxesLabels={controlsAxesLabels}
54
55
  onUpdateAxes={onUpdateAxes}
55
56
  onResetAxes={onResetAxes}
57
+ depthType={depthType}
56
58
  />
57
59
  <LineOptions
58
60
  lineEnabled={lineEnabled}
@@ -1,10 +1,13 @@
1
- export const getAxesRangesFromChart = (chartRef) => {
1
+ export const getAxesRangesFromChart = (chartRef, axes) => {
2
2
  const { scales = {} } = chartRef.current || {};
3
- return Object.entries(scales).map(([key, { min, max }]) => {
3
+ return Object.entries(scales).map(([key, { min, max }], i) => {
4
+ const axesArray = axes.x.concat(axes.y);
5
+ const unit = axesArray?.[i]?.unit;
4
6
  return {
5
7
  id: key,
6
8
  min,
7
9
  max,
10
+ ...(unit ? { unit } : {}),
8
11
  };
9
12
  });
10
13
  };
@@ -16,6 +16,11 @@ export const LineChartPropTypes = {
16
16
  label: PropTypes.string,
17
17
  position: PropTypes.oneOf(['top', 'bottom']),
18
18
  color: PropTypes.string,
19
+ unit: PropTypes.shape({
20
+ options: PropTypes.arrayOf(PropTypes.string),
21
+ selectedUnit: PropTypes.string,
22
+ setSelectedUnit: PropTypes.func,
23
+ }),
19
24
  }),
20
25
  ),
21
26
  y: PropTypes.arrayOf(
@@ -106,6 +111,11 @@ export const LineChartPropTypes = {
106
111
  onPointUnhover: PropTypes.func,
107
112
  onAnimationComplete: PropTypes.func,
108
113
  }),
114
+ depthType: PropTypes.shape({
115
+ options: PropTypes.arrayOf(PropTypes.string),
116
+ selectedDepthType: PropTypes.string,
117
+ setSelectedDepthType: PropTypes.func,
118
+ }),
109
119
  dragData: PropTypes.shape({
110
120
  enableDragData: PropTypes.bool,
111
121
  showTooltip: PropTypes.bool,
@@ -217,6 +227,7 @@ export const getDefaultProps = (props) => {
217
227
  onAnimationComplete:
218
228
  props.chart.options.interactions.onAnimationComplete,
219
229
  },
230
+ depthType: props.chart.options.depthType,
220
231
  dragData: {
221
232
  enableDragData: props.chart.options.dragData.enableDragData || false,
222
233
  showTooltip: props.chart.options.dragData.showTooltip || true,
@@ -46,10 +46,17 @@ export interface ILineChartAdditionalAxesOptions {
46
46
  autoAxisPadding: boolean;
47
47
  }
48
48
 
49
+ export interface IUnitOptions {
50
+ options: string[],
51
+ selectedUnit: string,
52
+ setSelectedUnit: () => void,
53
+ }
54
+
49
55
  export interface ILineChartAxis<PositionType> {
50
56
  label: string;
51
57
  position: PositionType;
52
58
  color: string;
59
+ unit: IUnitOptions
53
60
  }
54
61
 
55
62
  export interface ILineChartAxes {
@@ -57,6 +64,11 @@ export interface ILineChartAxes {
57
64
  y: ILineChartAxis<'left' | 'right'>[];
58
65
  }
59
66
 
67
+ export interface IDepthType {
68
+ options: string[],
69
+ selectedUnit: string,
70
+ setSelectedUnit: () => void,
71
+ }
60
72
  export interface ILineChartOptions {
61
73
  title: string | string[];
62
74
  axes: ILineChartAxes;
@@ -68,6 +80,7 @@ export interface ILineChartOptions {
68
80
  legend: IChartLegend;
69
81
  chartOptions: IChartOptions;
70
82
  interactions: IChartInteractions;
83
+ depthType: IDepthType
71
84
  draggableData :IChartDraggableData;
72
85
  }
73
86
 
@@ -113,6 +113,7 @@ const LineChart = (props) => {
113
113
  graph,
114
114
  interactions,
115
115
  legend,
116
+ depthType,
116
117
  dragData,
117
118
  } = options;
118
119
  const { showLine, showPoints, enableZoom, enablePan } = chartOptions;
@@ -161,7 +162,7 @@ const LineChart = (props) => {
161
162
  //save the initial axis ranges in state (we need this for resetting ranges)
162
163
  dispatch({
163
164
  type: SAVE_INITIAL_AXES_RANGES,
164
- payload: { initialAxesRanges: getAxesRangesFromChart(chartRef) },
165
+ payload: { initialAxesRanges: getAxesRangesFromChart(chartRef, axes) },
165
166
  });
166
167
  }
167
168
  }, []);
@@ -364,11 +365,15 @@ const LineChart = (props) => {
364
365
  const axisType = i ? AxisType.Y : AxisType.X; // only first element is 'x' - rest is 'y'
365
366
  const min = axis.min ?? additionalAxesOptions?.range?.[axisType]?.min;
366
367
  const max = axis.max ?? additionalAxesOptions?.range?.[axisType]?.max;
368
+ // we need to get all axes element to array to set unit.
369
+ const axesArray = axes.x.concat(axes.y);
370
+ const unit = axesArray?.[i]?.unit;
367
371
  return {
368
372
  ...axis,
369
373
  //only add min and max properties if they are defined:
370
374
  ...(min ? { min } : {}),
371
375
  ...(max ? { max } : {}),
376
+ ...(unit ? { unit } : {}),
372
377
  };
373
378
  });
374
379
  };
@@ -455,6 +460,7 @@ const LineChart = (props) => {
455
460
  subheaderComponent={subheaderComponent}
456
461
  table={table}
457
462
  zoomEnabled={state.zoomEnabled}
463
+ depthType={depthType}
458
464
  enableDragPoints={state.enableDragPoints}
459
465
  isDragDataAllowed={dragData.enableDragData}
460
466
  onToggleDragPoints={() => dispatch({ type: TOGGLE_DRAG_POINTS })}
@@ -11,6 +11,9 @@ const initialState = ({
11
11
  legendDisplay,
12
12
  annotationsData,
13
13
  customAxesRange,
14
+ selectedDepthTypes,
15
+ selectedUnits,
16
+ setSelectedDepthTypes,
14
17
  }) => {
15
18
  /**
16
19
  * getStateAxesByType
@@ -28,23 +31,27 @@ const initialState = ({
28
31
  const id = generateAxisId(axisType, index, axes[axisType].length > 1);
29
32
  const customMin = customAxesRange?.[id]?.min;
30
33
  const customMax = customAxesRange?.[id]?.max;
34
+ const { unit } = axisObj;
31
35
  return {
32
36
  id,
33
37
  //only add custom axis ranges if defined:
34
38
  ...(customMin ? { min: customMin } : {}),
35
39
  ...(customMax ? { max: customMax } : {}),
40
+ ...(unit ? { unit } : {}),
36
41
  };
37
42
  });
38
43
  } else {
39
44
  const id = generateAxisId(axisType);
40
45
  const customMin = customAxesRange?.[id]?.min;
41
46
  const customMax = customAxesRange?.[id]?.max;
47
+ const unit = axes?.[id][0].unit;
42
48
  return [
43
49
  {
44
50
  id,
45
51
  //only add custom axis ranges if defined:
46
52
  ...(customMin ? { min: customMin } : {}),
47
53
  ...(customMax ? { max: customMax } : {}),
54
+ ...(unit ? { unit } : {}),
48
55
  },
49
56
  ];
50
57
  }
@@ -63,6 +70,9 @@ const initialState = ({
63
70
  axes: stateAxes,
64
71
  showAnnotationLineIndex: setAnnotations(annotationsData),
65
72
  showTable: false,
73
+ selectedDepthTypes,
74
+ selectedUnits,
75
+ setSelectedDepthTypes,
66
76
  enableDragPoints: false,
67
77
  };
68
78
  };