使用Echarts结合Canvas实现立体双柱一折线图表

一. 前言

项目中遇到了要用图表展示业务数据的需求,于是引入了echarts———— 一个基于 JavaScript 的开源可视化图表库,echarts最初由百度开发,后交由阿帕奇基金会孵化。
echarts已经在全球范围内得到了广泛的应用。它能够运行在PC和移动设备上,并且兼容当前的主流浏览器。通过ECharts,开发者可以轻松地创建出各种类型的图表,包括折线图、柱状图、饼图、散点图等,从而帮助用户更好地理解和分析数据。本文给大家
分享一下echarts的基本使用方法。
先看效果图:
在这里插入图片描述

二. 使用方法

在我们的页面中引入echarts,准备一个盒子,注意盒子要设置宽度与高度

</template>
	<div class='chart-container' ref='myChart'></div>
</template>

<script>
import * as echarts from 'echarts/core';
export default {

  mounted() {
    this.registerShape();
    this.initChart();
  },
}
</script>

<style scoped>
.chart-container{
	width: 100%;
    height: 100%;
}
</style>

我们这里先准备好柱子,使用Canvas实现柱形

		registerShape() {
            const offsetX = 11;   //这里可调整柱子的宽度
            const offsetY = 8;
            // 绘制左侧面
            const CubeLeft = echarts.graphic.extendShape({
                shape: {
                    x: 0,
                    y: 0,
                },
                buildPath: function(ctx, shape) {
                    const xAxisPoint = shape.xAxisPoint;
                    const c0 = [shape.x, shape.y];
                    const c1 = [shape.x - offsetX, shape.y - offsetY];
                    const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY];
                    const c3 = [xAxisPoint[0], xAxisPoint[1]];
                    ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath();
                },
            });
            // 绘制右侧面
            const CubeRight = echarts.graphic.extendShape({
                shape: {
                    x: 0,
                    y: 0,
                },
                buildPath: function(ctx, shape) {
                    const xAxisPoint = shape.xAxisPoint;
                    const c1 = [shape.x, shape.y];
                    const c2 = [xAxisPoint[0], xAxisPoint[1]];
                    const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY];
                    const c4 = [shape.x + offsetX, shape.y - offsetY];
                    ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
                },
            });
            // 绘制顶面
            const CubeTop = echarts.graphic.extendShape({
                shape: {
                    x: 0,
                    y: 0,
                },
                buildPath: function(ctx, shape) {
                    const c1 = [shape.x, shape.y];
                    const c2 = [shape.x + offsetX, shape.y - offsetY]; //右点
                    const c3 = [shape.x, shape.y - offsetX];
                    const c4 = [shape.x - offsetX, shape.y - offsetY];
                    ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
                },
            });
            // 注册三个面图形
            echarts.graphic.registerShape('CubeLeft', CubeLeft);
            echarts.graphic.registerShape('CubeRight', CubeRight);
            echarts.graphic.registerShape('CubeTop', CubeTop);
        },

初始化echarts实例,我里我以Vue为例,也可以使用id选择元素。

