@gravity-ui/charts 1.24.2 → 1.26.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 (103) hide show
  1. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +3 -3
  2. package/dist/cjs/components/ChartInner/useChartInnerProps.js +34 -16
  3. package/dist/cjs/components/Legend/index.js +50 -28
  4. package/dist/cjs/hooks/useAxis/index.js +0 -1
  5. package/dist/cjs/hooks/useAxis/x-axis.d.ts +1 -3
  6. package/dist/cjs/hooks/useAxis/x-axis.js +3 -4
  7. package/dist/cjs/hooks/useAxisScales/index.d.ts +1 -3
  8. package/dist/cjs/hooks/useAxisScales/index.js +6 -35
  9. package/dist/cjs/hooks/useChartDimensions/index.js +16 -1
  10. package/dist/cjs/hooks/useRangeSlider/index.js +0 -1
  11. package/dist/cjs/hooks/useSeries/index.js +8 -8
  12. package/dist/cjs/hooks/useSeries/prepare-area.js +7 -5
  13. package/dist/cjs/hooks/useSeries/prepare-bar-x.js +8 -6
  14. package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +2 -0
  15. package/dist/cjs/hooks/useSeries/prepare-bar-y.js +7 -5
  16. package/dist/cjs/hooks/useSeries/prepare-funnel.js +14 -10
  17. package/dist/cjs/hooks/useSeries/prepare-heatmap.js +9 -7
  18. package/dist/cjs/hooks/useSeries/prepare-legend.js +75 -15
  19. package/dist/cjs/hooks/useSeries/prepare-line.js +6 -4
  20. package/dist/cjs/hooks/useSeries/prepare-pie.js +10 -6
  21. package/dist/cjs/hooks/useSeries/prepare-radar.js +7 -5
  22. package/dist/cjs/hooks/useSeries/prepare-sankey.js +3 -1
  23. package/dist/cjs/hooks/useSeries/prepare-scatter.js +4 -1
  24. package/dist/cjs/hooks/useSeries/prepare-treemap.js +4 -2
  25. package/dist/cjs/hooks/useSeries/prepare-waterfall.js +13 -8
  26. package/dist/cjs/hooks/useSeries/types.d.ts +5 -0
  27. package/dist/cjs/hooks/useSeries/utils.d.ts +7 -3
  28. package/dist/cjs/hooks/useSeries/utils.js +2 -2
  29. package/dist/cjs/hooks/useShapes/area/prepare-data.js +3 -0
  30. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +24 -46
  31. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +0 -3
  32. package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +4 -1
  33. package/dist/cjs/hooks/utils/bar-x.d.ts +3 -2
  34. package/dist/cjs/hooks/utils/bar-x.js +8 -6
  35. package/dist/cjs/hooks/utils/bar-y.d.ts +0 -1
  36. package/dist/cjs/hooks/utils/bar-y.js +3 -3
  37. package/dist/cjs/types/chart/area.d.ts +3 -3
  38. package/dist/cjs/types/chart/axis.d.ts +1 -0
  39. package/dist/cjs/types/chart/bar-x.d.ts +3 -3
  40. package/dist/cjs/types/chart/bar-y.d.ts +3 -3
  41. package/dist/cjs/types/chart/base.d.ts +9 -0
  42. package/dist/cjs/types/chart/funnel.d.ts +10 -6
  43. package/dist/cjs/types/chart/heatmap.d.ts +3 -3
  44. package/dist/cjs/types/chart/legend.d.ts +12 -10
  45. package/dist/cjs/types/chart/line.d.ts +3 -3
  46. package/dist/cjs/types/chart/pie.d.ts +10 -6
  47. package/dist/cjs/types/chart/radar.d.ts +3 -3
  48. package/dist/cjs/types/chart/sankey.d.ts +3 -3
  49. package/dist/cjs/types/chart/scatter.d.ts +3 -3
  50. package/dist/cjs/types/chart/treemap.d.ts +3 -3
  51. package/dist/cjs/types/chart/waterfall.d.ts +2 -2
  52. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +3 -3
  53. package/dist/esm/components/ChartInner/useChartInnerProps.js +34 -16
  54. package/dist/esm/components/Legend/index.js +50 -28
  55. package/dist/esm/hooks/useAxis/index.js +0 -1
  56. package/dist/esm/hooks/useAxis/x-axis.d.ts +1 -3
  57. package/dist/esm/hooks/useAxis/x-axis.js +3 -4
  58. package/dist/esm/hooks/useAxisScales/index.d.ts +1 -3
  59. package/dist/esm/hooks/useAxisScales/index.js +6 -35
  60. package/dist/esm/hooks/useChartDimensions/index.js +16 -1
  61. package/dist/esm/hooks/useRangeSlider/index.js +0 -1
  62. package/dist/esm/hooks/useSeries/index.js +8 -8
  63. package/dist/esm/hooks/useSeries/prepare-area.js +7 -5
  64. package/dist/esm/hooks/useSeries/prepare-bar-x.js +8 -6
  65. package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +2 -0
  66. package/dist/esm/hooks/useSeries/prepare-bar-y.js +7 -5
  67. package/dist/esm/hooks/useSeries/prepare-funnel.js +14 -10
  68. package/dist/esm/hooks/useSeries/prepare-heatmap.js +9 -7
  69. package/dist/esm/hooks/useSeries/prepare-legend.js +75 -15
  70. package/dist/esm/hooks/useSeries/prepare-line.js +6 -4
  71. package/dist/esm/hooks/useSeries/prepare-pie.js +10 -6
  72. package/dist/esm/hooks/useSeries/prepare-radar.js +7 -5
  73. package/dist/esm/hooks/useSeries/prepare-sankey.js +3 -1
  74. package/dist/esm/hooks/useSeries/prepare-scatter.js +4 -1
  75. package/dist/esm/hooks/useSeries/prepare-treemap.js +4 -2
  76. package/dist/esm/hooks/useSeries/prepare-waterfall.js +13 -8
  77. package/dist/esm/hooks/useSeries/types.d.ts +5 -0
  78. package/dist/esm/hooks/useSeries/utils.d.ts +7 -3
  79. package/dist/esm/hooks/useSeries/utils.js +2 -2
  80. package/dist/esm/hooks/useShapes/area/prepare-data.js +3 -0
  81. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +24 -46
  82. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +0 -3
  83. package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +4 -1
  84. package/dist/esm/hooks/utils/bar-x.d.ts +3 -2
  85. package/dist/esm/hooks/utils/bar-x.js +8 -6
  86. package/dist/esm/hooks/utils/bar-y.d.ts +0 -1
  87. package/dist/esm/hooks/utils/bar-y.js +3 -3
  88. package/dist/esm/types/chart/area.d.ts +3 -3
  89. package/dist/esm/types/chart/axis.d.ts +1 -0
  90. package/dist/esm/types/chart/bar-x.d.ts +3 -3
  91. package/dist/esm/types/chart/bar-y.d.ts +3 -3
  92. package/dist/esm/types/chart/base.d.ts +9 -0
  93. package/dist/esm/types/chart/funnel.d.ts +10 -6
  94. package/dist/esm/types/chart/heatmap.d.ts +3 -3
  95. package/dist/esm/types/chart/legend.d.ts +12 -10
  96. package/dist/esm/types/chart/line.d.ts +3 -3
  97. package/dist/esm/types/chart/pie.d.ts +10 -6
  98. package/dist/esm/types/chart/radar.d.ts +3 -3
  99. package/dist/esm/types/chart/sankey.d.ts +3 -3
  100. package/dist/esm/types/chart/scatter.d.ts +3 -3
  101. package/dist/esm/types/chart/treemap.d.ts +3 -3
  102. package/dist/esm/types/chart/waterfall.d.ts +2 -2
  103. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { Dispatch } from 'd3';
