@gravity-ui/charts 1.28.2 → 1.30.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/README.md +19 -3
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +3 -1
- package/dist/cjs/constants/defaults/legend.d.ts +1 -0
- package/dist/cjs/constants/defaults/legend.js +1 -0
- package/dist/cjs/hooks/useAxisScales/index.js +32 -8
- package/dist/cjs/hooks/useRangeSlider/index.js +1 -0
- package/dist/cjs/hooks/useSeries/prepare-legend.js +17 -3
- package/dist/cjs/hooks/useSeries/prepare-line.js +1 -1
- package/dist/cjs/hooks/useSeries/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/area/index.js +1 -1
- package/dist/cjs/hooks/useShapes/bar-x/index.js +1 -1
- package/dist/cjs/hooks/useShapes/bar-y/index.js +1 -1
- package/dist/cjs/hooks/useShapes/funnel/index.js +1 -1
- package/dist/cjs/hooks/useShapes/heatmap/index.js +1 -1
- package/dist/cjs/hooks/useShapes/index.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/index.js +3 -1
- package/dist/cjs/hooks/useShapes/line/index.js +3 -3
- package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +6 -6
- package/dist/cjs/hooks/useShapes/line/types.d.ts +4 -6
- package/dist/cjs/hooks/useShapes/radar/index.js +1 -1
- package/dist/cjs/hooks/useShapes/sankey/index.js +1 -1
- package/dist/cjs/hooks/useShapes/waterfall/index.js +1 -1
- package/dist/cjs/types/chart/base.d.ts +6 -0
- package/dist/cjs/types/chart/legend.d.ts +7 -0
- package/dist/cjs/types/chart/line.d.ts +19 -13
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +3 -1
- package/dist/esm/constants/defaults/legend.d.ts +1 -0
- package/dist/esm/constants/defaults/legend.js +1 -0
- package/dist/esm/hooks/useAxisScales/index.js +32 -8
- package/dist/esm/hooks/useRangeSlider/index.js +1 -0
- package/dist/esm/hooks/useSeries/prepare-legend.js +17 -3
- package/dist/esm/hooks/useSeries/prepare-line.js +1 -1
- package/dist/esm/hooks/useSeries/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/area/index.js +1 -1
- package/dist/esm/hooks/useShapes/bar-x/index.js +1 -1
- package/dist/esm/hooks/useShapes/bar-y/index.js +1 -1
- package/dist/esm/hooks/useShapes/funnel/index.js +1 -1
- package/dist/esm/hooks/useShapes/heatmap/index.js +1 -1
- package/dist/esm/hooks/useShapes/index.d.ts +1 -0
- package/dist/esm/hooks/useShapes/index.js +3 -1
- package/dist/esm/hooks/useShapes/line/index.js +3 -3
- package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +1 -0
- package/dist/esm/hooks/useShapes/line/prepare-data.js +6 -6
- package/dist/esm/hooks/useShapes/line/types.d.ts +4 -6
- package/dist/esm/hooks/useShapes/radar/index.js +1 -1
- package/dist/esm/hooks/useShapes/sankey/index.js +1 -1
- package/dist/esm/hooks/useShapes/waterfall/index.js +1 -1
- package/dist/esm/types/chart/base.d.ts +6 -0
- package/dist/esm/types/chart/legend.d.ts +7 -0
- package/dist/esm/types/chart/line.d.ts +19 -13
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
|
-
# Gravity UI Charts
|
|
1
|
+
# Gravity UI Charts
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A flexible JavaScript library for data visualization and chart rendering using React.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@gravity-ui/charts) [](https://github.com/gravity-ui/charts/actions/workflows/ci.yml?query=branch:main) [](https://preview.gravity-ui.com/charts/)
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
- [Overview](https://gravity-ui.github.io/charts/pages/overview.html)
|
|
10
|
+
- [API](https://gravity-ui.github.io/charts/pages/api/overview.html)
|
|
11
|
+
- [Guides](https://gravity-ui.github.io/charts/pages/guides/tooltip.html)
|
|
12
|
+
|
|
13
|
+
## Get started
|
|
14
|
+
|
|
15
|
+
### Install
|
|
4
16
|
|
|
5
17
|
```shell
|
|
6
18
|
npm install @gravity-ui/uikit @gravity-ui/charts
|
|
7
19
|
```
|
|
8
20
|
|
|
9
|
-
|
|
21
|
+
### Development
|
|
10
22
|
|
|
11
23
|
To start the development server with storybook run the following:
|
|
12
24
|
|
|
13
25
|
```shell
|
|
14
26
|
npm run start
|
|
15
27
|
```
|
|
28
|
+
|
|
29
|
+
## Contributing
|
|
30
|
+
|
|
31
|
+
Please refer to the [contributing document](https://github.com/gravity-ui/charts/blob/main/CONTRIBUTING.md) if you wish to make pull requests.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { pointer } from 'd3';
|
|
2
|
+
import get from 'lodash/get';
|
|
2
3
|
import throttle from 'lodash/throttle';
|
|
3
4
|
import { IS_TOUCH_ENABLED } from '../../constants';
|
|
4
5
|
import { EventType } from '../../utils';
|
|
@@ -16,9 +17,10 @@ export function useChartInnerHandlers(props) {
|
|
|
16
17
|
dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
20
|
+
const shapesDataWithTooltipEnabled = shapesData.filter((d) => get(d, 'series.tooltip.enabled', true));
|
|
19
21
|
const closest = getClosestPoints({
|
|
20
22
|
position: [x, y],
|
|
21
|
-
shapesData,
|
|
23
|
+
shapesData: shapesDataWithTooltipEnabled,
|
|
22
24
|
boundsHeight,
|
|
23
25
|
boundsWidth,
|
|
24
26
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ChartLegend } from '../../types';
|
|
2
2
|
export declare const legendDefaults: {
|
|
3
3
|
align: Required<ChartLegend>["align"];
|
|
4
|
+
verticalAlign: Required<ChartLegend>["verticalAlign"];
|
|
4
5
|
justifyContent: Required<ChartLegend>["justifyContent"];
|
|
5
6
|
itemDistance: number;
|
|
6
7
|
margin: number;
|
|
@@ -116,8 +116,14 @@ export function createYScale(args) {
|
|
|
116
116
|
offsetMax += bandWidth / 2;
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
const
|
|
120
|
-
const
|
|
119
|
+
const isMinSpecified = typeof get(axis, 'min') === 'number' && !zoomStateY;
|
|
120
|
+
const isMaxSpecified = typeof get(axis, 'max') === 'number' && !zoomStateY;
|
|
121
|
+
const domainOffsetMin = isMinSpecified
|
|
122
|
+
? 0
|
|
123
|
+
: Math.abs(scale.invert(offsetMin) - scale.invert(0));
|
|
124
|
+
const domainOffsetMax = isMaxSpecified
|
|
125
|
+
? 0
|
|
126
|
+
: Math.abs(scale.invert(offsetMax) - scale.invert(0));
|
|
121
127
|
return scale.domain([yMin - domainOffsetMin, yMax + domainOffsetMax]);
|
|
122
128
|
}
|
|
123
129
|
break;
|
|
@@ -185,8 +191,14 @@ export function createYScale(args) {
|
|
|
185
191
|
offsetMax += bandWidth / 2;
|
|
186
192
|
}
|
|
187
193
|
}
|
|
188
|
-
const
|
|
189
|
-
const
|
|
194
|
+
const isMinSpecified = typeof get(axis, 'min') === 'number' && !zoomStateY;
|
|
195
|
+
const isMaxSpecified = typeof get(axis, 'max') === 'number' && !zoomStateY;
|
|
196
|
+
const domainOffsetMin = isMinSpecified
|
|
197
|
+
? 0
|
|
198
|
+
: Math.abs(scale.invert(offsetMin).getTime() - scale.invert(0).getTime());
|
|
199
|
+
const domainOffsetMax = isMaxSpecified
|
|
200
|
+
? 0
|
|
201
|
+
: Math.abs(scale.invert(offsetMax).getTime() - scale.invert(0).getTime());
|
|
190
202
|
return scale.domain([yMin - domainOffsetMin, yMax + domainOffsetMax]);
|
|
191
203
|
}
|
|
192
204
|
}
|
|
@@ -307,8 +319,14 @@ export function createXScale(args) {
|
|
|
307
319
|
offsetMax += bandWidth / 2;
|
|
308
320
|
}
|
|
309
321
|
}
|
|
310
|
-
const
|
|
311
|
-
const
|
|
322
|
+
const isMinSpecified = typeof get(axis, 'min') === 'number' && !zoomStateX;
|
|
323
|
+
const isMaxSpecified = typeof get(axis, 'max') === 'number' && !zoomStateX;
|
|
324
|
+
const domainOffsetMin = isMinSpecified
|
|
325
|
+
? 0
|
|
326
|
+
: Math.abs(scale.invert(offsetMin) - scale.invert(0));
|
|
327
|
+
const domainOffsetMax = isMaxSpecified
|
|
328
|
+
? 0
|
|
329
|
+
: Math.abs(scale.invert(offsetMax) - scale.invert(0));
|
|
312
330
|
// 10 is the default value for the number of ticks. Here, to preserve the appearance of a series with a small number of points
|
|
313
331
|
const nicedDomain = scale.copy().nice(Math.max(10, domainData.length)).domain();
|
|
314
332
|
scale.domain([xMin - domainOffsetMin, xMax + domainOffsetMax]);
|
|
@@ -374,8 +392,14 @@ export function createXScale(args) {
|
|
|
374
392
|
offsetMax += bandWidth / 2;
|
|
375
393
|
}
|
|
376
394
|
}
|
|
377
|
-
const
|
|
378
|
-
const
|
|
395
|
+
const isMinSpecified = typeof get(axis, 'min') === 'number' && !zoomStateX;
|
|
396
|
+
const isMaxSpecified = typeof get(axis, 'max') === 'number' && !zoomStateX;
|
|
397
|
+
const domainOffsetMin = isMinSpecified
|
|
398
|
+
? 0
|
|
399
|
+
: Math.abs(scale.invert(offsetMin).getTime() - scale.invert(0).getTime());
|
|
400
|
+
const domainOffsetMax = isMaxSpecified
|
|
401
|
+
? 0
|
|
402
|
+
: Math.abs(scale.invert(offsetMax).getTime() - scale.invert(0).getTime());
|
|
379
403
|
// 10 is the default value for the number of ticks. Here, to preserve the appearance of a series with a small number of points
|
|
380
404
|
const nicedDomain = scale.copy().nice(Math.max(10, domainData.length)).domain();
|
|
381
405
|
scale.domain([xMin - domainOffsetMin, xMax + domainOffsetMax]);
|
|
@@ -57,6 +57,7 @@ export async function getPreparedLegend(args) {
|
|
|
57
57
|
}
|
|
58
58
|
return {
|
|
59
59
|
align: get(legend, 'align', legendDefaults.align),
|
|
60
|
+
verticalAlign: get(legend, 'verticalAlign', legendDefaults.verticalAlign),
|
|
60
61
|
justifyContent: get(legend, 'justifyContent', legendDefaults.justifyContent),
|
|
61
62
|
enabled,
|
|
62
63
|
height,
|
|
@@ -174,7 +175,19 @@ function getPagination(args) {
|
|
|
174
175
|
return { pages };
|
|
175
176
|
}
|
|
176
177
|
function getLegendOffset(args) {
|
|
177
|
-
const { position, chartWidth, chartHeight, chartMargin, legendWidth, legendHeight } = args;
|
|
178
|
+
const { position, verticalAlign, chartWidth, chartHeight, chartMargin, legendWidth, legendHeight, } = args;
|
|
179
|
+
const getVerticalTop = () => {
|
|
180
|
+
const availableHeight = chartHeight - chartMargin.top - chartMargin.bottom;
|
|
181
|
+
switch (verticalAlign) {
|
|
182
|
+
case 'bottom':
|
|
183
|
+
return chartMargin.top + availableHeight - legendHeight;
|
|
184
|
+
case 'center':
|
|
185
|
+
return chartMargin.top + (availableHeight - legendHeight) / 2;
|
|
186
|
+
case 'top':
|
|
187
|
+
default:
|
|
188
|
+
return chartMargin.top;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
178
191
|
switch (position) {
|
|
179
192
|
case 'top':
|
|
180
193
|
return {
|
|
@@ -183,12 +196,12 @@ function getLegendOffset(args) {
|
|
|
183
196
|
};
|
|
184
197
|
case 'right':
|
|
185
198
|
return {
|
|
186
|
-
top:
|
|
199
|
+
top: getVerticalTop(),
|
|
187
200
|
left: chartWidth - chartMargin.right - legendWidth,
|
|
188
201
|
};
|
|
189
202
|
case 'left':
|
|
190
203
|
return {
|
|
191
|
-
top:
|
|
204
|
+
top: getVerticalTop(),
|
|
192
205
|
left: chartMargin.left,
|
|
193
206
|
};
|
|
194
207
|
case 'bottom':
|
|
@@ -257,6 +270,7 @@ export function getLegendComponents(args) {
|
|
|
257
270
|
}
|
|
258
271
|
const offset = getLegendOffset({
|
|
259
272
|
position: preparedLegend.position,
|
|
273
|
+
verticalAlign: preparedLegend.verticalAlign,
|
|
260
274
|
chartWidth,
|
|
261
275
|
chartHeight,
|
|
262
276
|
chartMargin,
|
|
@@ -94,7 +94,7 @@ export function prepareLineSeries(args) {
|
|
|
94
94
|
cursor: get(series, 'cursor', null),
|
|
95
95
|
yAxis: get(series, 'yAxis', 0),
|
|
96
96
|
tooltip: series.tooltip,
|
|
97
|
-
rangeSlider: Object.assign({}, seriesRangeSliderOptionsDefaults, series.rangeSlider),
|
|
97
|
+
rangeSlider: Object.assign(Object.assign({}, seriesRangeSliderOptionsDefaults), series.rangeSlider),
|
|
98
98
|
};
|
|
99
99
|
return prepared;
|
|
100
100
|
}, []);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DashStyle, LayoutAlgorithm, LineCap, SeriesOptionsDefaults, SymbolType } from '../../constants';
|
|
2
|
-
import type { AreaSeries, AreaSeriesData, BarXSeries, BarXSeriesData, BarYSeries, BarYSeriesData, BaseTextStyle, ChartLegend, ChartSeries, ChartSeriesRangeSliderOptions, ConnectorCurve, ConnectorShape, FunnelSeries, FunnelSeriesData, HeatmapSeries, HeatmapSeriesData, LineSeries, LineSeriesData, PathLegendSymbolOptions, PieSeries, PieSeriesData, RadarSeries, RadarSeriesCategory, RadarSeriesData, RectLegendSymbolOptions, SankeySeries, SankeySeriesData, ScatterSeries, ScatterSeriesData, SymbolLegendSymbolOptions, TreemapSeries, TreemapSeriesData, ValueFormat, WaterfallSeries, WaterfallSeriesData } from '../../types';
|
|
2
|
+
import type { AreaSeries, AreaSeriesData, BarXSeries, BarXSeriesData, BarYSeries, BarYSeriesData, BaseTextStyle, ChartLegend, ChartSeries, ChartSeriesRangeSliderOptions, ConnectorCurve, ConnectorShape, FunnelSeries, FunnelSeriesData, HeatmapSeries, HeatmapSeriesData, LineSeries, LineSeriesData, LineSeriesLineBaseStyle, PathLegendSymbolOptions, PieSeries, PieSeriesData, RadarSeries, RadarSeriesCategory, RadarSeriesData, RectLegendSymbolOptions, SankeySeries, SankeySeriesData, ScatterSeries, ScatterSeriesData, SymbolLegendSymbolOptions, TreemapSeries, TreemapSeriesData, ValueFormat, WaterfallSeries, WaterfallSeriesData } from '../../types';
|
|
3
3
|
export type RectLegendSymbol = {
|
|
4
4
|
shape: 'rect';
|
|
5
5
|
} & Required<RectLegendSymbolOptions>;
|
|
@@ -83,7 +83,7 @@ type BasePreparedSeries = {
|
|
|
83
83
|
tooltip: ChartSeries['tooltip'];
|
|
84
84
|
};
|
|
85
85
|
type BasePreparedAxisRelatedSeries = {
|
|
86
|
-
rangeSlider: Required<ChartSeriesRangeSliderOptions>;
|
|
86
|
+
rangeSlider: Required<ChartSeriesRangeSliderOptions> & Partial<LineSeriesLineBaseStyle>;
|
|
87
87
|
};
|
|
88
88
|
export type PreparedScatterSeries = {
|
|
89
89
|
type: ScatterSeries['type'];
|
|
@@ -30,7 +30,7 @@ function shouldUseClipPathId(seriesType, clipPathBySeriesType) {
|
|
|
30
30
|
return (_a = clipPathBySeriesType === null || clipPathBySeriesType === void 0 ? void 0 : clipPathBySeriesType[seriesType]) !== null && _a !== void 0 ? _a : true;
|
|
31
31
|
}
|
|
32
32
|
export const useShapes = (args) => {
|
|
33
|
-
const { boundsWidth, boundsHeight, clipPathId, clipPathBySeriesType, dispatcher, htmlLayout, isOutsideBounds = IS_OUTSIDE_BOUNDS, series, seriesOptions, split, xAxis, xScale, yAxis, yScale, } = args;
|
|
33
|
+
const { boundsWidth, boundsHeight, clipPathId, clipPathBySeriesType, dispatcher, htmlLayout, isOutsideBounds = IS_OUTSIDE_BOUNDS, isRangeSlider, series, seriesOptions, split, xAxis, xScale, yAxis, yScale, } = args;
|
|
34
34
|
const [shapesElemens, setShapesElements] = React.useState([]);
|
|
35
35
|
const [shapesElemensData, setShapesElemensData] = React.useState([]);
|
|
36
36
|
const countedRef = React.useRef(0);
|
|
@@ -106,6 +106,7 @@ export const useShapes = (args) => {
|
|
|
106
106
|
yScale,
|
|
107
107
|
split,
|
|
108
108
|
isOutsideBounds,
|
|
109
|
+
isRangeSlider,
|
|
109
110
|
});
|
|
110
111
|
shapes.push(React.createElement(LineSeriesShapes, { key: SERIES_TYPE.Line, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
111
112
|
shapesData.push(...preparedData);
|
|
@@ -232,6 +233,7 @@ export const useShapes = (args) => {
|
|
|
232
233
|
dispatcher,
|
|
233
234
|
htmlLayout,
|
|
234
235
|
isOutsideBounds,
|
|
236
|
+
isRangeSlider,
|
|
235
237
|
series,
|
|
236
238
|
seriesOptions,
|
|
237
239
|
split,
|
|
@@ -33,10 +33,10 @@ export const LineSeriesShapes = (args) => {
|
|
|
33
33
|
.attr('d', (d) => line(d.points))
|
|
34
34
|
.attr('fill', 'none')
|
|
35
35
|
.attr('stroke', (d) => d.color)
|
|
36
|
-
.attr('stroke-width', (d) => d.
|
|
36
|
+
.attr('stroke-width', (d) => d.lineWidth)
|
|
37
37
|
.attr('stroke-linejoin', (d) => d.linecap)
|
|
38
38
|
.attr('stroke-linecap', (d) => d.linecap)
|
|
39
|
-
.attr('stroke-dasharray', (d) => getLineDashArray(d.dashStyle, d.
|
|
39
|
+
.attr('stroke-dasharray', (d) => getLineDashArray(d.dashStyle, d.lineWidth))
|
|
40
40
|
.attr('opacity', (d) => d.opacity)
|
|
41
41
|
.attr('cursor', (d) => d.series.cursor);
|
|
42
42
|
let dataLabels = preparedData.reduce((acc, d) => {
|
|
@@ -49,7 +49,7 @@ export const LineSeriesShapes = (args) => {
|
|
|
49
49
|
.selectAll('text')
|
|
50
50
|
.data(dataLabels)
|
|
51
51
|
.join('text')
|
|
52
|
-
.
|
|
52
|
+
.html((d) => d.text)
|
|
53
53
|
.attr('class', b('label'))
|
|
54
54
|
.attr('x', (d) => d.x)
|
|
55
55
|
.attr('y', (d) => d.y)
|
|
@@ -13,8 +13,8 @@ async function getHtmlLabel(point, series, xMax) {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
export const prepareLineData = async (args) => {
|
|
16
|
-
var _a;
|
|
17
|
-
const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds } = args;
|
|
16
|
+
var _a, _b, _c;
|
|
17
|
+
const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider } = args;
|
|
18
18
|
const [_xMin, xRangeMax] = xScale.range();
|
|
19
19
|
const xMax = xRangeMax;
|
|
20
20
|
const acc = [];
|
|
@@ -99,16 +99,16 @@ export const prepareLineData = async (args) => {
|
|
|
99
99
|
points,
|
|
100
100
|
markers,
|
|
101
101
|
labels,
|
|
102
|
-
color: s.color,
|
|
103
|
-
width: s.lineWidth,
|
|
104
102
|
series: s,
|
|
105
103
|
hovered: false,
|
|
106
104
|
active: true,
|
|
107
105
|
id: s.id,
|
|
106
|
+
htmlElements,
|
|
107
|
+
color: s.color,
|
|
108
|
+
lineWidth: (_b = (isRangeSlider ? s.rangeSlider.lineWidth : undefined)) !== null && _b !== void 0 ? _b : s.lineWidth,
|
|
108
109
|
dashStyle: s.dashStyle,
|
|
109
110
|
linecap: s.linecap,
|
|
110
|
-
opacity: s.opacity,
|
|
111
|
-
htmlElements,
|
|
111
|
+
opacity: (_c = (isRangeSlider ? s.rangeSlider.opacity : undefined)) !== null && _c !== void 0 ? _c : s.opacity,
|
|
112
112
|
};
|
|
113
113
|
acc.push(result);
|
|
114
114
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DashStyle, LineCap } from '../../../constants';
|
|
2
|
-
import type { HtmlItem, LabelData, LineSeriesData } from '../../../types';
|
|
2
|
+
import type { HtmlItem, LabelData, LineSeriesData, LineSeriesLineBaseStyle } from '../../../types';
|
|
3
3
|
import type { PreparedLineSeries } from '../../useSeries/types';
|
|
4
4
|
export type PointData = {
|
|
5
5
|
x: number | null;
|
|
@@ -22,14 +22,12 @@ export type PreparedLineData = {
|
|
|
22
22
|
id: string;
|
|
23
23
|
points: PointData[];
|
|
24
24
|
markers: MarkerData[];
|
|
25
|
-
color: string;
|
|
26
|
-
width: number;
|
|
27
25
|
series: PreparedLineSeries;
|
|
28
26
|
hovered: boolean;
|
|
29
27
|
active: boolean;
|
|
30
28
|
labels: LabelData[];
|
|
29
|
+
htmlElements: HtmlItem[];
|
|
30
|
+
color: string;
|
|
31
31
|
dashStyle: DashStyle;
|
|
32
32
|
linecap: LineCap;
|
|
33
|
-
|
|
34
|
-
htmlElements: HtmlItem[];
|
|
35
|
-
};
|
|
33
|
+
} & Required<LineSeriesLineBaseStyle>;
|
|
@@ -56,6 +56,12 @@ export interface BaseSeries {
|
|
|
56
56
|
tooltip?: {
|
|
57
57
|
/** Formatting settings for tooltip value. */
|
|
58
58
|
valueFormat?: ValueFormat;
|
|
59
|
+
/**
|
|
60
|
+
* Enable or disable the visibility of this series in the tooltip.
|
|
61
|
+
*
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
enabled?: boolean;
|
|
59
65
|
};
|
|
60
66
|
}
|
|
61
67
|
export interface BaseSeriesData<T = MeaningfulAny> {
|
|
@@ -25,6 +25,13 @@ export interface ChartLegend extends ChartLegendItem {
|
|
|
25
25
|
* @default center
|
|
26
26
|
* */
|
|
27
27
|
align?: 'left' | 'center' | 'right';
|
|
28
|
+
/**
|
|
29
|
+
* The vertical alignment of the legend box within the chart area.
|
|
30
|
+
* Only applies when position is 'left' or 'right'.
|
|
31
|
+
*
|
|
32
|
+
* @default top
|
|
33
|
+
* */
|
|
34
|
+
verticalAlign?: 'top' | 'center' | 'bottom';
|
|
28
35
|
/**
|
|
29
36
|
* Defines how items should be positioned in the legend when overflowing (moving to the next line).
|
|
30
37
|
*
|
|
@@ -29,30 +29,36 @@ export interface LineSeriesData<T = MeaningfulAny> extends BaseSeriesData<T> {
|
|
|
29
29
|
};
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
export interface
|
|
32
|
+
export interface LineSeriesLineBaseStyle {
|
|
33
|
+
/** Pixel width of the graph line.
|
|
34
|
+
*
|
|
35
|
+
* @default 1 (for individual series).
|
|
36
|
+
* For series within the range slider, values are inherited from the individual series by default.
|
|
37
|
+
*/
|
|
38
|
+
lineWidth?: number;
|
|
39
|
+
/** Individual opacity for the line.
|
|
40
|
+
*
|
|
41
|
+
* For series within the range slider, values are inherited from the individual series by default.
|
|
42
|
+
*/
|
|
43
|
+
opacity?: number | null;
|
|
44
|
+
}
|
|
45
|
+
export interface LineSeries<T = MeaningfulAny> extends BaseSeries, LineSeriesLineBaseStyle {
|
|
33
46
|
type: typeof SERIES_TYPE.Line;
|
|
34
47
|
data: LineSeriesData<T>[];
|
|
35
48
|
/** The name of the series (used in legend, tooltip etc) */
|
|
36
49
|
name: string;
|
|
37
50
|
/** The main color of the series (hex, rgba) */
|
|
38
51
|
color?: string;
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
lineWidth?: number;
|
|
52
|
+
/** Option for line stroke style */
|
|
53
|
+
dashStyle?: DashStyle;
|
|
54
|
+
/** Option for line cap style */
|
|
55
|
+
linecap?: `${LineCap}`;
|
|
44
56
|
/** Individual series legend options. Has higher priority than legend options in widget data */
|
|
45
57
|
legend?: BaseSeriesLegend & {
|
|
46
58
|
symbol?: RectLegendSymbolOptions;
|
|
47
59
|
};
|
|
48
60
|
/** Options for the point markers of line series */
|
|
49
61
|
marker?: PointMarkerOptions;
|
|
50
|
-
/** Option for line stroke style */
|
|
51
|
-
dashStyle?: DashStyle;
|
|
52
|
-
/** Option for line cap style */
|
|
53
|
-
linecap?: `${LineCap}`;
|
|
54
|
-
/** Individual opacity for the line. */
|
|
55
|
-
opacity?: number;
|
|
56
62
|
/** Y-axis index (when using two axes) */
|
|
57
63
|
yAxis?: number;
|
|
58
64
|
/**
|
|
@@ -68,5 +74,5 @@ export interface LineSeries<T = MeaningfulAny> extends BaseSeries {
|
|
|
68
74
|
/**
|
|
69
75
|
* Options to configure how this series appears and behaves in the Range Slider component.
|
|
70
76
|
*/
|
|
71
|
-
rangeSlider?: ChartSeriesRangeSliderOptions;
|
|
77
|
+
rangeSlider?: ChartSeriesRangeSliderOptions & LineSeriesLineBaseStyle;
|
|
72
78
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { pointer } from 'd3';
|
|
2
|
+
import get from 'lodash/get';
|
|
2
3
|
import throttle from 'lodash/throttle';
|
|
3
4
|
import { IS_TOUCH_ENABLED } from '../../constants';
|
|
4
5
|
import { EventType } from '../../utils';
|
|
@@ -16,9 +17,10 @@ export function useChartInnerHandlers(props) {
|
|
|
16
17
|
dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
20
|
+
const shapesDataWithTooltipEnabled = shapesData.filter((d) => get(d, 'series.tooltip.enabled', true));
|
|
19
21
|
const closest = getClosestPoints({
|
|
20
22
|
position: [x, y],
|
|
21
|
-
shapesData,
|
|
23
|
+
shapesData: shapesDataWithTooltipEnabled,
|
|
22
24
|
boundsHeight,
|
|
23
25
|
boundsWidth,
|
|
24
26
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ChartLegend } from '../../types';
|
|
2
2
|
export declare const legendDefaults: {
|
|
3
3
|
align: Required<ChartLegend>["align"];
|
|
4
|
+
verticalAlign: Required<ChartLegend>["verticalAlign"];
|
|
4
5
|
justifyContent: Required<ChartLegend>["justifyContent"];
|
|
5
6
|
itemDistance: number;
|
|
6
7
|
margin: number;
|
|
@@ -116,8 +116,14 @@ export function createYScale(args) {
|
|
|
116
116
|
offsetMax += bandWidth / 2;
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
const
|
|
120
|
-
const
|
|
119
|
+
const isMinSpecified = typeof get(axis, 'min') === 'number' && !zoomStateY;
|
|
120
|
+
const isMaxSpecified = typeof get(axis, 'max') === 'number' && !zoomStateY;
|
|
121
|
+
const domainOffsetMin = isMinSpecified
|
|
122
|
+
? 0
|
|
123
|
+
: Math.abs(scale.invert(offsetMin) - scale.invert(0));
|
|
124
|
+
const domainOffsetMax = isMaxSpecified
|
|
125
|
+
? 0
|
|
126
|
+
: Math.abs(scale.invert(offsetMax) - scale.invert(0));
|
|
121
127
|
return scale.domain([yMin - domainOffsetMin, yMax + domainOffsetMax]);
|
|
122
128
|
}
|
|
123
129
|
break;
|
|
@@ -185,8 +191,14 @@ export function createYScale(args) {
|
|
|
185
191
|
offsetMax += bandWidth / 2;
|
|
186
192
|
}
|
|
187
193
|
}
|
|
188
|
-
const
|
|
189
|
-
const
|
|
194
|
+
const isMinSpecified = typeof get(axis, 'min') === 'number' && !zoomStateY;
|
|
195
|
+
const isMaxSpecified = typeof get(axis, 'max') === 'number' && !zoomStateY;
|
|
196
|
+
const domainOffsetMin = isMinSpecified
|
|
197
|
+
? 0
|
|
198
|
+
: Math.abs(scale.invert(offsetMin).getTime() - scale.invert(0).getTime());
|
|
199
|
+
const domainOffsetMax = isMaxSpecified
|
|
200
|
+
? 0
|
|
201
|
+
: Math.abs(scale.invert(offsetMax).getTime() - scale.invert(0).getTime());
|
|
190
202
|
return scale.domain([yMin - domainOffsetMin, yMax + domainOffsetMax]);
|
|
191
203
|
}
|
|
192
204
|
}
|
|
@@ -307,8 +319,14 @@ export function createXScale(args) {
|
|
|
307
319
|
offsetMax += bandWidth / 2;
|
|
308
320
|
}
|
|
309
321
|
}
|
|
310
|
-
const
|
|
311
|
-
const
|
|
322
|
+
const isMinSpecified = typeof get(axis, 'min') === 'number' && !zoomStateX;
|
|
323
|
+
const isMaxSpecified = typeof get(axis, 'max') === 'number' && !zoomStateX;
|
|
324
|
+
const domainOffsetMin = isMinSpecified
|
|
325
|
+
? 0
|
|
326
|
+
: Math.abs(scale.invert(offsetMin) - scale.invert(0));
|
|
327
|
+
const domainOffsetMax = isMaxSpecified
|
|
328
|
+
? 0
|
|
329
|
+
: Math.abs(scale.invert(offsetMax) - scale.invert(0));
|
|
312
330
|
// 10 is the default value for the number of ticks. Here, to preserve the appearance of a series with a small number of points
|
|
313
331
|
const nicedDomain = scale.copy().nice(Math.max(10, domainData.length)).domain();
|
|
314
332
|
scale.domain([xMin - domainOffsetMin, xMax + domainOffsetMax]);
|
|
@@ -374,8 +392,14 @@ export function createXScale(args) {
|
|
|
374
392
|
offsetMax += bandWidth / 2;
|
|
375
393
|
}
|
|
376
394
|
}
|
|
377
|
-
const
|
|
378
|
-
const
|
|
395
|
+
const isMinSpecified = typeof get(axis, 'min') === 'number' && !zoomStateX;
|
|
396
|
+
const isMaxSpecified = typeof get(axis, 'max') === 'number' && !zoomStateX;
|
|
397
|
+
const domainOffsetMin = isMinSpecified
|
|
398
|
+
? 0
|
|
399
|
+
: Math.abs(scale.invert(offsetMin).getTime() - scale.invert(0).getTime());
|
|
400
|
+
const domainOffsetMax = isMaxSpecified
|
|
401
|
+
? 0
|
|
402
|
+
: Math.abs(scale.invert(offsetMax).getTime() - scale.invert(0).getTime());
|
|
379
403
|
// 10 is the default value for the number of ticks. Here, to preserve the appearance of a series with a small number of points
|
|
380
404
|
const nicedDomain = scale.copy().nice(Math.max(10, domainData.length)).domain();
|
|
381
405
|
scale.domain([xMin - domainOffsetMin, xMax + domainOffsetMax]);
|
|
@@ -57,6 +57,7 @@ export async function getPreparedLegend(args) {
|
|
|
57
57
|
}
|
|
58
58
|
return {
|
|
59
59
|
align: get(legend, 'align', legendDefaults.align),
|
|
60
|
+
verticalAlign: get(legend, 'verticalAlign', legendDefaults.verticalAlign),
|
|
60
61
|
justifyContent: get(legend, 'justifyContent', legendDefaults.justifyContent),
|
|
61
62
|
enabled,
|
|
62
63
|
height,
|
|
@@ -174,7 +175,19 @@ function getPagination(args) {
|
|
|
174
175
|
return { pages };
|
|
175
176
|
}
|
|
176
177
|
function getLegendOffset(args) {
|
|
177
|
-
const { position, chartWidth, chartHeight, chartMargin, legendWidth, legendHeight } = args;
|
|
178
|
+
const { position, verticalAlign, chartWidth, chartHeight, chartMargin, legendWidth, legendHeight, } = args;
|
|
179
|
+
const getVerticalTop = () => {
|
|
180
|
+
const availableHeight = chartHeight - chartMargin.top - chartMargin.bottom;
|
|
181
|
+
switch (verticalAlign) {
|
|
182
|
+
case 'bottom':
|
|
183
|
+
return chartMargin.top + availableHeight - legendHeight;
|
|
184
|
+
case 'center':
|
|
185
|
+
return chartMargin.top + (availableHeight - legendHeight) / 2;
|
|
186
|
+
case 'top':
|
|
187
|
+
default:
|
|
188
|
+
return chartMargin.top;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
178
191
|
switch (position) {
|
|
179
192
|
case 'top':
|
|
180
193
|
return {
|
|
@@ -183,12 +196,12 @@ function getLegendOffset(args) {
|
|
|
183
196
|
};
|
|
184
197
|
case 'right':
|
|
185
198
|
return {
|
|
186
|
-
top:
|
|
199
|
+
top: getVerticalTop(),
|
|
187
200
|
left: chartWidth - chartMargin.right - legendWidth,
|
|
188
201
|
};
|
|
189
202
|
case 'left':
|
|
190
203
|
return {
|
|
191
|
-
top:
|
|
204
|
+
top: getVerticalTop(),
|
|
192
205
|
left: chartMargin.left,
|
|
193
206
|
};
|
|
194
207
|
case 'bottom':
|
|
@@ -257,6 +270,7 @@ export function getLegendComponents(args) {
|
|
|
257
270
|
}
|
|
258
271
|
const offset = getLegendOffset({
|
|
259
272
|
position: preparedLegend.position,
|
|
273
|
+
verticalAlign: preparedLegend.verticalAlign,
|
|
260
274
|
chartWidth,
|
|
261
275
|
chartHeight,
|
|
262
276
|
chartMargin,
|
|
@@ -94,7 +94,7 @@ export function prepareLineSeries(args) {
|
|
|
94
94
|
cursor: get(series, 'cursor', null),
|
|
95
95
|
yAxis: get(series, 'yAxis', 0),
|
|
96
96
|
tooltip: series.tooltip,
|
|
97
|
-
rangeSlider: Object.assign({}, seriesRangeSliderOptionsDefaults, series.rangeSlider),
|
|
97
|
+
rangeSlider: Object.assign(Object.assign({}, seriesRangeSliderOptionsDefaults), series.rangeSlider),
|
|
98
98
|
};
|
|
99
99
|
return prepared;
|
|
100
100
|
}, []);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DashStyle, LayoutAlgorithm, LineCap, SeriesOptionsDefaults, SymbolType } from '../../constants';
|
|
2
|
-
import type { AreaSeries, AreaSeriesData, BarXSeries, BarXSeriesData, BarYSeries, BarYSeriesData, BaseTextStyle, ChartLegend, ChartSeries, ChartSeriesRangeSliderOptions, ConnectorCurve, ConnectorShape, FunnelSeries, FunnelSeriesData, HeatmapSeries, HeatmapSeriesData, LineSeries, LineSeriesData, PathLegendSymbolOptions, PieSeries, PieSeriesData, RadarSeries, RadarSeriesCategory, RadarSeriesData, RectLegendSymbolOptions, SankeySeries, SankeySeriesData, ScatterSeries, ScatterSeriesData, SymbolLegendSymbolOptions, TreemapSeries, TreemapSeriesData, ValueFormat, WaterfallSeries, WaterfallSeriesData } from '../../types';
|
|
2
|
+
import type { AreaSeries, AreaSeriesData, BarXSeries, BarXSeriesData, BarYSeries, BarYSeriesData, BaseTextStyle, ChartLegend, ChartSeries, ChartSeriesRangeSliderOptions, ConnectorCurve, ConnectorShape, FunnelSeries, FunnelSeriesData, HeatmapSeries, HeatmapSeriesData, LineSeries, LineSeriesData, LineSeriesLineBaseStyle, PathLegendSymbolOptions, PieSeries, PieSeriesData, RadarSeries, RadarSeriesCategory, RadarSeriesData, RectLegendSymbolOptions, SankeySeries, SankeySeriesData, ScatterSeries, ScatterSeriesData, SymbolLegendSymbolOptions, TreemapSeries, TreemapSeriesData, ValueFormat, WaterfallSeries, WaterfallSeriesData } from '../../types';
|
|
3
3
|
export type RectLegendSymbol = {
|
|
4
4
|
shape: 'rect';
|
|
5
5
|
} & Required<RectLegendSymbolOptions>;
|
|
@@ -83,7 +83,7 @@ type BasePreparedSeries = {
|
|
|
83
83
|
tooltip: ChartSeries['tooltip'];
|
|
84
84
|
};
|
|
85
85
|
type BasePreparedAxisRelatedSeries = {
|
|
86
|
-
rangeSlider: Required<ChartSeriesRangeSliderOptions>;
|
|
86
|
+
rangeSlider: Required<ChartSeriesRangeSliderOptions> & Partial<LineSeriesLineBaseStyle>;
|
|
87
87
|
};
|
|
88
88
|
export type PreparedScatterSeries = {
|
|
89
89
|
type: ScatterSeries['type'];
|
|
@@ -30,7 +30,7 @@ function shouldUseClipPathId(seriesType, clipPathBySeriesType) {
|
|
|
30
30
|
return (_a = clipPathBySeriesType === null || clipPathBySeriesType === void 0 ? void 0 : clipPathBySeriesType[seriesType]) !== null && _a !== void 0 ? _a : true;
|
|
31
31
|
}
|
|
32
32
|
export const useShapes = (args) => {
|
|
33
|
-
const { boundsWidth, boundsHeight, clipPathId, clipPathBySeriesType, dispatcher, htmlLayout, isOutsideBounds = IS_OUTSIDE_BOUNDS, series, seriesOptions, split, xAxis, xScale, yAxis, yScale, } = args;
|
|
33
|
+
const { boundsWidth, boundsHeight, clipPathId, clipPathBySeriesType, dispatcher, htmlLayout, isOutsideBounds = IS_OUTSIDE_BOUNDS, isRangeSlider, series, seriesOptions, split, xAxis, xScale, yAxis, yScale, } = args;
|
|
34
34
|
const [shapesElemens, setShapesElements] = React.useState([]);
|
|
35
35
|
const [shapesElemensData, setShapesElemensData] = React.useState([]);
|
|
36
36
|
const countedRef = React.useRef(0);
|
|
@@ -106,6 +106,7 @@ export const useShapes = (args) => {
|
|
|
106
106
|
yScale,
|
|
107
107
|
split,
|
|
108
108
|
isOutsideBounds,
|
|
109
|
+
isRangeSlider,
|
|
109
110
|
});
|
|
110
111
|
shapes.push(React.createElement(LineSeriesShapes, { key: SERIES_TYPE.Line, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
111
112
|
shapesData.push(...preparedData);
|
|
@@ -232,6 +233,7 @@ export const useShapes = (args) => {
|
|
|
232
233
|
dispatcher,
|
|
233
234
|
htmlLayout,
|
|
234
235
|
isOutsideBounds,
|
|
236
|
+
isRangeSlider,
|
|
235
237
|
series,
|
|
236
238
|
seriesOptions,
|
|
237
239
|
split,
|
|
@@ -33,10 +33,10 @@ export const LineSeriesShapes = (args) => {
|
|
|
33
33
|
.attr('d', (d) => line(d.points))
|
|
34
34
|
.attr('fill', 'none')
|
|
35
35
|
.attr('stroke', (d) => d.color)
|
|
36
|
-
.attr('stroke-width', (d) => d.
|
|
36
|
+
.attr('stroke-width', (d) => d.lineWidth)
|
|
37
37
|
.attr('stroke-linejoin', (d) => d.linecap)
|
|
38
38
|
.attr('stroke-linecap', (d) => d.linecap)
|
|
39
|
-
.attr('stroke-dasharray', (d) => getLineDashArray(d.dashStyle, d.
|
|
39
|
+
.attr('stroke-dasharray', (d) => getLineDashArray(d.dashStyle, d.lineWidth))
|
|
40
40
|
.attr('opacity', (d) => d.opacity)
|
|
41
41
|
.attr('cursor', (d) => d.series.cursor);
|
|
42
42
|
let dataLabels = preparedData.reduce((acc, d) => {
|
|
@@ -49,7 +49,7 @@ export const LineSeriesShapes = (args) => {
|
|
|
49
49
|
.selectAll('text')
|
|
50
50
|
.data(dataLabels)
|
|
51
51
|
.join('text')
|
|
52
|
-
.
|
|
52
|
+
.html((d) => d.text)
|
|
53
53
|
.attr('class', b('label'))
|
|
54
54
|
.attr('x', (d) => d.x)
|
|
55
55
|
.attr('y', (d) => d.y)
|
|
@@ -13,8 +13,8 @@ async function getHtmlLabel(point, series, xMax) {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
export const prepareLineData = async (args) => {
|
|
16
|
-
var _a;
|
|
17
|
-
const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds } = args;
|
|
16
|
+
var _a, _b, _c;
|
|
17
|
+
const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider } = args;
|
|
18
18
|
const [_xMin, xRangeMax] = xScale.range();
|
|
19
19
|
const xMax = xRangeMax;
|
|
20
20
|
const acc = [];
|
|
@@ -99,16 +99,16 @@ export const prepareLineData = async (args) => {
|
|
|
99
99
|
points,
|
|
100
100
|
markers,
|
|
101
101
|
labels,
|
|
102
|
-
color: s.color,
|
|
103
|
-
width: s.lineWidth,
|
|
104
102
|
series: s,
|
|
105
103
|
hovered: false,
|
|
106
104
|
active: true,
|
|
107
105
|
id: s.id,
|
|
106
|
+
htmlElements,
|
|
107
|
+
color: s.color,
|
|
108
|
+
lineWidth: (_b = (isRangeSlider ? s.rangeSlider.lineWidth : undefined)) !== null && _b !== void 0 ? _b : s.lineWidth,
|
|
108
109
|
dashStyle: s.dashStyle,
|
|
109
110
|
linecap: s.linecap,
|
|
110
|
-
opacity: s.opacity,
|
|
111
|
-
htmlElements,
|
|
111
|
+
opacity: (_c = (isRangeSlider ? s.rangeSlider.opacity : undefined)) !== null && _c !== void 0 ? _c : s.opacity,
|
|
112
112
|
};
|
|
113
113
|
acc.push(result);
|
|
114
114
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DashStyle, LineCap } from '../../../constants';
|
|
2
|
-
import type { HtmlItem, LabelData, LineSeriesData } from '../../../types';
|
|
2
|
+
import type { HtmlItem, LabelData, LineSeriesData, LineSeriesLineBaseStyle } from '../../../types';
|
|
3
3
|
import type { PreparedLineSeries } from '../../useSeries/types';
|
|
4
4
|
export type PointData = {
|
|
5
5
|
x: number | null;
|
|
@@ -22,14 +22,12 @@ export type PreparedLineData = {
|
|
|
22
22
|
id: string;
|
|
23
23
|
points: PointData[];
|
|
24
24
|
markers: MarkerData[];
|
|
25
|
-
color: string;
|
|
26
|
-
width: number;
|
|
27
25
|
series: PreparedLineSeries;
|
|
28
26
|
hovered: boolean;
|
|
29
27
|
active: boolean;
|
|
30
28
|
labels: LabelData[];
|
|
29
|
+
htmlElements: HtmlItem[];
|
|
30
|
+
color: string;
|
|
31
31
|
dashStyle: DashStyle;
|
|
32
32
|
linecap: LineCap;
|
|
33
|
-
|
|
34
|
-
htmlElements: HtmlItem[];
|
|
35
|
-
};
|
|
33
|
+
} & Required<LineSeriesLineBaseStyle>;
|
|
@@ -56,6 +56,12 @@ export interface BaseSeries {
|
|
|
56
56
|
tooltip?: {
|
|
57
57
|
/** Formatting settings for tooltip value. */
|
|
58
58
|
valueFormat?: ValueFormat;
|
|
59
|
+
/**
|
|
60
|
+
* Enable or disable the visibility of this series in the tooltip.
|
|
61
|
+
*
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
enabled?: boolean;
|
|
59
65
|
};
|
|
60
66
|
}
|
|
61
67
|
export interface BaseSeriesData<T = MeaningfulAny> {
|
|
@@ -25,6 +25,13 @@ export interface ChartLegend extends ChartLegendItem {
|
|
|
25
25
|
* @default center
|
|
26
26
|
* */
|
|
27
27
|
align?: 'left' | 'center' | 'right';
|
|
28
|
+
/**
|
|
29
|
+
* The vertical alignment of the legend box within the chart area.
|
|
30
|
+
* Only applies when position is 'left' or 'right'.
|
|
31
|
+
*
|
|
32
|
+
* @default top
|
|
33
|
+
* */
|
|
34
|
+
verticalAlign?: 'top' | 'center' | 'bottom';
|
|
28
35
|
/**
|
|
29
36
|
* Defines how items should be positioned in the legend when overflowing (moving to the next line).
|
|
30
37
|
*
|
|
@@ -29,30 +29,36 @@ export interface LineSeriesData<T = MeaningfulAny> extends BaseSeriesData<T> {
|
|
|
29
29
|
};
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
export interface
|
|
32
|
+
export interface LineSeriesLineBaseStyle {
|
|
33
|
+
/** Pixel width of the graph line.
|
|
34
|
+
*
|
|
35
|
+
* @default 1 (for individual series).
|
|
36
|
+
* For series within the range slider, values are inherited from the individual series by default.
|
|
37
|
+
*/
|
|
38
|
+
lineWidth?: number;
|
|
39
|
+
/** Individual opacity for the line.
|
|
40
|
+
*
|
|
41
|
+
* For series within the range slider, values are inherited from the individual series by default.
|
|
42
|
+
*/
|
|
43
|
+
opacity?: number | null;
|
|
44
|
+
}
|
|
45
|
+
export interface LineSeries<T = MeaningfulAny> extends BaseSeries, LineSeriesLineBaseStyle {
|
|
33
46
|
type: typeof SERIES_TYPE.Line;
|
|
34
47
|
data: LineSeriesData<T>[];
|
|
35
48
|
/** The name of the series (used in legend, tooltip etc) */
|
|
36
49
|
name: string;
|
|
37
50
|
/** The main color of the series (hex, rgba) */
|
|
38
51
|
color?: string;
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
lineWidth?: number;
|
|
52
|
+
/** Option for line stroke style */
|
|
53
|
+
dashStyle?: DashStyle;
|
|
54
|
+
/** Option for line cap style */
|
|
55
|
+
linecap?: `${LineCap}`;
|
|
44
56
|
/** Individual series legend options. Has higher priority than legend options in widget data */
|
|
45
57
|
legend?: BaseSeriesLegend & {
|
|
46
58
|
symbol?: RectLegendSymbolOptions;
|
|
47
59
|
};
|
|
48
60
|
/** Options for the point markers of line series */
|
|
49
61
|
marker?: PointMarkerOptions;
|
|
50
|
-
/** Option for line stroke style */
|
|
51
|
-
dashStyle?: DashStyle;
|
|
52
|
-
/** Option for line cap style */
|
|
53
|
-
linecap?: `${LineCap}`;
|
|
54
|
-
/** Individual opacity for the line. */
|
|
55
|
-
opacity?: number;
|
|
56
62
|
/** Y-axis index (when using two axes) */
|
|
57
63
|
yAxis?: number;
|
|
58
64
|
/**
|
|
@@ -68,5 +74,5 @@ export interface LineSeries<T = MeaningfulAny> extends BaseSeries {
|
|
|
68
74
|
/**
|
|
69
75
|
* Options to configure how this series appears and behaves in the Range Slider component.
|
|
70
76
|
*/
|
|
71
|
-
rangeSlider?: ChartSeriesRangeSliderOptions;
|
|
77
|
+
rangeSlider?: ChartSeriesRangeSliderOptions & LineSeriesLineBaseStyle;
|
|
72
78
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravity-ui/charts",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.30.0",
|
|
4
|
+
"description": "A flexible JavaScript library for data visualization and chart rendering using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
7
7
|
"module": "./dist/esm/index.js",
|