@gravity-ui/charts 1.11.4 → 1.13.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/Axis/AxisX.js +62 -36
- package/dist/cjs/components/Axis/AxisY.js +67 -31
- package/dist/cjs/components/ChartInner/styles.css +1 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +15 -9
- package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +1 -0
- package/dist/cjs/components/Tooltip/ChartTooltipContent.js +3 -3
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/Row.d.ts +9 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/Row.js +10 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/RowTotals.d.ts +9 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/RowTotals.js +23 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.d.ts +11 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +102 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.d.ts +30 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.js +126 -0
- package/dist/cjs/components/Tooltip/index.js +1 -1
- package/dist/cjs/components/Tooltip/styles.css +14 -2
- package/dist/cjs/components/Tooltip/utils.d.ts +30 -0
- package/dist/cjs/components/Tooltip/utils.js +126 -0
- package/dist/cjs/constants/axis.d.ts +6 -0
- package/dist/cjs/constants/axis.js +6 -0
- package/dist/cjs/constants/index.d.ts +6 -4
- package/dist/cjs/constants/index.js +6 -4
- package/dist/cjs/constants/tooltip.d.ts +3 -0
- package/dist/cjs/constants/tooltip.js +3 -0
- package/dist/cjs/hooks/useAxisScales/index.d.ts +14 -3
- package/dist/cjs/hooks/useAxisScales/index.js +86 -22
- package/dist/cjs/hooks/useChartOptions/types.d.ts +5 -0
- package/dist/cjs/hooks/useChartOptions/utils.d.ts +11 -0
- package/dist/cjs/hooks/useChartOptions/utils.js +27 -0
- package/dist/cjs/hooks/useChartOptions/x-axis.js +6 -2
- package/dist/cjs/hooks/useChartOptions/y-axis.d.ts +4 -2
- package/dist/cjs/hooks/useChartOptions/y-axis.js +14 -4
- package/dist/cjs/hooks/useSeries/prepare-area.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +3 -0
- package/dist/cjs/hooks/useSeries/prepare-bar-y.js +5 -2
- package/dist/cjs/hooks/useSeries/prepare-line.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/prepare-radar.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/types.d.ts +3 -0
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +16 -13
- package/dist/cjs/hooks/useShapes/bar-y/index.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/bar-y/index.js +5 -9
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +80 -107
- package/dist/cjs/hooks/useShapes/bar-y/types.d.ts +7 -2
- package/dist/cjs/hooks/useShapes/index.js +1 -1
- package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +1 -1
- package/dist/cjs/hooks/utils/bar-y.d.ts +27 -0
- package/dist/cjs/hooks/utils/bar-y.js +55 -0
- package/dist/cjs/hooks/utils/index.d.ts +1 -0
- package/dist/cjs/hooks/utils/index.js +1 -0
- package/dist/cjs/i18n/keysets/en.json +7 -1
- package/dist/cjs/i18n/keysets/ru.json +7 -1
- package/dist/cjs/types/chart/axis.d.ts +15 -3
- package/dist/cjs/types/chart/bar-y.d.ts +10 -0
- package/dist/cjs/types/chart/series.d.ts +10 -0
- package/dist/cjs/types/chart/tooltip.d.ts +21 -0
- package/dist/cjs/utils/chart/axis-generators/bottom.js +26 -13
- package/dist/cjs/utils/chart/get-closest-data.js +13 -12
- package/dist/cjs/utils/chart/index.js +1 -1
- package/dist/cjs/utils/chart/series/sorting.d.ts +6 -2
- package/dist/cjs/utils/chart/series/sorting.js +29 -4
- package/dist/cjs/utils/chart/zoom.js +2 -1
- package/dist/cjs/validation/index.js +55 -1
- package/dist/esm/components/Axis/AxisX.js +62 -36
- package/dist/esm/components/Axis/AxisY.js +67 -31
- package/dist/esm/components/ChartInner/styles.css +1 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +15 -9
- package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +1 -0
- package/dist/esm/components/Tooltip/ChartTooltipContent.js +3 -3
- package/dist/esm/components/Tooltip/DefaultTooltipContent/Row.d.ts +9 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/Row.js +10 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/RowTotals.d.ts +9 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/RowTotals.js +23 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.d.ts +11 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +102 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.d.ts +30 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.js +126 -0
- package/dist/esm/components/Tooltip/index.js +1 -1
- package/dist/esm/components/Tooltip/styles.css +14 -2
- package/dist/esm/components/Tooltip/utils.d.ts +30 -0
- package/dist/esm/components/Tooltip/utils.js +126 -0
- package/dist/esm/constants/axis.d.ts +6 -0
- package/dist/esm/constants/axis.js +6 -0
- package/dist/esm/constants/index.d.ts +6 -4
- package/dist/esm/constants/index.js +6 -4
- package/dist/esm/constants/tooltip.d.ts +3 -0
- package/dist/esm/constants/tooltip.js +3 -0
- package/dist/esm/hooks/useAxisScales/index.d.ts +14 -3
- package/dist/esm/hooks/useAxisScales/index.js +86 -22
- package/dist/esm/hooks/useChartOptions/types.d.ts +5 -0
- package/dist/esm/hooks/useChartOptions/utils.d.ts +11 -0
- package/dist/esm/hooks/useChartOptions/utils.js +27 -0
- package/dist/esm/hooks/useChartOptions/x-axis.js +6 -2
- package/dist/esm/hooks/useChartOptions/y-axis.d.ts +4 -2
- package/dist/esm/hooks/useChartOptions/y-axis.js +14 -4
- package/dist/esm/hooks/useSeries/prepare-area.d.ts +1 -1
- package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +3 -0
- package/dist/esm/hooks/useSeries/prepare-bar-y.js +5 -2
- package/dist/esm/hooks/useSeries/prepare-line.d.ts +1 -1
- package/dist/esm/hooks/useSeries/prepare-radar.d.ts +1 -1
- package/dist/esm/hooks/useSeries/types.d.ts +3 -0
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +16 -13
- package/dist/esm/hooks/useShapes/bar-y/index.d.ts +2 -2
- package/dist/esm/hooks/useShapes/bar-y/index.js +5 -9
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.d.ts +2 -2
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +80 -107
- package/dist/esm/hooks/useShapes/bar-y/types.d.ts +7 -2
- package/dist/esm/hooks/useShapes/index.js +1 -1
- package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +1 -1
- package/dist/esm/hooks/utils/bar-y.d.ts +27 -0
- package/dist/esm/hooks/utils/bar-y.js +55 -0
- package/dist/esm/hooks/utils/index.d.ts +1 -0
- package/dist/esm/hooks/utils/index.js +1 -0
- package/dist/esm/i18n/keysets/en.json +7 -1
- package/dist/esm/i18n/keysets/ru.json +7 -1
- package/dist/esm/types/chart/axis.d.ts +15 -3
- package/dist/esm/types/chart/bar-y.d.ts +10 -0
- package/dist/esm/types/chart/series.d.ts +10 -0
- package/dist/esm/types/chart/tooltip.d.ts +21 -0
- package/dist/esm/utils/chart/axis-generators/bottom.js +26 -13
- package/dist/esm/utils/chart/get-closest-data.js +13 -12
- package/dist/esm/utils/chart/index.js +1 -1
- package/dist/esm/utils/chart/series/sorting.d.ts +6 -2
- package/dist/esm/utils/chart/series/sorting.js +29 -4
- package/dist/esm/utils/chart/zoom.js +2 -1
- package/dist/esm/validation/index.js +55 -1
- package/package.json +1 -1
- package/dist/cjs/components/Tooltip/DefaultContent.d.ts +0 -10
- package/dist/cjs/components/Tooltip/DefaultContent.js +0 -187
- package/dist/esm/components/Tooltip/DefaultContent.d.ts +0 -10
- package/dist/esm/components/Tooltip/DefaultContent.js +0 -187
- /package/dist/cjs/hooks/{useShapes/constants.d.ts → constants.d.ts} +0 -0
- /package/dist/cjs/hooks/{useShapes/constants.js → constants.js} +0 -0
- /package/dist/esm/hooks/{useShapes/constants.d.ts → constants.d.ts} +0 -0
- /package/dist/esm/hooks/{useShapes/constants.js → constants.js} +0 -0
|
@@ -51,17 +51,6 @@ export const AxisX = React.memo(function AxisX(props) {
|
|
|
51
51
|
}
|
|
52
52
|
const svgElement = select(ref.current);
|
|
53
53
|
svgElement.selectAll('*').remove();
|
|
54
|
-
const plotDataAttr = 'data-plot-x';
|
|
55
|
-
let plotBeforeContainer = null;
|
|
56
|
-
let plotAfterContainer = null;
|
|
57
|
-
if (plotBeforeRef === null || plotBeforeRef === void 0 ? void 0 : plotBeforeRef.current) {
|
|
58
|
-
plotBeforeContainer = select(plotBeforeRef.current);
|
|
59
|
-
plotBeforeContainer.selectAll(`[${plotDataAttr}]`).remove();
|
|
60
|
-
}
|
|
61
|
-
if (plotAfterRef === null || plotAfterRef === void 0 ? void 0 : plotAfterRef.current) {
|
|
62
|
-
plotAfterContainer = select(plotAfterRef.current);
|
|
63
|
-
plotAfterContainer.selectAll(`[${plotDataAttr}]`).remove();
|
|
64
|
-
}
|
|
65
54
|
if (!axis.visible) {
|
|
66
55
|
return;
|
|
67
56
|
}
|
|
@@ -122,6 +111,17 @@ export const AxisX = React.memo(function AxisX(props) {
|
|
|
122
111
|
}
|
|
123
112
|
});
|
|
124
113
|
}
|
|
114
|
+
const plotDataAttr = 'data-plot-x';
|
|
115
|
+
let plotBeforeContainer = null;
|
|
116
|
+
let plotAfterContainer = null;
|
|
117
|
+
if (plotBeforeRef === null || plotBeforeRef === void 0 ? void 0 : plotBeforeRef.current) {
|
|
118
|
+
plotBeforeContainer = select(plotBeforeRef.current);
|
|
119
|
+
plotBeforeContainer.selectAll(`[${plotDataAttr}]`).remove();
|
|
120
|
+
}
|
|
121
|
+
if (plotAfterRef === null || plotAfterRef === void 0 ? void 0 : plotAfterRef.current) {
|
|
122
|
+
plotAfterContainer = select(plotAfterRef.current);
|
|
123
|
+
plotAfterContainer.selectAll(`[${plotDataAttr}]`).remove();
|
|
124
|
+
}
|
|
125
125
|
// add plot bands
|
|
126
126
|
if (axis.plotBands.length > 0) {
|
|
127
127
|
const plotBandDataAttr = 'plot-x-band';
|
|
@@ -136,25 +136,38 @@ export const AxisX = React.memo(function AxisX(props) {
|
|
|
136
136
|
.join('g')
|
|
137
137
|
.attr(plotDataAttr, 1)
|
|
138
138
|
.attr(plotBandDataAttr, 1);
|
|
139
|
-
plotBandsSelection
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
plotBandsSelection.each(function () {
|
|
140
|
+
var _a, _b, _c, _e;
|
|
141
|
+
const plotBandSelection = select(this);
|
|
142
|
+
const band = plotBandSelection.datum();
|
|
143
143
|
const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
|
|
144
144
|
const halfBandwidth = ((_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 0) / 2;
|
|
145
145
|
const startPos = halfBandwidth + Math.min(from, to);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
146
|
+
const x = Math.max(0, startPos);
|
|
147
|
+
plotBandSelection
|
|
148
|
+
.append('rect')
|
|
149
|
+
.attr('x', x)
|
|
150
|
+
.attr('width', () => {
|
|
151
|
+
const endPos = Math.min(Math.abs(to - from), width - Math.min(from, to));
|
|
152
|
+
return Math.min(endPos, width);
|
|
153
|
+
})
|
|
154
|
+
.attr('y', 0)
|
|
155
|
+
.attr('height', totalHeight)
|
|
156
|
+
.attr('fill', () => band.color)
|
|
157
|
+
.attr('opacity', () => band.opacity);
|
|
158
|
+
if (band.label.text) {
|
|
159
|
+
const labelPadding = (_e = (_c = band.label) === null || _c === void 0 ? void 0 : _c.padding) !== null && _e !== void 0 ? _e : 0;
|
|
160
|
+
plotBandSelection
|
|
161
|
+
.append('text')
|
|
162
|
+
.text(band.label.text)
|
|
163
|
+
.style('fill', () => { var _a, _b; return (_b = (_a = band.label.style) === null || _a === void 0 ? void 0 : _a.fontColor) !== null && _b !== void 0 ? _b : null; })
|
|
164
|
+
.style('font-size', () => { var _a, _b; return (_b = (_a = band.label.style) === null || _a === void 0 ? void 0 : _a.fontSize) !== null && _b !== void 0 ? _b : null; })
|
|
165
|
+
.style('font-weight', () => { var _a, _b; return (_b = (_a = band.label.style) === null || _a === void 0 ? void 0 : _a.fontWeight) !== null && _b !== void 0 ? _b : null; })
|
|
166
|
+
.style('dominant-baseline', 'text-before-edge')
|
|
167
|
+
.style('text-anchor', 'end')
|
|
168
|
+
.style('transform', `translate(${x + labelPadding}px, ${labelPadding}px) rotate(-90deg)`);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
158
171
|
};
|
|
159
172
|
setPlotBands(plotBeforeContainer, axis.plotBands.filter((d) => d.layerPlacement === 'before'));
|
|
160
173
|
setPlotBands(plotAfterContainer, axis.plotBands.filter((d) => d.layerPlacement === 'after'));
|
|
@@ -174,20 +187,33 @@ export const AxisX = React.memo(function AxisX(props) {
|
|
|
174
187
|
.attr(plotDataAttr, 1)
|
|
175
188
|
.attr(plotLineDataAttr, 1);
|
|
176
189
|
const lineGenerator = line();
|
|
177
|
-
plotLinesSelection
|
|
178
|
-
|
|
179
|
-
|
|
190
|
+
plotLinesSelection.each(function () {
|
|
191
|
+
const itemSelection = select(this);
|
|
192
|
+
const plotLine = itemSelection.datum();
|
|
180
193
|
const plotLineValue = Number(axisScale(plotLine.value));
|
|
181
194
|
const points = [
|
|
182
195
|
[plotLineValue, 0],
|
|
183
196
|
[plotLineValue, totalHeight],
|
|
184
197
|
];
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
198
|
+
itemSelection
|
|
199
|
+
.append('path')
|
|
200
|
+
.attr('d', lineGenerator(points))
|
|
201
|
+
.attr('stroke', plotLine.color)
|
|
202
|
+
.attr('stroke-width', plotLine.width)
|
|
203
|
+
.attr('stroke-dasharray', getLineDashArray(plotLine.dashStyle, plotLine.width))
|
|
204
|
+
.attr('opacity', plotLine.opacity);
|
|
205
|
+
if (plotLine.label.text) {
|
|
206
|
+
itemSelection
|
|
207
|
+
.append('text')
|
|
208
|
+
.text(plotLine.label.text)
|
|
209
|
+
.style('fill', () => { var _a; return (_a = plotLine.label.style.fontColor) !== null && _a !== void 0 ? _a : null; })
|
|
210
|
+
.attr('font-size', plotLine.label.style.fontSize)
|
|
211
|
+
.style('font-weight', () => { var _a; return (_a = plotLine.label.style.fontWeight) !== null && _a !== void 0 ? _a : null; })
|
|
212
|
+
.style('dominant-baseline', 'text-after-edge')
|
|
213
|
+
.style('text-anchor', 'end')
|
|
214
|
+
.style('transform', `translate(${plotLineValue - plotLine.label.padding}px, ${plotLine.label.padding}px) rotate(-90deg)`);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
191
217
|
};
|
|
192
218
|
setPlotLines(plotBeforeContainer, axis.plotLines.filter((d) => d.layerPlacement === 'before'));
|
|
193
219
|
setPlotLines(plotAfterContainer, axis.plotLines.filter((d) => d.layerPlacement === 'after'));
|
|
@@ -172,16 +172,28 @@ export const AxisY = (props) => {
|
|
|
172
172
|
let elementY = 0;
|
|
173
173
|
axisItem
|
|
174
174
|
.selectAll('.tick')
|
|
175
|
-
.
|
|
176
|
-
|
|
177
|
-
const r =
|
|
178
|
-
|
|
175
|
+
.nodes()
|
|
176
|
+
.map((element) => {
|
|
177
|
+
const r = element.getBoundingClientRect();
|
|
178
|
+
return {
|
|
179
|
+
top: r.top,
|
|
180
|
+
bottom: r.bottom,
|
|
181
|
+
node: element,
|
|
182
|
+
};
|
|
183
|
+
}, {})
|
|
184
|
+
.sort((item1, item2) => {
|
|
185
|
+
return item2.top - item1.top;
|
|
186
|
+
})
|
|
187
|
+
.filter(function ({ top, bottom }, tickIndex) {
|
|
188
|
+
if (bottom > elementY && tickIndex !== 0) {
|
|
179
189
|
return true;
|
|
180
190
|
}
|
|
181
|
-
elementY =
|
|
191
|
+
elementY = top - d.labels.padding;
|
|
182
192
|
return false;
|
|
183
193
|
})
|
|
184
|
-
.
|
|
194
|
+
.forEach((item) => {
|
|
195
|
+
item.node.remove();
|
|
196
|
+
});
|
|
185
197
|
}
|
|
186
198
|
if (d.plotBands.length > 0) {
|
|
187
199
|
const plotBandDataAttr = `data-plot-y-band-${index}`;
|
|
@@ -197,25 +209,36 @@ export const AxisY = (props) => {
|
|
|
197
209
|
.attr(plotDataAttr, 1)
|
|
198
210
|
.attr(plotBandDataAttr, 1)
|
|
199
211
|
.style('transform', getAxisPlotsPosition(d, split));
|
|
200
|
-
plotBandsSelection
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
.
|
|
204
|
-
.attr('y', (band) => {
|
|
205
|
-
var _a, _b;
|
|
212
|
+
plotBandsSelection.each(function () {
|
|
213
|
+
var _a, _b, _c, _e;
|
|
214
|
+
const plotBandSelection = select(this);
|
|
215
|
+
const band = plotBandSelection.datum();
|
|
206
216
|
const { from, to } = getBandsPosition({ band, axisScale, axis: 'y' });
|
|
207
217
|
const halfBandwidth = ((_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 0) / 2;
|
|
208
218
|
const startPos = halfBandwidth + Math.min(from, to);
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
+
const endPos = Math.min(Math.abs(to - from), height - Math.min(from, to));
|
|
220
|
+
const y = Math.max(0, startPos);
|
|
221
|
+
plotBandSelection
|
|
222
|
+
.append('rect')
|
|
223
|
+
.attr('x', 0)
|
|
224
|
+
.attr('width', width)
|
|
225
|
+
.attr('y', y)
|
|
226
|
+
.attr('height', Math.min(endPos, height))
|
|
227
|
+
.attr('fill', () => band.color)
|
|
228
|
+
.attr('opacity', () => band.opacity);
|
|
229
|
+
if (band.label.text) {
|
|
230
|
+
const labelPadding = (_e = (_c = band.label) === null || _c === void 0 ? void 0 : _c.padding) !== null && _e !== void 0 ? _e : 0;
|
|
231
|
+
plotBandSelection
|
|
232
|
+
.append('text')
|
|
233
|
+
.text(band.label.text)
|
|
234
|
+
.style('fill', () => { var _a, _b; return (_b = (_a = band.label.style) === null || _a === void 0 ? void 0 : _a.fontColor) !== null && _b !== void 0 ? _b : null; })
|
|
235
|
+
.style('font-size', () => { var _a, _b; return (_b = (_a = band.label.style) === null || _a === void 0 ? void 0 : _a.fontSize) !== null && _b !== void 0 ? _b : null; })
|
|
236
|
+
.style('font-weight', () => { var _a, _b; return (_b = (_a = band.label.style) === null || _a === void 0 ? void 0 : _a.fontWeight) !== null && _b !== void 0 ? _b : null; })
|
|
237
|
+
.style('dominant-baseline', 'text-before-edge')
|
|
238
|
+
.attr('x', labelPadding)
|
|
239
|
+
.attr('y', y + labelPadding);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
219
242
|
};
|
|
220
243
|
setPlotBands(plotBeforeContainer, d.plotBands.filter((item) => item.layerPlacement === 'before'));
|
|
221
244
|
setPlotBands(plotAfterContainer, d.plotBands.filter((item) => item.layerPlacement === 'after'));
|
|
@@ -234,20 +257,32 @@ export const AxisY = (props) => {
|
|
|
234
257
|
.attr(plotDataAttr, 1)
|
|
235
258
|
.attr(plotLineDataAttr, 1)
|
|
236
259
|
.style('transform', getAxisPlotsPosition(d, split));
|
|
237
|
-
plotLinesSelection
|
|
238
|
-
|
|
239
|
-
|
|
260
|
+
plotLinesSelection.each(function () {
|
|
261
|
+
const itemSelection = select(this);
|
|
262
|
+
const plotLine = itemSelection.datum();
|
|
240
263
|
const plotLineValue = Number(axisScale(plotLine.value));
|
|
241
264
|
const points = [
|
|
242
265
|
[0, plotLineValue],
|
|
243
266
|
[width, plotLineValue],
|
|
244
267
|
];
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
268
|
+
itemSelection
|
|
269
|
+
.append('path')
|
|
270
|
+
.attr('d', lineGenerator(points))
|
|
271
|
+
.attr('stroke', plotLine.color)
|
|
272
|
+
.attr('stroke-width', plotLine.width)
|
|
273
|
+
.attr('stroke-dasharray', getLineDashArray(plotLine.dashStyle, plotLine.width))
|
|
274
|
+
.attr('opacity', plotLine.opacity);
|
|
275
|
+
if (plotLine.label.text) {
|
|
276
|
+
itemSelection
|
|
277
|
+
.append('text')
|
|
278
|
+
.text(plotLine.label.text)
|
|
279
|
+
.style('fill', () => { var _a; return (_a = plotLine.label.style.fontColor) !== null && _a !== void 0 ? _a : null; })
|
|
280
|
+
.attr('font-size', plotLine.label.style.fontSize)
|
|
281
|
+
.style('font-weight', () => { var _a; return (_a = plotLine.label.style.fontWeight) !== null && _a !== void 0 ? _a : null; })
|
|
282
|
+
.attr('x', plotLine.label.padding)
|
|
283
|
+
.attr('y', plotLineValue - plotLine.label.padding);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
251
286
|
};
|
|
252
287
|
setPlotLines(plotBeforeContainer, d.plotLines.filter((item) => item.layerPlacement === 'before'));
|
|
253
288
|
setPlotLines(plotAfterContainer, d.plotLines.filter((item) => item.layerPlacement === 'after'));
|
|
@@ -317,6 +352,7 @@ export const AxisY = (props) => {
|
|
|
317
352
|
lineGenerator,
|
|
318
353
|
plotBeforeRef,
|
|
319
354
|
plotAfterRef,
|
|
355
|
+
topLimit,
|
|
320
356
|
]);
|
|
321
357
|
return React.createElement("g", { ref: ref, className: b('container') });
|
|
322
358
|
};
|
|
@@ -21,10 +21,13 @@ export function useChartInnerProps(props) {
|
|
|
21
21
|
title: data.title,
|
|
22
22
|
tooltip: data.tooltip,
|
|
23
23
|
});
|
|
24
|
+
const preparedSeriesOptions = React.useMemo(() => {
|
|
25
|
+
return getPreparedOptions(data.series.options);
|
|
26
|
+
}, [data.series.options]);
|
|
24
27
|
const [zoomState, setZoomState] = React.useState({});
|
|
25
28
|
const sortedSeriesData = React.useMemo(() => {
|
|
26
|
-
return getSortedSeriesData(data.series.data);
|
|
27
|
-
}, [data.series.data]);
|
|
29
|
+
return getSortedSeriesData({ seriesData: data.series.data, yAxes: data.yAxis });
|
|
30
|
+
}, [data.series.data, data.yAxis]);
|
|
28
31
|
const { zoomedSeriesData, zoomedShapesSeriesData } = React.useMemo(() => {
|
|
29
32
|
return getZoomedSeriesData({
|
|
30
33
|
seriesData: sortedSeriesData,
|
|
@@ -41,15 +44,17 @@ export function useChartInnerProps(props) {
|
|
|
41
44
|
const [yAxis, setYAxis] = React.useState([]);
|
|
42
45
|
React.useEffect(() => {
|
|
43
46
|
setYAxis([]);
|
|
44
|
-
getPreparedYAxis({
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
getPreparedYAxis({
|
|
48
|
+
height,
|
|
49
|
+
seriesData: zoomedSeriesData,
|
|
50
|
+
seriesOptions: preparedSeriesOptions,
|
|
51
|
+
yAxis: data.yAxis,
|
|
52
|
+
}).then((val) => setYAxis(val));
|
|
53
|
+
}, [data.yAxis, height, preparedSeriesOptions, zoomedSeriesData]);
|
|
49
54
|
const { preparedSeries, preparedLegend, handleLegendItemClick } = useSeries({
|
|
50
55
|
colors,
|
|
51
56
|
legend: data.legend,
|
|
52
|
-
originalSeriesData:
|
|
57
|
+
originalSeriesData: sortedSeriesData,
|
|
53
58
|
seriesData: zoomedSeriesData,
|
|
54
59
|
seriesOptions: data.series.options,
|
|
55
60
|
});
|
|
@@ -89,9 +94,10 @@ export function useChartInnerProps(props) {
|
|
|
89
94
|
hasZoomX: Boolean(zoomState.x),
|
|
90
95
|
hasZoomY: Boolean(zoomState.y),
|
|
91
96
|
series: preparedSeries,
|
|
97
|
+
seriesOptions: preparedSeriesOptions,
|
|
98
|
+
split: preparedSplit,
|
|
92
99
|
xAxis,
|
|
93
100
|
yAxis,
|
|
94
|
-
split: preparedSplit,
|
|
95
101
|
});
|
|
96
102
|
const isOutsideBounds = React.useCallback((x, y) => {
|
|
97
103
|
return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
|
|
@@ -6,5 +6,6 @@ export interface ChartTooltipContentProps {
|
|
|
6
6
|
yAxis?: ChartYAxis;
|
|
7
7
|
renderer?: ChartTooltip['renderer'];
|
|
8
8
|
valueFormat?: ChartTooltip['valueFormat'];
|
|
9
|
+
totals?: ChartTooltip['totals'];
|
|
9
10
|
}
|
|
10
11
|
export declare const ChartTooltipContent: (props: ChartTooltipContentProps) => React.JSX.Element | null;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import isNil from 'lodash/isNil';
|
|
3
|
-
import {
|
|
3
|
+
import { DefaultTooltipContent } from './DefaultTooltipContent';
|
|
4
4
|
export const ChartTooltipContent = (props) => {
|
|
5
|
-
const { hovered, xAxis, yAxis, renderer, valueFormat } = props;
|
|
5
|
+
const { hovered, xAxis, yAxis, renderer, valueFormat, totals } = props;
|
|
6
6
|
if (!hovered) {
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
9
|
const customTooltip = renderer === null || renderer === void 0 ? void 0 : renderer({ hovered, xAxis, yAxis });
|
|
10
|
-
return isNil(customTooltip) ? (React.createElement(
|
|
10
|
+
return isNil(customTooltip) ? (React.createElement(DefaultTooltipContent, { hovered: hovered, xAxis: xAxis, yAxis: yAxis, valueFormat: valueFormat, totals: totals })) : (customTooltip);
|
|
11
11
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { block } from '../../../utils';
|
|
3
|
+
const b = block('tooltip');
|
|
4
|
+
export function Row(props) {
|
|
5
|
+
const { label, value, active, color, className, striped } = props;
|
|
6
|
+
return (React.createElement("div", { className: b('content-row', { active, striped }, className) },
|
|
7
|
+
color && React.createElement("div", { className: b('content-row-color'), style: { backgroundColor: color } }),
|
|
8
|
+
label,
|
|
9
|
+
React.createElement("span", { className: b('content-row-value') }, value)));
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ChartTooltipTotalsAggregationValue, ChartTooltipTotalsBuiltInAggregation, ValueFormat } from '../../../types';
|
|
3
|
+
import type { HoveredValue } from './utils';
|
|
4
|
+
export declare function RowTotals(props: {
|
|
5
|
+
aggregation: ChartTooltipTotalsBuiltInAggregation | (() => ChartTooltipTotalsAggregationValue);
|
|
6
|
+
values: HoveredValue[];
|
|
7
|
+
label?: string;
|
|
8
|
+
valueFormat?: ValueFormat;
|
|
9
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { block } from '../../../utils';
|
|
3
|
+
import { getFormattedValue } from '../../../utils/chart/format';
|
|
4
|
+
import { Row } from './Row';
|
|
5
|
+
import { getBuiltInAggregatedValue, getBuiltInAggregationLabel } from './utils';
|
|
6
|
+
const b = block('tooltip');
|
|
7
|
+
export function RowTotals(props) {
|
|
8
|
+
const { aggregation, label, valueFormat, values } = props;
|
|
9
|
+
let resultLabel = label;
|
|
10
|
+
if (!resultLabel && typeof aggregation === 'string') {
|
|
11
|
+
resultLabel = getBuiltInAggregationLabel({ aggregation });
|
|
12
|
+
}
|
|
13
|
+
const resultValue = typeof aggregation === 'function'
|
|
14
|
+
? aggregation()
|
|
15
|
+
: getBuiltInAggregatedValue({ aggregation, values });
|
|
16
|
+
const formattedResultValue = typeof resultValue === 'number'
|
|
17
|
+
? getFormattedValue({
|
|
18
|
+
value: resultValue,
|
|
19
|
+
format: valueFormat || { type: 'number' },
|
|
20
|
+
})
|
|
21
|
+
: resultValue;
|
|
22
|
+
return (React.createElement(Row, { className: b('content-row-totals'), label: resultLabel, value: formattedResultValue }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ChartTooltip, ChartXAxis, ChartYAxis, TooltipDataChunk, ValueFormat } from '../../../types';
|
|
3
|
+
type Props = {
|
|
4
|
+
hovered: TooltipDataChunk[];
|
|
5
|
+
totals?: ChartTooltip['totals'];
|
|
6
|
+
valueFormat?: ValueFormat;
|
|
7
|
+
xAxis?: ChartXAxis | null;
|
|
8
|
+
yAxis?: ChartYAxis;
|
|
9
|
+
};
|
|
10
|
+
export declare const DefaultTooltipContent: ({ hovered, xAxis, yAxis, valueFormat, totals }: Props) => React.JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Divider } from '@gravity-ui/uikit';
|
|
3
|
+
import get from 'lodash/get';
|
|
4
|
+
import { block } from '../../../utils';
|
|
5
|
+
import { getFormattedValue } from '../../../utils/chart/format';
|
|
6
|
+
import { Row } from './Row';
|
|
7
|
+
import { RowTotals } from './RowTotals';
|
|
8
|
+
import { getDefaultValueFormat, getHoveredValues, getMeasureValue, getPreparedAggregation, getXRowData, } from './utils';
|
|
9
|
+
const b = block('tooltip');
|
|
10
|
+
export const DefaultTooltipContent = ({ hovered, xAxis, yAxis, valueFormat, totals }) => {
|
|
11
|
+
const measureValue = getMeasureValue({ data: hovered, xAxis, yAxis });
|
|
12
|
+
const hoveredValues = getHoveredValues({ hovered, xAxis, yAxis });
|
|
13
|
+
return (React.createElement("div", { className: b('content') },
|
|
14
|
+
measureValue && React.createElement("div", { className: b('series-name') }, measureValue),
|
|
15
|
+
// eslint-disable-next-line complexity
|
|
16
|
+
hovered.map((seriesItem, i) => {
|
|
17
|
+
var _a;
|
|
18
|
+
const { data, series, closest } = seriesItem;
|
|
19
|
+
const id = `${get(series, 'id')}_${i}`;
|
|
20
|
+
const color = get(data, 'color') || get(series, 'color');
|
|
21
|
+
const active = closest && hovered.length > 1;
|
|
22
|
+
const striped = (i + 1) % 2 === 0;
|
|
23
|
+
switch (series.type) {
|
|
24
|
+
case 'scatter':
|
|
25
|
+
case 'line':
|
|
26
|
+
case 'area':
|
|
27
|
+
case 'bar-x': {
|
|
28
|
+
const format = valueFormat || getDefaultValueFormat({ axis: yAxis });
|
|
29
|
+
const formattedValue = getFormattedValue({
|
|
30
|
+
value: hoveredValues[i],
|
|
31
|
+
format,
|
|
32
|
+
});
|
|
33
|
+
return (React.createElement(Row, { key: id, active: active, color: color, label: series.name, striped: striped, value: formattedValue }));
|
|
34
|
+
}
|
|
35
|
+
case 'waterfall': {
|
|
36
|
+
const isTotal = get(data, 'total', false);
|
|
37
|
+
const subTotalValue = (_a = seriesItem.subTotal) !== null && _a !== void 0 ? _a : 0;
|
|
38
|
+
const format = valueFormat || getDefaultValueFormat({ axis: yAxis });
|
|
39
|
+
const subTotal = getFormattedValue({
|
|
40
|
+
value: subTotalValue,
|
|
41
|
+
format,
|
|
42
|
+
});
|
|
43
|
+
const formattedValue = getFormattedValue({
|
|
44
|
+
value: hoveredValues[i],
|
|
45
|
+
format,
|
|
46
|
+
});
|
|
47
|
+
return (React.createElement(React.Fragment, { key: id },
|
|
48
|
+
!isTotal && (React.createElement(React.Fragment, null,
|
|
49
|
+
React.createElement("div", { className: b('series-name') }, getXRowData(data, xAxis)),
|
|
50
|
+
React.createElement(Row, { label: series.name, value: formattedValue }))),
|
|
51
|
+
React.createElement(Row, { label: isTotal ? 'Total' : 'Subtotal', value: subTotal })));
|
|
52
|
+
}
|
|
53
|
+
case 'bar-y': {
|
|
54
|
+
const format = valueFormat || getDefaultValueFormat({ axis: xAxis });
|
|
55
|
+
const formattedValue = getFormattedValue({
|
|
56
|
+
value: hoveredValues[i],
|
|
57
|
+
format,
|
|
58
|
+
});
|
|
59
|
+
return (React.createElement(Row, { key: id, active: active, color: color, label: series.name, striped: striped, value: formattedValue }));
|
|
60
|
+
}
|
|
61
|
+
case 'pie':
|
|
62
|
+
case 'treemap': {
|
|
63
|
+
const seriesData = data;
|
|
64
|
+
const formattedValue = getFormattedValue({
|
|
65
|
+
value: hoveredValues[i],
|
|
66
|
+
format: valueFormat || { type: 'number' },
|
|
67
|
+
});
|
|
68
|
+
return (React.createElement(Row, { key: id, color: color, label: React.createElement("span", { dangerouslySetInnerHTML: {
|
|
69
|
+
__html: [seriesData.name || seriesData.id]
|
|
70
|
+
.flat()
|
|
71
|
+
.join('\n'),
|
|
72
|
+
} }), value: formattedValue }));
|
|
73
|
+
}
|
|
74
|
+
case 'sankey': {
|
|
75
|
+
const { target, data: source } = seriesItem;
|
|
76
|
+
const formattedValue = getFormattedValue({
|
|
77
|
+
value: hoveredValues[i],
|
|
78
|
+
format: valueFormat || { type: 'number' },
|
|
79
|
+
});
|
|
80
|
+
return (React.createElement(Row, { key: id, color: source.color, label: React.createElement("span", null,
|
|
81
|
+
source.name,
|
|
82
|
+
" \u2192 ", target === null || target === void 0 ? void 0 :
|
|
83
|
+
target.name,
|
|
84
|
+
":"), value: formattedValue }));
|
|
85
|
+
}
|
|
86
|
+
case 'radar': {
|
|
87
|
+
const radarSeries = series;
|
|
88
|
+
const formattedValue = getFormattedValue({
|
|
89
|
+
value: hoveredValues[i],
|
|
90
|
+
format: valueFormat || { type: 'number' },
|
|
91
|
+
});
|
|
92
|
+
return (React.createElement(Row, { key: id, active: active, color: color, label: radarSeries.name || radarSeries.id, value: formattedValue }));
|
|
93
|
+
}
|
|
94
|
+
default: {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}),
|
|
99
|
+
(totals === null || totals === void 0 ? void 0 : totals.enabled) && hovered.length > 1 && (React.createElement(React.Fragment, null,
|
|
100
|
+
React.createElement(Divider, { className: b('content-row-totals-divider') }),
|
|
101
|
+
React.createElement(RowTotals, { aggregation: getPreparedAggregation({ hovered, totals, xAxis, yAxis }), label: totals.label, values: hoveredValues, valueFormat: valueFormat })))));
|
|
102
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ChartSeriesData, ChartTooltip, ChartTooltipTotalsAggregationValue, ChartTooltipTotalsBuiltInAggregation, ChartXAxis, ChartYAxis, TooltipDataChunk, ValueFormat } from '../../../types';
|
|
2
|
+
export type HoveredValue = string | number | null | undefined;
|
|
3
|
+
export declare function getXRowData(data: ChartSeriesData, xAxis?: ChartXAxis | null): string | number | undefined;
|
|
4
|
+
export declare function getDefaultValueFormat({ axis, }: {
|
|
5
|
+
axis?: ChartXAxis | ChartYAxis | null;
|
|
6
|
+
}): ValueFormat | undefined;
|
|
7
|
+
export declare const getMeasureValue: ({ data, xAxis, yAxis, valueFormat, }: {
|
|
8
|
+
data: TooltipDataChunk[];
|
|
9
|
+
xAxis?: ChartXAxis | null;
|
|
10
|
+
yAxis?: ChartYAxis;
|
|
11
|
+
valueFormat?: ValueFormat;
|
|
12
|
+
}) => string | null;
|
|
13
|
+
export declare function getHoveredValues(args: {
|
|
14
|
+
hovered: TooltipDataChunk[];
|
|
15
|
+
xAxis?: ChartXAxis | null;
|
|
16
|
+
yAxis?: ChartYAxis;
|
|
17
|
+
}): HoveredValue[];
|
|
18
|
+
export declare function getBuiltInAggregatedValue(args: {
|
|
19
|
+
aggregation: ChartTooltipTotalsBuiltInAggregation;
|
|
20
|
+
values: HoveredValue[];
|
|
21
|
+
}): number | undefined;
|
|
22
|
+
export declare function getBuiltInAggregationLabel(args: {
|
|
23
|
+
aggregation: ChartTooltipTotalsBuiltInAggregation;
|
|
24
|
+
}): string;
|
|
25
|
+
export declare function getPreparedAggregation(args: {
|
|
26
|
+
hovered: TooltipDataChunk[];
|
|
27
|
+
totals?: ChartTooltip['totals'];
|
|
28
|
+
xAxis?: ChartXAxis | null;
|
|
29
|
+
yAxis?: ChartYAxis;
|
|
30
|
+
}): ChartTooltipTotalsBuiltInAggregation | (() => ChartTooltipTotalsAggregationValue);
|