Vue3 + echarts 5.4.2 实现

简介: Vue3 + echarts 5.4.2 实现

从vue2升级到vue3,对原来的柱状图、折线图组件进行了修改,这两个组件的语法保留了vue2,实际使用也没有问题。

1、通用柱状图 BarChart.vue

<template>
  <div :class="className" :style="{height: height, width: width}"/>
</template>
<script>
    import * as echarts from 'echarts';
    import 'echarts/theme/macarons.js'
    export default {
        props: {
            className: {
                type: String,
                default: 'chart'
            },
            width: {
                type: String,
                default: '100%'
            },
            height: {
                type: String,
                default: '450px'
            },
            title: {
                type: String,
                required: true
            },
            chartData: {
                type: Object,
                required: true
            }
        },
        data() {
          // vue3需要这样写,否则`tooltip`无效
            chart: null
            return {
                // chart: null
            }
        },
        watch: {
            chartData: {
                deep: true,
                handler(val) {
                    this.setOptions(val)
                }
            }
        },
        mounted() {
            this.$nextTick(() => {
                this.initChart()
            })
        },
        beforeDestroy() {
            if (!this.chart) {
                return
            }
            this.chart.dispose()
            this.chart = null
        },
        methods: {
            initChart() {
                this.chart = echarts.init(this.$el, 'macarons')
                this.chart.setOption({
                    title: {
                        text: this.title,
                        textStyle: {
                            fontSize: 15
                        }
                    },
                    toolbox: {
                        show: true,
                        orient: 'horizontal',
                        left: 'right',
                        top: 'top',
                        feature: {
                            mark: { show: true },
                            magicType: { show: true, type: ['line', 'bar'] },
                        }
                    },
                    tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            type: 'shadow'
                        }
                    },
                    grid: {
                        top: '10%',
                        left: '2%',
                        right: '2%',
                        bottom: '4%',
                        containLabel: true
                    },
                    xAxis: [{
                        type: 'category',
                        axisTick: { show: false },
                    }],
                    yAxis: [{
                        type: 'value',
                    }],
                    series: []
                })
            },
            setOptions(data) {
                let map = data.map
                let series = []
                map.forEach((val, key) => {
                    let obj = {
                        name: key,
                        data: Array.from(val),
                        type: 'bar',
                        barWidth: '10%',
                        barGap: 0,
                        emphasis: {
                            focus: 'series'
                        },
                        animationDuration: 2800,
                        animationEasing: 'quadraticOut'
                    }
                    series.push(obj)
                });
                
                this.chart.setOption({
                    xAxis: [{
                        data: data.date,
                    }],
                    legend: {
                        data: Array.from(map.keys())
                    },
                    series: series
                })
            }
        }
    }
</script>

2、通用的折线图组件 LineChart.vue

<template>
  <div :class="className" :style="{height: height, width: width}"/>
</template>
<script>
    import * as echarts from 'echarts';
    import 'echarts/theme/macarons.js'
    export default {
        props: {
            className: {
                type: String,
                default: 'chart'
            },
            width: {
                type: String,
                default: '100%'
            },
            height: {
                type: String,
                default: '450px'
            },
            title: {
                type: String,
                required: true
            },
            chartData: {
                type: Object,
                required: true
            }
        },
        data() {
          // vue3需要这样写,否则`tooltip`无效
            chart: null
            return {
                // chart: null
            }
        },
        watch: {
            chartData: {
                deep: true,
                handler(val) {
                    this.setOptions(val)
                }
            }
        },
        mounted() {
            this.$nextTick(() => {
                this.initChart()
            })
        },
        beforeDestroy() {
            if (!this.chart) {
                return
            }
            this.chart.dispose()
            this.chart = null
        },
        methods: {
            initChart() {
                this.chart = echarts.init(this.$el, 'macarons')
                this.chart.setOption({
                    title: {
                        text: this.title,
                        textStyle: {
                            fontSize: 15
                        }
                    },
                    xAxis: {
                        type: 'category',
                        boundaryGap: false,
                    },
                    grid: {
                        left: 15,
                        right: 10,
                        bottom: 20,
                        top: '10%',
                        containLabel: true
                    },
                    toolbox: {
                        show: true,
                        orient: 'horizontal',
                        left: 'right',
                        top: 'top',
                        feature: {
                            mark: { show: true },
                            magicType: { show: true, type: ['line', 'bar'] },
                        }
                    },
                    tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            type: 'shadow'
                        },
                    },
                    yAxis: {
                        type: 'value',
                        axisTick: {
                            show: false
                        }
                    },
                    series: []
                })
            },
            setOptions(data) {
                let map = data.map
                let series = []
                map.forEach((val, key) => {
                    let obj = {
                        name: key,
                        data: Array.from(val),
                        type: 'line',
                        barWidth: '40',
                        smooth: true,
                        itemStyle: {
                            normal: {
                                lineStyle: {
                                    width: 2
                                }
                            }
                        },
                        animationDuration: 2800,
                        animationEasing: 'quadraticOut'
                    }
                    series.push(obj)
                });
                
                this.chart.setOption({
                    xAxis: {
                        data: data.date,
                    },
                    series: series
                })
            }
        }
    }
