vue整合Echart图表柱形图 动态容器大小 饼形图vue使用柱形图 vue使用 echart图表柱形图饼形图 vue使用柱形图饼形图实现 容器大小根据浏览器屏幕大小变化,异步加载数据

11 篇文章 1 订阅

vue整合Echart图表柱形图 动态容器大小 饼形图vue使用柱形图 vue使用 echart图表柱形图饼形图 vue使用柱形图饼形图实现 容器大小根据浏览器屏幕大小变化,异步加载数据

1、安装依赖

官方文档:https://echarts.apache.org/zh/option.html#title

官方在线示例:https://echarts.apache.org/examples/zh/index.html

npm i echarts

Vue2

柱形图

2.1 效果图

在这里插入图片描述

2.2 页面Demo

<template>
  <div id="main">
    <div>
      <div id="chart" />
    </div>
  </div>
</template>
<script>

import echarts from 'echarts'
export default {
  // 组件名称
  name: 'Index',
  // import引入的组件需要注入到对象中才能使用
  components: {},
  // 父组件传递值
  props: {
  },
  data() {
    // 这里存放数据
    return {
      myChart: {}
    }
  },
  // 监听属性 类似于data概念
  computed: {},
  // 监控data中的数据变化
  watch: {},
  // 生命周期 - 创建完成(可以访问当前this实例)
  created() {
  },
  // 生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
    // 数据
    const title = '我是柱形图标题'
    const subtext = '我是简介标题'
    const chartData = [
      [
        96, // 柱形图的二维数据,如果是横向的 数据值必须要在第一位,如果是纵向标题值必须要是第一位
        '华为'
      ],
      [
        90,
        '苹果'

      ],
      [
        80,
        '小米'

      ],
      [
        20,
        '菠萝手机'
      ],
      [
        92,
        'VIVO'
      ]
    ]

    // 计算图表容器高度,自动根据数据大小改变而改变
    let containerHeight = 600
    if (chartData.length <= 1) {
      containerHeight = 600
    } else {
      containerHeight = chartData.length * 50 // 假设每个柱形的宽度/高度为 50
    }
    
    // 初始化图表
    const chartDom = document.getElementById('main')
    this.myChart = echarts.init(chartDom, 'dark', {
      devicePixelRatio: 1,
      renderer: 'svg', // 使用 canvas 渲染可能比使用 svg 渲染更高效
      width: document.getElementById('main').offsetWidth, // 获取一个DIV,使用这个DIV的可视化宽度作为图表的宽度
      height: containerHeight
    })

    // 赋值图表数据
    const option = {
      backgroundColor: 'linear-gradient(15deg, #13547a 0%, #80d0c7 100%)', // 设置背景颜色
      animation: false, // 禁用动画效果
      title: {
        text: title,
        subtext: subtext
      },
      dataset: {
        source: chartData
      },
      grid: { containLabel: true },
      xAxis: { name: '我是小标题哈哈哈' },
      yAxis: { type: 'category' },
      series: [
        {
          type: 'bar',
          barWidth: '50%',
          barCategoryGap: 10, // 原理是减小柱状图的宽度
          encode: {
            // Map the "value" column to X axis.
            x: 'value',
            // Map the "amount" column to Y axis.
            y: 'title'
          },
          label: {
            show: true, // 设置为 true 显示标签
            position: 'top', // 设置标签位置,可以是 'top', 'insideTop', 'insideBottom' 等
            color: 'black', // 设置标签颜色
            distance: 0, // 距离图形元素的距离。
            formatter: function(params) {
              // 格式化 数值内容
              return params.data[0] + ' %'
            },
            textStyle: {
              color: 'white' // 设置字体颜色
            },
            padding: [4, 5],
            lineHeight: 26,
            // eslint-disable-next-line no-dupe-keys
            position: 'right',
            // eslint-disable-next-line no-dupe-keys
            distance: 5,
            fontSize: 12
          },
          showBackground: true,
          itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: '#ffffff' },
              { offset: 0.5, color: '#ffffff' },
              { offset: 1, color: '#ffffff' }
            ])
          }
        }
      ]
    }
    this.myChart.setOption(option)
  },
  beforeCreate() { }, // 生命周期 - 创建之前
  beforeMount() { }, // 生命周期 - 挂载之前
  beforeUpdate() { }, // 生命周期 - 更新之前
  updated() { }, // 生命周期 - 更新之后
  beforeDestroy() { }, // 生命周期 - 销毁之前
  destroyed() { }, // 生命周期 - 销毁完成
  activated() {
  },
  // 方法集合
  methods: {
  }
}
</script>
<style>
</style>

