Showing
33 changed files
with
498 additions
and
100 deletions
@@ -32,6 +32,6 @@ module.exports = { | @@ -32,6 +32,6 @@ module.exports = { | ||
32 | 'vue/no-unused-vars': 'off', | 32 | 'vue/no-unused-vars': 'off', |
33 | 'vue/multi-word-component-names': 'off', | 33 | 'vue/multi-word-component-names': 'off', |
34 | 'vue/valid-template-root': 'off', | 34 | 'vue/valid-template-root': 'off', |
35 | - 'vue/no-mutating-props': 'off', | 35 | + 'vue/no-mutating-props': 'off' |
36 | } | 36 | } |
37 | } | 37 | } |
readme/sponsors/dandian-banner.png
0 → 100644
14.9 KB
readme/sponsors/mdy-banner.png
0 → 100644
53.7 KB
@@ -11,7 +11,10 @@ export const option = { | @@ -11,7 +11,10 @@ export const option = { | ||
11 | dataset: dataJson, | 11 | dataset: dataJson, |
12 | mapRegion: { | 12 | mapRegion: { |
13 | adcode: 'china', | 13 | adcode: 'china', |
14 | - showHainanIsLands: true | 14 | + showHainanIsLands: true, |
15 | + enter: false, | ||
16 | + backSize: 20, | ||
17 | + backColor: '#ffffff' | ||
15 | }, | 18 | }, |
16 | tooltip: { | 19 | tooltip: { |
17 | show: true, | 20 | show: true, |
@@ -103,19 +106,19 @@ export const option = { | @@ -103,19 +106,19 @@ export const option = { | ||
103 | borderColor: 'rgba(147, 235, 248, 0.8)', | 106 | borderColor: 'rgba(147, 235, 248, 0.8)', |
104 | textStyle: { | 107 | textStyle: { |
105 | color: '#FFFFFF', | 108 | color: '#FFFFFF', |
106 | - fontSize: 12, | 109 | + fontSize: 12 |
107 | } | 110 | } |
108 | }, | 111 | }, |
109 | label: { | 112 | label: { |
110 | show: false, | 113 | show: false, |
111 | color: '#FFFFFF', | 114 | color: '#FFFFFF', |
112 | - fontSize: 12, | 115 | + fontSize: 12 |
113 | }, | 116 | }, |
114 | emphasis: { | 117 | emphasis: { |
115 | disabled: false, | 118 | disabled: false, |
116 | label: { | 119 | label: { |
117 | color: '#FFFFFF', | 120 | color: '#FFFFFF', |
118 | - fontSize: 12, | 121 | + fontSize: 12 |
119 | }, | 122 | }, |
120 | itemStyle: { | 123 | itemStyle: { |
121 | areaColor: '#389BB7', | 124 | areaColor: '#389BB7', |
@@ -148,6 +151,26 @@ export const option = { | @@ -148,6 +151,26 @@ export const option = { | ||
148 | shadowOffsetY: 2, | 151 | shadowOffsetY: 2, |
149 | shadowBlur: 10 | 152 | shadowBlur: 10 |
150 | } | 153 | } |
154 | + }, | ||
155 | + { | ||
156 | + type: 'lines', | ||
157 | + zlevel: 2, | ||
158 | + effect: { | ||
159 | + show: true, | ||
160 | + period: 4, //箭头指向速度,值越小速度越快 | ||
161 | + trailLength: 0.4, //特效尾迹长度[0,1]值越大,尾迹越长重 | ||
162 | + symbol: 'arrow', //箭头图标 | ||
163 | + symbolSize: 7 //图标大小 | ||
164 | + }, | ||
165 | + lineStyle: { | ||
166 | + normal: { | ||
167 | + color: '#4fb6d2', | ||
168 | + width: 1, //线条宽度 | ||
169 | + opacity: 0.1, //尾迹线条透明度 | ||
170 | + curveness: 0.3 //尾迹线条曲直度 | ||
171 | + } | ||
172 | + }, | ||
173 | + data: [] | ||
151 | } | 174 | } |
152 | ] | 175 | ] |
153 | } | 176 | } |
@@ -69,11 +69,7 @@ | @@ -69,11 +69,7 @@ | ||
69 | </n-space> | 69 | </n-space> |
70 | </SettingItem> | 70 | </SettingItem> |
71 | <SettingItem name="字体颜色"> | 71 | <SettingItem name="字体颜色"> |
72 | - <n-color-picker | ||
73 | - size="small" | ||
74 | - :modes="['hex']" | ||
75 | - v-model:value="seriesList[1].label.color" | ||
76 | - ></n-color-picker> | 72 | + <n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[1].label.color"></n-color-picker> |
77 | </SettingItem> | 73 | </SettingItem> |
78 | <SettingItem name="字体大小"> | 74 | <SettingItem name="字体大小"> |
79 | <n-input-number | 75 | <n-input-number |
@@ -129,7 +125,7 @@ | @@ -129,7 +125,7 @@ | ||
129 | ></n-color-picker> | 125 | ></n-color-picker> |
130 | </SettingItem> | 126 | </SettingItem> |
131 | </SettingItemBox> | 127 | </SettingItemBox> |
132 | - | 128 | + |
133 | <SettingItemBox name="悬浮弹窗"> | 129 | <SettingItemBox name="悬浮弹窗"> |
134 | <SettingItem name="显示"> | 130 | <SettingItem name="显示"> |
135 | <n-space> | 131 | <n-space> |
@@ -180,6 +176,22 @@ | @@ -180,6 +176,22 @@ | ||
180 | <SettingItem> | 176 | <SettingItem> |
181 | <n-checkbox v-model:checked="mapRegion.showHainanIsLands" size="small">显示南海群岛</n-checkbox> | 177 | <n-checkbox v-model:checked="mapRegion.showHainanIsLands" size="small">显示南海群岛</n-checkbox> |
182 | </SettingItem> | 178 | </SettingItem> |
179 | + <SettingItem v-if="seriesList[2]"> | ||
180 | + <n-checkbox v-model:checked="mapRegion.enter" size="small">点击进入下级</n-checkbox> | ||
181 | + </SettingItem> | ||
182 | + </SettingItemBox> | ||
183 | + <SettingItemBox name="返回图标" v-if="mapRegion.enter"> | ||
184 | + <SettingItem name="颜色"> | ||
185 | + <n-color-picker size="small" :modes="['hex']" v-model:value="mapRegion.backColor"></n-color-picker> | ||
186 | + </SettingItem> | ||
187 | + <SettingItem name="大小"> | ||
188 | + <n-input-number | ||
189 | + v-model:value="mapRegion.backSize" | ||
190 | + :min="1" | ||
191 | + size="small" | ||
192 | + placeholder="请输入字体大小" | ||
193 | + ></n-input-number> | ||
194 | + </SettingItem> | ||
183 | </SettingItemBox> | 195 | </SettingItemBox> |
184 | </CollapseItem> | 196 | </CollapseItem> |
185 | <CollapseItem name="标记" :expanded="true"> | 197 | <CollapseItem name="标记" :expanded="true"> |
@@ -191,7 +203,7 @@ | @@ -191,7 +203,7 @@ | ||
191 | <n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[0].itemStyle.color"></n-color-picker> | 203 | <n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[0].itemStyle.color"></n-color-picker> |
192 | </SettingItem> | 204 | </SettingItem> |
193 | </SettingItemBox> | 205 | </SettingItemBox> |
194 | - | 206 | + |
195 | <SettingItemBox name="文本"> | 207 | <SettingItemBox name="文本"> |
196 | <SettingItem name="显示"> | 208 | <SettingItem name="显示"> |
197 | <n-space> | 209 | <n-space> |
@@ -223,6 +235,47 @@ | @@ -223,6 +235,47 @@ | ||
223 | </SettingItem> | 235 | </SettingItem> |
224 | </SettingItemBox> | 236 | </SettingItemBox> |
225 | </CollapseItem> | 237 | </CollapseItem> |
238 | + | ||
239 | + <CollapseItem v-if="seriesList[2]" name="飞线" :expanded="true"> | ||
240 | + <SettingItemBox name="箭头"> | ||
241 | + <SettingItem name="速度"> | ||
242 | + <n-tooltip trigger="hover"> | ||
243 | + <template #trigger> | ||
244 | + <n-input-number v-model:value="seriesList[2].effect.period" size="small" :min="0"></n-input-number> | ||
245 | + </template> | ||
246 | + 值越小速度越快 | ||
247 | + </n-tooltip> | ||
248 | + </SettingItem> | ||
249 | + <SettingItem name="尾迹"> | ||
250 | + <n-tooltip trigger="hover"> | ||
251 | + <template #trigger> | ||
252 | + <n-input-number | ||
253 | + v-model:value="seriesList[2].effect.trailLength" | ||
254 | + size="small" | ||
255 | + :min="0" | ||
256 | + :max="1" | ||
257 | + ></n-input-number> | ||
258 | + </template> | ||
259 | + 特效尾迹长度[0,1]值越大,尾迹越长重 | ||
260 | + </n-tooltip> | ||
261 | + </SettingItem> | ||
262 | + <SettingItem name="大小"> | ||
263 | + <n-input-number v-model:value="seriesList[2].effect.symbolSize" size="small" :min="0"></n-input-number> | ||
264 | + </SettingItem> | ||
265 | + </SettingItemBox> | ||
266 | + <SettingItemBox name="配置"> | ||
267 | + <SettingItem name="颜色"> | ||
268 | + <n-color-picker | ||
269 | + size="small" | ||
270 | + :modes="['hex']" | ||
271 | + v-model:value="seriesList[2].lineStyle.normal.color" | ||
272 | + ></n-color-picker> | ||
273 | + </SettingItem> | ||
274 | + <SettingItem name="宽度"> | ||
275 | + <n-input-number v-model:value="seriesList[2].lineStyle.normal.width" size="small" :min="1"></n-input-number> | ||
276 | + </SettingItem> | ||
277 | + </SettingItemBox> | ||
278 | + </CollapseItem> | ||
226 | </template> | 279 | </template> |
227 | 280 | ||
228 | <script setup lang="ts"> | 281 | <script setup lang="ts"> |
@@ -21,6 +21,32 @@ | @@ -21,6 +21,32 @@ | ||
21 | "value": [126.642464, 45.756967, 101] | 21 | "value": [126.642464, 45.756967, 101] |
22 | } | 22 | } |
23 | ], | 23 | ], |
24 | + "line": [ | ||
25 | + { | ||
26 | + "coords": [ | ||
27 | + [113.665412, 34.757975], | ||
28 | + [116.405285, 39.904989] | ||
29 | + ] | ||
30 | + }, | ||
31 | + { | ||
32 | + "coords": [ | ||
33 | + [101.778916, 36.623178], | ||
34 | + [116.405285, 39.904989] | ||
35 | + ] | ||
36 | + }, | ||
37 | + { | ||
38 | + "coords": [ | ||
39 | + [106.278179, 38.46637], | ||
40 | + [116.405285, 39.904989] | ||
41 | + ] | ||
42 | + }, | ||
43 | + { | ||
44 | + "coords": [ | ||
45 | + [126.642464, 45.756967], | ||
46 | + [116.405285, 39.904989] | ||
47 | + ] | ||
48 | + } | ||
49 | + ], | ||
24 | "map": [ | 50 | "map": [ |
25 | { | 51 | { |
26 | "name": "北京市", | 52 | "name": "北京市", |
1 | <template> | 1 | <template> |
2 | - <v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize> | ||
3 | - </v-chart> | 2 | + <div> |
3 | + <div class="back-icon" v-if="(enter && levelHistory.length !== 0) || (enter && !isPreview())" @click="backLevel"> | ||
4 | + <n-icon :color="backColor" :size="backSize * 1.1"> | ||
5 | + <ArrowBackIcon /> | ||
6 | + </n-icon> | ||
7 | + <span | ||
8 | + :style="{ | ||
9 | + 'font-weight': 200, | ||
10 | + color: backColor, | ||
11 | + 'font-size': `${backSize}px` | ||
12 | + }" | ||
13 | + > | ||
14 | + 返回上级 | ||
15 | + </span> | ||
16 | + </div> | ||
17 | + <v-chart | ||
18 | + ref="vChartRef" | ||
19 | + :init-options="initOptions" | ||
20 | + :theme="themeColor" | ||
21 | + :option="option.value" | ||
22 | + :manual-update="isPreview()" | ||
23 | + autoresize | ||
24 | + @click="chartPEvents" | ||
25 | + > | ||
26 | + </v-chart> | ||
27 | + </div> | ||
4 | </template> | 28 | </template> |
5 | 29 | ||
6 | <script setup lang="ts"> | 30 | <script setup lang="ts"> |
7 | -import { PropType, reactive, watch, ref, nextTick } from 'vue' | 31 | +import { PropType, reactive, watch, ref, nextTick, toRefs } from 'vue' |
8 | import config, { includes } from './config' | 32 | import config, { includes } from './config' |
9 | import VChart from 'vue-echarts' | 33 | import VChart from 'vue-echarts' |
34 | +import { icon } from '@/plugins' | ||
10 | import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' | 35 | import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' |
11 | import { use, registerMap } from 'echarts/core' | 36 | import { use, registerMap } from 'echarts/core' |
12 | import { EffectScatterChart, MapChart } from 'echarts/charts' | 37 | import { EffectScatterChart, MapChart } from 'echarts/charts' |
@@ -16,6 +41,7 @@ import { mergeTheme, setOption } from '@/packages/public/chart' | @@ -16,6 +41,7 @@ import { mergeTheme, setOption } from '@/packages/public/chart' | ||
16 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 41 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
17 | import { isPreview } from '@/utils' | 42 | import { isPreview } from '@/utils' |
18 | import mapJsonWithoutHainanIsLands from './mapWithoutHainanIsLands.json' | 43 | import mapJsonWithoutHainanIsLands from './mapWithoutHainanIsLands.json' |
44 | +import mapChinaJson from './mapGeojson/china.json' | ||
19 | import { DatasetComponent, GridComponent, TooltipComponent, GeoComponent, VisualMapComponent } from 'echarts/components' | 45 | import { DatasetComponent, GridComponent, TooltipComponent, GeoComponent, VisualMapComponent } from 'echarts/components' |
20 | 46 | ||
21 | const props = defineProps({ | 47 | const props = defineProps({ |
@@ -33,6 +59,10 @@ const props = defineProps({ | @@ -33,6 +59,10 @@ const props = defineProps({ | ||
33 | } | 59 | } |
34 | }) | 60 | }) |
35 | 61 | ||
62 | +const { ArrowBackIcon } = icon.ionicons5 | ||
63 | +let levelHistory: any = ref([]) | ||
64 | + | ||
65 | +const { backColor, backSize, enter } = toRefs(props.chartConfig.option.mapRegion) | ||
36 | const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting) | 66 | const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting) |
37 | 67 | ||
38 | use([ | 68 | use([ |
@@ -67,7 +97,7 @@ registerMap(`${props.chartConfig.option.mapRegion.adcode}`, { geoJSON: {} as any | @@ -67,7 +97,7 @@ registerMap(`${props.chartConfig.option.mapRegion.adcode}`, { geoJSON: {} as any | ||
67 | // 进行更换初始化地图 如果为china 单独处理 | 97 | // 进行更换初始化地图 如果为china 单独处理 |
68 | const registerMapInitAsync = async () => { | 98 | const registerMapInitAsync = async () => { |
69 | await nextTick() | 99 | await nextTick() |
70 | - const adCode = `${props.chartConfig.option.mapRegion.adcode}`; | 100 | + const adCode = `${props.chartConfig.option.mapRegion.adcode}` |
71 | if (adCode !== 'china') { | 101 | if (adCode !== 'china') { |
72 | await getGeojson(adCode) | 102 | await getGeojson(adCode) |
73 | } else { | 103 | } else { |
@@ -87,7 +117,16 @@ const vEchartsSetOption = () => { | @@ -87,7 +117,16 @@ const vEchartsSetOption = () => { | ||
87 | const dataSetHandle = async (dataset: any) => { | 117 | const dataSetHandle = async (dataset: any) => { |
88 | props.chartConfig.option.series.forEach((item: any) => { | 118 | props.chartConfig.option.series.forEach((item: any) => { |
89 | if (item.type === 'effectScatter' && dataset.point) item.data = dataset.point | 119 | if (item.type === 'effectScatter' && dataset.point) item.data = dataset.point |
90 | - else if (item.type === 'map' && dataset.map) item.data = dataset.map | 120 | + else if (item.type === 'lines' && dataset.line) { |
121 | + item.data = dataset.line.map((it: any) => { | ||
122 | + return { | ||
123 | + ...it, | ||
124 | + lineStyle: { | ||
125 | + color: props.chartConfig.option.series[2].lineStyle.normal.color | ||
126 | + } | ||
127 | + } | ||
128 | + }) | ||
129 | + } else if (item.type === 'map' && dataset.map) item.data = dataset.map | ||
91 | }) | 130 | }) |
92 | if (dataset.pieces) props.chartConfig.option.visualMap.pieces = dataset.pieces | 131 | if (dataset.pieces) props.chartConfig.option.visualMap.pieces = dataset.pieces |
93 | 132 | ||
@@ -101,6 +140,45 @@ const hainanLandsHandle = async (newData: boolean) => { | @@ -101,6 +140,45 @@ const hainanLandsHandle = async (newData: boolean) => { | ||
101 | registerMap('china', { geoJSON: mapJsonWithoutHainanIsLands as any, specialAreas: {} }) | 140 | registerMap('china', { geoJSON: mapJsonWithoutHainanIsLands as any, specialAreas: {} }) |
102 | } | 141 | } |
103 | } | 142 | } |
143 | + | ||
144 | +// 点击区域 | ||
145 | +const chartPEvents = (e: any) => { | ||
146 | + if (e.seriesType !== 'map') return | ||
147 | + if (!props.chartConfig.option.mapRegion.enter) { | ||
148 | + return | ||
149 | + } | ||
150 | + mapChinaJson.features.forEach(item => { | ||
151 | + var pattern = new RegExp(e.name) | ||
152 | + if (pattern.test(item.properties.name)) { | ||
153 | + let code = String(item.properties.adcode) | ||
154 | + levelHistory.value.push(code) | ||
155 | + checkOrMap(code) | ||
156 | + } | ||
157 | + }) | ||
158 | +} | ||
159 | + | ||
160 | +// 返回上一级 | ||
161 | +const backLevel = () => { | ||
162 | + levelHistory.value = [] | ||
163 | + if (levelHistory.value.length > 1) { | ||
164 | + levelHistory.value.pop() | ||
165 | + const code = levelHistory[levelHistory.value.length - 1] | ||
166 | + checkOrMap(code) | ||
167 | + } else { | ||
168 | + checkOrMap('china') | ||
169 | + } | ||
170 | +} | ||
171 | + | ||
172 | +// 切换地图 | ||
173 | +const checkOrMap = async (newData: string) => { | ||
174 | + await getGeojson(newData) | ||
175 | + props.chartConfig.option.geo.map = newData | ||
176 | + props.chartConfig.option.series.forEach((item: any) => { | ||
177 | + if (item.type === 'map') item.map = newData | ||
178 | + }) | ||
179 | + vEchartsSetOption() | ||
180 | +} | ||
181 | + | ||
104 | //监听 dataset 数据发生变化 | 182 | //监听 dataset 数据发生变化 |
105 | watch( | 183 | watch( |
106 | () => props.chartConfig.option.dataset, | 184 | () => props.chartConfig.option.dataset, |
@@ -113,33 +191,42 @@ watch( | @@ -113,33 +191,42 @@ watch( | ||
113 | } | 191 | } |
114 | ) | 192 | ) |
115 | 193 | ||
116 | -//监听是否显示南海群岛 | ||
117 | -watch( | ||
118 | - () => props.chartConfig.option.mapRegion.showHainanIsLands, | ||
119 | - async newData => { | ||
120 | - try { | ||
121 | - await hainanLandsHandle(newData) | ||
122 | - vEchartsSetOption() | ||
123 | - } catch (error) { | ||
124 | - console.log(error) | 194 | +// 监听线的颜色 |
195 | +if (props.chartConfig.option.series[2] && !isPreview()) { | ||
196 | + watch( | ||
197 | + () => props.chartConfig.option.series[2].lineStyle.normal.color, | ||
198 | + () => { | ||
199 | + dataSetHandle(props.chartConfig.option.dataset) | ||
200 | + }, | ||
201 | + { | ||
202 | + deep: false | ||
125 | } | 203 | } |
126 | - }, | ||
127 | - { | ||
128 | - deep: false | ||
129 | - } | ||
130 | -) | 204 | + ) |
205 | +} | ||
131 | 206 | ||
207 | +//监听是否显示南海群岛 | ||
208 | +if (!isPreview()) { | ||
209 | + watch( | ||
210 | + () => props.chartConfig.option.mapRegion.showHainanIsLands, | ||
211 | + async newData => { | ||
212 | + try { | ||
213 | + await hainanLandsHandle(newData) | ||
214 | + vEchartsSetOption() | ||
215 | + } catch (error) { | ||
216 | + console.log(error) | ||
217 | + } | ||
218 | + }, | ||
219 | + { | ||
220 | + deep: false | ||
221 | + } | ||
222 | + ) | ||
223 | +} | ||
132 | //监听地图展示区域发生变化 | 224 | //监听地图展示区域发生变化 |
133 | watch( | 225 | watch( |
134 | () => `${props.chartConfig.option.mapRegion.adcode}`, | 226 | () => `${props.chartConfig.option.mapRegion.adcode}`, |
135 | - async newData => { | 227 | + newData => { |
136 | try { | 228 | try { |
137 | - await getGeojson(newData) | ||
138 | - props.chartConfig.option.geo.map = newData | ||
139 | - props.chartConfig.option.series.forEach((item: any) => { | ||
140 | - if (item.type === 'map') item.map = newData | ||
141 | - }) | ||
142 | - vEchartsSetOption() | 229 | + checkOrMap(newData) |
143 | } catch (error) { | 230 | } catch (error) { |
144 | console.log(error) | 231 | console.log(error) |
145 | } | 232 | } |
@@ -154,3 +241,16 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | @@ -154,3 +241,16 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | ||
154 | dataSetHandle(newData) | 241 | dataSetHandle(newData) |
155 | }) | 242 | }) |
156 | </script> | 243 | </script> |
244 | + | ||
245 | +<style scope lang="scss"> | ||
246 | +.back-icon { | ||
247 | + z-index: 50; | ||
248 | + cursor: pointer; | ||
249 | + position: absolute; | ||
250 | + display: flex; | ||
251 | + align-items: center; | ||
252 | + top: 0; | ||
253 | + left: 0; | ||
254 | + gap: 2px; | ||
255 | +} | ||
256 | +</style> |
@@ -9,7 +9,8 @@ export const includes = [] | @@ -9,7 +9,8 @@ export const includes = [] | ||
9 | // 关系图布局 | 9 | // 关系图布局 |
10 | export const GraphLayout = [ | 10 | export const GraphLayout = [ |
11 | { label: '无', value: 'none' }, | 11 | { label: '无', value: 'none' }, |
12 | - { label: '环形', value: 'circular' } | 12 | + { label: '环形', value: 'circular' }, |
13 | + { label: '力引导', value: 'force' } | ||
13 | ] | 14 | ] |
14 | 15 | ||
15 | // 标签开关 | 16 | // 标签开关 |
@@ -24,7 +25,13 @@ export const LabelPosition = [ | @@ -24,7 +25,13 @@ export const LabelPosition = [ | ||
24 | { label: '右侧', value: 'right' }, | 25 | { label: '右侧', value: 'right' }, |
25 | { label: '顶部', value: 'top' }, | 26 | { label: '顶部', value: 'top' }, |
26 | { label: '底部', value: 'bottom' }, | 27 | { label: '底部', value: 'bottom' }, |
27 | - { label: '内部', value: 'inside' }, | 28 | + { label: '内部', value: 'inside' } |
29 | +] | ||
30 | + | ||
31 | +// 图-迭代动画 | ||
32 | +export const LayoutAnimation = [ | ||
33 | + { label: '开启', value: 1 }, | ||
34 | + { label: '关闭', value: 0 } | ||
28 | ] | 35 | ] |
29 | 36 | ||
30 | export const option = { | 37 | export const option = { |
@@ -33,11 +40,11 @@ export const option = { | @@ -33,11 +40,11 @@ export const option = { | ||
33 | legend:{ | 40 | legend:{ |
34 | show:true, | 41 | show:true, |
35 | textStyle:{ | 42 | textStyle:{ |
36 | - color:"#eee", | ||
37 | - fontSize: 14 , | 43 | + color: '#eee', |
44 | + fontSize: 14 | ||
38 | }, | 45 | }, |
39 | data: dataJson.categories.map(function (a) { | 46 | data: dataJson.categories.map(function (a) { |
40 | - return a.name; | 47 | + return a.name |
41 | }) | 48 | }) |
42 | }, | 49 | }, |
43 | series: [ | 50 | series: [ |
@@ -47,7 +54,7 @@ export const option = { | @@ -47,7 +54,7 @@ export const option = { | ||
47 | data: dataJson.nodes, | 54 | data: dataJson.nodes, |
48 | links: dataJson.links, | 55 | links: dataJson.links, |
49 | categories: dataJson.categories, | 56 | categories: dataJson.categories, |
50 | - label: { // 标签 | 57 | + label: { |
51 | show: 1, | 58 | show: 1, |
52 | position: 'right', | 59 | position: 'right', |
53 | formatter: '{b}' | 60 | formatter: '{b}' |
@@ -58,10 +65,17 @@ export const option = { | @@ -58,10 +65,17 @@ export const option = { | ||
58 | lineStyle: { | 65 | lineStyle: { |
59 | color: 'source', // 线条颜色 | 66 | color: 'source', // 线条颜色 |
60 | curveness: 0.2 // 线条卷曲程度 | 67 | curveness: 0.2 // 线条卷曲程度 |
68 | + }, | ||
69 | + force: { | ||
70 | + repulsion: 100, | ||
71 | + gravity: 0.1, | ||
72 | + edgeLength: 30, | ||
73 | + layoutAnimation: 1, | ||
74 | + friction: 0.6 | ||
61 | } | 75 | } |
62 | } | 76 | } |
63 | ] | 77 | ] |
64 | - }; | 78 | +} |
65 | 79 | ||
66 | export default class Config extends PublicConfigClass implements CreateComponentType { | 80 | export default class Config extends PublicConfigClass implements CreateComponentType { |
67 | public key = GraphConfig.key | 81 | public key = GraphConfig.key |
@@ -35,7 +35,58 @@ | @@ -35,7 +35,58 @@ | ||
35 | ></n-color-picker> | 35 | ></n-color-picker> |
36 | </SettingItem> | 36 | </SettingItem> |
37 | <SettingItem name="文本"> | 37 | <SettingItem name="文本"> |
38 | - <n-input-number v-model:value="optionData.legend.textStyle.fontSize" :min="0" :step="1" size="small" placeholder="文字大小"> | 38 | + <n-input-number |
39 | + v-model:value="optionData.legend.textStyle.fontSize" | ||
40 | + :min="0" | ||
41 | + :step="1" | ||
42 | + size="small" | ||
43 | + placeholder="文字大小" | ||
44 | + > | ||
45 | + </n-input-number> | ||
46 | + </SettingItem> | ||
47 | + </SettingItemBox> | ||
48 | + <SettingItemBox name="力引导" v-if="optionData.series[0].force && graphConfig.layout == 'force'"> | ||
49 | + <SettingItem name="斥力因子" v-if="optionData.series[0].force.repulsion"> | ||
50 | + <n-input-number | ||
51 | + v-model:value="optionData.series[0].force.repulsion" | ||
52 | + :min="0" | ||
53 | + :step="1" | ||
54 | + size="small" | ||
55 | + placeholder="斥力因子大小" | ||
56 | + > | ||
57 | + </n-input-number> | ||
58 | + </SettingItem> | ||
59 | + <SettingItem name="引力因子" v-if="optionData.series[0].force.gravity"> | ||
60 | + <n-input-number | ||
61 | + v-model:value="optionData.series[0].force.gravity" | ||
62 | + :min="0" | ||
63 | + :step="0.1" | ||
64 | + size="small" | ||
65 | + placeholder="引力因子" | ||
66 | + > | ||
67 | + </n-input-number> | ||
68 | + </SettingItem> | ||
69 | + <SettingItem name="节点距离"> | ||
70 | + <n-input-number | ||
71 | + v-model:value="optionData.series[0].force.edgeLength" | ||
72 | + :min="0" | ||
73 | + :step="1" | ||
74 | + size="small" | ||
75 | + placeholder="节点距离" | ||
76 | + > | ||
77 | + </n-input-number> | ||
78 | + </SettingItem> | ||
79 | + <SettingItem name="迭代动画"> | ||
80 | + <n-select v-model:value="graphConfig.force.layoutAnimation" :options="LayoutAnimation" size="small" /> | ||
81 | + </SettingItem> | ||
82 | + <SettingItem name="节点速度"> | ||
83 | + <n-input-number | ||
84 | + v-model:value="optionData.series[0].force.friction" | ||
85 | + :min="0" | ||
86 | + :step="0.1" | ||
87 | + size="small" | ||
88 | + placeholder="节点速度" | ||
89 | + > | ||
39 | </n-input-number> | 90 | </n-input-number> |
40 | </SettingItem> | 91 | </SettingItem> |
41 | </SettingItemBox> | 92 | </SettingItemBox> |
@@ -46,7 +97,7 @@ | @@ -46,7 +97,7 @@ | ||
46 | <script setup lang="ts"> | 97 | <script setup lang="ts"> |
47 | import { PropType, computed } from 'vue' | 98 | import { PropType, computed } from 'vue' |
48 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | 99 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' |
49 | -import { option, GraphLayout, LabelSwitch, LabelPosition } from './config' | 100 | +import { option, GraphLayout, LabelSwitch, LabelPosition, LayoutAnimation } from './config' |
50 | import { GlobalThemeJsonType } from '@/settings/chartThemes/index' | 101 | import { GlobalThemeJsonType } from '@/settings/chartThemes/index' |
51 | 102 | ||
52 | const props = defineProps({ | 103 | const props = defineProps({ |
@@ -56,7 +107,7 @@ const props = defineProps({ | @@ -56,7 +107,7 @@ const props = defineProps({ | ||
56 | } | 107 | } |
57 | }) | 108 | }) |
58 | 109 | ||
59 | -const graphConfig = computed<typeof option.series[0]>(() => { | 110 | +const graphConfig = computed<(typeof option.series)[0]>(() => { |
60 | return props.optionData.series[0] | 111 | return props.optionData.series[0] |
61 | }) | 112 | }) |
62 | </script> | 113 | </script> |
1 | <template> | 1 | <template> |
2 | - <v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option" :manual-update="isPreview()" autoresize></v-chart> | 2 | + <v-chart |
3 | + ref="vChartRef" | ||
4 | + :init-options="initOptions" | ||
5 | + :theme="themeColor" | ||
6 | + :option="option" | ||
7 | + :manual-update="isPreview()" | ||
8 | + autoresize | ||
9 | + ></v-chart> | ||
3 | </template> | 10 | </template> |
4 | 11 | ||
5 | <script setup lang="ts"> | 12 | <script setup lang="ts"> |
@@ -8,4 +8,14 @@ import { DialConfig } from './Dial/index' | @@ -8,4 +8,14 @@ import { DialConfig } from './Dial/index' | ||
8 | import { SankeyConfig } from './Sankey/index' | 8 | import { SankeyConfig } from './Sankey/index' |
9 | import { GraphConfig } from './Graph/index' | 9 | import { GraphConfig } from './Graph/index' |
10 | 10 | ||
11 | -export default [ProcessConfig, RadarConfig, FunnelConfig, HeatmapConfig, WaterPoloConfig, TreeMapConfig, GraphConfig, SankeyConfig, DialConfig] | 11 | +export default [ |
12 | + ProcessConfig, | ||
13 | + RadarConfig, | ||
14 | + FunnelConfig, | ||
15 | + HeatmapConfig, | ||
16 | + WaterPoloConfig, | ||
17 | + TreeMapConfig, | ||
18 | + GraphConfig, | ||
19 | + SankeyConfig, | ||
20 | + DialConfig | ||
21 | +] |
@@ -33,8 +33,6 @@ const option = shallowReactive({ | @@ -33,8 +33,6 @@ const option = shallowReactive({ | ||
33 | dataset: '' | 33 | dataset: '' |
34 | }) | 34 | }) |
35 | 35 | ||
36 | - | ||
37 | - | ||
38 | const getStyle = (radius: number) => { | 36 | const getStyle = (radius: number) => { |
39 | return { | 37 | return { |
40 | borderRadius: `${radius}px`, | 38 | borderRadius: `${radius}px`, |
@@ -78,7 +76,6 @@ watch( | @@ -78,7 +76,6 @@ watch( | ||
78 | return | 76 | return |
79 | } | 77 | } |
80 | option.dataset = newData | 78 | option.dataset = newData |
81 | - | ||
82 | }, | 79 | }, |
83 | { | 80 | { |
84 | immediate: true | 81 | immediate: true |
@@ -161,6 +161,26 @@ export const option = { | @@ -161,6 +161,26 @@ export const option = { | ||
161 | shadowOffsetY: 2, | 161 | shadowOffsetY: 2, |
162 | shadowBlur: 10 | 162 | shadowBlur: 10 |
163 | } | 163 | } |
164 | + }, | ||
165 | + { | ||
166 | + type: 'lines', | ||
167 | + zlevel: 2, | ||
168 | + effect: { | ||
169 | + show: true, | ||
170 | + period: 4, //箭头指向速度,值越小速度越快 | ||
171 | + trailLength: 0.4, //特效尾迹长度[0,1]值越大,尾迹越长重 | ||
172 | + symbol: 'arrow', //箭头图标 | ||
173 | + symbolSize: 7 //图标大小 | ||
174 | + }, | ||
175 | + lineStyle: { | ||
176 | + normal: { | ||
177 | + color: '#4fb6d2', | ||
178 | + width: 1, //线条宽度 | ||
179 | + opacity: 0.1, //尾迹线条透明度 | ||
180 | + curveness: 0.3 //尾迹线条曲直度 | ||
181 | + } | ||
182 | + }, | ||
183 | + data: [] | ||
164 | } | 184 | } |
165 | ] | 185 | ] |
166 | } | 186 | } |
@@ -246,6 +246,46 @@ | @@ -246,6 +246,46 @@ | ||
246 | </SettingItem> | 246 | </SettingItem> |
247 | </SettingItemBox> | 247 | </SettingItemBox> |
248 | </CollapseItem> | 248 | </CollapseItem> |
249 | + <CollapseItem v-if="seriesList[2]" name="飞线" :expanded="true"> | ||
250 | + <SettingItemBox name="箭头"> | ||
251 | + <SettingItem name="速度"> | ||
252 | + <n-tooltip trigger="hover"> | ||
253 | + <template #trigger> | ||
254 | + <n-input-number v-model:value="seriesList[2].effect.period" size="small" :min="0"></n-input-number> | ||
255 | + </template> | ||
256 | + 值越小速度越快 | ||
257 | + </n-tooltip> | ||
258 | + </SettingItem> | ||
259 | + <SettingItem name="尾迹"> | ||
260 | + <n-tooltip trigger="hover"> | ||
261 | + <template #trigger> | ||
262 | + <n-input-number | ||
263 | + v-model:value="seriesList[2].effect.trailLength" | ||
264 | + size="small" | ||
265 | + :min="0" | ||
266 | + :max="1" | ||
267 | + ></n-input-number> | ||
268 | + </template> | ||
269 | + 特效尾迹长度[0,1]值越大,尾迹越长重 | ||
270 | + </n-tooltip> | ||
271 | + </SettingItem> | ||
272 | + <SettingItem name="大小"> | ||
273 | + <n-input-number v-model:value="seriesList[2].effect.symbolSize" size="small" :min="0"></n-input-number> | ||
274 | + </SettingItem> | ||
275 | + </SettingItemBox> | ||
276 | + <SettingItemBox name="配置"> | ||
277 | + <SettingItem name="颜色"> | ||
278 | + <n-color-picker | ||
279 | + size="small" | ||
280 | + :modes="['hex']" | ||
281 | + v-model:value="seriesList[2].lineStyle.normal.color" | ||
282 | + ></n-color-picker> | ||
283 | + </SettingItem> | ||
284 | + <SettingItem name="宽度"> | ||
285 | + <n-input-number v-model:value="seriesList[2].lineStyle.normal.width" size="small" :min="1"></n-input-number> | ||
286 | + </SettingItem> | ||
287 | + </SettingItemBox> | ||
288 | + </CollapseItem> | ||
249 | </template> | 289 | </template> |
250 | 290 | ||
251 | <script setup lang="ts"> | 291 | <script setup lang="ts"> |
@@ -26,6 +26,36 @@ | @@ -26,6 +26,36 @@ | ||
26 | "value": [126.642464, 45.756967, 101] | 26 | "value": [126.642464, 45.756967, 101] |
27 | } | 27 | } |
28 | ], | 28 | ], |
29 | + "line": [ | ||
30 | + { | ||
31 | + "adcode": 410000, | ||
32 | + "coords": [ | ||
33 | + [113.665412, 34.757975], | ||
34 | + [116.405285, 39.904989] | ||
35 | + ] | ||
36 | + }, | ||
37 | + { | ||
38 | + "adcode": 630000, | ||
39 | + "coords": [ | ||
40 | + [101.778916, 36.623178], | ||
41 | + [116.405285, 39.904989] | ||
42 | + ] | ||
43 | + }, | ||
44 | + { | ||
45 | + "adcode": 640000, | ||
46 | + "coords": [ | ||
47 | + [106.278179, 38.46637], | ||
48 | + [116.405285, 39.904989] | ||
49 | + ] | ||
50 | + }, | ||
51 | + { | ||
52 | + "adcode": 230000, | ||
53 | + "coords": [ | ||
54 | + [126.642464, 45.756967], | ||
55 | + [116.405285, 39.904989] | ||
56 | + ] | ||
57 | + } | ||
58 | + ], | ||
29 | "map": [ | 59 | "map": [ |
30 | { | 60 | { |
31 | "name": "北京市", | 61 | "name": "北京市", |
@@ -202,9 +202,19 @@ const vEchartsSetOption = async () => { | @@ -202,9 +202,19 @@ const vEchartsSetOption = async () => { | ||
202 | const dataSetHandle = async (dataset: any) => { | 202 | const dataSetHandle = async (dataset: any) => { |
203 | props.chartConfig.option.series.forEach((item: any) => { | 203 | props.chartConfig.option.series.forEach((item: any) => { |
204 | if (item.type === 'effectScatter' && dataset.point) item.data = dataset.point | 204 | if (item.type === 'effectScatter' && dataset.point) item.data = dataset.point |
205 | - else if (item.type === 'map' && dataset.map) item.data = dataset.map | 205 | + else if (item.type === 'lines' && dataset.line) { |
206 | + item.data = dataset.line.map((it: any) => { | ||
207 | + return { | ||
208 | + ...it, | ||
209 | + lineStyle: { | ||
210 | + color: props.chartConfig.option.series[2].lineStyle.normal.color | ||
211 | + } | ||
212 | + } | ||
213 | + }) | ||
214 | + } else if (item.type === 'map' && dataset.map) item.data = dataset.map | ||
206 | }) | 215 | }) |
207 | if (dataset.pieces) props.chartConfig.option.visualMap.pieces = dataset.pieces | 216 | if (dataset.pieces) props.chartConfig.option.visualMap.pieces = dataset.pieces |
217 | + | ||
208 | isPreview() && vEchartsSetOption() | 218 | isPreview() && vEchartsSetOption() |
209 | } | 219 | } |
210 | 220 | ||
@@ -245,14 +255,16 @@ watch( | @@ -245,14 +255,16 @@ watch( | ||
245 | } | 255 | } |
246 | ) | 256 | ) |
247 | 257 | ||
248 | -//处理数据标点 | 258 | +//处理数据标点包括飞线 |
249 | const handleDataPoint = (newData: any) => { | 259 | const handleDataPoint = (newData: any) => { |
250 | if (newData === 'china') { | 260 | if (newData === 'china') { |
251 | dataSetHandle(dataJson) | 261 | dataSetHandle(dataJson) |
252 | } else { | 262 | } else { |
253 | const filterPoint = dataJson.point.filter((item: any) => item.adcode === newData) | 263 | const filterPoint = dataJson.point.filter((item: any) => item.adcode === newData) |
264 | + // const filterLine = dataJson.line.filter((item: any) => item.adcode === newData) | ||
254 | dataSetHandle({ | 265 | dataSetHandle({ |
255 | - point: filterPoint | 266 | + point: filterPoint, |
267 | + line: [] //由于点击单个地图模块,所以去除飞线 | ||
256 | }) | 268 | }) |
257 | } | 269 | } |
258 | } | 270 | } |
@@ -310,7 +322,7 @@ const handleVChartClick = async (params: any) => { | @@ -310,7 +322,7 @@ const handleVChartClick = async (params: any) => { | ||
310 | const level = item.properties.level.toUpperCase() | 322 | const level = item.properties.level.toUpperCase() |
311 | const adcode = item.properties.adcode | 323 | const adcode = item.properties.adcode |
312 | if (level === 'DISTRICT') return | 324 | if (level === 'DISTRICT') return |
313 | - if(String(adcode).startsWith('15') && level===areaEnum.CITY) return | 325 | + if (String(adcode).startsWith('15') && level === areaEnum.CITY) return |
314 | props.chartConfig.option.mapRegion.adcode = adcode | 326 | props.chartConfig.option.mapRegion.adcode = adcode |
315 | saveLevelStr.level = level | 327 | saveLevelStr.level = level |
316 | handleDataPoint(adcode) | 328 | handleDataPoint(adcode) |
@@ -27,6 +27,16 @@ export let packagesList: PackagesType = { | @@ -27,6 +27,16 @@ export let packagesList: PackagesType = { | ||
27 | [PackagesCategoryEnum.ICONS]: IconList | 27 | [PackagesCategoryEnum.ICONS]: IconList |
28 | } | 28 | } |
29 | 29 | ||
30 | +// 组件缓存, 可以大幅度提升组件加载速度 | ||
31 | +const componentCacheMap = new Map<string, any>() | ||
32 | +const loadConfig = (packageName: string, categoryName: string, keyName: string) => { | ||
33 | + const key = packageName + categoryName + keyName | ||
34 | + if (!componentCacheMap.has(key)) { | ||
35 | + componentCacheMap.set(key, import(`./components/${packageName}/${categoryName}/${keyName}/config.ts`)) | ||
36 | + } | ||
37 | + return componentCacheMap.get(key) | ||
38 | +} | ||
39 | + | ||
30 | /** | 40 | /** |
31 | * * 获取目标组件配置信息 | 41 | * * 获取目标组件配置信息 |
32 | * @param targetData | 42 | * @param targetData |
@@ -36,10 +46,10 @@ export const createComponent = async (targetData: ConfigType) => { | @@ -36,10 +46,10 @@ export const createComponent = async (targetData: ConfigType) => { | ||
36 | // redirectComponent 是给图片组件库和图标组件库使用的 | 46 | // redirectComponent 是给图片组件库和图标组件库使用的 |
37 | if (redirectComponent) { | 47 | if (redirectComponent) { |
38 | const [packageName, categoryName, keyName] = redirectComponent.split('/') | 48 | const [packageName, categoryName, keyName] = redirectComponent.split('/') |
39 | - const redirectChart = await import(`./components/${packageName}/${categoryName}/${keyName}/config.ts`) | 49 | + const redirectChart = await loadConfig(packageName, categoryName, keyName) |
40 | return new redirectChart.default() | 50 | return new redirectChart.default() |
41 | } | 51 | } |
42 | - const chart = await import(`./components/${targetData.package}/${category}/${key}/config.ts`) | 52 | + const chart = await loadConfig(targetData.package, category, key) |
43 | return new chart.default() | 53 | return new chart.default() |
44 | } | 54 | } |
45 | 55 | ||
@@ -98,5 +108,4 @@ export const fetchImages = async (targetData?: ConfigType) => { | @@ -98,5 +108,4 @@ export const fetchImages = async (targetData?: ConfigType) => { | ||
98 | } | 108 | } |
99 | return '' | 109 | return '' |
100 | } | 110 | } |
101 | - | ||
102 | useInjectLib(packagesList as any) // THINGS_KIT 修改注册组件 | 111 | useInjectLib(packagesList as any) // THINGS_KIT 修改注册组件 |
@@ -24,7 +24,6 @@ import cloneDeep from 'lodash/cloneDeep' | @@ -24,7 +24,6 @@ import cloneDeep from 'lodash/cloneDeep' | ||
24 | * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯 | 24 | * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯 |
25 | * 源代码 requestDataType: RequestDataTypeEnum.STATIC, | 25 | * 源代码 requestDataType: RequestDataTypeEnum.STATIC, |
26 | * 修改后的代码 requestDataType: RequestDataTypeEnum.Pond, | 26 | * 修改后的代码 requestDataType: RequestDataTypeEnum.Pond, |
27 | - * 修改后代码在//ft之间 | ||
28 | */ | 27 | */ |
29 | // 请求基础属性 | 28 | // 请求基础属性 |
30 | export const requestConfig: RequestConfigType = { | 29 | export const requestConfig: RequestConfigType = { |
@@ -49,7 +48,6 @@ export const requestConfig: RequestConfigType = { | @@ -49,7 +48,6 @@ export const requestConfig: RequestConfigType = { | ||
49 | Params: {} | 48 | Params: {} |
50 | } | 49 | } |
51 | } | 50 | } |
52 | -//ft之间 | ||
53 | 51 | ||
54 | // 单实例类 | 52 | // 单实例类 |
55 | export class PublicConfigClass implements PublicConfigType { | 53 | export class PublicConfigClass implements PublicConfigType { |
@@ -162,17 +162,17 @@ export const useChartEditStore = defineStore({ | @@ -162,17 +162,17 @@ export const useChartEditStore = defineStore({ | ||
162 | }, | 162 | }, |
163 | getComponentList(): Array<CreateComponentType | CreateComponentGroupType> { | 163 | getComponentList(): Array<CreateComponentType | CreateComponentGroupType> { |
164 | return this.componentList | 164 | return this.componentList |
165 | - }, | ||
166 | - // 获取需要存储的数据项 | 165 | + } |
166 | + }, | ||
167 | + actions: { | ||
168 | + // * 获取需要存储的数据项 | ||
167 | getStorageInfo(): ChartEditStorage { | 169 | getStorageInfo(): ChartEditStorage { |
168 | return { | 170 | return { |
169 | [ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: this.getEditCanvasConfig, | 171 | [ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: this.getEditCanvasConfig, |
170 | [ChartEditStoreEnum.COMPONENT_LIST]: this.getComponentList, | 172 | [ChartEditStoreEnum.COMPONENT_LIST]: this.getComponentList, |
171 | [ChartEditStoreEnum.REQUEST_GLOBAL_CONFIG]: this.getRequestGlobalConfig | 173 | [ChartEditStoreEnum.REQUEST_GLOBAL_CONFIG]: this.getRequestGlobalConfig |
172 | } | 174 | } |
173 | - } | ||
174 | - }, | ||
175 | - actions: { | 175 | + }, |
176 | // * 设置 editCanvas 数据项 | 176 | // * 设置 editCanvas 数据项 |
177 | setEditCanvas<T extends keyof EditCanvasType, K extends EditCanvasType[T]>(key: T, value: K) { | 177 | setEditCanvas<T extends keyof EditCanvasType, K extends EditCanvasType[T]>(key: T, value: K) { |
178 | this.editCanvas[key] = value | 178 | this.editCanvas[key] = value |
@@ -10,13 +10,7 @@ import { useInjectAside } from './external/useInjectAside' | @@ -10,13 +10,7 @@ import { useInjectAside } from './external/useInjectAside' | ||
10 | 10 | ||
11 | // 图标 | 11 | // 图标 |
12 | const { AirPlaneOutlineIcon, ImageIcon, BarChartIcon } = icon.ionicons5 | 12 | const { AirPlaneOutlineIcon, ImageIcon, BarChartIcon } = icon.ionicons5 |
13 | -const { | ||
14 | - TableSplitIcon, | ||
15 | - RoadmapIcon, | ||
16 | - SpellCheckIcon, | ||
17 | - GraphicalDataFlowIcon, | ||
18 | -} = icon.carbon | ||
19 | - | 13 | +const { TableSplitIcon, RoadmapIcon, SpellCheckIcon, GraphicalDataFlowIcon } = icon.carbon |
20 | 14 | ||
21 | // 图表 | 15 | // 图表 |
22 | export type MenuOptionsType = { | 16 | export type MenuOptionsType = { |
@@ -9,7 +9,7 @@ export const exportHandle = () => { | @@ -9,7 +9,7 @@ export const exportHandle = () => { | ||
9 | 9 | ||
10 | // 导出数据 | 10 | // 导出数据 |
11 | downloadTextFile( | 11 | downloadTextFile( |
12 | - JSONStringify(chartEditStore.getStorageInfo || []), | 12 | + JSONStringify(chartEditStore.getStorageInfo() || []), |
13 | undefined, | 13 | undefined, |
14 | 'json' | 14 | 'json' |
15 | ) | 15 | ) |
@@ -19,14 +19,14 @@ export const syncData = () => { | @@ -19,14 +19,14 @@ export const syncData = () => { | ||
19 | transformOrigin: 'center', | 19 | transformOrigin: 'center', |
20 | onPositiveCallback: () => { | 20 | onPositiveCallback: () => { |
21 | window['$message'].success('正在同步编辑器...') | 21 | window['$message'].success('正在同步编辑器...') |
22 | - dispatchEvent(new CustomEvent(SavePageEnum.CHART, { detail: chartEditStore.getStorageInfo })) | 22 | + dispatchEvent(new CustomEvent(SavePageEnum.CHART, { detail: chartEditStore.getStorageInfo() })) |
23 | } | 23 | } |
24 | }) | 24 | }) |
25 | } | 25 | } |
26 | 26 | ||
27 | // 同步数据到预览页 | 27 | // 同步数据到预览页 |
28 | export const syncDataToPreview = () => { | 28 | export const syncDataToPreview = () => { |
29 | - dispatchEvent(new CustomEvent(SavePageEnum.CHART_TO_PREVIEW, { detail: chartEditStore.getStorageInfo })) | 29 | + dispatchEvent(new CustomEvent(SavePageEnum.CHART_TO_PREVIEW, { detail: chartEditStore.getStorageInfo() })) |
30 | } | 30 | } |
31 | 31 | ||
32 | // 侦听器更新 | 32 | // 侦听器更新 |
@@ -160,7 +160,7 @@ const editHandle = () => { | @@ -160,7 +160,7 @@ const editHandle = () => { | ||
160 | 160 | ||
161 | // 把内存中的数据同步到SessionStorage 便于传递给新窗口初始化数据 | 161 | // 把内存中的数据同步到SessionStorage 便于传递给新窗口初始化数据 |
162 | const updateToSession = (id: string) => { | 162 | const updateToSession = (id: string) => { |
163 | - const storageInfo = chartEditStore.getStorageInfo | 163 | + const storageInfo = chartEditStore.getStorageInfo() |
164 | const sessionStorageInfo = getLocalStorage(StorageEnum.GO_CHART_STORAGE_LIST) || [] | 164 | const sessionStorageInfo = getLocalStorage(StorageEnum.GO_CHART_STORAGE_LIST) || [] |
165 | 165 | ||
166 | if (sessionStorageInfo?.length) { | 166 | if (sessionStorageInfo?.length) { |
@@ -9,7 +9,7 @@ export const exportHandle = () => { | @@ -9,7 +9,7 @@ export const exportHandle = () => { | ||
9 | 9 | ||
10 | // 导出数据 | 10 | // 导出数据 |
11 | downloadTextFile( | 11 | downloadTextFile( |
12 | - JSONStringify(chartEditStore.getStorageInfo || []), | 12 | + JSONStringify(chartEditStore.getStorageInfo() || []), |
13 | undefined, | 13 | undefined, |
14 | 'json' | 14 | 'json' |
15 | ) | 15 | ) |
@@ -32,7 +32,7 @@ const previewHandle = () => { | @@ -32,7 +32,7 @@ const previewHandle = () => { | ||
32 | const { id } = routerParamsInfo.params | 32 | const { id } = routerParamsInfo.params |
33 | // id 标识 | 33 | // id 标识 |
34 | const previewId = typeof id === 'string' ? id : id[0] | 34 | const previewId = typeof id === 'string' ? id : id[0] |
35 | - const storageInfo = chartEditStore.getStorageInfo | 35 | + const storageInfo = chartEditStore.getStorageInfo() |
36 | const sessionStorageInfo = getLocalStorage(StorageEnum.GO_CHART_STORAGE_LIST) || [] | 36 | const sessionStorageInfo = getLocalStorage(StorageEnum.GO_CHART_STORAGE_LIST) || [] |
37 | 37 | ||
38 | if (sessionStorageInfo?.length) { | 38 | if (sessionStorageInfo?.length) { |
@@ -32,7 +32,7 @@ const previewHandle = () => { | @@ -32,7 +32,7 @@ const previewHandle = () => { | ||
32 | const { id } = routerParamsInfo.params | 32 | const { id } = routerParamsInfo.params |
33 | // id 标识 | 33 | // id 标识 |
34 | const previewId = typeof id === 'string' ? id : id[0] | 34 | const previewId = typeof id === 'string' ? id : id[0] |
35 | - const storageInfo = chartEditStore.getStorageInfo | 35 | + const storageInfo = chartEditStore.getStorageInfo() |
36 | const sessionStorageInfo = getLocalStorage(StorageEnum.GO_CHART_STORAGE_LIST) || [] | 36 | const sessionStorageInfo = getLocalStorage(StorageEnum.GO_CHART_STORAGE_LIST) || [] |
37 | 37 | ||
38 | if (sessionStorageInfo?.length) { | 38 | if (sessionStorageInfo?.length) { |
@@ -76,7 +76,7 @@ const handleBlur = async () => { | @@ -76,7 +76,7 @@ const handleBlur = async () => { | ||
76 | dataViewId, | 76 | dataViewId, |
77 | dataViewContent: { | 77 | dataViewContent: { |
78 | id: dataViewContent.id, | 78 | id: dataViewContent.id, |
79 | - content: JSON.stringify(chartEditStore.getStorageInfo) | 79 | + content: JSON.stringify(chartEditStore.getStorageInfo()) |
80 | } | 80 | } |
81 | } as unknown as BaseUpdateContentParams | 81 | } as unknown as BaseUpdateContentParams |
82 | await contentUpdateApi(saveContent) | 82 | await contentUpdateApi(saveContent) |
@@ -92,7 +92,7 @@ export const useSyncRemote = () => { | @@ -92,7 +92,7 @@ export const useSyncRemote = () => { | ||
92 | const saveContent = { | 92 | const saveContent = { |
93 | dataViewContent: { | 93 | dataViewContent: { |
94 | id: dataViewContent.id, | 94 | id: dataViewContent.id, |
95 | - content: JSONStringify(chartEditStore.getStorageInfo || {}) | 95 | + content: JSONStringify(chartEditStore.getStorageInfo() || {}) |
96 | }, | 96 | }, |
97 | dataViewName, | 97 | dataViewName, |
98 | dataViewId | 98 | dataViewId |
1 | <template> | 1 | <template> |
2 | <div | 2 | <div |
3 | - class="chart-item" | ||
4 | - v-for="item in groupData.groupList" | ||
5 | - :class="animationsClass(item.styles.animations)" | ||
6 | - :key="item.id" | 3 | + :class="animationsClass(groupData.styles.animations)" |
7 | :style="{ | 4 | :style="{ |
8 | - ...getComponentAttrStyle(item.attr, groupIndex), | ||
9 | - ...getFilterStyle(item.styles), | ||
10 | - ...getTransformStyle(item.styles), | ||
11 | - ...getStatusStyle(item.status), | ||
12 | - ...getPreviewConfigStyle(item.preview), | ||
13 | - ...getBlendModeStyle(item.styles) as any | 5 | + ...getSizeStyle(groupData.attr), |
6 | + ...getFilterStyle(groupData.styles), | ||
14 | }" | 7 | }" |
15 | > | 8 | > |
9 | + <div | ||
10 | + class="chart-item" | ||
11 | + v-for="item in groupData.groupList" | ||
12 | + :class="animationsClass(item.styles.animations)" | ||
13 | + :key="item.id" | ||
14 | + :style="{ | ||
15 | + ...getComponentAttrStyle(item.attr, groupIndex), | ||
16 | + ...getStatusStyle(item.status), | ||
17 | + ...getPreviewConfigStyle(item.preview), | ||
18 | + ...getBlendModeStyle(item.styles) as any | ||
19 | + }" | ||
20 | + > | ||
16 | <component | 21 | <component |
17 | :is="item.chartConfig.chartKey" | 22 | :is="item.chartConfig.chartKey" |
18 | :id="item.id" | 23 | :id="item.id" |
19 | :chartConfig="item" | 24 | :chartConfig="item" |
20 | :themeSetting="themeSetting" | 25 | :themeSetting="themeSetting" |
21 | :themeColor="themeColor" | 26 | :themeColor="themeColor" |
22 | - :style="{ ...getSizeStyle(item.attr) }" | ||
23 | - v-on="useLifeHandler(item)" | ||
24 | - ></component> | 27 | + :style="{ |
28 | + ...getSizeStyle(item.attr), | ||
29 | + ...getFilterStyle(item.styles), | ||
30 | + ...getTransformStyle(item.styles) | ||
31 | + }" | ||
32 | + v-on="useLifeHandler(item)" | ||
33 | + ></component> | ||
34 | + </div> | ||
25 | </div> | 35 | </div> |
26 | </template> | 36 | </template> |
27 | 37 |
@@ -6,7 +6,6 @@ | @@ -6,7 +6,6 @@ | ||
6 | :key="item.id" | 6 | :key="item.id" |
7 | :style="{ | 7 | :style="{ |
8 | ...getComponentAttrStyle(item.attr, index), | 8 | ...getComponentAttrStyle(item.attr, index), |
9 | - ...getFilterStyle(item.styles), | ||
10 | ...getTransformStyle(item.styles), | 9 | ...getTransformStyle(item.styles), |
11 | ...getStatusStyle(item.status), | 10 | ...getStatusStyle(item.status), |
12 | ...getPreviewConfigStyle(item.preview), | 11 | ...getPreviewConfigStyle(item.preview), |
@@ -31,7 +30,10 @@ | @@ -31,7 +30,10 @@ | ||
31 | :chartConfig="item" | 30 | :chartConfig="item" |
32 | :themeSetting="themeSetting" | 31 | :themeSetting="themeSetting" |
33 | :themeColor="themeColor" | 32 | :themeColor="themeColor" |
34 | - :style="{ ...getSizeStyle(item.attr) }" | 33 | + :style="{ |
34 | + ...getSizeStyle(item.attr), | ||
35 | + ...getFilterStyle(item.styles) | ||
36 | + }" | ||
35 | v-on="useLifeHandler(item)" | 37 | v-on="useLifeHandler(item)" |
36 | ></component> | 38 | ></component> |
37 | </div> | 39 | </div> |
@@ -33,7 +33,7 @@ import { getFilterStyle, setTitle } from '@/utils' | @@ -33,7 +33,7 @@ import { getFilterStyle, setTitle } from '@/utils' | ||
33 | 33 | ||
34 | // THINGS_KIT 重写预览逻辑,调用接口 | 34 | // THINGS_KIT 重写预览逻辑,调用接口 |
35 | import { dragCanvas } from './utils' | 35 | import { dragCanvas } from './utils' |
36 | -import { getEditCanvasConfigStyle,keyRecordHandle } from './utils' | 36 | +import { getEditCanvasConfigStyle, keyRecordHandle } from './utils' |
37 | import { getSessionStorageInfo } from './external/usePreview' | 37 | import { getSessionStorageInfo } from './external/usePreview' |
38 | 38 | ||
39 | import { useComInstall } from './hooks/useComInstall.hook' | 39 | import { useComInstall } from './hooks/useComInstall.hook' |
@@ -52,6 +52,7 @@ setTitle(`预览-${chartEditStore.editCanvasConfig.projectName}`) | @@ -52,6 +52,7 @@ setTitle(`预览-${chartEditStore.editCanvasConfig.projectName}`) | ||
52 | 52 | ||
53 | const previewRefStyle = computed(() => { | 53 | const previewRefStyle = computed(() => { |
54 | return { | 54 | return { |
55 | + overflow: 'hidden', | ||
55 | ...getEditCanvasConfigStyle(chartEditStore.editCanvasConfig), | 56 | ...getEditCanvasConfigStyle(chartEditStore.editCanvasConfig), |
56 | ...getFilterStyle(chartEditStore.editCanvasConfig) | 57 | ...getFilterStyle(chartEditStore.editCanvasConfig) |
57 | } | 58 | } |
@@ -15,7 +15,7 @@ let key = ref(Date.now()) | @@ -15,7 +15,7 @@ let key = ref(Date.now()) | ||
15 | 15 | ||
16 | // 数据变更 -> 组件销毁重建 | 16 | // 数据变更 -> 组件销毁重建 |
17 | ;[SavePageEnum.JSON, SavePageEnum.CHART_TO_PREVIEW].forEach((saveEvent: string) => { | 17 | ;[SavePageEnum.JSON, SavePageEnum.CHART_TO_PREVIEW].forEach((saveEvent: string) => { |
18 | - if (!window.opener) return | 18 | + if (!window.opener && !window.opener.addEventListener) return |
19 | window.opener.addEventListener(saveEvent, async (e: any) => { | 19 | window.opener.addEventListener(saveEvent, async (e: any) => { |
20 | const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType | 20 | const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType |
21 | setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, [{ ...e.detail, id: localStorageInfo.id }]) | 21 | setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, [{ ...e.detail, id: localStorageInfo.id }]) |