@gravity-ui/chartkit 4.11.0 → 4.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.
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { select } from 'd3';
2
+ import { select, line as lineGenerator } from 'd3';
3
3
  import { block } from '../../../../utils/cn';
4
4
  const b = block('d3-legend');
5
5
  const getLegendPosition = (args) => {
@@ -56,6 +56,58 @@ const appendPaginator = (args) => {
56
56
  });
57
57
  paginationLine.attr('transform', transform);
58
58
  };
59
+ const legendSymbolGenerator = lineGenerator()
60
+ .x((d) => d.x)
61
+ .y((d) => d.y);
62
+ function renderLegendSymbol(args) {
63
+ const { selection, legend } = args;
64
+ const line = selection.data();
65
+ const getXPosition = (i) => {
66
+ return line.slice(0, i).reduce((acc, legendItem) => {
67
+ return (acc +
68
+ legendItem.symbol.width +
69
+ legendItem.symbol.padding +
70
+ legendItem.textWidth +
71
+ legend.itemDistance);
72
+ }, 0);
73
+ };
74
+ selection.each(function (d, i) {
75
+ const element = select(this);
76
+ const x = getXPosition(i);
77
+ const className = b('item-symbol', { shape: d.symbol.shape, unselected: !d.visible });
78
+ const color = d.visible ? d.color : '';
79
+ switch (d.symbol.shape) {
80
+ case 'path': {
81
+ const y = legend.lineHeight / 2;
82
+ const points = [
83
+ { x: x, y },
84
+ { x: x + d.symbol.width, y },
85
+ ];
86
+ element
87
+ .append('path')
88
+ .attr('d', legendSymbolGenerator(points))
89
+ .attr('fill', 'none')
90
+ .attr('stroke-width', d.symbol.strokeWidth)
91
+ .attr('class', className)
92
+ .style('stroke', color);
93
+ break;
94
+ }
95
+ case 'rect': {
96
+ const y = (legend.lineHeight - d.symbol.height) / 2;
97
+ element
98
+ .append('rect')
99
+ .attr('x', x)
100
+ .attr('y', y)
101
+ .attr('width', d.symbol.width)
102
+ .attr('height', d.symbol.height)
103
+ .attr('rx', d.symbol.radius)
104
+ .attr('class', className)
105
+ .style('fill', color);
106
+ break;
107
+ }
108
+ }
109
+ });
110
+ }
59
111
  export const Legend = (props) => {
60
112
  const { boundsWidth, chartSeries, legend, items, config, onItemClick } = props;
61
113
  const ref = React.useRef(null);
@@ -95,25 +147,7 @@ export const Legend = (props) => {
95
147
  legend.itemDistance);
96
148
  }, 0);
97
149
  };
98
- legendItemTemplate
99
- .append('rect')
100
- .attr('x', function (_d, i) {
101
- return getXPosition(i);
102
- })
103
- .attr('y', (legendItem) => {
104
- return (legend.lineHeight - legendItem.symbol.height) / 2;
105
- })
106
- .attr('width', (legendItem) => {
107
- return legendItem.symbol.width;
108
- })
109
- .attr('height', (legendItem) => legendItem.symbol.height)
110
- .attr('rx', (legendItem) => legendItem.symbol.radius)
111
- .attr('class', function (d) {
112
- return b('item-shape', { unselected: !d.visible });
113
- })
114
- .style('fill', function (d) {
115
- return d.visible ? d.color : '';
116
- });
150
+ renderLegendSymbol({ selection: legendItemTemplate, legend });
117
151
  legendItemTemplate
118
152
  .append('text')