饼形图

3.1 效果图

在这里插入图片描述

3.2 页面Demo

<template>
  <div id="main">
    <div>
      <div id="chart" />
    </div>
  </div>
</template>
<script>

import echarts from 'echarts'
export default {
  // 组件名称
  name: 'Index',
  // import引入的组件需要注入到对象中才能使用
  components: {},
  // 父组件传递值
  props: {
  },
  data() {
    // 这里存放数据
    return {
      myChart: {}
    }
  },
  // 监听属性 类似于data概念
  computed: {},
  // 监控data中的数据变化
  watch: {},
  // 生命周期 - 创建完成(可以访问当前this实例)
  created() {
  },
  // 生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
    // 数据
    const title = '我是饼形图标题'
    const subtext = '我是简介标题'
    const chartData = [
      {
        'name': '人口红利阿萨德',
        'value': 8.00
      },
      {
        'name': '123123',
        'value': 16.00
      },
      {
        'name': '4.请问请问',
        'value': 16.00
      },
      {
        'name': '4.企鹅群翁去',
        'value': 8.00
      },
      {
        'name': '啊实打实大时代啊',
        'value': 8.00
      },
      {
        'name': '123啊实打实多',
        'value': 16.00
      },
      {
        'name': '阿萨德阿萨德请问qweqwe13213 ',
        'value': 16.00
      },
      {
        'name': '阿达四大1321323',
        'value': 8.00
      }
    ]

    // 初始化图表
    const chartDom = document.getElementById('main')
    this.myChart = echarts.init(chartDom, 'dark', {
      devicePixelRatio: 1,
      renderer: 'svg', // 使用 canvas 渲染可能比使用 svg 渲染更高效
      width: document.getElementById('main').offsetWidth, // 获取一个DIV,使用这个DIV的可视化宽度作为图表的宽度
      height: 800
    })

    // 赋值图表数据
    const option = {
      backgroundColor: 'linear-gradient(15deg, #13547a 0%, #80d0c7 100%)', // 设置背景颜色
      title: {
        text: `${title}`,
        subtext: `${subtext}`,
        left: 'center'
      },
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: ({d}%)' // {a} 表示系列名称,{b} 表示数据项的名称,{c} 表示数据项的值,{d} 表示百分比
      },
      legend: {
        orient: 'vertical',
        left: 'left'
      },
      series: [
        {
          name: '不良现象占比',
          type: 'pie',
          radius: '50%',
          data: chartData,
          label: {
            show: true,
            formatter: '{b}:  ({d}%)' // {b} 表示数据项的名称,{c} 表示数据项的值,{d} 表示百分比
          },
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          }
        }
      ]
    }
    this.myChart.setOption(option)
  },
  beforeCreate() { }, // 生命周期 - 创建之前
  beforeMount() { }, // 生命周期 - 挂载之前
  beforeUpdate() { }, // 生命周期 - 更新之前
  updated() { }, // 生命周期 - 更新之后
  beforeDestroy() { }, // 生命周期 - 销毁之前
  destroyed() { }, // 生命周期 - 销毁完成
  activated() {
  },
  // 方法集合
  methods: {
  }
}
</script>
<style>
</style>

Vue3

实现 容器大小根据浏览器屏幕大小变化,异步加载数据 在线演示

