@gravity-ui/chartkit 4.14.0 → 4.15.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/constants/index.d.ts +1 -0
- package/build/constants/index.js +1 -0
- package/build/constants/widget-data.d.ts +27 -0
- package/build/constants/widget-data.js +29 -0
- package/build/plugins/d3/examples/ExampleWrapper.d.ts +7 -0
- package/build/plugins/d3/examples/ExampleWrapper.js +5 -0
- package/build/plugins/d3/examples/area/Basic.js +3 -4
- package/build/plugins/d3/examples/area/StackedArea.js +3 -4
- package/build/plugins/d3/examples/bar-x/Basic.js +8 -4
- package/build/plugins/d3/examples/bar-x/DataLabels.js +4 -2
- package/build/plugins/d3/examples/bar-x/GroupedColumns.js +4 -2
- package/build/plugins/d3/examples/bar-x/StackedColumns.js +4 -2
- package/build/plugins/d3/examples/bar-y/Basic.js +4 -2
- package/build/plugins/d3/examples/bar-y/GroupedColumns.js +4 -2
- package/build/plugins/d3/examples/bar-y/StackedColumns.js +4 -2
- package/build/plugins/d3/examples/combined/LineAndBarX.js +5 -3
- package/build/plugins/d3/examples/line/Basic.js +4 -2
- package/build/plugins/d3/examples/line/DataLabels.js +4 -2
- package/build/plugins/d3/examples/line/LineWithMarkers.js +4 -2
- package/build/plugins/d3/examples/line/Shapes.d.ts +2 -0
- package/build/plugins/d3/examples/line/Shapes.js +93 -0
- package/build/plugins/d3/examples/pie/Basic.js +4 -2
- package/build/plugins/d3/examples/pie/Donut.js +4 -2
- package/build/plugins/d3/examples/scatter/Basic.js +4 -2
- package/build/plugins/d3/renderer/components/Legend.js +4 -0
- package/build/plugins/d3/renderer/hooks/useSeries/constants.d.ts +2 -3
- package/build/plugins/d3/renderer/hooks/useSeries/constants.js +1 -1
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-line-series.d.ts +2 -0
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-line-series.js +11 -0
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-pie.d.ts +2 -1
- package/build/plugins/d3/renderer/hooks/useSeries/prepare-pie.js +11 -1
- package/build/plugins/d3/renderer/hooks/useSeries/prepareSeries.js +1 -1
- package/build/plugins/d3/renderer/hooks/useSeries/types.d.ts +16 -10
- package/build/plugins/d3/renderer/hooks/useShapes/area/index.js +5 -62
- package/build/plugins/d3/renderer/hooks/useShapes/line/index.js +9 -65
- package/build/plugins/d3/renderer/hooks/useShapes/line/prepare-data.js +5 -2
- package/build/plugins/d3/renderer/hooks/useShapes/line/types.d.ts +3 -0
- package/build/plugins/d3/renderer/hooks/useShapes/marker.d.ts +12 -0
- package/build/plugins/d3/renderer/hooks/useShapes/marker.js +70 -0
- package/build/plugins/d3/renderer/hooks/useShapes/pie/index.d.ts +3 -2
- package/build/plugins/d3/renderer/hooks/useShapes/pie/index.js +28 -0
- package/build/plugins/d3/renderer/hooks/useShapes/pie/prepare-data.js +9 -3
- package/build/plugins/d3/renderer/hooks/useShapes/pie/types.d.ts +5 -0
- package/build/plugins/d3/renderer/hooks/useShapes/scatter/index.js +1 -1
- package/build/plugins/d3/renderer/hooks/useShapes/utils.d.ts +2 -0
- package/build/plugins/d3/renderer/hooks/useShapes/utils.js +17 -0
- package/build/plugins/d3/renderer/validation/index.js +2 -8
- package/build/plugins/highcharts/renderer/helpers/config/config.js +0 -3
- package/build/types/widget-data/area.d.ts +2 -1
- package/build/types/widget-data/bar-x.d.ts +2 -1
- package/build/types/widget-data/bar-y.d.ts +2 -1
- package/build/types/widget-data/halo.d.ts +9 -0
- package/build/types/widget-data/halo.js +1 -0
- package/build/types/widget-data/index.d.ts +1 -0
- package/build/types/widget-data/index.js +1 -0
- package/build/types/widget-data/line.d.ts +6 -1
- package/build/types/widget-data/marker.d.ts +0 -8
- package/build/types/widget-data/pie.d.ts +2 -1
- package/build/types/widget-data/scatter.d.ts +2 -1
- package/build/types/widget-data/series.d.ts +19 -4
- package/package.json +6 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BarXSeries, BarXSeriesData, BaseTextStyle, ChartKitWidgetLegend, PieSeries, PieSeriesData, RectLegendSymbolOptions, ScatterSeries, ScatterSeriesData, BarYSeries, BarYSeriesData, LineSeries, LineSeriesData, ConnectorShape, ConnectorCurve, PathLegendSymbolOptions, AreaSeries, AreaSeriesData } from '../../../../../types';
|
|
2
2
|
import type { SeriesOptionsDefaults } from '../../constants';
|
|
3
|
+
import { DashStyle, LineCap } from '../../../../../constants';
|
|
3
4
|
export type RectLegendSymbol = {
|
|
4
5
|
shape: 'rect';
|
|
5
6
|
} & Required<RectLegendSymbolOptions>;
|
|
@@ -22,6 +23,7 @@ export type LegendItem = {
|
|
|
22
23
|
symbol: PreparedLegendSymbol;
|
|
23
24
|
textWidth: number;
|
|
24
25
|
visible?: boolean;
|
|
26
|
+
dashStyle?: DashStyle;
|
|
25
27
|
};
|
|
26
28
|
export type LegendConfig = {
|
|
27
29
|
offset: {
|
|
@@ -33,6 +35,11 @@ export type LegendConfig = {
|
|
|
33
35
|
maxPage: number;
|
|
34
36
|
};
|
|
35
37
|
};
|
|
38
|
+
export type PreparedHaloOptions = {
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
opacity: number;
|
|
41
|
+
size: number;
|
|
42
|
+
};
|
|
36
43
|
type BasePreparedSeries = {
|
|
37
44
|
color: string;
|
|
38
45
|
name: string;
|
|
@@ -93,6 +100,11 @@ export type PreparedPieSeries = {
|
|
|
93
100
|
distance: number;
|
|
94
101
|
connectorCurve: ConnectorCurve;
|
|
95
102
|
};
|
|
103
|
+
states: {
|
|
104
|
+
hover: {
|
|
105
|
+
halo: PreparedHaloOptions;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
96
108
|
} & BasePreparedSeries;
|
|
97
109
|
export type PreparedLineSeries = {
|
|
98
110
|
type: LineSeries['type'];
|
|
@@ -118,14 +130,12 @@ export type PreparedLineSeries = {
|
|
|
118
130
|
radius: number;
|
|
119
131
|
borderWidth: number;
|
|
120
132
|
borderColor: string;
|
|
121
|
-
halo:
|
|
122
|
-
enabled: boolean;
|
|
123
|
-
opacity: number;
|
|
124
|
-
radius: number;
|
|
125
|
-
};
|
|
133
|
+
halo: PreparedHaloOptions;
|
|
126
134
|
};
|
|
127
135
|
};
|
|
128
136
|
};
|
|
137
|
+
dashStyle: DashStyle;
|
|
138
|
+
linecap: LineCap;
|
|
129
139
|
} & BasePreparedSeries;
|
|
130
140
|
export type PreparedAreaSeries = {
|
|
131
141
|
type: AreaSeries['type'];
|
|
@@ -154,11 +164,7 @@ export type PreparedAreaSeries = {
|
|
|
154
164
|
radius: number;
|
|
155
165
|
borderWidth: number;
|
|
156
166
|
borderColor: string;
|
|
157
|
-
halo:
|
|
158
|
-
enabled: boolean;
|
|
159
|
-
opacity: number;
|
|
160
|
-
radius: number;
|
|
161
|
-
};
|
|
167
|
+
halo: PreparedHaloOptions;
|
|
162
168
|
};
|
|
163
169
|
};
|
|
164
170
|
};
|
|
@@ -1,43 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { color, line as lineGenerator, area as areaGenerator, select
|
|
2
|
+
import { color, line as lineGenerator, area as areaGenerator, select } from 'd3';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
4
|
import { block } from '../../../../../../utils/cn';
|
|
5
5
|
import { filterOverlappingLabels } from '../../../utils';
|
|
6
6
|
import { setActiveState } from '../utils';
|
|
7
|
+
import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
|
|
7
8
|
const b = block('d3-area');
|
|
8
|
-
function setMarker(selection, state) {
|
|
9
|
-
selection
|
|
10
|
-
.attr('d', (d) => {
|
|
11
|
-
const radius = d.point.series.marker.states[state].radius +
|
|
12
|
-
d.point.series.marker.states[state].borderWidth;
|
|
13
|
-
return getMarkerSymbol(d.point.series.marker.states.normal.symbol, radius);
|
|
14
|
-
})
|
|
15
|
-
.attr('stroke-width', (d) => d.point.series.marker.states[state].borderWidth)
|
|
16
|
-
.attr('stroke', (d) => d.point.series.marker.states[state].borderColor);
|
|
17
|
-
}
|
|
18
|
-
function getMarkerSymbol(type, radius) {
|
|
19
|
-
switch (type) {
|
|
20
|
-
case 'square': {
|
|
21
|
-
const size = Math.pow(radius, 2) * Math.PI;
|
|
22
|
-
return symbol(symbolSquare, size)();
|
|
23
|
-
}
|
|
24
|
-
case 'circle':
|
|
25
|
-
default: {
|
|
26
|
-
const size = Math.pow(radius, 2) * Math.PI;
|
|
27
|
-
return symbol(symbolCircle, size)();
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
const getMarkerVisibility = (d) => {
|
|
32
|
-
const markerStates = d.point.series.marker.states;
|
|
33
|
-
const enabled = (markerStates.hover.enabled && d.hovered) || markerStates.normal.enabled;
|
|
34
|
-
return enabled ? '' : 'hidden';
|
|
35
|
-
};
|
|
36
|
-
const getMarkerHaloVisibility = (d) => {
|
|
37
|
-
const markerStates = d.point.series.marker.states;
|
|
38
|
-
const enabled = markerStates.hover.halo.enabled && d.hovered;
|
|
39
|
-
return enabled ? '' : 'hidden';
|
|
40
|
-
};
|
|
41
9
|
export const AreaSeriesShapes = (args) => {
|
|
42
10
|
const { dispatcher, preparedData, seriesOptions } = args;
|
|
43
11
|
const ref = React.useRef(null);
|
|
@@ -100,28 +68,7 @@ export const AreaSeriesShapes = (args) => {
|
|
|
100
68
|
.selectAll('marker')
|
|
101
69
|
.data(markers)
|
|
102
70
|
.join('g')
|
|
103
|
-
.
|
|
104
|
-
.attr('visibility', getMarkerVisibility)
|
|
105
|
-
.attr('transform', (d) => {
|
|
106
|
-
return `translate(${d.point.x},${d.point.y})`;
|
|
107
|
-
});
|
|
108
|
-
markerSelection
|
|
109
|
-
.append('path')
|
|
110
|
-
.attr('class', b('marker-halo'))
|
|
111
|
-
.attr('d', (d) => {
|
|
112
|
-
const type = d.point.series.marker.states.normal.symbol;
|
|
113
|
-
const radius = d.point.series.marker.states.hover.halo.radius;
|
|
114
|
-
return getMarkerSymbol(type, radius);
|
|
115
|
-
})
|
|
116
|
-
.attr('fill', (d) => d.point.series.color)
|
|
117
|
-
.attr('opacity', (d) => d.point.series.marker.states.hover.halo.opacity)
|
|
118
|
-
.attr('z-index', -1)
|
|
119
|
-
.attr('visibility', getMarkerHaloVisibility);
|
|
120
|
-
markerSelection
|
|
121
|
-
.append('path')
|
|
122
|
-
.attr('class', b('marker-symbol'))
|
|
123
|
-
.call(setMarker, 'normal')
|
|
124
|
-
.attr('fill', (d) => d.point.series.color);
|
|
71
|
+
.call(renderMarker);
|
|
125
72
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
126
73
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
127
74
|
dispatcher.on('hover-shape.area', (data) => {
|
|
@@ -165,12 +112,8 @@ export const AreaSeriesShapes = (args) => {
|
|
|
165
112
|
if (d.hovered !== hovered) {
|
|
166
113
|
d.hovered = hovered;
|
|
167
114
|
elementSelection.attr('visibility', getMarkerVisibility(d));
|
|
168
|
-
elementSelection
|
|
169
|
-
|
|
170
|
-
.attr('visibility', getMarkerHaloVisibility);
|
|
171
|
-
elementSelection
|
|
172
|
-
.select(`.${b('marker-symbol')}`)
|
|
173
|
-
.call(setMarker, hovered ? 'hover' : 'normal');
|
|
115
|
+
selectMarkerHalo(elementSelection).attr('visibility', getMarkerHaloVisibility);
|
|
116
|
+
selectMarkerSymbol(elementSelection).call(setMarker, hovered ? 'hover' : 'normal');
|
|
174
117
|
}
|
|
175
118
|
if (d.point.series.marker.states.normal.enabled) {
|
|
176
119
|
const isActive = Boolean(!inactiveEnabled ||
|
|
@@ -1,43 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { color, line as lineGenerator, select
|
|
2
|
+
import { color, line as lineGenerator, select } from 'd3';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
4
|
import { block } from '../../../../../../utils/cn';
|
|
5
5
|
import { filterOverlappingLabels } from '../../../utils';
|
|
6
|
-
import { setActiveState } from '../utils';
|
|
6
|
+
import { getLineDashArray, setActiveState } from '../utils';
|
|
7
|
+
import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
|
|
7
8
|
const b = block('d3-line');
|
|
8
|
-
function setMarker(selection, state) {
|
|
9
|
-
selection
|
|
10
|
-
.attr('d', (d) => {
|
|
11
|
-
const radius = d.point.series.marker.states[state].radius +
|
|
12
|
-
d.point.series.marker.states[state].borderWidth;
|
|
13
|
-
return getMarkerSymbol(d.point.series.marker.states.normal.symbol, radius);
|
|
14
|
-
})
|
|
15
|
-
.attr('stroke-width', (d) => d.point.series.marker.states[state].borderWidth)
|
|
16
|
-
.attr('stroke', (d) => d.point.series.marker.states[state].borderColor);
|
|
17
|
-
}
|
|
18
|
-
function getMarkerSymbol(type, radius) {
|
|
19
|
-
switch (type) {
|
|
20
|
-
case 'square': {
|
|
21
|
-
const size = Math.pow(radius, 2) * Math.PI;
|
|
22
|
-
return symbol(symbolSquare, size)();
|
|
23
|
-
}
|
|
24
|
-
case 'circle':
|
|
25
|
-
default: {
|
|
26
|
-
const size = Math.pow(radius, 2) * Math.PI;
|
|
27
|
-
return symbol(symbolCircle, size)();
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
const getMarkerVisibility = (d) => {
|
|
32
|
-
const markerStates = d.point.series.marker.states;
|
|
33
|
-
const enabled = (markerStates.hover.enabled && d.hovered) || markerStates.normal.enabled;
|
|
34
|
-
return enabled ? '' : 'hidden';
|
|
35
|
-
};
|
|
36
|
-
const getMarkerHaloVisibility = (d) => {
|
|
37
|
-
const markerStates = d.point.series.marker.states;
|
|
38
|
-
const enabled = markerStates.hover.halo.enabled && d.hovered;
|
|
39
|
-
return enabled ? '' : 'hidden';
|
|
40
|
-
};
|
|
41
9
|
export const LineSeriesShapes = (args) => {
|
|
42
10
|
const { dispatcher, preparedData, seriesOptions } = args;
|
|
43
11
|
const ref = React.useRef(null);
|
|
@@ -61,8 +29,9 @@ export const LineSeriesShapes = (args) => {
|
|
|
61
29
|
.attr('fill', 'none')
|
|
62
30
|
.attr('stroke', (d) => d.color)
|
|
63
31
|
.attr('stroke-width', (d) => d.width)
|
|
64
|
-
.attr('stroke-linejoin',
|
|
65
|
-
.attr('stroke-linecap',
|
|
32
|
+
.attr('stroke-linejoin', (d) => d.linecap)
|
|
33
|
+
.attr('stroke-linecap', (d) => d.linecap)
|
|
34
|
+
.attr('stroke-dasharray', (d) => getLineDashArray(d.dashStyle, d.width));
|
|
66
35
|
let dataLabels = preparedData.reduce((acc, d) => {
|
|
67
36
|
return acc.concat(d.labels);
|
|
68
37
|
}, []);
|
|
@@ -86,28 +55,7 @@ export const LineSeriesShapes = (args) => {
|
|
|
86
55
|
.selectAll('marker')
|
|
87
56
|
.data(markers)
|
|
88
57
|
.join('g')
|
|
89
|
-
.
|
|
90
|
-
.attr('visibility', getMarkerVisibility)
|
|
91
|
-
.attr('transform', (d) => {
|
|
92
|
-
return `translate(${d.point.x},${d.point.y})`;
|
|
93
|
-
});
|
|
94
|
-
markerSelection
|
|
95
|
-
.append('path')
|
|
96
|
-
.attr('class', b('marker-halo'))
|
|
97
|
-
.attr('d', (d) => {
|
|
98
|
-
const type = d.point.series.marker.states.normal.symbol;
|
|
99
|
-
const radius = d.point.series.marker.states.hover.halo.radius;
|
|
100
|
-
return getMarkerSymbol(type, radius);
|
|
101
|
-
})
|
|
102
|
-
.attr('fill', (d) => d.point.series.color)
|
|
103
|
-
.attr('opacity', (d) => d.point.series.marker.states.hover.halo.opacity)
|
|
104
|
-
.attr('z-index', -1)
|
|
105
|
-
.attr('visibility', getMarkerHaloVisibility);
|
|
106
|
-
markerSelection
|
|
107
|
-
.append('path')
|
|
108
|
-
.attr('class', b('marker-symbol'))
|
|
109
|
-
.call(setMarker, 'normal')
|
|
110
|
-
.attr('fill', (d) => d.point.series.color);
|
|
58
|
+
.call(renderMarker);
|
|
111
59
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
112
60
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
113
61
|
dispatcher.on('hover-shape.line', (data) => {
|
|
@@ -150,12 +98,8 @@ export const LineSeriesShapes = (args) => {
|
|
|
150
98
|
if (d.hovered !== hovered) {
|
|
151
99
|
d.hovered = hovered;
|
|
152
100
|
elementSelection.attr('visibility', getMarkerVisibility(d));
|
|
153
|
-
elementSelection
|
|
154
|
-
|
|
155
|
-
.attr('visibility', getMarkerHaloVisibility);
|
|
156
|
-
elementSelection
|
|
157
|
-
.select(`.${b('marker-symbol')}`)
|
|
158
|
-
.call(setMarker, hovered ? 'hover' : 'normal');
|
|
101
|
+
selectMarkerHalo(elementSelection).attr('visibility', getMarkerHaloVisibility);
|
|
102
|
+
selectMarkerSymbol(elementSelection).call(setMarker, hovered ? 'hover' : 'normal');
|
|
159
103
|
}
|
|
160
104
|
if (d.point.series.marker.states.normal.enabled) {
|
|
161
105
|
const isActive = Boolean(!inactiveEnabled ||
|
|
@@ -51,7 +51,7 @@ export const prepareLineData = (args) => {
|
|
|
51
51
|
hovered: false,
|
|
52
52
|
}));
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
const result = {
|
|
55
55
|
points,
|
|
56
56
|
markers,
|
|
57
57
|
labels,
|
|
@@ -61,7 +61,10 @@ export const prepareLineData = (args) => {
|
|
|
61
61
|
hovered: false,
|
|
62
62
|
active: true,
|
|
63
63
|
id: s.id,
|
|
64
|
-
|
|
64
|
+
dashStyle: s.dashStyle,
|
|
65
|
+
linecap: s.linecap,
|
|
66
|
+
};
|
|
67
|
+
acc.push(result);
|
|
65
68
|
return acc;
|
|
66
69
|
}, []);
|
|
67
70
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PreparedLineSeries } from '../../useSeries/types';
|
|
2
2
|
import { LineSeriesData } from '../../../../../../types';
|
|
3
3
|
import { LabelData } from '../../../types';
|
|
4
|
+
import { DashStyle, LineCap } from '../../../../../../constants';
|
|
4
5
|
export type PointData = {
|
|
5
6
|
x: number;
|
|
6
7
|
y: number;
|
|
@@ -22,4 +23,6 @@ export type PreparedLineData = {
|
|
|
22
23
|
hovered: boolean;
|
|
23
24
|
active: boolean;
|
|
24
25
|
labels: LabelData[];
|
|
26
|
+
dashStyle: DashStyle;
|
|
27
|
+
linecap: LineCap;
|
|
25
28
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseType, Selection } from 'd3';
|
|
2
|
+
import { MarkerData as LineMarkerData } from './line/types';
|
|
3
|
+
import { MarkerData as AreaMarkerData } from './area/types';
|
|
4
|
+
type MarkerData = LineMarkerData | AreaMarkerData;
|
|
5
|
+
export declare function renderMarker<T extends MarkerData>(selection: Selection<BaseType | SVGGElement, T, SVGGElement, unknown>): Selection<SVGGElement | BaseType, T, SVGGElement, unknown>;
|
|
6
|
+
export declare function getMarkerVisibility(d: MarkerData): "" | "hidden";
|
|
7
|
+
export declare function getMarkerHaloVisibility(d: MarkerData): "" | "hidden";
|
|
8
|
+
export declare function setMarker<T extends BaseType, D extends MarkerData>(selection: Selection<T, D, BaseType | null, unknown>, state: 'normal' | 'hover'): void;
|
|
9
|
+
export declare function getMarkerSymbol(type: string, radius: number): string | null;
|
|
10
|
+
export declare function selectMarkerHalo<T>(parentSelection: Selection<BaseType, T, null, undefined>): Selection<BaseType, T, null, undefined>;
|
|
11
|
+
export declare function selectMarkerSymbol<T>(parentSelection: Selection<BaseType, T, null, undefined>): Selection<BaseType, T, null, undefined>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { symbol, symbolCircle, symbolSquare } from 'd3';
|
|
2
|
+
import { block } from '../../../../../utils/cn';
|
|
3
|
+
const b = block('d3-marker');
|
|
4
|
+
const haloClassName = b('halo');
|
|
5
|
+
const symbolClassName = b('symbol');
|
|
6
|
+
export function renderMarker(selection) {
|
|
7
|
+
const markerSelection = selection
|
|
8
|
+
.attr('class', b('wrapper'))
|
|
9
|
+
.attr('visibility', getMarkerVisibility)
|
|
10
|
+
.attr('transform', (d) => {
|
|
11
|
+
return `translate(${d.point.x},${d.point.y})`;
|
|
12
|
+
});
|
|
13
|
+
markerSelection
|
|
14
|
+
.append('path')
|
|
15
|
+
.attr('class', haloClassName)
|
|
16
|
+
.attr('d', (d) => {
|
|
17
|
+
const type = d.point.series.marker.states.normal.symbol;
|
|
18
|
+
const radius = d.point.series.marker.states.hover.halo.size;
|
|
19
|
+
return getMarkerSymbol(type, radius);
|
|
20
|
+
})
|
|
21
|
+
.attr('fill', (d) => d.point.series.color)
|
|
22
|
+
.attr('opacity', (d) => d.point.series.marker.states.hover.halo.opacity)
|
|
23
|
+
.attr('z-index', -1)
|
|
24
|
+
.attr('visibility', getMarkerHaloVisibility);
|
|
25
|
+
markerSelection
|
|
26
|
+
.append('path')
|
|
27
|
+
.attr('class', symbolClassName)
|
|
28
|
+
.call(setMarker, 'normal')
|
|
29
|
+
.attr('fill', (d) => d.point.series.color);
|
|
30
|
+
return markerSelection;
|
|
31
|
+
}
|
|
32
|
+
export function getMarkerVisibility(d) {
|
|
33
|
+
const markerStates = d.point.series.marker.states;
|
|
34
|
+
const enabled = (markerStates.hover.enabled && d.hovered) || markerStates.normal.enabled;
|
|
35
|
+
return enabled ? '' : 'hidden';
|
|
36
|
+
}
|
|
37
|
+
export function getMarkerHaloVisibility(d) {
|
|
38
|
+
const markerStates = d.point.series.marker.states;
|
|
39
|
+
const enabled = markerStates.hover.halo.enabled && d.hovered;
|
|
40
|
+
return enabled ? '' : 'hidden';
|
|
41
|
+
}
|
|
42
|
+
export function setMarker(selection, state) {
|
|
43
|
+
selection
|
|
44
|
+
.attr('d', (d) => {
|
|
45
|
+
const radius = d.point.series.marker.states[state].radius +
|
|
46
|
+
d.point.series.marker.states[state].borderWidth;
|
|
47
|
+
return getMarkerSymbol(d.point.series.marker.states.normal.symbol, radius);
|
|
48
|
+
})
|
|
49
|
+
.attr('stroke-width', (d) => d.point.series.marker.states[state].borderWidth)
|
|
50
|
+
.attr('stroke', (d) => d.point.series.marker.states[state].borderColor);
|
|
51
|
+
}
|
|
52
|
+
export function getMarkerSymbol(type, radius) {
|
|
53
|
+
switch (type) {
|
|
54
|
+
case 'square': {
|
|
55
|
+
const size = Math.pow(radius, 2) * Math.PI;
|
|
56
|
+
return symbol(symbolSquare, size)();
|
|
57
|
+
}
|
|
58
|
+
case 'circle':
|
|
59
|
+
default: {
|
|
60
|
+
const size = Math.pow(radius, 2) * Math.PI;
|
|
61
|
+
return symbol(symbolCircle, size)();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function selectMarkerHalo(parentSelection) {
|
|
66
|
+
return parentSelection.select(`.${haloClassName}`);
|
|
67
|
+
}
|
|
68
|
+
export function selectMarkerSymbol(parentSelection) {
|
|
69
|
+
return parentSelection.select(`.${symbolClassName}`);
|
|
70
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Dispatch } from 'd3';
|
|
2
|
+
import type { Dispatch, PieArcDatum } from 'd3';
|
|
3
3
|
import { PreparedSeriesOptions } from '../../useSeries/types';
|
|
4
|
-
import { PreparedPieData } from './types';
|
|
4
|
+
import { PreparedPieData, SegmentData } from './types';
|
|
5
5
|
type PreparePieSeriesArgs = {
|
|
6
6
|
dispatcher: Dispatch<object>;
|
|
7
7
|
preparedData: PreparedPieData[];
|
|
8
8
|
seriesOptions: PreparedSeriesOptions;
|
|
9
9
|
svgContainer: SVGSVGElement | null;
|
|
10
10
|
};
|
|
11
|
+
export declare function getHaloVisibility(d: PieArcDatum<SegmentData>): "" | "hidden";
|
|
11
12
|
export declare function PieSeriesShapes(args: PreparePieSeriesArgs): React.JSX.Element;
|
|
12
13
|
export {};
|
|
@@ -7,6 +7,10 @@ import { line as lineGenerator } from 'd3-shape';
|
|
|
7
7
|
import { setEllipsisForOverflowTexts } from '../../../utils';
|
|
8
8
|
import { getCurveFactory } from './utils';
|
|
9
9
|
const b = block('d3-pie');
|
|
10
|
+
export function getHaloVisibility(d) {
|
|
11
|
+
const enabled = d.data.pie.halo.enabled && d.data.hovered;
|
|
12
|
+
return enabled ? '' : 'hidden';
|
|
13
|
+
}
|
|
10
14
|
export function PieSeriesShapes(args) {
|
|
11
15
|
const { dispatcher, preparedData, seriesOptions, svgContainer } = args;
|
|
12
16
|
const ref = React.useRef(null);
|
|
@@ -30,6 +34,27 @@ export function PieSeriesShapes(args) {
|
|
|
30
34
|
})
|
|
31
35
|
.style('stroke', (pieData) => pieData.borderColor)
|
|
32
36
|
.style('stroke-width', (pieData) => pieData.borderWidth);
|
|
37
|
+
shapesSelection
|
|
38
|
+
.selectAll('halo')
|
|
39
|
+
.data((pieData) => {
|
|
40
|
+
if (pieData.halo.enabled) {
|
|
41
|
+
return pieData.segments;
|
|
42
|
+
}
|
|
43
|
+
return [];
|
|
44
|
+
})
|
|
45
|
+
.join('path')
|
|
46
|
+
.attr('d', (d) => {
|
|
47
|
+
const arcGenerator = arc()
|
|
48
|
+
.innerRadius(d.data.pie.innerRadius)
|
|
49
|
+
.outerRadius(d.data.pie.radius + d.data.pie.halo.size)
|
|
50
|
+
.cornerRadius(d.data.pie.borderRadius);
|
|
51
|
+
return arcGenerator(d);
|
|
52
|
+
})
|
|
53
|
+
.attr('class', b('halo'))
|
|
54
|
+
.attr('fill', (d) => d.data.color)
|
|
55
|
+
.attr('opacity', (d) => d.data.pie.halo.opacity)
|
|
56
|
+
.attr('z-index', -1)
|
|
57
|
+
.attr('visibility', getHaloVisibility);
|
|
33
58
|
shapesSelection
|
|
34
59
|
.selectAll(segmentSelector)
|
|
35
60
|
.data((pieData) => pieData.segments)
|
|
@@ -108,6 +133,7 @@ export function PieSeriesShapes(args) {
|
|
|
108
133
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
109
134
|
shapesSelection.datum((_d, index, list) => {
|
|
110
135
|
const pieSelection = select(list[index]);
|
|
136
|
+
const haloSelection = pieSelection.selectAll(`.${b('halo')}`);
|
|
111
137
|
pieSelection
|
|
112
138
|
.selectAll(segmentSelector)
|
|
113
139
|
.datum((d, i, elements) => {
|
|
@@ -122,6 +148,8 @@ export function PieSeriesShapes(args) {
|
|
|
122
148
|
}
|
|
123
149
|
return initialColor;
|
|
124
150
|
});
|
|
151
|
+
const currentSegmentHalo = haloSelection.nodes()[i];
|
|
152
|
+
select(currentSegmentHalo).attr('visibility', getHaloVisibility);
|
|
125
153
|
}
|
|
126
154
|
setActiveState({
|
|
127
155
|
element: elements[i],
|
|
@@ -15,12 +15,13 @@ const getCenter = (boundsWidth, boundsHeight, center) => {
|
|
|
15
15
|
return [resultX, resultY];
|
|
16
16
|
};
|
|
17
17
|
export function preparePieData(args) {
|
|
18
|
-
const { series:
|
|
18
|
+
const { series: preparedSeries, boundsWidth, boundsHeight } = args;
|
|
19
19
|
const maxRadius = Math.min(boundsWidth, boundsHeight) / 2;
|
|
20
|
-
const groupedPieSeries = group(
|
|
20
|
+
const groupedPieSeries = group(preparedSeries, (pieSeries) => pieSeries.stackId);
|
|
21
21
|
return Array.from(groupedPieSeries).map(([stackId, items]) => {
|
|
22
22
|
var _a, _b, _c;
|
|
23
|
-
const
|
|
23
|
+
const series = items[0];
|
|
24
|
+
const { center, borderWidth, borderColor, borderRadius, radius: seriesRadius, innerRadius: seriesInnerRadius, dataLabels, } = series;
|
|
24
25
|
const radius = (_a = calculateNumericProperty({ value: seriesRadius, base: maxRadius })) !== null && _a !== void 0 ? _a : maxRadius;
|
|
25
26
|
const data = {
|
|
26
27
|
id: stackId,
|
|
@@ -34,6 +35,11 @@ export function preparePieData(args) {
|
|
|
34
35
|
borderRadius,
|
|
35
36
|
series: items[0],
|
|
36
37
|
connectorCurve: dataLabels.connectorCurve,
|
|
38
|
+
halo: {
|
|
39
|
+
enabled: series.states.hover.halo.enabled,
|
|
40
|
+
opacity: series.states.hover.halo.opacity,
|
|
41
|
+
size: series.states.hover.halo.size,
|
|
42
|
+
},
|
|
37
43
|
};
|
|
38
44
|
const segments = items.map((item) => {
|
|
39
45
|
return {
|
|
@@ -22,7 +22,7 @@ export function ScatterSeriesShape(props) {
|
|
|
22
22
|
const hoverOptions = get(seriesOptions, 'scatter.states.hover');
|
|
23
23
|
const inactiveOptions = get(seriesOptions, 'scatter.states.inactive');
|
|
24
24
|
const selection = svgElement
|
|
25
|
-
.selectAll(
|
|
25
|
+
.selectAll('circle')
|
|
26
26
|
.data(preparedData, shapeKey)
|
|
27
27
|
.join((enter) => enter.append('circle').attr('class', b('point')), (update) => update, (exit) => exit.remove())
|
|
28
28
|
.attr('fill', (d) => d.data.color || d.series.color || '')
|
|
@@ -2,6 +2,7 @@ import type { BaseType } from 'd3';
|
|
|
2
2
|
import type { BasicInactiveState } from '../../../../../types';
|
|
3
3
|
import type { ChartScale } from '../useAxisScales';
|
|
4
4
|
import type { PreparedAxis } from '../useChartOptions/types';
|
|
5
|
+
import { DashStyle } from '../../../../../constants';
|
|
5
6
|
export declare function getXValue(args: {
|
|
6
7
|
point: {
|
|
7
8
|
x?: number | string;
|
|
@@ -25,3 +26,4 @@ export declare function setActiveState<T extends {
|
|
|
25
26
|
state: BasicInactiveState | undefined;
|
|
26
27
|
active: boolean;
|
|
27
28
|
}): T;
|
|
29
|
+
export declare const getLineDashArray: (dashStyle: DashStyle, strokeWidth?: number) => string;
|
|
@@ -34,3 +34,20 @@ export function setActiveState(args) {
|
|
|
34
34
|
}
|
|
35
35
|
return datum;
|
|
36
36
|
}
|
|
37
|
+
export const getLineDashArray = (dashStyle, strokeWidth = 2) => {
|
|
38
|
+
const value = dashStyle.toLowerCase();
|
|
39
|
+
const arrayValue = value
|
|
40
|
+
.replace('shortdashdotdot', '3,1,1,1,1,1,')
|
|
41
|
+
.replace('shortdashdot', '3,1,1,1')
|
|
42
|
+
.replace('shortdot', '1,1,')
|
|
43
|
+
.replace('shortdash', '3,1,')
|
|
44
|
+
.replace('longdash', '8,3,')
|
|
45
|
+
.replace(/dot/g, '1,3,')
|
|
46
|
+
.replace('dash', '4,3,')
|
|
47
|
+
.replace(/,$/, '')
|
|
48
|
+
.split(',')
|
|
49
|
+
.map((part) => {
|
|
50
|
+
return `${parseInt(part, 10) * strokeWidth}`;
|
|
51
|
+
});
|
|
52
|
+
return arrayValue.join(',').replace(/NaN/g, 'none');
|
|
53
|
+
};
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import isEmpty from 'lodash/isEmpty';
|
|
3
|
+
import { SeriesType } from '../../../../constants';
|
|
3
4
|
import { ChartKitError, CHARTKIT_ERROR_CODE } from '../../../../libs';
|
|
4
5
|
import { i18n } from '../../../../i18n';
|
|
5
6
|
import { DEFAULT_AXIS_TYPE } from '../constants';
|
|
6
|
-
const AVAILABLE_SERIES_TYPES =
|
|
7
|
-
'area',
|
|
8
|
-
'bar-x',
|
|
9
|
-
'bar-y',
|
|
10
|
-
'line',
|
|
11
|
-
'pie',
|
|
12
|
-
'scatter',
|
|
13
|
-
];
|
|
7
|
+
const AVAILABLE_SERIES_TYPES = Object.values(SeriesType);
|
|
14
8
|
const validateXYSeries = (args) => {
|
|
15
9
|
const { series, xAxis, yAxis } = args;
|
|
16
10
|
const xType = get(xAxis, 'type', DEFAULT_AXIS_TYPE);
|
|
@@ -1155,9 +1155,6 @@ export function prepareConfig(data, options, isMobile, holidays) {
|
|
|
1155
1155
|
var _a;
|
|
1156
1156
|
if (chartType === 'column' || chartType === 'bar') {
|
|
1157
1157
|
this.series.forEach((seriesItem) => {
|
|
1158
|
-
if (!seriesItem.legendItem) {
|
|
1159
|
-
return;
|
|
1160
|
-
}
|
|
1161
1158
|
const color = seriesItem.color;
|
|
1162
1159
|
// The update method updates all series, and therefore,
|
|
1163
1160
|
// after working out the handleLegendItemMouseOverAndOut,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SeriesType } from '../../constants';
|
|
1
2
|
import type { BaseSeries, BaseSeriesData } from './base';
|
|
2
3
|
import type { ChartKitWidgetLegend, RectLegendSymbolOptions } from './legend';
|
|
3
4
|
import type { PointMarkerOptions } from './marker';
|
|
@@ -24,7 +25,7 @@ export type AreaMarkerOptions = PointMarkerOptions & {
|
|
|
24
25
|
symbol?: AreaMarkerSymbol;
|
|
25
26
|
};
|
|
26
27
|
export type AreaSeries<T = any> = BaseSeries & {
|
|
27
|
-
type:
|
|
28
|
+
type: typeof SeriesType.Area;
|
|
28
29
|
data: AreaSeriesData<T>[];
|
|
29
30
|
/** The name of the series (used in legend, tooltip etc) */
|
|
30
31
|
name: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SeriesType } from '../../constants';
|
|
1
2
|
import type { BaseSeries, BaseSeriesData } from './base';
|
|
2
3
|
import type { ChartKitWidgetSeriesOptions } from './series';
|
|
3
4
|
import { ChartKitWidgetLegend, RectLegendSymbolOptions } from './legend';
|
|
@@ -26,7 +27,7 @@ export type BarXSeriesData<T = any> = BaseSeriesData<T> & {
|
|
|
26
27
|
label?: string | number;
|
|
27
28
|
};
|
|
28
29
|
export type BarXSeries<T = any> = BaseSeries & {
|
|
29
|
-
type:
|
|
30
|
+
type: typeof SeriesType.BarX;
|
|
30
31
|
data: BarXSeriesData<T>[];
|
|
31
32
|
/** The name of the series (used in legend, tooltip etc) */
|
|
32
33
|
name: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SeriesType } from '../../constants';
|
|
1
2
|
import type { BaseSeries, BaseSeriesData } from './base';
|
|
2
3
|
import type { ChartKitWidgetSeriesOptions } from './series';
|
|
3
4
|
import { ChartKitWidgetLegend, RectLegendSymbolOptions } from './legend';
|
|
@@ -20,7 +21,7 @@ export type BarYSeriesData<T = any> = BaseSeriesData<T> & {
|
|
|
20
21
|
label?: string | number;
|
|
21
22
|
};
|
|
22
23
|
export type BarYSeries<T = any> = BaseSeries & {
|
|
23
|
-
type:
|
|
24
|
+
type: typeof SeriesType.BarY;
|
|
24
25
|
data: BarYSeriesData<T>[];
|
|
25
26
|
/** The name of the series (used in legend, tooltip etc) */
|
|
26
27
|
name: string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** The halo appearing around the hovered part of series(point in line-type series or slice in pie charts) */
|
|
2
|
+
export type Halo = {
|
|
3
|
+
/** Enable or disable the halo */
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
/** The opacity of halo */
|
|
6
|
+
opacity?: number;
|
|
7
|
+
/** The pixel size of the halo. Radius for point markers or width of the outside slice in pie charts. */
|
|
8
|
+
size?: number;
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|