@oliasoft-open-source/charts-library 2.11.3 → 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.3",
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": {
package/release-notes.md CHANGED
@@ -1,5 +1,9 @@
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
+
3
7
  ## 2.11.3
4
8
 
5
9
  - Submit Axes option on keyboard Enter ([OW-10995](https://oliasoft.atlassian.net/browse/OW-10995))
@@ -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,6 +52,13 @@ const AxesOptionsPopover = ({
45
52
  });
46
53
  };
47
54
 
55
+ const onEditUnit = ({ name, value, id }) => {
56
+ dispatch({
57
+ type: actionTypes.unitUpdated,
58
+ payload: { name, value, id },
59
+ });
60
+ };
61
+
48
62
  const onDone = (e) => {
49
63
  e.preventDefault();
50
64
  if (valid) {
@@ -56,6 +70,17 @@ const AxesOptionsPopover = ({
56
70
  onUpdateAxes({
57
71
  axes: sanitizedFormState,
58
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
+ }
59
84
  }
60
85
  close();
61
86
  };
@@ -66,8 +91,16 @@ const AxesOptionsPopover = ({
66
91
  type: actionTypes.reset,
67
92
  payload: { axes, initialAxesRanges },
68
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
+
69
101
  //reset parent state
70
102
  onResetAxes();
103
+ close();
71
104
  };
72
105
 
73
106
  const isCustomValue = axes.filter((axis) => axis.max || axis.min).length > 0;
@@ -83,6 +116,7 @@ const AxesOptionsPopover = ({
83
116
  const max = formState.find((a) => a.id === axis.id)?.max;
84
117
  const minError = errors?.find((a) => a.id === axis.id)?.min?.[0];
85
118
  const maxError = errors?.find((a) => a.id === axis.id)?.max?.[0];
119
+ const unit = formState.find((a) => a.id === axis.id)?.unit;
86
120
  return (
87
121
  <Field key={i} label={axisLabel || axis.id || ''}>
88
122
  <InputGroup small>
@@ -117,10 +151,43 @@ const AxesOptionsPopover = ({
117
151
  }
118
152
  onFocus={handleInputFocus}
119
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}
120
169
  </InputGroup>
121
170
  </Field>
122
171
  );
123
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
+
124
191
  <Flex gap="8px" alignItems="center">
125
192
  <Button type="submit" small colored label="Done" disabled={!valid} />
126
193
  <Button
@@ -144,6 +211,7 @@ export const AxesOptions = ({
144
211
  controlsAxesLabels,
145
212
  onUpdateAxes,
146
213
  onResetAxes,
214
+ depthType,
147
215
  }) => {
148
216
  return (
149
217
  <Popover
@@ -156,6 +224,7 @@ export const AxesOptions = ({
156
224
  controlsAxesLabels={controlsAxesLabels}
157
225
  onUpdateAxes={onUpdateAxes}
158
226
  onResetAxes={onResetAxes}
227
+ depthType={depthType}
159
228
  />
160
229
  }
161
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
  };