vue+echarts: 信息中心动画

61 阅读5分钟

本文用于记录

image.png

具体可参考信息中心动画 (zhangmuchen.top)

渔船画像icon.png

img_info_bg_ship.png

<template>
    <div class="CaseSituation">
        <!-- 标题-->
        <div class="common-index-part-title">
            <common-title title="渔船画像">
            </common-title>
        </div>
        <!-- 内容-->
        <div class="common-index-part-content"
            v-loading="isLoading"
            element-loading-text="拼命加载中"
            element-loading-background="rgba(0, 0, 0, 0.8)"
        >
            <!-- 图表-->
            <div style="width:100%;height:100%;margin-top:15px" id="shipPort"></div>
        </div>
    </div>
</template>
<script>
import CommonTitle from "@/pages/enforceStatistic/components/commonTitle/commonTitle";
import shipBack from "../../../../assets/enforceStatistic/decisionMark/shipBack.png"
import shipIcon from "../../../../assets/enforceStatistic/decisionMark/shipIcon.png"
export default {
    name: "CaseSituation",
    components: {CommonTitle},
    data () {
        return {
            myChart: null,
            isLoading: false,
            allArr: [],
            width: 60,
            timer: null
        }
    },
    mounted () {
        clearInterval(this.timer)
        this.initChart()
    },
    methods: {
        initChart () {
            let points = [
                {
                    name: '拆解灭失',
                    desc: {
                        type: 1,
                    },
                },
                {
                    name: '渔船交易',
                    desc: {
                        type: 2,
                    },
                },
                {
                    name: '渔船检验',
                    desc: {
                        type: 1,
                    },
                },
                {
                    name: '渔船新造',
                    desc: {
                        type: 1,
                    },
                },
                {
                    name: '渔船证书',
                    desc: {
                        type: 1,
                    },
                },
                {
                    name: '渔船生产',
                    desc: {
                        type: 1,
                    },
                },
                {
                    name: '渔船改造',
                    desc: {
                        type: 1,
                    },
                },
            ];
            let oneArr = [
                {
                    name: '中心点',
                    desc: {
                        type: 0,
                    },
                    symbol: 'none',
                    symbolSize: 233,
                },
            ];
            let erArr = points;
            let allArr = [...oneArr, ...erArr]
            // 点
            allArr.forEach((el, ind) => {
                if (el.desc.type > 0) {
                    el.symbolSize = [100, 40];
                    el.symbol =
                        'image://data:image/png;base64,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';
                    el.itemStyle = {
                        color: '#fff',
                        fontSize: '16px',
                    };
                }
                el.label = {
                    show: true,
                    position: 'bottom',
                    distance: -28,
                    color: '#fff',
                    fontSize: '16px',
                    fontFamily: 'SourceHanSansCN-Medium',
                };
            });

            

            // 点分布
            oneArr = this.CalutePointToSplitCircle(oneArr, {
                stratAngle: 0,
                raduis: 0,
                nodeRadius: 0,
                emptyCenterRadius: 0,
            });
            erArr = this.CalutePointToSplitCircle(erArr, {
                stratAngle: -45,
                raduis: 40,
                nodeRadius: 5,
                emptyCenterRadius: 10,
            });

            allArr = [...oneArr, ...erArr];
            this.allArr = allArr
            this.isBig = true
            this.myChart= this.$echarts.init(
                document.getElementById('shipPort')
            )
            this.timer = setInterval(this.draw, 500);
        },
        draw() {
            let [minwidth, maxwidth] = [60, 70]; // 最小、初始、最大 缩放尺寸
            var width = this.width
            if (this.isBig) {
                width += 5
                if (width > maxwidth) {
                    this.isBig = false
                }
            } else {
                width -= 5
                if (width < minwidth) {
                    this.isBig = true
                }
            }
            this.width = width
            let option = this.getOption(width);
            this.myChart.setOption(option, true);
        },
        getOption (width) {
            let option = {
                xAxis: {
                    show: false,
                    type: 'value',
                    max: 50,
                    min: -51,
                },
                grid: {
                    top: 10,
                    bottom: 10,
                    left: 10,
                    right: 10,
                },
                yAxis: {
                    show: false,
                    type: 'value',
                    max: 50,
                    min: -50,
                },
                graphic: {
                    elements: [
                        {
                            type: 'image',
                            z: 4,
                            style: {
                                image: shipBack,
                                width: 170,
                                height: 170,
                            },
                            left: 'center',
                            top: 'center',
                        },
                        {
                            type: 'image',
                            z: 5,
                            style: {
                                image: shipIcon,
                                width: width,
                                height: width,
                            },
                            left: 'center',
                            top: 'center',
                        },
                    ],
                },
                series: [
                    {
                        name: '节点',
                        type: 'graph',
                        silent: false,
                        cursor: 'default',
                        coordinateSystem: 'cartesian2d',
                        z: 3,
                        data: this.allArr,
                    },
                ],
            };
            return option;
        },
        // 圆形分区
        CalutePointToSplitCircle(arr, option) {
            const newArray = [];
            let single_angle = (360 / 8).toFixed(2);
            let UtilCalute = {
                calute_x: (ang, radius) => {
                    return (Math.cos((ang * Math.PI) / 180).toFixed(2) * radius).toFixed(2);
                },
                calute_y: (ang, radius) => {
                    return (Math.sin((ang * Math.PI) / 180).toFixed(2) * radius).toFixed(2);
                },
            };
            // 正东方向开始 逆时针方向
            arr.forEach((e, index) => {
                let itemDesc = e.desc;
                let ang =
                    option.stratAngle +
                    (itemDesc.angle && typeof itemDesc.angle === 'number' ? itemDesc.angle : single_angle * index);
                // 各节点中心点
                const x = UtilCalute.calute_x(ang, option.raduis);
                const y = UtilCalute.calute_y(ang, option.raduis);

                e.value = [x, y]; // 节点中心点
                newArray.push(e);
            });
            return newArray;
        },
    },
    beforeDestroy () {
        clearInterval(this.timer)
    }
}
</script>
<style lang="less" scoped>

</style>