在这里插入图片描述

完整代码

<template>
    <div class="main-div bg" id="main">
        <div class="echart-button">
            <button @click="loadAsyncData1()">重新赋值数据</button>
            <button @click="loadAsyncData2()">还原默认数据</button>
        </div>
        <div class="echart-content">

            <div id="myChart1" class="echart-c" :style="{ width: computeWidth }" />
            <div id="myChart2" class="echart-c" :style="{ width: computeWidth }" />
            <div id="myChart3" class="echart-c" :style="{ width: computeWidth }" />
        </div>
    </div>
</template>

<script setup lang="ts">

// 引入 Echart
import * as echarts from "echarts";

import { ref, shallowRef, onActivated, onMounted } from 'vue'


// 定义三个 echart实例, 不能使用 ref存储echart实例,需要使用 shallowRef(https://cn.vuejs.org/api/reactivity-advanced.html#shallowref),具体原因:https://echarts.apache.org/zh/faq.html#others
const myChart1 = shallowRef({})
const myChart2 = shallowRef({})
const myChart3 = shallowRef({})


// 定义 echart图表标题文字样式
const titleStyle = {
    color: 'white', // 标题颜色
    fontSize: 18, // 标题字体大小
    fontWeight: 'bold', // 标题字体粗细
    fontFamily: 'Inter, system-ui, Avenir, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB","Microsoft YaHei", "微软雅黑", Arial, sans-serif', // 标题字体
}

// 定义 echart图表 legend标题文字样式
const legendStyle = {
    color: 'white', // 标题颜色
    fontSize: 10, // 标题字体大小
    fontFamily: 'Inter, system-ui, Avenir, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB","Microsoft YaHei", "微软雅黑", Arial, sans-serif', // 标题字体
}

// 定义三个echart实例对应的option

// 折线图
const option1 = ref({
    title: {
        text: '折线图示例',
        textStyle: titleStyle,
        left: 'right'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine'],
        textStyle: legendStyle
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    toolbox: {
        feature: {
            saveAsImage: {}
        }
    },
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            name: 'Email',
            type: 'line',
            stack: 'Total',
            data: [120, 132, 101, 134, 90, 230, 210]
        },
        {
            name: 'Union Ads',
            type: 'line',
            stack: 'Total',
            data: [220, 182, 191, 234, 290, 330, 310]
        },
        {
            name: 'Video Ads',
            type: 'line',
            stack: 'Total',
            data: [150, 232, 201, 154, 190, 330, 410]
        },
        {
            name: 'Direct',
            type: 'line',
            stack: 'Total',
            data: [320, 332, 301, 334, 390, 330, 320]
        },
        {
            name: 'Search Engine',
            type: 'line',
            stack: 'Total',
            data: [820, 932, 901, 934, 1290, 1330, 1320]
        }
    ]
})
// 柱形图
const option2 = ref({
    title: {
        text: '柱形图',
        subtext: 'Fake Data',
        left: 'right',
        textStyle: titleStyle
    },
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow'
        }
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    xAxis: [
        {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
            axisTick: {
                alignWithLabel: true
            }
        }
    ],
    yAxis: [
        {
            type: 'value'
        }
    ],
    series: [
        {
            name: 'Direct',
            type: 'bar',
            barWidth: '60%',
            data: [10, 52, 200, 334, 390, 330, 220]
        }
    ]
})
// 饼状图
const option3 = ref({
    title: {
        text: '饼状图',
        subtext: 'Fake Data',
        left: 'right',
        textStyle: titleStyle
    },
    tooltip: {
        trigger: 'item'
    },
    legend: {
        orient: 'vertical',
        left: 'left',
        textStyle: legendStyle
    },
    series: [
        {
            name: 'Access From',
            type: 'pie',
            radius: '50%',
            data: [
                { value: 1048, name: 'Search Engine' },
                { value: 735, name: 'Direct' },
                { value: 580, name: 'Email' },
                { value: 484, name: 'Union Ads' },
                { value: 300, name: 'Video Ads' }
            ],
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
        }
    ]
})

