Commit e268d6d0c39f5f384600e630570b00b43c5dd108

Authored by xp.Huang
2 parents f1960079 dd543698

Merge branch 'ft' into 'main_dev'

feat(src/packages): 优化三维模型拖动时,webgl上下文丢失问题

See merge request yunteng/thingskit-view!134
Showing 24 changed files with 193 additions and 176 deletions
@@ -111,7 +111,7 @@ export const getVideoUrl = (id: string) => @@ -111,7 +111,7 @@ export const getVideoUrl = (id: string) =>
111 }) 111 })
112 112
113 //获取行政区域 113 //获取行政区域
114 -export const getGeoJsonMap = (code: number, level: string) => 114 +export const getGeoJsonMap = (code: number | string, level: string) =>
115 defHttp.get({ 115 defHttp.get({
116 url: `${Api.GEOJSONURL}${code}/${level}` 116 url: `${Api.GEOJSONURL}${code}/${level}`
117 }) 117 })
@@ -14,6 +14,26 @@ export const enum areaEnum { @@ -14,6 +14,26 @@ export const enum areaEnum {
14 TOWN = 'TOWN' //镇 14 TOWN = 'TOWN' //镇
15 } 15 }
16 16
  17 +//父级地区编码和级别接口
  18 +export interface HistoryParentType {
  19 + adcode: string | number
  20 + level: string
  21 +}
  22 +
  23 +//数据源接口
  24 +export interface dataPointI {
  25 + name: string
  26 + value: number[]
  27 + adcode: number
  28 + height: number
  29 + itemStyle: {
  30 + color: string
  31 + opacity: number
  32 + borderWidth: number
  33 + borderColor: string
  34 + }
  35 +}
  36 +
