@carto/ps-react-ui 4.3.6 → 4.3.8
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/components.js +123 -123
- package/dist/components.js.map +1 -1
- package/dist/error-CEkRPccv.js +39 -0
- package/dist/error-CEkRPccv.js.map +1 -0
- package/dist/{lasso-tool-BctzdzBu.js → lasso-tool-jl4YK02H.js} +19 -19
- package/dist/lasso-tool-jl4YK02H.js.map +1 -0
- package/dist/no-data-hR3KcJ-_.js +60 -0
- package/dist/no-data-hR3KcJ-_.js.map +1 -0
- package/dist/{row-D3uVFImu.js → row-BKmVAUN5.js} +2 -2
- package/dist/{row-D3uVFImu.js.map → row-BKmVAUN5.js.map} +1 -1
- package/dist/{series-BAImrSBo.js → series-D1pynfeh.js} +3 -3
- package/dist/{series-BAImrSBo.js.map → series-D1pynfeh.js.map} +1 -1
- package/dist/{styles-CCZnY17y.js → styles-DrPyd0y5.js} +28 -22
- package/dist/styles-DrPyd0y5.js.map +1 -0
- package/dist/types/components/lasso-tool/types.d.ts +1 -1
- package/dist/types/widgets/_shared/chart-config/index.d.ts +1 -1
- package/dist/types/widgets/_shared/chart-config/option-builders.d.ts +7 -0
- package/dist/types/widgets/_shared/chart-config/option-builders.test.d.ts +1 -0
- package/dist/types/widgets/actions/change-column/change-column.d.ts +4 -0
- package/dist/types/widgets/actions/fullscreen/fullscreen.d.ts +1 -1
- package/dist/types/widgets/actions/fullscreen/types.d.ts +2 -1
- package/dist/types/widgets/actions/index.d.ts +1 -1
- package/dist/types/widgets/actions/lock-selection/types.d.ts +7 -7
- package/dist/types/widgets/actions/relative-data/types.d.ts +1 -1
- package/dist/types/widgets/echart/types.d.ts +0 -4
- package/dist/types/widgets/echart/utils.d.ts +2 -1
- package/dist/types/widgets/error/error.d.ts +1 -1
- package/dist/types/widgets/error/types.d.ts +8 -0
- package/dist/types/widgets/loader/loader.d.ts +1 -1
- package/dist/types/widgets/loader/types.d.ts +1 -1
- package/dist/types/widgets/stores/types.d.ts +1 -1
- package/dist/{use-widget-ref-B8x4sHIj.js → use-widget-ref-P-2i0MJG.js} +2 -2
- package/dist/{use-widget-ref-B8x4sHIj.js.map → use-widget-ref-P-2i0MJG.js.map} +1 -1
- package/dist/{utils-D3-eQyDR.js → utils-idmvq0Oa.js} +17 -16
- package/dist/utils-idmvq0Oa.js.map +1 -0
- package/dist/{widget-store-Dn0Bnc4h.js → widget-store-CzDt8oSK.js} +31 -46
- package/dist/widget-store-CzDt8oSK.js.map +1 -0
- package/dist/widgets/actions.js +714 -697
- package/dist/widgets/actions.js.map +1 -1
- package/dist/widgets/bar.js +67 -63
- package/dist/widgets/bar.js.map +1 -1
- package/dist/widgets/category.js +250 -241
- package/dist/widgets/category.js.map +1 -1
- package/dist/widgets/echart.js +93 -100
- package/dist/widgets/echart.js.map +1 -1
- package/dist/widgets/error.js +1 -1
- package/dist/widgets/formula.js +64 -72
- package/dist/widgets/formula.js.map +1 -1
- package/dist/widgets/histogram.js +75 -73
- package/dist/widgets/histogram.js.map +1 -1
- package/dist/widgets/loader.js +58 -49
- package/dist/widgets/loader.js.map +1 -1
- package/dist/widgets/markdown.js +2 -2
- package/dist/widgets/no-data.js +1 -1
- package/dist/widgets/pie.js +4 -4
- package/dist/widgets/range.js +97 -105
- package/dist/widgets/range.js.map +1 -1
- package/dist/widgets/scatterplot.js +8 -8
- package/dist/widgets/skeleton-loader.js +1 -1
- package/dist/widgets/spread.js +84 -100
- package/dist/widgets/spread.js.map +1 -1
- package/dist/widgets/stores.js +1 -1
- package/dist/widgets/table.js +493 -485
- package/dist/widgets/table.js.map +1 -1
- package/dist/widgets/timeseries.js +4 -4
- package/dist/widgets/wrapper.js +156 -156
- package/dist/widgets/wrapper.js.map +1 -1
- package/dist/widgets.js +4 -4
- package/package.json +1 -1
- package/src/components/lasso-tool/lasso-tool-inline.tsx +19 -17
- package/src/components/lasso-tool/lasso-tool.tsx +22 -20
- package/src/components/lasso-tool/types.ts +4 -3
- package/src/widgets/_shared/chart-config/index.ts +1 -0
- package/src/widgets/_shared/chart-config/option-builders.test.ts +40 -0
- package/src/widgets/_shared/chart-config/option-builders.ts +12 -0
- package/src/widgets/actions/change-column/change-column.test.tsx +129 -2
- package/src/widgets/actions/change-column/change-column.tsx +79 -2
- package/src/widgets/actions/fullscreen/fullscreen.tsx +8 -8
- package/src/widgets/actions/fullscreen/types.ts +6 -1
- package/src/widgets/actions/index.ts +4 -1
- package/src/widgets/actions/lock-selection/lock-selection.test.tsx +28 -30
- package/src/widgets/actions/lock-selection/types.ts +8 -8
- package/src/widgets/actions/relative-data/relative-data.test.tsx +13 -13
- package/src/widgets/actions/relative-data/types.ts +1 -1
- package/src/widgets/actions/stack-toggle/stack-toggle.test.tsx +19 -9
- package/src/widgets/actions/zoom-toggle/zoom-toggle.tsx +113 -95
- package/src/widgets/bar/config.ts +37 -28
- package/src/widgets/category/category-ui.tsx +25 -22
- package/src/widgets/echart/echart-ui.test.tsx +3 -18
- package/src/widgets/echart/echart-ui.tsx +4 -22
- package/src/widgets/echart/echart.test.tsx +9 -25
- package/src/widgets/echart/echart.tsx +36 -29
- package/src/widgets/echart/types.ts +0 -4
- package/src/widgets/echart/utils.ts +3 -1
- package/src/widgets/error/error.tsx +17 -14
- package/src/widgets/error/types.ts +10 -0
- package/src/widgets/formula/components/value.tsx +13 -13
- package/src/widgets/histogram/config.ts +36 -29
- package/src/widgets/loader/loader.tsx +28 -25
- package/src/widgets/loader/types.ts +3 -1
- package/src/widgets/no-data/no-data.tsx +8 -11
- package/src/widgets/range/components/range-item.tsx +9 -13
- package/src/widgets/spread/components/max-value.tsx +13 -13
- package/src/widgets/spread/components/min-value.tsx +13 -13
- package/src/widgets/stores/types.ts +1 -4
- package/src/widgets/stores/widget-store.ts +1 -27
- package/src/widgets/table/hooks/use-pagination.ts +44 -35
- package/src/widgets/table/hooks/use-sort.ts +25 -23
- package/src/widgets/wrapper/wrapper-ui.tsx +16 -17
- package/dist/error-piB8FwYO.js +0 -38
- package/dist/error-piB8FwYO.js.map +0 -1
- package/dist/lasso-tool-BctzdzBu.js.map +0 -1
- package/dist/no-data-jdlbMef0.js +0 -61
- package/dist/no-data-jdlbMef0.js.map +0 -1
- package/dist/styles-CCZnY17y.js.map +0 -1
- package/dist/utils-D3-eQyDR.js.map +0 -1
- package/dist/widget-store-Dn0Bnc4h.js.map +0 -1
|
@@ -5,11 +5,10 @@ import {
|
|
|
5
5
|
} from '@mui/icons-material'
|
|
6
6
|
import { useEffect, useCallback } from 'react'
|
|
7
7
|
import { useWidgetStore } from '../../stores/widget-store'
|
|
8
|
-
import type { ZoomToggleProps
|
|
8
|
+
import type { ZoomToggleProps } from './types'
|
|
9
9
|
import { styles } from './style'
|
|
10
10
|
import { Tooltip } from '../../../components'
|
|
11
11
|
import { getEChartZoomConfig } from '../../echart/utils'
|
|
12
|
-
import type { EchartWidgetState } from '../../echart/types'
|
|
13
12
|
import type { EchartOptionsProps } from '../../echart/types'
|
|
14
13
|
import { useShallow } from 'zustand/shallow'
|
|
15
14
|
|
|
@@ -45,143 +44,162 @@ export function ZoomToggle({
|
|
|
45
44
|
IconButtonProps,
|
|
46
45
|
}: ZoomToggleProps) {
|
|
47
46
|
const theme = useTheme()
|
|
48
|
-
const setWidget = useWidgetStore((state) => state.setWidget)
|
|
49
47
|
const getWidget = useWidgetStore((state) => state.getWidget)
|
|
50
48
|
const registerTool = useWidgetStore((state) => state.registerTool)
|
|
51
49
|
const unregisterTool = useWidgetStore((state) => state.unregisterTool)
|
|
52
50
|
const setToolEnabled = useWidgetStore((state) => state.setToolEnabled)
|
|
53
51
|
const updateToolConfig = useWidgetStore((state) => state.updateToolConfig)
|
|
54
52
|
|
|
55
|
-
const
|
|
53
|
+
const zoomTool = useWidgetStore(
|
|
56
54
|
useShallow((state) => {
|
|
57
|
-
const
|
|
58
|
-
return
|
|
55
|
+
const tools = state.getWidget(id)?.registeredTools ?? []
|
|
56
|
+
return tools.find((tool) => tool.id === ZOOM_TOGGLE_TOOL_ID)
|
|
59
57
|
}),
|
|
60
58
|
)
|
|
61
59
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
)
|
|
60
|
+
const zoom = zoomTool?.enabled ?? defaultZoom
|
|
61
|
+
const zoomStart =
|
|
62
|
+
(zoomTool?.config?.start as number | undefined) ?? defaultZoomStart
|
|
63
|
+
const zoomEnd =
|
|
64
|
+
(zoomTool?.config?.end as number | undefined) ?? defaultZoomEnd
|
|
68
65
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
// Handle dataZoom event to update zoom range in tool config
|
|
67
|
+
const handleDataZoom = useCallback(
|
|
68
|
+
(event: unknown) => {
|
|
69
|
+
const zoomEvent = event as {
|
|
70
|
+
start?: number
|
|
71
|
+
end?: number
|
|
72
|
+
batch?: {
|
|
73
|
+
start?: number
|
|
74
|
+
end?: number
|
|
75
|
+
}[]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const start = zoomEvent.start ?? zoomEvent.batch?.[0]?.start
|
|
79
|
+
const end = zoomEvent.end ?? zoomEvent.batch?.[0]?.end
|
|
80
|
+
|
|
81
|
+
if (start !== undefined && end !== undefined) {
|
|
82
|
+
setToolEnabled(id, ZOOM_TOGGLE_TOOL_ID, true)
|
|
83
|
+
updateToolConfig(id, ZOOM_TOGGLE_TOOL_ID, {
|
|
84
|
+
enabled: true,
|
|
85
|
+
start,
|
|
86
|
+
end,
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
[id, setToolEnabled, updateToolConfig],
|
|
74
91
|
)
|
|
75
92
|
|
|
76
93
|
// Register config tool on mount
|
|
77
94
|
useEffect(() => {
|
|
95
|
+
const existingTool = getWidget(id)?.registeredTools?.find(
|
|
96
|
+
(tool) => tool.id === ZOOM_TOGGLE_TOOL_ID,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
const initialEnabled = existingTool?.enabled ?? defaultZoom
|
|
100
|
+
const initialStart =
|
|
101
|
+
(existingTool?.config?.start as number | undefined) ?? defaultZoomStart
|
|
102
|
+
const initialEnd =
|
|
103
|
+
(existingTool?.config?.end as number | undefined) ?? defaultZoomEnd
|
|
104
|
+
|
|
78
105
|
registerTool(id, {
|
|
79
106
|
id: ZOOM_TOGGLE_TOOL_ID,
|
|
80
107
|
type: 'config',
|
|
81
108
|
order: 20,
|
|
82
|
-
enabled:
|
|
109
|
+
enabled: initialEnabled,
|
|
83
110
|
fn: (currentConfig, toolConfig) => {
|
|
84
111
|
const config = currentConfig as Record<string, unknown>
|
|
85
112
|
const option = config.option as EchartOptionsProps | undefined
|
|
113
|
+
const currentOnEvents =
|
|
114
|
+
(config.onEvents as Record<string, unknown> | undefined) ?? {}
|
|
115
|
+
|
|
86
116
|
const enabled = (toolConfig?.enabled as boolean) ?? false
|
|
87
117
|
const start = (toolConfig?.start as number) ?? 0
|
|
88
118
|
const end = (toolConfig?.end as number) ?? 100
|
|
89
119
|
|
|
120
|
+
const legend = option?.legend as { show?: boolean } | undefined
|
|
121
|
+
const hasLegend = legend?.show !== false && legend !== undefined
|
|
122
|
+
|
|
123
|
+
const sliderHeight = parseInt(theme?.spacing?.(4) ?? '32')
|
|
124
|
+
const sliderGap = 8
|
|
125
|
+
const legendBottomOffset = hasLegend ? 28 : 0
|
|
126
|
+
|
|
90
127
|
const zoomConfig = getEChartZoomConfig(
|
|
91
128
|
enabled,
|
|
92
129
|
{ start, end },
|
|
93
|
-
{
|
|
130
|
+
{
|
|
131
|
+
inside: true,
|
|
132
|
+
xSlider: true,
|
|
133
|
+
ySlider: false,
|
|
134
|
+
bottomOffset: legendBottomOffset,
|
|
135
|
+
},
|
|
94
136
|
theme,
|
|
95
137
|
)
|
|
96
|
-
|
|
138
|
+
|
|
139
|
+
const grid = option?.grid as { bottom?: number | string } | undefined
|
|
140
|
+
const currentGridBottom =
|
|
141
|
+
typeof grid?.bottom === 'number'
|
|
142
|
+
? grid.bottom
|
|
143
|
+
: parseInt(grid?.bottom ?? '24')
|
|
144
|
+
|
|
145
|
+
const gridBottom = enabled
|
|
146
|
+
? currentGridBottom + sliderHeight + sliderGap
|
|
147
|
+
: currentGridBottom
|
|
148
|
+
|
|
149
|
+
const onEventsWithoutDataZoom = { ...currentOnEvents }
|
|
150
|
+
delete onEventsWithoutDataZoom.dataZoom
|
|
151
|
+
const onEvents = enabled
|
|
152
|
+
? { ...currentOnEvents, dataZoom: handleDataZoom }
|
|
153
|
+
: onEventsWithoutDataZoom
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
...config,
|
|
157
|
+
option: {
|
|
158
|
+
...option,
|
|
159
|
+
...zoomConfig,
|
|
160
|
+
grid: { ...grid, bottom: gridBottom },
|
|
161
|
+
},
|
|
162
|
+
onEvents,
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
config: {
|
|
166
|
+
enabled: initialEnabled,
|
|
167
|
+
start: initialStart,
|
|
168
|
+
end: initialEnd,
|
|
97
169
|
},
|
|
98
|
-
config: { enabled: zoom, start: zoomStart, end: zoomEnd },
|
|
99
170
|
})
|
|
100
171
|
return () => unregisterTool(id, ZOOM_TOGGLE_TOOL_ID)
|
|
101
|
-
}, [
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// Initialize zoom state from defaults only if not already set
|
|
114
|
-
useEffect(() => {
|
|
115
|
-
const existingState = getWidget<ZoomState>(id)
|
|
116
|
-
|
|
117
|
-
if (existingState?.zoom) return
|
|
118
|
-
|
|
119
|
-
setWidget<ZoomState>(id, {
|
|
120
|
-
zoom: existingState?.zoom ?? defaultZoom,
|
|
121
|
-
zoomStart: existingState?.zoomStart ?? defaultZoomStart,
|
|
122
|
-
zoomEnd: existingState?.zoomEnd ?? defaultZoomEnd,
|
|
123
|
-
})
|
|
124
|
-
}, [defaultZoom, defaultZoomEnd, defaultZoomStart, getWidget, id, setWidget])
|
|
125
|
-
|
|
126
|
-
// Cleanup: disable zoom when component unmounts
|
|
127
|
-
useEffect(() => {
|
|
128
|
-
return () => {
|
|
129
|
-
setWidget<ZoomState>(id, { zoom: false })
|
|
130
|
-
}
|
|
131
|
-
}, [id, setWidget])
|
|
172
|
+
}, [
|
|
173
|
+
defaultZoom,
|
|
174
|
+
defaultZoomEnd,
|
|
175
|
+
defaultZoomStart,
|
|
176
|
+
getWidget,
|
|
177
|
+
handleDataZoom,
|
|
178
|
+
id,
|
|
179
|
+
registerTool,
|
|
180
|
+
theme,
|
|
181
|
+
unregisterTool,
|
|
182
|
+
])
|
|
132
183
|
|
|
133
184
|
const handleToggle = () => {
|
|
134
185
|
const newZoom = !zoom
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
zoomEnd: newZoom ? (existingState?.zoomEnd ?? defaultZoomEnd) : 100,
|
|
186
|
+
setToolEnabled(id, ZOOM_TOGGLE_TOOL_ID, newZoom)
|
|
187
|
+
updateToolConfig(id, ZOOM_TOGGLE_TOOL_ID, {
|
|
188
|
+
enabled: newZoom,
|
|
189
|
+
start: newZoom ? zoomStart : 0,
|
|
190
|
+
end: newZoom ? zoomEnd : 100,
|
|
141
191
|
})
|
|
142
192
|
}
|
|
143
193
|
|
|
144
194
|
const handleReset = () => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
195
|
+
setToolEnabled(id, ZOOM_TOGGLE_TOOL_ID, true)
|
|
196
|
+
updateToolConfig(id, ZOOM_TOGGLE_TOOL_ID, {
|
|
197
|
+
enabled: true,
|
|
198
|
+
start: defaultZoomStart,
|
|
199
|
+
end: defaultZoomEnd,
|
|
149
200
|
})
|
|
150
201
|
}
|
|
151
202
|
|
|
152
|
-
// Handle dataZoom event to update zoom range in store
|
|
153
|
-
const handleDataZoom = useCallback(
|
|
154
|
-
(event: unknown) => {
|
|
155
|
-
const zoomEvent = event as {
|
|
156
|
-
start: number
|
|
157
|
-
end: number
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const start = zoomEvent.start
|
|
161
|
-
const end = zoomEvent.end
|
|
162
|
-
|
|
163
|
-
if (start !== undefined && end !== undefined) {
|
|
164
|
-
setWidget<ZoomState>(id, {
|
|
165
|
-
zoom: true,
|
|
166
|
-
zoomStart: start,
|
|
167
|
-
zoomEnd: end,
|
|
168
|
-
})
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
[id, setWidget],
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
// Register dataZoom event handler when zoom is enabled
|
|
175
|
-
useEffect(() => {
|
|
176
|
-
if (zoom) {
|
|
177
|
-
setWidget<EchartWidgetState>(id, {
|
|
178
|
-
onEvents: {
|
|
179
|
-
dataZoom: handleDataZoom,
|
|
180
|
-
},
|
|
181
|
-
})
|
|
182
|
-
}
|
|
183
|
-
}, [id, zoom, handleDataZoom, setWidget])
|
|
184
|
-
|
|
185
203
|
const enableLabel = labels?.enable ?? 'Enable zoom'
|
|
186
204
|
const disableLabel = labels?.disable ?? 'Disable zoom'
|
|
187
205
|
const resetLabel = labels?.reset ?? 'Reset zoom'
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
buildGridConfig,
|
|
11
11
|
createTooltipPositioner,
|
|
12
12
|
createTooltipFormatter,
|
|
13
|
-
|
|
13
|
+
niceNum,
|
|
14
14
|
} from '../_shared/chart-config'
|
|
15
15
|
import { downloadToCSV, downloadToPNG, type DownloadItem } from '../actions'
|
|
16
16
|
import type { ConfigProps } from '../loader/types'
|
|
@@ -47,32 +47,7 @@ function getOption({
|
|
|
47
47
|
}: BarConfig): EchartOptionsProps {
|
|
48
48
|
const hasLegend = (data?.length ?? 0) > 1
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
type: 'value' as const,
|
|
52
|
-
splitNumber: 1,
|
|
53
|
-
axisLabel: {
|
|
54
|
-
fontSize: theme.typography.overlineDelicate.fontSize,
|
|
55
|
-
fontFamily: theme.typography.overlineDelicate.fontFamily,
|
|
56
|
-
margin: parseInt(theme.spacing(1)),
|
|
57
|
-
show: true,
|
|
58
|
-
showMaxLabel: true,
|
|
59
|
-
showMinLabel: false,
|
|
60
|
-
verticalAlign: 'bottom' as const,
|
|
61
|
-
inside: true,
|
|
62
|
-
},
|
|
63
|
-
axisLine: {
|
|
64
|
-
show: false,
|
|
65
|
-
},
|
|
66
|
-
axisTick: {
|
|
67
|
-
show: false,
|
|
68
|
-
},
|
|
69
|
-
splitLine: {
|
|
70
|
-
show: true,
|
|
71
|
-
lineStyle: {
|
|
72
|
-
color: theme.palette.black[4],
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
}
|
|
50
|
+
let niceMax = 1
|
|
76
51
|
|
|
77
52
|
return {
|
|
78
53
|
legend: buildLegendConfig(hasLegend),
|
|
@@ -90,7 +65,41 @@ function getOption({
|
|
|
90
65
|
margin: 0,
|
|
91
66
|
},
|
|
92
67
|
},
|
|
93
|
-
yAxis:
|
|
68
|
+
yAxis: {
|
|
69
|
+
type: 'value' as const,
|
|
70
|
+
min: 0,
|
|
71
|
+
max: (extent: { min: number; max: number }) => {
|
|
72
|
+
niceMax = extent.max <= 0 ? 1 : niceNum(extent.max)
|
|
73
|
+
return niceMax
|
|
74
|
+
},
|
|
75
|
+
splitNumber: 1,
|
|
76
|
+
axisLabel: {
|
|
77
|
+
fontSize: theme.typography.overlineDelicate.fontSize,
|
|
78
|
+
fontFamily: theme.typography.overlineDelicate.fontFamily,
|
|
79
|
+
margin: parseInt(theme.spacing(1)),
|
|
80
|
+
show: true,
|
|
81
|
+
showMaxLabel: true,
|
|
82
|
+
showMinLabel: false,
|
|
83
|
+
verticalAlign: 'bottom' as const,
|
|
84
|
+
inside: true,
|
|
85
|
+
formatter: (value: number) => {
|
|
86
|
+
if (value !== niceMax) return ''
|
|
87
|
+
return formatter ? formatter(value) : String(value)
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
axisLine: {
|
|
91
|
+
show: false,
|
|
92
|
+
},
|
|
93
|
+
axisTick: {
|
|
94
|
+
show: false,
|
|
95
|
+
},
|
|
96
|
+
splitLine: {
|
|
97
|
+
show: true,
|
|
98
|
+
lineStyle: {
|
|
99
|
+
color: theme.palette.black[4],
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
94
103
|
tooltip: {
|
|
95
104
|
position: createTooltipPositioner(theme),
|
|
96
105
|
formatter: createTooltipFormatter((item) => {
|
|
@@ -15,30 +15,33 @@ const defaultFormatter = (value: number) => value.toString()
|
|
|
15
15
|
|
|
16
16
|
export function CategoryUI({ id }: CategoryUIProps) {
|
|
17
17
|
const theme = useTheme()
|
|
18
|
-
const
|
|
19
|
-
useShallow((state) =>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
const _formatter = useWidgetStore(
|
|
19
|
+
useShallow((state) => state.getWidget<CategoryWidgetState>(id)?.formatter),
|
|
20
|
+
)
|
|
21
|
+
const _series = useWidgetStore(
|
|
22
|
+
useShallow((state) => state.getWidget<CategoryWidgetState>(id)?.series),
|
|
23
|
+
)
|
|
24
|
+
const data = useWidgetStore(
|
|
25
|
+
useShallow((state) => state.getWidget<CategoryWidgetState>(id)?.data),
|
|
26
|
+
)
|
|
27
|
+
const maxItems = useWidgetStore(
|
|
28
|
+
useShallow((state) => state.getWidget<CategoryWidgetState>(id)?.maxItems),
|
|
29
|
+
)
|
|
30
|
+
const labels = useWidgetStore(
|
|
31
|
+
useShallow((state) => state.getWidget<CategoryWidgetState>(id)?.labels),
|
|
32
|
+
)
|
|
33
|
+
const onRowClick = useWidgetStore(
|
|
34
|
+
useShallow((state) => state.getWidget<CategoryWidgetState>(id)?.onRowClick),
|
|
35
|
+
)
|
|
36
|
+
const selected = useWidgetStore(
|
|
37
|
+
useShallow((state) => state.getWidget<CategoryWidgetState>(id)?.selected),
|
|
38
|
+
)
|
|
39
|
+
const max = useWidgetStore(
|
|
40
|
+
useShallow((state) => state.getWidget<CategoryWidgetState>(id)?.max),
|
|
32
41
|
)
|
|
33
42
|
|
|
34
|
-
const formatter =
|
|
35
|
-
const series =
|
|
36
|
-
const data = widget?.data
|
|
37
|
-
const maxItems = widget?.maxItems
|
|
38
|
-
const labels = widget?.labels
|
|
39
|
-
const onRowClick = widget?.onRowClick
|
|
40
|
-
const selected = widget?.selected
|
|
41
|
-
const max = widget?.max
|
|
43
|
+
const formatter = _formatter ?? defaultFormatter
|
|
44
|
+
const series = _series ?? []
|
|
42
45
|
|
|
43
46
|
const [maxHeight] = useState<string | number | undefined>(
|
|
44
47
|
maxItems ? 40 * (series.length || 1) * maxItems : undefined,
|
|
@@ -175,7 +175,7 @@ describe('EchartUI', () => {
|
|
|
175
175
|
|
|
176
176
|
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
177
177
|
lazyUpdate: true,
|
|
178
|
-
|
|
178
|
+
notMerge: true,
|
|
179
179
|
})
|
|
180
180
|
})
|
|
181
181
|
|
|
@@ -200,22 +200,7 @@ describe('EchartUI', () => {
|
|
|
200
200
|
|
|
201
201
|
expect(mockChart.setOption).toHaveBeenCalledWith(newOption, {
|
|
202
202
|
lazyUpdate: true,
|
|
203
|
-
|
|
204
|
-
})
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
test('uses provided replaceMerge values', () => {
|
|
208
|
-
render(
|
|
209
|
-
<EchartUI
|
|
210
|
-
{...defaultProps}
|
|
211
|
-
option={basicOption}
|
|
212
|
-
replaceMerge={['series']}
|
|
213
|
-
/>,
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
217
|
-
lazyUpdate: true,
|
|
218
|
-
replaceMerge: ['series'],
|
|
203
|
+
notMerge: true,
|
|
219
204
|
})
|
|
220
205
|
})
|
|
221
206
|
|
|
@@ -496,7 +481,7 @@ describe('EchartUI', () => {
|
|
|
496
481
|
|
|
497
482
|
expect(mockChart.setOption).toHaveBeenCalledWith(complexOption, {
|
|
498
483
|
lazyUpdate: true,
|
|
499
|
-
|
|
484
|
+
notMerge: true,
|
|
500
485
|
})
|
|
501
486
|
})
|
|
502
487
|
|
|
@@ -3,13 +3,8 @@ import * as echarts from 'echarts'
|
|
|
3
3
|
import type { EchartUIProps } from './types'
|
|
4
4
|
import { useWidgetRef } from '../../hooks'
|
|
5
5
|
|
|
6
|
-
const DEFAULT_REPLACE_MERGE: string[] = ['dataset', 'series']
|
|
7
|
-
|
|
8
6
|
export function EchartUI(props: EchartUIProps) {
|
|
9
7
|
const { id, ref, init, option, className, style, onEvents } = props
|
|
10
|
-
const replaceMerge = toReplaceMerge(
|
|
11
|
-
(props as { replaceMerge?: unknown }).replaceMerge,
|
|
12
|
-
)
|
|
13
8
|
|
|
14
9
|
const chartRef = useWidgetRef<HTMLDivElement>(id)
|
|
15
10
|
const chartInstance = useRef<echarts.ECharts>(null)
|
|
@@ -34,16 +29,11 @@ export function EchartUI(props: EchartUIProps) {
|
|
|
34
29
|
|
|
35
30
|
// Update chart when options change
|
|
36
31
|
useEffect(() => {
|
|
37
|
-
|
|
32
|
+
chartInstance.current?.setOption(option, {
|
|
38
33
|
lazyUpdate: true,
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
chartInstance.current?.setOption(
|
|
43
|
-
option,
|
|
44
|
-
setOptionConfig as Parameters<echarts.ECharts['setOption']>[1],
|
|
45
|
-
)
|
|
46
|
-
}, [option, replaceMerge])
|
|
34
|
+
notMerge: true,
|
|
35
|
+
})
|
|
36
|
+
}, [option])
|
|
47
37
|
|
|
48
38
|
// Handle resize using ResizeObserver
|
|
49
39
|
useEffect(() => {
|
|
@@ -82,11 +72,3 @@ export function EchartUI(props: EchartUIProps) {
|
|
|
82
72
|
|
|
83
73
|
return <div id={id} ref={chartRef} style={style} className={className} />
|
|
84
74
|
}
|
|
85
|
-
|
|
86
|
-
function toReplaceMerge(value: unknown): string[] | undefined {
|
|
87
|
-
if (!Array.isArray(value)) {
|
|
88
|
-
return undefined
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return value.filter((item): item is string => typeof item === 'string')
|
|
92
|
-
}
|
|
@@ -184,7 +184,7 @@ describe('Echart', () => {
|
|
|
184
184
|
}),
|
|
185
185
|
{
|
|
186
186
|
lazyUpdate: true,
|
|
187
|
-
|
|
187
|
+
notMerge: true,
|
|
188
188
|
},
|
|
189
189
|
)
|
|
190
190
|
})
|
|
@@ -277,7 +277,7 @@ describe('Echart', () => {
|
|
|
277
277
|
|
|
278
278
|
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
279
279
|
lazyUpdate: true,
|
|
280
|
-
|
|
280
|
+
notMerge: true,
|
|
281
281
|
})
|
|
282
282
|
|
|
283
283
|
const newOption: EChartsOption = {
|
|
@@ -299,7 +299,7 @@ describe('Echart', () => {
|
|
|
299
299
|
|
|
300
300
|
expect(mockChart.setOption).toHaveBeenCalledWith(newOption, {
|
|
301
301
|
lazyUpdate: true,
|
|
302
|
-
|
|
302
|
+
notMerge: true,
|
|
303
303
|
})
|
|
304
304
|
})
|
|
305
305
|
|
|
@@ -367,7 +367,7 @@ describe('Echart', () => {
|
|
|
367
367
|
|
|
368
368
|
expect(mockChart.setOption).toHaveBeenCalledWith(complexOption, {
|
|
369
369
|
lazyUpdate: true,
|
|
370
|
-
|
|
370
|
+
notMerge: true,
|
|
371
371
|
})
|
|
372
372
|
})
|
|
373
373
|
|
|
@@ -404,7 +404,7 @@ describe('Echart', () => {
|
|
|
404
404
|
)
|
|
405
405
|
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
406
406
|
lazyUpdate: true,
|
|
407
|
-
|
|
407
|
+
notMerge: true,
|
|
408
408
|
})
|
|
409
409
|
expect(mockChart.on).toHaveBeenCalledWith('click', clickHandler)
|
|
410
410
|
})
|
|
@@ -447,7 +447,7 @@ describe('Echart', () => {
|
|
|
447
447
|
|
|
448
448
|
expect(mockChart.setOption).toHaveBeenCalledWith(emptyOption, {
|
|
449
449
|
lazyUpdate: true,
|
|
450
|
-
|
|
450
|
+
notMerge: true,
|
|
451
451
|
})
|
|
452
452
|
})
|
|
453
453
|
|
|
@@ -470,7 +470,7 @@ describe('Echart', () => {
|
|
|
470
470
|
}),
|
|
471
471
|
{
|
|
472
472
|
lazyUpdate: true,
|
|
473
|
-
|
|
473
|
+
notMerge: true,
|
|
474
474
|
},
|
|
475
475
|
)
|
|
476
476
|
})
|
|
@@ -516,7 +516,7 @@ describe('Echart', () => {
|
|
|
516
516
|
|
|
517
517
|
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
518
518
|
lazyUpdate: true,
|
|
519
|
-
|
|
519
|
+
notMerge: true,
|
|
520
520
|
})
|
|
521
521
|
|
|
522
522
|
rerender(<Echart id='chart-b' />)
|
|
@@ -525,27 +525,11 @@ describe('Echart', () => {
|
|
|
525
525
|
{ series: [{ type: 'line', data: [1, 2, 3] }] },
|
|
526
526
|
{
|
|
527
527
|
lazyUpdate: true,
|
|
528
|
-
|
|
528
|
+
notMerge: true,
|
|
529
529
|
},
|
|
530
530
|
)
|
|
531
531
|
})
|
|
532
532
|
|
|
533
|
-
test('passes replaceMerge from widget to EchartUI', () => {
|
|
534
|
-
useWidgetStore.getState().setWidget('test-echart', {
|
|
535
|
-
id: 'test-echart',
|
|
536
|
-
type: 'echart',
|
|
537
|
-
option: basicOption,
|
|
538
|
-
replaceMerge: ['series'],
|
|
539
|
-
} as EchartWidgetState)
|
|
540
|
-
|
|
541
|
-
render(<Echart id='test-echart' />)
|
|
542
|
-
|
|
543
|
-
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
544
|
-
lazyUpdate: true,
|
|
545
|
-
replaceMerge: ['series'],
|
|
546
|
-
})
|
|
547
|
-
})
|
|
548
|
-
|
|
549
533
|
test('disposes chart when component unmounts', () => {
|
|
550
534
|
useWidgetStore.getState().setWidget('test-echart', {
|
|
551
535
|
id: 'test-echart',
|
|
@@ -10,43 +10,50 @@ import { useShallow } from 'zustand/shallow'
|
|
|
10
10
|
import { useMemo } from 'react'
|
|
11
11
|
|
|
12
12
|
export function Echart(props: EchartProps) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
const id = useWidgetStore(
|
|
14
|
+
(state) => state.getWidget<EchartWidgetState>(props.id)?.id,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
const data = useWidgetStore(
|
|
18
|
+
useShallow(
|
|
19
|
+
(state) =>
|
|
20
|
+
state.getWidget<EchartWidgetState>(props.id)?.data as
|
|
21
|
+
| EchartWidgetData
|
|
22
|
+
| undefined,
|
|
23
|
+
),
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
const widgetOption = useWidgetStore(
|
|
27
|
+
useShallow((state) => state.getWidget<EchartWidgetState>(props.id)?.option),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
const onEvents = useWidgetStore(
|
|
31
|
+
useShallow(
|
|
32
|
+
(state) => state.getWidget<EchartWidgetState>(props.id)?.onEvents,
|
|
33
|
+
),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
const init = useWidgetStore(
|
|
37
|
+
(state) => state.getWidget<EchartWidgetState>(props.id)?.init,
|
|
25
38
|
)
|
|
26
39
|
|
|
27
40
|
// Memoize dataset transformation to avoid re-computing on every render
|
|
28
|
-
const dataset = useMemo(() => buildDataset(
|
|
41
|
+
const dataset = useMemo(() => buildDataset(data), [data])
|
|
29
42
|
|
|
30
|
-
|
|
43
|
+
const option = useMemo<EchartOptionsProps>(
|
|
44
|
+
() => ({
|
|
45
|
+
...widgetOption,
|
|
46
|
+
...(dataset && { dataset }),
|
|
47
|
+
}),
|
|
48
|
+
[widgetOption, dataset],
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if (!id) {
|
|
31
52
|
return null
|
|
32
53
|
}
|
|
33
|
-
const option: EchartOptionsProps = {
|
|
34
|
-
...widget.option,
|
|
35
|
-
...(dataset && { dataset }),
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const onEvents = widget.onEvents
|
|
39
|
-
const init = widget.init
|
|
40
|
-
const replaceMerge = widget.replaceMerge
|
|
41
54
|
|
|
42
55
|
return (
|
|
43
|
-
<EchartUI
|
|
44
|
-
id={props.id}
|
|
45
|
-
option={option}
|
|
46
|
-
onEvents={onEvents}
|
|
47
|
-
init={init}
|
|
48
|
-
replaceMerge={replaceMerge}
|
|
49
|
-
/>
|
|
56
|
+
<EchartUI id={props.id} option={option} onEvents={onEvents} init={init} />
|
|
50
57
|
)
|
|
51
58
|
}
|
|
52
59
|
|