2022-09-27 地图重影 symbolOffset: [0, '-120%'],

-->

   

       

            v-if="drillDown.isDrillDown()"

            type="primary"

            size="small"

            class="tjkw-btnBack"

            icon="el-icon-arrow-left"

            @click="drillUp"

        >返回

       

import { serieStyle, DrillDown, MapStore }from '@/components/gChart/helpers'

import commonMixinfrom 'widget/views/mixins'

import {

mapType,

    getCustomerDistributionProjectCount,

    getCustomerDistributionProjectInfo,

    convertLinesData,

    convertScattersData

}from './utils'

function filterName (name ='') {

return name.replace('省', '').replace('市', '').replace('自治区')

}

export default {

name:'TianjinkaiwuBaseMap',

    mixins: [commonMixin],

    props: {

type:{

type:String,

        },

        // 飞线颜色

        lineColor: {

type:String,

            default:'#a6c84c'

        },

        // 项目点颜色

        effectScatterColor: {

type:String,

            default:'#a6c84c'

        },

        // 迁徙线数据

        // [[起点名, 终点名], [起点名, 终点名]...]

        linesData: {

type:Array,

            default: () => []

},

        // 分布点数据

        // [[地名, value], [地名, value]...]

        effectScatterData: {

type:Array,

            default: () => []

},

        // 地图类型

        mapType: {

type:String,

            required:true,

            validator (val) {

return !!mapType[val]

}

},

        startPointName: {

required:true,

            type:String,

            default:'天津'

        },

        // 企业详情的列名和列值

        columns: {

type:Array,

            default: () => []

}

},

    data () {

return {

mapStore:null,

            mapName:'china',

            chartInstance:null,

            drillDown:null,

            linesCoordData: [],

            scattersCoordData: [],

            linesNameData: [],

            scattersNameData: [],

            originData: [],

            projectInfo: [],

            enumColor:['#47A0FF','#28E3F2','#32DEA2','#7BDE7C']

}

},

    methods: {

getCustomerDistributionProjectCount () {

const params = {

tenantId:this.tenantId,

                type:this.mapType

            }

return getCustomerDistributionProjectCount(params).then(res => {

const {data = []} = res || {}

this.originData = data

this.linesNameData =convertLinesData(data, this.startPointName)

this.scattersNameData =convertScattersData(data)

})

},

        getCustomerDistributionProjectInfo (cityName) {

const params = {

tenantId:this.tenantId,

                type:this.mapType,

                city: cityName

}

return getCustomerDistributionProjectInfo(params).then(res => {

const {data = []} = res || {}

this.projectInfo = data

})

},

        // 名称可能带省或市的,这里适配处理

        getCoordByName (map, name ='') {

const coord = map[name] ||

map[name.replace('省', '')] ||

map[name.replace('市', '')] ||

map[name.replace('区', '')] ||

map[name.replace('自治区', '')] ||

map[name.replace('自治州', '')]

if (coord) {

return coord

}

},

        getCoordFromOriginDataByName (data, name) {

return data.find(item => {

const {province} = item

return filterName(province) ===filterName(name)

})

},

        // 将迁徙线的名称数组转化为坐标数组

        convertLinesNameDataToCoordData (val = []) {

this.linesCoordData = val.reduce((arr, item) => {

const [startPointName, endPointName, value] = item

const coordMap =this.mapStore.coordMap

                const startCoord =this.getCoordByName(coordMap, startPointName)

const endCoord =this.getCoordByName(coordMap, endPointName)

if (startCoord && endCoord) {

arr.push([

{coord: startCoord.cp},

                        {coord: endCoord.cp,value}

])

}

return arr

}, [])

},

        // 将分布点的名称数组转化为坐标数组

        convertScattersNameDataToCoordData (val = []) {

this.scattersCoordData = val.reduce((arr, item) => {

const [provinceName, value] = item

const coordMap =this.mapStore.coordMap

                const coordItem =this.getCoordByName(coordMap, provinceName)

if (coordItem) {

arr.push({

name: provinceName,

                        value: [...coordItem.cp, value]

})

}

return arr

}, [])

},

        // 将分布点的名称数组转化为坐标数组

        convertScattersNameDataToCoordDataOfProvince (val = [], provinceName) {

const coordMap =this.mapStore.coordMap[provinceName]

console.log(coordMap, '地级市')

if (coordMap) {

this.scattersCoordData = val.reduce((arr, item) => {

const [name, value] = item

const {citys} = coordMap

const coordItem =this.getCoordByName(citys, name)

if (coordItem) {

arr.push({

name: name,

                                value: [...coordItem.cp, value]

})

}

return arr

}, [])

}

},

        reloadMap () {

this.chartInstance &&this.chartInstance.clear()

this.chartInstance =this.$echarts.init(this.$refs.mapWrap)

this.registerChartEvent()

this.updateMap()

},

        // 更新地图

        updateMap () {

const option =this.setChartOption()

if (this.chartInstance) {

this.chartInstance.clear()

this.chartInstance.setOption(option, true)

this.chartInstance.resize()

}

},

        // 转换地级市坐标点

        convertCityListByName (name) {

let provincesInfo =this.getCoordFromOriginDataByName(this.originData, name)

console.log(provincesInfo, 'info')

if (provincesInfo) {

const {cityList} = provincesInfo

this.scattersNameData =convertScattersData(cityList)

console.log(this.scattersNameData, 'scattersNameData')

this.convertScattersNameDataToCoordDataOfProvince(this.scattersNameData, name)

console.log(this.scattersCoordData, 'scattersCoordData')

}else {

provincesInfo = {

cityList:[

],

                    projectCount:0 ,

                    province:""

                }

const {cityList} = provincesInfo

this.scattersNameData =convertScattersData(cityList)

console.log(this.scattersNameData, 'scattersNameData')

this.convertScattersNameDataToCoordDataOfProvince(this.scattersNameData, name)

console.log(this.scattersCoordData, 'scattersCoordData')

}

},

        // 提供外部手动触发下钻

        triggerDrillDown(name) {

// 保证省份可以正常匹配 | 北京市 -> 北京

            name =this.mapStore.nameMapAdaptor(name)

this.mapStore.registProvincialMap(name).then(() => {

this.drillDownFn(name)

})

},

        // 下钻方法

        drillDownFn (name) {

this.drillDown.add(name)

this.convertCityListByName(name)

this.updateMap()

this.$emit('drill-down', name)

},

        // 下钻后的返回

        drillUp() {

const currentMap =this.drillDown.back()

this.mapStore.setCurrentMap(currentMap)

this.mapStore.setCurrentZoom(1)

this.scattersNameData =convertScattersData(this.originData)

this.convertScattersNameDataToCoordData(this.scattersNameData)

this.updateMap()

this.$emit('drill-up', currentMap)

},

        // 点 线 流 颜色

        handleNumPublicMethod(params){

if(this.drillDown.isDrillDown()){

if (params.value){

const numDrillDown = params.value

                    if (numDrillDown>0&&numDrillDown<=10){

return '#47A0FF'

                    }else if (numDrillDown>10&&numDrillDown<=20){

return '#28E3F2'

                    }else if (numDrillDown>20){

return '#32DEA2'

                    }

}

}else {

if (this.type ==1){

let num = params.value

                    if (num >=0 && num <=15) {

return this.enumColor[0]

}else if (num >15 && num <=30) {

return this.enumColor[1]

}else if (num >30 && num <=45) {

return this.enumColor[2]

}else if (num >45) {

return this.enumColor[3]

}

}else if (this.type ==2){

let numType = params.value

                    // let numType

// params.value?numType = Number(params.value[2]):numType=0

                    if (numType >=0 && numType <=25) {

return this.enumColor[0]

}else if (numType >25 && numType <=50) {

return this.enumColor[1]

}else if (numType >50 && numType <=75) {

return this.enumColor[2]

}else if (numType >75 && numType <=100) {

return this.enumColor[3]

}

}

}

},

        /**

        * data数据类型为:

* [

*  [{

                coord: [x, y] //起点横纵坐标

            }, {

                coord: [x, y] //终点横纵坐标

            }],

[{

                coord: [x, y] //起点横纵坐标

            }, {

                coord: [x, y] //终点横纵坐标

            }]

...

*  ]

*/

        setLinesSeries (data) {

const planePath ='path://M.6,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705';

            const moveLines = {

name:'moveLines',

                type:'lines',

                zlevel:1,

                effect: {

show:true,

                    period:6,

                    trailLength:0.7,

                    color:'#fff',

                    symbolSize:3

                },

                lineStyle: {

normal: {

color: (params)=>{

console.log(params,'342');

                            return this.handleNumPublicMethod(params)

},

                        width:0,

                        curveness:0.4

                    }

},

                data

}

const staticLines = {

name:'',

                type:'lines',

                zlevel:2,

                effect: {

show:true,

                    period:6,

                    trailLength:0,

                    symbol: planePath,

                    symbolSize:15

                },

                lineStyle: {

normal: {

color: (params)=>{

return this.handleNumPublicMethod(params)

},

                        width:1,

                        opacity:0.4,

                        curveness:0.4

                    }

},

                data

}

return [moveLines, staticLines]

},

        /**

        *  data数据类型为:

* [

        *  {name, value: [x, y, value]}, // 横纵坐标和value(客户数量,用来区分标点直径大小)

        *  {name, value: [x, y, value]},

*  ...

* ]

*/

        setEffectScatterSeries (data) {

const effectScatterOptions = {

name:'effectScatter',

                type:'effectScatter',

                coordinateSystem:'geo',

                zlevel:2,

                rippleEffect: {

brushType:'stroke'

                },

                label: {

normal: {

show:true,

                        position:'bottom',

                        formatter:'{b}',

                        color:'rgba(255, 255, 255)'

                    }

},

                symbolSize: (val, params) => {

const {name} = params

if (name ===this.startPointName)return 20

                    return 15

                },

                itemStyle: {

normal: {

color: (params)=>{

if(this.drillDown.isDrillDown()){

if (params.value){

const numDrillDown = params.value[2]

if (numDrillDown>0&&numDrillDown<=10){

return '#47A0FF'

                                    }else if (numDrillDown>10&&numDrillDown<=20){

return '#28E3F2'

                                    }else if (numDrillDown>20){

return '#32DEA2'

                                    }

}

}else {

if (params.value){

if (this.type ==1){

let num = params.value[2]

if (num >=0 && num <=15) {

return this.enumColor[0]

}else if (num >15 && num <=30) {

return this.enumColor[1]

}else if (num >30 && num <=45) {

return this.enumColor[2]

}else if (num >45) {

return this.enumColor[3]

}

}else if (this.type ==2){

let numType = params.value[2]

if (numType >=0 && numType <=25) {

return this.enumColor[0]

}else if (numType >25 && numType <=50) {

return this.enumColor[1]

}else if (numType >50 && numType <=75) {

return this.enumColor[2]

}else if (numType >75 && numType <=100) {

return this.enumColor[3]

}

}

}

}

},

                    }

},

                symbolOffset: [0, '-120%'],

                data

}

return [effectScatterOptions]

},

        getCityOfProvinceDomString (name) {

const province =this.originData.find(item =>filterName(item.province) ===filterName(name))

if (province) {

const {cityList} = province

let domString =''

              cityList.forEach(item => {

domString +=`

                  ${item.city}

                  ${item.projectCount}

               

`

              })

return domString

}

},

        getProvinceTooltip (params) {

return `

                        ${params.name}

                        ${params.value[2]}

                        ${this.getCityOfProvinceDomString(params.name)}

          `

        },

        renderProjectTable () {

let domString ='

序号
'

            this.columns.forEach(h => {

domString +=`

${h.title}
`

            })

domString +=''

            this.projectInfo.forEach((item, idx) => {

domString +=`${idx +1}`

              this.columns.forEach(col => {

domString +=`

${item[col.prop]===null?'-':item[col.prop]}${col.prop ==='contractAmount' ?'万元' :''}
`

              })

})

return domString

},

        // 获取企业信息的表格数据展示html字符串

        getProjectInfoDom (params) {

let domString =`

                        ${params.name}

                                ${this.renderProjectTable()}

            `

            return domString

},

        setChartOption () {

this.mapName =this.mapStore &&this.mapStore.getCurrentMap()

let series = []

let linesSeries

linesSeries =this.setLinesSeries(this.linesCoordData)

console.log(this.mapType, this.linesCoordData)

// 线的数据在下钻后,迁徙线不消失,这里清空data,使其消失

            if (this.drillDown.isDrillDown()) {

linesSeries[0] && (linesSeries[0].data = [])

linesSeries[1] && (linesSeries[1].data = [])

}

series = series.concat(linesSeries)

const scattersSeries =this.setEffectScatterSeries(this.scattersCoordData)

series = series.concat(scattersSeries)

var option = {

title: {

left:'left',

                    textStyle: {

color:'#fff'

                    }

},

                tooltip: {

enterable:true,

                    triggerOn:this.drillDown.isDrillDown() ?'click' :'mousemove',

                    confine:true,

                    backgroundColor:'transparent',

                    formatter: (params, ticket, callback) => {

console.log(params, 'params')

const {componentSubType} = params

if (componentSubType ==='lines') {

return

                        }

if (this.drillDown.isDrillDown()) {

this.getCustomerDistributionProjectInfo(params.name)

.then(() => {

callback(ticket, this.getProjectInfoDom(params))

})

return 'Loading...'

                        }else {

return this.getProvinceTooltip(params)

}

}

},

                geo: {

map:this.mapName,

                    zoom:1.2,

                    label: {

normal: {

show:true,

                            color:'rgba(255, 255, 255, 0.2)',

                            // 不起作用?

                            // formatter (params) {

//  return ''

// }

                        },

                        emphasis: {

show:false,  // 不起作用

                          color:'rgba(255, 255, 255, 0.2)'

                        }

},

                    roam:'scale',

                    itemStyle: {

normal: {

// areaColor: 'transparent',

// areaColor: '#0B1C3B',

// color: {

//  image: this.$refs.bgImg,

//  repeat: 'repeat',

//  global: false

// },

                            color: {

type:'linear',

                                x:0,

                                y:0,

                                x2:0,

                                y2:1,

                                colorStops: [{

// offset: 0, color: 'red' // 0% 处的颜色

                                    offset:0, color:'#224585' // 0% 处的颜色

                                    // offset: 0, color: '#4AC3FF' // 100% 处的颜色

                                }, {

// offset: 1, color: '#4AC3FF' // 100% 处的颜色

                                    // offset: 1, color: '#0B1C3A' // 100% 处的颜色

                                    // offset: 1, color: '#0E3B88' // 100% 处的颜色

                                    offset:1, color:'#0B1C3C' // 100% 处的颜色

                                }],

                                global:false // 缺省为false

                            },

                            borderColor:'#1381B8',

                            borderWidth:2

                        },

                        emphasis: {

areaColor:'#15749B'

                        }

}

},

                series

};

            return option

},

        registerChartEvent() {

this.chartInstance.on('click', param => {

console.log('click', param)

const { name, componentType, componentSubType } = param

switch (componentType) {

case 'geo':

if (name ==='China' || name ==='') {

this.mapStore.registChinaMap().then(() => {

this.drillDown.add('china')

})

}else {

this.mapStore.registProvincialMap(name).then(() => {

this.drillDownFn(name)

})

}

break;

                    default:

break;

                }

})

},

        // 初始化地图状态管理和下钻控制

        initMapStore () {

this.mapStore = MapStore.init({

currentMap:this.mapName

            })

this.drillDown = DrillDown.init(this.mapName)

},

        resizeChart() {

this.chartInstance.resize()

},

        // 初始化地图

        initMap () {

if (this.mapStore) {

// 这里项目点和基础地图都是异步的,并且需要同时完成才能处理数据,初始化地图

                Promise.all([

this.mapStore.registChinaMap().then(() => {

this.chartInstance =this.$echarts.init(this.$refs.mapWrap)

this.registerChartEvent()

window.addEventListener('resize', this.resizeChart)

}),

                    this.getCustomerDistributionProjectCount()

]).then(() => {

// 先转化完数据,再初始化地图

                    console.log('lines name data', this.linesNameData)

this.convertLinesNameDataToCoordData(this.linesNameData)

this.convertScattersNameDataToCoordData(this.scattersNameData)

this.chartInstance.setOption(this.setChartOption())

})

}

}

},

    created () {

this.initMapStore()

},

    beforeDestroy() {

window.removeEventListener('resize', this.resizeChart)

if (this.chartInstance) {

this.chartInstance.clear()

}

},

    mounted () {

this.initMap()

}

}