@gravity-ui/charts 1.37.2 → 1.38.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/ChartInner/index.js +2 -1
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +0 -2
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +1 -4
- package/dist/cjs/components/Legend/index.js +20 -22
- package/dist/cjs/hooks/useChartOptions/tooltip.d.ts +5 -0
- package/dist/cjs/hooks/useChartOptions/tooltip.js +2 -2
- package/dist/cjs/hooks/useSeries/prepare-legend.js +2 -2
- package/dist/cjs/hooks/useSeries/prepare-line.js +3 -1
- package/dist/cjs/hooks/useSeries/types.d.ts +3 -1
- package/dist/cjs/hooks/useSeries/utils.js +6 -2
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/utils/chart/symbol.d.ts +4 -0
- package/dist/cjs/utils/chart/symbol.js +15 -0
- package/dist/cjs/utils/chart/text.js +4 -6
- package/dist/esm/components/ChartInner/index.js +2 -1
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +0 -2
- package/dist/esm/components/ChartInner/useChartInnerProps.js +1 -4
- package/dist/esm/components/Legend/index.js +20 -22
- package/dist/esm/hooks/useChartOptions/tooltip.d.ts +5 -0
- package/dist/esm/hooks/useChartOptions/tooltip.js +2 -2
- package/dist/esm/hooks/useSeries/prepare-legend.js +2 -2
- package/dist/esm/hooks/useSeries/prepare-line.js +3 -1
- package/dist/esm/hooks/useSeries/types.d.ts +3 -1
- package/dist/esm/hooks/useSeries/utils.js +6 -2
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/utils/chart/symbol.d.ts +4 -0
- package/dist/esm/utils/chart/symbol.js +15 -0
- package/dist/esm/utils/chart/text.js +4 -6
- package/package.json +1 -1
|
@@ -66,7 +66,8 @@ export const ChartInner = (props) => {
|
|
|
66
66
|
const { allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit, prevHeight, prevWidth, shapes, shapesData, shapesReady, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
67
67
|
dispatcher,
|
|
68
68
|
htmlLayout, plotNode: plotRef.current, preparedChart,
|
|
69
|
-
rangeSliderState,
|
|
69
|
+
rangeSliderState,
|
|
70
|
+
updateZoomState,
|
|
70
71
|
zoomState }));
|
|
71
72
|
const debouncedBoundsWidth = useDebouncedValue({
|
|
72
73
|
value: boundsWidth,
|
|
@@ -9,7 +9,6 @@ type Props = ChartInnerProps & {
|
|
|
9
9
|
htmlLayout: HTMLElement | null;
|
|
10
10
|
plotNode: SVGGElement | null;
|
|
11
11
|
preparedChart: PreparedChart;
|
|
12
|
-
svgContainer: SVGGElement | null;
|
|
13
12
|
updateZoomState: (nextZoomState: Partial<ZoomState>) => void;
|
|
14
13
|
zoomState: Partial<ZoomState>;
|
|
15
14
|
rangeSliderState?: RangeSliderState;
|
|
@@ -44,7 +43,6 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
44
43
|
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
45
44
|
shapesData: import("../../hooks").ShapeData[];
|
|
46
45
|
shapesReady: boolean;
|
|
47
|
-
svgXPos: number | undefined;
|
|
48
46
|
xAxis: import("../../hooks").PreparedXAxis | null;
|
|
49
47
|
xScale: import("../../hooks").ChartScale | undefined;
|
|
50
48
|
yAxis: (Omit<import("../../types").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
|
|
@@ -75,8 +75,7 @@ export function useLegend({ preparedLegend, preparedChart, preparedSeries, width
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
export function useChartInnerProps(props) {
|
|
78
|
-
|
|
79
|
-
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, svgContainer, width, updateZoomState, zoomState, } = props;
|
|
78
|
+
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, width, updateZoomState, zoomState, } = props;
|
|
80
79
|
const prevWidth = usePrevious(width);
|
|
81
80
|
const prevHeight = usePrevious(height);
|
|
82
81
|
const colors = React.useMemo(() => {
|
|
@@ -214,7 +213,6 @@ export function useChartInnerProps(props) {
|
|
|
214
213
|
getYAxisWidth,
|
|
215
214
|
legendConfig,
|
|
216
215
|
});
|
|
217
|
-
const { x } = (_a = svgContainer === null || svgContainer === void 0 ? void 0 : svgContainer.getBoundingClientRect()) !== null && _a !== void 0 ? _a : {};
|
|
218
216
|
return {
|
|
219
217
|
allPreparedSeries,
|
|
220
218
|
boundsHeight,
|
|
@@ -234,7 +232,6 @@ export function useChartInnerProps(props) {
|
|
|
234
232
|
shapes,
|
|
235
233
|
shapesData,
|
|
236
234
|
shapesReady,
|
|
237
|
-
svgXPos: x,
|
|
238
235
|
xAxis,
|
|
239
236
|
xScale,
|
|
240
237
|
yAxis,
|
|
@@ -71,7 +71,7 @@ function renderLegendSymbol(args) {
|
|
|
71
71
|
const getXPosition = (i) => {
|
|
72
72
|
return line.slice(0, i).reduce((acc, legendItem) => {
|
|
73
73
|
return (acc +
|
|
74
|
-
legendItem.symbol.
|
|
74
|
+
legendItem.symbol.bboxWidth +
|
|
75
75
|
legendItem.symbol.padding +
|
|
76
76
|
legendItem.textWidth +
|
|
77
77
|
legend.itemDistance);
|
|
@@ -82,13 +82,15 @@ function renderLegendSymbol(args) {
|
|
|
82
82
|
const x = getXPosition(i);
|
|
83
83
|
const className = b('item-symbol', { shape: d.symbol.shape, unselected: !d.visible });
|
|
84
84
|
const color = d.visible ? d.color : '';
|
|
85
|
+
const symbolType = d.symbol.symbolType;
|
|
86
|
+
const scatterSymbol = getSymbol(symbolType);
|
|
85
87
|
switch (d.symbol.shape) {
|
|
86
88
|
case 'path': {
|
|
87
89
|
appendLinePathElement({
|
|
88
90
|
svgRootElement: element.node(),
|
|
89
91
|
x,
|
|
90
92
|
height: legendLineHeight,
|
|
91
|
-
width: d.symbol.
|
|
93
|
+
width: d.symbol.bboxWidth,
|
|
92
94
|
color,
|
|
93
95
|
className,
|
|
94
96
|
dashStyle: d.dashStyle,
|
|
@@ -102,7 +104,7 @@ function renderLegendSymbol(args) {
|
|
|
102
104
|
.append('rect')
|
|
103
105
|
.attr('x', x)
|
|
104
106
|
.attr('y', y)
|
|
105
|
-
.attr('width', d.symbol.
|
|
107
|
+
.attr('width', d.symbol.bboxWidth)
|
|
106
108
|
.attr('height', d.symbol.height)
|
|
107
109
|
.attr('rx', d.symbol.radius)
|
|
108
110
|
.attr('class', className)
|
|
@@ -110,18 +112,14 @@ function renderLegendSymbol(args) {
|
|
|
110
112
|
break;
|
|
111
113
|
}
|
|
112
114
|
case 'symbol': {
|
|
115
|
+
const symbolAreaSize = Math.pow(d.symbol.width, 2);
|
|
113
116
|
const y = legendLineHeight / 2;
|
|
117
|
+
const bboxWidth = d.symbol.bboxWidth;
|
|
114
118
|
element
|
|
115
119
|
.append('svg:path')
|
|
116
|
-
.attr('d', () =>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// https://d3js.org/d3-shape/symbol#symbol
|
|
120
|
-
return symbol(scatterSymbol, d.symbol.width * d.symbol.width)();
|
|
121
|
-
})
|
|
122
|
-
.attr('transform', (_d, _index, elements) => {
|
|
123
|
-
var _a, _b;
|
|
124
|
-
const translateX = x + ((_b = (_a = elements[0]) === null || _a === void 0 ? void 0 : _a.getBBox()) === null || _b === void 0 ? void 0 : _b.width) / 2;
|
|
120
|
+
.attr('d', () => symbol(scatterSymbol, symbolAreaSize)())
|
|
121
|
+
.attr('transform', () => {
|
|
122
|
+
const translateX = x + bboxWidth / 2;
|
|
125
123
|
return 'translate(' + translateX + ',' + y + ')';
|
|
126
124
|
})
|
|
127
125
|
.attr('class', className)
|
|
@@ -140,7 +138,7 @@ export const Legend = (props) => {
|
|
|
140
138
|
}, [config.maxWidth]);
|
|
141
139
|
React.useEffect(() => {
|
|
142
140
|
async function prepareLegend() {
|
|
143
|
-
var _a, _b, _c, _e, _f, _g, _h
|
|
141
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
144
142
|
if (!ref.current || !htmlLayout) {
|
|
145
143
|
return;
|
|
146
144
|
}
|
|
@@ -157,7 +155,7 @@ export const Legend = (props) => {
|
|
|
157
155
|
let legendTop = 0;
|
|
158
156
|
if (legend.type === 'discrete') {
|
|
159
157
|
const start = (_b = (_a = config.pagination) === null || _a === void 0 ? void 0 : _a.pages[pageIndex]) === null || _b === void 0 ? void 0 : _b.start;
|
|
160
|
-
const end = (
|
|
158
|
+
const end = (_d = (_c = config.pagination) === null || _c === void 0 ? void 0 : _c.pages[pageIndex]) === null || _d === void 0 ? void 0 : _d.end;
|
|
161
159
|
const pageItems = typeof start === 'number' && typeof end === 'number'
|
|
162
160
|
? items.slice(start, end)
|
|
163
161
|
: items;
|
|
@@ -178,7 +176,7 @@ export const Legend = (props) => {
|
|
|
178
176
|
const getXPosition = (i) => {
|
|
179
177
|
return line.slice(0, i).reduce((acc, legendItem) => {
|
|
180
178
|
return (acc +
|
|
181
|
-
legendItem.symbol.
|
|
179
|
+
legendItem.symbol.bboxWidth +
|
|
182
180
|
legendItem.symbol.padding +
|
|
183
181
|
legendItem.textWidth +
|
|
184
182
|
legend.itemDistance);
|
|
@@ -202,7 +200,7 @@ export const Legend = (props) => {
|
|
|
202
200
|
return `${d.textWidth}px`;
|
|
203
201
|
})
|
|
204
202
|
.style('left', function (d, i) {
|
|
205
|
-
return `${getXPosition(i) + d.symbol.
|
|
203
|
+
return `${getXPosition(i) + d.symbol.bboxWidth + d.symbol.padding}px`;
|
|
206
204
|
})
|
|
207
205
|
.style('top', function (d) {
|
|
208
206
|
if (d.height < legendLineHeight) {
|
|
@@ -221,7 +219,7 @@ export const Legend = (props) => {
|
|
|
221
219
|
.append('text')
|
|
222
220
|
.attr('x', function (legendItem, i) {
|
|
223
221
|
return (getXPosition(i) +
|
|
224
|
-
legendItem.symbol.
|
|
222
|
+
legendItem.symbol.bboxWidth +
|
|
225
223
|
legendItem.symbol.padding);
|
|
226
224
|
})
|
|
227
225
|
.attr('height', legend.height)
|
|
@@ -238,7 +236,7 @@ export const Legend = (props) => {
|
|
|
238
236
|
}
|
|
239
237
|
else {
|
|
240
238
|
contentWidth = line.reduce((sum, l, index) => {
|
|
241
|
-
sum += l.textWidth + l.symbol.
|
|
239
|
+
sum += l.textWidth + l.symbol.bboxWidth + l.symbol.padding;
|
|
242
240
|
if (index > 0) {
|
|
243
241
|
sum += legend.itemDistance;
|
|
244
242
|
}
|
|
@@ -311,7 +309,7 @@ export const Legend = (props) => {
|
|
|
311
309
|
legendLeft = left;
|
|
312
310
|
legendTop = top;
|
|
313
311
|
// gradient rect
|
|
314
|
-
const domain = (
|
|
312
|
+
const domain = (_e = legend.colorScale.domain) !== null && _e !== void 0 ? _e : [];
|
|
315
313
|
const rectHeight = CONTINUOUS_LEGEND_SIZE.height;
|
|
316
314
|
svgElement.call(createGradientRect, {
|
|
317
315
|
y: legend.title.height + legend.title.margin,
|
|
@@ -380,9 +378,9 @@ export const Legend = (props) => {
|
|
|
380
378
|
.attr('class', legendTitleClassname)
|
|
381
379
|
.append('text')
|
|
382
380
|
.attr('dx', dx)
|
|
383
|
-
.attr('font-weight', (
|
|
384
|
-
.attr('font-size', (
|
|
385
|
-
.attr('fill', (
|
|
381
|
+
.attr('font-weight', (_f = legend.title.style.fontWeight) !== null && _f !== void 0 ? _f : null)
|
|
382
|
+
.attr('font-size', (_g = legend.title.style.fontSize) !== null && _g !== void 0 ? _g : null)
|
|
383
|
+
.attr('fill', (_h = legend.title.style.fontColor) !== null && _h !== void 0 ? _h : null)
|
|
386
384
|
.style('dominant-baseline', 'text-before-edge')
|
|
387
385
|
.html(legend.title.text);
|
|
388
386
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { ChartData, ChartSeries, ChartXAxis, ChartYAxis } from '../../types';
|
|
2
2
|
import type { PreparedTooltip } from './types';
|
|
3
|
+
export declare function getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis, }: {
|
|
4
|
+
seriesData: ChartSeries[];
|
|
5
|
+
yAxes?: ChartYAxis[];
|
|
6
|
+
xAxis?: ChartXAxis;
|
|
7
|
+
}): import("../../types").ValueFormat | undefined;
|
|
3
8
|
export declare const getPreparedTooltip: (args: {
|
|
4
9
|
tooltip: ChartData["tooltip"];
|
|
5
10
|
seriesData: ChartSeries[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import { getDefaultValueFormat } from '../../components/Tooltip/DefaultTooltipContent/utils';
|
|
3
3
|
import { getDomainDataXBySeries, getDomainDataYBySeries, getMinSpaceBetween } from '../../utils';
|
|
4
|
-
function
|
|
4
|
+
export function getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis, }) {
|
|
5
5
|
if (seriesData.every((item) => ['pie', 'treemap', 'waterfall', 'sankey', 'radar', 'heatmap', 'funnel'].includes(item.type))) {
|
|
6
6
|
return undefined;
|
|
7
7
|
}
|
|
@@ -17,5 +17,5 @@ function getDefaultHeaderFormat({ seriesData, yAxes, xAxis, }) {
|
|
|
17
17
|
export const getPreparedTooltip = (args) => {
|
|
18
18
|
var _a, _b;
|
|
19
19
|
const { tooltip, seriesData, yAxes, xAxis } = args;
|
|
20
|
-
return Object.assign(Object.assign({}, tooltip), { enabled: get(tooltip, 'enabled', true), throttle: (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.throttle) !== null && _a !== void 0 ? _a : 0, headerFormat: (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.headerFormat) !== null && _b !== void 0 ? _b :
|
|
20
|
+
return Object.assign(Object.assign({}, tooltip), { enabled: get(tooltip, 'enabled', true), throttle: (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.throttle) !== null && _a !== void 0 ? _a : 0, headerFormat: (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.headerFormat) !== null && _b !== void 0 ? _b : getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis }) });
|
|
21
21
|
};
|
|
@@ -101,7 +101,7 @@ async function getGroupedLegendItems(args) {
|
|
|
101
101
|
const item = items[i];
|
|
102
102
|
const resultItem = clone(item);
|
|
103
103
|
resultItem.text = item.name;
|
|
104
|
-
const maxTextWidth = maxLegendWidth - resultItem.symbol.
|
|
104
|
+
const maxTextWidth = maxLegendWidth - resultItem.symbol.bboxWidth - resultItem.symbol.padding;
|
|
105
105
|
let textHeight = 0;
|
|
106
106
|
let textWidth = 0;
|
|
107
107
|
if (preparedLegend.html) {
|
|
@@ -143,7 +143,7 @@ async function getGroupedLegendItems(args) {
|
|
|
143
143
|
}
|
|
144
144
|
result[lineIndex].push(resultItem);
|
|
145
145
|
const symbolsWidth = result[lineIndex].reduce((acc, { symbol }) => {
|
|
146
|
-
return acc + symbol.
|
|
146
|
+
return acc + symbol.bboxWidth + symbol.padding;
|
|
147
147
|
}, 0);
|
|
148
148
|
const distancesWidth = (result[lineIndex].length - 1) * preparedLegend.itemDistance;
|
|
149
149
|
const isOverflowedAsOnlyItemInLine = resultItem.overflowed && result[lineIndex].length === 1;
|
|
@@ -22,9 +22,11 @@ function prepareLineLegendSymbol(series, seriesOptions) {
|
|
|
22
22
|
var _a;
|
|
23
23
|
const symbolOptions = ((_a = series.legend) === null || _a === void 0 ? void 0 : _a.symbol) || {};
|
|
24
24
|
const defaultLineWidth = get(seriesOptions, 'line.lineWidth', DEFAULT_LINE_WIDTH);
|
|
25
|
+
const width = (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.width) || DEFAULT_LEGEND_SYMBOL_SIZE;
|
|
25
26
|
return {
|
|
26
27
|
shape: 'path',
|
|
27
|
-
width:
|
|
28
|
+
width: width,
|
|
29
|
+
bboxWidth: width,
|
|
28
30
|
padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || DEFAULT_LEGEND_SYMBOL_PADDING,
|
|
29
31
|
strokeWidth: get(series, 'lineWidth', defaultLineWidth),
|
|
30
32
|
};
|
|
@@ -11,7 +11,9 @@ export type SymbolLegendSymbol = {
|
|
|
11
11
|
shape: 'symbol';
|
|
12
12
|
symbolType: `${SymbolType}`;
|
|
13
13
|
} & Required<SymbolLegendSymbolOptions>;
|
|
14
|
-
export type PreparedLegendSymbol = RectLegendSymbol | PathLegendSymbol | SymbolLegendSymbol
|
|
14
|
+
export type PreparedLegendSymbol = (RectLegendSymbol | PathLegendSymbol | SymbolLegendSymbol) & {
|
|
15
|
+
bboxWidth: number;
|
|
16
|
+
};
|
|
15
17
|
export type PreparedLegend = Required<Omit<ChartLegend, 'title' | 'colorScale'>> & {
|
|
16
18
|
height: number;
|
|
17
19
|
lineHeight: number;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import memoize from 'lodash/memoize';
|
|
2
2
|
import { SymbolType } from '../../constants';
|
|
3
|
+
import { getSymbolBBoxWidth } from '../../utils';
|
|
3
4
|
import { getUniqId } from '../../utils/misc';
|
|
4
5
|
import { DEFAULT_LEGEND_SYMBOL_PADDING, DEFAULT_LEGEND_SYMBOL_SIZE } from './constants';
|
|
5
6
|
export const getActiveLegendItems = (series) => {
|
|
@@ -16,10 +17,13 @@ export const getAllLegendItems = (series) => {
|
|
|
16
17
|
export function prepareLegendSymbol(series, symbolType) {
|
|
17
18
|
var _a;
|
|
18
19
|
const symbolOptions = ((_a = series.legend) === null || _a === void 0 ? void 0 : _a.symbol) || {};
|
|
20
|
+
const width = (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.width) || DEFAULT_LEGEND_SYMBOL_SIZE;
|
|
21
|
+
const type = symbolType || SymbolType.Circle;
|
|
19
22
|
return {
|
|
20
23
|
shape: 'symbol',
|
|
21
|
-
symbolType:
|
|
22
|
-
width
|
|
24
|
+
symbolType: type,
|
|
25
|
+
width,
|
|
26
|
+
bboxWidth: getSymbolBBoxWidth({ symbolSize: Math.pow(width, 2), symbolType: type }),
|
|
23
27
|
padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || DEFAULT_LEGEND_SYMBOL_PADDING,
|
|
24
28
|
};
|
|
25
29
|
}
|
package/dist/cjs/index.d.ts
CHANGED
package/dist/cjs/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { SymbolType } from '../../constants';
|
|
2
2
|
export declare const getSymbolType: (index: number) => SymbolType;
|
|
3
3
|
export declare const getSymbol: (symbolType: `${SymbolType}`) => import("d3-shape").SymbolType;
|
|
4
|
+
export declare function getSymbolBBoxWidth({ symbolSize, symbolType, }: {
|
|
5
|
+
symbolSize: number;
|
|
6
|
+
symbolType: `${SymbolType}`;
|
|
7
|
+
}): number;
|
|
@@ -34,3 +34,18 @@ export const getSymbol = (symbolType) => {
|
|
|
34
34
|
return symbolCircle;
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
+
export function getSymbolBBoxWidth({ symbolSize, symbolType, }) {
|
|
38
|
+
switch (symbolType) {
|
|
39
|
+
case SymbolType.Diamond:
|
|
40
|
+
return Math.sqrt(symbolSize * 2);
|
|
41
|
+
case SymbolType.Circle:
|
|
42
|
+
return Math.sqrt(symbolSize / Math.PI) * 2;
|
|
43
|
+
case SymbolType.Square:
|
|
44
|
+
return Math.sqrt(symbolSize);
|
|
45
|
+
case SymbolType.Triangle:
|
|
46
|
+
case SymbolType.TriangleDown:
|
|
47
|
+
return Math.sqrt((4 * symbolSize * Math.sqrt(3)) / 3);
|
|
48
|
+
default:
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -176,9 +176,6 @@ function unescapeHtml(str) {
|
|
|
176
176
|
return result.replace(value, key);
|
|
177
177
|
}, str);
|
|
178
178
|
}
|
|
179
|
-
function getCssStyle(prop, el = document.body) {
|
|
180
|
-
return window.getComputedStyle(el, null).getPropertyValue(prop);
|
|
181
|
-
}
|
|
182
179
|
let measureCanvas = null;
|
|
183
180
|
export function getTextSizeFn({ style }) {
|
|
184
181
|
var _a;
|
|
@@ -188,9 +185,10 @@ export function getTextSizeFn({ style }) {
|
|
|
188
185
|
throw new Error("Couldn't get canvas context");
|
|
189
186
|
}
|
|
190
187
|
const element = (_a = document.getElementsByClassName(b())[0]) !== null && _a !== void 0 ? _a : document.body;
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
const
|
|
188
|
+
const computedStyle = window.getComputedStyle(element, null);
|
|
189
|
+
const defaultFontFamily = computedStyle.getPropertyValue('font-family');
|
|
190
|
+
const defaultFontSize = computedStyle.getPropertyValue('font-size');
|
|
191
|
+
const defaultFontWeight = computedStyle.getPropertyValue('font-weight');
|
|
194
192
|
return async (str) => {
|
|
195
193
|
var _a, _b;
|
|
196
194
|
await document.fonts.ready;
|
|
@@ -66,7 +66,8 @@ export const ChartInner = (props) => {
|
|
|
66
66
|
const { allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit, prevHeight, prevWidth, shapes, shapesData, shapesReady, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
67
67
|
dispatcher,
|
|
68
68
|
htmlLayout, plotNode: plotRef.current, preparedChart,
|
|
69
|
-
rangeSliderState,
|
|
69
|
+
rangeSliderState,
|
|
70
|
+
updateZoomState,
|
|
70
71
|
zoomState }));
|
|
71
72
|
const debouncedBoundsWidth = useDebouncedValue({
|
|
72
73
|
value: boundsWidth,
|
|
@@ -9,7 +9,6 @@ type Props = ChartInnerProps & {
|
|
|
9
9
|
htmlLayout: HTMLElement | null;
|
|
10
10
|
plotNode: SVGGElement | null;
|
|
11
11
|
preparedChart: PreparedChart;
|
|
12
|
-
svgContainer: SVGGElement | null;
|
|
13
12
|
updateZoomState: (nextZoomState: Partial<ZoomState>) => void;
|
|
14
13
|
zoomState: Partial<ZoomState>;
|
|
15
14
|
rangeSliderState?: RangeSliderState;
|
|
@@ -44,7 +43,6 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
44
43
|
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
45
44
|
shapesData: import("../../hooks").ShapeData[];
|
|
46
45
|
shapesReady: boolean;
|
|
47
|
-
svgXPos: number | undefined;
|
|
48
46
|
xAxis: import("../../hooks").PreparedXAxis | null;
|
|
49
47
|
xScale: import("../../hooks").ChartScale | undefined;
|
|
50
48
|
yAxis: (Omit<import("../..").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
|
|
@@ -75,8 +75,7 @@ export function useLegend({ preparedLegend, preparedChart, preparedSeries, width
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
export function useChartInnerProps(props) {
|
|
78
|
-
|
|
79
|
-
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, svgContainer, width, updateZoomState, zoomState, } = props;
|
|
78
|
+
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, width, updateZoomState, zoomState, } = props;
|
|
80
79
|
const prevWidth = usePrevious(width);
|
|
81
80
|
const prevHeight = usePrevious(height);
|
|
82
81
|
const colors = React.useMemo(() => {
|
|
@@ -214,7 +213,6 @@ export function useChartInnerProps(props) {
|
|
|
214
213
|
getYAxisWidth,
|
|
215
214
|
legendConfig,
|
|
216
215
|
});
|
|
217
|
-
const { x } = (_a = svgContainer === null || svgContainer === void 0 ? void 0 : svgContainer.getBoundingClientRect()) !== null && _a !== void 0 ? _a : {};
|
|
218
216
|
return {
|
|
219
217
|
allPreparedSeries,
|
|
220
218
|
boundsHeight,
|
|
@@ -234,7 +232,6 @@ export function useChartInnerProps(props) {
|
|
|
234
232
|
shapes,
|
|
235
233
|
shapesData,
|
|
236
234
|
shapesReady,
|
|
237
|
-
svgXPos: x,
|
|
238
235
|
xAxis,
|
|
239
236
|
xScale,
|
|
240
237
|
yAxis,
|
|
@@ -71,7 +71,7 @@ function renderLegendSymbol(args) {
|
|
|
71
71
|
const getXPosition = (i) => {
|
|
72
72
|
return line.slice(0, i).reduce((acc, legendItem) => {
|
|
73
73
|
return (acc +
|
|
74
|
-
legendItem.symbol.
|
|
74
|
+
legendItem.symbol.bboxWidth +
|
|
75
75
|
legendItem.symbol.padding +
|
|
76
76
|
legendItem.textWidth +
|
|
77
77
|
legend.itemDistance);
|
|
@@ -82,13 +82,15 @@ function renderLegendSymbol(args) {
|
|
|
82
82
|
const x = getXPosition(i);
|
|
83
83
|
const className = b('item-symbol', { shape: d.symbol.shape, unselected: !d.visible });
|
|
84
84
|
const color = d.visible ? d.color : '';
|
|
85
|
+
const symbolType = d.symbol.symbolType;
|
|
86
|
+
const scatterSymbol = getSymbol(symbolType);
|
|
85
87
|
switch (d.symbol.shape) {
|
|
86
88
|
case 'path': {
|
|
87
89
|
appendLinePathElement({
|
|
88
90
|
svgRootElement: element.node(),
|
|
89
91
|
x,
|
|
90
92
|
height: legendLineHeight,
|
|
91
|
-
width: d.symbol.
|
|
93
|
+
width: d.symbol.bboxWidth,
|
|
92
94
|
color,
|
|
93
95
|
className,
|
|
94
96
|
dashStyle: d.dashStyle,
|
|
@@ -102,7 +104,7 @@ function renderLegendSymbol(args) {
|
|
|
102
104
|
.append('rect')
|
|
103
105
|
.attr('x', x)
|
|
104
106
|
.attr('y', y)
|
|
105
|
-
.attr('width', d.symbol.
|
|
107
|
+
.attr('width', d.symbol.bboxWidth)
|
|
106
108
|
.attr('height', d.symbol.height)
|
|
107
109
|
.attr('rx', d.symbol.radius)
|
|
108
110
|
.attr('class', className)
|
|
@@ -110,18 +112,14 @@ function renderLegendSymbol(args) {
|
|
|
110
112
|
break;
|
|
111
113
|
}
|
|
112
114
|
case 'symbol': {
|
|
115
|
+
const symbolAreaSize = Math.pow(d.symbol.width, 2);
|
|
113
116
|
const y = legendLineHeight / 2;
|
|
117
|
+
const bboxWidth = d.symbol.bboxWidth;
|
|
114
118
|
element
|
|
115
119
|
.append('svg:path')
|
|
116
|
-
.attr('d', () =>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// https://d3js.org/d3-shape/symbol#symbol
|
|
120
|
-
return symbol(scatterSymbol, d.symbol.width * d.symbol.width)();
|
|
121
|
-
})
|
|
122
|
-
.attr('transform', (_d, _index, elements) => {
|
|
123
|
-
var _a, _b;
|
|
124
|
-
const translateX = x + ((_b = (_a = elements[0]) === null || _a === void 0 ? void 0 : _a.getBBox()) === null || _b === void 0 ? void 0 : _b.width) / 2;
|
|
120
|
+
.attr('d', () => symbol(scatterSymbol, symbolAreaSize)())
|
|
121
|
+
.attr('transform', () => {
|
|
122
|
+
const translateX = x + bboxWidth / 2;
|
|
125
123
|
return 'translate(' + translateX + ',' + y + ')';
|
|
126
124
|
})
|
|
127
125
|
.attr('class', className)
|
|
@@ -140,7 +138,7 @@ export const Legend = (props) => {
|
|
|
140
138
|
}, [config.maxWidth]);
|
|
141
139
|
React.useEffect(() => {
|
|
142
140
|
async function prepareLegend() {
|
|
143
|
-
var _a, _b, _c, _e, _f, _g, _h
|
|
141
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
144
142
|
if (!ref.current || !htmlLayout) {
|
|
145
143
|
return;
|
|
146
144
|
}
|
|
@@ -157,7 +155,7 @@ export const Legend = (props) => {
|
|
|
157
155
|
let legendTop = 0;
|
|
158
156
|
if (legend.type === 'discrete') {
|
|
159
157
|
const start = (_b = (_a = config.pagination) === null || _a === void 0 ? void 0 : _a.pages[pageIndex]) === null || _b === void 0 ? void 0 : _b.start;
|
|
160
|
-
const end = (
|
|
158
|
+
const end = (_d = (_c = config.pagination) === null || _c === void 0 ? void 0 : _c.pages[pageIndex]) === null || _d === void 0 ? void 0 : _d.end;
|
|
161
159
|
const pageItems = typeof start === 'number' && typeof end === 'number'
|
|
162
160
|
? items.slice(start, end)
|
|
163
161
|
: items;
|
|
@@ -178,7 +176,7 @@ export const Legend = (props) => {
|
|
|
178
176
|
const getXPosition = (i) => {
|
|
179
177
|
return line.slice(0, i).reduce((acc, legendItem) => {
|
|
180
178
|
return (acc +
|
|
181
|
-
legendItem.symbol.
|
|
179
|
+
legendItem.symbol.bboxWidth +
|
|
182
180
|
legendItem.symbol.padding +
|
|
183
181
|
legendItem.textWidth +
|
|
184
182
|
legend.itemDistance);
|
|
@@ -202,7 +200,7 @@ export const Legend = (props) => {
|
|
|
202
200
|
return `${d.textWidth}px`;
|
|
203
201
|
})
|
|
204
202
|
.style('left', function (d, i) {
|
|
205
|
-
return `${getXPosition(i) + d.symbol.
|
|
203
|
+
return `${getXPosition(i) + d.symbol.bboxWidth + d.symbol.padding}px`;
|
|
206
204
|
})
|
|
207
205
|
.style('top', function (d) {
|
|
208
206
|
if (d.height < legendLineHeight) {
|
|
@@ -221,7 +219,7 @@ export const Legend = (props) => {
|
|
|
221
219
|
.append('text')
|
|
222
220
|
.attr('x', function (legendItem, i) {
|
|
223
221
|
return (getXPosition(i) +
|
|
224
|
-
legendItem.symbol.
|
|
222
|
+
legendItem.symbol.bboxWidth +
|
|
225
223
|
legendItem.symbol.padding);
|
|
226
224
|
})
|
|
227
225
|
.attr('height', legend.height)
|
|
@@ -238,7 +236,7 @@ export const Legend = (props) => {
|
|
|
238
236
|
}
|
|
239
237
|
else {
|
|
240
238
|
contentWidth = line.reduce((sum, l, index) => {
|
|
241
|
-
sum += l.textWidth + l.symbol.
|
|
239
|
+
sum += l.textWidth + l.symbol.bboxWidth + l.symbol.padding;
|
|
242
240
|
if (index > 0) {
|
|
243
241
|
sum += legend.itemDistance;
|
|
244
242
|
}
|
|
@@ -311,7 +309,7 @@ export const Legend = (props) => {
|
|
|
311
309
|
legendLeft = left;
|
|
312
310
|
legendTop = top;
|
|
313
311
|
// gradient rect
|
|
314
|
-
const domain = (
|
|
312
|
+
const domain = (_e = legend.colorScale.domain) !== null && _e !== void 0 ? _e : [];
|
|
315
313
|
const rectHeight = CONTINUOUS_LEGEND_SIZE.height;
|
|
316
314
|
svgElement.call(createGradientRect, {
|
|
317
315
|
y: legend.title.height + legend.title.margin,
|
|
@@ -380,9 +378,9 @@ export const Legend = (props) => {
|
|
|
380
378
|
.attr('class', legendTitleClassname)
|
|
381
379
|
.append('text')
|
|
382
380
|
.attr('dx', dx)
|
|
383
|
-
.attr('font-weight', (
|
|
384
|
-
.attr('font-size', (
|
|
385
|
-
.attr('fill', (
|
|
381
|
+
.attr('font-weight', (_f = legend.title.style.fontWeight) !== null && _f !== void 0 ? _f : null)
|
|
382
|
+
.attr('font-size', (_g = legend.title.style.fontSize) !== null && _g !== void 0 ? _g : null)
|
|
383
|
+
.attr('fill', (_h = legend.title.style.fontColor) !== null && _h !== void 0 ? _h : null)
|
|
386
384
|
.style('dominant-baseline', 'text-before-edge')
|
|
387
385
|
.html(legend.title.text);
|
|
388
386
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { ChartData, ChartSeries, ChartXAxis, ChartYAxis } from '../../types';
|
|
2
2
|
import type { PreparedTooltip } from './types';
|
|
3
|
+
export declare function getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis, }: {
|
|
4
|
+
seriesData: ChartSeries[];
|
|
5
|
+
yAxes?: ChartYAxis[];
|
|
6
|
+
xAxis?: ChartXAxis;
|
|
7
|
+
}): import("../..").ValueFormat | undefined;
|
|
3
8
|
export declare const getPreparedTooltip: (args: {
|
|
4
9
|
tooltip: ChartData["tooltip"];
|
|
5
10
|
seriesData: ChartSeries[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import { getDefaultValueFormat } from '../../components/Tooltip/DefaultTooltipContent/utils';
|
|
3
3
|
import { getDomainDataXBySeries, getDomainDataYBySeries, getMinSpaceBetween } from '../../utils';
|
|
4
|
-
function
|
|
4
|
+
export function getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis, }) {
|
|
5
5
|
if (seriesData.every((item) => ['pie', 'treemap', 'waterfall', 'sankey', 'radar', 'heatmap', 'funnel'].includes(item.type))) {
|
|
6
6
|
return undefined;
|
|
7
7
|
}
|
|
@@ -17,5 +17,5 @@ function getDefaultHeaderFormat({ seriesData, yAxes, xAxis, }) {
|
|
|
17
17
|
export const getPreparedTooltip = (args) => {
|
|
18
18
|
var _a, _b;
|
|
19
19
|
const { tooltip, seriesData, yAxes, xAxis } = args;
|
|
20
|
-
return Object.assign(Object.assign({}, tooltip), { enabled: get(tooltip, 'enabled', true), throttle: (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.throttle) !== null && _a !== void 0 ? _a : 0, headerFormat: (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.headerFormat) !== null && _b !== void 0 ? _b :
|
|
20
|
+
return Object.assign(Object.assign({}, tooltip), { enabled: get(tooltip, 'enabled', true), throttle: (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.throttle) !== null && _a !== void 0 ? _a : 0, headerFormat: (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.headerFormat) !== null && _b !== void 0 ? _b : getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis }) });
|
|
21
21
|
};
|
|
@@ -101,7 +101,7 @@ async function getGroupedLegendItems(args) {
|
|
|
101
101
|
const item = items[i];
|
|
102
102
|
const resultItem = clone(item);
|
|
103
103
|
resultItem.text = item.name;
|
|
104
|
-
const maxTextWidth = maxLegendWidth - resultItem.symbol.
|
|
104
|
+
const maxTextWidth = maxLegendWidth - resultItem.symbol.bboxWidth - resultItem.symbol.padding;
|
|
105
105
|
let textHeight = 0;
|
|
106
106
|
let textWidth = 0;
|
|
107
107
|
if (preparedLegend.html) {
|
|
@@ -143,7 +143,7 @@ async function getGroupedLegendItems(args) {
|
|
|
143
143
|
}
|
|
144
144
|
result[lineIndex].push(resultItem);
|
|
145
145
|
const symbolsWidth = result[lineIndex].reduce((acc, { symbol }) => {
|
|
146
|
-
return acc + symbol.
|
|
146
|
+
return acc + symbol.bboxWidth + symbol.padding;
|
|
147
147
|
}, 0);
|
|
148
148
|
const distancesWidth = (result[lineIndex].length - 1) * preparedLegend.itemDistance;
|
|
149
149
|
const isOverflowedAsOnlyItemInLine = resultItem.overflowed && result[lineIndex].length === 1;
|
|
@@ -22,9 +22,11 @@ function prepareLineLegendSymbol(series, seriesOptions) {
|
|
|
22
22
|
var _a;
|
|
23
23
|
const symbolOptions = ((_a = series.legend) === null || _a === void 0 ? void 0 : _a.symbol) || {};
|
|
24
24
|
const defaultLineWidth = get(seriesOptions, 'line.lineWidth', DEFAULT_LINE_WIDTH);
|
|
25
|
+
const width = (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.width) || DEFAULT_LEGEND_SYMBOL_SIZE;
|
|
25
26
|
return {
|
|
26
27
|
shape: 'path',
|
|
27
|
-
width:
|
|
28
|
+
width: width,
|
|
29
|
+
bboxWidth: width,
|
|
28
30
|
padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || DEFAULT_LEGEND_SYMBOL_PADDING,
|
|
29
31
|
strokeWidth: get(series, 'lineWidth', defaultLineWidth),
|
|
30
32
|
};
|
|
@@ -11,7 +11,9 @@ export type SymbolLegendSymbol = {
|
|
|
11
11
|
shape: 'symbol';
|
|
12
12
|
symbolType: `${SymbolType}`;
|
|
13
13
|
} & Required<SymbolLegendSymbolOptions>;
|
|
14
|
-
export type PreparedLegendSymbol = RectLegendSymbol | PathLegendSymbol | SymbolLegendSymbol
|
|
14
|
+
export type PreparedLegendSymbol = (RectLegendSymbol | PathLegendSymbol | SymbolLegendSymbol) & {
|
|
15
|
+
bboxWidth: number;
|
|
16
|
+
};
|
|
15
17
|
export type PreparedLegend = Required<Omit<ChartLegend, 'title' | 'colorScale'>> & {
|
|
16
18
|
height: number;
|
|
17
19
|
lineHeight: number;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import memoize from 'lodash/memoize';
|
|
2
2
|
import { SymbolType } from '../../constants';
|
|
3
|
+
import { getSymbolBBoxWidth } from '../../utils';
|
|
3
4
|
import { getUniqId } from '../../utils/misc';
|
|
4
5
|
import { DEFAULT_LEGEND_SYMBOL_PADDING, DEFAULT_LEGEND_SYMBOL_SIZE } from './constants';
|
|
5
6
|
export const getActiveLegendItems = (series) => {
|
|
@@ -16,10 +17,13 @@ export const getAllLegendItems = (series) => {
|
|
|
16
17
|
export function prepareLegendSymbol(series, symbolType) {
|
|
17
18
|
var _a;
|
|
18
19
|
const symbolOptions = ((_a = series.legend) === null || _a === void 0 ? void 0 : _a.symbol) || {};
|
|
20
|
+
const width = (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.width) || DEFAULT_LEGEND_SYMBOL_SIZE;
|
|
21
|
+
const type = symbolType || SymbolType.Circle;
|
|
19
22
|
return {
|
|
20
23
|
shape: 'symbol',
|
|
21
|
-
symbolType:
|
|
22
|
-
width
|
|
24
|
+
symbolType: type,
|
|
25
|
+
width,
|
|
26
|
+
bboxWidth: getSymbolBBoxWidth({ symbolSize: Math.pow(width, 2), symbolType: type }),
|
|
23
27
|
padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || DEFAULT_LEGEND_SYMBOL_PADDING,
|
|
24
28
|
};
|
|
25
29
|
}
|
package/dist/esm/index.d.ts
CHANGED
package/dist/esm/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { SymbolType } from '../../constants';
|
|
2
2
|
export declare const getSymbolType: (index: number) => SymbolType;
|
|
3
3
|
export declare const getSymbol: (symbolType: `${SymbolType}`) => import("d3-shape").SymbolType;
|
|
4
|
+
export declare function getSymbolBBoxWidth({ symbolSize, symbolType, }: {
|
|
5
|
+
symbolSize: number;
|
|
6
|
+
symbolType: `${SymbolType}`;
|
|
7
|
+
}): number;
|
|
@@ -34,3 +34,18 @@ export const getSymbol = (symbolType) => {
|
|
|
34
34
|
return symbolCircle;
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
+
export function getSymbolBBoxWidth({ symbolSize, symbolType, }) {
|
|
38
|
+
switch (symbolType) {
|
|
39
|
+
case SymbolType.Diamond:
|
|
40
|
+
return Math.sqrt(symbolSize * 2);
|
|
41
|
+
case SymbolType.Circle:
|
|
42
|
+
return Math.sqrt(symbolSize / Math.PI) * 2;
|
|
43
|
+
case SymbolType.Square:
|
|
44
|
+
return Math.sqrt(symbolSize);
|
|
45
|
+
case SymbolType.Triangle:
|
|
46
|
+
case SymbolType.TriangleDown:
|
|
47
|
+
return Math.sqrt((4 * symbolSize * Math.sqrt(3)) / 3);
|
|
48
|
+
default:
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -176,9 +176,6 @@ function unescapeHtml(str) {
|
|
|
176
176
|
return result.replace(value, key);
|
|
177
177
|
}, str);
|
|
178
178
|
}
|
|
179
|
-
function getCssStyle(prop, el = document.body) {
|
|
180
|
-
return window.getComputedStyle(el, null).getPropertyValue(prop);
|
|
181
|
-
}
|
|
182
179
|
let measureCanvas = null;
|
|
183
180
|
export function getTextSizeFn({ style }) {
|
|
184
181
|
var _a;
|
|
@@ -188,9 +185,10 @@ export function getTextSizeFn({ style }) {
|
|
|
188
185
|
throw new Error("Couldn't get canvas context");
|
|
189
186
|
}
|
|
190
187
|
const element = (_a = document.getElementsByClassName(b())[0]) !== null && _a !== void 0 ? _a : document.body;
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
const
|
|
188
|
+
const computedStyle = window.getComputedStyle(element, null);
|
|
189
|
+
const defaultFontFamily = computedStyle.getPropertyValue('font-family');
|
|
190
|
+
const defaultFontSize = computedStyle.getPropertyValue('font-size');
|
|
191
|
+
const defaultFontWeight = computedStyle.getPropertyValue('font-weight');
|
|
194
192
|
return async (str) => {
|
|
195
193
|
var _a, _b;
|
|
196
194
|
await document.fonts.ready;
|