ECharts.js

  • 这也是一款基于HTML5的图形库。图形的创建也比较简单,直接引用Javascript即可。
  • 使用这个库的原因主要有三点
    • 一个是因为这个库是百度的项目,而且一直有更新,目前最新的是EChart 5;
    • 第二个是这个库的项目文档比较详细,每个点都说明的比较清楚,而且是中文的,理解比较容易;
    • 第三点是这个库支持的图形很丰富,并且可以直接切换图形,使用起来很方便。
  • echarts.apache.org
  • [Documentation - Apache ECharts](https://echarts.apache.org/zh/tutorial.html#ECharts 5 Upgrade Guide)

小案例

  • 小案例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    <!DOCTYPE html>
    <body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="height:400px"></div>
    <!-- ECharts单文件引入 -->
    <script crossorigin="anonymous" src="https://lib.baomitu.com/echarts/5.1.2/echarts.common.js"></script>
    <script type="text/javascript">
    // 路径配置
    require.config({
    paths: {
    echarts: 'http://echarts.baidu.com/build/dist'
    }
    });

    // 使用
    require(
    [
    'echarts',
    'echarts/chart/bar' // 使用柱状图就加载bar模块,按需加载
    ],
    function (ec) {
    // 基于准备好的dom,初始化echarts图表
    var myChart = ec.init(document.getElementById('main'));

    var option = {
    tooltip: {
    show: true
    },
    legend: {
    data:['销量']
    },
    xAxis : [
    {
    type : 'category',
    data : ["苹果","三星","小米","华为","oppo","酷派"]
    }
    ],
    yAxis : [
    {
    type : 'value'
    }
    ],
    series : [
    {
    "name":"销量",
    "type":"bar",
    "data":[100, 120, 150, 160, 220, 80]
    }
    ]
    };

    // 为echarts对象加载数据
    myChart.setOption(option);
    }
    );
    </script>
    </body>
    </html>

CEharts进行步骤讲解

  1. 第一步,引用Js文件

    1
    <script type="text/javascript" src="js/echarts.js"></script>
  2. 第一步,准备一个放图表的容器

    1
    <div id="main" style="width:600px; height: 400px;"></div>
  3. 第三步,设置参数,初始化图表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <script type="text/javascript">
    //指定图标的配置和数据
    var option = {
    title:{
    text:'数据统计'
    },
    tooltip:{},
    legend:{
    data:['手机销量']
    },
    xAxis:{
    data:["苹果","小米","华为","三星"]
    },
    yAxis:{

    },
    series:[{
    name:'销量',
    type:'line',
    data:[800,1000,1300,400]
    }]
    };
    //初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'));

    //使用制定的配置项和数据显示图表
    myChart.setOption(option);
    </script>

引入echarts

  • 使用 npm 引入echarts

    1
    npm install echarts --save
  • 4.X版本

    1
    2
    3
    import echarts from ('echarts');
    // 按需导入
    import echarts from 'echarts/lib/echarts'
  • 5.X版本去除了 defautl exports的支持

    1
    2
    3
    4
    5
    import * as echarts from ('echarts');
    // 按需导入
    import * as echarts from 'echarts/lib/echarts'
    // require引入
    const echarts = require('echarts');
  • 5.X 新增了按需导入接口

    • ECharts 按需引入的时候不再提供任何渲染器,所以需要选择引入CanvasRenderer或者SVGRenderer作为渲染器。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
    import * as echarts from 'echarts/core';
    // 引入柱状图图表,图表后缀都为 Chart
    import {
    BarChart
    } from 'echarts/charts';
    // 引入提示框,标题,直角坐标系组件,组件后缀都为 Component
    import {
    TitleComponent,
    TooltipComponent,
    GridComponent
    } from 'echarts/components';
    // 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
    import {
    CanvasRenderer
    } from 'echarts/renderers';

    // 注册必须的组件
    echarts.use(
    [TitleComponent, TooltipComponent, GridComponent, BarChart, CanvasRenderer]
    );

    // 接下来的使用就跟之前一样,初始化图表,设置配置项
    var myChart = echarts.init(document.getElementById('main'));
    myChart.setOption({
    ...
    });

封装ECharts组件

  • 在 utils 文件夹下,新建了一个 echartsUi.js 文件 (这个文件存放位置,依据自己需求)按照官方介绍,按需引用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
    import * as echarts from "echarts/core";
    // const echarts = require('echarts/core');
    // 引入各种图表,图表后缀都为 Chart
    import { BarChart, PieChart } from "echarts/charts"; //这里我引用两个类型的图表
    // 引入提示框,标题,直角坐标系等组件,组件后缀都为 Component
    import {
    TitleComponent,
    TooltipComponent,
    GridComponent,
    LegendComponent,
    // GeoCoComponent
    } from "echarts/components";
    // 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
    import { CanvasRenderer } from "echarts/renderers";

    // 注册必须的组件
    echarts.use([
    TitleComponent,
    TooltipComponent,
    GridComponent,
    LegendComponent,
    BarChart,
    PieChart,
    CanvasRenderer,
    ]);

    export default echarts;
  • 在 main.js 文件中引入 echats.js 并注册使用

    1
    2
    import echarts from "@/utils/echartsUi";
    Vue.prototype.$echarts = echarts;
  • 在 components 下新建 Echat.vue

    1
    2
    3
    4
    5
    <!-- Echarts组件 -->
    <template>
    <!--图表展示在这个div中-->
    <div style="height: 100%;width:100%" ref="echart"></div>
    </template>

基本图形

  • 折线图示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    option = {
    xAxis: {
    type: "category",
    data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    },
    yAxis: {
    type: "value",
    },
    series: [
    {
    data: [150, 230, 224, 218, 135, 147, 260],
    type: "line",
    },
    ],
    };

  • 柱状图示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
option = {
xAxis: {
type: "category",
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
},
yAxis: {
type: "value",
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: "bar",
showBackground: true,
backgroundStyle: {
color: "rgba(180, 180, 180, 0.2)",
},
},
],
};

  • 柱状图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