3
- import type { RangeSliderState, ZoomState } from '../../hooks';
3
+ import type { PreparedLegend, RangeSliderState, ZoomState } from '../../hooks';
4
4
  import type { ChartInnerProps } from './types';
5
5
  type Props = ChartInnerProps & {
6
6
  clipPathId: string;
@@ -35,7 +35,7 @@ export declare function useChartInnerProps(props: Props): {
35
35
  } | undefined;
36
36
  legendItems: never[] | import("../../hooks").LegendItem[][];
37
37
  preparedChart: import("../../hooks").PreparedChart;
38
- preparedLegend: import("../../hooks").PreparedLegend | null;
38
+ preparedLegend: PreparedLegend | null;
39
39
  preparedSeries: import("../../hooks").PreparedSeries[];
40
40
  preparedSeriesOptions: import("../../constants").SeriesOptionsDefaults;
41
41
  preparedSplit: import("../../hooks").PreparedSplit;
@@ -52,7 +52,7 @@ export declare function useChartInnerProps(props: Props): {
52
52
  xScale: import("../../hooks").ChartScale | undefined;
53
53
  yAxis: (Omit<import("../..").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
54
54
  type: import("../..").ChartAxisType;
55
- labels: Omit<import("../..").ChartAxisLabels, "enabled" | "style" | "padding" | "autoRotation"> & Required<Pick<import("../..").ChartAxisLabels, "enabled" | "html" | "padding" | "margin" | "rotation">> & {
55
+ labels: Omit<import("../..").ChartAxisLabels, "enabled" | "style" | "padding" | "autoRotation"> & Required<Pick<import("../..").ChartAxisLabels, "margin" | "html" | "enabled" | "padding" | "rotation">> & {
56
56
  style: import("../..").BaseTextStyle;
57
57
  rotation: number;
58
58
  height: number;
@@ -9,6 +9,30 @@ import { hasAtLeastOneSeriesDataPerPlot } from './utils';
9
9
  const CLIP_PATH_BY_SERIES_TYPE = {
10
10
  [SERIES_TYPE.Scatter]: false,
11
11
  };
12
+ function getBoundsOffsetTop(args) {
13
+ const { chartMarginTop, preparedLegend } = args;
14
+ return (chartMarginTop +
15
+ ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'top'
16
+ ? preparedLegend.height + preparedLegend.margin
17
+ : 0));
18
+ }
19
+ function getBoundsOffsetLeft(args) {
20
+ const { chartMarginLeft, preparedLegend, yAxis, getYAxisWidth: getAxisWidth } = args;
21
+ const legendOffset = (preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'left'
22
+ ? preparedLegend.width + preparedLegend.margin
23
+ : 0;
24
+ const leftAxisWidth = yAxis.reduce((acc, axis) => {
25
+ if (axis.position !== 'left') {
26
+ return acc;
27
+ }
28
+ const axisWidth = getAxisWidth(axis);
29
+ if (acc < axisWidth) {
30
+ acc = axisWidth;
31
+ }
32
+ return acc;
33
+ }, 0);
34
+ return chartMarginLeft + legendOffset + leftAxisWidth;
35
+ }
12
36
  export function useChartInnerProps(props) {
13
37
  var _a;
14
38
  const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, rangeSliderState, svgContainer, width, updateZoomState, zoomState, } = props;
@@ -81,7 +105,6 @@ export function useChartInnerProps(props) {
81
105
  boundsHeight,
82
106
  rangeSliderState,
83
107
  series: preparedSeries,
84
- seriesOptions: preparedSeriesOptions,
85
108
  split: preparedSplit,
86
109
  xAxis,
87
110
  yAxis,
@@ -130,22 +153,17 @@ export function useChartInnerProps(props) {
130
153
  yAxis,
131
154
  yScale,
132
155
  });
133
- const boundsOffsetTop = chart.margin.top +
134
- ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'top'
135
- ? preparedLegend.height + preparedLegend.margin
136
- : 0);
156
+ const boundsOffsetTop = getBoundsOffsetTop({
157
+ chartMarginTop: chart.margin.top,
158
+ preparedLegend,
159
+ });
137
160
  // We need to calculate the width of each left axis because the first axis can be hidden
138
- const boundsOffsetLeft = chart.margin.left +
139
- yAxis.reduce((acc, axis) => {
140
- if (axis.position !== 'left') {
141
- return acc;
142
- }
143
- const axisWidth = getYAxisWidth(axis);
144
- if (acc < axisWidth) {
145
- acc = axisWidth;
146
- }
147
- return acc;
148
- }, 0);
161
+ const boundsOffsetLeft = getBoundsOffsetLeft({
162
+ chartMarginLeft: chart.margin.left,
163
+ preparedLegend,
164
+ yAxis,
165
+ getYAxisWidth,
166
+ });
149
167
  const { x } = (_a = svgContainer === null || svgContainer === void 0 ? void 0 : svgContainer.getBoundingClientRect()) !== null && _a !== void 0 ? _a : {};
150
168
  return {
151
169
  allPreparedSeries,
@@ -6,16 +6,21 @@ import { block, createGradientRect, getContinuesColorFn, getLabelsSize, getLineD
6
6
  import { axisBottom } from '../../utils/chart/axis-generators';
7
7
  import './styles.css';
8
8
  const b = block('legend');
9
- const getLegendPosition = (args) => {
10
- const { align, offsetLeft = 0, width, contentWidth } = args;
11
- const top = 0;
12
- if (align === 'left') {
13
- return { top, left: offsetLeft };
14
- }
9
+ const getLegendItemPosition = (args) => {
10
+ const { align, width, contentWidth } = args;
15
11
  if (align === 'right') {
16
- return { top, left: offsetLeft + width - contentWidth };
12
+ return { left: width - contentWidth };
13
+ }
14
+ else if (align === 'left') {
15
+ return { left: 0 };
16
+ }
17
+ else {
18
+ return { left: width / 2 - contentWidth / 2 };
17
19
  }
18
- return { top, left: offsetLeft + width / 2 - contentWidth / 2 };
20
+ };
21
+ const getLegendPosition = (args) => {
22
+ const { offsetLeft, offsetTop, contentWidth, width } = args;
23
+ return { top: offsetTop, left: offsetLeft + width / 2 - contentWidth / 2 };
19
24
  };
20
25
  const appendPaginator = (args) => {
21
26
  const { container, pageIndex, legend, transform, pages, onArrowClick } = args;
@@ -115,7 +120,6 @@ function renderLegendSymbol(args) {
115
120
  }
116
121
  case 'symbol': {
117
122
  const y = legendLineHeight / 2;
118
- const translateX = x + d.symbol.width / 2;
119
123
  element
120
124
  .append('svg:path')
121
125
  .attr('d', () => {
@@ -124,7 +128,9 @@ function renderLegendSymbol(args) {
124
128
  // https://d3js.org/d3-shape/symbol#symbol
125
129
  return symbol(scatterSymbol, d.symbol.width * d.symbol.width)();
126
130
  })
127
- .attr('transform', () => {
131
+ .attr('transform', (_d, _index, elements) => {
132
+ var _a, _b;
133
+ const translateX = x + ((_b = (_a = elements[0]) === null || _a === void 0 ? void 0 : _a.getBBox()) === null || _b === void 0 ? void 0 : _b.width) / 2;
128
134
  return 'translate(' + translateX + ',' + y + ')';
129
135
  })
130
136
  .attr('class', className)
@@ -143,7 +149,7 @@ export const Legend = (props) => {
143
149
  }, [config.maxWidth]);
144
150
  React.useEffect(() => {
145
151
  async function prepareLegend() {
146
- var _a, _b, _c, _d, _e, _f, _g, _h;
152
+ var _a, _b, _c, _e, _f, _g, _h, _j;
147
153
  if (!ref.current || !htmlLayout) {
148
154
  return;
149
155
  }
@@ -156,9 +162,11 @@ export const Legend = (props) => {
156
162
  ? htmlElement.append('div').attr('data-legend', 1).style('position', 'absolute')
157
163
  : null;
158
164
  let legendWidth = 0;
165
+ let legendLeft = 0;
166
+ let legendTop = 0;
159
167
  if (legend.type === 'discrete') {
160
168
  const start = (_b = (_a = config.pagination) === null || _a === void 0 ? void 0 : _a.pages[pageIndex]) === null || _b === void 0 ? void 0 : _b.start;
161
- const end = (_d = (_c = config.pagination) === null || _c === void 0 ? void 0 : _c.pages[pageIndex]) === null || _d === void 0 ? void 0 : _d.end;
169
+ const end = (_e = (_c = config.pagination) === null || _c === void 0 ? void 0 : _c.pages[pageIndex]) === null || _e === void 0 ? void 0 : _e.end;
162
170
  const pageItems = typeof start === 'number' && typeof end === 'number'
163
171
  ? items.slice(start, end)
164
172
  : items;
@@ -174,7 +182,7 @@ export const Legend = (props) => {
174
182
  .append('g')
175
183
  .attr('class', b('item'))
176
184
  .on('click', function (e, d) {
177
- onItemClick({ name: d.name, metaKey: e.metaKey });
185
+ onItemClick({ id: d.id, name: d.name, metaKey: e.metaKey });
178
186
  onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate();
179
187
  });
180
188
  const getXPosition = (i) => {
@@ -213,7 +221,7 @@ export const Legend = (props) => {
213
221
  return '0px';
214
222
  })
215
223
  .on('click', function (e, d) {
216
- onItemClick({ name: d.name, metaKey: e.metaKey });
224
+ onItemClick({ id: d.id, name: d.name, metaKey: e.metaKey });
217
225
  onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate();
218
226
  })[legend.html ? 'html' : 'text'](function (d) {
219
227
  return d.name;
@@ -248,11 +256,10 @@ export const Legend = (props) => {
248
256
  let left = 0;
249
257
  switch (legend.justifyContent) {
250
258
  case 'center': {
251
- const legendLinePostion = getLegendPosition({
259
+ const legendLinePostion = getLegendItemPosition({
252
260
  align: legend.align,
253
261
  width: config.maxWidth,
254
262
  contentWidth,
255
- offsetLeft: config.offset.left,
256
263
  });
257
264
  left = legendLinePostion.left;
258
265
  legendWidth = config.maxWidth;
@@ -279,10 +286,31 @@ export const Legend = (props) => {
279
286
  onArrowClick: setPageIndex,
280
287
  });
281
288
  }
289
+ const { left, top } = getLegendPosition({
290
+ width: config.maxWidth,
291
+ contentWidth: legendWidth,
292
+ offsetLeft: config.offset.left,
293
+ offsetTop: config.offset.top,
294
+ });
295
+ legendLeft = left;
296
+ legendTop = top;
282
297
  }
283
298
  else {
299
+ const { left } = getLegendItemPosition({
300
+ align: legend.align,
301
+ width: config.maxWidth,
302
+ contentWidth: legend.width,
303
+ });
304
+ const { top } = getLegendPosition({
305
+ width: config.maxWidth,
306
+ contentWidth: legendWidth,
307
+ offsetLeft: config.offset.left,
308
+ offsetTop: config.offset.top,
309
+ });
310
+ legendLeft = left;
311
+ legendTop = top;
284
312
  // gradient rect
285
- const domain = (_e = legend.colorScale.domain) !== null && _e !== void 0 ? _e : [];
313
+ const domain = (_f = legend.colorScale.domain) !== null && _f !== void 0 ? _f : [];
286
314
  const rectHeight = CONTINUOUS_LEGEND_SIZE.height;
287
315
  svgElement.call(createGradientRect, {
288
316
  y: legend.title.height + legend.title.margin,
@@ -351,25 +379,19 @@ export const Legend = (props) => {
351
379
  .attr('class', legendTitleClassname)
352
380
  .append('text')
353
381
  .attr('dx', dx)
354
- .attr('font-weight', (_f = legend.title.style.fontWeight) !== null && _f !== void 0 ? _f : null)
355
- .attr('font-size', (_g = legend.title.style.fontSize) !== null && _g !== void 0 ? _g : null)
356
- .attr('fill', (_h = legend.title.style.fontColor) !== null && _h !== void 0 ? _h : null)
382
+ .attr('font-weight', (_g = legend.title.style.fontWeight) !== null && _g !== void 0 ? _g : null)
383
+ .attr('font-size', (_h = legend.title.style.fontSize) !== null && _h !== void 0 ? _h : null)
384
+ .attr('fill', (_j = legend.title.style.fontColor) !== null && _j !== void 0 ? _j : null)
357
385
  .style('dominant-baseline', 'text-before-edge')
358
386
  .html(legend.title.text);
359
387
  }
360
388
  else {
361
389
  svgElement.selectAll(`.${legendTitleClassname}`).remove();
362
390
  }
363
- const { left } = getLegendPosition({
364
- align: legend.align,
365
- width: config.maxWidth,
366
- contentWidth: legendWidth,
367
- offsetLeft: config.offset.left,
368
- });
369
391
  svgElement
370
- .attr('transform', `translate(${[left, config.offset.top].join(',')})`)
392
+ .attr('transform', `translate(${[legendLeft, legendTop].join(',')})`)
371
393
  .style('opacity', 1);
372
- htmlContainer === null || htmlContainer === void 0 ? void 0 : htmlContainer.style('transform', `translate(${left}px, ${config.offset.top}px)`);
394
+ htmlContainer === null || htmlContainer === void 0 ? void 0 : htmlContainer.style('transform', `translate(${legendLeft}px, ${legendTop}px)`);
373
395
  }
374
396
  prepareLegend();
375
397
  }, [chartSeries, onItemClick, onUpdate, legend, items, config, pageIndex, htmlLayout]);
@@ -18,7 +18,6 @@ export function useAxis(props) {
18
18
  xAxis,
19
19
  width,
20
20
  seriesData,
21
- seriesOptions: preparedSeriesOptions,
22
21
  });
23
22
  let estimatedBoundsHeight = boundsHeight !== null && boundsHeight !== void 0 ? boundsHeight : height;
24
23
  if (preparedXAxis && typeof boundsHeight !== 'number') {
@@ -1,9 +1,7 @@
1
1
  import type { ChartSeries, ChartXAxis } from '../../types';
2
- import type { PreparedSeriesOptions } from '../useSeries/types';
3
2
  import type { PreparedXAxis } from './types';
4
- export declare const getPreparedXAxis: ({ xAxis, seriesData, seriesOptions, width, }: {
3
+ export declare const getPreparedXAxis: ({ xAxis, seriesData, width, }: {
5
4
  xAxis?: ChartXAxis;
6
5
  seriesData: ChartSeries[];
7
- seriesOptions: PreparedSeriesOptions;
8
6
  width: number;
9
7
  }) => Promise<PreparedXAxis | null>;
@@ -4,8 +4,8 @@ import { calculateCos, calculateNumericProperty, formatAxisTickLabel, getAxisIte
4
4
  import { createXScale } from '../useAxisScales';
5
5
  import { getPreparedRangeSlider } from './range-slider';
6
6
  import { prepareAxisPlotLabel } from './utils';
7
- async function setLabelSettings({ axis, seriesData, seriesOptions, width, autoRotation = true, }) {
8
- const scale = createXScale({ axis, series: seriesData, seriesOptions, boundsWidth: width });
7
+ async function setLabelSettings({ axis, seriesData, width, autoRotation = true, }) {
8
+ const scale = createXScale({ axis, series: seriesData, boundsWidth: width });
9
9
  if (!scale) {
10
10
  axis.labels.height = 0;
11
11
  axis.labels.rotation = 0;
@@ -56,7 +56,7 @@ function getMaxPaddingBySeries({ series }) {
56
56
  }
57
57
  return 0.01;
58
58
  }
59
- export const getPreparedXAxis = async ({ xAxis, seriesData, seriesOptions, width, }) => {
59
+ export const getPreparedXAxis = async ({ xAxis, seriesData, width, }) => {
60
60
  var _a, _b, _c, _d, _e;
61
61
  const hasAxisRelatedSeries = seriesData.some(isAxisRelatedSeries);
62
62
  if (!hasAxisRelatedSeries) {
@@ -159,7 +159,6 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, seriesOptions, width
159
159
  await setLabelSettings({
160
160
  axis: preparedXAxis,
161
161
  seriesData,
162
- seriesOptions,
163
162
  width,
164
163
  autoRotation: (_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _e === void 0 ? void 0 : _e.autoRotation,
165
164
  });
@@ -1,12 +1,11 @@
1
1
  import type { ScaleBand, ScaleLinear, ScaleTime } from 'd3';
2
- import type { PreparedAxis, PreparedSeries, PreparedSeriesOptions, PreparedSplit, RangeSliderState, ZoomState } from '../../hooks';
2
+ import type { PreparedAxis, PreparedSeries, PreparedSplit, RangeSliderState, ZoomState } from '../../hooks';
3
3
  import type { ChartAxis, ChartSeries } from '../../types';
4
4
  export type ChartScale = ScaleLinear<number, number> | ScaleBand<string> | ScaleTime<number, number>;
5
5
  type Args = {
6
6
  boundsWidth: number;
7
7
  boundsHeight: number;
8
8
  series: PreparedSeries[];
9
- seriesOptions: PreparedSeriesOptions;
10
9
  xAxis: PreparedAxis | null;
11
10
  yAxis: PreparedAxis[];
12
11
  split: PreparedSplit;
@@ -27,7 +26,6 @@ export declare function createXScale(args: {
27
26
  axis: PreparedAxis | ChartAxis;
28
27
  boundsWidth: number;
29
28
  series: (PreparedSeries | ChartSeries)[];
30
- seriesOptions: PreparedSeriesOptions;
31
29
  rangeSliderState?: RangeSliderState;
32
30
  zoomStateX?: [number, number];
33
31
  }): ScaleBand<string> | ScaleLinear<number, number, never> | ScaleTime<number, number, never> | undefined;
@@ -3,7 +3,6 @@ import { extent, scaleBand, scaleLinear, scaleLog, scaleUtc } from 'd3';
3
3
  import get from 'lodash/get';
4
4
  import { DEFAULT_AXIS_TYPE, SERIES_TYPE } from '../../constants';
5
5
  import { CHART_SERIES_WITH_VOLUME_ON_Y_AXIS, getAxisCategories, getAxisHeight, getDataCategoryValue, getDefaultMaxXAxisValue, getDefaultMinXAxisValue, getDomainDataXBySeries, getDomainDataYBySeries, getOnlyVisibleSeries, isAxisRelatedSeries, isSeriesWithCategoryValues, } from '../../utils';
6
- import { getBarXLayoutForNumericScale, groupBarXDataByXValue } from '../utils/bar-x';
7
6
  import { getBandSize } from '../utils/get-band-size';
8
7
  import { checkIsPointDomain, getMinMaxPropsOrState, hasOnlyMarkerSeries } from './utils';
9
8
  const X_AXIS_ZOOM_PADDING = 0.02;
@@ -214,32 +213,19 @@ function calculateXAxisPadding(series) {
214
213
  return result;
215
214
  }
216
215
  function isSeriesWithXAxisOffset(series) {
217
- const types = [SERIES_TYPE.Heatmap];
216
+ const types = [SERIES_TYPE.Heatmap, SERIES_TYPE.BarX];
218
217
  return series.some((s) => types.includes(s.type));
219
218
  }
220
- function getXScaleRange({ boundsWidth, series, seriesOptions, hasZoomX, axis, }) {
219
+ function getXScaleRange({ boundsWidth, hasZoomX }) {
221
220
  const xAxisZoomPadding = boundsWidth * X_AXIS_ZOOM_PADDING;
222
221
  const xRange = [0, boundsWidth];
223
222
  const xRangeZoom = [0 + xAxisZoomPadding, boundsWidth - xAxisZoomPadding];
224
223
  const range = hasZoomX ? xRangeZoom : xRange;
225
- const barXSeries = series.filter((s) => s.type === SERIES_TYPE.BarX);
226
- if (barXSeries.length) {
227
- const groupedData = groupBarXDataByXValue(barXSeries, axis);
228
- if (Object.keys(groupedData).length > 1) {
229
- const { bandSize } = getBarXLayoutForNumericScale({
230
- plotWidth: boundsWidth,
231
- groupedData,
232
- seriesOptions,
233
- });
234
- const offset = bandSize / 2;
235
- return [range[0] + offset, range[1] - offset];
236
- }
237
- }
238
224
  return range;
239
225
  }
240
226
  // eslint-disable-next-line complexity
241
227
  export function createXScale(args) {
242
- const { axis, boundsWidth, series, seriesOptions, rangeSliderState, zoomStateX } = args;
228
+ const { axis, boundsWidth, series, rangeSliderState, zoomStateX } = args;
243
229
  const [xMinPropsOrState, xMaxPropsOrState] = getMinMaxPropsOrState({
244
230
  axis,
245
231
  maxValues: [zoomStateX === null || zoomStateX === void 0 ? void 0 : zoomStateX[1], rangeSliderState === null || rangeSliderState === void 0 ? void 0 : rangeSliderState.max],
@@ -260,10 +246,7 @@ export function createXScale(args) {
260
246
  const xAxisMaxPadding = boundsWidth * maxPadding + calculateXAxisPadding(series);
261
247
  const range = getXScaleRange({
262
248
  boundsWidth,
263
- series,
264
- seriesOptions,
265
249
  hasZoomX,
266
- axis,
267
250
  });
268
251
  switch (axis.order) {
269
252
  case 'sortDesc':
@@ -407,7 +390,7 @@ export function createXScale(args) {
407
390
  throw new Error('Failed to create xScale');
408
391
  }
409
392
  const createScales = (args) => {
410
- const { boundsWidth, boundsHeight, rangeSliderState, series, seriesOptions, split, xAxis, yAxis, zoomState, } = args;
393
+ const { boundsWidth, boundsHeight, rangeSliderState, series, split, xAxis, yAxis, zoomState } = args;
411
394
  let visibleSeries = getOnlyVisibleSeries(series);
412
395
  // Reassign to all series in case of all series unselected,
413
396
  // otherwise we will get an empty space without grid
@@ -419,7 +402,6 @@ const createScales = (args) => {
419
402
  boundsWidth,
420
403
  rangeSliderState,
421
404
  series: visibleSeries,
422
- seriesOptions,
423
405
  zoomStateX: zoomState === null || zoomState === void 0 ? void 0 : zoomState.x,
424
406
  })
425
407
  : undefined,
@@ -445,7 +427,7 @@ const createScales = (args) => {
445
427
  * Uses to create scales for axis related series
446
428
  */
447
429
  export const useAxisScales = (args) => {
448
- const { boundsWidth, boundsHeight, rangeSliderState, series, seriesOptions, split, xAxis, yAxis, zoomState, } = args;
430
+ const { boundsWidth, boundsHeight, rangeSliderState, series, split, xAxis, yAxis, zoomState } = args;
449
431
  return React.useMemo(() => {
450
432
  let xScale;
451
433
  let yScale;
@@ -456,7 +438,6 @@ export const useAxisScales = (args) => {
456
438
  boundsHeight,
457
439
  rangeSliderState,
458
440
  series,
459
- seriesOptions,
460
441
  split,
461
442
  xAxis,
462
443
  yAxis,
@@ -464,15 +445,5 @@ export const useAxisScales = (args) => {
464
445
  }));
465
446
  }
466
447
  return { xScale, yScale };
467
- }, [
468
- boundsWidth,
469
- boundsHeight,
470
- rangeSliderState,
471
- series,
472
- seriesOptions,
473
- split,
474
- xAxis,
475
- yAxis,
476
- zoomState,
477
- ]);
448
+ }, [boundsWidth, boundsHeight, rangeSliderState, series, split, xAxis, yAxis, zoomState]);
478
449
  };
@@ -30,6 +30,18 @@ const getTopOffset = ({ preparedLegend }) => {
30
30
  }
31
31
  return 0;
32
32
  };
33
+ const getRightOffset = ({ preparedLegend }) => {
34
+ if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'right') {
35
+ return preparedLegend.width + preparedLegend.margin;
36
+ }
37
+ return 0;
38
+ };
39
+ const getLeftOffset = ({ preparedLegend }) => {
40
+ if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'left') {
41
+ return preparedLegend.width + preparedLegend.margin;
42
+ }
43
+ return 0;
44
+ };
33
45
  export const useChartDimensions = (args) => {
34
46
  const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width } = args;
35
47
  return React.useMemo(() => {
@@ -41,7 +53,10 @@ export const useChartDimensions = (args) => {
41
53
  preparedXAxis,
42
54
  });
43
55
  const topOffset = getTopOffset({ preparedLegend });
56
+ const rightOffset = getRightOffset({ preparedLegend });
57
+ const leftOffset = getLeftOffset({ preparedLegend });
44
58
  const boundsHeight = height - margin.top - margin.bottom - bottomOffset - topOffset;
45
- return { boundsWidth, boundsHeight };
59
+ const adjustedBoundsWidth = boundsWidth - rightOffset - leftOffset;
60
+ return { boundsWidth: adjustedBoundsWidth, boundsHeight };
46
61
  }, [height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width]);
47
62
  };
@@ -41,7 +41,6 @@ export function useRangeSlider(props) {
41
41
  boundsHeight: preparedRangeSlider.height,
42
42
  boundsWidth,
43
43
  series: preparedSeries,
44
- seriesOptions: preparedSeriesOptions,
45
44
  split: EMPTY_PREPARED_SPLIT,
46
45
  xAxis: preparedXAxis,
47
46
  yAxis: preparedYAxis,
@@ -9,7 +9,7 @@ const useVisibleSeries = ({ preparedSeries, activeLegendItems, }) => {
9
9
  return React.useMemo(() => {
10
10
  return preparedSeries.map((singleSeries) => {
11
11
  if (singleSeries.legend.enabled) {
12
- return Object.assign(Object.assign({}, singleSeries), { visible: activeLegendItems.includes(singleSeries.name) });
12
+ return Object.assign(Object.assign({}, singleSeries), { visible: activeLegendItems.includes(singleSeries.legend.groupId) });
13
13
  }
14
14
  return singleSeries;
15
15
  });
@@ -61,15 +61,15 @@ export const useSeries = (args) => {
61
61
  }, [seriesData, seriesOptions, preparedLegend, colors]);
62
62
  const prevOriginalSeriesData = usePrevious(originalSeriesData);
63
63
  const chartSeries = useVisibleSeries({ preparedSeries, activeLegendItems });
64
- const handleLegendItemClick = React.useCallback(({ name, metaKey }) => {
64
+ const handleLegendItemClick = React.useCallback(({ id, metaKey }) => {
65
65
  const allItems = getAllLegendItems(preparedSeries);
66
- const onlyItemSelected = activeLegendItems.length === 1 && activeLegendItems.includes(name);
66
+ const onlyItemSelected = activeLegendItems.length === 1 && activeLegendItems.includes(id);
67
67
  let nextActiveLegendItems;
68
- if (metaKey && activeLegendItems.includes(name)) {
69
- nextActiveLegendItems = activeLegendItems.filter((item) => item !== name);
68
+ if (metaKey && activeLegendItems.includes(id)) {
69
+ nextActiveLegendItems = activeLegendItems.filter((item) => item !== id);
70
70
  }
71
- else if (metaKey && !activeLegendItems.includes(name)) {
72
- nextActiveLegendItems = activeLegendItems.concat(name);
71
+ else if (metaKey && !activeLegendItems.includes(id)) {
72
+ nextActiveLegendItems = activeLegendItems.concat(id);
73
73
  }
74
74
  else if (onlyItemSelected && allItems.length === 1) {
75
75
  nextActiveLegendItems = [];
@@ -78,7 +78,7 @@ export const useSeries = (args) => {
78
78
  nextActiveLegendItems = allItems;
79
79
  }
80
80
  else {
81
- nextActiveLegendItems = [name];
81
+ nextActiveLegendItems = [id];
82
82
  }
83
83
  setActiveLegendItems(nextActiveLegendItems);
84
84
  }, [preparedSeries, activeLegendItems]);
@@ -32,7 +32,6 @@ function prepareSeriesData(series) {
32
32
  case 'zero':
33
33
  return data.map((p) => { var _a; return (Object.assign(Object.assign({}, p), { y: (_a = p.y) !== null && _a !== void 0 ? _a : 0 })); });
34
34
  case 'connect':
35
- return data.filter((p) => p.y !== null);
36
35
  case 'skip':
37
36
  default:
38
37
  return data;
@@ -43,7 +42,7 @@ export function prepareArea(args) {
43
42
  const defaultAreaWidth = get(seriesOptions, 'area.lineWidth', DEFAULT_LINE_WIDTH);
44
43
  const defaultOpacity = get(seriesOptions, 'area.opacity', 0.75);
45
44
  return seriesList.map((series) => {
46
- var _a, _b, _c;
45
+ var _a, _b, _c, _d, _e, _f, _g;
47
46
  const id = getUniqId();
48
47
  const name = series.name || '';
49
48
  const color = series.color || colorScale(name);
@@ -58,23 +57,26 @@ export function prepareArea(args) {
58
57
  legend: {
59
58
  enabled: get(series, 'legend.enabled', legend.enabled),
60
59
  symbol: prepareLegendSymbol(series),
60
+ groupId: (_b = (_a = series.legend) === null || _a === void 0 ? void 0 : _a.groupId) !== null && _b !== void 0 ? _b : getUniqId(),
61
+ itemText: (_d = (_c = series.legend) === null || _c === void 0 ? void 0 : _c.itemText) !== null && _d !== void 0 ? _d : name,
61
62
  },
62
63
  data: prepareSeriesData(series),
63
64
  stacking: series.stacking,
64
65
  stackId: getSeriesStackId(series),
65
66
  dataLabels: {
66
- enabled: ((_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) || false,
67
- style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_b = series.dataLabels) === null || _b === void 0 ? void 0 : _b.style),
67
+ enabled: ((_e = series.dataLabels) === null || _e === void 0 ? void 0 : _e.enabled) || false,
68
+ style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_f = series.dataLabels) === null || _f === void 0 ? void 0 : _f.style),
68
69
  padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
69
70
  allowOverlap: get(series, 'dataLabels.allowOverlap', false),
70
71
  html: get(series, 'dataLabels.html', false),
71
- format: (_c = series.dataLabels) === null || _c === void 0 ? void 0 : _c.format,
72
+ format: (_g = series.dataLabels) === null || _g === void 0 ? void 0 : _g.format,
72
73
  },
73
74
  marker: prepareMarker(series, seriesOptions),
74
75
  cursor: get(series, 'cursor', null),
75
76
  yAxis: get(series, 'yAxis', 0),
76
77
  tooltip: series.tooltip,
77
78
  rangeSlider: Object.assign({}, seriesRangeSliderOptionsDefaults, series.rangeSlider),
79
+ nullMode: series.nullMode,
78
80
  };
79
81
  return prepared;
80
82
  }, []);
@@ -12,13 +12,13 @@ function prepareSeriesData(series) {
12
12
  return data.map((p) => { var _a; return (Object.assign(Object.assign({}, p), { y: (_a = p.y) !== null && _a !== void 0 ? _a : 0 })); });
13
13
  case 'skip':
14
14
  default:
15
- return data.filter((p) => p.y !== null);
15
+ return data;
16
16
  }
17
17
  }
18
18
  export function prepareBarXSeries(args) {
19
19
  const { colorScale, series: seriesList, seriesOptions, legend } = args;
20
20
  return seriesList.map((series) => {
21
- var _a, _b, _c, _d;
21
+ var _a, _b, _c, _d, _e, _f, _g, _h;
22
22
  const name = series.name || '';
23
23
  const color = series.color || colorScale(name);
24
24
  const dataLabelsInside = series.stacking === 'percent' ? true : get(series, 'dataLabels.inside', false);
@@ -31,18 +31,20 @@ export function prepareBarXSeries(args) {
31
31
  legend: {
32
32
  enabled: get(series, 'legend.enabled', legend.enabled),
33
33
  symbol: prepareLegendSymbol(series),
34
+ groupId: (_b = (_a = series.legend) === null || _a === void 0 ? void 0 : _a.groupId) !== null && _b !== void 0 ? _b : getUniqId(),
35
+ itemText: (_d = (_c = series.legend) === null || _c === void 0 ? void 0 : _c.itemText) !== null && _d !== void 0 ? _d : name,
34
36
  },
35
37
  data: prepareSeriesData(series),
36
38
  stacking: series.stacking,
37
39
  stackId: getSeriesStackId(series),
38
40
  dataLabels: {
39
- enabled: ((_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) || false,
41
+ enabled: ((_e = series.dataLabels) === null || _e === void 0 ? void 0 : _e.enabled) || false,
40
42
  inside: dataLabelsInside,
41
- style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_b = series.dataLabels) === null || _b === void 0 ? void 0 : _b.style),
42
- allowOverlap: ((_c = series.dataLabels) === null || _c === void 0 ? void 0 : _c.allowOverlap) || false,
43
+ style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_f = series.dataLabels) === null || _f === void 0 ? void 0 : _f.style),
44
+ allowOverlap: ((_g = series.dataLabels) === null || _g === void 0 ? void 0 : _g.allowOverlap) || false,
43
45
  padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
44
46
  html: get(series, 'dataLabels.html', false),
45
- format: (_d = series.dataLabels) === null || _d === void 0 ? void 0 : _d.format,
47
+ format: (_h = series.dataLabels) === null || _h === void 0 ? void 0 : _h.format,
46
48
  },
47
49
  cursor: get(series, 'cursor', null),
48
50
  yAxis: get(series, 'yAxis', 0),
@@ -32,6 +32,8 @@ export declare function prepareBarYSeries(args: PrepareBarYSeriesArgs): Promise<
32
32
  id: string;
33
33
  visible: boolean;
34
34
  legend: {
35
+ groupId: string;
36
+ itemText: string;
35
37
  enabled: boolean;
36
38
  symbol: import("./types").PreparedLegendSymbol;
37
39
  };