@lobehub/charts 1.6.2 → 1.7.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.
@@ -17,6 +17,7 @@ export interface DonutChartProps extends BaseAnimationTimingProps {
17
17
  donutLabel?: string;
18
18
  index?: string;
19
19
  label?: string;
20
+ loading?: boolean;
20
21
  noDataText?: NoDataProps['noDataText'];
21
22
  onValueChange?: (value: EventProps) => void;
22
23
  showAnimation?: boolean;
@@ -2,12 +2,13 @@
2
2
 
3
3
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
4
4
  import _taggedTemplateLiteral from "@babel/runtime/helpers/esm/taggedTemplateLiteral";
5
- import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
6
5
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
6
+ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
7
7
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
8
8
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
9
9
  var _templateObject;
10
- var _excluded = ["data", "category", "index", "colors", "variant", "valueFormatter", "label", "showLabel", "animationDuration", "showAnimation", "showTooltip", "noDataText", "onValueChange", "customTooltip", "className", "width", "height", "style", "customCategories", "donutLabel"];
10
+ var _excluded = ["data", "category", "index", "colors", "variant", "valueFormatter", "label", "showLabel", "animationDuration", "showAnimation", "showTooltip", "noDataText", "onValueChange", "customTooltip", "className", "width", "loading", "height", "style", "customCategories", "donutLabel"];
11
+ import { Skeleton } from 'antd';
11
12
  import { css, useThemeMode } from 'antd-style';
12
13
  import { forwardRef, useEffect, useState } from 'react';
13
14
  import { Flexbox } from 'react-layout-kit';
@@ -55,6 +56,7 @@ var DonutChart = /*#__PURE__*/forwardRef(function (props, ref) {
55
56
  className = props.className,
56
57
  _props$width = props.width,
57
58
  width = _props$width === void 0 ? '100%' : _props$width,
59
+ loading = props.loading,
58
60
  _props$height = props.height,
59
61
  height = _props$height === void 0 ? '10rem' : _props$height,
60
62
  style = props.style,
@@ -71,19 +73,6 @@ var DonutChart = /*#__PURE__*/forwardRef(function (props, ref) {
71
73
  activeIndex = _useState2[0],
72
74
  setActiveIndex = _useState2[1];
73
75
  var hasOnValueChange = !!onValueChange;
74
- var onShapeClick = function onShapeClick(data, index, event) {
75
- event.stopPropagation();
76
- if (!hasOnValueChange) return;
77
- if (activeIndex === index) {
78
- setActiveIndex(undefined);
79
- onValueChange === null || onValueChange === void 0 || onValueChange(null);
80
- } else {
81
- setActiveIndex(index);
82
- onValueChange === null || onValueChange === void 0 || onValueChange(_objectSpread({
83
- eventType: 'slice'
84
- }, data.payload.payload));
85
- }
86
- };
87
76
  useEffect(function () {
88
77
  var pieSectors = document.querySelectorAll('.recharts-pie-sector');
89
78
  if (pieSectors) {
@@ -101,6 +90,27 @@ var DonutChart = /*#__PURE__*/forwardRef(function (props, ref) {
101
90
  }
102
91
  }
103
92
  }, [activeIndex]);
93
+ if (loading || !data) return /*#__PURE__*/_jsx(Skeleton.Button, {
94
+ active: true,
95
+ block: true,
96
+ style: {
97
+ height: height,
98
+ width: width
99
+ }
100
+ });
101
+ var onShapeClick = function onShapeClick(data, index, event) {
102
+ event.stopPropagation();
103
+ if (!hasOnValueChange) return;
104
+ if (activeIndex === index) {
105
+ setActiveIndex(undefined);
106
+ onValueChange === null || onValueChange === void 0 || onValueChange(null);
107
+ } else {
108
+ setActiveIndex(index);
109
+ onValueChange === null || onValueChange === void 0 || onValueChange(_objectSpread({
110
+ eventType: 'slice'
111
+ }, data.payload.payload));
112
+ }
113
+ };
104
114
  var parseData = function parseData(data, colors) {
105
115
  return data.map(function (dataPoint, idx) {
106
116
  var baseColor = idx < colors.length ? colors[idx] : theme.colorPrimary;
@@ -138,7 +148,7 @@ var DonutChart = /*#__PURE__*/forwardRef(function (props, ref) {
138
148
  textAnchor: "middle",
139
149
  x: "50%",
140
150
  y: "50%",
141
- children: donutLabel || typeof activeIndex === 'number' ? valueFormatter(data === null || data === void 0 || (_data = data[activeIndex]) === null || _data === void 0 ? void 0 : _data[category]) : parsedLabelInput
151
+ children: donutLabel || (typeof activeIndex === 'number' ? valueFormatter(data === null || data === void 0 || (_data = data[activeIndex]) === null || _data === void 0 ? void 0 : _data[category]) : parsedLabelInput)
142
152
  }) : null, /*#__PURE__*/_jsx(Pie, {
143
153
  activeIndex: activeIndex,
144
154
  animationDuration: animationDuration,
@@ -0,0 +1,4 @@
1
+ declare const ArrowRightIcon: ({ ...props }: {
2
+ [x: string]: any;
3
+ }) => import("react/jsx-runtime").JSX.Element;
4
+ export default ArrowRightIcon;
@@ -0,0 +1,17 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import _objectDestructuringEmpty from "@babel/runtime/helpers/esm/objectDestructuringEmpty";
3
+ import React from 'react';
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ var ArrowRightIcon = function ArrowRightIcon(_ref) {
6
+ var props = Object.assign({}, (_objectDestructuringEmpty(_ref), _ref));
7
+ return /*#__PURE__*/_jsx("svg", _objectSpread(_objectSpread({
8
+ fill: "currentColor",
9
+ viewBox: "0 0 24 24",
10
+ xmlns: "http://www.w3.org/2000/svg"
11
+ }, props), {}, {
12
+ children: /*#__PURE__*/_jsx("path", {
13
+ d: "M16.1716 10.9999L10.8076 5.63589L12.2218 4.22168L20 11.9999L12.2218 19.778L10.8076 18.3638L16.1716 12.9999H4V10.9999H16.1716Z"
14
+ })
15
+ }));
16
+ };
17
+ export default ArrowRightIcon;
@@ -0,0 +1,19 @@
1
+ /// <reference types="react" />
2
+ import BaseChartProps from "../common/BaseChartProps";
3
+ type CalculateFrom = 'first' | 'previous';
4
+ type DataT = {
5
+ name: string;
6
+ value: number;
7
+ };
8
+ export interface FunnelChartProps extends Omit<BaseChartProps, 'categories' | 'index'> {
9
+ barGap?: number | `${number}%`;
10
+ calculateFrom?: CalculateFrom;
11
+ data: DataT[];
12
+ evolutionGradient?: boolean;
13
+ gradient?: boolean;
14
+ showArrow?: boolean;
15
+ variant?: 'base' | 'center';
16
+ yAxisPadding?: number;
17
+ }
18
+ declare const FunnelChart: import("react").ForwardRefExoticComponent<FunnelChartProps & import("react").RefAttributes<HTMLDivElement>>;
19
+ export default FunnelChart;
@@ -0,0 +1,492 @@
1
+ 'use client';
2
+
3
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
4
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/esm/taggedTemplateLiteral";
5
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
6
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
7
+ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
8
+ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
9
+ var _templateObject, _templateObject2, _templateObject3;
10
+ var _excluded = ["data", "evolutionGradient", "gradient", "valueFormatter", "calculateFrom", "color", "variant", "showGridLines", "showYAxis", "showXAxis", "showArrow", "xAxisLabel", "yAxisLabel", "yAxisAlign", "showTooltip", "onValueChange", "customTooltip", "noDataText", "rotateLabelX", "barGap", "loading", "width", "height", "className", "style", "yAxisWidth"];
11
+ import { useSize } from 'ahooks';
12
+ import { Skeleton } from 'antd';
13
+ import { css } from 'antd-style';
14
+ import { Fragment, forwardRef, useEffect, useMemo, useRef, useState } from 'react';
15
+ import { Flexbox } from 'react-layout-kit';
16
+ import ArrowRightIcon from "./ArrowRightIcon";
17
+ import ChartTooltip from "../common/ChartTooltip";
18
+ import NoData from "../common/NoData";
19
+ import { useThemeColorRange } from "../hooks/useThemeColorRange";
20
+ import { defaultValueFormatter } from "../utils";
21
+ import { getMaxLabelLength } from "../utils/getMaxLabelLength";
22
+ import { useStyles } from "./styles";
23
+ import { jsx as _jsx } from "react/jsx-runtime";
24
+ import { jsxs as _jsxs } from "react/jsx-runtime";
25
+ import { Fragment as _Fragment } from "react/jsx-runtime";
26
+ var GLOBAL_PADDING = 10;
27
+ var HALF_PADDING = GLOBAL_PADDING / 2;
28
+ var Y_AXIS_LABELS = ['100%', '75%', '50%', '25%', '0%'];
29
+ var validateData = function validateData(data, calculatedFrom) {
30
+ if (data && data.length > 0) {
31
+ if (calculatedFrom === 'previous' && data[0].value <= 0) {
32
+ return "The value of the first item \"".concat(data[0].name, "\" is not greater than 0. This is not allowed when setting the \"calculateFrom\" prop to \"previous\". Please enter a value greater than 0.");
33
+ }
34
+ var _iterator = _createForOfIteratorHelper(data),
35
+ _step;
36
+ try {
37
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
38
+ var item = _step.value;
39
+ if (item.value < 0) {
40
+ return "Item \"".concat(item.name, "\" has a negative value: ").concat(item.value, ". This is not allowed. The value must be greater than or equal to 0.");
41
+ }
42
+ }
43
+ } catch (err) {
44
+ _iterator.e(err);
45
+ } finally {
46
+ _iterator.f();
47
+ }
48
+ }
49
+ return null;
50
+ };
51
+ var FunnelChart = /*#__PURE__*/forwardRef(function (props, ref) {
52
+ var _tooltip$data, _tooltip$data$name, _tooltip$data2, _tooltip$data$color, _tooltip$data3, _tooltip$data4;
53
+ var _useStyles = useStyles(),
54
+ cx = _useStyles.cx,
55
+ theme = _useStyles.theme,
56
+ styles = _useStyles.styles;
57
+ var themeColorRange = useThemeColorRange();
58
+ var _props$data = props.data,
59
+ data = _props$data === void 0 ? [] : _props$data,
60
+ _props$evolutionGradi = props.evolutionGradient,
61
+ evolutionGradient = _props$evolutionGradi === void 0 ? true : _props$evolutionGradi,
62
+ _props$gradient = props.gradient,
63
+ gradient = _props$gradient === void 0 ? false : _props$gradient,
64
+ _props$valueFormatter = props.valueFormatter,
65
+ valueFormatter = _props$valueFormatter === void 0 ? defaultValueFormatter : _props$valueFormatter,
66
+ _props$calculateFrom = props.calculateFrom,
67
+ calculateFrom = _props$calculateFrom === void 0 ? 'first' : _props$calculateFrom,
68
+ _props$color = props.color,
69
+ color = _props$color === void 0 ? themeColorRange[0] : _props$color,
70
+ _props$variant = props.variant,
71
+ variant = _props$variant === void 0 ? 'base' : _props$variant,
72
+ _props$showGridLines = props.showGridLines,
73
+ showGridLines = _props$showGridLines === void 0 ? true : _props$showGridLines,
74
+ _props$showYAxis = props.showYAxis,
75
+ showYAxis = _props$showYAxis === void 0 ? calculateFrom === 'previous' ? false : true : _props$showYAxis,
76
+ _props$showXAxis = props.showXAxis,
77
+ showXAxis = _props$showXAxis === void 0 ? true : _props$showXAxis,
78
+ _props$showArrow = props.showArrow,
79
+ showArrow = _props$showArrow === void 0 ? true : _props$showArrow,
80
+ _props$xAxisLabel = props.xAxisLabel,
81
+ xAxisLabel = _props$xAxisLabel === void 0 ? '' : _props$xAxisLabel,
82
+ _props$yAxisLabel = props.yAxisLabel,
83
+ yAxisLabel = _props$yAxisLabel === void 0 ? '' : _props$yAxisLabel,
84
+ _props$yAxisAlign = props.yAxisAlign,
85
+ yAxisAlign = _props$yAxisAlign === void 0 ? 'left' : _props$yAxisAlign,
86
+ _props$showTooltip = props.showTooltip,
87
+ showTooltip = _props$showTooltip === void 0 ? true : _props$showTooltip,
88
+ onValueChange = props.onValueChange,
89
+ customTooltip = props.customTooltip,
90
+ noDataText = props.noDataText,
91
+ rotateLabelX = props.rotateLabelX,
92
+ _props$barGap = props.barGap,
93
+ barGap = _props$barGap === void 0 ? '20%' : _props$barGap,
94
+ loading = props.loading,
95
+ _props$width = props.width,
96
+ width = _props$width === void 0 ? '100%' : _props$width,
97
+ _props$height = props.height,
98
+ height = _props$height === void 0 ? '20rem' : _props$height,
99
+ className = props.className,
100
+ style = props.style,
101
+ yAxisWidth = props.yAxisWidth,
102
+ rest = _objectWithoutProperties(props, _excluded);
103
+ var svgRef = useRef(ref);
104
+ var size = useSize(svgRef);
105
+ var tooltipRef = useRef(null);
106
+ var _useState = useState(0),
107
+ _useState2 = _slicedToArray(_useState, 2),
108
+ svgWidth = _useState2[0],
109
+ setSvgWidth = _useState2[1];
110
+ var _useState3 = useState(0),
111
+ _useState4 = _slicedToArray(_useState3, 2),
112
+ svgHeight = _useState4[0],
113
+ setSvgHeight = _useState4[1];
114
+ var _useState5 = useState({
115
+ x: 0,
116
+ y: 0
117
+ }),
118
+ _useState6 = _slicedToArray(_useState5, 2),
119
+ tooltip = _useState6[0],
120
+ setTooltip = _useState6[1];
121
+ var _useState7 = useState(),
122
+ _useState8 = _slicedToArray(_useState7, 2),
123
+ activeBar = _useState8[0],
124
+ setActiveBar = _useState8[1];
125
+ var DEFAULT_X_AXIS_HEIGHT = showXAxis && xAxisLabel ? 25 : 15;
126
+ var CustomTooltip = customTooltip;
127
+ var calculatedYAxisWidth = useMemo(function () {
128
+ if (yAxisWidth) return yAxisWidth;
129
+ return getMaxLabelLength({
130
+ data: data,
131
+ index: 'value',
132
+ valueFormatter: valueFormatter
133
+ }) / 4 + (yAxisLabel ? 24 : 0);
134
+ }, [yAxisWidth, data, valueFormatter, yAxisLabel]);
135
+ useEffect(function () {
136
+ var handleResize = function handleResize() {
137
+ setSvgWidth((size === null || size === void 0 ? void 0 : size.width) || 0);
138
+ setSvgHeight((size === null || size === void 0 ? void 0 : size.height) || 0);
139
+ };
140
+ handleResize();
141
+ }, [size]);
142
+ useEffect(function () {
143
+ var handleTooltipOverflows = function handleTooltipOverflows() {
144
+ if (tooltipRef.current) {
145
+ var boundingBox = tooltipRef.current.getBoundingClientRect();
146
+ if (boundingBox.right > window.innerWidth) {
147
+ tooltipRef.current.style.left = "".concat(svgWidth - boundingBox.width, "px");
148
+ }
149
+ }
150
+ };
151
+ handleTooltipOverflows();
152
+ window.addEventListener('resize', handleTooltipOverflows);
153
+ return function () {
154
+ return window.removeEventListener('resize', handleTooltipOverflows);
155
+ };
156
+ }, [tooltip, svgWidth]);
157
+ var maxValue = useMemo(function () {
158
+ return Math.max.apply(Math, _toConsumableArray(data.map(function (item) {
159
+ return item.value;
160
+ })));
161
+ }, [data]);
162
+ var widthWithoutPadding = svgWidth - GLOBAL_PADDING - calculatedYAxisWidth;
163
+ var gap = useMemo(function () {
164
+ if (typeof barGap === 'number') {
165
+ return barGap;
166
+ } else if (typeof barGap === 'string' && barGap.endsWith('%')) {
167
+ var percentage = Number.parseFloat(barGap.slice(0, -1));
168
+ var totalWidthForGaps = widthWithoutPadding * percentage / 100;
169
+ var numberOfGaps = data.length - 1;
170
+ return totalWidthForGaps / numberOfGaps;
171
+ } else {
172
+ console.error('Invalid barGap value. It must be a number or a percentage string (e.g., "10%").');
173
+ return 30;
174
+ }
175
+ }, [widthWithoutPadding, data.length, barGap]);
176
+ var barWidth = useMemo(function () {
177
+ return (widthWithoutPadding - (data.length - 1) * gap - gap) / data.length;
178
+ }, [widthWithoutPadding, gap, data.length]);
179
+ var realHeight = svgHeight - GLOBAL_PADDING - (showXAxis ? ((rotateLabelX === null || rotateLabelX === void 0 ? void 0 : rotateLabelX.xAxisHeight) || DEFAULT_X_AXIS_HEIGHT) + (showXAxis && xAxisLabel ? 30 : 10) : 0);
180
+ var isPreviousCalculation = calculateFrom === 'previous';
181
+ var isVariantCenter = variant === 'center';
182
+ var formattedData = useMemo(function () {
183
+ if (realHeight <= 0) return [];
184
+ return data.reduce(function (acc, item, index) {
185
+ var _prev$value, _prev$barHeight, _prev$barHeight2, _data;
186
+ var prev = acc[index - 1];
187
+ var value = item.value;
188
+ var valueToCompareWith = isPreviousCalculation ? (_prev$value = prev === null || prev === void 0 ? void 0 : prev.value) !== null && _prev$value !== void 0 ? _prev$value : maxValue : maxValue;
189
+ var calculationHeight = isPreviousCalculation ? (_prev$barHeight = prev === null || prev === void 0 ? void 0 : prev.barHeight) !== null && _prev$barHeight !== void 0 ? _prev$barHeight : realHeight : realHeight;
190
+ var normalizedValue = value / valueToCompareWith;
191
+ var barHeight = normalizedValue * calculationHeight;
192
+ var startX = index * (barWidth + gap) + 0.5 * gap;
193
+ var startY = calculationHeight - barHeight + (isPreviousCalculation ? realHeight - ((_prev$barHeight2 = prev === null || prev === void 0 ? void 0 : prev.barHeight) !== null && _prev$barHeight2 !== void 0 ? _prev$barHeight2 : realHeight) : 0);
194
+ var nextValue = (_data = data[index + 1]) === null || _data === void 0 ? void 0 : _data.value;
195
+ var nextNormalizedValue = nextValue / valueToCompareWith;
196
+ var nextBarHeight = nextNormalizedValue * calculationHeight;
197
+ var nextStartX = (index + 1) * (barWidth + gap) + 0.5 * gap;
198
+ acc.push({
199
+ barHeight: barHeight,
200
+ name: item.name,
201
+ nextBarHeight: nextBarHeight,
202
+ nextNormalizedValue: nextNormalizedValue,
203
+ nextStartX: nextStartX,
204
+ nextValue: nextValue,
205
+ normalizedValue: normalizedValue,
206
+ startX: startX,
207
+ startY: startY,
208
+ value: value
209
+ });
210
+ return acc;
211
+ }, []);
212
+ }, [data, realHeight, isPreviousCalculation, barWidth, gap, maxValue]);
213
+ var handleTooltip = function handleTooltip(touch) {
214
+ var _svgRef$current;
215
+ var chartBoundingRect = (_svgRef$current = svgRef.current) === null || _svgRef$current === void 0 ? void 0 : _svgRef$current.getBoundingClientRect();
216
+ if (!chartBoundingRect) return;
217
+ var chartX = chartBoundingRect.x;
218
+ if (formattedData.length === 0) {
219
+ return setTooltip({
220
+ x: 0,
221
+ y: 0
222
+ });
223
+ }
224
+ var pageX = touch.pageX - chartX - barWidth / 2 - calculatedYAxisWidth - HALF_PADDING;
225
+ var closestBar = formattedData.reduce(function (acc, current) {
226
+ var currentDistance = Math.abs(current.startX - pageX);
227
+ var accDistance = Math.abs(acc.startX - pageX);
228
+ return currentDistance < accDistance ? current : acc;
229
+ }, formattedData[0]); // 提供初始值
230
+
231
+ var closestBarIndex = formattedData.indexOf(closestBar);
232
+ setTooltip({
233
+ data: {
234
+ className: cx(css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n cursor: ", ";\n color: ", ";\n "])), onValueChange ? 'pointer' : undefined, color !== null && color !== void 0 ? color : theme.colorPrimary)),
235
+ color: color !== null && color !== void 0 ? color : theme.colorPrimary,
236
+ dataKey: closestBar.name,
237
+ fill: '',
238
+ name: closestBar.name,
239
+ payload: closestBar,
240
+ value: closestBar.value
241
+ },
242
+ index: closestBarIndex,
243
+ x: closestBar.startX,
244
+ y: closestBar.startY
245
+ });
246
+ };
247
+ if (loading || !data) return /*#__PURE__*/_jsx(Skeleton.Button, {
248
+ active: true,
249
+ block: true,
250
+ style: {
251
+ height: height,
252
+ width: width
253
+ }
254
+ });
255
+ var errorMessage = data ? validateData(data, calculateFrom) : null;
256
+ if (errorMessage) {
257
+ return /*#__PURE__*/_jsx(NoData, {
258
+ noDataText: errorMessage
259
+ });
260
+ }
261
+ var onBarClick = function onBarClick(data, idx, event) {
262
+ event.stopPropagation();
263
+ if (!onValueChange) return;
264
+ if (idx === (activeBar === null || activeBar === void 0 ? void 0 : activeBar.index)) {
265
+ setActiveBar(undefined);
266
+ onValueChange === null || onValueChange === void 0 || onValueChange(null);
267
+ } else {
268
+ setActiveBar({
269
+ data: data,
270
+ index: idx
271
+ });
272
+ onValueChange === null || onValueChange === void 0 || onValueChange(_objectSpread({
273
+ categoryClicked: data.name,
274
+ eventType: 'bar'
275
+ }, data));
276
+ }
277
+ };
278
+ return /*#__PURE__*/_jsx(Flexbox, _objectSpread(_objectSpread({
279
+ className: className,
280
+ height: height,
281
+ ref: svgRef,
282
+ style: _objectSpread({
283
+ position: 'relative'
284
+ }, style),
285
+ width: width
286
+ }, rest), {}, {
287
+ children: data !== null && data !== void 0 && data.length ? /*#__PURE__*/_jsxs(_Fragment, {
288
+ children: [/*#__PURE__*/_jsxs("svg", {
289
+ onMouseLeave: function onMouseLeave() {
290
+ return setTooltip({
291
+ x: 0,
292
+ y: 0
293
+ });
294
+ },
295
+ onMouseMove: function onMouseMove(e) {
296
+ var fakeTouch = {
297
+ clientX: e.clientX,
298
+ clientY: e.clientY,
299
+ pageX: e.pageX,
300
+ pageY: e.pageY
301
+ };
302
+ handleTooltip(fakeTouch);
303
+ },
304
+ onTouchEnd: function onTouchEnd() {
305
+ return setTooltip({
306
+ x: 0,
307
+ y: 0
308
+ });
309
+ },
310
+ onTouchMove: function onTouchMove(e) {
311
+ var touch = e.touches[0];
312
+ handleTooltip(touch);
313
+ },
314
+ style: {
315
+ height: '100%',
316
+ width: '100%'
317
+ },
318
+ xmlns: "http://www.w3.org/2000/svg",
319
+ children: [Y_AXIS_LABELS.map(function (label, index) {
320
+ return /*#__PURE__*/_jsxs(Fragment, {
321
+ children: [showGridLines && /*#__PURE__*/_jsx("line", {
322
+ className: styles.gridLines,
323
+ x1: calculatedYAxisWidth + HALF_PADDING,
324
+ x2: svgWidth - HALF_PADDING,
325
+ y1: index * realHeight / 4 + HALF_PADDING,
326
+ y2: index * realHeight / 4 + HALF_PADDING
327
+ }), /*#__PURE__*/_jsx("text", {
328
+ className: styles.label,
329
+ textAnchor: yAxisAlign === 'left' ? 'start' : 'end',
330
+ x: yAxisAlign === 'left' ? yAxisLabel ? 24 : 0 : calculatedYAxisWidth - 10 + HALF_PADDING,
331
+ y: index * realHeight / 4 + 5 + HALF_PADDING,
332
+ children: label
333
+ })]
334
+ }, "y-axis-".concat(index));
335
+ }), formattedData.map(function (item, index) {
336
+ var _formattedData, _formattedData2;
337
+ return /*#__PURE__*/_jsxs("g", {
338
+ children: [/*#__PURE__*/_jsx("rect", {
339
+ height: realHeight,
340
+ style: {
341
+ fill: tooltip.index === index ? theme.colorFillTertiary : 'transparent',
342
+ zIndex: 0
343
+ },
344
+ width: barWidth + gap,
345
+ x: item.startX - gap * 0.5 + HALF_PADDING + calculatedYAxisWidth,
346
+ y: HALF_PADDING
347
+ }), gradient && /*#__PURE__*/_jsx("rect", {
348
+ fill: "url(#base-gradient)",
349
+ height: (realHeight - item.barHeight - (isPreviousCalculation ? realHeight - ((_formattedData = formattedData[index - 1]) === null || _formattedData === void 0 ? void 0 : _formattedData.barHeight) || 0 : 0)) / (isVariantCenter ? 2 : 1),
350
+ style: {
351
+ opacity: activeBar && activeBar.index !== index ? 0.3 : 1
352
+ },
353
+ width: barWidth,
354
+ x: item.startX + HALF_PADDING + calculatedYAxisWidth,
355
+ y: realHeight - (isPreviousCalculation ? ((_formattedData2 = formattedData[index - 1]) === null || _formattedData2 === void 0 ? void 0 : _formattedData2.barHeight) || realHeight : realHeight) + HALF_PADDING
356
+ }), /*#__PURE__*/_jsx("rect", {
357
+ height: item.barHeight,
358
+ onClick: function onClick(e) {
359
+ return onBarClick(item, index, e);
360
+ },
361
+ style: {
362
+ cursor: onValueChange ? 'pointer' : undefined,
363
+ fill: color !== null && color !== void 0 ? color : theme.colorPrimary,
364
+ opacity: activeBar && activeBar.index !== index ? 0.3 : 1
365
+ },
366
+ width: barWidth,
367
+ x: item.startX + HALF_PADDING + calculatedYAxisWidth,
368
+ y: (isVariantCenter ? realHeight / 2 - item.barHeight / 2 : item.startY) + HALF_PADDING
369
+ }), gradient && isVariantCenter && /*#__PURE__*/_jsx("rect", {
370
+ fill: "url(#base-gradient-revert)",
371
+ height: (realHeight - item.barHeight) / 2,
372
+ style: {
373
+ opacity: activeBar && activeBar.index !== index ? 0.3 : 1
374
+ },
375
+ width: barWidth,
376
+ x: item.startX + HALF_PADDING + calculatedYAxisWidth,
377
+ y: realHeight / 2 + item.barHeight / 2 + HALF_PADDING
378
+ }), showXAxis && /*#__PURE__*/_jsx("foreignObject", {
379
+ height: (rotateLabelX === null || rotateLabelX === void 0 ? void 0 : rotateLabelX.xAxisHeight) || DEFAULT_X_AXIS_HEIGHT,
380
+ transform: rotateLabelX ? "rotate(".concat(rotateLabelX === null || rotateLabelX === void 0 ? void 0 : rotateLabelX.angle, ", ").concat(item.startX + barWidth / 2 + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight + ((rotateLabelX === null || rotateLabelX === void 0 ? void 0 : rotateLabelX.xAxisHeight) || DEFAULT_X_AXIS_HEIGHT) / 2 + HALF_PADDING + ((rotateLabelX === null || rotateLabelX === void 0 ? void 0 : rotateLabelX.verticalShift) || 0), ")") : undefined,
381
+ width: barWidth,
382
+ x: item.startX + HALF_PADDING + calculatedYAxisWidth,
383
+ y: realHeight + HALF_PADDING + 10,
384
+ children: /*#__PURE__*/_jsx("div", {
385
+ className: cx(styles.strongLabel, styles.emphasis),
386
+ title: item.name,
387
+ children: item.name
388
+ })
389
+ })]
390
+ }, "bar-".concat(index));
391
+ }), formattedData.map(function (item, index) {
392
+ return /*#__PURE__*/_jsxs(Fragment, {
393
+ children: [index < data.length - 1 && evolutionGradient && (isVariantCenter ? /*#__PURE__*/_jsxs(_Fragment, {
394
+ children: [/*#__PURE__*/_jsx("polygon", {
395
+ fill: "url(#base-gradient)",
396
+ points: "\n ".concat(item.startX + barWidth + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight / 2 + item.nextBarHeight / 4 + HALF_PADDING, "\n ").concat(item.nextStartX + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight / 2 + item.nextBarHeight / 4 + HALF_PADDING, "\n ").concat(item.nextStartX + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight / 2 - item.nextBarHeight / 2 + HALF_PADDING, "\n ").concat(item.startX + barWidth + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight / 2 - item.barHeight / 2 + HALF_PADDING, "\n "),
397
+ style: {
398
+ opacity: activeBar && activeBar.index !== index ? 0.3 : 1,
399
+ zIndex: 10
400
+ }
401
+ }), /*#__PURE__*/_jsx("polygon", {
402
+ fill: "url(#base-gradient-revert)",
403
+ points: "\n ".concat(item.startX + barWidth + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight / 2 + item.barHeight / 2 + HALF_PADDING, "\n ").concat(item.nextStartX + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight / 2 + item.nextBarHeight / 2 + HALF_PADDING, "\n ").concat(item.nextStartX + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight / 2 - item.nextBarHeight / 4 + HALF_PADDING, "\n ").concat(item.startX + barWidth + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight / 2 - item.nextBarHeight / 4 + HALF_PADDING, "\n "),
404
+ style: {
405
+ opacity: activeBar && activeBar.index !== index ? 0.3 : 1,
406
+ zIndex: 10
407
+ }
408
+ })]
409
+ }) : /*#__PURE__*/_jsx("polygon", {
410
+ fill: "url(#base-gradient)",
411
+ points: "\n ".concat(item.startX + barWidth + HALF_PADDING + calculatedYAxisWidth, ", ").concat(item.startY + HALF_PADDING, "\n ").concat(item.nextStartX + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight - item.nextBarHeight + HALF_PADDING, "\n ").concat(item.nextStartX + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight + HALF_PADDING, "\n ").concat(item.startX + barWidth + HALF_PADDING + calculatedYAxisWidth, ", ").concat(realHeight + HALF_PADDING, "\n "),
412
+ style: {
413
+ opacity: activeBar && activeBar.index !== index ? 0.3 : 1,
414
+ zIndex: 10
415
+ }
416
+ })), index < data.length - 1 && showXAxis && showArrow && gap >= 14 && /*#__PURE__*/_jsx("foreignObject", {
417
+ height: (rotateLabelX === null || rotateLabelX === void 0 ? void 0 : rotateLabelX.xAxisHeight) || DEFAULT_X_AXIS_HEIGHT,
418
+ width: 12,
419
+ x: item.startX + barWidth + HALF_PADDING + calculatedYAxisWidth - 6 + gap / 2,
420
+ y: realHeight + HALF_PADDING + 11,
421
+ children: /*#__PURE__*/_jsx(ArrowRightIcon, {})
422
+ })]
423
+ }, "gradient-".concat(index));
424
+ }), /*#__PURE__*/_jsxs("linearGradient", {
425
+ className: cx(css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n stop {\n stop-color: ", ";\n }\n "])), color !== null && color !== void 0 ? color : theme.colorPrimary)),
426
+ id: 'base-gradient',
427
+ x1: "0%",
428
+ x2: "0%",
429
+ y1: "0%",
430
+ y2: "100%",
431
+ children: [/*#__PURE__*/_jsx("stop", {
432
+ offset: "5%",
433
+ stopOpacity: 0.4
434
+ }), /*#__PURE__*/_jsx("stop", {
435
+ offset: "95%",
436
+ stopOpacity: 0
437
+ })]
438
+ }), /*#__PURE__*/_jsxs("linearGradient", {
439
+ className: cx(css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n stop {\n stop-color: ", ";\n }\n "])), color !== null && color !== void 0 ? color : theme.colorPrimary)),
440
+ id: 'base-gradient-revert',
441
+ x1: "0%",
442
+ x2: "0%",
443
+ y1: "0%",
444
+ y2: "100%",
445
+ children: [/*#__PURE__*/_jsx("stop", {
446
+ offset: "5%",
447
+ stopOpacity: 0
448
+ }), /*#__PURE__*/_jsx("stop", {
449
+ offset: "95%",
450
+ stopOpacity: 0.4
451
+ })]
452
+ }), showXAxis && xAxisLabel && /*#__PURE__*/_jsx("text", {
453
+ className: cx(styles.strongLabel, styles.emphasis),
454
+ x: svgWidth / 2 + calculatedYAxisWidth / 2,
455
+ y: realHeight + HALF_PADDING + 50,
456
+ children: xAxisLabel
457
+ }), showYAxis && yAxisLabel && /*#__PURE__*/_jsx("text", {
458
+ className: cx(styles.strongLabel, styles.emphasis),
459
+ transform: "rotate(-90, 0, ".concat(realHeight / 2, ")"),
460
+ x: -5,
461
+ y: realHeight / 2 + 10,
462
+ children: yAxisLabel
463
+ })]
464
+ }), showTooltip && /*#__PURE__*/_jsx("div", {
465
+ ref: tooltipRef,
466
+ style: {
467
+ display: tooltip.data ? 'block' : 'none',
468
+ left: tooltip.x + barWidth * 0.66,
469
+ pointerEvents: 'none',
470
+ position: 'absolute',
471
+ top: 0
472
+ },
473
+ tabIndex: -1,
474
+ children: CustomTooltip ? /*#__PURE__*/_jsx(CustomTooltip, {
475
+ active: !!tooltip.data,
476
+ label: (_tooltip$data = tooltip.data) === null || _tooltip$data === void 0 ? void 0 : _tooltip$data.name,
477
+ payload: tooltip.data ? [tooltip.data] : []
478
+ }) : /*#__PURE__*/_jsx(ChartTooltip, {
479
+ active: !!tooltip.data,
480
+ categoryColors: new Map([[(_tooltip$data$name = (_tooltip$data2 = tooltip.data) === null || _tooltip$data2 === void 0 ? void 0 : _tooltip$data2.name) !== null && _tooltip$data$name !== void 0 ? _tooltip$data$name : '', (_tooltip$data$color = (_tooltip$data3 = tooltip.data) === null || _tooltip$data3 === void 0 ? void 0 : _tooltip$data3.color) !== null && _tooltip$data$color !== void 0 ? _tooltip$data$color : '']]),
481
+ label: ((_tooltip$data4 = tooltip.data) === null || _tooltip$data4 === void 0 ? void 0 : _tooltip$data4.name) || '',
482
+ payload: tooltip.data ? [tooltip.data] : [],
483
+ valueFormatter: valueFormatter
484
+ })
485
+ })]
486
+ }) : /*#__PURE__*/_jsx(NoData, {
487
+ noDataText: noDataText
488
+ })
489
+ }));
490
+ });
491
+ FunnelChart.displayName = 'FunnelChart';
492
+ export default FunnelChart;
@@ -0,0 +1,6 @@
1
+ export declare const useStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
2
+ emphasis: import("antd-style").SerializedStyles;
3
+ gridLines: import("antd-style").SerializedStyles;
4
+ label: import("antd-style").SerializedStyles;
5
+ strongLabel: import("antd-style").SerializedStyles;
6
+ }>;
@@ -0,0 +1,13 @@
1
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/esm/taggedTemplateLiteral";
2
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4;
3
+ import { createStyles } from 'antd-style';
4
+ export var useStyles = createStyles(function (_ref) {
5
+ var css = _ref.css,
6
+ token = _ref.token;
7
+ return {
8
+ emphasis: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n "]))),
9
+ gridLines: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n stroke: ", ";\n stroke-width: 1;\n "])), token.colorBorderSecondary),
10
+ label: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n font-size: 12px;\n line-height: 16px;\n fill: ", ";\n "])), token.colorTextDescription),
11
+ strongLabel: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n fill: ", ";\n "])), token.colorTextSecondary)
12
+ };
13
+ });
@@ -0,0 +1,28 @@
1
+ export type Tooltip = {
2
+ data?: {
3
+ className?: string;
4
+ color?: string;
5
+ dataKey: string;
6
+ fill?: string;
7
+ name: string;
8
+ payload?: any;
9
+ value: number;
10
+ };
11
+ index?: number;
12
+ x: number;
13
+ y: number;
14
+ };
15
+ export type DataT = {
16
+ name: string;
17
+ value: number;
18
+ };
19
+ export type FormattedDataT = DataT & {
20
+ barHeight: number;
21
+ nextBarHeight: number;
22
+ nextNormalizedValue: number;
23
+ nextStartX: number;
24
+ nextValue: number;
25
+ normalizedValue: number;
26
+ startX: number;
27
+ startY: number;
28
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -19,7 +19,6 @@ var NoData = /*#__PURE__*/memo(function (_ref) {
19
19
  children: /*#__PURE__*/_jsx(Empty, {
20
20
  className: className,
21
21
  description: isReactNodeText ? noDataText : /*#__PURE__*/_jsxs(Flexbox, {
22
- gap: 4,
23
22
  padding: 8,
24
23
  children: [/*#__PURE__*/_jsx("div", {
25
24
  style: {
@@ -31,7 +30,7 @@ var NoData = /*#__PURE__*/memo(function (_ref) {
31
30
  }), /*#__PURE__*/_jsx("div", {
32
31
  style: {
33
32
  color: theme.colorTextDescription,
34
- fontSize: 14
33
+ fontSize: 12
35
34
  },
36
35
  children: noDataText === null || noDataText === void 0 ? void 0 : noDataText.desc
37
36
  })]
package/es/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { type Bar, default as BarList, type BarListProps } from './BarList';
4
4
  export { default as ChartTooltipFrame } from './common/ChartTooltip/ChartTooltipFrame';
5
5
  export * from './DataBars';
6
6
  export { default as DonutChart, type DonutChartProps } from './DonutChart';
7
+ export { default as FunnelChart, type FunnelChartProps } from './FunnelChart';
7
8
  export { default as Heatmaps, type HeatmapsProps } from './Heatmaps';
8
9
  export { default as Legend, type LegendProps } from './Legend';
9
10
  export { default as LineChart, type LineChartProps } from './LineChart';
package/es/index.js CHANGED
@@ -4,6 +4,7 @@ export { default as BarList } from "./BarList";
4
4
  export { default as ChartTooltipFrame } from "./common/ChartTooltip/ChartTooltipFrame";
5
5
  export * from "./DataBars";
6
6
  export { default as DonutChart } from "./DonutChart";
7
+ export { default as FunnelChart } from "./FunnelChart";
7
8
  export { default as Heatmaps } from "./Heatmaps";
8
9
  export { default as Legend } from "./Legend";
9
10
  export { default as LineChart } from "./LineChart";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/charts",
3
- "version": "1.6.2",
3
+ "version": "1.7.1",
4
4
  "description": "React modern charts components built on recharts",
5
5
  "keywords": [
6
6
  "lobehub",