@gravity-ui/charts 1.42.4 → 1.43.1
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/dist/cjs/components/AxisX/AxisX.js +27 -0
- package/dist/cjs/components/AxisX/prepare-axis-data.js +41 -0
- package/dist/cjs/components/AxisX/types.d.ts +18 -1
- package/dist/cjs/components/AxisY/AxisY.js +27 -0
- package/dist/cjs/components/AxisY/prepare-axis-data.js +41 -0
- package/dist/cjs/components/AxisY/types.d.ts +18 -1
- package/dist/cjs/components/ChartInner/index.js +19 -3
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +3 -3
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +16 -17
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +2 -4
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +8 -4
- package/dist/cjs/components/ChartInner/useDefaultState.js +4 -3
- package/dist/cjs/components/ChartInner/utils/chart.js +1 -1
- package/dist/cjs/components/ChartInner/utils/normalized-original-data.d.ts +1 -0
- package/dist/cjs/components/ChartInner/utils/title.d.ts +4 -2
- package/dist/cjs/components/ChartInner/utils/title.js +77 -14
- package/dist/cjs/components/Title/index.d.ts +1 -3
- package/dist/cjs/components/Title/index.js +3 -5
- package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +2 -1
- package/dist/cjs/components/Tooltip/ChartTooltipContent.js +3 -2
- package/dist/cjs/components/Tooltip/index.js +2 -2
- package/dist/cjs/core/axes/types.d.ts +26 -9
- package/dist/cjs/core/axes/x-axis.js +14 -1
- package/dist/cjs/core/axes/y-axis.js +20 -7
- package/dist/cjs/core/constants/defaults/axis.d.ts +1 -0
- package/dist/cjs/core/constants/defaults/axis.js +1 -0
- package/dist/cjs/core/constants/index.d.ts +0 -1
- package/dist/cjs/core/constants/index.js +0 -1
- package/dist/cjs/core/scales/y-scale.js +37 -13
- package/dist/cjs/core/types/chart/axis.d.ts +43 -1
- package/dist/cjs/core/types/chart/title.d.ts +10 -0
- package/dist/cjs/core/types/chart/tooltip.d.ts +3 -1
- package/dist/cjs/core/utils/common.js +1 -1
- package/dist/cjs/core/utils/get-hovered-plots.d.ts +3 -2
- package/dist/cjs/core/utils/get-hovered-plots.js +28 -4
- package/dist/cjs/core/utils/labels.d.ts +1 -1
- package/dist/cjs/core/utils/labels.js +3 -2
- package/dist/cjs/core/utils/text.js +12 -2
- package/dist/cjs/hooks/types.d.ts +5 -2
- package/dist/cjs/hooks/useSeries/index.js +8 -2
- package/dist/cjs/hooks/useShapes/area/index.js +2 -2
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +15 -10
- package/dist/cjs/hooks/useShapes/area/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/bar-x/index.js +2 -2
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +27 -16
- package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/index.js +18 -5
- package/dist/cjs/hooks/useShapes/line/index.js +7 -16
- package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +11 -7
- package/dist/cjs/hooks/useShapes/line/types.d.ts +2 -2
- package/dist/cjs/hooks/useTooltip/index.d.ts +3 -2
- package/dist/cjs/hooks/useTooltip/index.js +5 -3
- package/dist/cjs/types/chart-ui.d.ts +4 -0
- package/dist/esm/components/AxisX/AxisX.js +27 -0
- package/dist/esm/components/AxisX/prepare-axis-data.js +41 -0
- package/dist/esm/components/AxisX/types.d.ts +18 -1
- package/dist/esm/components/AxisY/AxisY.js +27 -0
- package/dist/esm/components/AxisY/prepare-axis-data.js +41 -0
- package/dist/esm/components/AxisY/types.d.ts +18 -1
- package/dist/esm/components/ChartInner/index.js +19 -3
- package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +3 -3
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +16 -17
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +2 -4
- package/dist/esm/components/ChartInner/useChartInnerProps.js +8 -4
- package/dist/esm/components/ChartInner/useDefaultState.js +4 -3
- package/dist/esm/components/ChartInner/utils/chart.js +1 -1
- package/dist/esm/components/ChartInner/utils/normalized-original-data.d.ts +1 -0
- package/dist/esm/components/ChartInner/utils/title.d.ts +4 -2
- package/dist/esm/components/ChartInner/utils/title.js +77 -14
- package/dist/esm/components/Title/index.d.ts +1 -3
- package/dist/esm/components/Title/index.js +3 -5
- package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +2 -1
- package/dist/esm/components/Tooltip/ChartTooltipContent.js +3 -2
- package/dist/esm/components/Tooltip/index.js +2 -2
- package/dist/esm/core/axes/types.d.ts +26 -9
- package/dist/esm/core/axes/x-axis.js +14 -1
- package/dist/esm/core/axes/y-axis.js +20 -7
- package/dist/esm/core/constants/defaults/axis.d.ts +1 -0
- package/dist/esm/core/constants/defaults/axis.js +1 -0
- package/dist/esm/core/constants/index.d.ts +0 -1
- package/dist/esm/core/constants/index.js +0 -1
- package/dist/esm/core/scales/y-scale.js +37 -13
- package/dist/esm/core/types/chart/axis.d.ts +43 -1
- package/dist/esm/core/types/chart/title.d.ts +10 -0
- package/dist/esm/core/types/chart/tooltip.d.ts +3 -1
- package/dist/esm/core/utils/common.js +1 -1
- package/dist/esm/core/utils/get-hovered-plots.d.ts +3 -2
- package/dist/esm/core/utils/get-hovered-plots.js +28 -4
- package/dist/esm/core/utils/labels.d.ts +1 -1
- package/dist/esm/core/utils/labels.js +3 -2
- package/dist/esm/core/utils/text.js +12 -2
- package/dist/esm/hooks/types.d.ts +5 -2
- package/dist/esm/hooks/useSeries/index.js +8 -2
- package/dist/esm/hooks/useShapes/area/index.js +2 -2
- package/dist/esm/hooks/useShapes/area/prepare-data.js +15 -10
- package/dist/esm/hooks/useShapes/area/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/bar-x/index.js +2 -2
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +27 -16
- package/dist/esm/hooks/useShapes/bar-x/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/index.js +18 -5
- package/dist/esm/hooks/useShapes/line/index.js +7 -16
- package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +2 -0
- package/dist/esm/hooks/useShapes/line/prepare-data.js +11 -7
- package/dist/esm/hooks/useShapes/line/types.d.ts +2 -2
- package/dist/esm/hooks/useTooltip/index.d.ts +3 -2
- package/dist/esm/hooks/useTooltip/index.js +5 -3
- package/dist/esm/types/chart-ui.d.ts +4 -0
- package/package.json +1 -1
- package/dist/cjs/core/constants/misc.d.ts +0 -1
- package/dist/cjs/core/constants/misc.js +0 -7
- package/dist/esm/core/constants/misc.d.ts +0 -1
- package/dist/esm/core/constants/misc.js +0 -7
|
@@ -23,6 +23,7 @@ export const AxisX = (props) => {
|
|
|
23
23
|
const plotDataAttr = 'data-plot-x';
|
|
24
24
|
const plotBandDataAttr = `data-plot-x-band-${preparedAxisData.id}`;
|
|
25
25
|
const plotLineDataAttr = `data-plot-x-line-${preparedAxisData.id}`;
|
|
26
|
+
const plotShapeDataAttr = `data-plot-x-shape-${preparedAxisData.id}`;
|
|
26
27
|
if (plotBeforeRef === null || plotBeforeRef === void 0 ? void 0 : plotBeforeRef.current) {
|
|
27
28
|
plotBeforeContainer = select(plotBeforeRef.current);
|
|
28
29
|
}
|
|
@@ -186,14 +187,40 @@ export const AxisX = (props) => {
|
|
|
186
187
|
setPlotLines(plotBeforeContainer, preparedAxisData.plotLines.filter((item) => item.layerPlacement === 'before'));
|
|
187
188
|
setPlotLines(plotAfterContainer, preparedAxisData.plotLines.filter((item) => item.layerPlacement === 'after'));
|
|
188
189
|
}
|
|
190
|
+
if (preparedAxisData.plotShapes.length > 0) {
|
|
191
|
+
const setPlotShapes = (plotContainer, plotShapes) => {
|
|
192
|
+
if (!plotContainer || !plotShapes.length) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
plotContainer
|
|
196
|
+
.selectAll(`[${plotShapeDataAttr}]`)
|
|
197
|
+
.remove()
|
|
198
|
+
.data(plotShapes)
|
|
199
|
+
.join('g')
|
|
200
|
+
.attr(plotDataAttr, 1)
|
|
201
|
+
.attr(plotShapeDataAttr, 1)
|
|
202
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`)
|
|
203
|
+
.attr('opacity', (d) => d.opacity)
|
|
204
|
+
.html((d) => d.renderer({
|
|
205
|
+
x: d.x,
|
|
206
|
+
y: 0,
|
|
207
|
+
plotHeight: d.plotHeight,
|
|
208
|
+
plotWidth: d.plotWidth,
|
|
209
|
+
}));
|
|
210
|
+
};
|
|
211
|
+
setPlotShapes(plotBeforeContainer, preparedAxisData.plotShapes.filter((item) => item.layerPlacement === 'before'));
|
|
212
|
+
setPlotShapes(plotAfterContainer, preparedAxisData.plotShapes.filter((item) => item.layerPlacement === 'after'));
|
|
213
|
+
}
|
|
189
214
|
return () => {
|
|
190
215
|
if (plotBeforeContainer) {
|
|
191
216
|
plotBeforeContainer.selectAll(`[${plotBandDataAttr}]`).remove();
|
|
192
217
|
plotBeforeContainer.selectAll(`[${plotLineDataAttr}]`).remove();
|
|
218
|
+
plotBeforeContainer.selectAll(`[${plotShapeDataAttr}]`).remove();
|
|
193
219
|
}
|
|
194
220
|
if (plotAfterContainer) {
|
|
195
221
|
plotAfterContainer.selectAll(`[${plotBandDataAttr}]`).remove();
|
|
196
222
|
plotAfterContainer.selectAll(`[${plotLineDataAttr}]`).remove();
|
|
223
|
+
plotAfterContainer.selectAll(`[${plotShapeDataAttr}]`).remove();
|
|
197
224
|
}
|
|
198
225
|
};
|
|
199
226
|
}, [lineGenerator, plotAfterRef, plotBeforeRef, preparedAxisData]);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getUniqId } from '@gravity-ui/uikit';
|
|
2
|
+
import { select } from 'd3-selection';
|
|
2
3
|
import { calculateCos, calculateSin, formatAxisTickLabel, getBandsPosition, getLabelsSize, getMinSpaceBetween, getTextSizeFn, getTextWithElipsis, } from '../../core/utils';
|
|
3
4
|
import { getXAxisTickValues } from '../../core/utils/axis/x-axis';
|
|
4
5
|
import { getMultilineTitleContentRows } from '../utils/axis-title';
|
|
@@ -328,6 +329,45 @@ export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRig
|
|
|
328
329
|
dashStyle: plotLine.dashStyle,
|
|
329
330
|
});
|
|
330
331
|
}
|
|
332
|
+
const plotShapes = [];
|
|
333
|
+
const measureContainer = axis.plotShapes.length
|
|
334
|
+
? select(document.body)
|
|
335
|
+
.append('svg')
|
|
336
|
+
.style('visibility', 'hidden')
|
|
337
|
+
.style('position', 'absolute')
|
|
338
|
+
.style('top', '-200vw')
|
|
339
|
+
: null;
|
|
340
|
+
for (let i = 0; i < axis.plotShapes.length; i++) {
|
|
341
|
+
if (!measureContainer) {
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
const plotShape = axis.plotShapes[i];
|
|
345
|
+
const axisScale = scale;
|
|
346
|
+
const shapeX = Number(axisScale(plotShape.value));
|
|
347
|
+
if (shapeX < 0 || shapeX > boundsWidth) {
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
const markup = plotShape.renderer({
|
|
351
|
+
x: shapeX,
|
|
352
|
+
y: 0,
|
|
353
|
+
plotHeight: axisHeight,
|
|
354
|
+
plotWidth: axisWidth,
|
|
355
|
+
});
|
|
356
|
+
const wrapper = measureContainer.append('g').html(markup);
|
|
357
|
+
const bbox = wrapper.node().getBBox();
|
|
358
|
+
wrapper.remove();
|
|
359
|
+
plotShapes.push({
|
|
360
|
+
hitbox: { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height },
|
|
361
|
+
layerPlacement: plotShape.layerPlacement,
|
|
362
|
+
opacity: plotShape.opacity,
|
|
363
|
+
plotHeight: axisHeight,
|
|
364
|
+
plotWidth: axisWidth,
|
|
365
|
+
renderer: plotShape.renderer,
|
|
366
|
+
x: shapeX,
|
|
367
|
+
y: axisTop,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
measureContainer === null || measureContainer === void 0 ? void 0 : measureContainer.remove();
|
|
331
371
|
xAxisItems.push({
|
|
332
372
|
id: getUniqId(),
|
|
333
373
|
gridEnabled: axis.grid.enabled,
|
|
@@ -336,6 +376,7 @@ export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRig
|
|
|
336
376
|
domain,
|
|
337
377
|
plotBands,
|
|
338
378
|
plotLines,
|
|
379
|
+
plotShapes,
|
|
339
380
|
});
|
|
340
381
|
}
|
|
341
382
|
return xAxisItems;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DashStyle } from 'src/core/constants';
|
|
2
|
+
import type { AxisPlotShape } from '../../core/types/chart/axis';
|
|
2
3
|
import type { BaseTextStyle, HtmlItem, PlotLayerPlacement, PointPosition } from '../../types';
|
|
3
4
|
import type { TextRowData } from '../types';
|
|
4
5
|
export type AxisSvgLabelData = {
|
|
@@ -67,6 +68,21 @@ export type AxisPlotBandData = {
|
|
|
67
68
|
opacity: number;
|
|
68
69
|
label: AxisPlotLineLabel | null;
|
|
69
70
|
};
|
|
71
|
+
export type AxisPlotShapeData = {
|
|
72
|
+
hitbox: {
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
width: number;
|
|
76
|
+
height: number;
|
|
77
|
+
};
|
|
78
|
+
layerPlacement: PlotLayerPlacement;
|
|
79
|
+
opacity: number;
|
|
80
|
+
plotHeight: number;
|
|
81
|
+
plotWidth: number;
|
|
82
|
+
renderer: AxisPlotShape['renderer'];
|
|
83
|
+
x: number;
|
|
84
|
+
y: number;
|
|
85
|
+
};
|
|
70
86
|
export type AxisDomainData = {
|
|
71
87
|
start: [number, number];
|
|
72
88
|
end: [number, number];
|
|
@@ -78,6 +94,7 @@ export type AxisXData = {
|
|
|
78
94
|
title: AxisTitleData | null;
|
|
79
95
|
domain: AxisDomainData | null;
|
|
80
96
|
ticks: AxisTickData[];
|
|
81
|
-
plotLines: AxisPlotLineData[];
|
|
82
97
|
plotBands: AxisPlotBandData[];
|
|
98
|
+
plotLines: AxisPlotLineData[];
|
|
99
|
+
plotShapes: AxisPlotShapeData[];
|
|
83
100
|
};
|
|
@@ -28,6 +28,7 @@ export const AxisY = (props) => {
|
|
|
28
28
|
const plotDataAttr = 'data-plot-y';
|
|
29
29
|
const plotBandDataAttr = `data-plot-y-band-${preparedAxisData.id}`;
|
|
30
30
|
const plotLineDataAttr = `data-plot-y-line-${preparedAxisData.id}`;
|
|
31
|
+
const plotShapeDataAttr = `data-plot-y-shape-${preparedAxisData.id}`;
|
|
31
32
|
if (plotBeforeRef === null || plotBeforeRef === void 0 ? void 0 : plotBeforeRef.current) {
|
|
32
33
|
plotBeforeContainer = select(plotBeforeRef.current);
|
|
33
34
|
}
|
|
@@ -191,14 +192,40 @@ export const AxisY = (props) => {
|
|
|
191
192
|
setPlotLines(plotBeforeContainer, preparedAxisData.plotLines.filter((item) => item.layerPlacement === 'before'));
|
|
192
193
|
setPlotLines(plotAfterContainer, preparedAxisData.plotLines.filter((item) => item.layerPlacement === 'after'));
|
|
193
194
|
}
|
|
195
|
+
if (preparedAxisData.plotShapes.length > 0) {
|
|
196
|
+
const setPlotShapes = (plotContainer, plotShapes) => {
|
|
197
|
+
if (!plotContainer || !plotShapes.length) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
plotContainer
|
|
201
|
+
.selectAll(`[${plotShapeDataAttr}]`)
|
|
202
|
+
.remove()
|
|
203
|
+
.data(plotShapes)
|
|
204
|
+
.join('g')
|
|
205
|
+
.attr(plotDataAttr, 1)
|
|
206
|
+
.attr(plotShapeDataAttr, 1)
|
|
207
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`)
|
|
208
|
+
.attr('opacity', (d) => d.opacity)
|
|
209
|
+
.html((d) => d.renderer({
|
|
210
|
+
x: 0,
|
|
211
|
+
y: d.y,
|
|
212
|
+
plotHeight: d.plotHeight,
|
|
213
|
+
plotWidth: d.plotWidth,
|
|
214
|
+
}));
|
|
215
|
+
};
|
|
216
|
+
setPlotShapes(plotBeforeContainer, preparedAxisData.plotShapes.filter((item) => item.layerPlacement === 'before'));
|
|
217
|
+
setPlotShapes(plotAfterContainer, preparedAxisData.plotShapes.filter((item) => item.layerPlacement === 'after'));
|
|
218
|
+
}
|
|
194
219
|
return () => {
|
|
195
220
|
if (plotBeforeContainer) {
|
|
196
221
|
plotBeforeContainer.selectAll(`[${plotBandDataAttr}]`).remove();
|
|
197
222
|
plotBeforeContainer.selectAll(`[${plotLineDataAttr}]`).remove();
|
|
223
|
+
plotBeforeContainer.selectAll(`[${plotShapeDataAttr}]`).remove();
|
|
198
224
|
}
|
|
199
225
|
if (plotAfterContainer) {
|
|
200
226
|
plotAfterContainer.selectAll(`[${plotBandDataAttr}]`).remove();
|
|
201
227
|
plotAfterContainer.selectAll(`[${plotLineDataAttr}]`).remove();
|
|
228
|
+
plotAfterContainer.selectAll(`[${plotShapeDataAttr}]`).remove();
|
|
202
229
|
}
|
|
203
230
|
};
|
|
204
231
|
}, [lineGenerator, plotAfterRef, plotBeforeRef, preparedAxisData]);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getUniqId } from '@gravity-ui/uikit';
|
|
2
|
+
import { select } from 'd3-selection';
|
|
2
3
|
import { calculateCos, calculateSin, formatAxisTickLabel, getBandsPosition, getLabelsSize, getMinSpaceBetween, getTextSizeFn, getTextWithElipsis, wrapText, } from '../../core/utils';
|
|
3
4
|
import { prepareHtmlYAxisTitle, prepareSvgYAxisTitle } from './prepare-axis-title';
|
|
4
5
|
import { getTickValues } from './utils';
|
|
@@ -290,6 +291,45 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
290
291
|
dashStyle: plotLine.dashStyle,
|
|
291
292
|
});
|
|
292
293
|
}
|
|
294
|
+
const plotShapes = [];
|
|
295
|
+
const measureContainer = axis.plotShapes.length
|
|
296
|
+
? select(document.body)
|
|
297
|
+
.append('svg')
|
|
298
|
+
.style('visibility', 'hidden')
|
|
299
|
+
.style('position', 'absolute')
|
|
300
|
+
.style('top', '-200vw')
|
|
301
|
+
: null;
|
|
302
|
+
for (let i = 0; i < axis.plotShapes.length; i++) {
|
|
303
|
+
if (!measureContainer) {
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
const plotShape = axis.plotShapes[i];
|
|
307
|
+
const axisScale = scale;
|
|
308
|
+
const shapeY = Number(axisScale(plotShape.value));
|
|
309
|
+
if (shapeY < 0 || shapeY > axisHeight) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
const markup = plotShape.renderer({
|
|
313
|
+
x: 0,
|
|
314
|
+
y: shapeY,
|
|
315
|
+
plotHeight: axisHeight,
|
|
316
|
+
plotWidth: width,
|
|
317
|
+
});
|
|
318
|
+
const wrapper = measureContainer.append('g').html(markup);
|
|
319
|
+
const bbox = wrapper.node().getBBox();
|
|
320
|
+
wrapper.remove();
|
|
321
|
+
plotShapes.push({
|
|
322
|
+
hitbox: { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height },
|
|
323
|
+
layerPlacement: plotShape.layerPlacement,
|
|
324
|
+
opacity: plotShape.opacity,
|
|
325
|
+
plotHeight: axisHeight,
|
|
326
|
+
plotWidth: width,
|
|
327
|
+
renderer: plotShape.renderer,
|
|
328
|
+
x: 0,
|
|
329
|
+
y: axisPlotTopPosition + shapeY,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
measureContainer === null || measureContainer === void 0 ? void 0 : measureContainer.remove();
|
|
293
333
|
return {
|
|
294
334
|
id: getUniqId(),
|
|
295
335
|
gridEnabled: axis.grid.enabled,
|
|
@@ -298,5 +338,6 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
298
338
|
domain,
|
|
299
339
|
plotBands,
|
|
300
340
|
plotLines,
|
|
341
|
+
plotShapes,
|
|
301
342
|
};
|
|
302
343
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DashStyle } from 'src/core/constants';
|
|
2
|
+
import type { AxisPlotShape } from '../../core/types/chart/axis';
|
|
2
3
|
import type { BaseTextStyle, HtmlItem, PlotLayerPlacement, PointPosition } from '../../types';
|
|
3
4
|
import type { TextRowData } from '../types';
|
|
4
5
|
export type AxisSvgLabelData = {
|
|
@@ -78,6 +79,21 @@ export type AxisPlotBandData = {
|
|
|
78
79
|
opacity: number;
|
|
79
80
|
label: AxisPlotLineLabel | null;
|
|
80
81
|
};
|
|
82
|
+
export type AxisPlotShapeData = {
|
|
83
|
+
hitbox: {
|
|
84
|
+
x: number;
|
|
85
|
+
y: number;
|
|
86
|
+
width: number;
|
|
87
|
+
height: number;
|
|
88
|
+
};
|
|
89
|
+
layerPlacement: PlotLayerPlacement;
|
|
90
|
+
opacity: number;
|
|
91
|
+
plotHeight: number;
|
|
92
|
+
plotWidth: number;
|
|
93
|
+
renderer: AxisPlotShape['renderer'];
|
|
94
|
+
x: number;
|
|
95
|
+
y: number;
|
|
96
|
+
};
|
|
81
97
|
export type AxisDomainData = {
|
|
82
98
|
start: [number, number];
|
|
83
99
|
end: [number, number];
|
|
@@ -89,6 +105,7 @@ export type AxisYData = {
|
|
|
89
105
|
title: HtmlAxisTitleData | SvgAxisTitleData | null;
|
|
90
106
|
domain: AxisDomainData | null;
|
|
91
107
|
ticks: AxisTickData[];
|
|
92
|
-
plotLines: AxisPlotLineData[];
|
|
93
108
|
plotBands: AxisPlotBandData[];
|
|
109
|
+
plotLines: AxisPlotLineData[];
|
|
110
|
+
plotShapes: AxisPlotShapeData[];
|
|
94
111
|
};
|
|
@@ -71,7 +71,7 @@ export const ChartInner = (props) => {
|
|
|
71
71
|
value: allPreparedSeries,
|
|
72
72
|
delay: DEBOUNCED_VALUE_DELAY,
|
|
73
73
|
});
|
|
74
|
-
const { handleChartClick,
|
|
74
|
+
const { handleChartClick, handlePointerLeave, throttledHandlePointerMove, throttledHandleTouchMove, } = useChartInnerHandlers({
|
|
75
75
|
boundsHeight,
|
|
76
76
|
boundsOffsetLeft,
|
|
77
77
|
boundsOffsetTop,
|
|
@@ -154,6 +154,13 @@ export const ChartInner = (props) => {
|
|
|
154
154
|
split: preparedSplit,
|
|
155
155
|
series: preparedSeries.filter((s) => s.visible),
|
|
156
156
|
});
|
|
157
|
+
axisData.plotShapes.forEach((shapeData, j) => {
|
|
158
|
+
if (axis.plotShapes[j]) {
|
|
159
|
+
axis.plotShapes[j].hitbox = shapeData.hitbox;
|
|
160
|
+
axis.plotShapes[j].x = shapeData.x;
|
|
161
|
+
axis.plotShapes[j].y = shapeData.y;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
157
164
|
items.push(axisData);
|
|
158
165
|
}
|
|
159
166
|
}
|
|
@@ -180,6 +187,15 @@ export const ChartInner = (props) => {
|
|
|
180
187
|
split: preparedSplit,
|
|
181
188
|
yAxis,
|
|
182
189
|
});
|
|
190
|
+
axisData.forEach((data) => {
|
|
191
|
+
data.plotShapes.forEach((shapeData, i) => {
|
|
192
|
+
if (axis.plotShapes[i]) {
|
|
193
|
+
axis.plotShapes[i].hitbox = shapeData.hitbox;
|
|
194
|
+
axis.plotShapes[i].x = shapeData.x;
|
|
195
|
+
axis.plotShapes[i].y = shapeData.y;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
});
|
|
183
199
|
items.push(...axisData);
|
|
184
200
|
}
|
|
185
201
|
return items;
|
|
@@ -240,7 +256,7 @@ export const ChartInner = (props) => {
|
|
|
240
256
|
React.createElement("rect", { x: 0, y: 0, width: boundsWidth, height: boundsHeight })),
|
|
241
257
|
React.createElement("clipPath", { id: getClipPathIdByBounds({ clipPathId, bounds: 'horizontal' }) },
|
|
242
258
|
React.createElement("rect", { x: 0, y: -boundsHeight, width: boundsWidth, height: boundsHeight * 3 }))),
|
|
243
|
-
preparedTitle && React.createElement(Title, Object.assign({}, preparedTitle
|
|
259
|
+
preparedTitle && React.createElement(Title, Object.assign({}, preparedTitle)),
|
|
244
260
|
React.createElement("g", { transform: `translate(0, ${boundsOffsetTop})` }, preparedSplit === null || preparedSplit === void 0 ? void 0 : preparedSplit.plots.map((plot, index) => {
|
|
245
261
|
return React.createElement(PlotTitle, { key: `plot-${index}`, title: plot.title });
|
|
246
262
|
})),
|
|
@@ -267,7 +283,7 @@ export const ChartInner = (props) => {
|
|
|
267
283
|
React.createElement("svg", { ref: svgRef, width: width, height: height,
|
|
268
284
|
// We use onPointerMove here because onMouseMove works incorrectly when the zoom setting is enabled:
|
|
269
285
|
// when starting to select an area, the tooltip remains in the position where the selection began
|
|
270
|
-
onPointerMove:
|
|
286
|
+
onPointerMove: throttledHandlePointerMove, onPointerLeave: handlePointerLeave, onTouchStart: throttledHandleTouchMove, onTouchMove: throttledHandleTouchMove, onClick: handleChartClick }, initialized ? chartContent : null),
|
|
271
287
|
React.createElement("div", { className: b('html-layer'), ref: setHtmlLayout, style: {
|
|
272
288
|
'--g-html-layout-transform': `translate(${boundsOffsetLeft}px, ${boundsOffsetTop}px)`,
|
|
273
289
|
} }),
|
|
@@ -23,8 +23,8 @@ type Props = {
|
|
|
23
23
|
};
|
|
24
24
|
export declare function useChartInnerHandlers(props: Props): {
|
|
25
25
|
handleChartClick: (event: React.MouseEvent<SVGSVGElement>) => void;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
throttledHandleTouchMove: import("lodash").DebouncedFuncLeading<React.TouchEventHandler<SVGSVGElement
|
|
26
|
+
handlePointerLeave: React.PointerEventHandler<SVGSVGElement>;
|
|
27
|
+
throttledHandlePointerMove: import("lodash").DebouncedFuncLeading<React.PointerEventHandler<SVGSVGElement>>;
|
|
28
|
+
throttledHandleTouchMove: import("lodash").DebouncedFuncLeading<React.TouchEventHandler<SVGSVGElement>>;
|
|
29
29
|
};
|
|
30
30
|
export {};
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import { pointer } from 'd3-selection';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
4
|
import throttle from 'lodash/throttle';
|
|
5
|
-
import { IS_TOUCH_ENABLED } from '../../core/constants';
|
|
6
5
|
import { EventType } from '../../core/utils';
|
|
7
6
|
import { getClosestPoints } from '../../core/utils/get-closest-data';
|
|
8
7
|
import { getHoveredPlots } from '../../core/utils/get-hovered-plots';
|
|
@@ -29,7 +28,7 @@ export function useChartInnerHandlers(props) {
|
|
|
29
28
|
boundsHeight,
|
|
30
29
|
boundsWidth,
|
|
31
30
|
});
|
|
32
|
-
const { plotLines,
|
|
31
|
+
const { plotBands, plotLines, plotShapes } = getHoveredPlots({
|
|
33
32
|
pointerX: x,
|
|
34
33
|
pointerY: y,
|
|
35
34
|
xAxis,
|
|
@@ -37,7 +36,7 @@ export function useChartInnerHandlers(props) {
|
|
|
37
36
|
xScale,
|
|
38
37
|
yScale,
|
|
39
38
|
});
|
|
40
|
-
const hoveredPlotsArg = { lines: plotLines,
|
|
39
|
+
const hoveredPlotsArg = { bands: plotBands, lines: plotLines, shapes: plotShapes };
|
|
41
40
|
dispatcher.call(EventType.HOVER_SHAPE, event.target, closest, [pointerX, pointerY], hoveredPlotsArg);
|
|
42
41
|
dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
|
|
43
42
|
hovered: closest,
|
|
@@ -47,18 +46,19 @@ export function useChartInnerHandlers(props) {
|
|
|
47
46
|
hoveredPlotBands: plotBands,
|
|
48
47
|
}, event);
|
|
49
48
|
};
|
|
50
|
-
const
|
|
49
|
+
const handlePointerMove = (event) => {
|
|
50
|
+
if (event.pointerType === 'touch') {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
51
53
|
const [pointerX, pointerY] = pointer(event, svgContainer);
|
|
52
54
|
handleMove([pointerX, pointerY], event);
|
|
53
55
|
};
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
: throttle(handleMouseMove, tooltipThrottle);
|
|
57
|
-
const handleMouseLeave = (event) => {
|
|
56
|
+
const throttledHandlePointerMove = throttle(handlePointerMove, tooltipThrottle);
|
|
57
|
+
const handlePointerLeave = (event) => {
|
|
58
58
|
if (tooltipPinned) {
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
throttledHandlePointerMove.cancel();
|
|
62
62
|
dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
|
|
63
63
|
dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
|
|
64
64
|
};
|
|
@@ -67,9 +67,7 @@ export function useChartInnerHandlers(props) {
|
|
|
67
67
|
const [pointerX, pointerY] = pointer(touch, svgContainer);
|
|
68
68
|
handleMove([pointerX, pointerY], event);
|
|
69
69
|
};
|
|
70
|
-
const throttledHandleTouchMove =
|
|
71
|
-
? throttle(handleTouchMove, tooltipThrottle)
|
|
72
|
-
: undefined;
|
|
70
|
+
const throttledHandleTouchMove = throttle(handleTouchMove, tooltipThrottle);
|
|
73
71
|
const handleChartClick = (event) => {
|
|
74
72
|
const [pointerX, pointerY] = pointer(event, svgContainer);
|
|
75
73
|
const x = pointerX - boundsOffsetLeft;
|
|
@@ -93,7 +91,7 @@ export function useChartInnerHandlers(props) {
|
|
|
93
91
|
dispatcher.call(EventType.CLICK_CHART, undefined, { point: selected.data, series: selected.series }, event);
|
|
94
92
|
const nextTooltipFixed = !tooltipPinned;
|
|
95
93
|
if (!nextTooltipFixed) {
|
|
96
|
-
const { plotLines,
|
|
94
|
+
const { plotBands, plotLines, plotShapes } = getHoveredPlots({
|
|
97
95
|
pointerX: x,
|
|
98
96
|
pointerY: y,
|
|
99
97
|
xAxis,
|
|
@@ -101,22 +99,23 @@ export function useChartInnerHandlers(props) {
|
|
|
101
99
|
xScale,
|
|
102
100
|
yScale,
|
|
103
101
|
});
|
|
104
|
-
const hoveredPlotsArg = { lines: plotLines,
|
|
102
|
+
const hoveredPlotsArg = { bands: plotBands, lines: plotLines, shapes: plotShapes };
|
|
105
103
|
dispatcher.call(EventType.HOVER_SHAPE, event.target, items, [pointerX, pointerY], hoveredPlotsArg);
|
|
106
104
|
dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
|
|
107
105
|
hovered: items,
|
|
108
106
|
xAxis,
|
|
109
107
|
yAxis: yAxis[0],
|
|
110
|
-
hoveredPlotLines: plotLines,
|
|
111
108
|
hoveredPlotBands: plotBands,
|
|
109
|
+
hoveredPlotLines: plotLines,
|
|
110
|
+
hoveredPlotShapes: plotShapes,
|
|
112
111
|
}, event);
|
|
113
112
|
}
|
|
114
113
|
togglePinTooltip === null || togglePinTooltip === void 0 ? void 0 : togglePinTooltip(nextTooltipFixed, event);
|
|
115
114
|
};
|
|
116
115
|
return {
|
|
117
116
|
handleChartClick,
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
handlePointerLeave,
|
|
118
|
+
throttledHandlePointerMove,
|
|
120
119
|
throttledHandleTouchMove,
|
|
121
120
|
};
|
|
122
121
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Dispatch } from 'd3-dispatch';
|
|
3
3
|
import type { ChartScale, LegendItem, OnLegendItemClick, PreparedLegend, PreparedSeries, PreparedSplit, PreparedXAxis, PreparedYAxis, RangeSliderState, ShapeData, ZoomState } from '../../hooks';
|
|
4
|
-
import type { PreparedChart } from '../../hooks/types';
|
|
4
|
+
import type { PreparedChart, PreparedTitle } from '../../hooks/types';
|
|
5
5
|
import type { LegendConfig } from '../../types';
|
|
6
6
|
import type { ChartInnerProps } from './types';
|
|
7
7
|
type Props = ChartInnerProps & {
|
|
@@ -24,9 +24,7 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
24
24
|
shapesData: ShapeData[];
|
|
25
25
|
shapesReady: boolean;
|
|
26
26
|
handleLegendItemClick: OnLegendItemClick;
|
|
27
|
-
preparedTitle:
|
|
28
|
-
height: number;
|
|
29
|
-
}) | undefined;
|
|
27
|
+
preparedTitle: PreparedTitle | undefined;
|
|
30
28
|
preparedChart: PreparedChart | undefined;
|
|
31
29
|
allPreparedSeries?: PreparedSeries[] | undefined;
|
|
32
30
|
legendConfig?: LegendConfig | undefined;
|
|
@@ -48,15 +48,19 @@ export function useChartInnerProps(props) {
|
|
|
48
48
|
currentRunRef.current++;
|
|
49
49
|
const currentRun = currentRunRef.current;
|
|
50
50
|
(async function () {
|
|
51
|
-
var _a, _b, _c;
|
|
51
|
+
var _a, _b, _c, _d;
|
|
52
52
|
const chartDataChanged = !(previousChartData.current && isEqual(previousChartData.current, data));
|
|
53
|
-
const preparedTitle = await getPreparedTitle({
|
|
53
|
+
const preparedTitle = await getPreparedTitle({
|
|
54
|
+
title: data.title,
|
|
55
|
+
chartWidth: width,
|
|
56
|
+
chartMargin: (_a = data.chart) === null || _a === void 0 ? void 0 : _a.margin,
|
|
57
|
+
});
|
|
54
58
|
const preparedChart = getPreparedChart({
|
|
55
59
|
chart: data.chart,
|
|
56
60
|
seriesData: data.series.data,
|
|
57
61
|
preparedTitle,
|
|
58
62
|
});
|
|
59
|
-
const colors = (
|
|
63
|
+
const colors = (_b = data.colors) !== null && _b !== void 0 ? _b : DEFAULT_PALETTE;
|
|
60
64
|
const normalizedSeriesData = getSortedSeriesData({
|
|
61
65
|
seriesData: data.series.data,
|
|
62
66
|
xAxis: data.xAxis,
|
|
@@ -79,7 +83,7 @@ export function useChartInnerProps(props) {
|
|
|
79
83
|
});
|
|
80
84
|
}
|
|
81
85
|
else {
|
|
82
|
-
allPreparedSeries = (
|
|
86
|
+
allPreparedSeries = (_d = (_c = prevStateValue.current) === null || _c === void 0 ? void 0 : _c.allPreparedSeries) !== null && _d !== void 0 ? _d : [];
|
|
83
87
|
}
|
|
84
88
|
const activeLegendItems = selectedLegendItems !== null && selectedLegendItems !== void 0 ? selectedLegendItems : getActiveLegendItems(allPreparedSeries);
|
|
85
89
|
const visiblePreparedSeries = getVisibleSeries({
|
|
@@ -29,7 +29,7 @@ export function useDefaultState(props) {
|
|
|
29
29
|
boundsHeight,
|
|
30
30
|
boundsWidth,
|
|
31
31
|
});
|
|
32
|
-
const { plotLines,
|
|
32
|
+
const { plotBands, plotLines, plotShapes } = getHoveredPlots({
|
|
33
33
|
pointerX: x,
|
|
34
34
|
pointerY: y,
|
|
35
35
|
xAxis,
|
|
@@ -37,7 +37,7 @@ export function useDefaultState(props) {
|
|
|
37
37
|
xScale,
|
|
38
38
|
yScale,
|
|
39
39
|
});
|
|
40
|
-
const hoveredPlotsArg = { lines: plotLines,
|
|
40
|
+
const hoveredPlotsArg = { bands: plotBands, lines: plotLines, shapes: plotShapes };
|
|
41
41
|
const svgPointerX = x + boundsOffsetLeft;
|
|
42
42
|
const svgPointerY = y + boundsOffsetTop;
|
|
43
43
|
dispatcher.call(EventType.HOVER_SHAPE, undefined, closest, [svgPointerX, svgPointerY], hoveredPlotsArg);
|
|
@@ -55,8 +55,9 @@ export function useDefaultState(props) {
|
|
|
55
55
|
hovered: closest,
|
|
56
56
|
xAxis,
|
|
57
57
|
yAxis: yAxis[0],
|
|
58
|
-
hoveredPlotLines: plotLines,
|
|
59
58
|
hoveredPlotBands: plotBands,
|
|
59
|
+
hoveredPlotLines: plotLines,
|
|
60
|
+
hoveredPlotShapes: plotShapes,
|
|
60
61
|
}, syntheticEvent);
|
|
61
62
|
});
|
|
62
63
|
}, [
|
|
@@ -4,7 +4,7 @@ const getMarginTop = (args) => {
|
|
|
4
4
|
const { chart, preparedTitle } = args;
|
|
5
5
|
let marginTop = get(chart, 'margin.top', 0);
|
|
6
6
|
if (preparedTitle === null || preparedTitle === void 0 ? void 0 : preparedTitle.height) {
|
|
7
|
-
marginTop += preparedTitle.height;
|
|
7
|
+
marginTop += preparedTitle.height + preparedTitle.margin;
|
|
8
8
|
}
|
|
9
9
|
return marginTop;
|
|
10
10
|
};
|
|
@@ -22,6 +22,7 @@ export declare function getNormalizedXAxis(props: {
|
|
|
22
22
|
maxPadding?: number;
|
|
23
23
|
plotLines?: import("../../../types").AxisPlotLine[];
|
|
24
24
|
plotBands?: import("../../../types").AxisPlotBand[];
|
|
25
|
+
plotShapes?: import("../../../types").AxisPlotShape[];
|
|
25
26
|
tickMarks?: import("../../../types").ChartAxisTickMarks;
|
|
26
27
|
visible?: boolean;
|
|
27
28
|
order?: "sortAsc" | "sortDesc" | "reverse";
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { PreparedTitle } from '../../../hooks/types';
|
|
2
|
-
import type { ChartData } from '../../../types';
|
|
3
|
-
export declare const getPreparedTitle: ({ title, }: {
|
|
2
|
+
import type { ChartData, ChartMargin } from '../../../types';
|
|
3
|
+
export declare const getPreparedTitle: ({ title, chartWidth, chartMargin, }: {
|
|
4
4
|
title: ChartData["title"];
|
|
5
|
+
chartWidth: number;
|
|
6
|
+
chartMargin?: Partial<ChartMargin>;
|
|
5
7
|
}) => Promise<PreparedTitle | undefined>;
|