119
153
  .attr('x', function (legendItem, i) {
@@ -21,12 +21,12 @@
21
21
  user-select: none;
22
22
  }
23
23
 
24
- .chartkit-d3-legend__item-shape {
25
- fill: var(--g-color-base-misc-medium);
24
+ .chartkit-d3-legend__item-symbol_shape_rect.chartkit-d3-legend__item-symbol_unselected {
25
+ fill: var(--g-color-text-hint);
26
26
  }
27
27
 
28
- .chartkit-d3-legend__item-shape_unselected {
29
- fill: var(--g-color-text-hint);
28
+ .chartkit-d3-legend__item-symbol_shape_path.chartkit-d3-legend__item-symbol_unselected {
29
+ stroke: var(--g-color-text-hint);
30
30
  }
31
31
 
32
32
  .chartkit-d3-legend__item-text {
@@ -1,4 +1,5 @@
1
1
  import { BaseTextStyle } from '../../../../../types';
2
2
  export declare const DEFAULT_LEGEND_SYMBOL_SIZE = 8;
3
+ export declare const DEFAULT_LEGEND_SYMBOL_PADDING = 5;
3
4
  export declare const DEFAULT_DATALABELS_PADDING = 5;
4
5
  export declare const DEFAULT_DATALABELS_STYLE: BaseTextStyle;
@@ -1,4 +1,5 @@
1
1
  export const DEFAULT_LEGEND_SYMBOL_SIZE = 8;
2
+ export const DEFAULT_LEGEND_SYMBOL_PADDING = 5;
2
3
  export const DEFAULT_DATALABELS_PADDING = 5;
3
4
  export const DEFAULT_DATALABELS_STYLE = {
4
5
  fontSize: '11px',
@@ -1,4 +1,4 @@
1
- import type { ChartKitWidgetData } from '../../../../../types/widget-data';
1
+ import type { ChartKitWidgetData } from '../../../../../types';
2
2
  import type { PreparedAxis, PreparedChart } from '../useChartOptions/types';
3
3
  import type { PreparedLegend, PreparedSeries, LegendItem } from './types';
4
4
  export declare const getPreparedLegend: (args: {
@@ -1,6 +1,8 @@
1
1
  import { ScaleOrdinal } from 'd3';
2
2
  import { ChartKitWidgetSeriesOptions, LineSeries } from '../../../../../types';
3
3
  import { PreparedLegend, PreparedSeries } from './types';
4
+ export declare const DEFAULT_LEGEND_SYMBOL_SIZE = 16;
5
+ export declare const DEFAULT_LINE_WIDTH = 1;
4
6
  type PrepareLineSeriesArgs = {
5
7
  colorScale: ScaleOrdinal<string, string>;
6
8
  series: LineSeries[];
@@ -1,10 +1,22 @@
1
1
  import get from 'lodash/get';
2
- import { DEFAULT_DATALABELS_PADDING, DEFAULT_DATALABELS_STYLE } from './constants';
3
- import { prepareLegendSymbol } from './utils';
2
+ import { DEFAULT_DATALABELS_PADDING, DEFAULT_DATALABELS_STYLE, DEFAULT_LEGEND_SYMBOL_PADDING, } from './constants';
4
3
  import { getRandomCKId } from '../../../../../utils';
4
+ export const DEFAULT_LEGEND_SYMBOL_SIZE = 16;
5
+ export const DEFAULT_LINE_WIDTH = 1;
6
+ function prepareLineLegendSymbol(series, seriesOptions) {
7
+ var _a;
8
+ const symbolOptions = ((_a = series.legend) === null || _a === void 0 ? void 0 : _a.symbol) || {};
9
+ const defaultLineWidth = get(seriesOptions, 'line.lineWidth', DEFAULT_LINE_WIDTH);
10
+ return {
11
+ shape: 'path',
12
+ width: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.width) || DEFAULT_LEGEND_SYMBOL_SIZE,
13
+ padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || DEFAULT_LEGEND_SYMBOL_PADDING,
14
+ strokeWidth: get(series, 'lineWidth', defaultLineWidth),
15
+ };
16
+ }
5
17
  export function prepareLineSeries(args) {
6
18
  const { colorScale, series: seriesList, seriesOptions, legend } = args;
7
- const defaultLineWidth = get(seriesOptions, 'line.lineWidth', 1);
19
+ const defaultLineWidth = get(seriesOptions, 'line.lineWidth', DEFAULT_LINE_WIDTH);
8
20
  return seriesList.map((series) => {
9
21
  var _a, _b;
10
22
  const id = getRandomCKId();
@@ -19,7 +31,7 @@ export function prepareLineSeries(args) {
19
31
  visible: get(series, 'visible', true),
20
32
  legend: {
21
33
  enabled: get(series, 'legend.enabled', legend.enabled),
22
- symbol: prepareLegendSymbol(series),
34
+ symbol: prepareLineLegendSymbol(series, seriesOptions),
23
35
  },
24
36
  data: series.data,
25
37
  dataLabels: {
@@ -1,9 +1,13 @@
1
- import { BarXSeries, BarXSeriesData, BaseTextStyle, ChartKitWidgetLegend, PieSeries, PieSeriesData, RectLegendSymbolOptions, ScatterSeries, ScatterSeriesData, BarYSeries, BarYSeriesData, LineSeries, LineSeriesData, ConnectorShape, ConnectorCurve } from '../../../../../types';
1
+ import { BarXSeries, BarXSeriesData, BaseTextStyle, ChartKitWidgetLegend, PieSeries, PieSeriesData, RectLegendSymbolOptions, ScatterSeries, ScatterSeriesData, BarYSeries, BarYSeriesData, LineSeries, LineSeriesData, ConnectorShape, ConnectorCurve, PathLegendSymbolOptions } from '../../../../../types';
2
2
  import type { SeriesOptionsDefaults } from '../../constants';
3
3
  export type RectLegendSymbol = {
4
4
  shape: 'rect';
5
5
  } & Required<RectLegendSymbolOptions>;
6
- export type PreparedLegendSymbol = RectLegendSymbol;
6
+ export type PathLegendSymbol = {
7
+ shape: 'path';
8
+ strokeWidth: number;
9
+ } & Required<PathLegendSymbolOptions>;
10
+ export type PreparedLegendSymbol = RectLegendSymbol | PathLegendSymbol;
7
11
  export type PreparedLegend = Required<ChartKitWidgetLegend> & {
8
12
  height: number;
9
13
  lineHeight: number;
@@ -1,4 +1,4 @@
1
- import { DEFAULT_LEGEND_SYMBOL_SIZE } from './constants';
1
+ import { DEFAULT_LEGEND_SYMBOL_PADDING, DEFAULT_LEGEND_SYMBOL_SIZE } from './constants';
2
2
  export const getActiveLegendItems = (series) => {
3
3
  return series.reduce((acc, s) => {
4
4
  if (s.legend.enabled && s.visible) {
@@ -19,6 +19,6 @@ export function prepareLegendSymbol(series) {
19
19
  width: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.width) || DEFAULT_LEGEND_SYMBOL_SIZE,
20
20
  height: symbolHeight,
21
21
  radius: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.radius) || symbolHeight / 2,
22
- padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || 5,
22
+ padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || DEFAULT_LEGEND_SYMBOL_PADDING,
23
23
  };
24
24
  }
@@ -50,3 +50,11 @@ export type RectLegendSymbolOptions = BaseLegendSymbol & {
50
50
  */
51
51
  radius?: number;
52
52
  };
53
+ export type PathLegendSymbolOptions = BaseLegendSymbol & {
54
+ /**
55
+ * The pixel width of the symbol for series types that use a path in the legend
56
+ *
57
+ * @default 16
58
+ * */
59
+ width?: number;
60
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/chartkit",
3
- "version": "4.11.0",
3
+ "version": "4.12.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",
@@ -48,7 +48,7 @@
48
48
  "dependencies": {
49
49
  "@bem-react/classname": "^1.6.0",
50
50
  "@gravity-ui/date-utils": "^1.4.1",
51
- "@gravity-ui/yagr": "^4.0.0",
51
+ "@gravity-ui/yagr": "^4.0.1",
52
52
  "afterframe": "^1.0.2",
53
53
  "d3": "^7.8.5",
54
54
  "lodash": "^4.17.21",