玩转ECharts之实现“环形渐变”

11,902 阅读4分钟

前言

玩转ECharts系列,主要为大家讲解我们基于ECharts如何实现企业级大屏项目中较为常用的各种奇奇怪怪的图表,接下来我们将通过几篇文章从基础图表开始为大家详细讲解实现这些图表样式的一些“小心机”。

导读

阅读完此文,你会了解基于ECharts:
1、如何实现线性渐变
2、如何用线性渐变模拟环形渐变
3、如何动态计算环形渐变的方向

知识点

series-pie.data.itemStyle. color属性为例,对color属性赋值可以实现线性渐变、径向渐变、纹理填充等。 赋值方式如下:

代码

// 线性渐变,前四个参数分别是 x0, y0, x2, y2, 范围从 0 - 1,相当于在图形包围盒中的百分比,如果 globalCoord 为 `true`,则该四个值是绝对的像素位置
color: {
    type: 'linear',
    x: 0,
    y: 0,
    x2: 0,
    y2: 1,
    colorStops: [{
        offset: 0, color: 'red' // 0% 处的颜色
    }, {
        offset: 1, color: 'blue' // 100% 处的颜色
    }],
    global: false // 缺省为 false
}
// 径向渐变,前三个参数分别是圆心 x, y 和半径,取值同线性渐变
color: {
    type: 'radial',
    x: 0.5,
    y: 0.5,
    r: 0.5,
    colorStops: [{
        offset: 0, color: 'red' // 0% 处的颜色
    }, {
        offset: 1, color: 'blue' // 100% 处的颜色
    }],
    global: false // 缺省为 false
}
// 纹理填充
color: {
    image: imageDom, // 支持为 HTMLImageElement, HTMLCanvasElement,不支持路径字符串
    repeat: 'repeat' // 是否平铺,可以是 'repeat-x', 'repeat-y', 'no-repeat'
}

核心代码

今天主要用到的知识点为线性渐变 :

color: {   
    type: 'linear',
    x: 0,
    y: 0,
    x2: 0,
    y2: 1,
    colorStops: [{
        offset: 0, color: 'red' // 0% 处的颜色
    }, {
        offset: 1, color: 'blue' // 100% 处的颜色
    }],
    global: false // 缺省为 false
}

说明

线性渐变,前四个参数分别是 x, y, x2, y2, 范围从 0 - 1,相当于在图形包围盒中的百分比。x,y构成A点,x2,y2构成B点,A点到B点的方向即为线性渐变的方向。

colorStops定义开始和结束点的颜色。

实现线性渐变

参考示例:gallery.echartsjs.com/editor.html…

核心代码

"itemStyle": {
  "color": {
      "x": 1,
      "y": 0,
      "x2": 1,
      "y2": 1,
      "type": "linear",
      "global": false,
      "colorStops": [{
          "offset": 0,
          "color": "rgba(21, 118, 210, 0)"
      },{
          "offset": 1,
          "color": "rgba(21, 118, 210, 1)"
      }]
  }
}

说明

给每个饼图数据的itemStyle.color赋线性渐变,根据我们给定的颜色修改一下不透明度作为渐变的起止颜色。

效果

可以看出直接应用线性渐变的效果并不好,主要原因是渐变方向和图形方向不一致,表现层次不明确、**没有方向感。**接下来我们来解决它。

注意:图中亮色部分仅为说明渐变方向,实际应用中请勿如此。

线性渐变模拟环形渐变

参考示例:gallery.echartsjs.com/editor.html…

效果

效果有了明显的提升,但很不幸我们没法手动计算每一个环形的方向,接下来我们来介绍如何动态计算环形渐变的方向。

说明

我们修改了每一个线性渐变的方向,使线性渐变的方向与环形的方向整体一致。

核心代码

"itemStyle": {
  "color": {
      "x": 0,
      "y": 0.2113248654051872,
      "x2": 1,
      "y2": 0.7886751345948129,
      "type": "linear",
      "global": false,
      "colorStops": [{
          "offset": 0,
          "color": "rgba(21, 118, 210, 0)"
      },{
        // 注意:该亮色部分仅为说明渐变方向实际应用中请勿如此。
        offset: 0.5,
        color: '#87ceeb',
      }, {
          "offset": 1,
          "color": "rgba(21, 118, 210, 1)"
      }]
  }
}

动态计算环形渐变的方向

参考示例:gallery.echartsjs.com/editor.html…

核心代码

/**
 * 线性渐变起止方向的计算方法
 * 
 *
 * @param {*} startArc 开始角度
 * @param {*} endArc 结束角度
 * @returns 四个坐标 x,y,x2,y2
 */
function getCoordinates(startArc, endArc) {
    const posi = [
        Math.sin(startArc),
        -Math.cos(startArc),
        Math.sin(endArc),
        -Math.cos(endArc)
    ]
    const dx = posi[2] - posi[0]
    const dy = posi[3] - posi[1]

    return getLocation(dx, dy)
}

function getLocation(dx, dy) {
  const tanV = dx / dy
  const directSign = Math.abs(tanV) < 1
  const t = directSign ? tanV : 1 / tanV

  const sign1 = t > 0 ? 1 : -1
  const sign2 = dx > 0 ? 1 : -1
  const sign = directSign ? sign1 * sign2 : sign2

  const group1 = [ 0.5 - sign * t / 2, 0.5 + sign * t / 2]
  const group2 = sign > 0 ? [0, 1] : [1, 0]
  const group = [...group1, ...group2]
  const keys = directSign ? ['x', 'x2', 'y', 'y2'] : ['y', 'y2', 'x', 'x2' ]

  let res = {}
  keys.forEach((k, idx) => {
    res[k] = group[idx]
  })
  return res

说明

本质上是根据环形区域的开始角度结束角度计算了一个环形的大体朝向,并在这个方向上根据图形的横纵比做了一个精细拟合。

效果

最终实际应用时,去掉上述中用以说明渐变方向的亮色部分,显示的结果如下。

实例展示

这里有一些我们在实际应用中使用的的效果,抛砖引玉,为大家设计时提供一个思路。

往届回顾

  1. 如何实现动态的label颜色

  2. 如何实现自定义的icon