@alfalab/core-components-chart 3.3.2 → 3.4.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/Component.js +1 -1
- package/components/Dot/index.css +8 -8
- package/components/Dot/index.js +1 -1
- package/components/Legends/index.css +13 -10
- package/components/Legends/index.js +1 -1
- package/components/Tick/index.css +7 -5
- package/components/Tick/index.js +1 -1
- package/components/TooltipContent/index.css +14 -10
- package/components/TooltipContent/index.js +1 -1
- package/cssm/components/Legends/index.module.css +5 -2
- package/cssm/components/Tick/index.module.css +3 -1
- package/cssm/components/TooltipContent/index.module.css +7 -3
- package/cssm/index.module.css +3 -1
- package/esm/Component.js +1 -1
- package/esm/components/Dot/index.css +8 -8
- package/esm/components/Dot/index.js +1 -1
- package/esm/components/Legends/index.css +13 -10
- package/esm/components/Legends/index.js +1 -1
- package/esm/components/Tick/index.css +7 -5
- package/esm/components/Tick/index.js +1 -1
- package/esm/components/TooltipContent/index.css +14 -10
- package/esm/components/TooltipContent/index.js +1 -1
- package/esm/index.css +8 -6
- package/index.css +8 -6
- package/modern/Component.js +1 -1
- package/modern/components/Dot/index.css +8 -8
- package/modern/components/Dot/index.js +1 -1
- package/modern/components/Legends/index.css +13 -10
- package/modern/components/Legends/index.js +1 -1
- package/modern/components/Tick/index.css +7 -5
- package/modern/components/Tick/index.js +1 -1
- package/modern/components/TooltipContent/index.css +14 -10
- package/modern/components/TooltipContent/index.js +1 -1
- package/modern/index.css +8 -6
- package/moderncssm/Component.d.ts +8 -0
- package/moderncssm/Component.js +251 -0
- package/moderncssm/components/CustomizedLabel.d.ts +4 -0
- package/moderncssm/components/CustomizedLabel.js +11 -0
- package/moderncssm/components/Dot/index.d.ts +5 -0
- package/moderncssm/components/Dot/index.js +43 -0
- package/moderncssm/components/Dot/index.module.css +22 -0
- package/moderncssm/components/Legends/index.d.ts +14 -0
- package/moderncssm/components/Legends/index.js +36 -0
- package/moderncssm/components/Legends/index.module.css +36 -0
- package/moderncssm/components/LinearGradient.d.ts +5 -0
- package/moderncssm/components/LinearGradient.js +5 -0
- package/moderncssm/components/RectBar.d.ts +3 -0
- package/moderncssm/components/RectBar.js +27 -0
- package/moderncssm/components/Tick/index.d.ts +5 -0
- package/moderncssm/components/Tick/index.js +16 -0
- package/moderncssm/components/Tick/index.module.css +18 -0
- package/moderncssm/components/TooltipContent/index.d.ts +11 -0
- package/moderncssm/components/TooltipContent/index.js +26 -0
- package/moderncssm/components/TooltipContent/index.module.css +51 -0
- package/moderncssm/hooks/usePathBar/index.d.ts +14 -0
- package/moderncssm/hooks/usePathBar/index.js +37 -0
- package/moderncssm/hooks/usePathBar/utils/getRadius.d.ts +2 -0
- package/moderncssm/hooks/usePathBar/utils/getRadius.js +6 -0
- package/moderncssm/hooks/useSettings/index.d.ts +19 -0
- package/moderncssm/hooks/useSettings/index.js +43 -0
- package/moderncssm/hooks/useSettings/utils/setComposedChartsMargin.d.ts +12 -0
- package/moderncssm/hooks/useSettings/utils/setComposedChartsMargin.js +12 -0
- package/moderncssm/hooks/useSettings/utils/setDatas.d.ts +5 -0
- package/moderncssm/hooks/useSettings/utils/setDatas.js +32 -0
- package/moderncssm/hooks/useSettings/utils/setGradientCharts.d.ts +3 -0
- package/moderncssm/hooks/useSettings/utils/setGradientCharts.js +35 -0
- package/moderncssm/hooks/useSettings/utils/setLegendMargin.d.ts +4 -0
- package/moderncssm/hooks/useSettings/utils/setLegendMargin.js +14 -0
- package/moderncssm/hooks/useSettings/utils/sortByIndex.d.ts +3 -0
- package/moderncssm/hooks/useSettings/utils/sortByIndex.js +8 -0
- package/moderncssm/icons/Circle.d.ts +8 -0
- package/moderncssm/icons/Circle.js +6 -0
- package/moderncssm/icons/CircleLine.d.ts +8 -0
- package/moderncssm/icons/CircleLine.js +7 -0
- package/moderncssm/icons/FilledCircle.d.ts +8 -0
- package/moderncssm/icons/FilledCircle.js +10 -0
- package/moderncssm/icons/Point.d.ts +8 -0
- package/moderncssm/icons/Point.js +7 -0
- package/moderncssm/icons/StrokeCircle.d.ts +8 -0
- package/moderncssm/icons/StrokeCircle.js +6 -0
- package/moderncssm/index.d.ts +2 -0
- package/moderncssm/index.js +1 -0
- package/moderncssm/index.module.css +19 -0
- package/moderncssm/types/brush.types.d.ts +41 -0
- package/moderncssm/types/brush.types.js +1 -0
- package/moderncssm/types/cartesianGrid.types.d.ts +23 -0
- package/moderncssm/types/cartesianGrid.types.js +1 -0
- package/moderncssm/types/chart.types.d.ts +61 -0
- package/moderncssm/types/chart.types.js +1 -0
- package/moderncssm/types/composedChart.types.d.ts +33 -0
- package/moderncssm/types/composedChart.types.js +1 -0
- package/moderncssm/types/index.d.ts +14 -0
- package/moderncssm/types/index.js +1 -0
- package/moderncssm/types/labelList.types.d.ts +5 -0
- package/moderncssm/types/labelList.types.js +1 -0
- package/moderncssm/types/legend.types.d.ts +30 -0
- package/moderncssm/types/legend.types.js +1 -0
- package/moderncssm/types/options.types.d.ts +59 -0
- package/moderncssm/types/options.types.js +1 -0
- package/moderncssm/types/payload.types.d.ts +29 -0
- package/moderncssm/types/payload.types.js +1 -0
- package/moderncssm/types/responsiveContainer.types.d.ts +10 -0
- package/moderncssm/types/responsiveContainer.types.js +1 -0
- package/moderncssm/types/seria.types.d.ts +72 -0
- package/moderncssm/types/seria.types.js +1 -0
- package/moderncssm/types/tooltip.types.d.ts +70 -0
- package/moderncssm/types/tooltip.types.js +1 -0
- package/moderncssm/types/utils/axis.types.d.ts +68 -0
- package/moderncssm/types/utils/axis.types.js +1 -0
- package/moderncssm/types/utils/coordinates.types.d.ts +11 -0
- package/moderncssm/types/utils/coordinates.types.js +1 -0
- package/moderncssm/types/utils/data.types.d.ts +17 -0
- package/moderncssm/types/utils/data.types.js +1 -0
- package/moderncssm/types/utils/dot.types.d.ts +73 -0
- package/moderncssm/types/utils/dot.types.js +1 -0
- package/moderncssm/types/utils/gradient.types.d.ts +29 -0
- package/moderncssm/types/utils/gradient.types.js +1 -0
- package/moderncssm/types/utils/index.d.ts +7 -0
- package/moderncssm/types/utils/index.js +1 -0
- package/moderncssm/types/utils/tick.types.d.ts +19 -0
- package/moderncssm/types/utils/tick.types.js +1 -0
- package/moderncssm/types/xAxis.types.d.ts +16 -0
- package/moderncssm/types/xAxis.types.js +1 -0
- package/moderncssm/types/yAxis.types.d.ts +8 -0
- package/moderncssm/types/yAxis.types.js +1 -0
- package/package.json +4 -4
- package/src/components/Legends/index.module.css +2 -2
- package/src/components/Tick/index.module.css +1 -1
- package/src/components/TooltipContent/index.module.css +2 -2
- package/src/index.module.css +1 -1
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import React, { useState, useRef, useMemo, useCallback, useEffect } from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { ResponsiveContainer, Legend, CartesianGrid, XAxis, YAxis, Brush, Tooltip, Area, Line, Bar, LabelList, Cell, ComposedChart } from 'recharts';
|
|
4
|
+
import { CustomizedLabel } from './components/CustomizedLabel.js';
|
|
5
|
+
import { Dot } from './components/Dot/index.js';
|
|
6
|
+
import { Legends } from './components/Legends/index.js';
|
|
7
|
+
import { LinearGradient } from './components/LinearGradient.js';
|
|
8
|
+
import { RectBar } from './components/RectBar.js';
|
|
9
|
+
import { Tick } from './components/Tick/index.js';
|
|
10
|
+
import { TooltipContent } from './components/TooltipContent/index.js';
|
|
11
|
+
import { useSettings } from './hooks/useSettings/index.js';
|
|
12
|
+
import styles from './index.module.css';
|
|
13
|
+
|
|
14
|
+
const CustomizedHOC = (Component, options) => {
|
|
15
|
+
const NewComponent = (props) => React.createElement(Component, { ...props, ...options });
|
|
16
|
+
return NewComponent;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/* eslint-disable @typescript-eslint/no-explicit-any,prefer-template */
|
|
20
|
+
const Chart = (props) => {
|
|
21
|
+
const [{ state, data, charts, filterCount }, { setCharts, setFilterCount }] = useSettings(props);
|
|
22
|
+
const [activeDotsState, setActiveDotsState] = useState({
|
|
23
|
+
prev: null,
|
|
24
|
+
active: null,
|
|
25
|
+
});
|
|
26
|
+
const [yBrush, setYBrush] = useState(null);
|
|
27
|
+
const [tooltipArrowSide, setTooltipArrowSide] = useState(null);
|
|
28
|
+
const [heightLegend, setHeightLegend] = useState(0);
|
|
29
|
+
const svgRef = useRef(null);
|
|
30
|
+
const tooltipRef = useRef(null);
|
|
31
|
+
const renderGradient = useMemo(() => {
|
|
32
|
+
if (!state)
|
|
33
|
+
return null;
|
|
34
|
+
return state.series.map((item) => {
|
|
35
|
+
const { chart, gradient } = item;
|
|
36
|
+
if (chart !== 'gradient' || !gradient)
|
|
37
|
+
return null;
|
|
38
|
+
const { gid, points } = gradient;
|
|
39
|
+
return (React.createElement(LinearGradient, { key: `${state.id}-${gid}`, id: state.id, gid: gid, points: points }));
|
|
40
|
+
});
|
|
41
|
+
}, [state]);
|
|
42
|
+
const toggleChart = useCallback((item) => {
|
|
43
|
+
const { chart, properties: { dataKey }, } = item;
|
|
44
|
+
const withGrad = chart === 'area';
|
|
45
|
+
let changed = false;
|
|
46
|
+
if (charts[dataKey + ''] && filterCount > 1) {
|
|
47
|
+
changed = true;
|
|
48
|
+
setFilterCount((prev) => prev - 1);
|
|
49
|
+
}
|
|
50
|
+
if (!charts[dataKey + '']) {
|
|
51
|
+
changed = true;
|
|
52
|
+
setFilterCount((prev) => prev + 1);
|
|
53
|
+
}
|
|
54
|
+
if (!changed)
|
|
55
|
+
return;
|
|
56
|
+
setCharts((prev) => {
|
|
57
|
+
const newState = { ...prev };
|
|
58
|
+
newState[dataKey + ''] = !newState[dataKey + ''];
|
|
59
|
+
if (withGrad)
|
|
60
|
+
newState[dataKey + '-gradient'] = !newState[dataKey + '-gradient'];
|
|
61
|
+
return newState;
|
|
62
|
+
});
|
|
63
|
+
}, [charts, filterCount, setCharts, setFilterCount]);
|
|
64
|
+
const legendRef = useCallback((node) => {
|
|
65
|
+
if (node !== null) {
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
const { height } = node.getBoundingClientRect();
|
|
68
|
+
setHeightLegend(height);
|
|
69
|
+
}, 0);
|
|
70
|
+
}
|
|
71
|
+
}, []);
|
|
72
|
+
const renderLegend = useMemo(() => {
|
|
73
|
+
if (!state?.legend)
|
|
74
|
+
return null;
|
|
75
|
+
const translate = state?.xAxis?.tickMargin && state?.legend?.verticalAlign !== 'top'
|
|
76
|
+
? state.xAxis.tickMargin + (state?.brush?.brushMargin || 0)
|
|
77
|
+
: 0;
|
|
78
|
+
return (React.createElement(Legend, { ...(state.legend || null), content: React.createElement(Legends, { legend: state.legend, series: state.series, id: state.id, toggleChart: toggleChart, ref: legendRef, charts: charts }), wrapperStyle: {
|
|
79
|
+
transform: `translateY(${translate}px)`,
|
|
80
|
+
} }));
|
|
81
|
+
}, [state, charts, toggleChart, legendRef]);
|
|
82
|
+
const renderCartesianGrid = useMemo(() => {
|
|
83
|
+
if (!state?.cartesianGrid)
|
|
84
|
+
return null;
|
|
85
|
+
return React.createElement(CartesianGrid, { ...state.cartesianGrid });
|
|
86
|
+
}, [state]);
|
|
87
|
+
const renderXAxis = useMemo(() => {
|
|
88
|
+
if (!state?.xAxis)
|
|
89
|
+
return null;
|
|
90
|
+
let tick;
|
|
91
|
+
if (state?.xAxis?.tickType === 'point') {
|
|
92
|
+
tick = CustomizedHOC(Tick, { xAxis: state.xAxis });
|
|
93
|
+
}
|
|
94
|
+
else if (typeof state.xAxis.tick === 'boolean') {
|
|
95
|
+
tick = state.xAxis.tick;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
tick = true;
|
|
99
|
+
}
|
|
100
|
+
return React.createElement(XAxis, { ...state.xAxis, tick: tick });
|
|
101
|
+
}, [state]);
|
|
102
|
+
const renderYAxis = useMemo(() => {
|
|
103
|
+
if (!state?.yAxis)
|
|
104
|
+
return null;
|
|
105
|
+
let tick;
|
|
106
|
+
if (state?.yAxis?.tick) {
|
|
107
|
+
tick = CustomizedHOC(state.yAxis.tick, { state });
|
|
108
|
+
}
|
|
109
|
+
else if (typeof state.yAxis.tick === 'boolean') {
|
|
110
|
+
tick = state.yAxis.tick;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
tick = true;
|
|
114
|
+
}
|
|
115
|
+
return React.createElement(YAxis, { ...state.yAxis, tick: tick });
|
|
116
|
+
}, [state]);
|
|
117
|
+
const renderBrush = useMemo(() => {
|
|
118
|
+
if (!state?.brush)
|
|
119
|
+
return null;
|
|
120
|
+
return React.createElement(Brush, { y: typeof yBrush === 'number' ? yBrush : 0, ...state.brush });
|
|
121
|
+
}, [state, yBrush]);
|
|
122
|
+
const renderTooltip = useMemo(() => {
|
|
123
|
+
if (!state?.tooltip)
|
|
124
|
+
return null;
|
|
125
|
+
return (React.createElement(Tooltip, { ref: tooltipRef, ...state.tooltip, content: CustomizedHOC(TooltipContent, { series: state.series, tooltipArrowSide }) }));
|
|
126
|
+
}, [state, tooltipArrowSide]);
|
|
127
|
+
const renderChartsItems = useMemo(() => {
|
|
128
|
+
if (!state || !charts)
|
|
129
|
+
return null;
|
|
130
|
+
return state.series.map((item) => {
|
|
131
|
+
const { chart, properties, radius, labelList } = item;
|
|
132
|
+
const show = charts[`${properties.dataKey}`];
|
|
133
|
+
switch (chart) {
|
|
134
|
+
case 'bar':
|
|
135
|
+
return show && !item?.hide ? (React.createElement(Bar, { key: `${state.id}-${properties.dataKey}`, ...properties, shape: React.createElement(RectBar, { radius: radius }) },
|
|
136
|
+
labelList && (React.createElement(LabelList, { dataKey: properties.dataKey.toString(), ...labelList, content: React.createElement(CustomizedLabel, { radius: radius }) })),
|
|
137
|
+
data.map((_, index) => {
|
|
138
|
+
const key = `${state.id}-${properties.dataKey}-${index}`;
|
|
139
|
+
return (React.createElement(Cell, { key: key, className: cn(styles.bar, typeof activeDotsState.active === 'number' &&
|
|
140
|
+
activeDotsState.active !== index
|
|
141
|
+
? styles.unfocused
|
|
142
|
+
: '') }));
|
|
143
|
+
}))) : null;
|
|
144
|
+
case 'area':
|
|
145
|
+
case 'line':
|
|
146
|
+
return show && !item?.hide ? (React.createElement(Line, { key: `${state.id}-${properties.dataKey}`, ...properties, dot: properties.dot && properties.dotSettings
|
|
147
|
+
? CustomizedHOC(Dot, {
|
|
148
|
+
activeDot: activeDotsState.active,
|
|
149
|
+
dotSettings: properties.dotSettings,
|
|
150
|
+
inherit: properties?.inheritStroke
|
|
151
|
+
? properties.inheritStroke
|
|
152
|
+
: false,
|
|
153
|
+
})
|
|
154
|
+
: false, activeDot: false })) : null;
|
|
155
|
+
case 'gradient':
|
|
156
|
+
return show && !item?.hide ? (React.createElement(Area, { ...item.properties, key: `${state.id}-${item.properties.dataKey}`, dataKey: `${item.properties.dataKey}`, stroke: 'transparent', fill: item.gradient.gid
|
|
157
|
+
? `url(#${state.id}-${item.gradient.gid})`
|
|
158
|
+
: item.properties.fill, dot: false, activeDot: false })) : null;
|
|
159
|
+
default:
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}, [charts, state, activeDotsState, data]);
|
|
164
|
+
// Позиционирование brush
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
if (!state || !state.brush)
|
|
167
|
+
return;
|
|
168
|
+
if (!heightLegend || heightLegend === 0)
|
|
169
|
+
return;
|
|
170
|
+
const align = state?.legend?.verticalAlign;
|
|
171
|
+
const legendHeight = align === 'top' ? 0 : heightLegend;
|
|
172
|
+
const marginTick = state?.xAxis?.tickMargin ? state?.xAxis?.tickMargin : 0;
|
|
173
|
+
const brushY = (svgRef.current?.clientHeight ? svgRef.current.clientHeight : 0) -
|
|
174
|
+
legendHeight -
|
|
175
|
+
state.brush.height -
|
|
176
|
+
(state?.composeChart?.margin?.bottom ? state.composeChart.margin.bottom : 0) +
|
|
177
|
+
marginTick +
|
|
178
|
+
(state.brush?.brushMargin ? state.brush.brushMargin : 0);
|
|
179
|
+
setYBrush(brushY);
|
|
180
|
+
}, [heightLegend, state]);
|
|
181
|
+
const leaveEvent = (isTooltipActive) => {
|
|
182
|
+
if (isTooltipActive)
|
|
183
|
+
return;
|
|
184
|
+
if (typeof activeDotsState.prev !== 'number' || typeof activeDotsState.active !== 'number')
|
|
185
|
+
return;
|
|
186
|
+
setActiveDotsState({
|
|
187
|
+
prev: null,
|
|
188
|
+
active: null,
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
const arrowTooltipEvent = (activeCoordinate) => {
|
|
192
|
+
if (!state?.tooltip?.arrow)
|
|
193
|
+
return;
|
|
194
|
+
if (state?.tooltip?.arrow && activeCoordinate?.x) {
|
|
195
|
+
const side = (svgRef?.current?.clientWidth || 0) -
|
|
196
|
+
(state?.composeChart?.margin?.right || 0) -
|
|
197
|
+
activeCoordinate.x -
|
|
198
|
+
(tooltipRef.current?.state?.boxWidth || 0) >
|
|
199
|
+
20;
|
|
200
|
+
setTooltipArrowSide(side);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
const hoverEvent = (isTooltipActive, activeTooltipIndex) => {
|
|
204
|
+
if (!isTooltipActive)
|
|
205
|
+
return;
|
|
206
|
+
if (typeof activeDotsState.active === 'number' &&
|
|
207
|
+
activeTooltipIndex === activeDotsState.active)
|
|
208
|
+
return;
|
|
209
|
+
if (typeof activeTooltipIndex === 'number' && typeof activeDotsState.active !== 'number') {
|
|
210
|
+
setActiveDotsState({
|
|
211
|
+
prev: activeTooltipIndex,
|
|
212
|
+
active: activeTooltipIndex,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (typeof activeTooltipIndex === 'number' && typeof activeDotsState.prev === 'number') {
|
|
216
|
+
setActiveDotsState((prev) => ({
|
|
217
|
+
prev: prev.active,
|
|
218
|
+
active: activeTooltipIndex,
|
|
219
|
+
}));
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const mouseMove = (e) => {
|
|
223
|
+
if (!state?.tooltip)
|
|
224
|
+
return;
|
|
225
|
+
arrowTooltipEvent(e.activeCoordinate);
|
|
226
|
+
hoverEvent(e.isTooltipActive, e.activeTooltipIndex);
|
|
227
|
+
leaveEvent(e.isTooltipActive);
|
|
228
|
+
};
|
|
229
|
+
const mouseLeave = (e) => {
|
|
230
|
+
if (!state?.tooltip)
|
|
231
|
+
return;
|
|
232
|
+
leaveEvent(e.isTooltipActive);
|
|
233
|
+
};
|
|
234
|
+
if (!data || !charts || !state)
|
|
235
|
+
return null;
|
|
236
|
+
return (React.createElement("div", { className: styles.coreChart, ref: svgRef, id: state?.id || '', style: { width: '100%', height: '100%' } },
|
|
237
|
+
React.createElement(ResponsiveContainer, { debounce: state?.responsiveContainer?.debounce ? state.responsiveContainer.debounce : 0, width: '100%' },
|
|
238
|
+
React.createElement(ComposedChart, { ...state?.composeChart, onMouseMove: mouseMove, onMouseLeave: mouseLeave, data: data },
|
|
239
|
+
React.createElement("defs", null, renderGradient),
|
|
240
|
+
state.cartesianGrid && renderCartesianGrid,
|
|
241
|
+
state.xAxis && renderXAxis,
|
|
242
|
+
state.yAxis && renderYAxis,
|
|
243
|
+
renderChartsItems,
|
|
244
|
+
state.tooltip && renderTooltip,
|
|
245
|
+
state.brush && renderBrush,
|
|
246
|
+
state.legend && renderLegend))));
|
|
247
|
+
};
|
|
248
|
+
Chart.displayName = 'Chart';
|
|
249
|
+
ResponsiveContainer.displayName = 'ResponsiveContainer';
|
|
250
|
+
|
|
251
|
+
export { Chart };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { usePathBar } from '../hooks/usePathBar/index.js';
|
|
3
|
+
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
const CustomizedLabel = ({ x, y, value, offset, radius, height, width, formatter, }) => {
|
|
6
|
+
const [initHeight] = usePathBar({ radius, height });
|
|
7
|
+
return (React.createElement("text", { x: x + width / 2, y: y + height - (initHeight + offset), width: width, height: initHeight, textAnchor: 'middle' },
|
|
8
|
+
React.createElement("tspan", { x: x + width / 2 }, formatter ? formatter(value) : value)));
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { CustomizedLabel };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { PointIcon } from '../../icons/Point.js';
|
|
4
|
+
import styles from './index.module.css';
|
|
5
|
+
|
|
6
|
+
const Dot = React.forwardRef(({ cx, cy, index, activeDot, dataKey, dotSettings, value, stroke }, ref) => {
|
|
7
|
+
const [windowWidth, setWindowWidth] = useState(0);
|
|
8
|
+
const [height, setHeight] = useState(0);
|
|
9
|
+
const [width, setWidth] = useState(0);
|
|
10
|
+
const [option, setOption] = useState(null);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
let dotSetting = Array.isArray(dotSettings) && dotSettings.length > 0
|
|
13
|
+
? dotSettings.find((item) => item.media && windowWidth < item.media)
|
|
14
|
+
: dotSettings;
|
|
15
|
+
if (Array.isArray(dotSettings) && dotSettings.length > 0 && !dotSetting) {
|
|
16
|
+
dotSetting = dotSettings[dotSettings.length - 1];
|
|
17
|
+
}
|
|
18
|
+
setWindowWidth(window.innerWidth);
|
|
19
|
+
setOption(dotSetting);
|
|
20
|
+
}, [dotSettings, windowWidth]);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!option)
|
|
23
|
+
return;
|
|
24
|
+
if (typeof activeDot === 'number' && activeDot === index) {
|
|
25
|
+
setHeight(option.height * option.scale);
|
|
26
|
+
setWidth(option.width * option.scale);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
setHeight(option.height * option.initScale);
|
|
30
|
+
setWidth(option.width * option.initScale);
|
|
31
|
+
}
|
|
32
|
+
}, [activeDot, index, option]);
|
|
33
|
+
if (!value)
|
|
34
|
+
return null;
|
|
35
|
+
return (React.createElement("g", { ref: ref, className: cn(styles.dot), transform: `translate(${cx - width / 2}, ${cy - height / 2})` },
|
|
36
|
+
React.createElement("g", { className: cn(styles.dotWrap), transform: `scale(${activeDot === index ? option?.scale || 0 : option?.initScale || 0})` },
|
|
37
|
+
React.createElement("svg", { className: cn(styles.dotItem, activeDot === index ? styles.dotActive : '', typeof activeDot === 'number' && activeDot !== index
|
|
38
|
+
? styles.dotUnfocused
|
|
39
|
+
: ''), "data-id": index, "data-name": dataKey, width: option?.width || 0, height: option?.height || 0 },
|
|
40
|
+
React.createElement(PointIcon, { fill: stroke })))));
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export { Dot };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.dotUnfocused {
|
|
2
|
+
opacity: 0.3;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.dot,
|
|
6
|
+
.dotItem,
|
|
7
|
+
.dotWrap {
|
|
8
|
+
transition: all 0.2s ease;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.dot {
|
|
12
|
+
animation: showDot 0.5s ease;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@keyframes showDot {
|
|
16
|
+
from {
|
|
17
|
+
opacity: 0;
|
|
18
|
+
}
|
|
19
|
+
to {
|
|
20
|
+
opacity: 1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { LegendProps } from "../../types/legend.types";
|
|
4
|
+
import { SeriaProps } from "../../types/seria.types";
|
|
5
|
+
import { DataDynamicBooleanProps } from "../../types/utils/data.types";
|
|
6
|
+
interface Props {
|
|
7
|
+
legend: LegendProps;
|
|
8
|
+
series: SeriaProps[];
|
|
9
|
+
id: string;
|
|
10
|
+
charts: DataDynamicBooleanProps;
|
|
11
|
+
toggleChart(item: SeriaProps): void;
|
|
12
|
+
}
|
|
13
|
+
declare const Legends: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLUListElement>>;
|
|
14
|
+
export { Legends };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { Typography } from '@alfalab/core-components-typography/moderncssm';
|
|
4
|
+
import { CircleIcon } from '../../icons/Circle.js';
|
|
5
|
+
import { CircleLineIcon } from '../../icons/CircleLine.js';
|
|
6
|
+
import { FilledCircleIcon } from '../../icons/FilledCircle.js';
|
|
7
|
+
import { StrokeCircleIcon } from '../../icons/StrokeCircle.js';
|
|
8
|
+
import styles from './index.module.css';
|
|
9
|
+
|
|
10
|
+
const icons = {
|
|
11
|
+
circleLine: CircleLineIcon,
|
|
12
|
+
filledCircle: FilledCircleIcon,
|
|
13
|
+
strokeCircle: StrokeCircleIcon,
|
|
14
|
+
circle: CircleIcon,
|
|
15
|
+
};
|
|
16
|
+
const Legends = React.forwardRef(({ legend, series, id, charts, toggleChart }, ref) => {
|
|
17
|
+
const style = {
|
|
18
|
+
textAlign: legend.align || 'center',
|
|
19
|
+
transform: `translateY(${(legend?.marginTop ? legend.marginTop : 0) *
|
|
20
|
+
(legend.verticalAlign === 'top' ? -1 : 1)}px)`,
|
|
21
|
+
};
|
|
22
|
+
return (React.createElement("ul", { ref: ref, className: cn(styles.legendWrap), style: style }, series.map((item) => {
|
|
23
|
+
if (item.hideLegend || item.hide)
|
|
24
|
+
return null;
|
|
25
|
+
const Icon = icons[item.icon] || CircleIcon;
|
|
26
|
+
return (React.createElement("li", { role: 'presentation', key: `${id}-${item.properties.dataKey}`, className: cn(styles.legendItem, charts[`${item.properties.dataKey}`] ? '' : styles.legendUnactive), onClick: () => toggleChart(item) },
|
|
27
|
+
React.createElement("div", { className: cn(styles.legendContent) },
|
|
28
|
+
Icon ? (React.createElement("i", { className: cn(styles.legendIcon) },
|
|
29
|
+
React.createElement(Icon, { fill: item.properties?.fill ||
|
|
30
|
+
item.properties?.stroke ||
|
|
31
|
+
'', height: legend.iconHeight || 16 }))) : null,
|
|
32
|
+
React.createElement(Typography.Text, { view: 'primary-medium', tag: 'span', className: cn(styles.legendValue) }, item.properties.name))));
|
|
33
|
+
})));
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export { Legends };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* */
|
|
2
|
+
|
|
3
|
+
.legendContent {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
flex-wrap: wrap;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.legendWrap {
|
|
10
|
+
width: 100%;
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.legendItem {
|
|
16
|
+
margin-right: var(--gap-32);
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
display: inline-block;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.legendItem:last-child {
|
|
22
|
+
margin-right: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.legendUnactive {
|
|
26
|
+
opacity: 0.3;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.legendIcon {
|
|
30
|
+
margin-right: 13px;
|
|
31
|
+
display: flex;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.legendValue {
|
|
35
|
+
text-transform: capitalize;
|
|
36
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const LinearGradient = ({ id, gid, points }) => (React.createElement("linearGradient", { key: `${id}-${gid}`, id: `${id}-${gid}`, x1: '0', y1: '0', x2: '0', y2: '1' }, points.map((point, index) => (React.createElement("stop", { key: `${id}${gid}-${index.toString()}`, offset: `${point.offset}%`, stopColor: point.stopColor, stopOpacity: point.stopOpacity })))));
|
|
4
|
+
|
|
5
|
+
export { LinearGradient };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { usePathBar } from '../hooks/usePathBar/index.js';
|
|
3
|
+
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
// eslint-disable-next-line complexity
|
|
6
|
+
const getPath = (x, width, height, initHeight, topRadius, bottomRadius, initY) => `
|
|
7
|
+
M${x + ((height !== 0 && bottomRadius) || 0)} ${initY + initHeight || 0}
|
|
8
|
+
Q${x} ${initY + initHeight} ${x} ${initY + initHeight - ((height !== 0 && bottomRadius) || 0)}
|
|
9
|
+
L${x} ${initY + ((height !== 0 && topRadius) || 0)}
|
|
10
|
+
Q${x} ${initY} ${x + ((height !== 0 && topRadius) || 0)} ${initY}
|
|
11
|
+
L${x + width - ((height !== 0 && topRadius) || 0)} ${initY}
|
|
12
|
+
Q${x + width} ${initY} ${x + width} ${initY + (topRadius || 0)}
|
|
13
|
+
L${x + width} ${initY + initHeight - ((height !== 0 && bottomRadius) || 0)}
|
|
14
|
+
Q${x + width} ${initY + initHeight} ${x + width - ((height !== 0 && bottomRadius) || 0)} ${initY + initHeight}
|
|
15
|
+
Z
|
|
16
|
+
`;
|
|
17
|
+
const RectBar = ({ fill, x, y, width, height, radius, background }) => {
|
|
18
|
+
const [initHeight, topRadius, bottomRadius, initY] = usePathBar({
|
|
19
|
+
radius,
|
|
20
|
+
height,
|
|
21
|
+
background,
|
|
22
|
+
y,
|
|
23
|
+
});
|
|
24
|
+
return useMemo(() => (React.createElement("path", { d: getPath(x, width, height, initHeight, topRadius, bottomRadius, initY), stroke: 'none', fill: fill })), [x, width, height, initHeight, topRadius, bottomRadius, initY, fill]);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { RectBar };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import styles from './index.module.css';
|
|
4
|
+
|
|
5
|
+
const Tick = ({ y, payload, tickFormatter, xAxis }) => {
|
|
6
|
+
const radius = 4;
|
|
7
|
+
const marginTick = xAxis?.tickMargin &&
|
|
8
|
+
(xAxis.tickMargin > 0 ? xAxis.tickMargin - radius / 2 : xAxis.tickMargin === 0)
|
|
9
|
+
? (radius / 2) * -1
|
|
10
|
+
: null;
|
|
11
|
+
return (React.createElement("g", { className: cn(styles.tick), opacity: '1', textAnchor: 'middle', transform: `translate(${payload.coordinate}, ${y - (typeof marginTick === 'number' ? marginTick : 0) - radius * 2})` },
|
|
12
|
+
React.createElement("text", { className: cn(styles.tickText), y: '30' }, tickFormatter ? tickFormatter(payload.value) : payload.value),
|
|
13
|
+
React.createElement("circle", { r: radius, className: cn(styles.circle) })));
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { Tick };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* */
|
|
2
|
+
|
|
3
|
+
.tickText {
|
|
4
|
+
fill: var(--color-light-text-primary);
|
|
5
|
+
font-size: 16px;
|
|
6
|
+
line-height: 24px;
|
|
7
|
+
font-weight: 400;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.circle {
|
|
11
|
+
opacity: 0.3;
|
|
12
|
+
fill: var(--color-dark-base-bg-primary);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.circle {
|
|
16
|
+
opacity: 0.3;
|
|
17
|
+
fill: var(--color-dark-base-bg-primary);
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { PayloadProps } from "../../types/payload.types";
|
|
4
|
+
import { SeriaProps } from "../../types/seria.types";
|
|
5
|
+
import { TooltipProps } from "../../types/tooltip.types";
|
|
6
|
+
interface TooltipContentProps extends TooltipProps {
|
|
7
|
+
payload: PayloadProps[];
|
|
8
|
+
series: SeriaProps[];
|
|
9
|
+
}
|
|
10
|
+
declare const TooltipContent: ({ payload, separator, label, tooltipArrowSide, arrow, series, labelFormatter, labelStyle, }: TooltipContentProps) => React.JSX.Element | null;
|
|
11
|
+
export { TooltipContentProps, TooltipContent };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { Typography } from '@alfalab/core-components-typography/moderncssm';
|
|
4
|
+
import styles from './index.module.css';
|
|
5
|
+
|
|
6
|
+
const TooltipContent = ({ payload, separator, label, tooltipArrowSide, arrow, series, labelFormatter, labelStyle, }) => {
|
|
7
|
+
if (!label || payload.length === 0)
|
|
8
|
+
return null;
|
|
9
|
+
return (React.createElement("div", { className: cn(styles.tooltip) },
|
|
10
|
+
arrow && (React.createElement("span", { className: cn(styles.tooltipArrow, tooltipArrowSide ? '' : styles.tooltipArrowRight) })),
|
|
11
|
+
React.createElement("ul", { className: cn(styles.tooltipList) },
|
|
12
|
+
React.createElement("li", { className: cn(styles.tooltipItem), style: labelStyle },
|
|
13
|
+
React.createElement(Typography.Text, { view: 'primary-medium', tag: 'span', weight: 'medium', className: cn(styles.tooltipLabel) }, labelFormatter ? labelFormatter(label) : label)),
|
|
14
|
+
payload.map((entry) => {
|
|
15
|
+
const data = series.find((d) => d.properties.dataKey === entry.dataKey);
|
|
16
|
+
if (data?.hideTooltip || data?.hide)
|
|
17
|
+
return null;
|
|
18
|
+
return (React.createElement("li", { className: cn(styles.tooltipItem), key: entry.dataKey, style: { color: entry.color } },
|
|
19
|
+
React.createElement(Typography.Text, { view: 'primary-medium', tag: 'span', weight: 'medium', className: cn(styles.tooltipValue) },
|
|
20
|
+
entry?.formatter ? entry.formatter(entry.value) : entry.value,
|
|
21
|
+
separator || ' '),
|
|
22
|
+
React.createElement(Typography.Text, { view: 'secondary-large', tag: 'span', className: cn(styles.tooltipName) }, `${entry.name}`)));
|
|
23
|
+
}))));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { TooltipContent };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* */
|
|
2
|
+
|
|
3
|
+
.tooltip {
|
|
4
|
+
background-color: var(--color-light-base-bg-primary);
|
|
5
|
+
border: 1px solid var(--color-light-neutral-400);
|
|
6
|
+
box-shadow: var(--shadow-l);
|
|
7
|
+
border-radius: var(--border-radius-m);
|
|
8
|
+
padding: var(--gap-12) var(--gap-16);
|
|
9
|
+
pointer-events: none;
|
|
10
|
+
position: relative;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.tooltipList {
|
|
14
|
+
position: relative;
|
|
15
|
+
z-index: 5;
|
|
16
|
+
list-style-type: none;
|
|
17
|
+
padding: 0;
|
|
18
|
+
margin: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.tooltipItem {
|
|
22
|
+
margin-bottom: 10px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.tooltipArrow {
|
|
26
|
+
position: absolute;
|
|
27
|
+
left: 0;
|
|
28
|
+
top: 50%;
|
|
29
|
+
transform: translate(-50%, -50%) scale(1, 1) rotate(45deg);
|
|
30
|
+
width: 10px;
|
|
31
|
+
height: 10px;
|
|
32
|
+
border: 1px solid var(--color-light-neutral-400);
|
|
33
|
+
background-color: var(--color-light-base-bg-primary);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.tooltipArrow:before {
|
|
37
|
+
content: '';
|
|
38
|
+
position: absolute;
|
|
39
|
+
left: -2px;
|
|
40
|
+
top: -2px;
|
|
41
|
+
width: 0;
|
|
42
|
+
height: 0;
|
|
43
|
+
border-style: solid;
|
|
44
|
+
border-width: 0 24px 24px 0;
|
|
45
|
+
border-color: transparent var(--color-light-base-bg-primary) transparent transparent;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.tooltipArrowRight {
|
|
49
|
+
left: 100%;
|
|
50
|
+
transform: translate(-50%, -50%) scale(-1, 1) rotate(45deg);
|
|
51
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RadiusProp } from "../../types/seria.types";
|
|
2
|
+
type usePathBarProps = {
|
|
3
|
+
radius?: RadiusProp;
|
|
4
|
+
height: number;
|
|
5
|
+
background?: {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
height: number;
|
|
9
|
+
width: number;
|
|
10
|
+
};
|
|
11
|
+
y?: number;
|
|
12
|
+
};
|
|
13
|
+
declare const usePathBar: (props: usePathBarProps) => number[];
|
|
14
|
+
export { usePathBarProps, usePathBar };
|