lowcoder-map-component 0.1.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.
Files changed (123) hide show
  1. package/README.md +37 -0
  2. package/icons/demo-icon.svg +10 -0
  3. package/icons/hills.svg +17 -0
  4. package/index.css +27 -0
  5. package/index.html +35 -0
  6. package/index.tsx +20 -0
  7. package/loader.mjs +11 -0
  8. package/package.json +175 -0
  9. package/src/README.md +35 -0
  10. package/src/components/ChartPropertyView.tsx +961 -0
  11. package/src/components/SeriesComp.tsx +368 -0
  12. package/src/components/TabPropertyView.tsx +127 -0
  13. package/src/comps/Barcharts/comp.tsx +338 -0
  14. package/src/comps/Barcharts/constants.tsx +77 -0
  15. package/src/comps/Linecharts/comp.tsx +350 -0
  16. package/src/comps/Linecharts/constants.tsx +53 -0
  17. package/src/comps/Linechartsv2/comp.tsx +350 -0
  18. package/src/comps/Linechartsv2/constants.tsx +68 -0
  19. package/src/comps/Mapcharts/comp.tsx +381 -0
  20. package/src/comps/Mapcharts/constants.tsx +312 -0
  21. package/src/comps/Mapchartsv2/comp.tsx +393 -0
  22. package/src/comps/Mapchartsv2/constants.tsx +340 -0
  23. package/src/comps/MixedLineBarCharts/comp.tsx +353 -0
  24. package/src/comps/MixedLineBarCharts/constants.tsx +60 -0
  25. package/src/comps/MultiLineCharts/comp.tsx +362 -0
  26. package/src/comps/MultiLineCharts/constants.tsx +96 -0
  27. package/src/comps/PercentageCharts/comp.tsx +359 -0
  28. package/src/comps/PercentageCharts/constants.tsx +98 -0
  29. package/src/comps/Piecharts/comp.tsx +334 -0
  30. package/src/comps/Piecharts/constants.tsx +48 -0
  31. package/src/comps/Tablecharts/comp.tsx +429 -0
  32. package/src/comps/Tablecharts/constants.tsx +97 -0
  33. package/src/comps/Totalcharts/comp.tsx +463 -0
  34. package/src/comps/Totalcharts/constants.tsx +66 -0
  35. package/src/comps/TwoLineCharts/comp.tsx +350 -0
  36. package/src/comps/TwoLineCharts/constants.tsx +82 -0
  37. package/src/comps/mapComponent/comp.tsx +338 -0
  38. package/src/comps/mapComponent/constants.tsx +2149 -0
  39. package/src/comps/tab/comp.tsx +283 -0
  40. package/src/comps/tab/constants.tsx +79 -0
  41. package/src/configs/barChartConfig.tsx +153 -0
  42. package/src/configs/baseConfig.tsx +66 -0
  43. package/src/configs/candleStickChartConfig.tsx +35 -0
  44. package/src/configs/cartesianAxisConfig.tsx +314 -0
  45. package/src/configs/chartUrls.tsx +9 -0
  46. package/src/configs/echartConfig.tsx +260 -0
  47. package/src/configs/echartsLabelConfig.tsx +47 -0
  48. package/src/configs/echartsLegendConfig.tsx +29 -0
  49. package/src/configs/echartsTitleConfig.tsx +49 -0
  50. package/src/configs/echartsTitleVerticalConfig.tsx +50 -0
  51. package/src/configs/funnelChartConfig.tsx +35 -0
  52. package/src/configs/gaugeChartConfig.tsx +31 -0
  53. package/src/configs/graphChartConfig.tsx +31 -0
  54. package/src/configs/heatmapChartConfig.tsx +31 -0
  55. package/src/configs/legendConfig.tsx +55 -0
  56. package/src/configs/lineChartConfig.tsx +246 -0
  57. package/src/configs/lineChartConfigv2.tsx +246 -0
  58. package/src/configs/mapChartConfig.tsx +106 -0
  59. package/src/configs/mapChartConfigv2.tsx +106 -0
  60. package/src/configs/mixedChartConfig.tsx +21 -0
  61. package/src/configs/pieChartConfig.tsx +156 -0
  62. package/src/configs/radarChartConfig.tsx +31 -0
  63. package/src/configs/sankeyChartConfig.tsx +35 -0
  64. package/src/configs/scatterChartConfig.tsx +152 -0
  65. package/src/configs/sunburstChartConfig.tsx +31 -0
  66. package/src/configs/tabConfig.tsx +0 -0
  67. package/src/configs/tableChartConfig.tsx +81 -0
  68. package/src/configs/themeriverChartConfig.tsx +31 -0
  69. package/src/configs/totalChartConfig.tsx +670 -0
  70. package/src/configs/treeChartConfig.tsx +31 -0
  71. package/src/configs/treemapChartConfig.tsx +31 -0
  72. package/src/controls/AnimationsControls.tsx +3 -0
  73. package/src/controls/AutoHeightControl.tsx +2 -0
  74. package/src/controls/AxisControls.tsx +146 -0
  75. package/src/controls/AxisVisibilityControl.tsx +14 -0
  76. package/src/controls/ChartTypeControl.tsx +15 -0
  77. package/src/controls/ColorScaleControl.tsx +221 -0
  78. package/src/controls/ColumnControl.tsx +204 -0
  79. package/src/controls/ConfigControl.tsx +37 -0
  80. package/src/controls/DirectionControls.tsx +20 -0
  81. package/src/controls/IconControl.tsx +88 -0
  82. package/src/controls/LegendControl.tsx +8 -0
  83. package/src/controls/RowLimitControl.tsx +91 -0
  84. package/src/controls/StyleControls.tsx +22 -0
  85. package/src/controls/TimeControls.tsx +41 -0
  86. package/src/controls/TrendlineControl.tsx +89 -0
  87. package/src/controls/UIEventControl.tsx +21 -0
  88. package/src/controls/index.ts +16 -0
  89. package/src/controls/radioControl.tsx +88 -0
  90. package/src/exposing/index.ts +3 -0
  91. package/src/exposing/setPoint.ts +19 -0
  92. package/src/geo/vn.geo.json +369897 -0
  93. package/src/geo/world.geo.json +32127 -0
  94. package/src/i18n/comps/index.tsx +39 -0
  95. package/src/i18n/comps/locales/en.ts +558 -0
  96. package/src/i18n/comps/locales/enObj.tsx +7186 -0
  97. package/src/i18n/comps/locales/index.ts +7 -0
  98. package/src/i18n/comps/locales/pt.ts +37 -0
  99. package/src/i18n/comps/locales/ptObj.tsx +40 -0
  100. package/src/i18n/comps/locales/types.tsx +622 -0
  101. package/src/i18n/comps/locales/zh.ts +3 -0
  102. package/src/i18n/comps/locales/zhObj.tsx +4 -0
  103. package/src/index.ts +31 -0
  104. package/src/types/global.d.ts +9 -0
  105. package/src/types/lowcoder-sdk.d.ts +578 -0
  106. package/src/utils/chartStyle.util.ts +121 -0
  107. package/src/utils/columnExtractor.util.ts +41 -0
  108. package/src/utils/dataTransform.util.ts +37 -0
  109. package/src/utils/deepEqual.util.ts +29 -0
  110. package/src/utils/echarts.util.tsx +822 -0
  111. package/src/utils/getDataKey.util.ts +115 -0
  112. package/src/utils/getLinearRegression.util.ts +46 -0
  113. package/src/utils/googleMaps.util.ts +28 -0
  114. package/src/utils/isEmpty.util.ts +10 -0
  115. package/src/utils/move.util.ts +6 -0
  116. package/src/utils/selection.util.ts +73 -0
  117. package/src/utils/style.util.ts +315 -0
  118. package/src/utils/time.util.ts +221 -0
  119. package/src/utils/timeFormatter.util.ts +104 -0
  120. package/src/utils/timeProcessing.util.ts +38 -0
  121. package/src/utils/trendline.util.ts +342 -0
  122. package/tsconfig.json +25 -0
  123. package/vite.config.js +19 -0
