首页 前端知识 Echarts实现伪3D地图 自定义标准的实现小记

Echarts实现伪3D地图 自定义标准的实现小记

2025-03-18 12:03:46 前端知识 前端哥 124 509 我要收藏

仅作为记录,欢迎参考,不喜勿喷

<template>
    <v-chart :option="option" autoresize></v-chart>
</template>

<script>
import { mapState } from 'vuex';
import { use, registerMap } from 'echarts/core';
import { MapChart, EffectScatterChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import {
    TitleComponent,
    TooltipComponent,
    GeoComponent,
    VisualMapComponent,
} from 'echarts/components';
import VChart from 'vue-echarts';
import ErrorTip from '@/assets/image/overview/icon_error.png';
import SuccessTip from '@/assets/image/overview/icon_success.png';
import chinaMap from '@/assets/map/china';

use([
    TitleComponent,
    TooltipComponent,
    GeoComponent,
    VisualMapComponent,
    MapChart,
    CanvasRenderer,
    EffectScatterChart
]);

const defaultOptions = () => ({
    tooltip: {
        trigger: 'item',
        backgroundColor: 'rgba(5, 52, 84, 0.50)',
        borderColor: 'rgba(128,227,255,0.32)',
        formatter(params) {
            const { seriesType, name, data } = params;
            let alive_count = 0;
            let rule_hit_car_count = 0;
            let rule_hit_count = 0;
            try {
                if (seriesType === 'effectScatter') {
                    alive_count = data.value[2].value.alive_count;
                    rule_hit_car_count = data.value[2].value.rule_hit_car_count;
                    rule_hit_count = data.value[2].value.rule_hit_count;
                } else {
                    alive_count = data?.other.alive_count || 0;
                    rule_hit_car_count = data?.other.rule_hit_car_count || 0;
                    rule_hit_count = data?.other.rule_hit_count || 0;
                }
            } catch (error) {
                // console.log(error);
            }
            return `
                <div class="custom-tooltip-wrapper">
                    <p class="title">${name}</p>
                    <p>
                        <span class="text">激活车辆:</span>
                        <span class="value">${alive_count}</span>
                    </p>
                    <p>
                        <span class="text">风险车辆:</span>
                        <span class="value">${rule_hit_car_count}</span>
                    </p>
                    <p>
                        <span class="text">风险总数:</span>
                        <span class="value">${rule_hit_count}</span>
                    </p>
                </div>
            `;
        }
    },
    visualMap: {
        type: 'piecewise',
        bottom: 20,
        textStyle: {
            color: '#fff',
            fontSize: 10,
            fontWeight: 400
        },
        pieces: [
            { min: 501, label: '500以上', color: '#E34438' },
            { min: 301, max: 500, color: '#F28F4C' },
            { min: 101, max: 300, color: '#2E70EE' },
            { min: 0, max: 100, label: '100以下', color: '#02A6D1' },
        ],
        itemWidth: 22,
        itemHeight: 9
    },
    // 实际地图
    geo: [
        {
            map: 'china',
            z: 1,
            aspectScale: 0.9,
            zoom: 1,
            roam: false,
            label: {
                show: true,
                color: '#9AEDFF',
                position: 'inside',
                distance: 0,
                fontSize: 10,
            },
            // 所有地图的区域颜色
            itemStyle: {
                normal: {
                    areaColor: '#2d6b92',
                    borderWidth: 1,
                    borderColor: '#092138',
                },
            },
            emphasis: {
                label: {
                    show: false
                },
                itemStyle: {
                    areaColor: '#01CCFF',
                }
            },
            select: {
                label: {
                    show: false
                },
                itemStyle: {
                    areaColor: '#01CCFF'
                }
            },
        },
        // 底部背景地图
        {
            map: 'china',
            z: 0,
            top: 67,
            aspectScale: 0.9,
            zoom: 1,
            roam: false,
            label: {
                normal: {
                    show: false,
                },
                emphasis: {
                    show: false,
                },
            },
            itemStyle: {
                normal: {
                    areaColor: '#091F35',
                    borderColor: '#073256',
                    borderWidth: 2,
                },
            },
            emphasis: {
                label: {
                    show: false
                },
                itemStyle: {
                    areaColor: '#091F35',
                }
            },
            tooltip: {
                show: false
            },
            regions: [
                {
                    name: '南海诸岛',
                    itemStyle: {
                        opacity: 0
                    },
                    label: {
                        show: false // 隐藏文字
                    }
                }
            ]
        },
    ],
    series: [
        {
            name: '风险分布',
            type: 'map',
            map: 'china',
            geoIndex: 0,
            data: []
        },
        {
            name: '风险数',
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: [],
            // 自定义标注
            symbol: function (params) {
                if (!params || !params[2]) {
                    return 'none';
                } else
                if (params[2].status === '未处理') {
                    return `image://${ErrorTip}`;
                } else {
                    return `image://${SuccessTip}`;
                }
            },
            symbolSize: [24.5, 36],
            rippleEffect: {
                number: 0
            },
            showEffectOn: 'emphasis',
            animation: false
        },
    ]
});

export default {
    name: 'v-china-chart',
    components: {
        VChart
    },
    data() {
        return {
            option: defaultOptions(),
        };
    },
    computed: {
        ...mapState('overview', ['chartData'])
    },
    watch: {
        chartData(newValue) {
            this.initData();
            this.option.series[0].data = this.formatChartData(newValue);
        },
        option(newOption) {
            this.option = newOption;
        }
    },
    methods: {
        initData() {
            let seriesData = chinaMap.features.map(province => {
                if (province.properties.name) {
                    const item = this.chartData.find(item => {
                        const itemProvince = item.province.replace(/省|市|自治区/g, '');
                        return itemProvince === province.properties.name;
                    });
                    return item ? {
                        name: province.properties.name,
                        // echarts地图实现自定义标注的关键
                        value: province.properties.cp.concat({
                            value: { ...item }
                        })
                    } : {
                        name: province.properties.name,
                        value: 0
                    };
                }
            });
            this.option.series[0].data = this.formatChartData(this.chartData);
            this.option.series[1].data = seriesData;
        },
        formatChartData(data) {
            return data.map(item => {
                const province = item.province.replace(/省|市|自治区/g, '');
                return {
                    name: province,
                    value: item.rule_hit_count,
                    other: { ...item }
                };
            });
        },
    },
    created() {
        // 注册地图
        registerMap('china', chinaMap);
        this.initData();
    }
};
</script>

<style lang="scss" scoped>

</style>
转载请注明出处或者链接地址:https://www.qianduange.cn//article/23993.html
标签
评论
发布的文章
大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!