option = {
title: {
text: "某站点用户访问来源",
subtext: "纯属虚构",
left: "center",
},
tooltip: {
trigger: "item",
},
legend: {
orient: "vertical",
left: "left",
},
series: [
{
name: "访问来源",
type: "pie",
radius: "50%",
data: [
{ value: 1048, name: "搜索引擎" },
{ value: 735, name: "直接访问" },
{ value: 580, name: "邮件营销" },
{ value: 484, name: "联盟广告" },
{ value: 300, name: "视频广告" },
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 11.5)",
},
},
},
],
};

组件参数与方法

  • 通过分析: xAxis, yAxis, series 这三个属性就能确定图形,其他的图形和信息暂时不关心。

  • 在mount加载dom后渲染图像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <script>
    export default {
    data() {
    return {
    option: {}
    };
    },

    //方法集合
    methods: {
    initEcharts() {
    this.echart = this.$echarts.init(this.$refs.echart);
    this.echart.setOption(this.option);
    }
    },

    //挂载完成 访问DOM元素
    mounted() {
    this.initEcharts();
    }
    };
    </script>

组件传值

  • 暴露二个属性

    • chartData : Option的数据{ xData: [], series: []}
    • isAxisChart: 是后带有x轴(默认折线图,柱状图)
  • 处理数据

    • computed: 支持缓存,只有依赖数据变化触发计算,不支持异步操作
    • watch:不支持缓存,支持异步,会监听旧值和新值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    computed: {
    //计算 选择是有x轴 还是没有
    options() {
    return this.isAxisChart ? this.axisOption : this.normalOption
    }
    },
    watch: {
    //监听chartData数据
    chartData: {
    handler: function() {
    this.initChart()
    },
    deep: true
    }
    },
    methods: {
    initChart() {
    //获取处理好的数据
    this.initChartData();
    //获取echart对象
    if (!this.echart) {
    //通过refs获取
    this.echart = this.$echarts.init(this.$refs.echart);
    }
    this.echart.setOption(this.options);
    },
    //处理好数据
    initChartData() {
    if (this.isAxisChart) {
    this.axisOption.xAxis.data = this.chartData.xData
    this.axisOption.series = this.chartData.series
    } else {
    this.normalOption.series = this.chartData.series
    }
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    data() {
    return {
    echart: null,
    //在数据中有些数据在数据件中是写死的
    axisOption: {
    legend: {
    textStyle: {
    color: '#333'
    }
    },
    grid: {
    left: '20%'
    },
    tooltip: {
    trigger: 'axis'
    },
    xAxis: {
    type: 'category',
    data: [],

    },
    axisLabel: {
    color: '#333'
    }
    },
    yAxis: [
    {
    type: 'value',
    axisLine: {
    lineStyle: {
    color: '#17b3a3'
    }
    }
    }
    ],
    color: [
    '#2ec7c9',
    '#b6a2de',
    '#5ab1ef',
    '#ffb980',
    '#d87a80',
    '#8d98b3',
    '#e5cf0d',
    '#97b552',
    '#95706d',
    '#dc69aa',
    '#07a2a4',
    '#9a7fd1',
    '#588dd5',
    '#f5994e',
    '#c05050',
    '#59678c',
    '#c9ab00',
    '#7eb00a',
    '#6f5553',
    '#c14089'
    ],
    series: []
    },
    normalOption: {
    tooltip: {
    trigger: 'item'
    },
    color: [
    '#0f78f4',
    '#dd536b',
    '#9462e5',
    '#a6a6a6',
    '#e1bb22',
    '#39c362',
    '#3ed1cf'
    ],
    series: []
    }
    };
    }

    图表尺寸改变

    • 改变图表尺寸,在容器大小发生改变时需要手动调用(因为侧边栏是可以收缩的,所以这里图表根据是否收缩来改变图表尺寸)

      1
      2
      3
      4
      5
      6
      7
      8
      methods: {
      resizeChart() {
      this.echart ? this.echart.resize() : ''
      }
      },
      mounted() {
      window.addEventListener('resize', this.resizeChart)
      }
    • 销毁

      1
      2
      3
      destroyed() {
      window.removeEventListener('resize', this.resizeChart)
      }

问题

  • 在使用组件的时候,发现chartData 传递数据后,watch的监控没有生效

  • 尝试开启watch的 immediate: true 后,第一次访问也能够看到数据了

  • 但是页面没有图形,发现控制台有错误

  • 改变思路,在mount生命周期内,dom已经完成,这个时候去初始化echart,取消immediate 属性, 成功显示属性

    1
    2
    3
    4
    //挂载完成 访问DOM元素
    mounted() {
    this.initChart();
    },

优化菜单栏折叠

  • 在测试的过程中,当菜单折叠后并不会触发resize操作,我们可以对其进行监控,手动调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    computed: {
    //用于下面的resize 改变图表尺寸,在容器大小发生改变时需要手动调用
    isCollapse() {
    return this.$store.state.tab.isCollapse;
    }
    },
    watch: {
    //监听isCollapse 因为头部水平扩展是一个动画需要时间,所以这里延迟300毫秒
    isCollapse() {
    setTimeout(() => {
    this.resizeChart();
    }, 300);
    }
    },