// 初始化所有echart图表
async function initAll() {

    // 等待宽度计算完成
    await computeWidthFun()

    // 初始化 dom图表
    myChart1.value = echarts.init(document.getElementById("myChart1"), null, { renderer: 'canvas' });
    myChart2.value = echarts.init(document.getElementById("myChart2"), null, { renderer: 'canvas' });
    myChart3.value = echarts.init(document.getElementById("myChart3"), null, { renderer: 'canvas' });

    console.info('图表DOM初始化完成,开始绘制图表')

    // 绘制图表数据
    myChart1.value.setOption(option1.value);
    myChart2.value.setOption(option2.value);
    myChart3.value.setOption(option3.value);
}
// 销毁所有echart图表
async function destroyAll() {
    myChart1.value.dispose()
    myChart2.value.dispose()
    myChart3.value.dispose()
}

// 动态计算 echart图表容器宽度
const computeWidth = ref('0px')

// 计算宽方法, 必须要等待宽度计算完成之后在渲染图表,不然会导致渲染图表的时候,框度还没计算出来,无法正常显示, 使用 async + Promise函数实现
async function computeWidthFun() {
    return new Promise<void>((resolve) => {
        // 当前屏幕可视化宽
        const clientWidth = document.getElementById('main').clientWidth
        // 计算三个容器平均宽度,需要去掉 padding、margin-left的宽
        computeWidth.value = (clientWidth / 3) - 24 + 'px'
        console.info('单个容器宽:', computeWidth.value)
        resolve()
    })

}

// 模拟异步加载数据
async function loadAsyncData1() {
    // 异步加载数据官网实例:https://echarts.apache.org/handbook/zh/how-to/data/dynamic-data

    // 重新绘制图表数据, 直接修改 option的数据
    const copyOption1 = option1.value
    const copyOption2 = option2.value
    const copyOption3 = option3.value

    copyOption1.series = [
        {
            name: 'Email',
            type: 'line',
            stack: 'Total',
            data: [820, 932, 901, 934, 1290, 1330, 1320]
        },
        {
            name: 'Union Ads',
            type: 'line',
            stack: 'Total',
            data: [150, 232, 22, 154, 190, 330, 410]
        },
        {
            name: 'Video Ads',
            type: 'line',
            stack: 'Total',
            data: [320, 332, 301, 334, 390, 330, 320]
        },
        {
            name: 'Direct',
            type: 'line',
            stack: 'Total',
            data: [220, 182, 191, 234, 290, 330, 310]
        },
        {
            name: 'Search Engine',
            type: 'line',
            stack: 'Total',
            data: [13213, 132, 101, 134, 90, 230, 210]
        }
    ]

    copyOption2.series = [
        {
            name: 'Direct',
            type: 'bar',
            barWidth: '60%',
            data: [300, 123, 22, 66, 22, 111, 800]
        }
    ]

    copyOption3.series = [
        {
            name: 'Access From',
            type: 'pie',
            radius: '50%',
            data: [
                { value: 10, name: 'Search Engine' },
                { value: 666, name: 'Direct' },
                { value: 580, name: 'Email' },
                { value: 122, name: 'Union Ads' },
                { value: 88, name: 'Video Ads' }
            ],
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
        }
    ]

    // 赋值
    myChart1.value.setOption(copyOption1);
    myChart2.value.setOption(copyOption2);
    myChart3.value.setOption(copyOption3);

}

