feat: 地图组件新增飞行轨迹、下钻二级地图功能

This commit is contained in:
tanhao 2023-08-31 10:20:57 +08:00
parent 9865626d78
commit 7ae73e9c32
4 changed files with 215 additions and 16 deletions

View File

@ -11,7 +11,10 @@ export const option = {
dataset: dataJson,
mapRegion: {
adcode: 'china',
showHainanIsLands: true
enter: false,
showHainanIsLands: false,
backSize: 50,
backColor: '#ffffff'
},
tooltip: {
show: true,
@ -84,10 +87,7 @@ export const option = {
shadowColor: '#E1FFFF',
shadowBlur: 10
},
data: [],
encode: {
value: 2
}
data: []
},
{
name: '区域',
@ -148,6 +148,26 @@ export const option = {
shadowOffsetY: 2,
shadowBlur: 10
}
},
{
type: 'lines',
zlevel: 2,
effect: {
show: true,
period: 4, //箭头指向速度,值越小速度越快
trailLength: 0.4, //特效尾迹长度[0,1]值越大,尾迹越长重
symbol: 'arrow', //箭头图标
symbolSize: 7, //图标大小
},
lineStyle: {
normal: {
color:'#4fb6d2',
width: 1, //线条宽度
opacity: 0.1, //尾迹线条透明度
curveness: .3 //尾迹线条曲直度
}
},
data: []
}
]
}

View File

@ -1,7 +1,7 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem name="地图" :expanded="true">
<CollapseItem name="地图" :expanded="false">
<SettingItemBox name="地图区域">
<SettingItem name="默认中国">
<n-select
@ -180,9 +180,25 @@
<SettingItem>
<n-checkbox v-model:checked="mapRegion.showHainanIsLands" size="small">显示南海群岛</n-checkbox>
</SettingItem>
<SettingItem>
<n-checkbox v-model:checked="mapRegion.enter" size="small">点击进入下级</n-checkbox>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="返回图标" v-if="mapRegion.enter">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="mapRegion.backColor"></n-color-picker>
</SettingItem>
<SettingItem name="大小">
<n-input-number
v-model:value="mapRegion.backSize"
:min="1"
size="small"
placeholder="请输入字体大小"
></n-input-number>
</SettingItem>
</SettingItemBox>
</CollapseItem>
<CollapseItem name="标记" :expanded="true">
<CollapseItem name="标记" :expanded="false">
<SettingItemBox name="样式">
<SettingItem name="大小">
<n-input-number v-model:value="seriesList[0].symbolSize" size="small" :min="0"></n-input-number>
@ -223,6 +239,38 @@
</SettingItem>
</SettingItemBox>
</CollapseItem>
<CollapseItem name="线条" :expanded="true">
<SettingItemBox name="箭头">
<SettingItem name="速度">
<n-tooltip trigger="hover">
<template #trigger>
<n-input-number v-model:value="seriesList[2].effect.period" size="small" :min="0"></n-input-number>
</template>
值越小速度越快
</n-tooltip>
</SettingItem>
<SettingItem name="尾迹">
<n-tooltip trigger="hover">
<template #trigger>
<n-input-number v-model:value="seriesList[2].effect.trailLength" size="small" :min="0" :max="1"></n-input-number>
</template>
特效尾迹长度[0,1]值越大尾迹越长重
</n-tooltip>
</SettingItem>
<SettingItem name="大小">
<n-input-number v-model:value="seriesList[2].effect.symbolSize" size="small" :min="0"></n-input-number>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="配置">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[2].lineStyle.normal.color"></n-color-picker>
</SettingItem>
<SettingItem name="宽度">
<n-input-number v-model:value="seriesList[2].lineStyle.normal.width" size="small" :min="1"></n-input-number>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">

View File