@@ -0,0 +1,961 @@
1
+ import { trans } from "@/i18n/comps";
2
+ import { extractColumnsFromData } from "@/utils/columnExtractor.util";
3
+ import { EChartPropsType } from "@/utils/echarts.util";
4
+ import { getDataKeys } from "@/utils/getDataKey.util";
5
+ import { move } from "@/utils/move.util";
6
+ import { Flex } from "antd";
7
+ import {
8
+ changeChildAction,
9
+ childrenToProps,
10
+ CompAction,
11
+ Dropdown,
12
+ EditorContext,
13
+ hiddenPropertyView,
14
+ Option,
15
+ RedButton,
16
+ Section,
17
+ sectionNames,
18
+ } from "lowcoder-sdk";
19
+ import { useContext, useEffect, useMemo, useRef } from "react";
20
+ import { newSeries } from "./SeriesComp";
21
+
22
+ export function ChartPropertyView(
23
+ children: EChartPropsType,
24
+ dispatch: (action: CompAction) => void
25
+ ) {
26
+ const {
27
+ xAxisKey,
28
+ chartType,
29
+ data,
30
+ series,
31
+ dataKeys,
32
+ dataQueryKey,
33
+ regionValue,
34
+ regionName,
35
+ sortBy,
36
+ sortOrder,
37
+ value,
38
+ showAxis,
39
+ yAxisKey,
40
+ yAxis2Key,
41
+ timeColumn,
42
+ timeGranularity,
43
+ timeRange,
44
+ } = childrenToProps(children);
45
+
46
+ const editorState: any = useContext(EditorContext);
47
+ const queriesList = editorState?.getQueriesComp()?.getView();
48
+
49
+ // region Default mock data
50
+ const defaultMockData = [
51
+ {
52
+ children: {
53
+ name: { getView: () => "users" },
54
+ compType: { getView: () => "restApi" },
55
+ data: {
56
+ getView: () => [
57
+ {
58
+ id: "1",
59
+ name: "Nguyễn Văn A",
60
+ email: "nguyenvana@email.com",
61
+ age: 28,
62
+ department: "Sales",
63
+ salary: 15000000,
64
+ status: "active",
65
+ joinDate: "2023-01-15",
66
+ avatar: "https://via.placeholder.com/50",
67
+ },
68
+ {
69
+ id: "2",
70
+ name: "Trần Thị B",
71
+ email: "tranthib@email.com",
72
+ age: 32,
73
+ department: "Marketing",
74
+ salary: 18000000,
75
+ status: "active",
76
+ joinDate: "2022-08-20",
77
+ avatar: "https://via.placeholder.com/50",
78
+ },
79
+ {
80
+ id: "3",
81
+ name: "Lê Văn C",
82
+ email: "levanc@email.com",
83
+ age: 25,
84
+ department: "IT",
85
+ salary: 20000000,
86
+ status: "inactive",
87
+ joinDate: "2023-05-10",
88
+ avatar: "https://via.placeholder.com/50",
89
+ },
90
+ {
91
+ id: "4",
92
+ name: "Phạm Thị D",
93
+ email: "phamthid@email.com",
94
+ age: 29,
95
+ department: "HR",
96
+ salary: 12000000,
97
+ status: "active",
98
+ joinDate: "2021-11-30",
99
+ avatar: "https://via.placeholder.com/50",
100
+ },
101
+ {
102
+ id: "5",
103
+ name: "Hoàng Văn E",
104
+ email: "hoangvane@email.com",
105
+ age: 35,
106
+ department: "Finance",
107
+ salary: 25000000,
108
+ status: "active",
109
+ joinDate: "2020-03-15",
110
+ avatar: "https://via.placeholder.com/50",
111
+ },
112
+ ],
113
+ },
114
+ description: { getView: () => "List of users" },
115
+ },
116
+ },
117
+ {
118
+ children: {
119
+ name: { getView: () => "products" },
120
+ compType: { getView: () => "sql" },
121
+ data: {
122
+ getView: () => [
123
+ {
124
+ id: "P001",
125
+ name: "iPhone 14 Pro",
126
+ category: "Phone",
127
+ price: 25990000,
128
+ stock: 45,
129
+ status: "available",
130
+ rating: 4.8,
131
+ sales: 1200,
132
+ image: "https://via.placeholder.com/100",
133
+ description: "iPhone 14 Pro 128GB",
134
+ },
135
+ {
136
+ id: "P002",
137
+ name: "Samsung Galaxy S23",
138
+ category: "Phone",
139
+ price: 18990000,
140
+ stock: 32,
141
+ status: "available",
142
+ rating: 4.6,
143
+ sales: 850,
144
+ image: "https://via.placeholder.com/100",
145
+ description: "Samsung Galaxy S23 256GB",
146
+ },
147
+ {
148
+ id: "P003",
149
+ name: "MacBook Air M2",
150
+ category: "Laptop",
151
+ price: 32990000,
152
+ stock: 15,
153
+ status: "low_stock",
154
+ rating: 4.9,
155
+ sales: 420,
156
+ image: "https://via.placeholder.com/100",
157
+ description: "MacBook Air M2 13 inch",
158
+ },
159
+ {
160
+ id: "P004",
161
+ name: "AirPods Pro",
162
+ category: "Accessory",
163
+ price: 5990000,
164
+ stock: 0,
165
+ status: "out_of_stock",
166
+ rating: 4.7,
167
+ sales: 2100,
168
+ image: "https://via.placeholder.com/100",
169
+ description: "AirPods Pro 2",
170
+ },
171
+ {
172
+ id: "P005",
173
+ name: "iPad Air",
174
+ category: "Tablet",
175
+ price: 15990000,
176
+ stock: 28,
177
+ status: "available",
178
+ rating: 4.5,
179
+ sales: 680,
180
+ image: "https://via.placeholder.com/100",
181
+ description: "iPad Air 10.9 inch",
182
+ },
183
+ ],
184
+ },
185
+ description: { getView: () => "List of products" },
186
+ },
187
+ },
188
+ ];
189
+
190
+ const queryItems = queriesList?.length ? queriesList : defaultMockData;
191
+
192
+ // region Memoized query data
193
+ const newQuery = useMemo(
194
+ () =>
195
+ queryItems.map((q: any) => ({
196
+ name: q.children.name.getView(),
197
+ data: q.children.data.getView(),
198
+ })),
199
+ [queryItems]
200
+ );
201
+
202
+ // region Memoized query options
203
+ const queryOptions = useMemo(
204
+ () => [
205
+ { label: "none", value: "none" },
206
+ ...(newQuery?.map((q: any) => ({
207
+ label: q.name,
208
+ value: q.name,
209
+ })) || []),
210
+ ],
211
+ [newQuery]
212
+ );
213
+
214
+ // region Refs for tracking
215
+ const prevKeysRef = useRef("");
216
+ const isInitializedRef = useRef(false);
217
+
218
+ // region Initialize data keys and columns
219
+ useEffect(() => {
220
+ getDataKeys({
221
+ data,
222
+ fallBack: (keys) => {
223
+ const extractedKeys =
224
+ chartType === "map" && typeof keys === "object" && "all" in keys
225
+ ? keys.number || []
226
+ : Array.isArray(keys)
227
+ ? keys
228
+ : keys.all || [];
229
+
230
+ if (extractedKeys.length === 0) return;
231
+
232
+ const keysSignature = extractedKeys.join("|");
233
+
234
+ if (
235
+ !isInitializedRef.current ||
236
+ keysSignature !== prevKeysRef.current
237
+ ) {
238
+ dispatch(
239
+ changeChildAction(
240
+ "dataKeys",
241
+ extractedKeys.map((key) => ({ label: key, value: key }))
242
+ )
243
+ );
244
+ if (["total", "pie"].includes(chartType))
245
+ dispatch(
246
+ changeChildAction(
247
+ "xAxisKey",
248
+ (keys as any)?.string?.[0] || extractedKeys?.[0] || ""
249
+ )
250
+ );
251
+
252
+ // region Update table columns
253
+ if (chartType === "table") {
254
+ const cols = children.columns.getView();
255
+ for (let i = cols.length - 1; i >= 0; i--) {
256
+ children.columns.dispatch(children.columns.deleteAction(i));
257
+ }
258
+ extractColumnsFromData(data).forEach((col) => {
259
+ children.columns.dispatch(children.columns.pushAction(col));
260
+ });
261
+ }
262
+
263
+ prevKeysRef.current = keysSignature;
264
+ isInitializedRef.current = true;
265
+ }
266
+ },
267
+ dataType: ["number", "string"],
268
+ targetKey: chartType === "total" ? "chartData" : undefined,
269
+ });
270
+ }, [data, chartType, children.columns, dispatch]);
271
+
272
+ // region Set query data
273
+ useEffect(() => {
274
+ if (dataQueryKey !== "none" && newQuery?.length > 0) {
275
+ dispatch(
276
+ changeChildAction(
277
+ "data",
278
+ JSON.stringify(
279
+ newQuery.find((q: any) => q.name === dataQueryKey).data
280
+ )
281
+ )
282
+ );
283
+ } else if (dataQueryKey === "none" || !data.length) {
284
+ dispatch(
285
+ changeChildAction(
286
+ "data",
287
+ JSON.stringify(children.defaultData.getView())
288
+ )
289
+ );
290
+ }
291
+ }, [dataQueryKey, children.defaultData]);
292
+
293
+ useEffect(() => {
294
+ const provinceData = children.provinceData?.getView?.();
295
+ if (provinceData && provinceData.length > 0) {
296
+ dispatch(
297
+ changeChildAction("defaultProvinceData", JSON.stringify(provinceData))
298
+ );
299
+ }
300
+ }, [children.provinceData]);
301
+
302
+
303
+ useEffect(() => {
304
+ const defaultStyle = children.defaultStyle?.getView?.();
305
+ console.log('defaultStyle',defaultStyle);
306
+ if (defaultStyle) {
307
+ dispatch(
308
+ changeChildAction("defaultMapStyle", defaultStyle)
309
+ );
310
+ }
311
+ }, [children.defaultStyle]);
312
+
313
+ // region Initialize map region value
314
+ useEffect(() => {
315
+ if (chartType === "map" && !regionValue) {
316
+ dispatch(changeChildAction("regionValue", "value"));
317
+ }
318
+ }, [chartType, regionValue, dispatch]);
319
+
320
+ // region Render map configuration section
321
+ const renderMapSection = () => (
322
+ <Section name="Map Configuration">
323
+ {children.chartConfig.getPropertyView()}
324
+ {/* <Option
325
+ items={dataKeys}
326
+ title={trans("mapChart.regionValue")}
327
+ itemTitle={(col) => col.label}
328
+ popoverTitle={() => trans("tableChart.columnSettings")}
329
+ content={() => null}
330
+ onMove={(fromIndex, toIndex) => {
331
+ const newDataKeys: any = move(dataKeys, fromIndex, toIndex);
332
+ dispatch(changeChildAction("regionValue", newDataKeys[0].value));
333
+ children.dataKeys.dispatch(
334
+ children.dataKeys.changeValueAction(newDataKeys)
335
+ );
336
+ }}
337
+ dataIndex={(col) => col.value}
338
+ /> */}
339
+ <Dropdown
340
+ value={regionName}
341
+ options={dataKeys}
342
+ label={trans("mapChart.regionName")}
343
+ onChange={(val: any) => {
344
+ dispatch(changeChildAction("regionName", val));
345
+ }}
346
+ />
347
+ {children.rowLimitConfig.getPropertyView()}
348
+ <Dropdown
349
+ value={sortBy}
350
+ options={dataKeys}
351
+ label={trans("chart.sortBy")}
352
+ onChange={(val: any) => {
353
+ dispatch(changeChildAction("sortBy", val));
354
+ }}
355
+ />
356
+ <Dropdown
357
+ value={sortOrder}
358
+ options={[
359
+ { label: trans("chart.ascending"), value: "asc" },
360
+ { label: trans("chart.descending"), value: "desc" },
361
+ ]}
362
+ label={trans("chart.sortOrder")}
363
+ onChange={(val: any) => {
364
+ dispatch(changeChildAction("sortOrder", val));
365
+ }}
366
+ />
367
+ </Section>
368
+ );
369
+
370
+ const renderMapSectionV2 = () => (
371
+ <>
372
+ <Section name="Map Configuration">
373
+ {children.chartConfig.getPropertyView()}
374
+ <Option
375
+ items={dataKeys}
376
+ title={trans("mapChart.regionValue")}
377
+ itemTitle={(col) => col.label}
378
+ popoverTitle={() => trans("tableChart.columnSettings")}
379
+ content={() => null}
380
+ onMove={(fromIndex, toIndex) => {
381
+ const newDataKeys: any = move(dataKeys, fromIndex, toIndex);
382
+ dispatch(changeChildAction("regionValue", newDataKeys[0].value));
383
+ children.dataKeys.dispatch(
384
+ children.dataKeys.changeValueAction(newDataKeys)
385
+ );
386
+ }}
387
+ dataIndex={(col) => col.value}
388
+ />
389
+ <Dropdown
390
+ value={regionName}
391
+ options={dataKeys}
392
+ label={trans("mapChart.regionName")}
393
+ onChange={(val: any) => {
394
+ dispatch(changeChildAction("regionName", val));
395
+ }}
396
+ />
397
+ {children.rowLimitConfig.getPropertyView()}
398
+ <Dropdown
399
+ value={sortBy}
400
+ options={dataKeys}
401
+ label={trans("chart.sortBy")}
402
+ onChange={(val: any) => {
403
+ dispatch(changeChildAction("sortBy", val));
404
+ }}
405
+ />
406
+ <Dropdown
407
+ value={sortOrder}
408
+ options={[
409
+ { label: trans("chart.ascending"), value: "asc" },
410
+ { label: trans("chart.descending"), value: "desc" },
411
+ ]}
412
+ label={trans("chart.sortOrder")}
413
+ onChange={(val: any) => {
414
+ dispatch(changeChildAction("sortOrder", val));
415
+ }}
416
+ />
417
+ </Section>
418
+ {/* <Section name="Style">
419
+ {children.borderColor.propertyView({ label: "Border Color" })}
420
+ {children.borderWidth.propertyView({ label: "Border Width" })}
421
+ {children.areaColor.propertyView({ label: "Area Color" })}
422
+ {children.hoverColor.propertyView({ label: "Hover Color" })}
423
+
424
+ {children.zoomLevel.propertyView({ label: "Zoom Level" })}
425
+ {children.width.propertyView({ label: "Width" })}
426
+ {children.width.propertyView({ label: "Width" })}
427
+ {children.height.propertyView({ label: "Height" })}
428
+ </Section> */}
429
+ <Section name="Tooltip">
430
+ <Option
431
+ items={children.tooltipItems.getView()}
432
+ title="Tooltip Fields"
433
+ itemTitle={(item) => item.getView().label || item.getView().key}
434
+ popoverTitle={() => "Tooltip Field"}
435
+ content={(item, index) => (
436
+ <>
437
+ <Dropdown
438
+ value={item.getView().key}
439
+ options={dataKeys}
440
+ label="Column"
441
+ onChange={(val: any) => {
442
+ item.children.key.dispatchChangeValueAction(val);
443
+ if (!item.getView().label) {
444
+ item.children.label.dispatchChangeValueAction(val);
445
+ }
446
+ }}
447
+ />
448
+ {item.children.label.propertyView({ label: "Label" })}
449
+ <RedButton
450
+ onClick={() => {
451
+ children.tooltipItems.dispatch(
452
+ children.tooltipItems.deleteAction(index)
453
+ );
454
+ }}
455
+ >
456
+ Delete
457
+ </RedButton>
458
+ </>
459
+ )}
460
+ onAdd={() => {
461
+ children.tooltipItems.dispatch(
462
+ children.tooltipItems.pushAction({ key: "", label: "" })
463
+ );
464
+ }}
465
+ onMove={(from, to) => {
466
+ children.tooltipItems.dispatch(
467
+ children.tooltipItems.arrayMoveAction(from, to)
468
+ );
469
+ }}
470
+ hide={() => false}
471
+ onHide={() => null}
472
+ dataIndex={(item) => item.getView().key}
473
+ />
474
+ </Section>
475
+ </>
476
+ );
477
+
478
+ // region Render table columns section
479
+ const renderTableColumnsSection = () => (
480
+ <Option
481
+ items={children.columns.getView()}
482
+ title={trans("tableChart.columns")}
483
+ itemTitle={(col) => col.getView().title || col.getView().dataIndex}
484
+ popoverTitle={() => trans("tableChart.columnSettings")}
485
+ content={(col, index) => (
486
+ <Flex vertical gap={5}>
487
+ {col.getPropertyView()}
488
+ <RedButton
489
+ onClick={() => {
490
+ children.columns.dispatch(children.columns.deleteAction(index));
491
+ }}
492
+ >
493
+ {trans("chart.delete")}
494
+ </RedButton>
495
+ </Flex>
496
+ )}
497
+ onAdd={() => {
498
+ children.columns.dispatch(
499
+ children.columns.pushAction({
500
+ title: trans("tableChart.newColumn"),
501
+ dataIndex: `column_${Date.now()}`,
502
+ key: `column_${Date.now()}`,
503
+ visible: true,
504
+ sortable: true,
505
+ defaultSortOrder: "none",
506
+ fixed: "none",
507
+ })
508
+ );
509
+ }}
510
+ onMove={(fromIndex, toIndex) => {
511
+ children.columns.dispatch(
512
+ children.columns.arrayMoveAction(fromIndex, toIndex)
513
+ );
514
+ }}
515
+ hide={(col) => !col.getView().visible}
516
+ onHide={() => null}
517
+ dataIndex={(col) => col.getView().dataIndex}
518
+ />
519
+ );
520
+
521
+ // region Render series section
522
+ const renderSeriesSection = () => (
523
+ <div className="chart-series-option-wrapper">
524
+ <Option
525
+ items={series}
526
+ title={trans("chart.chartSeries")}
527
+ itemTitle={(s) => s.getView().seriesName}
528
+ popoverTitle={(s) => s.getView().columnName}
529
+ content={(s, index) => (
530
+ <>
531
+ {s.getPropertyViewWithData(dataKeys)}
532
+ <RedButton
533
+ onClick={() => {
534
+ children.series.dispatch(children.series.deleteAction(index));
535
+ }}
536
+ >
537
+ {trans("chart.delete")}
538
+ </RedButton>
539
+ </>
540
+ )}
541
+ onAdd={() => {
542
+ if (dataKeys.length > 0) {
543
+ children.series.dispatch(
544
+ children.series.pushAction(
545
+ newSeries(
546
+ trans("chart.customSeries"),
547
+ dataKeys[0].value,
548
+ chartType
549
+ )
550
+ )
551
+ );
552
+ }
553
+ }}
554
+ onMove={(fromIndex, toIndex) => {
555
+ console.log("run move");
556
+ children.series.dispatch(
557
+ children.series.arrayMoveAction(fromIndex, toIndex)
558
+ );
559
+ }}
560
+ hide={(s) => s.getView().hide}
561
+ onHide={(s, hide) => s.children.hide.dispatchChangeValueAction(hide)}
562
+ dataIndex={(s) => s.getView().dataIndex}
563
+ />
564
+ </div>
565
+ );
566
+
567
+ // region Render area pieces section for line charts
568
+ const renderAreaPiecesSection = () => (
569
+ <Option
570
+ items={children.areaPieces.getView()}
571
+ title={trans("chart.areaPieces")}
572
+ itemTitle={(s) =>
573
+ `[${s.getView().from}-${s.getView().to}] ${s.getView().color}`
574
+ }
575
+ popoverTitle={() => trans("chart.areaPiece")}
576
+ content={(s, index) => (
577
+ <>
578
+ {s.getPropertyView({ label: "Type" })}
579
+ <RedButton
580
+ onClick={() => {
581
+ children.areaPieces.dispatch(
582
+ children.areaPieces.deleteAction(index)
583
+ );
584
+ }}
585
+ >
586
+ {trans("chart.delete")}
587
+ </RedButton>
588
+ </>
589
+ )}
590
+ onAdd={() => {
591
+ children.areaPieces.dispatch(children.areaPieces.pushAction({}));
592
+ }}
593
+ onMove={(fromIndex, toIndex) => {
594
+ children.areaPieces.dispatch(
595
+ children.areaPieces.arrayMoveAction(fromIndex, toIndex)
596
+ );
597
+ }}
598
+ hide={() => true}
599
+ onHide={() => null}
600
+ dataIndex={(s) => s.getView().dataIndex}
601
+ />
602
+ );
603
+
604
+ const renderAreaPiecesSectionv2 = () => (
605
+ <>
606
+ {children.areaColor.getPropertyView({ label: "Area Color" })}
607
+ {children.showMaxPoint.propertyView({ label: "Show Max Point" })}
608
+ {children.zoomLevel.propertyView({ label: "Zoom Level" })}
609
+ <Option
610
+ items={children.areaPieces.getView()}
611
+ title={trans("chart.areaPieces")}
612
+ itemTitle={(s) =>
613
+ `[${s.getView().from}-${s.getView().to}] ${s.getView().color}`
614
+ }
615
+ popoverTitle={() => trans("chart.areaPiece")}
616
+ content={(s, index) => (
617
+ <>
618
+ {s.getPropertyView({ label: "Type" })}
619
+ <RedButton
620
+ onClick={() => {
621
+ children.areaPieces.dispatch(
622
+ children.areaPieces.deleteAction(index)
623
+ );
624
+ }}
625
+ >
626
+ {trans("chart.delete")}
627
+ </RedButton>
628
+ </>
629
+ )}
630
+ onAdd={() => {
631
+ children.areaPieces.dispatch(children.areaPieces.pushAction({}));
632
+ }}
633
+ onMove={(fromIndex, toIndex) => {
634
+ children.areaPieces.dispatch(
635
+ children.areaPieces.arrayMoveAction(fromIndex, toIndex)
636
+ );
637
+ }}
638
+ hide={() => true}
639
+ onHide={() => null}
640
+ dataIndex={(s) => s.getView().dataIndex}
641
+ />
642
+ </>
643
+ );
644
+
645
+ // region Render axis configuration for non-pie/map charts
646
+ const renderAxisConfig = () => (
647
+ <>
648
+ {children.xAxisDirection.propertyView({
649
+ label: trans("chart.xAxisDirection"),
650
+ radioButton: true,
651
+ })}
652
+ {children.xConfig.getPropertyView()}
653
+ {children.yConfig.getPropertyView()}
654
+ </>
655
+ );
656
+
657
+ // region Render axis style sections
658
+ const renderAxisStyleSections = () => (
659
+ <>
660
+ <Section name={sectionNames.xAxisStyle}>
661
+ {children.xAxisStyle?.getPropertyView()}
662
+ </Section>
663
+
664
+ {chartType === "mixed" ? (
665
+ <>
666
+ <Section name="Y-axis 1">
667
+ <Dropdown
668
+ value={yAxisKey}
669
+ options={dataKeys}
670
+ label={trans("chart.value")}
671
+ onChange={(val: any) => {
672
+ dispatch(changeChildAction("yAxisKey", val));
673
+ }}
674
+ />
675
+ {children.type?.propertyView({
676
+ label: trans("chart.type"),
677
+ })}
678
+ {children.yAxisStyle?.getPropertyView()}
679
+ </Section>
680
+ <Section name="Y-axis 2">
681
+ <Dropdown
682
+ value={yAxis2Key}
683
+ options={dataKeys}
684
+ label={trans("chart.value")}
685
+ onChange={(val: any) => {
686
+ dispatch(changeChildAction("yAxis2Key", val));
687
+ }}
688
+ />
689
+ {children.type2?.propertyView({
690
+ label: trans("chart.type"),
691
+ })}
692
+ {children.yAxis2Style?.getPropertyView()}
693
+ </Section>
694
+ </>
695
+ ) : (
696
+ <Section name={sectionNames.yAxisStyle}>
697
+ {children.yAxisStyle?.getPropertyView()}
698
+ </Section>
699
+ )}
700
+ </>
701
+ );
702
+
703
+ const isMapChart = chartType === "map";
704
+ const isMapChartV2 = chartType === "mapv2";
705
+ const isTableChart = chartType === "table";
706
+ const isPieChart = chartType === "pie";
707
+ const isBarChart = chartType === "bar";
708
+ const isLineChart = chartType === "line";
709
+ const isLineChartv2 = chartType === "linev2";
710
+ const isTotalChart = chartType === "total";
711
+ const isMapCompent = chartType === "mapComponent";
712
+
713
+ return (
714
+ <div>
715
+ {/* Map Configuration */}
716
+ {isMapChart && renderMapSection()}
717
+ {isMapCompent && renderMapSection()}
718
+
719
+ {isMapChartV2 && renderMapSectionV2()}
720
+
721
+ {/* Data Section */}
722
+ <Section name={trans("chart.data")}>
723
+ <Dropdown
724
+ value={dataQueryKey}
725
+ options={queryOptions}
726
+ label={trans("chart.dataQueries")}
727
+ onChange={(val: any) => {
728
+ dispatch(changeChildAction("dataQueryKey", val));
729
+ }}
730
+ />
731
+
732
+ {isTableChart && renderTableColumnsSection()}
733
+
734
+ {isMapChart && (
735
+ <>
736
+ <Dropdown
737
+ value={value}
738
+ options={dataKeys}
739
+ label={trans("mapChart.value")}
740
+ onChange={(val: any) => {
741
+ dispatch(changeChildAction("value", val));
742
+ }}
743
+ />
744
+ {children.regionMapType.propertyView({
745
+ label: trans("mapChart.regionMapType"),
746
+ })}
747
+ </>
748
+ )}
749
+
750
+ {!isMapChart && children.chartConfig.getPropertyView()}
751
+
752
+ {!isTableChart && !isMapChart && !isMapChartV2 && (
753
+ <>
754
+ {children.animationDuration.propertyView({
755
+ label: trans("chart.animationDuration"),
756
+ })}
757
+ <Dropdown
758
+ value={xAxisKey}
759
+ options={dataKeys}
760
+ label={trans("chart.xAxis")}
761
+ onChange={(val: any) => {
762
+ dispatch(changeChildAction("xAxisKey", val));
763
+ }}
764
+ />
765
+ {children.chartConfig.getView()?.subtype === "waterfall" &&
766
+ children.xAxisData.propertyView({
767
+ label: "X-Label-Data",
768
+ })}
769
+ {children.rowLimitConfig.getPropertyView()}
770
+ {!isTotalChart && renderSeriesSection()}
771
+ {isLineChart && renderAreaPiecesSection()}
772
+ {isLineChartv2 && renderAreaPiecesSectionv2()}
773
+ </>
774
+ )}
775
+ </Section>
776
+
777
+ {/* Layout Section */}
778
+ {chartType !== "table" &&
779
+ chartType !== "linev2" &&
780
+ chartType !== "mapv2" &&
781
+ !isMapCompent && (
782
+ <Section name={sectionNames.layout}>
783
+ {children.echartsTitleConfig.getPropertyView()}
784
+ {children.echartsTitleVerticalConfig.getPropertyView()}
785
+ {children.legendConfig.getPropertyView()}
786
+ {children.title.propertyView({ label: trans("chart.title") })}
787
+ {children.left.propertyView({
788
+ label: trans("chart.left"),
789
+ tooltip: trans("chart.leftTooltip"),
790
+ })}
791
+ {children.right.propertyView({
792
+ label: trans("chart.right"),
793
+ tooltip: trans("chart.rightTooltip"),
794
+ })}
795
+ {children.top.propertyView({
796
+ label: trans("chart.top"),
797
+ tooltip: trans("chart.topTooltip"),
798
+ })}
799
+ {children.bottom.propertyView({
800
+ label: trans("chart.bottom"),
801
+ tooltip: trans("chart.bottomTooltip"),
802
+ })}
803
+
804
+ {!isPieChart && !isMapChart && !isMapChartV2 && renderAxisConfig()}
805
+
806
+ {hiddenPropertyView(children)}
807
+
808
+ {!isPieChart && !isMapChart && !isMapChartV2 && (
809
+ <>
810
+ <Dropdown
811
+ value={showAxis}
812
+ options={[
813
+ { label: "Hide", value: "hide" },
814
+ { label: "Show", value: "show" },
815
+ { label: "Custom", value: "custom" },
816
+ ]}
817
+ label={trans("chart.showAxis")}
818
+ onChange={(val: any) => {
819
+ dispatch(changeChildAction("showAxis", val));
820
+ }}
821
+ />
822
+ {showAxis === "custom" && (
823
+ <>
824
+ {children.showXAxis.propertyView({
825
+ label: trans("chart.showXAxis"),
826
+ })}
827
+ {children.showYAxis.propertyView({
828
+ label: trans("chart.showYAxis"),
829
+ })}
830
+ </>
831
+ )}
832
+ </>
833
+ )}
834
+
835
+ {children.tooltip.propertyView({
836
+ label: trans("chart.tooltip"),
837
+ tooltip: trans("chart.tooltip"),
838
+ })}
839
+ </Section>
840
+ )}
841
+
842
+ {/* Axis Style Section */}
843
+ {!isPieChart &&
844
+ !isBarChart &&
845
+ !isMapChart &&
846
+ !isMapCompent &&
847
+ !isMapChartV2 &&
848
+ !isTableChart &&
849
+ !isLineChartv2 &&
850
+ renderAxisStyleSections()}
851
+
852
+ {/* Time Section */}
853
+ {!isLineChartv2 && !isMapChartV2 && (
854
+ <Section name={trans("chart.time")}>
855
+ <Dropdown
856
+ value={timeColumn}
857
+ options={dataKeys}
858
+ label={trans("chart.timeColumn")}
859
+ onChange={(val: any) => {
860
+ dispatch(changeChildAction("timeColumn", val));
861
+ }}
862
+ />
863
+ <Dropdown
864
+ value={timeGranularity}
865
+ options={[
866
+ { label: trans("chart.second"), value: "second" },
867
+ { label: trans("chart.minute"), value: "minute" },
868
+ { label: trans("chart.hour"), value: "hour" },
869
+ { label: trans("chart.day"), value: "day" },
870
+ { label: trans("chart.week"), value: "week" },
871
+ { label: trans("chart.month"), value: "month" },
872
+ { label: trans("chart.quarter"), value: "quarter" },
873
+ { label: trans("chart.year"), value: "year" },
874
+ ]}
875
+ label={trans("chart.timeGranularity")}
876
+ onChange={(val: any) => {
877
+ dispatch(changeChildAction("timeGranularity", val));
878
+ }}
879
+ />
880
+ <Dropdown
881
+ value={timeRange}
882
+ options={[
883
+ { label: "Last day", value: "lastDay" },
884
+ { label: "Last week", value: "lastWeek" },
885
+ { label: "Last month", value: "lastMonth" },
886
+ { label: "Last quarter", value: "lastQuarter" },
887
+ { label: "Last year", value: "lastYear" },
888
+ { label: "Current day", value: "currentDay" },
889
+ { label: "No filter", value: "noFilter" },
890
+ { label: "Custom", value: "custom" },
891
+ ]}
892
+ label={trans("chart.timeRange")}
893
+ onChange={(val: any) => {
894
+ dispatch(changeChildAction("timeRange", val));
895
+ }}
896
+ />
897
+
898
+ {timeRange === "custom" && (
899
+ <>
900
+ {children.startTime.propertyView({
901
+ label: trans("chart.startTime"),
902
+ placeholder: "DD-MM-YYYY HH:mm",
903
+ })}
904
+ {children.endTime.propertyView({
905
+ label: trans("chart.endTime"),
906
+ placeholder: "DD-MM-YYYY HH:mm",
907
+ })}
908
+ </>
909
+ )}
910
+ </Section>
911
+ )}
912
+
913
+ {/* Advanced Section */}
914
+ <Section name={sectionNames.advanced}>
915
+ {children.data.propertyView({
916
+ label: trans("chart.data"),
917
+ })}
918
+ {children.provinceData.propertyView({
919
+ label: trans("chart.provinceData"),
920
+ })}
921
+
922
+ {children.defaultStyle.propertyView({
923
+ label: trans("chart.defaultMapStyle"),
924
+ })}
925
+
926
+ <Flex gap={8} vertical>
927
+ <Flex gap={5} vertical>
928
+ <div className="sub-title">{sectionNames.interaction}</div>
929
+ {children.onUIEvent.propertyView({
930
+ title: trans("chart.chartEventHandlers"),
931
+ })}
932
+ {children.onEvent.propertyView()}
933
+ </Flex>
934
+
935
+ {!isTableChart &&
936
+ !isMapChartV2 &&
937
+ !isLineChartv2 &&
938
+ !isMapChartV2 &&
939
+ !isMapCompent && (
940
+ <>
941
+ <Flex gap={5} vertical>
942
+ <div className="sub-title">{sectionNames.chartStyle}</div>
943
+ {children.chartStyle?.getPropertyView()}
944
+ </Flex>
945
+ <Flex gap={5} vertical>
946
+ <div className="sub-title">{sectionNames.titleStyle}</div>
947
+ {children.titleStyle?.getPropertyView()}
948
+ </Flex>
949
+ {!isMapChart && !isMapChartV2 && !isMapCompent && (
950
+ <Flex gap={5} vertical>
951
+ <div className="sub-title">{sectionNames.legendStyle}</div>
952
+ {children.legendStyle?.getPropertyView()}
953
+ </Flex>
954
+ )}
955
+ </>
956
+ )}
957
+ </Flex>
958
+ </Section>
959
+ </div>
960
+ );
961
+ }