</script>

3、通用饼图组件 PieChart.vue

<template>
  <div :class="className" :style="{height:height,width:width}"/>
</template>
<script>
    import * as echarts from 'echarts';
    import 'echarts/theme/macarons.js'
    const color = [
        "#37a2da",
        "#32c5e9",
        "#9fe6b8",
        "#ffdb5c",
        "#ff9f7f",
        "#fb7293",
        "#e7bcf3",
        "#8378ea"
    ];
    export default {
        props: {
            className: {
                type: String,
                default: 'chart'
            },
            width: {
                type: String,
                default: '100%'
            },
            height: {
                type: String,
                default: '350px'
            },
            title: {
                type: String,
                required: true
            },
            chartData: {
                type: Object,
                required: true
            }
        },
        data() {
            return {
                chart: null
            }
        },
        watch: {
            chartData: {
                deep: true,
                handler(val) {
                    this.setOptions(val)
                }
            }
        },
        mounted() {
            this.$nextTick(() => {
                this.initChart()
            })
        },
        beforeDestroy() {
            if (!this.chart) {
                return
            }
            this.chart.dispose()
            this.chart = null
        },
        methods: {
            initChart() {
                this.chart = echarts.init(this.$el, 'macarons')
                this.chart.setOption({
                    title: {
                        textStyle: {
                            fontSize: 15
                        }
                    },
                    tooltip: {
                        trigger: 'item',
                        formatter: '{b} : {c} ({d}%)'
                    },
                    itemStyle: {
                        normal:{
                            borderRadius: 10,
                            borderColor: '#fff',
                            borderWidth: 2
                        },
                    },
                    label: {
                        color: '#32c5e9'
                    },
                    labelLine: {
                        lineStyle: {
                            width: 2
                        }
                    },
                    grid: {
                        top: '10%',
                        left: '2%',
                        right: '2%',
                        bottom: '4%',
                        containLabel: true
                    },
                    series: [{
                        type: "pie",
                        radius: [50, 110],
                        center: ['50%', '50%'],
                        top: 10,
                        itemStyle: {
                            normal:{
                                color: item => {
                                    return color[item.dataIndex%(color.length)]
                                },
                                borderRadius: 10,
                                borderColor: '#fff',
                                borderWidth: 2
                            },
                        },
                        label: {
                            color: '#32c5e9'
                        },
                        labelLine: {
                            lineStyle: {
                                width: 2
                            }
                        },
                        emphasis: {
                            label: {
                                show: true,
                                fontSize: '20',
                                fontWeight: 'bold',
                            }
                        },
                        animationEasing: 'cubicInOut',
                        animationDuration: 2600
                    }]
                })
            },
            setOptions(data) {
                this.chart.setOption({
                    title: {
                        text: this.title,
                    },
                    series: [{
                        data: data,
                    }]
                })
            }
        }
    }
</script>

4、调用示例

<template>
  <div class="dashboard-editor-container">
    <el-row :gutter="32">
      <el-col :xs="24" :sm="24" :lg="24">
        <div class="chart-wrapper">         
          <el-radio-group v-model="period" @change="getData" style="margin: 0 0 20px 0">
            <el-radio-button label="30">近30天</el-radio-button>
            <el-radio-button label="180">近180天</el-radio-button>
            <el-radio-button label="365">近365天</el-radio-button>
          </el-radio-group>
                 
          <line-chart :chart-data="lineChartData" :title="`每日任务接收情况统计`"/>
        </div>
      </el-col>
    </el-row>
      
    <el-row :gutter="32">
      <el-col :xs="24" :sm="24" :lg="24">
        <div class="chart-wrapper">
          <bar-chart :chart-data="monthlyData" :title="`近半年统计月报`"/>
        </div>
      </el-col>
    </el-row>
  <el-row :gutter="32">
      <el-col :xs="24" :sm="24" :lg="8">
        <div class="chart-wrapper">
          <pie-chart :chart-data="diagnosePieChartData" :title="`诊断任务统计`"/>
        </div>
      </el-col>
    </el-row>
  </div>