17 export const includes = [] 37 export const includes = []
18 38
19 export const option = { 39 export const option = {
@@ -41,6 +61,9 @@ export const option = { @@ -41,6 +61,9 @@ export const option = {
41 emphasis: { 61 emphasis: {
42 label: { 62 label: {
43 show: true, 63 show: true,
  64 + formatter: function (params: Recordable) {
  65 + return params.data.name ? params.data.name : ' '
  66 + },
44 textStyle: { 67 textStyle: {
45 color: '#000', 68 color: '#000',
46 fontSize: 14 69 fontSize: 14
@@ -59,6 +82,9 @@ export const option = { @@ -59,6 +82,9 @@ export const option = {
59 regionHeight: 3, 82 regionHeight: 3,
60 label: { 83 label: {
61 show: true, 84 show: true,
  85 + formatter: function (params: Recordable) {
  86 + return params.data.name ? params.data.name : ' '
  87 + },
62 textStyle: { 88 textStyle: {
63 color: '#fff', 89 color: '#fff',
64 fontSize: 14 90 fontSize: 14
@@ -12,7 +12,7 @@ import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue @@ -12,7 +12,7 @@ import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue
12 import * as echarts from 'echarts' 12 import * as echarts from 'echarts'
13 import { registerMap } from 'echarts/core' 13 import { registerMap } from 'echarts/core'
14 import 'echarts-gl' 14 import 'echarts-gl'
15 -import config, { areaEnum } from './config' 15 +import config, { areaEnum, dataPointI, HistoryParentType } from './config'
16 import { getGeoJsonMap } from '@/api/external/common' 16 import { getGeoJsonMap } from '@/api/external/common'
17 import dataMaps from './data.json' 17 import dataMaps from './data.json'
18 18
@@ -73,28 +73,26 @@ props.chartConfig.option = { @@ -73,28 +73,26 @@ props.chartConfig.option = {
73 73
74 //地图点击返回 74 //地图点击返回
75 const watchAdcode = async () => { 75 const watchAdcode = async () => {
  76 + stopWatch()
76 if (props.chartConfig.option.drillingIn) { 77 if (props.chartConfig.option.drillingIn) {
77 //如果是从右边配置里设置的,比如点击四川省,然后点击返回 78 //如果是从右边配置里设置的,比如点击四川省,然后点击返回
78 const savePopParent = saveHistoryParent.value.pop() 79 const savePopParent = saveHistoryParent.value.pop()
79 - let saveAdcode: any = savePopParent?.adcode  
80 - saveLevelStr.level = savePopParent?.level as string 80 + let saveAdcode = savePopParent?.adcode as string | number
  81 + saveLevelStr.level = savePopParent?.level
81 if (!savePopParent) { 82 if (!savePopParent) {
82 saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode) 83 saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode)
83 - saveLevelStr.level = (regionMapParentArea as any)[props.chartConfig.option.mapRegion.saveSelect.levelStr] 84 + saveLevelStr.level = (regionMapParentArea as Recordable)[props.chartConfig.option.mapRegion.saveSelect.levelStr]
84 } 85 }
85 if (saveAdcode === 0) { 86 if (saveAdcode === 0) {
86 saveAdcode = 'china' 87 saveAdcode = 'china'
87 saveLevelStr.level = 'COUNTRY' 88 saveLevelStr.level = 'COUNTRY'
88 } 89 }
89 - await getGeojson(saveAdcode) 90 + const exist = await getGeojson(saveAdcode)
90 const adcode = saveAdcode === 100000 ? 'china' : saveAdcode 91 const adcode = saveAdcode === 100000 ? 'china' : saveAdcode
91 - props.chartConfig.option.geo3D.map = adcode  
92 - props.chartConfig.option.series.forEach((item: any) => {  
93 - if (item.type === 'map3D') item.map = adcode  
94 - item.data = props.chartConfig.option.dataset  
95 - })  
96 - handleSetOption(chartInstance.value, props.chartConfig.option)  
97 - handleDataPoint(adcode) 92 + if (exist) {
  93 + //fix解决点击下钻返回后页面为空问题
  94 + props.chartConfig.option.mapRegion.adcode = adcode
  95 + }
98 } 96 }
99 } 97 }
100 98
@@ -106,46 +104,40 @@ const regionMapParentArea = { @@ -106,46 +104,40 @@ const regionMapParentArea = {
106 } 104 }
107 105
108 //地图点击 106 //地图点击
109 -const handleMap3DClick = async (params: any) => { 107 +const handleMap3DClick = async (params: Recordable) => {
110 if (props.chartConfig.option.drillingIn) { 108 if (props.chartConfig.option.drillingIn) {
111 const { name } = params 109 const { name } = params
112 - saveGeojson.value?.features.forEach((item: any) => { 110 + saveGeojson.value?.features.forEach((item: Recordable) => {
113 if (item.properties.name === name) { 111 if (item.properties.name === name) {
114 const level = item.properties.level.toUpperCase() 112 const level = item.properties.level.toUpperCase()
115 const adcode = item.properties.adcode 113 const adcode = item.properties.adcode
116 if (level === 'DISTRICT') return 114 if (level === 'DISTRICT') return
117 - if(String(adcode).startsWith('15') && level===areaEnum.CITY) return 115 + if (String(adcode).startsWith('15') && level === areaEnum.CITY) return
118 props.chartConfig.option.mapRegion.adcode = adcode 116 props.chartConfig.option.mapRegion.adcode = adcode
119 saveLevelStr.level = level 117 saveLevelStr.level = level
120 handleDataPoint(adcode) 118 handleDataPoint(adcode)
121 saveHistoryParent.value.push({ 119 saveHistoryParent.value.push({
122 adcode: item.properties.parent.adcode, 120 adcode: item.properties.parent.adcode,
123 - level: (regionMapParentArea as any)[level] 121 + level: (regionMapParentArea as Recordable)[level]
124 }) 122 })
125 } 123 }
126 }) 124 })
127 } 125 }
128 } 126 }
129 127
130 -const saveGeojson: any = ref({}) // 保存geojson 128 +const saveGeojson: Recordable = ref({}) // 保存geojson
131 129
132 const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000 130 const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000
133 131
134 -const saveLevelStr = reactive({  
135 - // 地区级别  
136 - level: '' 132 +// 保存地区级别
  133 +const saveLevelStr = reactive<{ level: string | undefined }>({
  134 + level: ''
137 }) 135 })
138 136
139 -//父级地区编码和级别接口  
140 -interface HistoryParentType {  
141 - adcode: number  
142 - level: string  
143 -}  
144 -  
145 const saveHistoryParent = ref<HistoryParentType[]>([]) 137 const saveHistoryParent = ref<HistoryParentType[]>([])
146 138
147 //动态注册地图 139 //动态注册地图
148 -const getGeojson = (regionId: any) => { 140 +const getGeojson = (regionId: number | string) => {
149 try { 141 try {
150 return new Promise<boolean>(resolve => { 142 return new Promise<boolean>(resolve => {
151 const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别 143 const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
@@ -171,11 +163,10 @@ const getGeojson = (regionId: any) => { @@ -171,11 +163,10 @@ const getGeojson = (regionId: any) => {
171 } 163 }
172 } 164 }
173 165
174 -  
175 //传adcode 获取上级 166 //传adcode 获取上级
176 const getParentAdcode = (adcode: number) => { 167 const getParentAdcode = (adcode: number) => {
177 let adcodeNum = 100000 168 let adcodeNum = 100000
178 - saveGeojson.value?.features.forEach((item: any) => { 169 + saveGeojson.value?.features.forEach((item: Recordable) => {
179 if (item.properties.adcode === adcode) { 170 if (item.properties.adcode === adcode) {
180 adcodeNum = item.properties.parent.adcode 171 adcodeNum = item.properties.parent.adcode
181 } 172 }
@@ -200,13 +191,13 @@ const initMap = async () => { @@ -200,13 +191,13 @@ const initMap = async () => {
200 await nextTick().then(() => { 191 await nextTick().then(() => {
201 handleSetOption(chartInstance.value, props.chartConfig.option) 192 handleSetOption(chartInstance.value, props.chartConfig.option)
202 }) 193 })
203 - chartInstance.value.on('click', (e: any) => { 194 + chartInstance.value.on('click', (e: Recordable) => {
204 handleMap3DClick(e) 195 handleMap3DClick(e)
205 }) 196 })
206 } 197 }
207 198
208 // 手动触发渲染 199 // 手动触发渲染
209 -const handleSetOption = (instance: any, option: any) => { 200 +const handleSetOption = (instance: any, option: Recordable) => {
210 if (!instance) return 201 if (!instance) return
211 try { 202 try {
212 instance.clear() 203 instance.clear()
@@ -221,22 +212,22 @@ onMounted(() => { @@ -221,22 +212,22 @@ onMounted(() => {
221 }) 212 })
222 213
223 //处理数据标点 214 //处理数据标点
224 -const handleDataPoint = (newData: any) => { 215 +const handleDataPoint = (newData: string | number) => {
225 if (newData === 'china') { 216 if (newData === 'china') {
226 props.chartConfig.option.dataset = dataMaps 217 props.chartConfig.option.dataset = dataMaps
227 } else { 218 } else {
228 - props.chartConfig.option.dataset = dataMaps.filter((item: any) => item.adcode === newData) 219 + props.chartConfig.option.dataset = dataMaps.filter((item: dataPointI) => item.adcode === newData)
229 } 220 }
230 } 221 }
231 222
232 //监听地图展示区域发生变化 223 //监听地图展示区域发生变化
233 watch( 224 watch(
234 () => `${props.chartConfig.option.mapRegion.adcode}`, 225 () => `${props.chartConfig.option.mapRegion.adcode}`,
235 - async (newData: any) => { 226 + async (newData: string | number) => {
236 try { 227 try {
237 await getGeojson(newData) 228 await getGeojson(newData)
238 props.chartConfig.option.geo3D.map = newData 229 props.chartConfig.option.geo3D.map = newData
239 - props.chartConfig.option.series.forEach((item: any) => { 230 + props.chartConfig.option.series.forEach((item: Recordable) => {
240 if (item.type === 'map3D') { 231 if (item.type === 'map3D') {
241 item.map = newData 232 item.map = newData
242 item.data = props.chartConfig.option.dataset 233 item.data = props.chartConfig.option.dataset
@@ -254,7 +245,7 @@ watch( @@ -254,7 +245,7 @@ watch(
254 ) 245 )
255 246
256 // 监听地图右侧配置项变化 247 // 监听地图右侧配置项变化
257 -watch( 248 +const stopWatch = watch(
258 props.chartConfig.option, 249 props.chartConfig.option,
259 async newData => { 250 async newData => {
260 try { 251 try {
@@ -273,7 +264,7 @@ watch( @@ -273,7 +264,7 @@ watch(
273 () => props.chartConfig.option.dataset, 264 () => props.chartConfig.option.dataset,
274 newData => { 265 newData => {
275 try { 266 try {
276 - props.chartConfig.option.series.forEach((item: any) => { 267 + props.chartConfig.option.series.forEach((item: Recordable) => {
277 if (item.type === 'map3D') { 268 if (item.type === 'map3D') {
278 item.data = newData 269 item.data = newData
279 } 270 }
@@ -129,7 +129,7 @@ const loadList = async () => { @@ -129,7 +129,7 @@ const loadList = async () => {
129 } 129 }
130 130
131 const handleSubmit = () => { 131 const handleSubmit = () => {
132 - searchParams.deviceProfileIds = [searchParams.deviceProfileIds] as any 132 + // searchParams.deviceProfileIds = [searchParams.deviceProfileIds] as any
133 emit('searchParams', searchPage, searchParams) 133 emit('searchParams', searchPage, searchParams)
134 handleCancel() 134 handleCancel()
135 } 135 }
@@ -88,10 +88,11 @@ export const option = { @@ -88,10 +88,11 @@ export const option = {
88 amapLon: 104.108689, 88 amapLon: 104.108689,
89 amapLat: 30.66176, 89 amapLat: 30.66176,
90 amapZindex: 11, 90 amapZindex: 11,
91 - typeMarker: '', 91 + iconMarker: '1.png',
92 mpBorderConfig: { 92 mpBorderConfig: {
93 - value: 'Border01', 93 + value: 'Border01'
94 }, 94 },
  95 + bgColor: 'rgba(255, 255, 255, 0.1)',
95 marker: { 96 marker: {
96 fillColor: '#E98984FF', 97 fillColor: '#E98984FF',
97 fillOpacity: 0.5, 98 fillOpacity: 0.5,
@@ -81,8 +81,8 @@ @@ -81,8 +81,8 @@
81 size="small" 81 size="small"
82 placeholder="请选择您要使用的图标" 82 placeholder="请选择您要使用的图标"
83 style="width: 250px" 83 style="width: 250px"
84 - :value="typeMarkerValue"  
85 - :options="typeMarkerOptions" 84 + :value="iconMarkerValue"
  85 + :options="iconMarkerOptions"
86 :render-label="renderOption" 86 :render-label="renderOption"
87 clearable 87 clearable
88 filterable 88 filterable
@@ -92,16 +92,6 @@ @@ -92,16 +92,6 @@
92 </setting-item-box> 92 </setting-item-box>
93 <setting-item-box name="弹窗选择" v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.MARKER"> 93 <setting-item-box name="弹窗选择" v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.MARKER">
94 <setting-item name="弹窗选择"> 94 <setting-item name="弹窗选择">
95 - <!-- <NSelect  
96 - size="small"  
97 - placeholder="请选择您要使用的弹窗"  
98 - style="width: 250px"  
99 - :value="mapSelectBorderValue"  
100 - :options="mapSelectBorderOption.option"  
101 - @update:value="mapSelectBorderHandle"  
102 - clearable  
103 - filterable  
104 - /> -->  
105 <NSelect 95 <NSelect
106 size="small" 96 size="small"
107 placeholder="请选择您要使用的弹窗" 97 placeholder="请选择您要使用的弹窗"
@@ -115,11 +105,16 @@ @@ -115,11 +105,16 @@
115 /> 105 />
116 </setting-item> 106 </setting-item>
117 </setting-item-box> 107 </setting-item-box>
  108 + <setting-item-box name="弹窗背景" v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.MARKER">
  109 + <div style="width: 10vw">
  110 + <n-color-picker :modes="['rgb']" v-model:value="optionData.mapOptions.bgColor" size="small"></n-color-picker>
  111 + </div>
  112 + </setting-item-box>
118 </collapse-item> 113 </collapse-item>
119 </template> 114 </template>
120 115
121 <script setup lang="ts"> 116 <script setup lang="ts">
122 -import { PropType, ref, computed, h, onMounted, reactive } from 'vue' 117 +import { PropType, ref, computed, h, onMounted } from 'vue'
123 import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config' 118 import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config'
124 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' 119 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
125 import { NEllipsis, NImage, NSelect, NSpace, SelectOption } from 'naive-ui' 120 import { NEllipsis, NImage, NSelect, NSpace, SelectOption } from 'naive-ui'
@@ -234,7 +229,7 @@ const featuresOptions = [ @@ -234,7 +229,7 @@ const featuresOptions = [
234 const MarkerOptions = [ 229 const MarkerOptions = [
235 // { 230 // {
236 // value: MarkerEnum.CIRCLE_MARKER, 231 // value: MarkerEnum.CIRCLE_MARKER,
237 - // label: '圆形标点' 232 + // label: '圆形标点' //在地图里点击无效,所以注释,有需要自行打开即可
238 // }, 233 // },
239 { 234 {
240 value: MarkerEnum.MARKER, 235 value: MarkerEnum.MARKER,
@@ -246,17 +241,7 @@ const MarkerOptions = [ @@ -246,17 +241,7 @@ const MarkerOptions = [
246 } 241 }
247 ] 242 ]
248 243
249 -onMounted(() => {  
250 - props.optionData.mapOptions.typeMarker = getMarkerImagePath(props.optionData.mapOptions.typeMarker || 'position1.png')  
251 - typeMarkerValue.value = props.optionData.mapOptions.typeMarker || 'position1.png'  
252 - mapSelectBorderValue.value =  
253 - `${props.optionData.mapOptions.mpBorderConfig.value.toLocaleLowerCase()}.png` || 'border01.png'  
254 -})  
255 -  
256 -const typeMarkerValue = ref<string | null>('position1.png')  
257 -  
258 -const mapSelectBorderValue = ref<string | null>('border01.png')  
259 - 244 +/**通用函数封装 */
260 const isHref = (url: string) => { 245 const isHref = (url: string) => {
261 try { 246 try {
262 new URL(url) 247 new URL(url)
@@ -265,81 +250,86 @@ const isHref = (url: string) => { @@ -265,81 +250,86 @@ const isHref = (url: string) => {
265 return false 250 return false
266 } 251 }
267 } 252 }
  253 +const renderCommonOption = (option: SelectOption, src: string) => {
  254 + return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [
  255 + h(NImage, {
  256 + width: 25,
  257 + src,
  258 + previewDisabled: true,
  259 + style: { height: '25px' }
  260 + } as Recordable),
  261 + h(NEllipsis, null, () => option.label)
  262 + ])
  263 +}
  264 +const getImagePath = (path: string, name: string) => {
  265 + return isHref(name) ? name : new URL(`${path}/${name}`, import.meta.url).href
  266 +}
  267 +/** */
  268 +
  269 +/** 图标选择 */
  270 +const iconMarkerValue = ref<string | null>('1.png')
268 271
269 -// import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去  
270 -const typeMarkerOptions = computed(() => { 272 +// import.meta.glob 这里没有封装,不能通过传值传进去
  273 +const iconMarkerOptions = computed(() => {
271 const pathList = import.meta.glob('./images/marker/*') 274 const pathList = import.meta.glob('./images/marker/*')
272 return Object.keys(pathList).map(item => { 275 return Object.keys(pathList).map(item => {
273 const imgName = item.split('/').at(-1) 276 const imgName = item.split('/').at(-1)
274 return { 277 return {
275 label: imgName, 278 label: imgName,
276 value: imgName 279 value: imgName
277 - } as SelectOption 280 + }
278 }) 281 })
279 }) 282 })
280 // 283 //
281 284
282 -const getMarkerImagePath = (name: string) => {  
283 - return isHref(name) ? name : new URL(`./images/marker/${name}`, import.meta.url).href  
284 -} 285 +const getMarkerImagePath = (name: string) => getImagePath('./images/marker', name)
285 286
286 -const renderOption = (option: SelectOption) => {  
287 - return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [  
288 - h(NImage, {  
289 - width: 25,  
290 - src: getMarkerImagePath(option.value as string),  
291 - previewDisabled: true,  
292 - style: { height: '25px' }  
293 - } as Recordable),  
294 - h(NEllipsis, null, () => option.label)  
295 - ])  
296 -} 287 +const renderOption = (option: SelectOption) => renderCommonOption(option, getMarkerImagePath(option.value as string))
297 288
298 const selectHandle = (value: string) => { 289 const selectHandle = (value: string) => {
299 - typeMarkerValue.value = value  
300 - props.optionData.mapOptions.typeMarker = getMarkerImagePath(value) 290 + iconMarkerValue.value = value
  291 + props.optionData.mapOptions.iconMarker = getMarkerImagePath(value)
301 } 292 }
  293 +/** */
  294 +
  295 +/** 弹窗选择 */
  296 +const mapSelectBorderValue = ref<string | null>('border01.png')
302 297
303 const needBorder = ['border01.png', 'border02.png', 'border03.png', 'border05.png', 'border07.png'] 298 const needBorder = ['border01.png', 'border02.png', 'border03.png', 'border05.png', 'border07.png']
304 299
305 -// import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去 300 +// import.meta.glob 这里没有封装,不能通过传值传进去
306 const mapBorderOptions = computed(() => { 301 const mapBorderOptions = computed(() => {
307 const pathList = import.meta.glob('../../../../../../assets/images/chart/decorates/*') 302 const pathList = import.meta.glob('../../../../../../assets/images/chart/decorates/*')
308 return Object.keys(pathList) 303 return Object.keys(pathList)
309 .map(item => { 304 .map(item => {
310 const imgName = item.split('/').at(-1) as string 305 const imgName = item.split('/').at(-1) as string
311 - if (needBorder.includes(imgName)) {  
312 - return {  
313 - label: imgName,  
314 - value: imgName  
315 - } as SelectOption  
316 - } 306 + if (!needBorder.includes(imgName)) return
  307 + return {
  308 + label: imgName,
  309 + value: imgName
  310 + } as SelectOption
317 }) 311 })
318 .filter(Boolean) as SelectOption[] 312 .filter(Boolean) as SelectOption[]
319 }) 313 })
320 // 314 //
321 315
322 -const getMapBorderImagePath = (name: string) => {  
323 - return isHref(name) ? name : new URL(`../../../../../../assets/images/chart/decorates/${name}`, import.meta.url).href  
324 -} 316 +const getMapBorderImagePath = (name: string) => getImagePath('../../../../../../assets/images/chart/decorates', name)
325 317
326 -const renderMapBorderOption = (option: SelectOption) => {  
327 - return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [  
328 - h(NImage, {  
329 - width: 25,  
330 - src: getMapBorderImagePath(option.value as string),  
331 - previewDisabled: true,  
332 - style: { height: '25px' }  
333 - } as Recordable),  
334 - h(NEllipsis, null, () => option.label)  
335 - ])  
336 -} 318 +const renderMapBorderOption = (option: SelectOption) =>
  319 + renderCommonOption(option, getMapBorderImagePath(option.value as string))
337 320
338 const selectMapBorderHandle = (value: string) => { 321 const selectMapBorderHandle = (value: string) => {
339 mapSelectBorderValue.value = value 322 mapSelectBorderValue.value = value
340 const toLowerValue = value.toLocaleLowerCase() 323 const toLowerValue = value.toLocaleLowerCase()
341 ;(props.optionData.mapOptions.mpBorderConfig as BaseSelectBorderIF) = { 324 ;(props.optionData.mapOptions.mpBorderConfig as BaseSelectBorderIF) = {
342 - value: toLowerValue[0]?.toUpperCase() + toLowerValue?.substr(1)?.split('.')[0]  
343 - } 325 + value: toLowerValue[0]?.toUpperCase() + toLowerValue?.substring(1)?.split('.')[0]
  326 + } //这里首字母转大写,动态引入时匹配对应目录也是大写字母开头,即components\Decorates\Borders\Border01
344 } 327 }
  328 +/** */
  329 +
  330 +onMounted(() => {
  331 + iconMarkerValue.value = props.optionData.mapOptions.iconMarker?.split('/')?.at(-1) as string
  332 + props.optionData.mapOptions.iconMarker = getMarkerImagePath(iconMarkerValue.value)
  333 + mapSelectBorderValue.value = `${props.optionData.mapOptions.mpBorderConfig.value?.toLocaleLowerCase()}.png`
  334 +})
345 </script> 335 </script>
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/1.png renamed from src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position1.png

1.24 KB

src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/2.png renamed from src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position2.png

1.4 KB

src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/3.png renamed from src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position3.png

904 Bytes

src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/4.png renamed from src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position4.png

1.02 KB

src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/5.png renamed from src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position5.png

970 Bytes

1 <template> 1 <template>
2 <div @mouseenter="handleMouseenter" @mouseleave="handleMouseleave" class="chart-amap" ref="vChartRef"> 2 <div @mouseenter="handleMouseenter" @mouseleave="handleMouseleave" class="chart-amap" ref="vChartRef">
3 - <div v-show="showSearchBox" @click.stop="handleOpenSearchBox" class="search-box"></div>  
4 - <search-box :modelShow="modelShow" @searchParams="handleSearchParams" @closeDrawer="handleCloseDrawer"></search-box> 3 + <!-- <div v-show="showSearchBox" @click.stop="handleOpenSearchBox" class="search-box"></div>
  4 + <search-box :modelShow="modelShow" @searchParams="handleSearchParams" @closeDrawer="handleCloseDrawer"></search-box> -->
5 </div> 5 </div>
6 </template> 6 </template>
7 7
@@ -16,7 +16,7 @@ import { isArray } from '@/utils' @@ -16,7 +16,7 @@ import { isArray } from '@/utils'
16 import djh from './images/djh.png' 16 import djh from './images/djh.png'
17 import online from './images/online.png' 17 import online from './images/online.png'
18 import lx1 from './images/lx1.png' 18 import lx1 from './images/lx1.png'
19 -import positionImg from './images/marker/position1.png' 19 +import onLineImg from './images/marker/3.png'
20 import { getDeviceActiveTime, getDeviceList } from '@/api/external/common/index' 20 import { getDeviceActiveTime, getDeviceList } from '@/api/external/common/index'
21 import dayjs from 'dayjs' 21 import dayjs from 'dayjs'
22 import SearchBox from './components/SearchBox.vue' 22 import SearchBox from './components/SearchBox.vue'
@@ -32,7 +32,7 @@ const modelShow = ref(false) @@ -32,7 +32,7 @@ const modelShow = ref(false)
32 32
33 const showSearchBox = ref(false) 33 const showSearchBox = ref(false)
34 34
35 -let { 35 +const {
36 amapKey, 36 amapKey,
37 amapStyleKey, 37 amapStyleKey,
38 amapLon, 38 amapLon,
@@ -46,8 +46,9 @@ let { @@ -46,8 +46,9 @@ let {
46 pitch, 46 pitch,
47 skyColor, 47 skyColor,
48 marker, 48 marker,
49 - typeMarker,  
50 - mpBorderConfig 49 + iconMarker,
  50 + mpBorderConfig,
  51 + bgColor
51 } = toRefs(props.chartConfig.option.mapOptions) 52 } = toRefs(props.chartConfig.option.mapOptions)
52 53
53 //官方没有高德地图api的ts,所以类型全用的any 54 //官方没有高德地图api的ts,所以类型全用的any
@@ -104,7 +105,7 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { @@ -104,7 +105,7 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => {
104 const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间 105 const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间
105 let { lastUpdateTs } = res[0] 106 let { lastUpdateTs } = res[0]
106 const lastUpdateFormatTs = dayjs(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss') 107 const lastUpdateFormatTs = dayjs(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss')
107 - //render方式渲染小组件里的边框组件 108 + //render方式渲染小组件里的边框组件
108 const BorderInstance = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/index.vue`) 109 const BorderInstance = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/index.vue`)
109 const config = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/config.ts`) 110 const config = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/config.ts`)
110 const BorderConfigInstance = new config.default() 111 const BorderConfigInstance = new config.default()
@@ -132,7 +133,7 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { @@ -132,7 +133,7 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => {
132 </div> 133 </div>
133 <div style="color:white;">所属组织:${organizationDTO.name}</div> 134 <div style="color:white;">所属组织:${organizationDTO.name}</div>
134 <div style="margin-top:6px;color:white">接入协议:${deviceProfile.transportType}</div> 135 <div style="margin-top:6px;color:white">接入协议:${deviceProfile.transportType}</div>
135 - <div style="margin-top:6px;color:white"> 136 + <div style="margin-top:6px;color:white;width:15vw;text-overflow: ellipsis;overflow: hidden; word-break: break-all;white-space: nowrap;">
136 设备位置:${!deviceInfo.address ? '该设备暂无地理位置' : deviceInfo.address} 137 设备位置:${!deviceInfo.address ? '该设备暂无地理位置' : deviceInfo.address}
137 </div> 138 </div>
138 <div style="margin-top:6px;color:white"> 139 <div style="margin-top:6px;color:white">
@@ -158,10 +159,15 @@ const handleCloseDrawer = () => (modelShow.value = false) @@ -158,10 +159,15 @@ const handleCloseDrawer = () => (modelShow.value = false)
158 159
159 const handleSearchParams = async (searchPage: any, params: any) => { 160 const handleSearchParams = async (searchPage: any, params: any) => {
160 try { 161 try {
  162 + Object.keys(params).forEach(item => {
  163 + if (!params[item]) Reflect.deleteProperty(params, item)
  164 + })
161 const { items } = await getDeviceList(searchPage, params) 165 const { items } = await getDeviceList(searchPage, params)
162 const values = filterDevice(items) 166 const values = filterDevice(items)
163 if (!values) return 167 if (!values) return
164 - dataHandle(values) 168 + setTimeout(() => {
  169 + dataHandle(values)
  170 + }, 1000)
165 } finally { 171 } finally {
166 handleCloseDrawer() 172 handleCloseDrawer()
167 } 173 }
@@ -198,10 +204,11 @@ const dataHandle = (newData: dataJsonType) => { @@ -198,10 +204,11 @@ const dataHandle = (newData: dataJsonType) => {
198 // 记录新标记 204 // 记录新标记
199 if (mapMarkerType.value === MarkerEnum.MARKER) { 205 if (mapMarkerType.value === MarkerEnum.MARKER) {
200 newData.markers.forEach((markerItem: dataJsonMarkersType) => { 206 newData.markers.forEach((markerItem: dataJsonMarkersType) => {
  207 + const { deviceState } = markerItem.extraInfo
201 const markerInstance = new AMapIns.Marker({ 208 const markerInstance = new AMapIns.Marker({
202 position: [markerItem.position[0], markerItem.position[1]], 209 position: [markerItem.position[0], markerItem.position[1]],
203 offset: new AMapIns.Pixel(-13, -30), 210 offset: new AMapIns.Pixel(-13, -30),
204 - icon: typeMarker.value || positionImg 211 + icon: deviceState === 'ONLINE' ? onLineImg : iconMarker.value
205 }) 212 })
206 // markers.push(markerInstance) 原作者这种方式添加,属于JS API 1.4.8版本的 213 // markers.push(markerInstance) 原作者这种方式添加,属于JS API 1.4.8版本的
207 // markerInstance.setMap(mapIns) 214 // markerInstance.setMap(mapIns)
@@ -255,7 +262,9 @@ watch( @@ -255,7 +262,9 @@ watch(
255 // 预览 262 // 预览
256 useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { 263 useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
257 stopWatch() 264 stopWatch()
258 - dataHandle(newData) 265 + setTimeout(() => {
  266 + dataHandle(newData)
  267 + }, 1000)
259 }) 268 })
260 </script> 269 </script>
261 270
@@ -271,15 +280,9 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { @@ -271,15 +280,9 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
271 } 280 }
272 .amap-info-content .go-border-box { 281 .amap-info-content .go-border-box {
273 position: absolute; 282 position: absolute;
274 - transform: scale(0.7); 283 + transform: scale(0.68);
275 top: -10px; 284 top: -10px;
276 - /* opacity: 0,8; */  
277 - /* background-color: rgba(0, 0, 0, 0.1); */  
278 - background-color:rgba(255,255,255,0.1)  
279 -}  
280 -.amap-info-content .go-border-box svg {  
281 - /* background-color: rgba(0, 0, 0, 0.1); */  
282 - /* background-color: rgba(255, 255, 255, 0.8); */ 285 + background-color: v-bind(bgColor);
283 } 286 }
284 </style> 287 </style>
285 <style lang="scss" scoped> 288 <style lang="scss" scoped>
@@ -5,7 +5,7 @@ import cloneDeep from 'lodash/cloneDeep' @@ -5,7 +5,7 @@ import cloneDeep from 'lodash/cloneDeep'
5 import { chartInitConfig } from '@/settings/designSetting' 5 import { chartInitConfig } from '@/settings/designSetting'
6 6
7 export const option = { 7 export const option = {
8 - dataset: [new URL('/src/assets/external/three/test.obj', import.meta.url).href],//三维数据源 8 + dataset: [new URL('/src/assets/external/three/test.obj', import.meta.url).href], //三维数据源
9 backgroundColor: '', //场景背景色 9 backgroundColor: '', //场景背景色
10 backgroundAlpha: 0, //场景透明度 10 backgroundAlpha: 0, //场景透明度
11 enableDamping: false, //是否启用阻尼 11 enableDamping: false, //是否启用阻尼
@@ -18,7 +18,9 @@ export const option = { @@ -18,7 +18,9 @@ export const option = {
18 */ 18 */
19 outputEncoding: 'liner', 19 outputEncoding: 'liner',
20 clearScene: false, //是否清空场景内容 20 clearScene: false, //是否清空场景内容
21 - lights: [//灯光为数组,type 为 环境光(AmbientLight) | 方向光(DirectionalLight) | 点光(PointLight) | 半球光(HemisphereLight) 21 + lightInput: 1,
  22 + lights: [
  23 + //灯光为数组,type 为 环境光(AmbientLight) | 方向光(DirectionalLight) | 点光(PointLight) | 半球光(HemisphereLight)
22 { 24 {
23 type: 'AmbientLight', 25 type: 'AmbientLight',
24 label: '环境光(只有颜色)', 26 label: '环境光(只有颜色)',
@@ -54,38 +56,41 @@ export const option = { @@ -54,38 +56,41 @@ export const option = {
54 size: 1, 56 size: 1,
55 show: false 57 show: false
56 }, 58 },
57 - position: [//模型位置 59 + position: [
  60 + //模型位置
58 { 61 {
59 x: 0, 62 x: 0,
60 y: 0, 63 y: 0,
61 z: 0 64 z: 0
62 } 65 }
63 ], 66 ],
64 - rotation: [//模型旋转 67 + rotation: [
  68 + //模型旋转
65 { 69 {
66 x: 0, 70 x: 0,
67 y: 0, 71 y: 0,
68 z: 0 72 z: 0
69 } 73 }
70 ], 74 ],
71 - showFps:false,//是否显示fps  
72 - labels:[ //添加图片/文字标签,暂且支持文字 75 + showFps: false, //是否显示fps
  76 + labels: [
  77 + //添加图片/文字标签,暂且支持文字
73 { 78 {
74 - image: "",  
75 - text: "", 79 + image: '',
  80 + text: '',
76 textStyle: { 81 textStyle: {
77 - fontFamily: "Arial", 82 + fontFamily: 'Arial',
78 fontSize: 18, 83 fontSize: 18,
79 - fontWeight: "normal", 84 + fontWeight: 'normal',
80 lineHeight: 1, 85 lineHeight: 1,
81 - color: "#ffffff", 86 + color: '#ffffff',
82 borderWidth: 8, 87 borderWidth: 8,
83 borderRadius: 4, 88 borderRadius: 4,
84 - borderColor: "rgba(0,0,0,1)",  
85 - backgroundColor: "rgba(0, 0, 0, 1)" 89 + borderColor: 'rgba(0,0,0,1)',
  90 + backgroundColor: 'rgba(0, 0, 0, 1)'
86 }, 91 },
87 - position: {x:0, y:0, z:0},  
88 - scale:{x:1, y:1, z:0}, 92 + position: { x: 0, y: 0, z: 0 },
  93 + scale: { x: 1, y: 1, z: 0 },
89 sid: null 94 sid: null
90 } 95 }
91 ] 96 ]
@@ -11,15 +11,15 @@ @@ -11,15 +11,15 @@
11 <n-input-number :min="0" v-model:value="optionData.borderConfig.size" size="small" /> 11 <n-input-number :min="0" v-model:value="optionData.borderConfig.size" size="small" />
12 </setting-item> 12 </setting-item>
13 </setting-item-box> 13 </setting-item-box>
14 - <setting-item-box name="上传文件"> 14 + <setting-item-box name="上传文件">
15 <setting-item> 15 <setting-item>
16 <FileUpload 16 <FileUpload
17 - :max="100"  
18 - :fileList="optionData.dataset"  
19 - :threeSupportFileFormat="threeSupportFileFormat"  
20 - :singleFileType="singleFileTypeNotMtl"  
21 - @fileStaticUri="handleFileStaticUri"  
22 - /> 17 + :max="100"
  18 + :fileList="optionData.dataset"
  19 + :threeSupportFileFormat="threeSupportFileFormat"
  20 + :singleFileType="singleFileTypeNotMtl"
  21 + @fileStaticUri="handleFileStaticUri"
  22 + />
23 </setting-item> 23 </setting-item>
24 </setting-item-box> 24 </setting-item-box>
25 <setting-item-box :alone="true"> 25 <setting-item-box :alone="true">
@@ -78,8 +78,13 @@ @@ -78,8 +78,13 @@
78 </template> 78 </template>
79 </setting-item> 79 </setting-item>
80 </setting-item-box> 80 </setting-item-box>
  81 + <setting-item-box name="灯光选择">
  82 + <setting-item name="灯光选择((0,环境光),(1,方向光),(2,点光),(3,半球光))">
  83 + <n-input-number :min="0" :max="3" v-model:value="optionData.lightInput" size="small" />
  84 + </setting-item>
  85 + </setting-item-box>
81 <setting-item-box name="灯光配置"> 86 <setting-item-box name="灯光配置">
82 - <setting-item v-for="(item, index) in optionData.lights" :name="item.label" :key="index"> 87 + <setting-item v-for="(item, index) in [optionData.lights[optionData.lightInput]]" :name="item.label" :key="index">
83 <n-color-picker 88 <n-color-picker
84 v-if="!includeHemisphereLight.includes(item.type)" 89 v-if="!includeHemisphereLight.includes(item.type)"
85 size="small" 90 size="small"
@@ -180,15 +185,9 @@ @@ -180,15 +185,9 @@
180 <SettingItem v-if="optionData.enableDamping" name="阻尼值"> 185 <SettingItem v-if="optionData.enableDamping" name="阻尼值">
181 <n-input-number v-model:value="optionData.dampingFactor" :min="0" :max="1" size="small"></n-input-number> 186 <n-input-number v-model:value="optionData.dampingFactor" :min="0" :max="1" size="small"></n-input-number>
182 </SettingItem> 187 </SettingItem>
183 - <SettingItem name="启用动画">  
184 - <n-switch v-model:value="optionData.autoPlay" size="small" />  
185 - </SettingItem>  
186 - <SettingItem name="输出编码"> 188 + <SettingItem name="输出编码,可取值为 liner 或 sRGB。linear 是 LinearEncoding 线性编码, sRGB 即 sRGBEncoding rgb 模式编码(sRGBEncoding 能更好的还原材质颜色)">
187 <n-select v-model:value="optionData.outputEncoding" size="small" :options="encodinghList"></n-select> 189 <n-select v-model:value="optionData.outputEncoding" size="small" :options="encodinghList"></n-select>
188 </SettingItem> 190 </SettingItem>
189 - <SettingItem name="是否清空场景">  
190 - <n-switch @change="handleChange" v-model:value="optionData.clearScene" size="small" />  
191 - </SettingItem>  
192 </setting-item-box> 191 </setting-item-box>
193 </collapse-item> 192 </collapse-item>
194 </template> 193 </template>
@@ -253,10 +252,6 @@ const encodinghList = [ @@ -253,10 +252,6 @@ const encodinghList = [
253 { label: 'sRGB ', value: 'sRGB ' } 252 { label: 'sRGB ', value: 'sRGB ' }
254 ] 253 ]
255 254
256 -const handleChange = (e: boolean) => {  
257 - if (e) props.optionData.dataset = ['']  
258 -}  
259 -  
260 const handleFileStaticUri = (value: UploadFileInfo[]) => { 255 const handleFileStaticUri = (value: UploadFileInfo[]) => {
261 props.optionData.dataset = value.map(item => item?.url)?.filter(Boolean) as any 256 props.optionData.dataset = value.map(item => item?.url)?.filter(Boolean) as any
262 if (Array.isArray(props.optionData.dataset) && props.optionData.dataset.length === 0) { 257 if (Array.isArray(props.optionData.dataset) && props.optionData.dataset.length === 0) {
1 <template> 1 <template>
2 - <div class="go-content-box" :style="{ border: !borderConfig.show ? 'none' : ''}">  
3 - <div v-if="useDetectWebGLContext()"> 2 + <div class="go-content-box" :style="{ border: !borderConfig.show ? 'none' : '' }">
  3 + <div>
4 <vue3dLoader 4 <vue3dLoader
5 ref="vue3dLoaderRef" 5 ref="vue3dLoaderRef"
6 :webGLRendererOptions="webGLRendererOptions" 6 :webGLRendererOptions="webGLRendererOptions"
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 @load="onLoad" 20 @load="onLoad"
21 :position="position" 21 :position="position"
22 :rotation="rotation" 22 :rotation="rotation"
23 - :lights="lights" 23 + :lights="[lights[lightInput]]"
24 :showFps="showFps" 24 :showFps="showFps"
25 :labels="labels" 25 :labels="labels"
26 /> 26 />
@@ -29,15 +29,13 @@ @@ -29,15 +29,13 @@
29 <n-progress type="line" :color="themeColor" :percentage="process" :indicator-placement="'inside'" processing /> 29 <n-progress type="line" :color="themeColor" :percentage="process" :indicator-placement="'inside'" processing />
30 </div> 30 </div>
31 </div> 31 </div>
32 - <div v-else>您的浏览器不支持WebGL!</div>  
33 </div> 32 </div>
34 </template> 33 </template>
35 <script setup lang="ts"> 34 <script setup lang="ts">
36 -import { PropType, toRefs, ref, nextTick, computed, watch } from 'vue' 35 +import { PropType, toRefs, ref, nextTick, computed } from 'vue'
37 import { CreateComponentType } from '@/packages/index.d' 36 import { CreateComponentType } from '@/packages/index.d'
38 import { vue3dLoader } from 'vue-3d-loader' 37 import { vue3dLoader } from 'vue-3d-loader'
39 import { useDesignStore } from '@/store/modules/designStore/designStore' 38 import { useDesignStore } from '@/store/modules/designStore/designStore'
40 -import { useDetectWebGLContext } from '@/utils/external/useSupportWebGL'  
41 39
42 const designStore = useDesignStore() 40 const designStore = useDesignStore()
43 41
@@ -54,7 +52,6 @@ const themeColor = computed(() => { @@ -54,7 +52,6 @@ const themeColor = computed(() => {
54 52
55 const vue3dLoaderRef = ref(null) 53 const vue3dLoaderRef = ref(null)
56 54
57 -//threejs配置  
58 const webGLRendererOptions = { 55 const webGLRendererOptions = {
59 alpha: true, // 透明 56 alpha: true, // 透明
60 antialias: true, // 抗锯齿 57 antialias: true, // 抗锯齿
@@ -96,13 +93,9 @@ const { @@ -96,13 +93,9 @@ const {
96 rotation, 93 rotation,
97 lights, 94 lights,
98 showFps, 95 showFps,
99 - labels  
100 -} = toRefs(props.chartConfig.option) as any  
101 -  
102 -watch(dataset, (newData: string) => {  
103 - //dateset为空则清除场景  
104 - if(!newData) clearScene.value=true  
105 -}) 96 + labels,
  97 + lightInput
  98 +} = toRefs(props.chartConfig.option) as any
106 </script> 99 </script>
107 100
108 <style lang="scss" scoped> 101 <style lang="scss" scoped>
1 <template> 1 <template>
2 <div> 2 <div>
3 <n-tree 3 <n-tree
  4 + ref="nTreeRef"
4 :accordion="treeConfig.accordion" 5 :accordion="treeConfig.accordion"
5 :checkable="treeConfig.checkable" 6 :checkable="treeConfig.checkable"
6 :default-expand-all="treeConfig.defaultExpandAll" 7 :default-expand-all="treeConfig.defaultExpandAll"
@@ -11,17 +12,20 @@ @@ -11,17 +12,20 @@
11 label-field="name" 12 label-field="name"
12 children-field="children" 13 children-field="children"
13 @update:selected-keys="onClick" 14 @update:selected-keys="onClick"
  15 + @update:checked-keys="onClick"
  16 + :checked-keys="checkedKeys"
14 /> 17 />
15 </div> 18 </div>
16 </template> 19 </template>
17 20
18 <script setup lang="ts"> 21 <script setup lang="ts">
19 -import { PropType, toRefs } from 'vue' 22 +import { PropType, toRefs, ref } from 'vue'
20 import { CreateComponentType } from '@/packages/index.d' 23 import { CreateComponentType } from '@/packages/index.d'
21 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 24 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
22 import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook' 25 import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook'
23 import { InteractEventOn } from '@/enums/eventEnum' 26 import { InteractEventOn } from '@/enums/eventEnum'
24 import { ComponentInteractParamsEnum } from './interact' 27 import { ComponentInteractParamsEnum } from './interact'
  28 +import { NTree } from 'naive-ui'
25 29
26 const props = defineProps({ 30 const props = defineProps({
27 chartConfig: { 31 chartConfig: {
@@ -32,7 +36,16 @@ const props = defineProps({ @@ -32,7 +36,16 @@ const props = defineProps({
32 36
33 const { dataset, treeConfig } = toRefs(props.chartConfig.option) 37 const { dataset, treeConfig } = toRefs(props.chartConfig.option)
34 38
  39 +const nTreeRef = ref<null | InstanceType<typeof NTree>>(null)
  40 +
  41 +const checkedKeys = ref([])
  42 +
35 const onClick = (v: string[]) => { 43 const onClick = (v: string[]) => {
  44 + // nTreeRef.value?.selectedKeys(v)
  45 + console.log(nTreeRef.value)
  46 + console.log(v)
  47 + // nTreeRef.value?.onUpdateCheckedKeys(v)
  48 + if (Array.isArray(v) && v.length == 0) return
36 useChartInteract( 49 useChartInteract(
37 props.chartConfig, 50 props.chartConfig,
38 useChartEditStore, 51 useChartEditStore,