@oliasoft-open-source/charts-library 2.15.0 → 2.16.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oliasoft-open-source/charts-library",
3
- "version": "2.15.0",
3
+ "version": "2.16.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": {
package/release-notes.md CHANGED
@@ -1,10 +1,7 @@
1
1
  # Charts Library Release Notes
2
2
 
3
- ## 2.15.0
4
- - Added translation, by provider handled([OW-11237](https://oliasoft.atlassian.net/browse/OW-11237))
5
-
6
- ## 2.14.1
7
- - Fix save initAxesRange when dataset changed by parent component([OW-11332](https://oliasoft.atlassian.net/browse/OW-11332))
3
+ ## 2.16.0
4
+ - Added common chart area text plugin
8
5
 
9
6
  ## 2.14.0
10
7
  - Refactored line chart, for better performance, readable and reduce not needed re-renders
@@ -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,
@@ -125,7 +124,7 @@ const AxesOptionsPopover = ({
125
124
  <Input
126
125
  name="min"
127
126
  value={min}
128
- error={translations[minError]}
127
+ error={minError}
129
128
  size={5}
130
129
  width="100%"
131
130
  onChange={(evt) =>
@@ -141,7 +140,7 @@ const AxesOptionsPopover = ({
141
140
  <Input
142
141
  name="max"
143
142
  value={max}
144
- error={translations[maxError]}
143
+ error={maxError}
145
144
  size={5}
146
145
  width="100%"
147
146
  onChange={(evt) =>
@@ -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={translations.resetAxes}
197
+ label="Reset Axes"
205
198
  onClick={onReset}
206
199
  disabled={!isCustomValue}
207
200
  />
208
201
  <Text small muted>
209
- {translations.orDoubleClickToCanvas}
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>
@@ -36,13 +36,13 @@ const isEmptyString = (value) => value === '';
36
36
 
37
37
  const createErrorMessages = (value, compareTo, type) => {
38
38
  const errors = [];
39
- if (isEmptyString(value)) errors.push('mustHaveAValue');
40
- if (!validNumber(value)) errors.push('mustBeANumber');
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('mustBeLessThanMax');
43
+ errors.push('Must be less than max');
44
44
  } else if (type === 'max' && !isGreaterThanMin(value, compareTo)) {
45
- errors.push('mustBeGreaterThanMin');
45
+ errors.push('Must be greater than min');
46
46
  }
47
47
 
48
48
  return errors;
@@ -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={translations.downloadAsPNG} placement="bottom-end">
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 ? translations.showChart : translations.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: dragToZoom,
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
- {doubleClickToReset}
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: dragToPan,
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
- {orDoubleClickToCanvas}
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: dragToMovePoints,
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: dragDisabled,
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: translations.pointsLines,
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: translations.linesOnly,
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: translations.pointsOnly,
33
+ label: 'Points only',
35
34
  icon: <Icon icon={pointOnlyIcon} />,
36
35
  selected: pointsEnabled && !lineEnabled,
37
36
  onClick: () => {
@@ -38,6 +38,17 @@ export const useChartOptions = ({
38
38
  }) => {
39
39
  const {
40
40
  interactions: { onAnimationComplete },
41
+ annotations: {
42
+ labelAnnotation: {
43
+ showLabel,
44
+ text,
45
+ fontSize,
46
+ xOffset,
47
+ yOffset,
48
+ maxWidth,
49
+ lineHeight,
50
+ },
51
+ },
41
52
  } = options;
42
53
 
43
54
  const {
@@ -122,6 +133,15 @@ export const useChartOptions = ({
122
133
  chartAreaBorder: {
123
134
  borderColor: BORDER_COLOR,
124
135
  },
136
+ chartAreaText: {
137
+ showLabel,
138
+ text,
139
+ fontSize,
140
+ xOffset,
141
+ yOffset,
142
+ maxWidth,
143
+ lineHeight,
144
+ },
125
145
  ...dragData,
126
146
  };
127
147
 
@@ -72,7 +72,18 @@ export const LineChartPropTypes = {
72
72
  showMinorGridlines: PropTypes.bool,
73
73
  }),
74
74
  annotations: PropTypes.shape({
75
- labelAnnotation: PropTypes.object,
75
+ labelAnnotation: PropTypes.shape({
76
+ showLabel: PropTypes.bool,
77
+ text: PropTypes.oneOfType([
78
+ PropTypes.string,
79
+ PropTypes.arrayOf(PropTypes.string),
80
+ ]),
81
+ fontSize: PropTypes.number,
82
+ xOffset: PropTypes.number,
83
+ yOffset: PropTypes.number,
84
+ maxWidth: PropTypes.number,
85
+ lineHeight: PropTypes.number,
86
+ }),
76
87
  showAnnotations: PropTypes.bool,
77
88
  controlAnnotation: PropTypes.bool,
78
89
  annotationsData: PropTypes.arrayOf(
@@ -201,7 +212,21 @@ export const getDefaultProps = (props) => {
201
212
  props.chart.options.graph.showMinorGridlines || false,
202
213
  },
203
214
  annotations: {
204
- labelAnnotation: props.chart.options.annotations.labelAnnotation || {},
215
+ labelAnnotation: {
216
+ showLabel:
217
+ props.chart.options.annotations.labelAnnotation?.showLabel ?? false,
218
+ text: props.chart.options.annotations.labelAnnotation?.text ?? '',
219
+ fontSize:
220
+ props.chart.options.annotations.labelAnnotation?.fontSize ?? 12,
221
+ xOffset:
222
+ props.chart.options.annotations.labelAnnotation?.xOffset ?? 5,
223
+ yOffset:
224
+ props.chart.options.annotations.labelAnnotation?.yOffset ?? 10,
225
+ maxWidth:
226
+ props.chart.options.annotations.labelAnnotation?.maxWidth ?? 300,
227
+ lineHeight:
228
+ props.chart.options.annotations.labelAnnotation?.lineHeight ?? 12,
229
+ },
205
230
  showAnnotations:
206
231
  props.chart.options.annotations.showAnnotations ?? false,
207
232
  controlAnnotation:
@@ -29,8 +29,7 @@ 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';
32
+ import { chartAreaTextPlugin } from './plugins/chart-area-text-plugin';
34
33
 
35
34
  ChartJS.register(
36
35
  LinearScale,
@@ -46,6 +45,7 @@ ChartJS.register(
46
45
  dataLabelsPlugin,
47
46
  annotationPlugin,
48
47
  dragDataPlugin,
48
+ chartAreaTextPlugin,
49
49
  );
50
50
 
51
51
  /**
@@ -55,8 +55,7 @@ ChartJS.register(
55
55
  const LineChart = (props) => {
56
56
  setDefaultTheme();
57
57
  const chartRef = useRef(null);
58
- const { table, translations: translationsRaw } = props;
59
- const translations = getTranslations(translationsRaw);
58
+ const { table } = props;
60
59
  const chart = getDefaultProps(props);
61
60
  const {
62
61
  data: { datasets },
@@ -79,18 +78,11 @@ const LineChart = (props) => {
79
78
  );
80
79
 
81
80
  const generatedDatasets = useMemo(() => {
82
- return generateLineChartDatasets(datasets, state, options, translations);
81
+ return generateLineChartDatasets(datasets, state, options);
83
82
  }, [state.lineEnabled, state.pointsEnabled, axes, annotations, graph]);
84
83
 
85
84
  // Call the custom hooks.
86
- useChartState({
87
- chartRef,
88
- options,
89
- state,
90
- generatedDatasets,
91
- dispatch,
92
- persistenceId,
93
- });
85
+ useChartState({ chartRef, options, state, dispatch, persistenceId });
94
86
 
95
87
  const { resetZoom, handleDownload, handleKeyDown, handleKeyUp } =
96
88
  useChartFunctions({
@@ -135,7 +127,6 @@ const LineChart = (props) => {
135
127
  options={options}
136
128
  dispatch={dispatch}
137
129
  generatedDatasets={generatedDatasets}
138
- translations={translations}
139
130
  />
140
131
  {table && state.showTable ? (
141
132
  <div className={styles.table}>{table}</div>
@@ -0,0 +1,117 @@
1
+ const WORD_SEPARATOR = ' ';
2
+ const TRANSPARENT = 'rgba(0, 0, 0, 0.5)';
3
+
4
+ /**
5
+ * Splits the input text into words based on the predefined WORD_SEPARATOR.
6
+ * If the input is an array, it first joins the array and then splits it.
7
+ *
8
+ * @param {string | string[]} text - The text to split into words.
9
+ * @returns {string[]} An array of words.
10
+ */
11
+ const getWords = (text) => {
12
+ return Array.isArray(text)
13
+ ? text.join(WORD_SEPARATOR).split(WORD_SEPARATOR)
14
+ : text.split(WORD_SEPARATOR);
15
+ };
16
+
17
+ /**
18
+ * Counts the number of lines required to render the words within the specified maxWidth.
19
+ * It takes into consideration the context (ctx) provided to calculate the text width.
20
+ *
21
+ * @param {string[]} words - The array of words to be processed.
22
+ * @param {number} maxWidth - The maximum width allowed for the text.
23
+ * @param {CanvasRenderingContext2D} ctx - The canvas rendering context to measure the text width.
24
+ * @returns {number} The number of lines required.
25
+ */
26
+ const countLines = (words, maxWidth, ctx) => {
27
+ let line = '';
28
+ let lines = 0;
29
+
30
+ for (const word of words) {
31
+ const testLine = `${line}${word}${WORD_SEPARATOR}`;
32
+ const { width: testWidth } = ctx.measureText(testLine);
33
+
34
+ if (testWidth > maxWidth) {
35
+ line = `${word}${WORD_SEPARATOR}`;
36
+ lines++;
37
+ } else {
38
+ line = testLine;
39
+ }
40
+ }
41
+ lines++; // Add the last line
42
+ return lines;
43
+ };
44
+
45
+ const drawText = (ctx, lines, lineHeight, x, y) => {
46
+ lines.forEach((line, index) => {
47
+ ctx.fillText(line, x, y - (lines.length - 1 - index) * lineHeight);
48
+ });
49
+ };
50
+
51
+ export const chartAreaTextPlugin = {
52
+ id: 'chartAreaText',
53
+
54
+ beforeLayout: (chart, args, options) => {
55
+ const { showLabel, text, fontStyle, fontSize, maxWidth, lineHeight } =
56
+ options;
57
+ const { ctx } = chart;
58
+
59
+ if (!showLabel || !text) return;
60
+
61
+ ctx.save();
62
+ ctx.font = `${fontStyle} ${fontSize}px Arial`;
63
+
64
+ const words = getWords(text);
65
+ const lines = countLines(words, maxWidth, ctx);
66
+
67
+ // Calculate and set the padding needed at the bottom of the chart
68
+ const paddingNeeded = lines * lineHeight + lineHeight;
69
+ chart.options.layout.padding.bottom = paddingNeeded;
70
+
71
+ ctx.restore();
72
+ },
73
+
74
+ beforeDraw: (chart, args, options) => {
75
+ const { showLabel, text, fontSize, xOffset, yOffset, lineHeight } = options;
76
+ const { ctx, chartArea } = chart;
77
+
78
+ if (!showLabel || !text) return;
79
+
80
+ // Determine the maxWidth based on chartArea width
81
+ const maxWidth =
82
+ chartArea.width < 500
83
+ ? 100
84
+ : chartArea.width < 700
85
+ ? 200
86
+ : options.maxWidth;
87
+
88
+ // Split the text into words and calculate the number of lines
89
+ const words = getWords(text);
90
+ let line = '';
91
+ let lines = [];
92
+ for (let i = 0; i < words.length; i++) {
93
+ const testLine = `${line}${words[i]}${WORD_SEPARATOR}`;
94
+ const { width: testWidth } = ctx.measureText(testLine);
95
+ if (testWidth > maxWidth) {
96
+ lines.push(line.trim());
97
+ line = `${words[i]}${WORD_SEPARATOR}`;
98
+ } else {
99
+ line = testLine;
100
+ }
101
+ }
102
+ lines.push(line.trim()); // Add the last line
103
+
104
+ // Wrap the text based on the maxWidth and draw it on the canvas
105
+ ctx.save();
106
+ ctx.font = `${fontSize}px Arial`;
107
+ ctx.fillStyle = TRANSPARENT;
108
+ ctx.textAlign = 'right';
109
+
110
+ const y = chartArea.bottom - yOffset;
111
+ const x = chartArea.right - xOffset; // Subtract margin on the right
112
+
113
+ drawText(ctx, lines, lineHeight, x, y);
114
+
115
+ ctx.restore();
116
+ },
117
+ };
@@ -75,38 +75,26 @@ const useUpdateAxesRanges = (range, dispatch) => {
75
75
  };
76
76
 
77
77
  /**
78
- * A custom hook to save the initial axes ranges of a chart when the generated datasets change.
78
+ * Hook for saving the initial axes ranges in the chart state.
79
79
  *
80
- * @param {Object} chartRef - A reference to the chart object.
81
- * @param {Array} axes - An array of axes configurations.
82
- * @param {Array} generatedDatasets - An array of generated datasets for the chart.
83
- * @param {Function} dispatch - A dispatch function from the useContext hook for managing the state.
80
+ * @param chartRef - The reference to the chart.
81
+ * @param axes - The axes data.
82
+ * @param dispatch - The dispatch function for state management.
84
83
  */
85
- const useSaveInitialAxesRanges = (
86
- chartRef,
87
- axes,
88
- generatedDatasets,
89
- dispatch,
90
- ) => {
91
- const prevGeneratedDatasets = useRef();
92
-
84
+ const useSaveInitialAxesRanges = (chartRef, axes, dispatch) => {
93
85
  const saveInitialAxesRanges = useCallback(() => {
94
- if (
95
- chartRef &&
96
- !isEqual(generatedDatasets, prevGeneratedDatasets.current)
97
- ) {
86
+ if (chartRef) {
98
87
  const initialAxesRanges = getAxesRangesFromChart(chartRef, axes);
99
88
  dispatch({
100
89
  type: SAVE_INITIAL_AXES_RANGES,
101
90
  payload: { initialAxesRanges },
102
91
  });
103
- prevGeneratedDatasets.current = generatedDatasets;
104
92
  }
105
- }, [chartRef, generatedDatasets]);
93
+ }, [chartRef]);
106
94
 
107
95
  useEffect(() => {
108
96
  saveInitialAxesRanges();
109
- }, [saveInitialAxesRanges, generatedDatasets]);
97
+ }, [saveInitialAxesRanges]);
110
98
  };
111
99
 
112
100
  /**
@@ -115,7 +103,6 @@ const useSaveInitialAxesRanges = (
115
103
  * @param chartRef - The reference to the chart.
116
104
  * @param options - The chart options.
117
105
  * @param state - The chart state.
118
- * @param {Array} generatedDatasets - An array of generated datasets for the chart.
119
106
  * @param dispatch - The dispatch function for state management.
120
107
  * @param persistenceId - The chart persistenceId.
121
108
  */
@@ -123,7 +110,6 @@ export const useChartState = ({
123
110
  chartRef,
124
111
  options,
125
112
  state,
126
- generatedDatasets,
127
113
  dispatch,
128
114
  persistenceId,
129
115
  }) => {
@@ -137,5 +123,5 @@ export const useChartState = ({
137
123
  useStoreChartStateInStorage(memoState, persistenceId);
138
124
  useToggleCustomLegendVisibility(memoState, memoOptions);
139
125
  useUpdateAxesRanges(range, dispatch);
140
- useSaveInitialAxesRanges(chartRef, axes, generatedDatasets, dispatch);
126
+ useSaveInitialAxesRanges(chartRef, axes, dispatch);
141
127
  };
@@ -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 with the label property
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
- { label },
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 || `${label} ${i + 1}`,
91
+ label: line.label || `Label ${i + 1}`,
98
92
  data: filteredData,
99
93
  showLine: lineEnabled,
100
94
  lineTension,
@@ -26,12 +26,16 @@ export interface IChartAnnotationsData {
26
26
  };
27
27
 
28
28
  export interface ILabelAnnotation {
29
- content: string[];
30
- fontSize: number;
31
- xAdjust: number;
32
- yAdjust: number;
29
+ showLabel: boolean;
30
+ text: string | string[];
31
+ fontSize?: number;
32
+ xOffset: number
33
+ yOffset: number
34
+ maxWidth: number
35
+ lineHeight: number
33
36
  }
34
37
 
38
+
35
39
  export interface IChartAnnotations {
36
40
  showAnnotations: boolean;
37
41
  controlAnnotation: boolean;
@@ -1,7 +1,7 @@
1
1
  import { round } from '@oliasoft-open-source/units';
2
2
  import { defaults } from 'chart.js';
3
3
  import cx from 'classnames';
4
- import { chartMinorGridlinesPlugin } from '../components/line-chart/line-chart.minor-gridlines-plugin';
4
+ import { chartMinorGridlinesPlugin } from '../components/line-chart/plugins/line-chart.minor-gridlines-plugin';
5
5
  import {
6
6
  BORDER_COLOR,
7
7
  CUSTOM_LEGEND_PLUGIN_NAME,
@@ -86,37 +86,6 @@ const generateAnnotations = (options, state) => {
86
86
  return annotations;
87
87
  };
88
88
 
89
- /**
90
- * @param {import('../components/bar-chart/bar-chart.interface').IBarChartOptions |
91
- * import('../components/line-chart/line-chart.interface').ILineChartOptions} options - chart options object
92
- * @return {{label1: {}}}
93
- */
94
- const getLabelAnnotation = (options) => {
95
- const { annotations = {} } = options;
96
- const { labelAnnotation = {} } = annotations;
97
- const isDarkModeOn = options.chartStyling.darkMode || false;
98
- const {
99
- content = [],
100
- xAdjust = -200,
101
- yAdjust = 120,
102
- fontSize = 12,
103
- } = labelAnnotation;
104
-
105
- return {
106
- label1: {
107
- type: 'label',
108
- xAdjust,
109
- yAdjust,
110
- backgroundColor: 'rgba(0, 0, 0, 0)',
111
- color: isDarkModeOn && 'rgba(255, 255, 255, 1)',
112
- content,
113
- font: {
114
- size: fontSize,
115
- },
116
- },
117
- };
118
- };
119
-
120
89
  /**
121
90
  * @param {import('../components/bar-chart/bar-chart.interface').IBarChartOptions |
122
91
  * import('../components/line-chart/line-chart.interface').ILineChartOptions} options - chart options object
@@ -124,20 +93,14 @@ const getLabelAnnotation = (options) => {
124
93
  * @return {{annotations: []}}
125
94
  */
126
95
  const getAnnotation = (options, state) => {
127
- const { annotations } = options;
128
- const isAnnotationShown = annotations?.showAnnotations;
129
- const isAnnotationDataProvided = annotations?.annotationsData?.length;
96
+ const { showAnnotations, annotationsData } = options.annotations || {};
97
+ const shouldGenerateAnnotations = showAnnotations && annotationsData?.length;
130
98
 
131
- const formAnnotation =
132
- isAnnotationShown && isAnnotationDataProvided
133
- ? {
134
- ...getLabelAnnotation(options),
135
- ...generateAnnotations(options, state),
136
- }
137
- : null;
99
+ const annotations = shouldGenerateAnnotations
100
+ ? generateAnnotations(options, state)
101
+ : null;
138
102
 
139
- return {
140
- annotations: formAnnotation,
141
- };
103
+ return { annotations };
142
104
  };
105
+
143
106
  export default getAnnotation;
@@ -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
- };