// 还原默认数据
async function loadAsyncData2() {
    // 重新绘制图表数据, 重新赋值原option
    const copyOption1 = option1.value
    const copyOption2 = option2.value
    const copyOption3 = option3.value

    copyOption1.series = [
        {
            name: 'Email',
            type: 'line',
            stack: 'Total',
            data: [120, 132, 101, 134, 90, 230, 210]
        },
        {
            name: 'Union Ads',
            type: 'line',
            stack: 'Total',
            data: [220, 182, 191, 234, 290, 330, 310]
        },
        {
            name: 'Video Ads',
            type: 'line',
            stack: 'Total',
            data: [150, 232, 201, 154, 190, 330, 410]
        },
        {
            name: 'Direct',
            type: 'line',
            stack: 'Total',
            data: [320, 332, 301, 334, 390, 330, 320]
        },
        {
            name: 'Search Engine',
            type: 'line',
            stack: 'Total',
            data: [820, 932, 901, 934, 1290, 1330, 1320]
        }
    ]

    copyOption2.series = [
        {
            name: 'Direct',
            type: 'bar',
            barWidth: '60%',
            data: [10, 52, 200, 334, 390, 330, 220]
        }
    ]

    copyOption3.series = [
        {
            name: 'Access From',
            type: 'pie',
            radius: '50%',
            data: [
                { value: 1048, name: 'Search Engine' },
                { value: 735, name: 'Direct' },
                { value: 580, name: 'Email' },
                { value: 484, name: 'Union Ads' },
                { value: 300, name: 'Video Ads' }
            ],
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
        }
    ]

    // 赋值
    myChart1.value.setOption(copyOption1);
    myChart2.value.setOption(copyOption2);
    myChart3.value.setOption(copyOption3);
}

// 缓存组件重新打开
onActivated(() => {
    window.document.title = 'Echart示例'
})

// 页面初始化完成生命周期
onMounted(async () => {
    // 初始化图表
    await initAll()

    // 监听浏览器宽大小变化,重新初始化图表
    window.addEventListener('resize', async function () {
        // 销毁容器
        await destroyAll()

        // 重新初始化
        await initAll()
    });
})

</script>

<style scoped>
.main-div {
    height: calc(100vh - 60px);
    position: absolute;
    margin-top: 60px;
    width: 100%;
}

.bg {
    background-color: #522546;
}

.echart-c {
    float: left;
    width: 600px;
    height: 500px;
    background-color: #311d3f;
    margin-left: 10px;
    border-radius: 5px;
    padding: 10px 5px;
}

.echart-button {
    margin-top: 40px;
}

.echart-button button {
    background-color: #88304e;
    padding: 10px 60px;
    color: white;
    border-radius: 10px;
    border: none;
    margin: 0px 5px;
    cursor: pointer;
}

.echart-content {
    margin-top: 40px;
}
</style>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是在Vue使用echarts形图的步骤: 1.首先,在Vue项目中安装echarts: ```shell npm install echarts --save ``` 2.在需要使用形图的组件中引入echarts: ```javascript import echarts from 'echarts' ``` 3.在组件中定义一个方法来初始化echarts图表: ```javascript methods: { initChart() { let myChart = echarts.init(this.$refs.chart) myChart.setOption({ // 形图的配置项 // ... }) } } ``` 4.在组件的mounted钩子函数中调用initChart方法: ```javascript mounted() { this.initChart() } ``` 5.在组件的模板中添加一个div元素来渲染echarts图表: ```html <template> <div ref="chart" style="width: 100%; height: 400px;"></div> </template> ``` 6.根据需要配置形图数据和样式,例如: ```javascript myChart.setOption({ title: { text: '形图示例', left: 'center' }, tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' }, legend: { orient: 'vertical', left: 10, data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'] }, series: [ { name: '访问来源', type: 'pie', radius: ['50%', '70%'], avoidLabelOverlap: false, label: { show: false, position: 'center' }, emphasis: { label: { show: true, fontSize: '30', fontWeight: 'bold' } }, labelLine: { show: false }, data: [ {value: 335, name: '直接访问'}, {value: 310, name: '邮件营销'}, {value: 234, name: '联盟广告'}, {value: 135, name: '视频广告'}, {value: 1548, name: '搜索引擎'} ] } ] }) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值