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,338 @@
1
+ import { ChartPropertyView } from '@/components/ChartPropertyView';
2
+ import { EchartsAxisType } from '@/configs/cartesianAxisConfig';
3
+ import { ItemColorComp } from '@/configs/lineChartConfig';
4
+ import { AxisFormatterComp } from '@/controls';
5
+ import { trans } from '@/i18n/comps';
6
+ import { formatAllStyles } from '@/utils/chartStyle.util';
7
+ import { deepEqual } from '@/utils/deepEqual.util';
8
+ import { ChartSize, echartProps, getEChartConfig } from '@/utils/echarts.util';
9
+ import { getDataKeys } from '@/utils/getDataKey.util';
10
+ import {
11
+ changeChildAction,
12
+ changeValueAction,
13
+ chartColorPalette,
14
+ childrenToProps,
15
+ CompAction,
16
+ CompActionTypes,
17
+ depsConfig,
18
+ genRandomKey,
19
+ getPromiseAfterDispatch,
20
+ JSONObject,
21
+ NameConfig,
22
+ Theme,
23
+ ThemeContext,
24
+ UICompBuilder,
25
+ valueComp,
26
+ withDefault,
27
+ withExposingConfigs,
28
+ withViewFn,
29
+ wrapChildAction,
30
+ } from 'lowcoder-sdk';
31
+ import { useContext, useEffect, useMemo, useRef, useState } from 'react';
32
+ import { useResizeDetector } from 'react-resize-detector';
33
+ import { chartUiProps } from './constants';
34
+
35
+ let clickEventCallback = () => {};
36
+
37
+ let MapComponentTmpComp = (function () {
38
+ return new UICompBuilder(
39
+ {
40
+ ...echartProps,
41
+ ...chartUiProps,
42
+ },
43
+ () => null
44
+ )
45
+ .setPropertyViewFn(ChartPropertyView)
46
+ .build();
47
+ })();
48
+
49
+ MapComponentTmpComp = withViewFn(MapComponentTmpComp, (comp) => {
50
+ const data = comp.children.data?.getView?.() || [];
51
+ const districts = comp.children.defaultProvinceData?.getView?.() || [];
52
+ const mapStyle = comp.children.defaultMapStyle?.getView?.() || [];
53
+ const theme: Theme = useContext(ThemeContext);
54
+ const mapRef = useRef<HTMLDivElement>(null);
55
+ const mapLoaded = useRef(false);
56
+ const [map, setMap] = useState<any>(null);
57
+ const selectedPolygonId = useRef(null);
58
+ const defaultChartTheme = {
59
+ color: chartColorPalette,
60
+ backgroundColor: '#fff',
61
+ };
62
+ const activeFeatureIdsRef = useRef<Set<number>>(new Set());
63
+
64
+ let filter_color = [
65
+ 'case',
66
+ ['boolean', ['feature-state', 'isHidden'], true],
67
+ 'white',
68
+ ['boolean', ['feature-state', 'selected'], false],
69
+ '#faf25f',
70
+ [
71
+ 'step',
72
+ ['feature-state', 'process_value'],
73
+ '#FBE9D5',
74
+ 1,
75
+ '#ED5050', // 24–33
76
+ 50,
77
+ '#F7942F', // = 34
78
+ 70,
79
+ '#EAC344',
80
+ 80,
81
+ '#5CC488',
82
+ 90,
83
+ '#219653',
84
+ ],
85
+ ];
86
+ const opacity_color = [
87
+ 'case',
88
+ ['boolean', ['feature-state', 'hover'], false],
89
+ 1,
90
+ 0.4,
91
+ ];
92
+
93
+ let themeConfig = defaultChartTheme;
94
+ try {
95
+ themeConfig = theme?.theme?.chart
96
+ ? JSON.parse(theme.theme.chart)
97
+ : defaultChartTheme;
98
+ } catch (error) {
99
+ console.error('theme chart error: ', error);
100
+ }
101
+
102
+ useEffect(() => {
103
+ if (!mapRef.current) return; // tránh undefined
104
+ const newmap = new window.vtmapgl.Map({
105
+ accessToken: 'acfda3fa21ccc80fc6946681c4d6729f',
106
+ container: mapRef.current,
107
+ style:
108
+ 'https://ioc-rs.danang.gov.vn/documents/v5-style-admin_custom_nq57.json',
109
+ center: [107.96214000803525, 15.606049590212066],
110
+ zoom: 8,
111
+ });
112
+ setMap(newmap);
113
+ }, []);
114
+
115
+ const resetFeatureStates = () => {
116
+ activeFeatureIdsRef.current.forEach((id) => {
117
+ map.setFeatureState(
118
+ {
119
+ source: 'VTMap_Admin',
120
+ sourceLayer: 'tbl_communes_2025',
121
+ id,
122
+ },
123
+ {
124
+ process_value: 0,
125
+ isHidden: true,
126
+ }
127
+ );
128
+ });
129
+
130
+ activeFeatureIdsRef.current.clear();
131
+ };
132
+ const initMap = (dataDistrict: any[], districtsNew: any[]) => {
133
+ if (!map) return;
134
+ resetFeatureStates();
135
+ map.setFilter('view_communes_text_2025', [
136
+ 'match',
137
+ ['slice', ['get', 'obj_id'], 0, 6],
138
+ ['HAC_48'],
139
+ true,
140
+ false,
141
+ ]);
142
+
143
+ map.setFilter('tbl_communes_boundary', [
144
+ 'match',
145
+ ['slice', ['get', 'obj_id'], 0, 6],
146
+ ['HAC_48'],
147
+ true,
148
+ false,
149
+ ]);
150
+
151
+ map.setLayerZoomRange('view_communes_text_2025', 7, 21);
152
+ map.setLayerZoomRange('tbl_communes_boundary', 7, 21);
153
+
154
+ if (!Array.isArray(dataDistrict) || !Array.isArray(districtsNew)) return;
155
+
156
+ // 3️⃣ Apply state mới
157
+ districtsNew.forEach((district) => {
158
+ const cleanName = district?.name
159
+ ?.toLowerCase()
160
+ ?.replace(/^xã\s+|^phường\s+|^thị trấn\s+/i, '')
161
+ ?.trim();
162
+
163
+ if (!cleanName || !district.id) return;
164
+
165
+ const matched = dataDistrict.find((i) => {
166
+ const name = String(i?.name || '')
167
+ .toLowerCase()
168
+ .trim()
169
+ .replace(/^(ubnd\s+)?(xã\s+|phường\s+|thị trấn\s+)/i, '');
170
+
171
+ return name === cleanName;
172
+ });
173
+
174
+ const normalizedScore = Number(matched?.score || 0);
175
+ console.log('matched', matched);
176
+
177
+ map.setFeatureState(
178
+ {
179
+ source: 'VTMap_Admin',
180
+ sourceLayer: 'tbl_communes_2025',
181
+ id: district.id,
182
+ },
183
+ {
184
+ process_value: normalizedScore,
185
+ dataFeature: matched || null,
186
+ isHidden: false,
187
+ }
188
+ );
189
+
190
+ // 🔥 lưu lại ID đã set
191
+ activeFeatureIdsRef.current.add(district.id);
192
+ });
193
+
194
+ // 4️⃣ Style chỉ set 1 lần
195
+ map.setPaintProperty('tbl_communes_2025', 'fill-color', filter_color);
196
+ map.setPaintProperty('tbl_communes_boundary', 'line-width', 1);
197
+ };
198
+
199
+ useEffect(() => {
200
+ if (!map) return;
201
+ if (mapLoaded.current) initMap(data, districts);
202
+ else
203
+ map?.on('load', () => {
204
+ mapLoaded.current = true;
205
+ initMap(data, districts);
206
+ });
207
+
208
+ const onLayerClick = (e) => {
209
+ const popup = new window.vtmapgl.Popup();
210
+ clearSelection();
211
+ const feature = e.features?.[0];
212
+ if (!feature) return;
213
+ if (feature.properties?.province_area_code !== '48') return;
214
+ const value = Number(feature?.state?.process_value || 0);
215
+ const dataFeature = feature?.state?.dataFeature || {};
216
+ const formatted = new Intl.NumberFormat('vi-VN').format(value);
217
+ selectedPolygonId.current = feature.id;
218
+ map.setFeatureState(
219
+ {
220
+ source: 'VTMap_Admin',
221
+ sourceLayer: 'tbl_communes_2025',
222
+ id: selectedPolygonId.current,
223
+ },
224
+ { selected: true }
225
+ );
226
+
227
+ popup
228
+ .setLngLat(e.lngLat)
229
+ .setHTML(
230
+ `<div style="font-size: 14px; font-style: normal; min-width:200px;">
231
+ <svg viewBox="64 64 896 896" focusable="false" data-icon="environment" width="1em" height="1em" fill="green" aria-hidden="true"><path d="M512 327c-29.9 0-58 11.6-79.2 32.8A111.6 111.6 0 00400 439c0 29.9 11.7 58 32.8 79.2A111.6 111.6 0 00512 551c29.9 0 58-11.7 79.2-32.8C612.4 497 624 468.9 624 439c0-29.9-11.6-58-32.8-79.2S541.9 327 512 327zm342.6-37.9a362.49 362.49 0 00-79.9-115.7 370.83 370.83 0 00-118.2-77.8C610.7 76.6 562.1 67 512 67c-50.1 0-98.7 9.6-144.5 28.5-44.3 18.3-84 44.5-118.2 77.8A363.6 363.6 0 00169.4 289c-19.5 45-29.4 92.8-29.4 142 0 70.6 16.9 140.9 50.1 208.7 26.7 54.5 64 107.6 111 158.1 80.3 86.2 164.5 138.9 188.4 153a43.9 43.9 0 0022.4 6.1c7.8 0 15.5-2 22.4-6.1 23.9-14.1 108.1-66.8 188.4-153 47-50.4 84.3-103.6 111-158.1C867.1 572 884 501.8 884 431.1c0-49.2-9.9-97-29.4-142zM512 615c-97.2 0-176-78.8-176-176s78.8-176 176-176 176 78.8 176 176-78.8 176-176 176z"></path></svg>
232
+ <b>${e.features[0].properties.name}</b><br/>
233
+ <div>${dataFeature?.title || ''}: <span style="font-weight:600">${dataFeature?.score || 0}</span>${dataFeature?.unit || '%'}</div>
234
+ ${
235
+ dataFeature?.subData && dataFeature.subData.length > 0
236
+ ? `
237
+ <ul style="margin: 0px;">
238
+ ${dataFeature.subData
239
+ .map(
240
+ (item: any) => `
241
+ <li>
242
+ ${item.title}:
243
+ <span style="font-weight:600">${item.score}</span>
244
+ ${dataFeature?.unit || ''}
245
+ </li>
246
+ `
247
+ )
248
+ .join('')}
249
+ </ul>
250
+ `
251
+ : ''
252
+ }
253
+ </div>`
254
+ )
255
+ .addTo(map);
256
+ };
257
+
258
+ map.on('click', 'tbl_communes_2025', onLayerClick);
259
+
260
+ return () => {
261
+ map.off('click', 'tbl_communes_2025', onLayerClick);
262
+ };
263
+ }, [map, data, districts]);
264
+ const clearSelection = () => {
265
+ if (selectedPolygonId.current !== null) {
266
+ map.setFeatureState(
267
+ {
268
+ source: 'VTMap_Admin',
269
+ sourceLayer: 'tbl_communes_2025',
270
+ id: selectedPolygonId.current,
271
+ },
272
+ { selected: false }
273
+ );
274
+ }
275
+ selectedPolygonId.current = null;
276
+ };
277
+
278
+ return (
279
+ <div>
280
+ <div style={{ width: '100%', height: '100vh' }} ref={mapRef}></div>
281
+ </div>
282
+ );
283
+ });
284
+
285
+ MapComponentTmpComp = class extends MapComponentTmpComp {
286
+ updateContext(comp: any) {
287
+ // the context value of axis format
288
+ let resultComp = comp;
289
+ const data = comp.children.data.getView();
290
+ const sampleSeries = comp.children.series
291
+ .getView()
292
+ .find((s: any) => !s.getView().hide);
293
+
294
+ // item color context
295
+ return resultComp;
296
+ }
297
+
298
+ reduce(action: CompAction): this {
299
+ const comp = super.reduce(action);
300
+ if (action.type === CompActionTypes.UPDATE_NODES_V2) {
301
+ // const newData = comp.children.data.getView();
302
+ // // data changes
303
+ // if (comp.children.data !== this.children.data) {
304
+ // setTimeout(() => {
305
+ // // update x-axis value
306
+ // const keys = getDataKeys({ data: newData, dataType: 'string' });
307
+ // if (
308
+ // keys.length > 0 &&
309
+ // !keys.includes(comp.children.xAxisKey.getView())
310
+ // ) {
311
+ // comp.children.xAxisKey.dispatch(changeValueAction(keys[0] || ''));
312
+ // }
313
+ // // pass to child series comp
314
+ // comp.children.series.dispatchDataChanged(newData);
315
+ // }, 0);
316
+ // }
317
+ // return this.updateContext(comp);
318
+ return comp;
319
+ }
320
+ return comp;
321
+ }
322
+
323
+ autoHeight(): boolean {
324
+ return false;
325
+ }
326
+ };
327
+
328
+ let MapComponentComp = withExposingConfigs(MapComponentTmpComp, []);
329
+
330
+ export const MapComponentCompWithDefault = withDefault(MapComponentComp, {
331
+ series: [
332
+ {
333
+ dataIndex: genRandomKey(),
334
+ name: 'Name',
335
+ chartType: 'mapComponent',
336
+ },
337
+ ],
338
+ });