</template>
<script setup name="Index">
    import LineChart from './LineChart'
    import BarChart from './BarChart'
    import PieChart from './PieChart'
    
    import {
        countByMonthly,
        countByReceiptTime,
        countByTypeAndDept
    } from '@/api/xxx'
    const {proxy} = getCurrentInstance();
    const period = ref(180)
    const monthlyData = ref({});
    const lineChartData = ref({});
    const diagnosePieChartData = ref({});
    function getData() {
        lineChartData.value = {}
        countByReceiptTime(period.value).then(res => {
            let arr = res.data
            let date = arr.map(item => item.time);
            let data = arr.map(item => item.total);
            let map = new Map();
            map.set('每日接收任务', data);
            
            lineChartData.value = {
                date,
                map
            };
        })
    }
    function monthly() {
        monthlyData.value = {};
        countByMonthly().then(res => {
            let arr = res.data
            let date = arr.map(item => item.item);
            let data1 = arr.map(item => item["xx"]);
            let data2 = arr.map(item => item["xx"]);
            let data3 = arr.map(item => item["xx"]);
            let data4 = arr.map(item => item["xx"]);
            let data5 = arr.map(item => item["xx"]);
            let map = new Map();
            map.set('任务总数', data1);
            map.set('未开始', data2);
            map.set('进行中', data3);
            map.set('已完成', data4);
            map.set('已发布', data5);
            monthlyData.value = {
                date,
                map
            };
        })
    }
  function typeAndDept() {
        diagnosePieChartData.value = {}
        countByTypeAndDept().then(res => {
            let arr = res.data;
            diagnosePieChartData.value = arr.filter(item => item.type === 'diagnose').map(item => {
                return {"name": item.dept, "value": item.total}
            });
        })
    }
    
    getData();
    monthly();
    typeAndDept();
</script>
<style lang="scss" scoped>
  .dashboard-editor-container {
    padding: 32px;
    background-color: rgb(240, 242, 245);
    position: relative;
    
    .chart-wrapper {
      background: #fff;
      padding: 16px 16px 0;
      margin-bottom: 32px;
    }
  }
  
  @media (max-width: 1024px) {
    .chart-wrapper {
      padding: 8px;
    }
  }
</style>

5、实现效果:

  • 折线图

  • 柱状图
  • 饼图

相关文章
|
6天前
|
存储 JavaScript 数据可视化
vue3+echarts应用——深度遍历html的dom结构并用树图进行可视化
vue3+echarts应用——深度遍历html的dom结构并用树图进行可视化
44 1
|
8月前
|
缓存 JavaScript 数据可视化
echarts在vue3中的使用——其他页面跳转回echarts图表页面时,不显示图表的问题
echarts在vue3中的使用——其他页面跳转回echarts图表页面时,不显示图表的问题
146 0
|
6天前
|
数据采集 数据可视化 小程序
vue3+echarts可视化——记录我的2023编程之旅
vue3+echarts可视化——记录我的2023编程之旅
31 1
|
6天前
|
存储
vue2、vue3分别配置echarts多图表的同步缩放(二)
vue2、vue3分别配置echarts多图表的同步缩放
20 0
|
6天前
|
API
vue2、vue3分别配置echarts多图表的同步缩放(一)
vue2、vue3分别配置echarts多图表的同步缩放
19 0
|
6天前
|
JavaScript 前端开发 数据可视化
前端开发使用 Vue 3 + TypeScript + Pinia + Element Plus + ECharts
前端开发使用 Vue 3 + TypeScript + Pinia + Element Plus + ECharts
49 0
|
6天前
使用vue3实现echarts漏斗图表以及实现echarts全屏放大效果
使用vue3实现echarts漏斗图表以及实现echarts全屏放大效果
31 0
|
6天前
|
容器
vue3中echarts图表的实现
vue3中echarts图表的实现
|
6天前
|
资源调度 数据可视化 前端开发
如何在Vue3中使用Echarts?
如何在Vue3中使用Echarts?
92 1
|
6天前
|
数据可视化
echarts图表坐标轴数据标签添加下划线
echarts图表坐标轴数据标签添加下划线
70 0