@gravity-ui/charts 1.43.1 → 1.45.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/ChartInner/utils/zoom.js +3 -1
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +31 -6
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.js +4 -5
- package/dist/cjs/core/constants/chart-types.d.ts +1 -0
- package/dist/cjs/core/constants/chart-types.js +1 -0
- package/dist/cjs/core/constants/defaults/annotation.d.ts +12 -0
- package/dist/cjs/core/constants/defaults/annotation.js +12 -0
- package/dist/cjs/core/constants/defaults/index.d.ts +1 -0
- package/dist/cjs/core/constants/defaults/index.js +1 -0
- package/dist/cjs/core/constants/defaults/series-options.d.ts +5 -1
- package/dist/cjs/core/constants/defaults/series-options.js +13 -0
- package/dist/cjs/core/i18n/keysets/en.json +2 -1
- package/dist/cjs/core/i18n/keysets/ru.json +2 -1
- package/dist/cjs/core/series/constants.d.ts +1 -1
- package/dist/cjs/core/series/constants.js +1 -1
- package/dist/cjs/core/series/prepare-annotation.d.ts +12 -0
- package/dist/cjs/core/series/prepare-annotation.js +31 -0
- package/dist/cjs/core/series/prepare-legend.js +2 -2
- package/dist/cjs/core/series/prepare-x-range.d.ts +11 -0
- package/dist/cjs/core/series/prepare-x-range.js +41 -0
- package/dist/cjs/core/series/prepareSeries.js +9 -0
- package/dist/cjs/core/series/types.d.ts +34 -2
- package/dist/cjs/core/types/chart/annotation.d.ts +45 -0
- package/dist/cjs/core/types/chart/annotation.js +1 -0
- package/dist/cjs/core/types/chart/area.d.ts +10 -1
- package/dist/cjs/core/types/chart/bar-x.d.ts +6 -0
- package/dist/cjs/core/types/chart/line.d.ts +8 -0
- package/dist/cjs/core/types/chart/marker.d.ts +6 -4
- package/dist/cjs/core/types/chart/series.d.ts +36 -2
- package/dist/cjs/core/types/chart/tooltip.d.ts +7 -1
- package/dist/cjs/core/types/chart/x-range.d.ts +59 -0
- package/dist/cjs/core/types/chart/x-range.js +1 -0
- package/dist/cjs/core/types/chart/zoom.d.ts +1 -1
- package/dist/cjs/core/types/index.d.ts +2 -0
- package/dist/cjs/core/types/index.js +2 -0
- package/dist/cjs/core/utils/axis/x-axis.js +9 -1
- package/dist/cjs/core/utils/color.js +6 -0
- package/dist/cjs/core/utils/common.js +10 -0
- package/dist/cjs/core/utils/get-closest-data.js +19 -0
- package/dist/cjs/core/utils/text.d.ts +8 -0
- package/dist/cjs/core/utils/text.js +9 -1
- package/dist/cjs/core/validation/index.js +13 -0
- package/dist/cjs/core/zoom/zoom.js +24 -7
- package/dist/cjs/hooks/useShapes/annotation/index.d.ts +14 -0
- package/dist/cjs/hooks/useShapes/annotation/index.js +200 -0
- package/dist/cjs/hooks/useShapes/area/index.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/area/index.js +21 -2
- package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +2 -1
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +45 -26
- package/dist/cjs/hooks/useShapes/area/types.d.ts +4 -0
- package/dist/cjs/hooks/useShapes/bar-x/index.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/bar-x/index.js +30 -2
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +32 -11
- package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
- package/dist/cjs/hooks/useShapes/index.js +22 -3
- package/dist/cjs/hooks/useShapes/line/index.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/line/index.js +21 -7
- package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +2 -1
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +28 -10
- package/dist/cjs/hooks/useShapes/line/types.d.ts +4 -0
- package/dist/cjs/hooks/useShapes/x-range/index.d.ts +14 -0
- package/dist/cjs/hooks/useShapes/x-range/index.js +115 -0
- package/dist/cjs/hooks/useShapes/x-range/prepare-data.d.ts +15 -0
- package/dist/cjs/hooks/useShapes/x-range/prepare-data.js +147 -0
- package/dist/cjs/hooks/useShapes/x-range/types.d.ts +12 -0
- package/dist/cjs/hooks/useShapes/x-range/types.js +1 -0
- package/dist/esm/components/ChartInner/utils/zoom.js +3 -1
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +31 -6
- package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.js +4 -5
- package/dist/esm/core/constants/chart-types.d.ts +1 -0
- package/dist/esm/core/constants/chart-types.js +1 -0
- package/dist/esm/core/constants/defaults/annotation.d.ts +12 -0
- package/dist/esm/core/constants/defaults/annotation.js +12 -0
- package/dist/esm/core/constants/defaults/index.d.ts +1 -0
- package/dist/esm/core/constants/defaults/index.js +1 -0
- package/dist/esm/core/constants/defaults/series-options.d.ts +5 -1
- package/dist/esm/core/constants/defaults/series-options.js +13 -0
- package/dist/esm/core/i18n/keysets/en.json +2 -1
- package/dist/esm/core/i18n/keysets/ru.json +2 -1
- package/dist/esm/core/series/constants.d.ts +1 -1
- package/dist/esm/core/series/constants.js +1 -1
- package/dist/esm/core/series/prepare-annotation.d.ts +12 -0
- package/dist/esm/core/series/prepare-annotation.js +31 -0
- package/dist/esm/core/series/prepare-legend.js +2 -2
- package/dist/esm/core/series/prepare-x-range.d.ts +11 -0
- package/dist/esm/core/series/prepare-x-range.js +41 -0
- package/dist/esm/core/series/prepareSeries.js +9 -0
- package/dist/esm/core/series/types.d.ts +34 -2
- package/dist/esm/core/types/chart/annotation.d.ts +45 -0
- package/dist/esm/core/types/chart/annotation.js +1 -0
- package/dist/esm/core/types/chart/area.d.ts +10 -1
- package/dist/esm/core/types/chart/bar-x.d.ts +6 -0
- package/dist/esm/core/types/chart/line.d.ts +8 -0
- package/dist/esm/core/types/chart/marker.d.ts +6 -4
- package/dist/esm/core/types/chart/series.d.ts +36 -2
- package/dist/esm/core/types/chart/tooltip.d.ts +7 -1
- package/dist/esm/core/types/chart/x-range.d.ts +59 -0
- package/dist/esm/core/types/chart/x-range.js +1 -0
- package/dist/esm/core/types/chart/zoom.d.ts +1 -1
- package/dist/esm/core/types/index.d.ts +2 -0
- package/dist/esm/core/types/index.js +2 -0
- package/dist/esm/core/utils/axis/x-axis.js +9 -1
- package/dist/esm/core/utils/color.js +6 -0
- package/dist/esm/core/utils/common.js +10 -0
- package/dist/esm/core/utils/get-closest-data.js +19 -0
- package/dist/esm/core/utils/text.d.ts +8 -0
- package/dist/esm/core/utils/text.js +9 -1
- package/dist/esm/core/validation/index.js +13 -0
- package/dist/esm/core/zoom/zoom.js +24 -7
- package/dist/esm/hooks/useShapes/annotation/index.d.ts +14 -0
- package/dist/esm/hooks/useShapes/annotation/index.js +200 -0
- package/dist/esm/hooks/useShapes/area/index.d.ts +2 -0
- package/dist/esm/hooks/useShapes/area/index.js +21 -2
- package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +2 -1
- package/dist/esm/hooks/useShapes/area/prepare-data.js +45 -26
- package/dist/esm/hooks/useShapes/area/types.d.ts +4 -0
- package/dist/esm/hooks/useShapes/bar-x/index.d.ts +2 -0
- package/dist/esm/hooks/useShapes/bar-x/index.js +30 -2
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +32 -11
- package/dist/esm/hooks/useShapes/bar-x/types.d.ts +2 -0
- package/dist/esm/hooks/useShapes/index.d.ts +2 -1
- package/dist/esm/hooks/useShapes/index.js +22 -3
- package/dist/esm/hooks/useShapes/line/index.d.ts +2 -0
- package/dist/esm/hooks/useShapes/line/index.js +21 -7
- package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +2 -1
- package/dist/esm/hooks/useShapes/line/prepare-data.js +28 -10
- package/dist/esm/hooks/useShapes/line/types.d.ts +4 -0
- package/dist/esm/hooks/useShapes/x-range/index.d.ts +14 -0
- package/dist/esm/hooks/useShapes/x-range/index.js +115 -0
- package/dist/esm/hooks/useShapes/x-range/prepare-data.d.ts +15 -0
- package/dist/esm/hooks/useShapes/x-range/prepare-data.js +147 -0
- package/dist/esm/hooks/useShapes/x-range/types.d.ts +12 -0
- package/dist/esm/hooks/useShapes/x-range/types.js +1 -0
- package/package.json +2 -2
|
@@ -5,14 +5,16 @@ import get from 'lodash/get';
|
|
|
5
5
|
import { filterOverlappingLabels } from '../../../core/utils';
|
|
6
6
|
import { block } from '../../../utils';
|
|
7
7
|
import { HtmlLayer } from '../HtmlLayer';
|
|
8
|
+
import { renderAnnotations } from '../annotation';
|
|
8
9
|
import { getRectPath } from '../utils';
|
|
9
10
|
export { prepareBarXData } from './prepare-data';
|
|
10
11
|
export * from './types';
|
|
11
12
|
const b = block('bar-x');
|
|
12
13
|
export const BarXSeriesShapes = (args) => {
|
|
13
|
-
const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
|
|
14
|
+
const { boundsHeight, boundsWidth, dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId, } = args;
|
|
14
15
|
const hoveredDataRef = React.useRef(null);
|
|
15
16
|
const ref = React.useRef(null);
|
|
17
|
+
const annotationsRef = React.useRef(null);
|
|
16
18
|
const allowOverlapDataLabels = React.useMemo(() => {
|
|
17
19
|
return preparedData.some((d) => d === null || d === void 0 ? void 0 : d.series.dataLabels.allowOverlap);
|
|
18
20
|
}, [preparedData]);
|
|
@@ -65,6 +67,24 @@ export const BarXSeriesShapes = (args) => {
|
|
|
65
67
|
.style('font-size', (d) => d.style.fontSize)
|
|
66
68
|
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
67
69
|
.style('fill', (d) => d.style.fontColor || null);
|
|
70
|
+
if (annotationsRef.current) {
|
|
71
|
+
const anchors = [];
|
|
72
|
+
for (const d of preparedData) {
|
|
73
|
+
if (d.annotation) {
|
|
74
|
+
anchors.push({
|
|
75
|
+
annotation: d.annotation,
|
|
76
|
+
x: d.x + d.width / 2,
|
|
77
|
+
y: d.y,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
renderAnnotations({
|
|
82
|
+
anchors,
|
|
83
|
+
container: select(annotationsRef.current),
|
|
84
|
+
plotHeight: boundsHeight,
|
|
85
|
+
plotWidth: boundsWidth,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
68
88
|
function handleShapeHover(data) {
|
|
69
89
|
hoveredDataRef.current = data;
|
|
70
90
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
@@ -112,7 +132,14 @@ export const BarXSeriesShapes = (args) => {
|
|
|
112
132
|
return () => {
|
|
113
133
|
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.bar-x', null);
|
|
114
134
|
};
|
|
115
|
-
}, [
|
|
135
|
+
}, [
|
|
136
|
+
allowOverlapDataLabels,
|
|
137
|
+
boundsHeight,
|
|
138
|
+
boundsWidth,
|
|
139
|
+
dispatcher,
|
|
140
|
+
preparedData,
|
|
141
|
+
seriesOptions,
|
|
142
|
+
]);
|
|
116
143
|
const htmlLayerData = React.useMemo(() => {
|
|
117
144
|
const items = preparedData.map((d) => d === null || d === void 0 ? void 0 : d.htmlLabels).flat();
|
|
118
145
|
if (allowOverlapDataLabels) {
|
|
@@ -122,5 +149,6 @@ export const BarXSeriesShapes = (args) => {
|
|
|
122
149
|
}, [allowOverlapDataLabels, preparedData]);
|
|
123
150
|
return (React.createElement(React.Fragment, null,
|
|
124
151
|
React.createElement("g", { ref: ref, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
152
|
+
React.createElement("g", { ref: annotationsRef }),
|
|
125
153
|
React.createElement(HtmlLayer, { preparedData: htmlLayerData, htmlLayout: htmlLayout })));
|
|
126
154
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ascending, descending, max, min, reverse, sort } from 'd3-array';
|
|
2
2
|
import get from 'lodash/get';
|
|
3
|
+
import { prepareAnnotation } from '../../../core/series/prepare-annotation';
|
|
3
4
|
import { getDataCategoryValue, getLabelsSize } from '../../../core/utils';
|
|
4
5
|
import { getFormattedValue } from '../../../core/utils/format';
|
|
5
6
|
import { MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH } from '../../constants';
|
|
@@ -35,7 +36,7 @@ async function getLabelData(d, xMax) {
|
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
export const prepareBarXData = async (args) => {
|
|
38
|
-
var _a, _b, _c, _d, _e, _f;
|
|
39
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
39
40
|
const { series, seriesOptions, xAxis, xScale, yAxis, yScale, boundsHeight: plotHeight, split, isRangeSlider, } = args;
|
|
40
41
|
const stackGap = seriesOptions['bar-x'].stackGap;
|
|
41
42
|
const categories = (_a = xAxis === null || xAxis === void 0 ? void 0 : xAxis.categories) !== null && _a !== void 0 ? _a : [];
|
|
@@ -110,8 +111,8 @@ export const prepareBarXData = async (args) => {
|
|
|
110
111
|
const currentGroupWidth = rectWidth * stacks.length + rectGap * (stacks.length - 1);
|
|
111
112
|
for (let groupItemIndex = 0; groupItemIndex < stacks.length; groupItemIndex++) {
|
|
112
113
|
const yValues = stacks[groupItemIndex];
|
|
113
|
-
let
|
|
114
|
-
let
|
|
114
|
+
let positiveStackSum = 0;
|
|
115
|
+
let negativeStackSum = 0;
|
|
115
116
|
const stackItems = [];
|
|
116
117
|
let sortedData = yValues;
|
|
117
118
|
if (sortKey) {
|
|
@@ -144,7 +145,6 @@ export const prepareBarXData = async (args) => {
|
|
|
144
145
|
}
|
|
145
146
|
const x = xCenter - currentGroupWidth / 2 + (rectWidth + rectGap) * groupItemIndex;
|
|
146
147
|
const yDataValue = ((_d = yValue.data.y) !== null && _d !== void 0 ? _d : 0);
|
|
147
|
-
const y = seriesYScale(yDataValue);
|
|
148
148
|
let base = 0;
|
|
149
149
|
if (seriesYAxis.type === 'logarithmic') {
|
|
150
150
|
const domainData = seriesYScale.domain();
|
|
@@ -155,7 +155,22 @@ export const prepareBarXData = async (args) => {
|
|
|
155
155
|
base = seriesYScale(0);
|
|
156
156
|
}
|
|
157
157
|
const isLastStackItem = yValueIndex === sortedData.length - 1;
|
|
158
|
-
|
|
158
|
+
let height;
|
|
159
|
+
let barPositionY;
|
|
160
|
+
if (yDataValue > 0) {
|
|
161
|
+
const newSum = positiveStackSum + yDataValue;
|
|
162
|
+
const topPixel = seriesYScale(newSum);
|
|
163
|
+
const bottomPixel = positiveStackSum === 0 ? base : seriesYScale(positiveStackSum);
|
|
164
|
+
height = Math.abs(bottomPixel - topPixel);
|
|
165
|
+
barPositionY = yAxisTop + topPixel;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const newSum = negativeStackSum + yDataValue;
|
|
169
|
+
const bottomPixel = negativeStackSum === 0 ? base : seriesYScale(negativeStackSum);
|
|
170
|
+
const topPixel = seriesYScale(newSum);
|
|
171
|
+
height = Math.abs(bottomPixel - topPixel);
|
|
172
|
+
barPositionY = yAxisTop + bottomPixel;
|
|
173
|
+
}
|
|
159
174
|
let shapeHeight = height - (stackItems.length ? stackGap : 0);
|
|
160
175
|
if (shapeHeight < 0) {
|
|
161
176
|
shapeHeight = height;
|
|
@@ -164,10 +179,15 @@ export const prepareBarXData = async (args) => {
|
|
|
164
179
|
continue;
|
|
165
180
|
}
|
|
166
181
|
const barData = {
|
|
182
|
+
annotation: yValue.data.annotation && !isRangeSlider
|
|
183
|
+
? await prepareAnnotation({
|
|
184
|
+
annotation: yValue.data.annotation,
|
|
185
|
+
optionsLabel: (_g = (_f = seriesOptions['bar-x']) === null || _f === void 0 ? void 0 : _f.annotation) === null || _g === void 0 ? void 0 : _g.label,
|
|
186
|
+
optionsPopup: (_j = (_h = seriesOptions['bar-x']) === null || _h === void 0 ? void 0 : _h.annotation) === null || _j === void 0 ? void 0 : _j.popup,
|
|
187
|
+
})
|
|
188
|
+
: undefined,
|
|
167
189
|
x,
|
|
168
|
-
y:
|
|
169
|
-
? yAxisTop + y - positiveStackHeight
|
|
170
|
-
: yAxisTop + base + negativeStackHeight,
|
|
190
|
+
y: barPositionY,
|
|
171
191
|
width: rectWidth,
|
|
172
192
|
height: shapeHeight,
|
|
173
193
|
_height: height,
|
|
@@ -180,14 +200,15 @@ export const prepareBarXData = async (args) => {
|
|
|
180
200
|
};
|
|
181
201
|
stackItems.push(barData);
|
|
182
202
|
if (yDataValue > 0) {
|
|
183
|
-
|
|
203
|
+
positiveStackSum += yDataValue;
|
|
184
204
|
}
|
|
185
205
|
else {
|
|
186
|
-
|
|
206
|
+
negativeStackSum += yDataValue;
|
|
187
207
|
}
|
|
188
208
|
}
|
|
189
209
|
if (series.some((s) => s.stacking === 'percent')) {
|
|
190
210
|
let acc = 0;
|
|
211
|
+
const positiveStackHeight = stackItems.reduce((sum, item) => sum + item._height, 0);
|
|
191
212
|
const ratio = plotHeight / positiveStackHeight;
|
|
192
213
|
stackItems.forEach((item) => {
|
|
193
214
|
item.height = item._height * ratio;
|
|
@@ -207,7 +228,7 @@ export const prepareBarXData = async (args) => {
|
|
|
207
228
|
barData.x >= xMax ||
|
|
208
229
|
barData.y + barData.height <= 0 ||
|
|
209
230
|
barData.y >= plotHeight;
|
|
210
|
-
const isZeroValue = ((
|
|
231
|
+
const isZeroValue = ((_k = barData.data.y) !== null && _k !== void 0 ? _k : 0) === 0;
|
|
211
232
|
if (barData.series.dataLabels.enabled &&
|
|
212
233
|
!isRangeSlider &&
|
|
213
234
|
(!isBarOutsideBounds || isZeroValue)) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { PreparedAnnotation } from '../../../core/series/types';
|
|
1
2
|
import type { HtmlItem, LabelData, TooltipDataChunkBarX } from '../../../types';
|
|
2
3
|
import type { PreparedBarXSeries } from '../../useSeries/types';
|
|
3
4
|
export type PreparedBarXData = Omit<TooltipDataChunkBarX, 'series'> & {
|
|
5
|
+
annotation?: PreparedAnnotation;
|
|
4
6
|
x: number;
|
|
5
7
|
y: number;
|
|
6
8
|
width: number;
|
|
@@ -19,8 +19,9 @@ import type { PreparedScatterData } from './scatter/types';
|
|
|
19
19
|
export type { PreparedBarXData } from './bar-x';
|
|
20
20
|
export type { PreparedScatterData } from './scatter/types';
|
|
21
21
|
import type { PreparedWaterfallData } from './waterfall';
|
|
22
|
+
import type { PreparedXRangeData } from './x-range';
|
|
22
23
|
import './styles.css';
|
|
23
|
-
export type ShapeData = PreparedBarXData | PreparedBarYData | PreparedScatterData | PreparedLineData | PreparedPieData | PreparedAreaData | PreparedWaterfallData | PreparedSankeyData | PreparedRadarData | PreparedHeatmapData | PreparedFunnelData;
|
|
24
|
+
export type ShapeData = PreparedBarXData | PreparedBarYData | PreparedScatterData | PreparedLineData | PreparedPieData | PreparedAreaData | PreparedWaterfallData | PreparedSankeyData | PreparedRadarData | PreparedHeatmapData | PreparedFunnelData | PreparedXRangeData;
|
|
24
25
|
export type ClipPathBySeriesType = Partial<Record<SeriesType, boolean>>;
|
|
25
26
|
type Args = {
|
|
26
27
|
boundsWidth: number;
|
|
@@ -22,6 +22,7 @@ import { TreemapSeriesShape } from './treemap';
|
|
|
22
22
|
import { prepareTreemapData } from './treemap/prepare-data';
|
|
23
23
|
import { getSeriesClipPathId } from './utils';
|
|
24
24
|
import { WaterfallSeriesShapes, prepareWaterfallData } from './waterfall';
|
|
25
|
+
import { XRangeSeriesShapes, prepareXRangeData } from './x-range';
|
|
25
26
|
import './styles.css';
|
|
26
27
|
function IS_OUTSIDE_BOUNDS() {
|
|
27
28
|
return false;
|
|
@@ -61,7 +62,7 @@ export async function getShapes(args) {
|
|
|
61
62
|
split,
|
|
62
63
|
isRangeSlider,
|
|
63
64
|
});
|
|
64
|
-
shapes[index] = (React.createElement(BarXSeriesShapes, { key: SERIES_TYPE.BarX, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
65
|
+
shapes[index] = (React.createElement(BarXSeriesShapes, { key: SERIES_TYPE.BarX, boundsHeight: boundsHeight, boundsWidth: boundsWidth, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
65
66
|
shapesData.splice(index, 0, ...preparedData);
|
|
66
67
|
layers.push(...preparedData);
|
|
67
68
|
}
|
|
@@ -103,6 +104,7 @@ export async function getShapes(args) {
|
|
|
103
104
|
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
104
105
|
const preparedData = await prepareLineData({
|
|
105
106
|
series: chartSeries,
|
|
107
|
+
seriesOptions,
|
|
106
108
|
xAxis,
|
|
107
109
|
xScale,
|
|
108
110
|
yAxis,
|
|
@@ -117,7 +119,7 @@ export async function getShapes(args) {
|
|
|
117
119
|
yAxis,
|
|
118
120
|
zoomState,
|
|
119
121
|
});
|
|
120
|
-
shapes[index] = (React.createElement(LineSeriesShapes, { key: groupId, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: resultClipPathId }));
|
|
122
|
+
shapes[index] = (React.createElement(LineSeriesShapes, { key: groupId, boundsHeight: boundsHeight, boundsWidth: boundsWidth, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: resultClipPathId }));
|
|
121
123
|
shapesData.splice(index, 0, ...preparedData);
|
|
122
124
|
layers.push(...preparedData);
|
|
123
125
|
}
|
|
@@ -127,6 +129,7 @@ export async function getShapes(args) {
|
|
|
127
129
|
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
128
130
|
const preparedData = await prepareAreaData({
|
|
129
131
|
series: chartSeries,
|
|
132
|
+
seriesOptions,
|
|
130
133
|
xAxis,
|
|
131
134
|
xScale,
|
|
132
135
|
yAxis,
|
|
@@ -135,7 +138,7 @@ export async function getShapes(args) {
|
|
|
135
138
|
isOutsideBounds,
|
|
136
139
|
isRangeSlider,
|
|
137
140
|
});
|
|
138
|
-
shapes[index] = (React.createElement(AreaSeriesShapes, { key: SERIES_TYPE.Area, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
141
|
+
shapes[index] = (React.createElement(AreaSeriesShapes, { key: SERIES_TYPE.Area, boundsHeight: boundsHeight, boundsWidth: boundsWidth, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
139
142
|
shapesData.splice(index, 0, ...preparedData);
|
|
140
143
|
layers.push(...preparedData);
|
|
141
144
|
}
|
|
@@ -224,6 +227,22 @@ export async function getShapes(args) {
|
|
|
224
227
|
shapesData.splice(index, 0, preparedData);
|
|
225
228
|
break;
|
|
226
229
|
}
|
|
230
|
+
case SERIES_TYPE.XRange: {
|
|
231
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
232
|
+
const preparedData = await prepareXRangeData({
|
|
233
|
+
series: chartSeries,
|
|
234
|
+
xAxis,
|
|
235
|
+
xScale,
|
|
236
|
+
yAxis,
|
|
237
|
+
yScale,
|
|
238
|
+
boundsWidth,
|
|
239
|
+
isRangeSlider,
|
|
240
|
+
});
|
|
241
|
+
shapes[index] = (React.createElement(XRangeSeriesShapes, { key: SERIES_TYPE.XRange, dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
242
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
227
246
|
default: {
|
|
228
247
|
throw new ChartError({
|
|
229
248
|
message: `The display method is not defined for a series with type "${seriesType}"`,
|
|
@@ -3,6 +3,8 @@ import type { Dispatch } from 'd3-dispatch';
|
|
|
3
3
|
import type { PreparedSeriesOptions } from '../../useSeries/types';
|
|
4
4
|
import type { PreparedLineData } from './types';
|
|
5
5
|
type Args = {
|
|
6
|
+
boundsHeight: number;
|
|
7
|
+
boundsWidth: number;
|
|
6
8
|
clipPathId: string;
|
|
7
9
|
htmlLayout: HTMLElement | null;
|
|
8
10
|
preparedData: PreparedLineData[];
|
|
@@ -6,16 +6,19 @@ import get from 'lodash/get';
|
|
|
6
6
|
import { getLineDashArray } from '../../../core/utils';
|
|
7
7
|
import { block } from '../../../utils';
|
|
8
8
|
import { HtmlLayer } from '../HtmlLayer';
|
|
9
|
+
import { renderAnnotations } from '../annotation';
|
|
9
10
|
import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
|
|
10
11
|
import { setActiveState } from '../utils';
|
|
11
12
|
const b = block('line');
|
|
12
13
|
export const LineSeriesShapes = (args) => {
|
|
13
|
-
const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
|
|
14
|
+
const { boundsHeight, boundsWidth, dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId, } = args;
|
|
14
15
|
const hoveredDataRef = React.useRef(null);
|
|
15
16
|
const plotRef = React.useRef(null);
|
|
16
17
|
const markersRef = React.useRef(null);
|
|
17
18
|
const hoverMarkersRef = React.useRef(null);
|
|
19
|
+
const annotationsRef = React.useRef(null);
|
|
18
20
|
React.useEffect(() => {
|
|
21
|
+
var _a, _b;
|
|
19
22
|
if (!plotRef.current || !markersRef.current) {
|
|
20
23
|
return () => { };
|
|
21
24
|
}
|
|
@@ -64,13 +67,22 @@ export const LineSeriesShapes = (args) => {
|
|
|
64
67
|
.data(markers)
|
|
65
68
|
.join('g')
|
|
66
69
|
.call(renderMarker);
|
|
70
|
+
if (annotationsRef.current) {
|
|
71
|
+
const anchors = preparedData.flatMap((d) => d.annotations);
|
|
72
|
+
renderAnnotations({
|
|
73
|
+
anchors,
|
|
74
|
+
container: select(annotationsRef.current),
|
|
75
|
+
plotHeight: boundsHeight,
|
|
76
|
+
plotWidth: boundsWidth,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
67
79
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
68
80
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
69
81
|
function handleShapeHover(data) {
|
|
70
82
|
hoveredDataRef.current = data;
|
|
71
83
|
const selected = (data === null || data === void 0 ? void 0 : data.filter((d) => d.series.type === 'line')) || [];
|
|
72
|
-
const selectedDataItems = selected.map((d) => d.data);
|
|
73
84
|
const selectedSeriesIds = selected.map((d) => { var _a; return (_a = d.series) === null || _a === void 0 ? void 0 : _a.id; });
|
|
85
|
+
const closestChunk = selected.find((d) => d.closest);
|
|
74
86
|
lineSelection.datum((d, index, list) => {
|
|
75
87
|
const elementSelection = select(list[index]);
|
|
76
88
|
const hovered = Boolean(hoverEnabled && selectedSeriesIds.includes(d.id));
|
|
@@ -106,7 +118,7 @@ export const LineSeriesShapes = (args) => {
|
|
|
106
118
|
});
|
|
107
119
|
markerSelection.datum((d, index, list) => {
|
|
108
120
|
const elementSelection = select(list[index]);
|
|
109
|
-
const hovered = Boolean(hoverEnabled &&
|
|
121
|
+
const hovered = Boolean(hoverEnabled && d.point.data === (closestChunk === null || closestChunk === void 0 ? void 0 : closestChunk.data));
|
|
110
122
|
if (d.hovered !== hovered) {
|
|
111
123
|
d.hovered = hovered;
|
|
112
124
|
elementSelection.attr('visibility', getMarkerVisibility(d));
|
|
@@ -129,7 +141,7 @@ export const LineSeriesShapes = (args) => {
|
|
|
129
141
|
hoverMarkersSvgElement.selectAll('*').remove();
|
|
130
142
|
if (hoverEnabled && selected.length > 0) {
|
|
131
143
|
const hoverOnlyMarkers = [];
|
|
132
|
-
for (const chunk of selected) {
|
|
144
|
+
for (const chunk of selected.filter((c) => c.closest)) {
|
|
133
145
|
const seriesData = preparedData.find((pd) => pd.id === chunk.series.id);
|
|
134
146
|
if (!seriesData) {
|
|
135
147
|
continue;
|
|
@@ -165,11 +177,12 @@ export const LineSeriesShapes = (args) => {
|
|
|
165
177
|
if (hoveredDataRef.current !== null) {
|
|
166
178
|
handleShapeHover(hoveredDataRef.current);
|
|
167
179
|
}
|
|
168
|
-
|
|
180
|
+
const eventName = `hover-shape.line-${(_b = (_a = preparedData[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'unknown'}`;
|
|
181
|
+
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on(eventName, handleShapeHover);
|
|
169
182
|
return () => {
|
|
170
|
-
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on(
|
|
183
|
+
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on(eventName, null);
|
|
171
184
|
};
|
|
172
|
-
}, [dispatcher, preparedData, seriesOptions]);
|
|
185
|
+
}, [boundsHeight, boundsWidth, dispatcher, preparedData, seriesOptions]);
|
|
173
186
|
const htmlLayerData = React.useMemo(() => {
|
|
174
187
|
const items = preparedData.map((d) => d === null || d === void 0 ? void 0 : d.htmlLabels).flat();
|
|
175
188
|
return { htmlElements: items };
|
|
@@ -178,5 +191,6 @@ export const LineSeriesShapes = (args) => {
|
|
|
178
191
|
React.createElement("g", { ref: plotRef, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
179
192
|
React.createElement("g", { ref: markersRef }),
|
|
180
193
|
React.createElement("g", { ref: hoverMarkersRef }),
|
|
194
|
+
React.createElement("g", { ref: annotationsRef }),
|
|
181
195
|
React.createElement(HtmlLayer, { preparedData: htmlLayerData, htmlLayout: htmlLayout })));
|
|
182
196
|
};
|
|
@@ -2,10 +2,11 @@ import type { PreparedSplit } from '../../../core/layout/split-types';
|
|
|
2
2
|
import type { ChartScale } from '../../../core/scales/types';
|
|
3
3
|
import type { ShapeDataWithLabels } from '../../../types';
|
|
4
4
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
5
|
-
import type { PreparedLineSeries } from '../../useSeries/types';
|
|
5
|
+
import type { PreparedLineSeries, PreparedSeriesOptions } from '../../useSeries/types';
|
|
6
6
|
import type { PreparedLineData } from './types';
|
|
7
7
|
export declare const prepareLineData: (args: {
|
|
8
8
|
series: PreparedLineSeries[];
|
|
9
|
+
seriesOptions?: PreparedSeriesOptions;
|
|
9
10
|
xAxis: PreparedXAxis;
|
|
10
11
|
xScale: ChartScale;
|
|
11
12
|
yAxis: PreparedYAxis[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { prepareAnnotation } from '../../../core/series/prepare-annotation';
|
|
1
2
|
import { filterOverlappingLabels, getLabelsSize, getTextSizeFn } from '../../../core/utils';
|
|
2
3
|
import { getFormattedValue } from '../../../core/utils/format';
|
|
3
4
|
import { getXValue, getYValue } from '../utils';
|
|
@@ -15,8 +16,8 @@ async function getHtmlLabel(point, series, xMax) {
|
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
18
|
export const prepareLineData = async (args) => {
|
|
18
|
-
var _a, _b, _c, _d;
|
|
19
|
-
const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider, otherLayers, } = args;
|
|
19
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
20
|
+
const { series, seriesOptions, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider, otherLayers, } = args;
|
|
20
21
|
const [_xMin, xRangeMax] = xScale.range();
|
|
21
22
|
const xMax = xRangeMax;
|
|
22
23
|
const acc = [];
|
|
@@ -29,21 +30,31 @@ export const prepareLineData = async (args) => {
|
|
|
29
30
|
if (!seriesYScale) {
|
|
30
31
|
continue;
|
|
31
32
|
}
|
|
32
|
-
const
|
|
33
|
+
const annotationOpts = (_b = seriesOptions === null || seriesOptions === void 0 ? void 0 : seriesOptions.line) === null || _b === void 0 ? void 0 : _b.annotation;
|
|
34
|
+
const points = [];
|
|
35
|
+
for (let j = 0; j < s.data.length; j++) {
|
|
36
|
+
const d = s.data[j];
|
|
33
37
|
const yValue = getYValue({
|
|
34
38
|
point: d,
|
|
35
39
|
points: s.data,
|
|
36
40
|
yAxis: seriesYAxis,
|
|
37
41
|
yScale: seriesYScale,
|
|
38
42
|
});
|
|
39
|
-
|
|
43
|
+
points.push({
|
|
40
44
|
x: getXValue({ point: d, points: s.data, xAxis, xScale }),
|
|
41
45
|
y: yValue === null ? null : yAxisTop + yValue,
|
|
42
|
-
|
|
46
|
+
color: (_d = (_c = d.marker) === null || _c === void 0 ? void 0 : _c.color) !== null && _d !== void 0 ? _d : d.color,
|
|
43
47
|
data: d,
|
|
44
48
|
series: s,
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
annotation: d.annotation && !isRangeSlider
|
|
50
|
+
? await prepareAnnotation({
|
|
51
|
+
annotation: d.annotation,
|
|
52
|
+
optionsLabel: annotationOpts === null || annotationOpts === void 0 ? void 0 : annotationOpts.label,
|
|
53
|
+
optionsPopup: annotationOpts === null || annotationOpts === void 0 ? void 0 : annotationOpts.popup,
|
|
54
|
+
})
|
|
55
|
+
: undefined,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
47
58
|
let htmlElements = [];
|
|
48
59
|
let svgLabels = [];
|
|
49
60
|
if (s.dataLabels.enabled && !isRangeSlider) {
|
|
@@ -64,7 +75,7 @@ export const prepareLineData = async (args) => {
|
|
|
64
75
|
if (point.y !== null &&
|
|
65
76
|
point.x !== null &&
|
|
66
77
|
!isOutsideBounds(point.x, point.y)) {
|
|
67
|
-
const labelValue = (
|
|
78
|
+
const labelValue = (_e = point.data.label) !== null && _e !== void 0 ? _e : point.data.y;
|
|
68
79
|
const text = getFormattedValue(Object.assign({ value: labelValue }, s.dataLabels));
|
|
69
80
|
const labelSize = await getTextSize(text);
|
|
70
81
|
const style = s.dataLabels.style;
|
|
@@ -112,7 +123,14 @@ export const prepareLineData = async (args) => {
|
|
|
112
123
|
return result;
|
|
113
124
|
}, []);
|
|
114
125
|
}
|
|
126
|
+
const annotations = points.reduce((result, p) => {
|
|
127
|
+
if (p.annotation && p.x !== null && p.y !== null) {
|
|
128
|
+
result.push({ annotation: p.annotation, x: p.x, y: p.y });
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
}, []);
|
|
115
132
|
const result = {
|
|
133
|
+
annotations,
|
|
116
134
|
points,
|
|
117
135
|
markers,
|
|
118
136
|
svgLabels: svgLabels,
|
|
@@ -122,11 +140,11 @@ export const prepareLineData = async (args) => {
|
|
|
122
140
|
id: s.id,
|
|
123
141
|
htmlLabels: htmlElements,
|
|
124
142
|
color: s.color,
|
|
125
|
-
lineWidth: (
|
|
143
|
+
lineWidth: (_f = (isRangeSlider ? s.rangeSlider.lineWidth : undefined)) !== null && _f !== void 0 ? _f : s.lineWidth,
|
|
126
144
|
dashStyle: s.dashStyle,
|
|
127
145
|
linecap: s.linecap,
|
|
128
146
|
linejoin: s.linejoin,
|
|
129
|
-
opacity: (
|
|
147
|
+
opacity: (_g = (isRangeSlider ? s.rangeSlider.opacity : undefined)) !== null && _g !== void 0 ? _g : s.opacity,
|
|
130
148
|
};
|
|
131
149
|
acc.push(result);
|
|
132
150
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { DashStyle, LineCap, LineJoin } from '../../../core/constants';
|
|
2
|
+
import type { PreparedAnnotation } from '../../../core/series/types';
|
|
2
3
|
import type { HtmlItem, LabelData, LineSeriesData, LineSeriesLineBaseStyle } from '../../../types';
|
|
3
4
|
import type { PreparedLineSeries } from '../../useSeries/types';
|
|
5
|
+
import type { AnnotationAnchor } from '../annotation';
|
|
4
6
|
export type PointData = {
|
|
5
7
|
x: number | null;
|
|
6
8
|
y: number | null;
|
|
7
9
|
data: LineSeriesData;
|
|
8
10
|
series: PreparedLineSeries;
|
|
11
|
+
annotation?: PreparedAnnotation;
|
|
9
12
|
color?: string;
|
|
10
13
|
};
|
|
11
14
|
export type MarkerPointData = PointData & {
|
|
@@ -19,6 +22,7 @@ export type MarkerData = {
|
|
|
19
22
|
clipped: boolean;
|
|
20
23
|
};
|
|
21
24
|
export type PreparedLineData = {
|
|
25
|
+
annotations: AnnotationAnchor[];
|
|
22
26
|
id: string;
|
|
23
27
|
points: PointData[];
|
|
24
28
|
markers: MarkerData[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Dispatch } from 'd3-dispatch';
|
|
3
|
+
import type { PreparedSeriesOptions } from '../../useSeries/types';
|
|
4
|
+
export { prepareXRangeData } from './prepare-data';
|
|
5
|
+
export type { PreparedXRangeData } from './types';
|
|
6
|
+
import type { PreparedXRangeData } from './types';
|
|
7
|
+
type Args = {
|
|
8
|
+
clipPathId: string;
|
|
9
|
+
htmlLayout: HTMLElement | null;
|
|
10
|
+
preparedData: PreparedXRangeData[];
|
|
11
|
+
seriesOptions: PreparedSeriesOptions;
|
|
12
|
+
dispatcher?: Dispatch<object>;
|
|
13
|
+
};
|
|
14
|
+
export declare function XRangeSeriesShapes(args: Args): React.JSX.Element;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { color } from 'd3-color';
|
|
3
|
+
import { select } from 'd3-selection';
|
|
4
|
+
import get from 'lodash/get';
|
|
5
|
+
import { getLineDashArray } from '../../../core/utils';
|
|
6
|
+
import { block } from '../../../utils';
|
|
7
|
+
import { HtmlLayer } from '../HtmlLayer';
|
|
8
|
+
import { getRectPath } from '../utils';
|
|
9
|
+
export { prepareXRangeData } from './prepare-data';
|
|
10
|
+
const b = block('x-range');
|
|
11
|
+
export function XRangeSeriesShapes(args) {
|
|
12
|
+
const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
|
|
13
|
+
const hoveredDataRef = React.useRef(null);
|
|
14
|
+
const ref = React.useRef(null);
|
|
15
|
+
React.useEffect(() => {
|
|
16
|
+
var _a;
|
|
17
|
+
if (!ref.current) {
|
|
18
|
+
return () => { };
|
|
19
|
+
}
|
|
20
|
+
const svgElement = select(ref.current);
|
|
21
|
+
svgElement.selectAll('*').remove();
|
|
22
|
+
const segmentSelection = svgElement
|
|
23
|
+
.selectAll(`path.${b('segment')}`)
|
|
24
|
+
.data(preparedData)
|
|
25
|
+
.join('path')
|
|
26
|
+
.attr('d', (d) => {
|
|
27
|
+
const borderRadius = Math.min(d.height / 2, d.width / 2, d.series.borderRadius);
|
|
28
|
+
return getRectPath({
|
|
29
|
+
x: d.x,
|
|
30
|
+
y: d.y,
|
|
31
|
+
width: d.width,
|
|
32
|
+
height: d.height,
|
|
33
|
+
borderRadius,
|
|
34
|
+
}).toString();
|
|
35
|
+
})
|
|
36
|
+
.attr('class', b('segment'))
|
|
37
|
+
.attr('fill', (d) => d.color)
|
|
38
|
+
.attr('opacity', (d) => { var _a; return (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity; })
|
|
39
|
+
.attr('cursor', (d) => d.series.cursor);
|
|
40
|
+
svgElement
|
|
41
|
+
.selectAll(`path.${b('segment-border')}`)
|
|
42
|
+
.data(preparedData.filter((d) => d.series.borderWidth > 0))
|
|
43
|
+
.join('path')
|
|
44
|
+
.attr('d', (d) => {
|
|
45
|
+
const borderRadius = Math.min(d.height / 2, d.width / 2, d.series.borderRadius);
|
|
46
|
+
return getRectPath({
|
|
47
|
+
x: d.x,
|
|
48
|
+
y: d.y,
|
|
49
|
+
width: d.width,
|
|
50
|
+
height: d.height,
|
|
51
|
+
borderRadius,
|
|
52
|
+
}).toString();
|
|
53
|
+
})
|
|
54
|
+
.attr('class', b('segment-border'))
|
|
55
|
+
.attr('fill', 'none')
|
|
56
|
+
.attr('stroke', (d) => d.series.borderColor)
|
|
57
|
+
.attr('stroke-width', (d) => d.series.borderWidth)
|
|
58
|
+
.attr('stroke-dasharray', (d) => getLineDashArray(d.series.borderDashStyle, d.series.borderWidth))
|
|
59
|
+
.attr('opacity', (d) => { var _a; return (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity; })
|
|
60
|
+
.attr('pointer-events', 'none');
|
|
61
|
+
const svgLabels = preparedData.flatMap((d) => d.svgLabels);
|
|
62
|
+
svgElement
|
|
63
|
+
.selectAll(`text.${b('label')}`)
|
|
64
|
+
.data(svgLabels)
|
|
65
|
+
.join('text')
|
|
66
|
+
.attr('class', b('label'))
|
|
67
|
+
.attr('x', (d) => d.x)
|
|
68
|
+
.attr('y', (d) => d.y)
|
|
69
|
+
.attr('text-anchor', (d) => d.textAnchor)
|
|
70
|
+
.attr('dominant-baseline', 'central')
|
|
71
|
+
.attr('pointer-events', 'none')
|
|
72
|
+
.style('font-size', (d) => d.style.fontSize)
|
|
73
|
+
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
74
|
+
.style('fill', (d) => d.style.fontColor || null)
|
|
75
|
+
.html((d) => d.text);
|
|
76
|
+
const hoverOptions = get(seriesOptions, 'x-range.states.hover');
|
|
77
|
+
const inactiveOptions = get(seriesOptions, 'x-range.states.inactive');
|
|
78
|
+
function handleShapeHover(data) {
|
|
79
|
+
hoveredDataRef.current = data;
|
|
80
|
+
if (hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled) {
|
|
81
|
+
const hoveredSet = new Set(data === null || data === void 0 ? void 0 : data.map((d) => d.data));
|
|
82
|
+
segmentSelection.attr('fill', (d) => {
|
|
83
|
+
var _a;
|
|
84
|
+
const fillColor = d.color;
|
|
85
|
+
if (hoveredSet.has(d.data)) {
|
|
86
|
+
return (((_a = color(fillColor)) === null || _a === void 0 ? void 0 : _a.brighter(hoverOptions.brightness).toString()) ||
|
|
87
|
+
fillColor);
|
|
88
|
+
}
|
|
89
|
+
return fillColor;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled) {
|
|
93
|
+
const hoveredSeries = data === null || data === void 0 ? void 0 : data.map((d) => d.series.id);
|
|
94
|
+
segmentSelection.attr('opacity', (d) => {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
if ((hoveredSeries === null || hoveredSeries === void 0 ? void 0 : hoveredSeries.length) && !hoveredSeries.includes(d.series.id)) {
|
|
97
|
+
return inactiveOptions.opacity || null;
|
|
98
|
+
}
|
|
99
|
+
return (_b = (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity) !== null && _b !== void 0 ? _b : null;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (hoveredDataRef.current !== null) {
|
|
104
|
+
handleShapeHover((_a = hoveredDataRef.current) !== null && _a !== void 0 ? _a : undefined);
|
|
105
|
+
}
|
|
106
|
+
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.x-range', handleShapeHover);
|
|
107
|
+
return () => {
|
|
108
|
+
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.x-range', null);
|
|
109
|
+
};
|
|
110
|
+
}, [dispatcher, preparedData, seriesOptions]);
|
|
111
|
+
const htmlLayerData = React.useMemo(() => ({ htmlElements: preparedData.flatMap((d) => d.htmlLabels) }), [preparedData]);
|
|
112
|
+
return (React.createElement(React.Fragment, null,
|
|
113
|
+
React.createElement("g", { ref: ref, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
114
|
+
React.createElement(HtmlLayer, { preparedData: htmlLayerData, htmlLayout: htmlLayout })));
|
|
115
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ChartScale } from '../../../core/scales/types';
|
|
2
|
+
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
3
|
+
import type { PreparedXRangeSeries } from '../../useSeries/types';
|
|
4
|
+
import type { PreparedXRangeData } from './types';
|
|
5
|
+
type PrepareXRangeDataArgs = {
|
|
6
|
+
series: PreparedXRangeSeries[];
|
|
7
|
+
xAxis: PreparedXAxis;
|
|
8
|
+
xScale: ChartScale;
|
|
9
|
+
yAxis: PreparedYAxis[];
|
|
10
|
+
yScale: (ChartScale | undefined)[];
|
|
11
|
+
boundsWidth?: number;
|
|
12
|
+
isRangeSlider?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function prepareXRangeData(args: PrepareXRangeDataArgs): Promise<PreparedXRangeData[]>;
|
|
15
|
+
export {};
|