@gravity-ui/chartkit 5.5.0 → 5.6.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.
Files changed (52) hide show
  1. package/build/i18n/keysets/en.json +2 -1
  2. package/build/i18n/keysets/ru.json +2 -4
  3. package/build/plugins/d3/examples/area/TwoYAxis.d.ts +2 -0
  4. package/build/plugins/d3/examples/area/TwoYAxis.js +58 -0
  5. package/build/plugins/d3/examples/bar-x/TwoYAxis.d.ts +2 -0
  6. package/build/plugins/d3/examples/bar-x/TwoYAxis.js +58 -0
  7. package/build/plugins/d3/examples/line/TwoYAxis.d.ts +2 -0
  8. package/build/plugins/d3/examples/line/TwoYAxis.js +58 -0
  9. package/build/plugins/d3/examples/mars-weather.d.ts +13 -0
  10. package/build/plugins/d3/examples/mars-weather.js +1203 -0
  11. package/build/plugins/d3/examples/scatter/TwoYAxis.d.ts +2 -0
  12. package/build/plugins/d3/examples/scatter/TwoYAxis.js +58 -0
  13. package/build/plugins/d3/renderer/components/AxisY.d.ts +1 -1
  14. package/build/plugins/d3/renderer/components/AxisY.js +112 -79
  15. package/build/plugins/d3/renderer/components/Chart.js +4 -3
  16. package/build/plugins/d3/renderer/hooks/useAxisScales/index.d.ts +1 -1
  17. package/build/plugins/d3/renderer/hooks/useAxisScales/index.js +8 -1
  18. package/build/plugins/d3/renderer/hooks/useChartDimensions/utils.d.ts +1 -0
  19. package/build/plugins/d3/renderer/hooks/useChartDimensions/utils.js +11 -10
  20. package/build/plugins/d3/renderer/hooks/useChartOptions/types.d.ts +1 -0
  21. package/build/plugins/d3/renderer/hooks/useChartOptions/x-axis.js +1 -0
  22. package/build/plugins/d3/renderer/hooks/useChartOptions/y-axis.js +56 -50
  23. package/build/plugins/d3/renderer/hooks/useSeries/prepare-area.d.ts +1 -1
  24. package/build/plugins/d3/renderer/hooks/useSeries/prepare-area.js +1 -0
  25. package/build/plugins/d3/renderer/hooks/useSeries/prepare-bar-x.js +1 -0
  26. package/build/plugins/d3/renderer/hooks/useSeries/prepare-legend.js +3 -3
  27. package/build/plugins/d3/renderer/hooks/useSeries/prepare-line.d.ts +1 -1
  28. package/build/plugins/d3/renderer/hooks/useSeries/prepare-line.js +1 -0
  29. package/build/plugins/d3/renderer/hooks/useSeries/prepare-scatter.js +1 -0
  30. package/build/plugins/d3/renderer/hooks/useSeries/types.d.ts +4 -0
  31. package/build/plugins/d3/renderer/hooks/useShapes/area/prepare-data.d.ts +2 -1
  32. package/build/plugins/d3/renderer/hooks/useShapes/area/prepare-data.js +7 -6
  33. package/build/plugins/d3/renderer/hooks/useShapes/bar-x/prepare-data.d.ts +2 -1
  34. package/build/plugins/d3/renderer/hooks/useShapes/bar-x/prepare-data.js +4 -4
  35. package/build/plugins/d3/renderer/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
  36. package/build/plugins/d3/renderer/hooks/useShapes/bar-y/prepare-data.js +1 -1
  37. package/build/plugins/d3/renderer/hooks/useShapes/index.d.ts +1 -1
  38. package/build/plugins/d3/renderer/hooks/useShapes/index.js +3 -1
  39. package/build/plugins/d3/renderer/hooks/useShapes/line/prepare-data.d.ts +1 -1
  40. package/build/plugins/d3/renderer/hooks/useShapes/line/prepare-data.js +2 -1
  41. package/build/plugins/d3/renderer/hooks/useShapes/scatter/prepare-data.d.ts +2 -2
  42. package/build/plugins/d3/renderer/hooks/useShapes/scatter/prepare-data.js +5 -2
  43. package/build/plugins/d3/renderer/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
  44. package/build/plugins/d3/renderer/hooks/useShapes/waterfall/prepare-data.js +1 -1
  45. package/build/plugins/d3/renderer/utils/text.js +1 -1
  46. package/build/plugins/d3/renderer/validation/index.js +13 -4
  47. package/build/plugins/d3/utils/pie-center-text.js +1 -1
  48. package/build/types/widget-data/area.d.ts +2 -0
  49. package/build/types/widget-data/bar-x.d.ts +2 -0
  50. package/build/types/widget-data/line.d.ts +2 -0
  51. package/build/types/widget-data/scatter.d.ts +2 -0
  52. package/package.json +2 -1
