vue项目开发记录2:echarts绘制渐变镂空条形柱状图

不知道该怎么称呼,总之设计师出图如图所示,要求用echarts绘制。普通的柱状图无法满足如上图形,好在echarts提供了pictorialBar象形柱状图,可以自定义柱的形状。

简单配置如下:

<template>
  <div class="container">
    <div id="chart"></div>
  </div>
</template>
<script setup>
import * as echarts from "echarts";
import { onMounted } from "vue";

const xdata = ref([])
const option = {
  legend: {
    show: false,
  },
  xAxis: {
    data: ['数据1', '数据2', '数据3', '数据4', '数据5'],
  },
  yAxis: {
  },
  series: [
  {
    name: '随机数据',
    type: 'pictorialBar',
    symbol: 'roundRect',
    symbolRepeat: true,
    symbolSize: [20, 10],
    itemStyle: {
      normal: {
        barBorderRadius: 5,
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: "#FBDA61" },
          { offset: 0.5, color: "#FF5ACD" },
          { offset: 1, color: "#FF6A88" }
        ])
      }
    },
    barWidth: 16,
    barGap: 0.2,
    data: xdata.value
  }
  ]
}
function setXdata() {
  // 设置5个随机数作为数据
  for (let i = 0; i < 5; i++) {
    xdata.value.push(Math.floor(Math.random() * 100))
  }
}
onMounted(() => {
  setXdata();
  // 绘制echarts图形
  const chart = echarts.init(document.getElementById('chart');
  chart.setOption(option)
})
</script>
<style scoped>
</style>

得到的效果如下:

上面代码的渐变色被加到了每个单独的roundRect当中,这并不是我想要的效果,我想要的是整体有一个渐变的背景色作为底,上面显示圆角矩形,相当于镂空了固定的形状。

在echarts官网上搜索了半天,接近我想要的效果的是如下的图,用到了symbolClip属性,然而直接尝试之后依旧不行。

转变思路,既然echarts支持柱状图变成自己绘制的任意形状,那我为什么不直接绘制一个圆角矩形堆叠的图形?这样一来所有矩形被视为整体,渐变色自然能整体显示出来。

要想自己绘制形状,就要用到echarts的path进行绘制,官方给出的文档链接如下:

w3 - Paths - SVG 2

SVG的路径绘制非常复杂,研究了下。首先,绘制以path:// 开头,后面跟着用来画图的内容。

画图的内容为字母+数字的形式,字母代表操作,即绘制直线、曲线或者半圆;数字代表参数,不同的操作对应的参数个数不同,但是必定包含坐标。

将需要用到的规则总结如下

1. 画幅坐标:横向为x轴,纵向为y轴,左上角为原点(0, 0)

2. M写在最前面,表示开始,后面紧跟两个坐标,表示起始点的位置。例如 M 10 20 就是将起始点放到(10, 20)的位置,接下来的绘制从此处开始。

3. z写在最后面,表示闭合路径,也就是将z前面到达的点和起始点连接起来。例如 z之前进行的操作停在了(20, 20)的位置,那么加入z之后,自动给(20, 20)和(10, 20)之间绘制一条直线,闭合路径;如果z之前的点与起始点相同,则不做重复

4. 不同的数字之间要加空格间隔开,也可以加逗号;字母和数字之间可以加空格,也可以不加。"M 10 20", "M10, 20"的写法都是合法的,但是不能写成"M,10,20" 或者"M1020"的样子。

5. 绘制直线有3个字母,分别是L(line), H(horizontal), V(vertical)。L后面跟两个坐标,表示从前面的坐标到此坐标连接一条直线;H后面跟一个坐标x1,表示从前面的(x0, y)到(x1, y)绘制一条直线;V后面跟一个坐标y1,表示从前面的(x, y0)到(x, y1)绘制一条直线。形象化如图所示:

6. 绘制圆弧用到的字母是A,这个比较复杂,后面跟着7个参数,(rx ry x-axis-rotation large-arc-flag sweep-flag x y),前两个参数是x方向和y方向上的半径,如果一样,绘制出的就是圆形,不一样就可以绘制出椭圆;最后两个参数是弧线停止的位置;中间三个参数都是布尔值,官网上分别提供了0 1 0和0 0 0的案例,目前我不知道x-axis-rotation和sweep-flag是做什么用的,中间的large-arc-flag表示的是你要大的圆弧还是小的圆弧,例如,设置(10, 0)为起点,(0, 10)为终点,10为半径,large-arc-flag设置为0的时候绘制1/4圆,设置为1时绘制3/4圆。

知道了以上的内容,就可以开始绘制了!

因为ehcarts会将path生成的svg图像进行自适应,所以不用设置成实际的宽度和高度,暂定为宽100高40的矩形,矩形之间的距离为10.

示意图如下:

根据上面学习到的内容,可以轻松写出最上方矩形对应的path路径

M0 10 A10 10 0 0 1 10 0 H90 A10 10 0 0 1 100 10 V30 A10 10 0 0 1 90 40 H10 A10 10 0 0 1 0 30 V10z

因为形状是竖向摞着的,所以每次变化的只有y坐标。将y坐标替换为变量。

将之前的代码修改一下,可以得到最终的结果。

import * as echarts from "echarts";
import { onMounted } from "vue";

const xdata = ref([])
const option = {
  legend: {
    show: false,
  },
  xAxis: {
    data: ['数据1', '数据2', '数据3', '数据4', '数据5'],
  },
  yAxis: {
  },
  series: [
  {
    name: '随机数据',
    type: 'pictorialBar',
    symbolRepeat: false, // 不再需要设置symbol的形状,采用自定义形状
    itemStyle: {
      normal: {
        barBorderRadius: 5,
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: "#FBDA61" },
          { offset: 0.5, color: "#FF5ACD" },
          { offset: 1, color: "#FF6A88" }
        ])
      }
    },
    barWidth: 16,
    barGap: 0.2,
    data: xdata.value
  }
  ]
}
function setXdata() {
  // 设置5个随机数作为数据
  for (let i = 0; i < 5; i++) {
    xdata.value.push(Math.floor(Math.random() * 100))
  }
  // 获取最大值,用来计算步数
  const maxVal = Math.floor(Math.max(...xdata));
  // 处理数据
  xdata = xdata.map(item => {
    let str = 'path://'; //path字符串
    let step = item / maxVal * 20; //步数,即要绘制多少个圆角矩形,可以自定义
    let pos = 0; //从0位置开始
    for (let i = 0; i < step; i++) {
      str += `M0 ${pos + 10} A10 10 0 0 1 10 ${pos} H90 A10 10 0 0 1 100 ${pos + 10} V${pos + 30} A10 10 0 0 1 90 ${pos + 40} H10 A10 10 0 0 1 0 ${pos + 30} V${pos + 10} `;
      pos += 50;
    }
    str += 'z'; //闭合路径
    return {
      value: item,
      symbolClip: true, //为每个柱设置形状
      symbol: str
    }
  })
}
onMounted(() => {
  setXdata();
  // 绘制echarts图形
  const chart = echarts.init(document.getElementById('chart');
  chart.setOption(option)
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值