@ -21,6 +21,56 @@
"value": [126.642464, 45.756967, 101]
}
],
"line": [
{
"coords": [
[
113.665412,
34.757975
],
[
116.405285,
39.904989
]
]
},
{
"coords": [
[
101.778916,
36.623178
],
[
116.405285,
39.904989
]
]
},
{
"coords": [
[
106.278179,
38.46637
],
[
116.405285,
39.904989
]
]
},
{
"coords": [
[
126.642464,
45.756967
],
[
116.405285,
39.904989
]
]
}
],
"map": [
{
"name": "北京市",

View File

@ -1,12 +1,23 @@
<template>
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize>
<div>
<n-icon
v-if="(enter && levelHistory.length !== 0) || (enter && !isPreview())"
:color="backColor"
@click="backLevel"
:size="backSize" class="back-icon">
<ArrowBackIcon />
</n-icon>
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize @click="chartPEvents">
</v-chart>
</div>
</template>
<script setup lang="ts">
import { PropType, reactive, watch, ref, nextTick } from 'vue'
import { PropType, reactive, watch, ref, nextTick, toRefs } from 'vue'
import config, { includes } from './config'
import VChart from 'vue-echarts'
import { icon } from '@/plugins'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use, registerMap } from 'echarts/core'
import { EffectScatterChart, MapChart } from 'echarts/charts'
@ -16,8 +27,12 @@ import { mergeTheme, setOption } from '@/packages/public/chart'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
import mapJsonWithoutHainanIsLands from './mapWithoutHainanIsLands.json'
import mapChinaJson from './mapGeojson/china.json'
import { DatasetComponent, GridComponent, TooltipComponent, GeoComponent, VisualMapComponent } from 'echarts/components'
const { ArrowBackIcon } = icon.ionicons5
let levelHistory: any = ref([])
const props = defineProps({
themeSetting: {
type: Object,
@ -33,6 +48,8 @@ const props = defineProps({
}
})
const { backColor, backSize, enter } = toRefs(props.chartConfig.option.mapRegion)
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
use([
@ -87,6 +104,16 @@ const vEchartsSetOption = () => {
const dataSetHandle = async (dataset: any) => {
props.chartConfig.option.series.forEach((item: any) => {
if (item.type === 'effectScatter' && dataset.point) item.data = dataset.point
else if (item.type === 'lines' && dataset.line) {
item.data = dataset.line.map((it: any) => {
return {
...it,
lineStyle: {
color: props.chartConfig.option.series[2].lineStyle.normal.color
}
}
})
}
else if (item.type === 'map' && dataset.map) item.data = dataset.map
})
if (dataset.pieces) props.chartConfig.option.visualMap.pieces = dataset.pieces
@ -101,6 +128,44 @@ const hainanLandsHandle = async (newData: boolean) => {
registerMap('china', { geoJSON: mapJsonWithoutHainanIsLands as any, specialAreas: {} })
}
}
//
const chartPEvents = (e: any) => {
if (!props.chartConfig.option.mapRegion.enter) {
return
}
mapChinaJson.features.forEach((item) => {
var pattern = new RegExp(e.name);
if (pattern.test(item.properties.name)) {
let code = String(item.properties.adcode)
levelHistory.value.push(code)
checkOrMap(code)
}
})
}
//
const backLevel = () => {
levelHistory.value = []
if (levelHistory.value.length > 1) {
levelHistory.value.pop()
const code = levelHistory[levelHistory.value.length -1]
checkOrMap(code)
} else {
checkOrMap('china')
}
}
//
const checkOrMap = async (newData: string) => {
await getGeojson(newData)
props.chartConfig.option.geo.map = newData
props.chartConfig.option.series.forEach((item: any) => {
if (item.type === 'map') item.map = newData
})
vEchartsSetOption()
}
// dataset
watch(
() => props.chartConfig.option.dataset,
@ -113,6 +178,17 @@ watch(
}
)
// 线
watch(
() => props.chartConfig.option.series[2].lineStyle.normal.color,
() => {
dataSetHandle(props.chartConfig.option.dataset)
},
{
deep: false
}
)
//
watch(
() => props.chartConfig.option.mapRegion.showHainanIsLands,
@ -132,14 +208,9 @@ watch(
//
watch(
() => `${props.chartConfig.option.mapRegion.adcode}`,
async newData => {
newData => {
try {
await getGeojson(newData)
props.chartConfig.option.geo.map = newData
props.chartConfig.option.series.forEach((item: any) => {
if (item.type === 'map') item.map = newData
})
vEchartsSetOption()
checkOrMap(newData)
} catch (error) {
console.log(error)
}
@ -154,3 +225,13 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
dataSetHandle(newData)
})
</script>
<style scope lang="scss">
.back-icon {
cursor: pointer;
position: absolute;
top: 0;
left: 0;
z-index: 50;
}
</style>