@@ -49,13 +49,9 @@ function getXValues(series, xAxis, xScale) {
49
49
  return sort(Array.from(xValues), ([_x, xValue]) => xValue);
50
50
  }
51
51
  export const prepareAreaData = (args) => {
52
- const { series, xAxis, xScale, yScale } = args;
53
- const yLinearScale = yScale;
54
- const plotHeight = yLinearScale(yLinearScale.domain()[0]);
55
- const yAxis = args.yAxis[0];
52
+ const { series, xAxis, xScale, yAxis, yScale, boundsHeight: plotHeight } = args;
56
53
  const [_xMin, xRangeMax] = xScale.range();
57
54
  const xMax = xRangeMax / (1 - xAxis.maxPadding);
58
- const [yMin, _yMax] = yScale.range();
59
55
  return Array.from(group(series, (s) => s.stackId)).reduce((result, [_stackId, seriesStack]) => {
60
56
  const xValues = getXValues(seriesStack, xAxis, xScale);
61
57
  const accumulatedYValues = new Map();
@@ -63,6 +59,10 @@ export const prepareAreaData = (args) => {
63
59
  accumulatedYValues.set(key, 0);
64
60
  });
65
61
  const seriesStackData = seriesStack.reduce((acc, s) => {
62
+ const yAxisIndex = s.yAxis;
63
+ const seriesYAxis = yAxis[yAxisIndex];
64
+ const seriesYScale = yScale[yAxisIndex];
65
+ const [yMin, _yMax] = seriesYScale.range();
66
66
  const seriesData = s.data.reduce((m, d) => {
67
67
  return m.set(String(d.x), d);
68
68
  }, new Map());
@@ -74,7 +74,8 @@ export const prepareAreaData = (args) => {
74
74
  // FIXME: think about how to break the series into separate areas(null Y values)
75
75
  y: 0,
76
76
  };
77
- const yValue = getYValue({ point: d, yAxis, yScale }) - accumulatedYValue;
77
+ const yValue = getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale }) -
78
+ accumulatedYValue;
78
79
  accumulatedYValues.set(x, yMin - yValue);
79
80
  pointsAcc.push({
80
81
  y0: yMin - accumulatedYValue,
@@ -8,5 +8,6 @@ export declare const prepareBarXData: (args: {
8
8
  xAxis: PreparedAxis;
9
9
  xScale: ChartScale;
10
10
  yAxis: PreparedAxis[];
11
- yScale: ChartScale;
11
+ yScale: ChartScale[];
12
+ boundsHeight: number;
12
13
  }) => PreparedBarXData[];
@@ -24,9 +24,7 @@ function getLabelData(d) {
24
24
  };
25
25
  }
26
26
  export const prepareBarXData = (args) => {
27
- const { series, seriesOptions, xAxis, xScale, yScale } = args;
28
- const yLinearScale = yScale;
29
- const plotHeight = yLinearScale(yLinearScale.domain()[0]);
27
+ const { series, seriesOptions, xAxis, xScale, yScale, boundsHeight: plotHeight } = args;
30
28
  const categories = get(xAxis, 'categories', []);
31
29
  const barMaxWidth = get(seriesOptions, 'bar-x.barMaxWidth');
32
30
  const barPadding = get(seriesOptions, 'bar-x.barPadding');
@@ -100,6 +98,8 @@ export const prepareBarXData = (args) => {
100
98
  ? sort(yValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey)))
101
99
  : yValues;
102
100
  sortedData.forEach((yValue) => {
101
+ const yAxisIndex = yValue.series.yAxis;
102
+ const seriesYScale = yScale[yAxisIndex];
103
103
  let xCenter;
104
104
  if (xAxis.type === 'category') {
105
105
  const xBandScale = xScale;
@@ -110,7 +110,7 @@ export const prepareBarXData = (args) => {
110
110
  xCenter = xLinearScale(Number(xValue));
111
111
  }
112
112
  const x = xCenter - currentGroupWidth / 2 + (rectWidth + rectGap) * groupItemIndex;
113
- const y = yLinearScale(yValue.data.y);
113
+ const y = seriesYScale(yValue.data.y);
114
114
  const height = plotHeight - y;
115
115
  const barData = {
116
116
  x,
@@ -8,5 +8,5 @@ export declare const prepareBarYData: (args: {
8
8
  xAxis: PreparedAxis;
9
9
  xScale: ChartScale;
10
10
  yAxis: PreparedAxis[];
11
- yScale: ChartScale;
11
+ yScale: ChartScale[];
12
12
  }) => PreparedBarYData[];
@@ -48,7 +48,7 @@ function getBandWidth(series, yAxis, yScale) {
48
48
  return bandWidth;
49
49
  }
50
50
  export const prepareBarYData = (args) => {
51
- const { series, seriesOptions, yAxis, xScale, yScale } = args;
51
+ const { series, seriesOptions, yAxis, xScale, yScale: [yScale], } = args;
52
52
  const xLinearScale = xScale;
53
53
  const plotWidth = xLinearScale(xLinearScale.domain()[1]);
54
54
  const barMaxWidth = get(seriesOptions, 'bar-y.barMaxWidth');
@@ -23,7 +23,7 @@ type Args = {
23
23
  xAxis: PreparedAxis;
24
24
  yAxis: PreparedAxis[];
25
25
  xScale?: ChartScale;
26
- yScale?: ChartScale;
26
+ yScale?: ChartScale[];
27
27
  };
28
28
  export declare const useShapes: (args: Args) => {
29
29
  shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
@@ -32,6 +32,7 @@ export const useShapes = (args) => {
32
32
  xScale,
33
33
  yAxis,
34
34
  yScale,
35
+ boundsHeight,
35
36
  });
36
37
  acc.push(React.createElement(BarXSeriesShapes, { key: "bar-x", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData }));
37
38
  shapesData.push(...preparedData);
@@ -90,6 +91,7 @@ export const useShapes = (args) => {
90
91
  xScale,
91
92
  yAxis,
92
93
  yScale,
94
+ boundsHeight,
93
95
  });
94
96
  acc.push(React.createElement(AreaSeriesShapes, { key: "area", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData }));
95
97
  shapesData.push(...preparedData);
@@ -102,7 +104,7 @@ export const useShapes = (args) => {
102
104
  series: chartSeries,
103
105
  xAxis,
104
106
  xScale,
105
- yAxis: yAxis[0],
107
+ yAxis,
106
108
  yScale,
107
109
  });
108
110
  acc.push(React.createElement(ScatterSeriesShape, { key: "scatter", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions }));
@@ -7,5 +7,5 @@ export declare const prepareLineData: (args: {
7
7
  xAxis: PreparedAxis;
8
8
  xScale: ChartScale;
9
9
  yAxis: PreparedAxis[];
10
- yScale: ChartScale;
10
+ yScale: ChartScale[];
11
11
  }) => PreparedLineData[];
@@ -32,9 +32,10 @@ export const prepareLineData = (args) => {
32
32
  const [_xMin, xRangeMax] = xScale.range();
33
33
  const xMax = xRangeMax / (1 - xAxis.maxPadding);
34
34
  return series.reduce((acc, s) => {
35
+ const seriesYScale = yScale[s.yAxis];
35
36
  const points = s.data.map((d) => ({
36
37
  x: getXValue({ point: d, xAxis, xScale }),
37
- y: getYValue({ point: d, yAxis, yScale }),
38
+ y: getYValue({ point: d, yAxis, yScale: seriesYScale }),
38
39
  active: true,
39
40
  data: d,
40
41
  series: s,
@@ -6,6 +6,6 @@ export declare const prepareScatterData: (args: {
6
6
  series: PreparedScatterSeries[];
7
7
  xAxis: PreparedAxis;
8
8
  xScale: ChartScale;
9
- yAxis: PreparedAxis;
10
- yScale: ChartScale;
9
+ yAxis: PreparedAxis[];
10
+ yScale: ChartScale[];
11
11
  }) => PreparedScatterData[];
@@ -6,7 +6,10 @@ const getFilteredLinearScatterData = (data) => {
6
6
  export const prepareScatterData = (args) => {
7
7
  const { series, xAxis, xScale, yAxis, yScale } = args;
8
8
  return series.reduce((acc, s) => {
9
- const filteredData = xAxis.type === 'category' || yAxis.type === 'category'
9
+ const yAxisIndex = get(s, 'yAxis', 0);
10
+ const seriesYAxis = yAxis[yAxisIndex];
11
+ const seriesYScale = yScale[yAxisIndex];
12
+ const filteredData = xAxis.type === 'category' || seriesYAxis.type === 'category'
10
13
  ? s.data
11
14
  : getFilteredLinearScatterData(s.data);
12
15
  filteredData.forEach((d) => {
@@ -15,7 +18,7 @@ export const prepareScatterData = (args) => {
15
18
  data: d,
16
19
  series: s,
17
20
  x: getXValue({ point: d, xAxis, xScale }),
18
- y: getYValue({ point: d, yAxis, yScale }),
21
+ y: getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale }),
19
22
  opacity: get(d, 'opacity', null),
20
23
  },
21
24
  hovered: false,
@@ -8,5 +8,5 @@ export declare const prepareWaterfallData: (args: {
8
8
  xAxis: PreparedAxis;
9
9
  xScale: ChartScale;
10
10
  yAxis: PreparedAxis[];
11
- yScale: ChartScale;
11
+ yScale: ChartScale[];
12
12
  }) => PreparedWaterfallData[];
@@ -50,7 +50,7 @@ function getBandWidth(args) {
50
50
  return bandWidth;
51
51
  }
52
52
  export const prepareWaterfallData = (args) => {
53
- const { series, seriesOptions, xAxis, xScale, yAxis: [yAxis], yScale, } = args;
53
+ const { series, seriesOptions, xAxis, xScale, yAxis: [yAxis], yScale: [yScale], } = args;
54
54
  const yLinearScale = yScale;
55
55
  const plotHeight = yLinearScale(yLinearScale.domain()[0]);
56
56
  const barMaxWidth = get(seriesOptions, 'waterfall.barMaxWidth');
@@ -1,4 +1,4 @@
1
- import { select } from 'd3';
1
+ import { select } from 'd3-selection';
2
2
  export function setEllipsisForOverflowText(selection, maxWidth) {
3
3
  var _a, _b, _c, _d;
4
4
  let text = selection.text();
@@ -6,9 +6,19 @@ import { CHARTKIT_ERROR_CODE, ChartKitError } from '../../../../libs';
6
6
  import { DEFAULT_AXIS_TYPE } from '../constants';
7
7
  const AVAILABLE_SERIES_TYPES = Object.values(SeriesType);
8
8
  const validateXYSeries = (args) => {
9
- const { series, xAxis, yAxis } = args;
9
+ const { series, xAxis, yAxis = [] } = args;
10
+ const yAxisIndex = get(series, 'yAxis', 0);
11
+ const seriesYAxis = yAxis[yAxisIndex];
12
+ if (yAxisIndex !== 0 && typeof seriesYAxis === 'undefined') {
13
+ throw new ChartKitError({
14
+ code: CHARTKIT_ERROR_CODE.INVALID_DATA,
15
+ message: i18n('error', 'label_invalid-y-axis-index', {
16
+ index: yAxisIndex,
17
+ }),
18
+ });
19
+ }
10
20
  const xType = get(xAxis, 'type', DEFAULT_AXIS_TYPE);
11
- const yType = get(yAxis, 'type', DEFAULT_AXIS_TYPE);
21
+ const yType = get(seriesYAxis, 'type', DEFAULT_AXIS_TYPE);
12
22
  series.data.forEach(({ x, y }) => {
13
23
  switch (xType) {
14
24
  case 'category': {
@@ -203,7 +213,6 @@ export const validateData = (data) => {
203
213
  });
204
214
  }
205
215
  data.series.data.forEach((series) => {
206
- var _a;
207
- validateSeries({ series, yAxis: (_a = data.yAxis) === null || _a === void 0 ? void 0 : _a[0], xAxis: data.xAxis });
216
+ validateSeries({ series, yAxis: data.yAxis, xAxis: data.xAxis });
208
217
  });
209
218
  };
@@ -1,4 +1,4 @@
1
- import { create } from 'd3';
1
+ import { create } from 'd3-selection';
2
2
  import get from 'lodash/get';
3
3
  import { getLabelsSize } from '../renderer/utils';
4
4
  const MAX_FONT_SIZE = 64;
@@ -70,4 +70,6 @@ export type AreaSeries<T = any> = BaseSeries & {
70
70
  };
71
71
  /** Options for the point markers of line in area series */
72
72
  marker?: AreaMarkerOptions;
73
+ /** Y-axis index (when using two axes) */
74
+ yAxis?: number;
73
75
  };
@@ -61,4 +61,6 @@ export type BarXSeries<T = any> = BaseSeries & {
61
61
  legend?: ChartKitWidgetLegend & {
62
62
  symbol?: RectLegendSymbolOptions;
63
63
  };
64
+ /** Y-axis index (when using two axes) */
65
+ yAxis?: number;
64
66
  };
@@ -51,4 +51,6 @@ export type LineSeries<T = any> = BaseSeries & {
51
51
  linecap?: `${LineCap}`;
52
52
  /** Individual opacity for the line. */
53
53
  opacity?: number;
54
+ /** Y-axis index (when using two axes) */
55
+ yAxis?: number;
54
56
  };
@@ -40,4 +40,6 @@ export type ScatterSeries<T = any> = BaseSeries & {
40
40
  legend?: ChartKitWidgetLegend & {
41
41
  symbol?: RectLegendSymbolOptions;
42
42
  };
43
+ /** Y-axis index (when using two axes) */
44
+ yAxis?: number;
43
45
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/chartkit",
3
- "version": "5.5.0",
3
+ "version": "5.6.0",
4
4
  "description": "React component used to render charts based on any sources you need",
5
5
  "license": "MIT",
6
6
  "repository": "git@github.com:gravity-ui/ChartKit.git",
@@ -75,6 +75,7 @@
75
75
  "@storybook/react": "^7.0.26",
76
76
  "@storybook/react-webpack5": "^7.0.26",
77
77
  "@types/d3": "^7.4.0",
78
+ "@types/d3-selection": "^3.0.10",
78
79
  "@types/jest": "^28.1.3",
79
80
  "@types/lodash": "^4.14.177",
80
81
  "@types/node": "^18.0.0",