@gravity-ui/charts 1.46.1 → 1.48.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/dist/cjs/components/AxisX/prepare-axis-data.js +9 -6
- package/dist/cjs/components/AxisY/prepare-axis-data.js +11 -4
- package/dist/cjs/components/ChartInner/index.js +1 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +12 -5
- package/dist/cjs/core/axes/types.d.ts +4 -2
- package/dist/cjs/core/axes/x-axis.js +2 -0
- package/dist/cjs/core/axes/y-axis.js +2 -0
- package/dist/cjs/core/brush/index.d.ts +2 -0
- package/dist/cjs/core/brush/index.js +2 -0
- package/dist/cjs/{hooks/useBrush → core/brush}/types.d.ts +2 -2
- package/dist/{esm/hooks/useBrush → cjs/core/brush}/utils.d.ts +1 -1
- package/dist/cjs/core/chart/index.d.ts +1 -0
- package/dist/cjs/core/chart/index.js +1 -0
- package/dist/cjs/core/chart/types.d.ts +8 -0
- package/dist/cjs/core/index.d.ts +3 -0
- package/dist/cjs/core/index.js +3 -0
- package/dist/cjs/core/layout/chart-dimensions.d.ts +1 -1
- package/dist/cjs/core/range-slider/index.d.ts +2 -0
- package/dist/cjs/core/range-slider/index.js +2 -0
- package/dist/cjs/core/range-slider/types.d.ts +4 -0
- package/dist/cjs/{hooks/useRangeSlider → core/range-slider}/utils.d.ts +5 -5
- package/dist/cjs/{hooks/useRangeSlider → core/range-slider}/utils.js +1 -1
- package/dist/cjs/core/scales/x-scale.d.ts +2 -2
- package/dist/cjs/core/scales/y-scale.js +21 -0
- package/dist/cjs/core/series/prepare-legend.d.ts +1 -1
- package/dist/cjs/core/series/prepare-scatter.js +11 -3
- package/dist/cjs/core/series/types.d.ts +8 -0
- package/dist/cjs/core/shapes/area/prepare-data.js +8 -50
- package/dist/cjs/core/shapes/area/renderer.js +8 -14
- package/dist/cjs/core/shapes/area/types.d.ts +6 -5
- package/dist/cjs/core/shapes/bar-x/prepare-data.js +49 -35
- package/dist/cjs/core/shapes/bar-x/renderer.js +6 -12
- package/dist/cjs/core/shapes/bar-y/renderer.js +6 -12
- package/dist/cjs/core/shapes/data-labels.d.ts +15 -0
- package/dist/cjs/core/shapes/data-labels.js +15 -0
- package/dist/cjs/core/shapes/funnel/renderer.js +6 -11
- package/dist/cjs/core/shapes/heatmap/prepare-data.js +1 -0
- package/dist/cjs/core/shapes/heatmap/renderer.js +6 -11
- package/dist/cjs/core/shapes/heatmap/types.d.ts +1 -0
- package/dist/cjs/core/shapes/line/prepare-data.js +22 -59
- package/dist/cjs/core/shapes/line/renderer.js +7 -13
- package/dist/cjs/core/shapes/line/types.d.ts +5 -4
- package/dist/cjs/core/shapes/radar/renderer.js +8 -12
- package/dist/cjs/core/shapes/sankey/renderer.js +6 -12
- package/dist/cjs/core/shapes/scatter/prepare-data.d.ts +5 -2
- package/dist/cjs/core/shapes/scatter/prepare-data.js +43 -4
- package/dist/cjs/core/shapes/scatter/renderer.d.ts +2 -2
- package/dist/cjs/core/shapes/scatter/renderer.js +9 -1
- package/dist/cjs/core/shapes/scatter/types.d.ts +6 -1
- package/dist/cjs/core/shapes/utils.d.ts +24 -0
- package/dist/cjs/core/shapes/utils.js +48 -0
- package/dist/cjs/core/shapes/waterfall/renderer.js +6 -12
- package/dist/cjs/core/shapes/x-range/renderer.js +7 -13
- package/dist/cjs/core/types/chart/axis.d.ts +20 -0
- package/dist/cjs/core/types/chart/base.d.ts +17 -3
- package/dist/cjs/core/types/chart/scatter.d.ts +2 -0
- package/dist/cjs/core/types/chart/tooltip.d.ts +3 -3
- package/dist/cjs/core/types/formatter.d.ts +1 -40
- package/dist/cjs/core/utils/data-labels.d.ts +46 -0
- package/dist/cjs/core/utils/data-labels.js +64 -0
- package/dist/cjs/core/utils/format.d.ts +2 -2
- package/dist/cjs/core/utils/get-closest-data.js +13 -8
- package/dist/cjs/core/utils/index.d.ts +1 -0
- package/dist/cjs/core/utils/index.js +1 -0
- package/dist/cjs/core/zoom/index.d.ts +2 -0
- package/dist/cjs/core/zoom/index.js +2 -0
- package/dist/{esm/hooks/useZoom → cjs/core/zoom}/utils.d.ts +3 -3
- package/dist/{esm/hooks/useZoom → cjs/core/zoom}/utils.js +1 -1
- package/dist/cjs/core/zoom/zoom.d.ts +3 -3
- package/dist/cjs/hooks/index.d.ts +2 -2
- package/dist/cjs/hooks/index.js +2 -2
- package/dist/cjs/hooks/types.d.ts +2 -8
- package/dist/cjs/hooks/useBrush/index.d.ts +1 -1
- package/dist/cjs/hooks/useBrush/index.js +1 -1
- package/dist/cjs/hooks/useRangeSlider/index.js +3 -3
- package/dist/cjs/hooks/useRangeSlider/types.d.ts +5 -7
- package/dist/cjs/hooks/useShapes/index.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/index.js +5 -3
- package/dist/cjs/hooks/useShapes/scatter/index.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/scatter/index.js +4 -1
- package/dist/cjs/hooks/useShapes/styles.css +8 -25
- package/dist/cjs/hooks/useShapes/utils.d.ts +1 -1
- package/dist/cjs/hooks/useZoom/index.d.ts +1 -1
- package/dist/cjs/hooks/useZoom/index.js +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/libs/format-number/index.js +82 -14
- package/dist/cjs/libs/format-number/presets.d.ts +40 -0
- package/dist/cjs/libs/format-number/presets.js +66 -0
- package/dist/cjs/libs/format-number/types.d.ts +82 -3
- package/dist/esm/components/AxisX/prepare-axis-data.js +9 -6
- package/dist/esm/components/AxisY/prepare-axis-data.js +11 -4
- package/dist/esm/components/ChartInner/index.js +1 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +12 -5
- package/dist/esm/core/axes/types.d.ts +4 -2
- package/dist/esm/core/axes/x-axis.js +2 -0
- package/dist/esm/core/axes/y-axis.js +2 -0
- package/dist/esm/core/brush/index.d.ts +2 -0
- package/dist/esm/core/brush/index.js +2 -0
- package/dist/esm/{hooks/useBrush → core/brush}/types.d.ts +2 -2
- package/dist/esm/core/brush/types.js +1 -0
- package/dist/{cjs/hooks/useBrush → esm/core/brush}/utils.d.ts +1 -1
- package/dist/esm/core/chart/index.d.ts +1 -0
- package/dist/esm/core/chart/index.js +1 -0
- package/dist/esm/core/chart/types.d.ts +8 -0
- package/dist/esm/core/chart/types.js +1 -0
- package/dist/esm/core/index.d.ts +3 -0
- package/dist/esm/core/index.js +3 -0
- package/dist/esm/core/layout/chart-dimensions.d.ts +1 -1
- package/dist/esm/core/range-slider/index.d.ts +2 -0
- package/dist/esm/core/range-slider/index.js +2 -0
- package/dist/esm/core/range-slider/types.d.ts +4 -0
- package/dist/esm/core/range-slider/types.js +1 -0
- package/dist/esm/{hooks/useRangeSlider → core/range-slider}/utils.d.ts +5 -5
- package/dist/esm/{hooks/useRangeSlider → core/range-slider}/utils.js +1 -1
- package/dist/esm/core/scales/x-scale.d.ts +2 -2
- package/dist/esm/core/scales/y-scale.js +21 -0
- package/dist/esm/core/series/prepare-legend.d.ts +1 -1
- package/dist/esm/core/series/prepare-scatter.js +11 -3
- package/dist/esm/core/series/types.d.ts +8 -0
- package/dist/esm/core/shapes/area/prepare-data.js +8 -50
- package/dist/esm/core/shapes/area/renderer.js +8 -14
- package/dist/esm/core/shapes/area/types.d.ts +6 -5
- package/dist/esm/core/shapes/bar-x/prepare-data.js +49 -35
- package/dist/esm/core/shapes/bar-x/renderer.js +6 -12
- package/dist/esm/core/shapes/bar-y/renderer.js +6 -12
- package/dist/esm/core/shapes/data-labels.d.ts +15 -0
- package/dist/esm/core/shapes/data-labels.js +15 -0
- package/dist/esm/core/shapes/funnel/renderer.js +6 -11
- package/dist/esm/core/shapes/heatmap/prepare-data.js +1 -0
- package/dist/esm/core/shapes/heatmap/renderer.js +6 -11
- package/dist/esm/core/shapes/heatmap/types.d.ts +1 -0
- package/dist/esm/core/shapes/line/prepare-data.js +22 -59
- package/dist/esm/core/shapes/line/renderer.js +7 -13
- package/dist/esm/core/shapes/line/types.d.ts +5 -4
- package/dist/esm/core/shapes/radar/renderer.js +8 -12
- package/dist/esm/core/shapes/sankey/renderer.js +6 -12
- package/dist/esm/core/shapes/scatter/prepare-data.d.ts +5 -2
- package/dist/esm/core/shapes/scatter/prepare-data.js +43 -4
- package/dist/esm/core/shapes/scatter/renderer.d.ts +2 -2
- package/dist/esm/core/shapes/scatter/renderer.js +9 -1
- package/dist/esm/core/shapes/scatter/types.d.ts +6 -1
- package/dist/esm/core/shapes/utils.d.ts +24 -0
- package/dist/esm/core/shapes/utils.js +48 -0
- package/dist/esm/core/shapes/waterfall/renderer.js +6 -12
- package/dist/esm/core/shapes/x-range/renderer.js +7 -13
- package/dist/esm/core/types/chart/axis.d.ts +20 -0
- package/dist/esm/core/types/chart/base.d.ts +17 -3
- package/dist/esm/core/types/chart/scatter.d.ts +2 -0
- package/dist/esm/core/types/chart/tooltip.d.ts +3 -3
- package/dist/esm/core/types/formatter.d.ts +1 -40
- package/dist/esm/core/utils/data-labels.d.ts +46 -0
- package/dist/esm/core/utils/data-labels.js +64 -0
- package/dist/esm/core/utils/format.d.ts +2 -2
- package/dist/esm/core/utils/get-closest-data.js +13 -8
- package/dist/esm/core/utils/index.d.ts +1 -0
- package/dist/esm/core/utils/index.js +1 -0
- package/dist/esm/core/zoom/index.d.ts +2 -0
- package/dist/esm/core/zoom/index.js +2 -0
- package/dist/esm/core/zoom/types.js +1 -0
- package/dist/{cjs/hooks/useZoom → esm/core/zoom}/utils.d.ts +3 -3
- package/dist/{cjs/hooks/useZoom → esm/core/zoom}/utils.js +1 -1
- package/dist/esm/core/zoom/zoom.d.ts +3 -3
- package/dist/esm/hooks/index.d.ts +2 -2
- package/dist/esm/hooks/index.js +2 -2
- package/dist/esm/hooks/types.d.ts +2 -8
- package/dist/esm/hooks/useBrush/index.d.ts +1 -1
- package/dist/esm/hooks/useBrush/index.js +1 -1
- package/dist/esm/hooks/useRangeSlider/index.js +3 -3
- package/dist/esm/hooks/useRangeSlider/types.d.ts +5 -7
- package/dist/esm/hooks/useShapes/index.d.ts +1 -1
- package/dist/esm/hooks/useShapes/index.js +5 -3
- package/dist/esm/hooks/useShapes/scatter/index.d.ts +2 -2
- package/dist/esm/hooks/useShapes/scatter/index.js +4 -1
- package/dist/esm/hooks/useShapes/styles.css +8 -25
- package/dist/esm/hooks/useShapes/utils.d.ts +1 -1
- package/dist/esm/hooks/useZoom/index.d.ts +1 -1
- package/dist/esm/hooks/useZoom/index.js +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/libs/format-number/index.js +82 -14
- package/dist/esm/libs/format-number/presets.d.ts +40 -0
- package/dist/esm/libs/format-number/presets.js +66 -0
- package/dist/esm/libs/format-number/types.d.ts +82 -3
- package/package.json +1 -1
- /package/dist/cjs/{hooks/useBrush → core/brush}/types.js +0 -0
- /package/dist/cjs/{hooks/useBrush → core/brush}/utils.js +0 -0
- /package/dist/cjs/{hooks/useZoom → core/chart}/types.js +0 -0
- /package/dist/{esm/hooks/useBrush → cjs/core/range-slider}/types.js +0 -0
- /package/dist/cjs/{hooks/useZoom → core/zoom}/types.d.ts +0 -0
- /package/dist/{esm/hooks/useZoom → cjs/core/zoom}/types.js +0 -0
- /package/dist/esm/{hooks/useBrush → core/brush}/utils.js +0 -0
- /package/dist/esm/{hooks/useZoom → core/zoom}/types.d.ts +0 -0
|
@@ -2,6 +2,7 @@ import { color } from 'd3-color';
|
|
|
2
2
|
import { select } from 'd3-selection';
|
|
3
3
|
import { block } from '../../../utils';
|
|
4
4
|
import { getLineDashArray } from '../../utils';
|
|
5
|
+
import { renderDataLabels } from '../data-labels';
|
|
5
6
|
const b = block('funnel');
|
|
6
7
|
export function renderFunnel(elements, preparedData, seriesOptions, dispatcher) {
|
|
7
8
|
var _a, _b;
|
|
@@ -44,17 +45,11 @@ export function renderFunnel(elements, preparedData, seriesOptions, dispatcher)
|
|
|
44
45
|
connectorLines.append('path').attr('d', (d) => d.linePath[0].toString());
|
|
45
46
|
connectorLines.append('path').attr('d', (d) => d.linePath[1].toString());
|
|
46
47
|
// dataLabels
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
.attr('class', b('label'))
|
|
53
|
-
.attr('x', (d) => d.x)
|
|
54
|
-
.attr('y', (d) => d.y)
|
|
55
|
-
.style('font-size', (d) => d.style.fontSize)
|
|
56
|
-
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
57
|
-
.style('fill', (d) => d.style.fontColor || null);
|
|
48
|
+
renderDataLabels({
|
|
49
|
+
container: svgElement,
|
|
50
|
+
data: preparedData.svgLabels,
|
|
51
|
+
className: b('label'),
|
|
52
|
+
});
|
|
58
53
|
function handleShapeHover(data) {
|
|
59
54
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
60
55
|
if (hoverEnabled) {
|
|
@@ -84,6 +84,7 @@ export async function prepareHeatmapData({ series, xAxis, xScale, yAxis, yScale,
|
|
|
84
84
|
x: item.x + item.width / 2 - size.width / 2,
|
|
85
85
|
y: item.y + item.height / 2 - size.height / 2 + size.hangingOffset,
|
|
86
86
|
text,
|
|
87
|
+
textAnchor: 'start',
|
|
87
88
|
style: series.dataLabels.style,
|
|
88
89
|
});
|
|
89
90
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { color } from 'd3-color';
|
|
2
2
|
import { select } from 'd3-selection';
|
|
3
3
|
import { block } from '../../../utils';
|
|
4
|
+
import { renderDataLabels } from '../data-labels';
|
|
4
5
|
const b = block('heatmap');
|
|
5
6
|
export function renderHeatmap(elements, preparedData, seriesOptions, dispatcher) {
|
|
6
7
|
var _a, _b;
|
|
@@ -20,17 +21,11 @@ export function renderHeatmap(elements, preparedData, seriesOptions, dispatcher)
|
|
|
20
21
|
.attr('stroke', (d) => d.borderColor)
|
|
21
22
|
.attr('stroke-width', (d) => d.borderWidth);
|
|
22
23
|
// dataLabels
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.attr('class', b('label'))
|
|
29
|
-
.attr('x', (d) => d.x)
|
|
30
|
-
.attr('y', (d) => d.y)
|
|
31
|
-
.style('font-size', (d) => d.style.fontSize)
|
|
32
|
-
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
33
|
-
.style('fill', (d) => d.style.fontColor || null);
|
|
24
|
+
renderDataLabels({
|
|
25
|
+
container: svgElement,
|
|
26
|
+
data: preparedData.labels,
|
|
27
|
+
className: b('label'),
|
|
28
|
+
});
|
|
34
29
|
function handleShapeHover(data) {
|
|
35
30
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
36
31
|
if (hoverEnabled) {
|
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
import { prepareAnnotation } from '../../series/prepare-annotation';
|
|
2
|
-
import { filterOverlappingLabels,
|
|
3
|
-
import {
|
|
4
|
-
import { getXValue, getYValue } from '../utils';
|
|
5
|
-
async function getHtmlLabel(point, series, xMax) {
|
|
6
|
-
var _a;
|
|
7
|
-
const content = String((_a = point.data.label) !== null && _a !== void 0 ? _a : point.data.y);
|
|
8
|
-
const size = await getLabelsSize({ labels: [content], html: true });
|
|
9
|
-
const width = size.maxWidth;
|
|
10
|
-
return {
|
|
11
|
-
x: Math.min(xMax - size.maxWidth, Math.max(0, point.x - width / 2)),
|
|
12
|
-
y: Math.max(0, point.y - series.dataLabels.padding - size.maxHeight),
|
|
13
|
-
content,
|
|
14
|
-
size: { width, height: size.maxHeight },
|
|
15
|
-
style: series.dataLabels.style,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
2
|
+
import { filterOverlappingLabels, preparePointDataLabels } from '../../utils';
|
|
3
|
+
import { getXValue, getYValue, markHiddenPointsOutOfYRange } from '../utils';
|
|
18
4
|
export const prepareLineData = async (args) => {
|
|
19
|
-
var _a, _b, _c, _d, _e, _f
|
|
5
|
+
var _a, _b, _c, _d, _e, _f;
|
|
20
6
|
const { series, seriesOptions, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider, otherLayers, } = args;
|
|
21
7
|
const [_xMin, xRangeMax] = xScale.range();
|
|
22
8
|
const xMax = xRangeMax;
|
|
@@ -58,46 +44,15 @@ export const prepareLineData = async (args) => {
|
|
|
58
44
|
let htmlElements = [];
|
|
59
45
|
let svgLabels = [];
|
|
60
46
|
if (s.dataLabels.enabled && !isRangeSlider) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
const getTextSize = getTextSizeFn({ style: s.dataLabels.style });
|
|
73
|
-
for (let index = 0; index < points.length; index++) {
|
|
74
|
-
const point = points[index];
|
|
75
|
-
if (point.y !== null &&
|
|
76
|
-
point.x !== null &&
|
|
77
|
-
!isOutsideBounds(point.x, point.y)) {
|
|
78
|
-
const labelValue = (_e = point.data.label) !== null && _e !== void 0 ? _e : point.data.y;
|
|
79
|
-
const text = getFormattedValue(Object.assign({ value: labelValue }, s.dataLabels));
|
|
80
|
-
const labelSize = await getTextSize(text);
|
|
81
|
-
const style = s.dataLabels.style;
|
|
82
|
-
const y = Math.max(yAxisTop, point.y -
|
|
83
|
-
s.dataLabels.padding -
|
|
84
|
-
labelSize.height +
|
|
85
|
-
labelSize.hangingOffset);
|
|
86
|
-
const x = Math.min(xMax - labelSize.width, Math.max(0, point.x - labelSize.width / 2));
|
|
87
|
-
const labelData = {
|
|
88
|
-
text,
|
|
89
|
-
x,
|
|
90
|
-
y,
|
|
91
|
-
style,
|
|
92
|
-
size: labelSize,
|
|
93
|
-
textAnchor: 'start',
|
|
94
|
-
series: s,
|
|
95
|
-
active: true,
|
|
96
|
-
};
|
|
97
|
-
svgLabels.push(labelData);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
47
|
+
const labelsData = await preparePointDataLabels({
|
|
48
|
+
series: s,
|
|
49
|
+
points,
|
|
50
|
+
xMax,
|
|
51
|
+
yAxisTop,
|
|
52
|
+
isOutsideBounds,
|
|
53
|
+
});
|
|
54
|
+
svgLabels = labelsData.svgLabels;
|
|
55
|
+
htmlElements = labelsData.htmlLabels;
|
|
101
56
|
}
|
|
102
57
|
if (!s.dataLabels.allowOverlap) {
|
|
103
58
|
svgLabels = filterOverlappingLabels(svgLabels, otherLayers.map((l) => l.svgLabels).flat());
|
|
@@ -129,6 +84,14 @@ export const prepareLineData = async (args) => {
|
|
|
129
84
|
}
|
|
130
85
|
return result;
|
|
131
86
|
}, []);
|
|
87
|
+
markHiddenPointsOutOfYRange({
|
|
88
|
+
points,
|
|
89
|
+
yScale: seriesYScale,
|
|
90
|
+
yAxisTop,
|
|
91
|
+
axisMin: seriesYAxis.min,
|
|
92
|
+
axisMax: seriesYAxis.max,
|
|
93
|
+
getDataY: (p) => p.data.y,
|
|
94
|
+
});
|
|
132
95
|
const result = {
|
|
133
96
|
annotations,
|
|
134
97
|
points,
|
|
@@ -140,11 +103,11 @@ export const prepareLineData = async (args) => {
|
|
|
140
103
|
id: s.id,
|
|
141
104
|
htmlLabels: htmlElements,
|
|
142
105
|
color: s.color,
|
|
143
|
-
lineWidth: (
|
|
106
|
+
lineWidth: (_e = (isRangeSlider ? s.rangeSlider.lineWidth : undefined)) !== null && _e !== void 0 ? _e : s.lineWidth,
|
|
144
107
|
dashStyle: s.dashStyle,
|
|
145
108
|
linecap: s.linecap,
|
|
146
109
|
linejoin: s.linejoin,
|
|
147
|
-
opacity: (
|
|
110
|
+
opacity: (_f = (isRangeSlider ? s.rangeSlider.opacity : undefined)) !== null && _f !== void 0 ? _f : s.opacity,
|
|
148
111
|
};
|
|
149
112
|
acc.push(result);
|
|
150
113
|
}
|
|
@@ -5,6 +5,7 @@ import get from 'lodash/get';
|
|
|
5
5
|
import { block } from '../../../utils';
|
|
6
6
|
import { getLineDashArray } from '../../utils';
|
|
7
7
|
import { renderAnnotations } from '../annotation';
|
|
8
|
+
import { renderDataLabels } from '../data-labels';
|
|
8
9
|
import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
|
|
9
10
|
import { setActiveState } from '../utils';
|
|
10
11
|
const b = block('line');
|
|
@@ -17,7 +18,7 @@ export function renderLine(elements, preparedData, seriesOptions, dispatcher) {
|
|
|
17
18
|
const hoverOptions = get(seriesOptions, 'line.states.hover');
|
|
18
19
|
const inactiveOptions = get(seriesOptions, 'line.states.inactive');
|
|
19
20
|
const line = lineGenerator()
|
|
20
|
-
.defined((d) => d.y !== null && d.x !== null)
|
|
21
|
+
.defined((d) => d.y !== null && d.x !== null && !d.hiddenInLine)
|
|
21
22
|
.x((d) => d.x)
|
|
22
23
|
.y((d) => d.y);
|
|
23
24
|
plotSvgElement.selectAll('*').remove();
|
|
@@ -38,18 +39,11 @@ export function renderLine(elements, preparedData, seriesOptions, dispatcher) {
|
|
|
38
39
|
const dataLabels = preparedData.reduce((acc, d) => {
|
|
39
40
|
return acc.concat(d.svgLabels);
|
|
40
41
|
}, []);
|
|
41
|
-
const labelsSelection =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.attr('class', b('label'))
|
|
47
|
-
.attr('x', (d) => d.x)
|
|
48
|
-
.attr('y', (d) => d.y)
|
|
49
|
-
.attr('text-anchor', (d) => d.textAnchor)
|
|
50
|
-
.style('font-size', (d) => d.style.fontSize)
|
|
51
|
-
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
52
|
-
.style('fill', (d) => d.style.fontColor || null);
|
|
42
|
+
const labelsSelection = renderDataLabels({
|
|
43
|
+
container: plotSvgElement,
|
|
44
|
+
data: dataLabels,
|
|
45
|
+
className: b('label'),
|
|
46
|
+
});
|
|
53
47
|
const markers = preparedData.reduce((acc, d) => acc.concat(d.markers), []);
|
|
54
48
|
const markerSelection = markersSvgElement
|
|
55
49
|
.selectAll('marker')
|
|
@@ -2,12 +2,13 @@ import type { HtmlItem, LabelData, LineSeriesData, LineSeriesLineBaseStyle } fro
|
|
|
2
2
|
import type { DashStyle, LineCap, LineJoin } from '../../constants';
|
|
3
3
|
import type { AnnotationAnchor, PreparedAnnotation, PreparedLineSeries } from '../../series/types';
|
|
4
4
|
export type PointData = {
|
|
5
|
-
x: number | null;
|
|
6
|
-
y: number | null;
|
|
7
|
-
data: LineSeriesData;
|
|
8
|
-
series: PreparedLineSeries;
|
|
9
5
|
annotation?: PreparedAnnotation;
|
|
10
6
|
color?: string;
|
|
7
|
+
data: LineSeriesData;
|
|
8
|
+
hiddenInLine?: boolean;
|
|
9
|
+
series: PreparedLineSeries;
|
|
10
|
+
x: number | null;
|
|
11
|
+
y: number | null;
|
|
11
12
|
};
|
|
12
13
|
export type MarkerPointData = PointData & {
|
|
13
14
|
y: number;
|
|
@@ -3,6 +3,7 @@ import { select } from 'd3-selection';
|
|
|
3
3
|
import { line } from 'd3-shape';
|
|
4
4
|
import get from 'lodash/get';
|
|
5
5
|
import { block } from '../../../utils';
|
|
6
|
+
import { renderDataLabels } from '../../shapes/data-labels';
|
|
6
7
|
import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../../shapes/marker';
|
|
7
8
|
import { setActiveState } from '../../shapes/utils';
|
|
8
9
|
const b = block('radar');
|
|
@@ -59,18 +60,13 @@ export function renderRadar(elements, preparedData, seriesOptions, dispatcher) {
|
|
|
59
60
|
.join('g')
|
|
60
61
|
.call(renderMarker);
|
|
61
62
|
// Render labels
|
|
62
|
-
radarSelection
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.attr('y', (d) => d.y)
|
|
70
|
-
.attr('text-anchor', (d) => d.textAnchor)
|
|
71
|
-
.style('font-size', (d) => d.style.fontSize)
|
|
72
|
-
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
73
|
-
.style('fill', (d) => d.style.fontColor || null);
|
|
63
|
+
radarSelection.each(function (radarData) {
|
|
64
|
+
renderDataLabels({
|
|
65
|
+
container: select(this),
|
|
66
|
+
data: radarData.labels,
|
|
67
|
+
className: b('label'),
|
|
68
|
+
});
|
|
69
|
+
});
|
|
74
70
|
// Handle hover events
|
|
75
71
|
const eventName = `hover-shape.radar`;
|
|
76
72
|
const hoverOptions = get(seriesOptions, 'radar.states.hover');
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { select } from 'd3-selection';
|
|
2
2
|
import { block } from '../../../utils';
|
|
3
|
+
import { renderDataLabels } from '../data-labels';
|
|
3
4
|
const b = block('sankey');
|
|
4
5
|
export function renderSankey(elements, preparedData, _seriesOptions, dispatcher) {
|
|
5
6
|
const svgElement = select(elements.plot);
|
|
@@ -28,18 +29,11 @@ export function renderSankey(elements, preparedData, _seriesOptions, dispatcher)
|
|
|
28
29
|
.attr('stroke', (d) => d.color)
|
|
29
30
|
.attr('stroke-width', (d) => d.strokeWidth);
|
|
30
31
|
// dataLabels
|
|
31
|
-
|
|
32
|
-
.append('g')
|
|
33
|
-
.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
.html((d) => d.text)
|
|
37
|
-
.attr('class', b('label'))
|
|
38
|
-
.attr('x', (d) => d.x)
|
|
39
|
-
.attr('y', (d) => d.y)
|
|
40
|
-
.attr('dy', '0.35em')
|
|
41
|
-
.attr('text-anchor', (d) => d.textAnchor)
|
|
42
|
-
.attr('fill', (d) => { var _a; return (_a = d.style.fontColor) !== null && _a !== void 0 ? _a : null; });
|
|
32
|
+
renderDataLabels({
|
|
33
|
+
container: svgElement.append('g'),
|
|
34
|
+
data: preparedData.labels,
|
|
35
|
+
className: b('label'),
|
|
36
|
+
}).attr('dy', '0.35em');
|
|
43
37
|
const eventName = `hover-shape.sankey`;
|
|
44
38
|
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on(eventName, (_data) => {
|
|
45
39
|
// no-op hover handler
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../axes/types';
|
|
2
|
+
import type { PreparedSplit } from '../../layout/split-types';
|
|
2
3
|
import type { ChartScale } from '../../scales/types';
|
|
3
4
|
import type { PreparedScatterSeries } from '../../series/types';
|
|
4
|
-
import type {
|
|
5
|
+
import type { PreparedScatterShapeData } from './types';
|
|
5
6
|
export declare function prepareScatterData(args: {
|
|
6
7
|
series: PreparedScatterSeries[];
|
|
7
8
|
xAxis: PreparedXAxis;
|
|
8
9
|
xScale: ChartScale;
|
|
9
10
|
yAxis: PreparedYAxis[];
|
|
10
11
|
yScale: (ChartScale | undefined)[];
|
|
12
|
+
split: PreparedSplit;
|
|
11
13
|
isOutsideBounds: (x: number, y: number) => boolean;
|
|
12
|
-
|
|
14
|
+
isRangeSlider?: boolean;
|
|
15
|
+
}): Promise<PreparedScatterShapeData>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import { getXValue, getYValue } from '../../shapes/utils';
|
|
3
|
-
import { getDataCategoryValue } from '../../utils';
|
|
3
|
+
import { filterOverlappingLabels, getDataCategoryValue, preparePointDataLabels } from '../../utils';
|
|
4
4
|
function getFilteredLinearScatterData(data) {
|
|
5
5
|
return data.filter((d) => typeof d.x === 'number' && typeof d.y === 'number');
|
|
6
6
|
}
|
|
@@ -32,9 +32,12 @@ function getFilteredCategoryScatterData(args) {
|
|
|
32
32
|
return xInRange && yInRange;
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
-
export function prepareScatterData(args) {
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
export async function prepareScatterData(args) {
|
|
36
|
+
var _a;
|
|
37
|
+
const { series, xAxis, xScale, yAxis, yScale, split, isOutsideBounds, isRangeSlider } = args;
|
|
38
|
+
const [_xMin, xRangeMax] = xScale.range();
|
|
39
|
+
const xMax = xRangeMax;
|
|
40
|
+
const markers = series.reduce((acc, s) => {
|
|
38
41
|
const yAxisIndex = get(s, 'yAxis', 0);
|
|
39
42
|
const seriesYAxis = yAxis[yAxisIndex];
|
|
40
43
|
const seriesYScale = yScale[yAxisIndex];
|
|
@@ -74,4 +77,40 @@ export function prepareScatterData(args) {
|
|
|
74
77
|
});
|
|
75
78
|
return acc;
|
|
76
79
|
}, []);
|
|
80
|
+
const allSvgLabels = [];
|
|
81
|
+
const allHtmlLabels = [];
|
|
82
|
+
if (!isRangeSlider) {
|
|
83
|
+
for (const s of series) {
|
|
84
|
+
if (!s.dataLabels.enabled) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const yAxisIndex = get(s, 'yAxis', 0);
|
|
88
|
+
const seriesYAxis = yAxis[yAxisIndex];
|
|
89
|
+
const seriesYScale = yScale[yAxisIndex];
|
|
90
|
+
if (!seriesYScale) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const yAxisTop = ((_a = split.plots[seriesYAxis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
|
|
94
|
+
const seriesPoints = markers
|
|
95
|
+
.filter((m) => m.point.series.id === s.id && !m.clipped)
|
|
96
|
+
.map((m) => m.point);
|
|
97
|
+
const { svgLabels, htmlLabels } = await preparePointDataLabels({
|
|
98
|
+
series: s,
|
|
99
|
+
points: seriesPoints,
|
|
100
|
+
xMax,
|
|
101
|
+
yAxisTop,
|
|
102
|
+
isOutsideBounds,
|
|
103
|
+
anchorYOffset: s.marker.states.normal.radius,
|
|
104
|
+
});
|
|
105
|
+
if (s.dataLabels.allowOverlap) {
|
|
106
|
+
allSvgLabels.push(...svgLabels);
|
|
107
|
+
allHtmlLabels.push(...htmlLabels);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
allSvgLabels.push(...filterOverlappingLabels(svgLabels, allSvgLabels));
|
|
111
|
+
allHtmlLabels.push(...filterOverlappingLabels(htmlLabels, allHtmlLabels));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { markers, svgLabels: allSvgLabels, htmlLabels: allHtmlLabels };
|
|
77
116
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Dispatch } from 'd3-dispatch';
|
|
2
2
|
import type { PreparedSeriesOptions } from '../../series/types';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PreparedScatterShapeData } from './types';
|
|
4
4
|
export declare function renderScatter(elements: {
|
|
5
5
|
plot: SVGGElement;
|
|
6
|
-
}, preparedData:
|
|
6
|
+
}, preparedData: PreparedScatterShapeData, seriesOptions: PreparedSeriesOptions, dispatcher?: Dispatch<object>): () => void;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { select } from 'd3-selection';
|
|
2
2
|
import get from 'lodash/get';
|
|
3
|
+
import { block } from '../../../utils';
|
|
3
4
|
import { getMarkerHaloVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../../shapes/marker';
|
|
4
5
|
import { setActiveState, shapeKey } from '../../shapes/utils';
|
|
6
|
+
import { renderDataLabels } from '../data-labels';
|
|
7
|
+
const b = block('scatter');
|
|
5
8
|
export function renderScatter(elements, preparedData, seriesOptions, dispatcher) {
|
|
6
9
|
const svgElement = select(elements.plot);
|
|
7
10
|
const hoverOptions = get(seriesOptions, 'scatter.states.hover');
|
|
@@ -9,11 +12,16 @@ export function renderScatter(elements, preparedData, seriesOptions, dispatcher)
|
|
|
9
12
|
svgElement.selectAll('*').remove();
|
|
10
13
|
const selection = svgElement
|
|
11
14
|
.selectAll('path')
|
|
12
|
-
.data(preparedData, shapeKey)
|
|
15
|
+
.data(preparedData.markers, shapeKey)
|
|
13
16
|
.join('g')
|
|
14
17
|
.call(renderMarker)
|
|
15
18
|
.attr('opacity', (d) => d.point.opacity)
|
|
16
19
|
.attr('cursor', (d) => d.point.series.cursor);
|
|
20
|
+
renderDataLabels({
|
|
21
|
+
container: svgElement,
|
|
22
|
+
data: preparedData.svgLabels,
|
|
23
|
+
className: b('label'),
|
|
24
|
+
});
|
|
17
25
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
18
26
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
19
27
|
function handleShapeHover(data) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HtmlItem, ScatterSeriesData } from '../../../types';
|
|
1
|
+
import type { HtmlItem, LabelData, ScatterSeriesData } from '../../../types';
|
|
2
2
|
import type { PreparedScatterSeries } from '../../series/types';
|
|
3
3
|
type PointData = {
|
|
4
4
|
x: number;
|
|
@@ -16,4 +16,9 @@ export type MarkerData = {
|
|
|
16
16
|
clipped: boolean;
|
|
17
17
|
};
|
|
18
18
|
export type PreparedScatterData = MarkerData;
|
|
19
|
+
export type PreparedScatterShapeData = {
|
|
20
|
+
markers: PreparedScatterData[];
|
|
21
|
+
svgLabels: LabelData[];
|
|
22
|
+
htmlLabels: HtmlItem[];
|
|
23
|
+
};
|
|
19
24
|
export {};
|
|
@@ -22,6 +22,30 @@ export declare function getYValue(args: {
|
|
|
22
22
|
yAxis: PreparedYAxis;
|
|
23
23
|
yScale: ChartScale;
|
|
24
24
|
}): number | null;
|
|
25
|
+
/**
|
|
26
|
+
* Hides out-of-range points from line/area path generators via `hiddenInLine`.
|
|
27
|
+
* Neighbors of in-range points are kept as anchors so the path retains its
|
|
28
|
+
* slope at the plot edges instead of stopping abruptly at the visible point.
|
|
29
|
+
*
|
|
30
|
+
* Pixel check alone is not enough: a degenerate/clamped scale domain (see the
|
|
31
|
+
* y-scale.ts guard) can map out-of-range data into the plot rectangle, leaving
|
|
32
|
+
* phantom hover targets. Pass `axisMin`/`axisMax` + `getDataY` to also reject
|
|
33
|
+
* points whose raw value is outside the user's intended range.
|
|
34
|
+
*
|
|
35
|
+
* Stacked shapes must NOT pass the data check — `point.data.y` is the unstacked
|
|
36
|
+
* value and doesn't reflect where the point actually lands on the plot.
|
|
37
|
+
*/
|
|
38
|
+
export declare function markHiddenPointsOutOfYRange<P extends {
|
|
39
|
+
y: number | null;
|
|
40
|
+
hiddenInLine?: boolean;
|
|
41
|
+
}>(args: {
|
|
42
|
+
points: P[];
|
|
43
|
+
yScale: ChartScale;
|
|
44
|
+
yAxisTop: number;
|
|
45
|
+
axisMin?: number;
|
|
46
|
+
axisMax?: number;
|
|
47
|
+
getDataY?: (point: P) => unknown;
|
|
48
|
+
}): void;
|
|
25
49
|
export declare function shapeKey(d: unknown): string | number;
|
|
26
50
|
export declare function setActiveState<T extends {
|
|
27
51
|
active?: boolean;
|
|
@@ -53,6 +53,54 @@ export function getYValue(args) {
|
|
|
53
53
|
}
|
|
54
54
|
return point.y === null ? null : yLinearScale(point.y);
|
|
55
55
|
}
|
|
56
|
+
// Slack for d3 scale rounding (a `500` edge can come back as `499.9999`).
|
|
57
|
+
// Half a pixel matches the ±0.5 of a 1px centered stroke and far exceeds any
|
|
58
|
+
// plausible float error.
|
|
59
|
+
const Y_RANGE_PIXEL_TOLERANCE = 0.5;
|
|
60
|
+
/**
|
|
61
|
+
* Hides out-of-range points from line/area path generators via `hiddenInLine`.
|
|
62
|
+
* Neighbors of in-range points are kept as anchors so the path retains its
|
|
63
|
+
* slope at the plot edges instead of stopping abruptly at the visible point.
|
|
64
|
+
*
|
|
65
|
+
* Pixel check alone is not enough: a degenerate/clamped scale domain (see the
|
|
66
|
+
* y-scale.ts guard) can map out-of-range data into the plot rectangle, leaving
|
|
67
|
+
* phantom hover targets. Pass `axisMin`/`axisMax` + `getDataY` to also reject
|
|
68
|
+
* points whose raw value is outside the user's intended range.
|
|
69
|
+
*
|
|
70
|
+
* Stacked shapes must NOT pass the data check — `point.data.y` is the unstacked
|
|
71
|
+
* value and doesn't reflect where the point actually lands on the plot.
|
|
72
|
+
*/
|
|
73
|
+
export function markHiddenPointsOutOfYRange(args) {
|
|
74
|
+
const { points, yScale, yAxisTop, axisMin, axisMax, getDataY } = args;
|
|
75
|
+
const [yRangeA, yRangeB] = yScale.range();
|
|
76
|
+
const yMinPx = yAxisTop + Math.min(yRangeA, yRangeB);
|
|
77
|
+
const yMaxPx = yAxisTop + Math.max(yRangeA, yRangeB);
|
|
78
|
+
const hasDataBoundsCheck = Boolean(getDataY) && (typeof axisMin === 'number' || typeof axisMax === 'number');
|
|
79
|
+
const isInRange = (point) => {
|
|
80
|
+
if (point.y === null) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
if (hasDataBoundsCheck) {
|
|
84
|
+
const dataY = getDataY === null || getDataY === void 0 ? void 0 : getDataY(point);
|
|
85
|
+
if (typeof dataY === 'number') {
|
|
86
|
+
if (typeof axisMin === 'number' && dataY < axisMin) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (typeof axisMax === 'number' && dataY > axisMax) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return (point.y >= yMinPx - Y_RANGE_PIXEL_TOLERANCE &&
|
|
95
|
+
point.y <= yMaxPx + Y_RANGE_PIXEL_TOLERANCE);
|
|
96
|
+
};
|
|
97
|
+
const inRange = points.map(isInRange);
|
|
98
|
+
for (let idx = 0; idx < points.length; idx++) {
|
|
99
|
+
if (!inRange[idx] && !inRange[idx - 1] && !inRange[idx + 1]) {
|
|
100
|
+
points[idx].hiddenInLine = true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
56
104
|
export function shapeKey(d) {
|
|
57
105
|
return d.id || -1;
|
|
58
106
|
}
|
|
@@ -5,6 +5,7 @@ import get from 'lodash/get';
|
|
|
5
5
|
import { block } from '../../../utils';
|
|
6
6
|
import { DASH_STYLE } from '../../constants';
|
|
7
7
|
import { filterOverlappingLabels, getLineDashArray, getWaterfallPointColor } from '../../utils';
|
|
8
|
+
import { renderDataLabels } from '../data-labels';
|
|
8
9
|
const b = block('waterfall');
|
|
9
10
|
export function renderWaterfall(elements, preparedData, seriesOptions, allowOverlapDataLabels, dispatcher) {
|
|
10
11
|
const svgElement = select(elements.plot);
|
|
@@ -28,18 +29,11 @@ export function renderWaterfall(elements, preparedData, seriesOptions, allowOver
|
|
|
28
29
|
if (!allowOverlapDataLabels) {
|
|
29
30
|
dataLabels = filterOverlappingLabels(dataLabels);
|
|
30
31
|
}
|
|
31
|
-
const labelSelection =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
.attr('class', b('label'))
|
|
37
|
-
.attr('x', (d) => d.x)
|
|
38
|
-
.attr('y', (d) => d.y)
|
|
39
|
-
.attr('text-anchor', (d) => d.textAnchor)
|
|
40
|
-
.style('font-size', (d) => d.style.fontSize)
|
|
41
|
-
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
42
|
-
.style('fill', (d) => d.style.fontColor || null);
|
|
32
|
+
const labelSelection = renderDataLabels({
|
|
33
|
+
container: svgElement,
|
|
34
|
+
data: dataLabels,
|
|
35
|
+
className: b('label'),
|
|
36
|
+
});
|
|
43
37
|
// Add the connector line between bars
|
|
44
38
|
svgElement
|
|
45
39
|
.selectAll(connectorSelector)
|
|
@@ -4,6 +4,7 @@ import get from 'lodash/get';
|
|
|
4
4
|
import { block } from '../../../utils';
|
|
5
5
|
import { getRectPath } from '../../shapes/utils';
|
|
6
6
|
import { getLineDashArray } from '../../utils';
|
|
7
|
+
import { renderDataLabels } from '../data-labels';
|
|
7
8
|
const b = block('x-range');
|
|
8
9
|
export function renderXRange(elements, preparedData, seriesOptions, dispatcher) {
|
|
9
10
|
const svgElement = select(elements.plot);
|
|
@@ -48,20 +49,13 @@ export function renderXRange(elements, preparedData, seriesOptions, dispatcher)
|
|
|
48
49
|
.attr('opacity', (d) => { var _a; return (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity; })
|
|
49
50
|
.attr('pointer-events', 'none');
|
|
50
51
|
const svgLabels = preparedData.flatMap((d) => d.svgLabels);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.attr('x', (d) => d.x)
|
|
57
|
-
.attr('y', (d) => d.y)
|
|
58
|
-
.attr('text-anchor', (d) => d.textAnchor)
|
|
52
|
+
renderDataLabels({
|
|
53
|
+
container: svgElement,
|
|
54
|
+
data: svgLabels,
|
|
55
|
+
className: b('label'),
|
|
56
|
+
})
|
|
59
57
|
.attr('dominant-baseline', 'central')
|
|
60
|
-
.attr('pointer-events', 'none')
|
|
61
|
-
.style('font-size', (d) => d.style.fontSize)
|
|
62
|
-
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
63
|
-
.style('fill', (d) => d.style.fontColor || null)
|
|
64
|
-
.html((d) => d.text);
|
|
58
|
+
.attr('pointer-events', 'none');
|
|
65
59
|
const hoverOptions = get(seriesOptions, 'x-range.states.hover');
|
|
66
60
|
const inactiveOptions = get(seriesOptions, 'x-range.states.inactive');
|
|
67
61
|
function handleShapeHover(data) {
|
|
@@ -317,6 +317,7 @@ export interface AxisPlotShape extends AxisPlot {
|
|
|
317
317
|
plotHeight: number;
|
|
318
318
|
}) => string;
|
|
319
319
|
}
|
|
320
|
+
export type PlotBandAlign = 'start' | 'end';
|
|
320
321
|
export interface AxisPlotBand extends AxisPlot {
|
|
321
322
|
/**
|
|
322
323
|
* The start position of the plot band in axis units.
|
|
@@ -336,6 +337,25 @@ export interface AxisPlotBand extends AxisPlot {
|
|
|
336
337
|
* If the value is `Infinity` or `null`, it will be treated as the end of the axis.
|
|
337
338
|
*/
|
|
338
339
|
to: number | string | null;
|
|
340
|
+
/**
|
|
341
|
+
* Anchor side on the perpendicular axis when `size` is set.
|
|
342
|
+
*
|
|
343
|
+
* - `'start'` — the band sticks to the main axis line (bottom for an X axis,
|
|
344
|
+
* left for a left Y axis, right for a right Y axis).
|
|
345
|
+
* - `'end'` — the band sticks to the opposite side of the plot area.
|
|
346
|
+
*
|
|
347
|
+
* Has no effect without `size`.
|
|
348
|
+
* @default 'start'
|
|
349
|
+
*/
|
|
350
|
+
align?: PlotBandAlign;
|
|
351
|
+
/**
|
|
352
|
+
* Perpendicular extent of the band.
|
|
353
|
+
*
|
|
354
|
+
* Accepts a pixel number (`40`), a pixel string (`"40px"`), or a percentage of
|
|
355
|
+
* the perpendicular plot extent (`"25%"`). When omitted, the band spans the
|
|
356
|
+
* full perpendicular extent of the plot area (default behavior).
|
|
357
|
+
*/
|
|
358
|
+
size?: number | string;
|
|
339
359
|
}
|
|
340
360
|
export interface AxisCrosshair extends Pick<AxisPlotLine, 'color' | 'dashStyle' | 'opacity' | 'layerPlacement' | 'width'> {
|
|
341
361
|
/**
|