@gravity-ui/chartkit 5.1.0 → 5.2.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/build/plugins/d3/renderer/components/Chart.js +5 -4
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-area.js +1 -0
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-bar-x.js +1 -0
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-bar-y.js +1 -0
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-line.js +1 -0
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-pie.js +1 -0
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-scatter.js +1 -0
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-treemap.js +3 -1
- package/build/plugins/d3/renderer/hooks/useSeries/types.d.ts +2 -1
- package/build/plugins/d3/renderer/hooks/useShapes/area/index.js +2 -1
- package/build/plugins/d3/renderer/hooks/useShapes/bar-x/index.js +2 -1
- package/build/plugins/d3/renderer/hooks/useShapes/bar-y/index.js +2 -1
- package/build/plugins/d3/renderer/hooks/useShapes/line/index.js +2 -1
- package/build/plugins/d3/renderer/hooks/useShapes/pie/index.js +2 -1
- package/build/plugins/d3/renderer/hooks/useShapes/scatter/index.js +2 -1
- package/build/plugins/d3/renderer/hooks/useShapes/treemap/index.js +2 -1
- package/build/plugins/highcharts/renderer/components/withSplitPane/withSplitPane.d.ts +1 -0
- package/build/plugins/highcharts/renderer/components/withSplitPane/withSplitPane.js +2 -0
- package/build/plugins/yagr/renderer/tooltip/renderTooltip.d.ts +2 -2
- package/build/plugins/yagr/renderer/tooltip/renderTooltip.js +23 -2
- package/build/plugins/yagr/renderer/utils.js +1 -1
- package/build/plugins/yagr/types.d.ts +12 -2
- package/build/types/widget-data/base.d.ts +2 -0
- package/package.json +4 -3
|
@@ -13,6 +13,7 @@ import { Tooltip, TooltipTriggerArea } from './Tooltip';
|
|
|
13
13
|
import './styles.css';
|
|
14
14
|
const b = block('d3');
|
|
15
15
|
export const Chart = (props) => {
|
|
16
|
+
var _a, _b;
|
|
16
17
|
const { width, height, data } = props;
|
|
17
18
|
const svgRef = React.useRef(null);
|
|
18
19
|
const dispatcher = React.useMemo(() => {
|
|
@@ -60,15 +61,15 @@ export const Chart = (props) => {
|
|
|
60
61
|
yScale,
|
|
61
62
|
svgContainer: svgRef.current,
|
|
62
63
|
});
|
|
64
|
+
const clickHandler = (_b = (_a = data.chart) === null || _a === void 0 ? void 0 : _a.events) === null || _b === void 0 ? void 0 : _b.click;
|
|
63
65
|
React.useEffect(() => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
dispatcher.on('click-chart', (_d = (_c = data.chart) === null || _c === void 0 ? void 0 : _c.events) === null || _d === void 0 ? void 0 : _d.click);
|
|
66
|
+
if (clickHandler) {
|
|
67
|
+
dispatcher.on('click-chart', clickHandler);
|
|
67
68
|
}
|
|
68
69
|
return () => {
|
|
69
70
|
dispatcher.on('click-chart', null);
|
|
70
71
|
};
|
|
71
|
-
}, [dispatcher]);
|
|
72
|
+
}, [dispatcher, clickHandler]);
|
|
72
73
|
const boundsOffsetTop = chart.margin.top;
|
|
73
74
|
const boundsOffsetLeft = chart.margin.left + getWidthOccupiedByYAxis({ preparedAxis: yAxis });
|
|
74
75
|
return (React.createElement(React.Fragment, null,
|
|
@@ -30,6 +30,7 @@ export function prepareBarXSeries(args) {
|
|
|
30
30
|
allowOverlap: ((_e = series.dataLabels) === null || _e === void 0 ? void 0 : _e.allowOverlap) || false,
|
|
31
31
|
padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
|
|
32
32
|
},
|
|
33
|
+
cursor: get(series, 'cursor', null),
|
|
33
34
|
};
|
|
34
35
|
}, []);
|
|
35
36
|
}
|
|
@@ -10,7 +10,7 @@ export function prepareTreemap(args) {
|
|
|
10
10
|
const id = getRandomCKId();
|
|
11
11
|
const name = s.name || '';
|
|
12
12
|
const color = s.color || colorScale(name);
|
|
13
|
-
|
|
13
|
+
const preparedSeries = {
|
|
14
14
|
color,
|
|
15
15
|
data: s.data,
|
|
16
16
|
dataLabels: {
|
|
@@ -29,6 +29,8 @@ export function prepareTreemap(args) {
|
|
|
29
29
|
},
|
|
30
30
|
levels: s.levels,
|
|
31
31
|
layoutAlgorithm: get(s, 'layoutAlgorithm', LayoutAlgorithm.Binary),
|
|
32
|
+
cursor: get(s, 'cursor', null),
|
|
32
33
|
};
|
|
34
|
+
return preparedSeries;
|
|
33
35
|
});
|
|
34
36
|
}
|
|
@@ -53,6 +53,7 @@ type BasePreparedSeries = {
|
|
|
53
53
|
enabled: boolean;
|
|
54
54
|
symbol: PreparedLegendSymbol;
|
|
55
55
|
};
|
|
56
|
+
cursor: string | null;
|
|
56
57
|
};
|
|
57
58
|
export type PreparedScatterSeries = {
|
|
58
59
|
type: ScatterSeries['type'];
|
|
@@ -206,7 +207,7 @@ export type PreparedTreemapSeries = {
|
|
|
206
207
|
allowOverlap: boolean;
|
|
207
208
|
};
|
|
208
209
|
layoutAlgorithm: `${LayoutAlgorithm}`;
|
|
209
|
-
} & BasePreparedSeries & TreemapSeries
|
|
210
|
+
} & BasePreparedSeries & Omit<TreemapSeries, keyof BasePreparedSeries>;
|
|
210
211
|
export type PreparedSeries = PreparedScatterSeries | PreparedBarXSeries | PreparedBarYSeries | PreparedPieSeries | PreparedLineSeries | PreparedAreaSeries | PreparedTreemapSeries;
|
|
211
212
|
export type PreparedSeriesOptions = SeriesOptionsDefaults;
|
|
212
213
|
export type StackedSeries = BarXSeries | AreaSeries | BarYSeries;
|
|
@@ -25,7 +25,8 @@ export const AreaSeriesShapes = (args) => {
|
|
|
25
25
|
.selectAll('shape')
|
|
26
26
|
.data(preparedData)
|
|
27
27
|
.join('g')
|
|
28
|
-
.attr('class', b('series'))
|
|
28
|
+
.attr('class', b('series'))
|
|
29
|
+
.attr('cursor', (d) => d.series.cursor);
|
|
29
30
|
shapeSelection
|
|
30
31
|
.append('path')
|
|
31
32
|
.attr('class', b('line'))
|
|
@@ -28,7 +28,8 @@ export const BarXSeriesShapes = (args) => {
|
|
|
28
28
|
.attr('height', (d) => d.height)
|
|
29
29
|
.attr('width', (d) => d.width)
|
|
30
30
|
.attr('fill', (d) => d.data.color || d.series.color)
|
|
31
|
-
.attr('opacity', (d) => d.opacity)
|
|
31
|
+
.attr('opacity', (d) => d.opacity)
|
|
32
|
+
.attr('cursor', (d) => d.series.cursor);
|
|
32
33
|
let dataLabels = preparedData.map((d) => d.label).filter(Boolean);
|
|
33
34
|
if (!((_a = preparedData[0]) === null || _a === void 0 ? void 0 : _a.series.dataLabels.allowOverlap)) {
|
|
34
35
|
dataLabels = filterOverlappingLabels(dataLabels);
|
|
@@ -24,7 +24,8 @@ export const BarYSeriesShapes = (args) => {
|
|
|
24
24
|
.attr('height', (d) => d.height)
|
|
25
25
|
.attr('width', (d) => d.width)
|
|
26
26
|
.attr('fill', (d) => d.color)
|
|
27
|
-
.attr('opacity', (d) => d.data.opacity || null)
|
|
27
|
+
.attr('opacity', (d) => d.data.opacity || null)
|
|
28
|
+
.attr('cursor', (d) => d.series.cursor);
|
|
28
29
|
const dataLabels = preparedData.filter((d) => d.series.dataLabels.enabled);
|
|
29
30
|
const labelSelection = svgElement
|
|
30
31
|
.selectAll('text')
|
|
@@ -32,7 +32,8 @@ export const LineSeriesShapes = (args) => {
|
|
|
32
32
|
.attr('stroke-linejoin', (d) => d.linecap)
|
|
33
33
|
.attr('stroke-linecap', (d) => d.linecap)
|
|
34
34
|
.attr('stroke-dasharray', (d) => getLineDashArray(d.dashStyle, d.width))
|
|
35
|
-
.attr('opacity', (d) => d.opacity)
|
|
35
|
+
.attr('opacity', (d) => d.opacity)
|
|
36
|
+
.attr('cursor', (d) => d.series.cursor);
|
|
36
37
|
let dataLabels = preparedData.reduce((acc, d) => {
|
|
37
38
|
return acc.concat(d.labels);
|
|
38
39
|
}, []);
|
|
@@ -32,7 +32,8 @@ export function PieSeriesShapes(args) {
|
|
|
32
32
|
return `translate(${x}, ${y})`;
|
|
33
33
|
})
|
|
34
34
|
.style('stroke', (pieData) => pieData.borderColor)
|
|
35
|
-
.style('stroke-width', (pieData) => pieData.borderWidth)
|
|
35
|
+
.style('stroke-width', (pieData) => pieData.borderWidth)
|
|
36
|
+
.attr('cursor', (pieData) => pieData.series.cursor);
|
|
36
37
|
// Render halo appearing outside the hovered slice
|
|
37
38
|
shapesSelection
|
|
38
39
|
.selectAll('halo')
|
|
@@ -23,7 +23,8 @@ export function ScatterSeriesShape(props) {
|
|
|
23
23
|
.join('g')
|
|
24
24
|
.call(renderMarker)
|
|
25
25
|
.attr('fill', (d) => d.point.data.color || d.point.series.color || '')
|
|
26
|
-
.attr('opacity', (d) => d.point.opacity)
|
|
26
|
+
.attr('opacity', (d) => d.point.opacity)
|
|
27
|
+
.attr('cursor', (d) => d.point.series.cursor);
|
|
27
28
|
const getSelectedPoint = (element) => {
|
|
28
29
|
return select(element).datum();
|
|
29
30
|
};
|
|
@@ -18,7 +18,8 @@ export const TreemapSeriesShape = (props) => {
|
|
|
18
18
|
.selectAll('g')
|
|
19
19
|
.data(leaves)
|
|
20
20
|
.join('g')
|
|
21
|
-
.attr('transform', (d) => `translate(${d.x0},${d.y0})`)
|
|
21
|
+
.attr('transform', (d) => `translate(${d.x0},${d.y0})`)
|
|
22
|
+
.attr('cursor', series.cursor);
|
|
22
23
|
const rectSelection = leaf
|
|
23
24
|
.append('rect')
|
|
24
25
|
.attr('id', (d) => d.id || d.name)
|
|
@@ -110,8 +110,10 @@ export const withSplitPane = (ComposedComponent) => {
|
|
|
110
110
|
}
|
|
111
111
|
};
|
|
112
112
|
this.afterCreateCallback = (chart) => {
|
|
113
|
+
var _a, _b;
|
|
113
114
|
chart.tooltip.splitTooltip = true;
|
|
114
115
|
chart.tooltip.getTooltipContainer = this.getTooltipContainer;
|
|
116
|
+
(_b = (_a = this.props).callback) === null || _b === void 0 ? void 0 : _b.call(_a, chart);
|
|
115
117
|
};
|
|
116
118
|
this.setInitialPaneSize = (callback) => {
|
|
117
119
|
if (!this.tooltipContainerRef.current || !this.rootRef.current) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TooltipRenderOptions } from '../../types';
|
|
2
|
-
export declare const getRenderTooltip: (
|
|
1
|
+
import type { TooltipRenderOptions, YagrWidgetData } from '../../types';
|
|
2
|
+
export declare const getRenderTooltip: (userData: YagrWidgetData['data']) => (data: TooltipRenderOptions) => string;
|
|
@@ -7,12 +7,33 @@ const calcOption = (d) => {
|
|
|
7
7
|
})
|
|
8
8
|
: d;
|
|
9
9
|
};
|
|
10
|
+
const getSeriesColorProperty = (args) => {
|
|
11
|
+
var _a;
|
|
12
|
+
const { data, userData, row, rowIndex } = args;
|
|
13
|
+
const userSeries = userData.graphs[rowIndex];
|
|
14
|
+
const lineColor = (_a = data.yagr.getSeriesById(row.id)) === null || _a === void 0 ? void 0 : _a.lineColor;
|
|
15
|
+
let seriesColor = row.color;
|
|
16
|
+
switch (userSeries === null || userSeries === void 0 ? void 0 : userSeries.legendColorKey) {
|
|
17
|
+
case 'lineColor': {
|
|
18
|
+
if (lineColor) {
|
|
19
|
+
seriesColor = lineColor;
|
|
20
|
+
}
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
case 'color':
|
|
24
|
+
default: {
|
|
25
|
+
seriesColor = row.color;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return seriesColor;
|
|
29
|
+
};
|
|
10
30
|
/*
|
|
11
31
|
* Default tooltip renderer.
|
|
12
32
|
* Adapter between native Yagr tooltip config and ChartKit
|
|
13
33
|
* tooltip renderer.
|
|
14
34
|
*/
|
|
15
|
-
export const getRenderTooltip = (
|
|
35
|
+
export const getRenderTooltip = (userData) => (data) => {
|
|
36
|
+
const { timeZone } = userData;
|
|
16
37
|
const cfg = data.yagr.config;
|
|
17
38
|
const timeMultiplier = cfg.chart.timeMultiplier || 1;
|
|
18
39
|
const opts = data.options;
|
|
@@ -41,7 +62,7 @@ export const getRenderTooltip = (timeZone) => (data) => {
|
|
|
41
62
|
activeRowAlwaysFirstInTooltip: rows.length > 1,
|
|
42
63
|
tooltipHeader: dateTime({ input: x / timeMultiplier, timeZone }).format('DD MMMM YYYY HH:mm:ss'),
|
|
43
64
|
shared: true,
|
|
44
|
-
lines: rows.map((row, i) => (Object.assign(Object.assign({}, row), { seriesName: row.name || 'Serie ' + (i + 1), seriesColor: row
|
|
65
|
+
lines: rows.map((row, i) => (Object.assign(Object.assign({}, row), { seriesName: row.name || 'Serie ' + (i + 1), seriesColor: getSeriesColorProperty({ data, userData, row, rowIndex: i }), selectedSeries: row.active, seriesIdx: row.seriesIdx, percentValue: typeof row.transformed === 'number' ? row.transformed.toFixed(1) : '' }))),
|
|
45
66
|
withPercent: calcOption(opts.percent),
|
|
46
67
|
hiddenRowsNumber: hiddenRowsNumber,
|
|
47
68
|
hiddenRowsSum,
|
|
@@ -111,7 +111,7 @@ export const shapeYagrConfig = (args) => {
|
|
|
111
111
|
config.chart = chart;
|
|
112
112
|
if ((_a = config.tooltip) === null || _a === void 0 ? void 0 : _a.show) {
|
|
113
113
|
config.tooltip = config.tooltip || {};
|
|
114
|
-
config.tooltip.render = ((_b = config.tooltip) === null || _b === void 0 ? void 0 : _b.render) || getRenderTooltip(
|
|
114
|
+
config.tooltip.render = ((_b = config.tooltip) === null || _b === void 0 ? void 0 : _b.render) || getRenderTooltip(data);
|
|
115
115
|
if (!config.tooltip.className) {
|
|
116
116
|
// "className" property prevent default yagr styles adding
|
|
117
117
|
config.tooltip.className = 'chartkit-yagr-tooltip';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MinimalValidConfig, RawSerieData, YagrConfig } from '@gravity-ui/yagr';
|
|
1
|
+
import type { MinimalValidConfig, RawSerieData, SeriesOptions, YagrConfig } from '@gravity-ui/yagr';
|
|
2
2
|
import type Yagr from '@gravity-ui/yagr';
|
|
3
3
|
import { ChartKitProps } from 'src/types';
|
|
4
4
|
export type { default as Yagr } from '@gravity-ui/yagr';
|
|
@@ -10,9 +10,19 @@ export interface CustomTooltipProps {
|
|
|
10
10
|
export type YagrWidgetProps = ChartKitProps<'yagr'> & {
|
|
11
11
|
id: string;
|
|
12
12
|
};
|
|
13
|
+
export type YagrSeriesData<T = Omit<SeriesOptions, 'type'>> = RawSerieData<T> & {
|
|
14
|
+
/**
|
|
15
|
+
* Determines what data value should be used to get a color for tooltip series. Does not work in case of using custom tooltip rendered via `tooltip` property.
|
|
16
|
+
* - `lineColor` indicates that lineColor property should be used
|
|
17
|
+
* - `color` indicates that color property should be used
|
|
18
|
+
*
|
|
19
|
+
* @default 'color'
|
|
20
|
+
*/
|
|
21
|
+
legendColorKey?: 'color' | 'lineColor';
|
|
22
|
+
};
|
|
13
23
|
export type YagrWidgetData = {
|
|
14
24
|
data: {
|
|
15
|
-
graphs:
|
|
25
|
+
graphs: YagrSeriesData[];
|
|
16
26
|
timeline: number[];
|
|
17
27
|
/**
|
|
18
28
|
* Allow to setup timezone for X axis and tooltip's header.
|
|
@@ -22,6 +22,8 @@ export type BaseSeries = {
|
|
|
22
22
|
* */
|
|
23
23
|
allowOverlap?: boolean;
|
|
24
24
|
};
|
|
25
|
+
/** You can set the cursor to "pointer" if you have click events attached to the series, to signal to the user that the points and lines can be clicked. */
|
|
26
|
+
cursor?: string;
|
|
25
27
|
};
|
|
26
28
|
export type BaseSeriesData<T = any> = {
|
|
27
29
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravity-ui/chartkit",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.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,18 +48,19 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@bem-react/classname": "^1.6.0",
|
|
50
50
|
"@gravity-ui/date-utils": "^2.1.0",
|
|
51
|
+
"@gravity-ui/i18n": "^1.0.0",
|
|
51
52
|
"@gravity-ui/yagr": "^4.2.3",
|
|
52
53
|
"afterframe": "^1.0.2",
|
|
53
54
|
"d3": "^7.8.5",
|
|
54
55
|
"lodash": "^4.17.21",
|
|
55
|
-
"react-split-pane": "^0.1.92"
|
|
56
|
+
"react-split-pane": "^0.1.92",
|
|
57
|
+
"tslib": "^2.6.2"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
58
60
|
"@babel/preset-env": "^7.22.6",
|
|
59
61
|
"@babel/preset-react": "^7.22.5",
|
|
60
62
|
"@babel/preset-typescript": "^7.22.5",
|
|
61
63
|
"@gravity-ui/eslint-config": "^3.1.1",
|
|
62
|
-
"@gravity-ui/i18n": "^1.0.0",
|
|
63
64
|
"@gravity-ui/prettier-config": "^1.1.0",
|
|
64
65
|
"@gravity-ui/stylelint-config": "^4.0.1",
|
|
65
66
|
"@gravity-ui/tsconfig": "^1.0.0",
|