initChart() {
      let echartsDom = this.$refs.myChart;
      let echartInstance = echarts.init(echartsDom);
      let option = {
      	backgroundColor: '#051542', //背景色
        tooltip: {
          trigger: 'axis',
        },
        //这里可以调整图表与容器之间的间距
        grid: {
          left: '10%',
          right: '10%',
          bottom: '10%',
          top: '10%',
          containLabel: false,
        },
        //需要多少系列配置在legend数组里面
        legend: [
          {
            data: [
              {
                name: '员工数量',
              },
            ],
            textStyle: {
              color: '#FFFFFF',
              fontSize: 14,
            },
            left: '10%',
            //这里可以定义系列选择器的样式
            itemHeight: 6,
            itemStyle: {
              color: '#319DEA',
            },
          },
          {
            data: [
              {
                name: '支出工资',
              },
            ],
            textStyle: {
              color: '#FFFFFF',
              fontSize: 14,
            },
            left: 'center',
            itemHeight: 6,
            itemStyle: {
              color: '#23C0BB',
            },
          },
          {
            data: [
              {
                name: '公司营收趋势',
              },
            ],
            textStyle: {
              color: '#FFFFFF',
              fontSize: 14,
            },
            itemHeight: 8,
            itemStyle: {
              color: '#F6AB00',
            },
            right: '10%',
          },
        ],
        xAxis: {
          type: 'category',
          data: [2022,2023,2024],
          axisLine: {
            show: true,
            lineStyle: {
              color: 'rgba(45, 60, 92, 1)',
            },
          },
          axisTick: {
            show: false,
          },
          axisLabel: {
            textStyle: {
              fontFamily: 'Microsoft YaHei',
              color: '#fff', // x轴颜色
              fontWeight: 'normal',
              fontSize: '14',
              lineHeight: 22,
            },
            interval: 0, //标签设置为全部显示
            lineHeight: 15,
          },
        },

        yAxis: [
          {
           //这两个值可定义这条轴的最大刻度与最小刻度,可不写,将自行优化分配刻度
            min: 0,
            max: 800,
            type: 'value',
            name: '个',
            //分成刻度段
            splitNumber: 4,
            nameTextStyle: {
              color: '#fff',
              fontSize: '12px',
            },
            axisLine: {
              show: true,
              lineStyle: {
                color: 'rgba(45, 60, 92, 1)',
              },
            },
            splitLine: {
              show: true,
              lineStyle: {
                color: 'rgba(45, 60, 92, .3)', //左侧显示线
              },
            },
            axisTick: {
              show: false,
            },
            axisLabel: {
              textStyle: {
                color: '#fff',
                fontSize: 14,
              },
            },
          },
          {
            type: 'value',
            name: '元',
            splitNumber: 4,
            nameTextStyle: {
              color: '#fff',
              fontSize: '12px',
            },
            axisLine: {
              show: true,
              lineStyle: {
                color: '#15205B',
              },
            },
            splitLine: {
              show: false,
              lineStyle: {
                color: 'rgba(135,140,147,1)', //左侧显示线
              },
            },
            axisTick: {
              show: true,
            },
            axisLabel: {
              textStyle: {
                color: '#fff',
                fontSize: 14,
              },
            },
          },

          {
            // min: -100,
            // max: 100,
            type: 'value',
            name: '百分比',
            interval: 20,
            offset: 85,
            nameTextStyle: {
              color: '#fff',
              fontSize: '12px',
            },
            splitNumber: 4,
            axisLine: {
              show: true,
              lineStyle: {
                color: '#15205B',
              },
            },
            splitLine: {
              show: false,
              lineStyle: {
                color: 'rgba(135,140,147,1)', //左侧显示线
              },
            },
            axisTick: {
              show: true,
            },
            axisLabel: {
              margin: -31,
              //数据格式
              formatter: '{value}%',
              textStyle: {
                color: '#fff',
                fontSize: 14,
              },
            },
          },

        ],
        series: [
          {
            name: '员工数量',
            type: 'custom',    //使用自定义柱子,这里的type要写 'custom'
            color: '#319DEA',
            yAxisIndex: 0,	   //使用第一个y轴
            renderItem: (params, api) => {
              const location = api.coord([api.value(0), api.value(1)]);
              return {
                x: -14,			//如果多个系列都是用自定义柱子的话,可适当调整x的值
                type: 'group',  //组合
                children: [
                  {
                    type: 'CubeLeft',
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0]),
                    },
                    style: {
                      //这里设置柱子的颜色
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 0,
                          color: 'rgba(57, 206, 255, 1)',
                        },
                        {
                          offset: 1,
                          color: 'rgba(45, 72, 173, 0.1)',
                        },
                      ]),
                    },
                  },
                  {
                    type: 'CubeRight',
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0]),
                    },
                    style: {
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 0,
                          color: 'rgba(57, 206, 255, 1)',
                        },
                        {
                          offset: 1,
                          color: 'rgba(45, 72, 173, 0.1)',
                        },
                      ]),
                    },
                  },
                  {
                    type: 'CubeTop',
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0]),
                    },
                    style: {
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 0,
                          color: 'rgba(57, 206, 255, 1)',
                        },
                        {
                          offset: 1,
                          color: 'rgba(57, 206, 255, 1)',
                        },
                      ]),
                    },
                  },
                ],
              };
            },
            //鼠标悬停时的提示
            tooltip: {
              valueFormatter: function(value) {
                return formatNumber(value) + '个';
              },
            },
            data: [168,256,365],
          },

          {
            name: '支出工资',
            type: 'custom',
            color: '#23C0BB',
            yAxisIndex: 1,
            renderItem: (params, api) => {
              const location = api.coord([api.value(0), api.value(1)]);
              return {
                x: 14,
                type: 'group',
                children: [
                  {
                    type: 'CubeLeft',
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0]),
                    },
                    style: {
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 0,
                          color: 'rgba(49, 213, 199, 1)',
                        },
                        {
                          offset: 1,
                          color: 'rgba(29, 39, 115, 0.1)',
                        },
                      ]),
                    },
                  },
                  {
                    type: 'CubeRight',
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0]),
                    },
                    style: {
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 0,
                          color: 'rgba(49, 213, 199, 1)',
                        },
                        {
                          offset: 1,
                          color: 'rgba(29, 39, 115, 0.1)',
                        },
                      ]),
                    },
                  },
                  {
                    type: 'CubeTop',
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0]),
                    },
                    style: {
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 1,
                          color: 'rgba(49, 213, 199, 1)',
                        },
                        {
                          offset: 1,
                          color: 'rgba(49, 213, 199, 1)',
                        },
                      ]),
                    },
                  },
                ],
              };
            },
            tooltip: {
              valueFormatter: function(value) {
                return formatNumber(value) + '元';
              },
            },
            data: [1608,1256,965]
          },
          {
            name: '公司营收趋势',
            type: 'line',
            smooth: true, //是否使用平滑曲线
            stack: '3',
            yAxisIndex: 2,
            symbol: 'circle',
            symbolSize: 10,
            itemStyle: {
              shadowColor: '#fff',
              shadowBlur: 5,
              color: '#F6AB00',
            },
            tooltip: {
              valueFormatter: function(value) {
                return value + '%';
              },
            },
            data: [25.6,23.9,87.6]
          },
        ],
      };
      myEcharts.setOption(option);
    },

这样一个自定义双柱一折线的echarts图表就实现了,各位觉得怎么样呢,欢迎评论区留言啊!

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值