<template>
    <div ref="chart" id="map-chart"></div>
</template>

<script>
import * as echarts from 'echarts';
import JiangXi from '../JiangXi.json';
import 'echarts-gl';
import menuOptions from '../mixins/menuOptions';
export default {
    name: 'MapChart',
    mixins: [menuOptions],
    props: {
        valueInfo: {
            type: Object,
            default: () => {
                return {};
            },
        },
    },
    data() {
        return {
            myChart: null,
            active: '南昌市',
            preActive: '南昌市',
            flag: true,
            isOn: false,
            timeData: null,
            desc: 1000,
            sndStat: {},
            showLables: [],
        };
    },
    computed: {
        labels() {
            return this.valueInfo.labels || [];
        },
        datas() {
            return this.valueInfo.data || [];
        },
    },
    watch: {
        active() {
            this.changeChoose();
        },
    },
    mounted() {
        window.addEventListener('resize', this.resize);
    },
    beforeUpdate() {
        if (this.timeData) {
            clearTimeout(this.timeData);
        }
    },
    beforeDestroy() {
        if (this.timeData) {
            clearTimeout(this.timeData);
        }
    },
    methods: {
        resize() {
            this.myChart.resize();
        },
        clearDom() {
            if (this.timeData) {
                clearTimeout(this.timeData);
            }
            if (!this.myChart) {
                var chartDom = document.getElementById('map-chart');
                this.myChart = echarts.init(chartDom);
            } else {
                this.myChart.dispose();
            }
        },
        init() {
            this.clearDom();
            this.$nextTick(() => {
                console.log(this.chooseMenu);
                if (this.chooseMenu === 0) {
                    this.initHeatmap();
                } else if (this.chooseMenu === 2 || this.chooseMenu === 5 || this.chooseMenu === 3) {
                    this.initScatter();
                } else if (this.chooseMenu === 4 || this.chooseMenu === 6) {
                    this.showLables =
                        this.chooseMenu === 6
                            ? ['初级示范区', '高级示范区', '重点示范区']
                            : ['高新基地', '高级高新基地', '重点高新基地'];
                    this.initScatter('more');
                } else if (this.chooseMenu === 1) {
                    this.init3D();
                }
            });
        },
        init3D() {
            var chartDom = document.getElementById('map-chart');
            this.myChart = echarts.init(chartDom);
            this.myChart.setOption({
                color: '#0A2B6A',
                geo3D: {
                    map: 'JangXi',
                    shading: 'lambert',
                    instancing: true,
                    label: {
                        show: false,
                        formatter: (params) => {
                            this.active = params.name;
                            return '';
                        },
                    },
                    light: {
                        main: {
                            intensity: 1,
                        },
                        ambient: {
                            intensity: 0.5,
                        },
                    },
                    regionHeight: 5,
                    boxHeight: 40,
                    viewControl: {
                        distance: 200,
                        minDistance: 150,
                        alpha: 40,
                        beta: 30,
                        rotateSensitivity: [1, 0],
                    },
                },
                zAxis3D: {
                    type: 'value',
                    min: 0,
                    max: 40,
                },
                series: [
                    {
                        id: 'value',
                        type: 'bar3D',
                        name: '江西省数据',
                        coordinateSystem: 'geo3D',
                        shading: 'lambert',
                        data: [],
                        bevelSize: 0.3,
                        barSize: 5,
                        minHeight: 0,
                        bevelSmoothness: 2,
                        zlevel: 1,
                        silent: true,
                        light: {
                            main: {
                                intensity: 1.2,
                            },
                        },
                    },
                    {
                        id: 'name',
                        type: 'bar3D',
                        name: '江西省名称',
                        coordinateSystem: 'geo3D',
                        shading: 'lambert',
                        data: JiangXi.features.map((item) => {
                            let value = this.getCenter(item, true);

                            if (this.active === item) {
                                value.push(15);
                            } else {
                                value.push(0);
                            }
                            return {
                                name: item,
                                value: value,
                                itemStyle: {
                                    color: this.active === item ? '#FA8816' : '#0A2B6A',
                                },
                            };
                        }),
                        barSize: 1,
                        minHeight: 0,
                        bevelSmoothness: 0,
                        label: {
                            show: true,
                            formatter: (params) => {
                                return params.name;
                            },
                            distance: 0,
                            textStyle: {
                                color: '#fff',
                            },
                        },
                        silent: true,
                        zlevel: 2,
                    },
                ],
            });
            this.myChart.getZr().on('mouseout', () => {
                this.isOn = true;
            });
            this.myChart.getZr().on('globalout', () => {
                this.isOn = false;
                this.animationMove();
            });
            this.changeChoose();
            this.animationMove();
        },
        initScatter(type = 'one') {
            var chartDom = document.getElementById('map-chart');
            this.myChart = echarts.init(chartDom, 'jmrh');
            this.myChart.setOption({
                geo: {
                    map: 'JangXi',
                    label: {
                        show: true,
                        color: '#fff',
                    },
                    itemStyle: {
                        color: '#0C4189',
                        borderColor: '#8CD9FD',
                    },
                    silent: true,
                },
                tooltip: {
                    trigger: 'item',
                },
                visualMap: {
                    show: true,
                    bottom: 30,
                    left: 'center',
                    orient: 'horizontal',
                    min: 0,
                    max: type === 'one' ? this.maxList([...this.datas]) : 3,
                    seriesIndex: 0,
                    calculable: true,
                    inRange: {
                        color: ['#FDA033', '#FD6C33', '#FD4C33'],
                    },
                },
            });

            if (type == 'one') {
                this.myChart.setOption({
                    series: [
                        {
                            type: 'effectScatter',
                            coordinateSystem: 'geo',
                            data: [...this.labels].map((item, index) => {
                                let list = [this.getCenter(item), [...this.datas][index]];
                                return {
                                    name: item,
                                    value: list.flat(),
                                };
                            }),
                            symbolSize: function (val) {
                                let size = val[2];
                                if (size > 100) {
                                    size = Math.floor(size / 5);
                                }
                                if (size > 100) {
                                    size = Math.floor(size / 20);
                                }
                                return size;
                            },
                            encode: {
                                value: 2,
                            },
                            showEffectOn: 'render',
                            rippleEffect: {
                                brushType: 'stroke',
                            },
                            hoverAnimation: true,
                            label: {
                                formatter: (params) => {
                                    return params.name + '\r\n' + params.value[2];
                                },
                                show: true,
                                color: '#fff',
                                fontWeight: 'bold',
                            },
                            itemStyle: {
                                shadowBlur: 10,
                                shadowColor: '#333',
                            },
                            zlevel: 1,
                        },
                    ],
                });
            } else {
                let points = [...this.labels]
                    .map((item, index) => {
                        return this.getRadomlngLat(item, 3, ([...this.datas][index] % 3) + 1);
                    })
                    .flat();

                this.myChart.setOption({
                    visualMap: {
                        show: false,
                    },
                    series: [
                        {
                            type: 'effectScatter',
                            coordinateSystem: 'geo',
                            data: points,
                            symbolSize: function (val) {
                                return 20;
                            },
                            showEffectOn: 'render',
                            rippleEffect: {
                                brushType: 'stroke',
                            },
                            hoverAnimation: true,
                            label: {
                                formatter: (params) => {
                                    return [...this.showLables][params.value[2] - 1];
                                },
                                show: false,
                                color: '#fff',
                                fontWeight: 'bold',
                                position: 'right',
                            },
                            emphasis: {
                                label: {
                                    show: true,
                                },
                            },
                            itemStyle: {
                                shadowBlur: 10,
                                shadowColor: '#333',
                            },
                            zlevel: 1,
                        },
                    ],
                });
            }
        },
        initHeatmap() {
            var chartDom = document.getElementById('map-chart');
            this.myChart = echarts.init(chartDom, 'jmrh');
            this.myChart.setOption({
                geo: {
                    map: 'JangXi',
                    label: {
                        show: true,
                        color: '#fff',
                    },
                    itemStyle: {
                        color: '#0C4189',
                        borderColor: '#8CD9FD',
                    },
                    silent: true,
                },
                visualMap: {
                    show: true,
                    bottom: 30,
                    left: 'center',
                    orient: 'horizontal',
                    min: 0,
                    max: 5,
                    seriesIndex: 0,
                    calculable: true,
                    inRange: {
                        color: ['blue', 'blue', 'green', 'yellow', 'red'],
                    },
                },
            });

            this.$nextTick(() => {
                let points = [...this.labels]
                    .map((item) => {
                        return this.getRadomlngLat(item);
                    })
                    .flat();
                this.myChart.setOption({
                    series: [
                        {
                            type: 'heatmap',
                            coordinateSystem: 'geo',
                            geoIndexnumber: 0,
                            data: points,
                        },
                    ],
                });
            });
        },
        maxList(list, type = 'max') {
            list = list.sort((a, b) => {
                return b - a;
            });

            return type === 'max' ? list[0] : list[list.length] - 1;
        },
        changeChoose() {
            const res = { ...this.valueInfo };
            this.myChart.setOption({
                geo3D: {
                    regions: res.labels.map((item) => {
                        return {
                            name: item,
                            height: this.active === item ? 15 : 5,
                            itemStyle:
                                this.active === item
                                    ? {
                                          color: '#FA8816',
                                          borderWidth: 1,
                                          borderColor: '#FA8816',
                                      }
                                    : {
                                          color: '#0A2B6A',
                                          borderWidth: 1,
                                          borderColor: '#8CD9FD',
                                      },
                            emphasis: {
                                itemStyle:
                                    this.active === item
                                        ? {
                                              color: '#FA8816',
                                          }
                                        : {
                                              color: '#0A2B6A',
                                          },
                            },
                        };
                    }),
                },
                series: [
                    {
                        id: 'value',
                        name: '江西省数据',
                        data: res.labels.map((item, index) => {
                            let value = 0;
                            if (this.active === item) {
                                value = res.data[index] + this.desc;
                            } else {
                                value = res.data[index];
                            }

                            return {
                                name: item,
                                value: [...this.getCenter(item), value],
                                itemStyle: {
                                    color: this.active === item ? '#ffc38c' : '#5AC1FF',
                                    opacity: 0.8,
                                },
                                label: {
                                    show: true,
                                    formatter: (params) => {
                                        if (params.name === this.active) {
                                            return params.value[2] - this.desc;
                                        } else {
                                            return params.value[2];
                                        }
                                    },
                                    distance: 2,
                                    textStyle: {
                                        color: this.active === item ? '#FA8816' : '#fff',
                                        fontSize: this.active === item ? 18 : 12,
                                        opacity: 1,
                                        fontWeight: 'bold',
                                    },
                                },
                            };
                        }),
                    },
                    {
                        id: 'name',
                        name: '江西省名称',
                        data: res.labels.map((item) => {
                            let value = this.getCenter(item, true);
                            value.push(0);
                            return {
                                name: item,
                                value: value,
                                itemStyle: {
                                    color: this.active === item ? '#FA8816' : '#0A2B6A',
                                },
                                label: {
                                    distance: this.active === item ? 10 : 2,
                                    textStyle: {
                                        fontSize: this.active === item ? 18 : 12,
                                    },
                                },
                            };
                        }),
                    },
                ],
            });
        },
        getRadomlngLat(name = '南昌市', val = 1, randomCount) {
            if (!randomCount) {
                let index = [...this.labels].findIndex((item) => {
                    return item === name;
                });

                if (index || index === 0) {
                    randomCount = this.datas[index];
                }
            }

            if (val !== 1) {
                val = (Math.floor(Math.random() * 10) % val) + 1;
            }

            var data = [];

            var geo = this.myChart.getModel().getComponent('geo').coordinateSystem;
            var region = geo.getRegion(name);
            var rect = region.getBoundingRect();
            for (var i = 0; i < randomCount; i++) {
                var coord = [Infinity, Infinity, val];
                while (!region.contain(coord)) {
                    coord[0] = rect.x + Math.random() * rect.width;
                    coord[1] = rect.y + Math.random() * rect.height;
                }
                // const itemName = 's' + i;
                // geoCoordMap[itemName] = coord;

                data.push(coord);
            }
            return data;
        },
        getCenter(name, isLable = false) {
            let info = JiangXi.features.find((item) => {
                return name === item.properties.name;
            });
            let center = info ? info.properties.centroid : [0, 0];
            if (isLable) {
                center = [center[0] + 0.200151, center[1] - 0.276493];
            }
            return center;
        },
        animationMove() {
            if (this.timeData) {
                clearTimeout(this.timeData);
            }

            this.timeData = setTimeout(() => {
                if (!this.flag || this.isOn) {
                    return;
                } else {
                    const citys = JiangXi.features;
                    let index =
                        citys.findIndex((item) => {
                            return this.active === item.properties.name;
                        }) || 0;
                    this.active = citys[(index + 1) % citys.length].properties.name;
                    this.animationMove();
                }
            }, 3000);
        },
    },
};
</script>

<style lang="less" scoped>
#map-chart {
    width: 100%;
    height: 100%;
}
</style>
