Echarts 环图 颜色渐变、灰色背景、自适应

  • 前言
  • 效果图
  • 颜色渐变
  • 灰色环形背景
  • 自适应
  • 完整代码


前言

在项目中大量使用echarts,由于配置项太多,好记性不如烂笔头,于是整理记录一些完整的echarts 项目代码,以便以后查阅。
git源码 https://github.com/SoulRonin/Echarts-Pie

效果图

先上效果图镇楼

android灰色渐变背景色 浅灰渐变背景_数据

颜色渐变

美工总是很喜欢炫酷的渐变色,有这爱好,码农就只能满足这一癖好(^ _ ^)
有线性渐变、径向渐变,还有纹理填充,到官方文档配置项里面查阅详细参数说明 传送门 UI给的是线性渐变,配置如下:

{
  type: 'linear',
  x: 0,
  y: 0,
  x2: 0,
  y2: 1,
  colorStops: [
    { offset: 0, color: '#15f1a9' },
    { offset: 0.1, color: '#13eea2' },
    { offset: 0.2, color: '#11eb99' },
    { offset: 0.3, color: '#0ee68e' },
    { offset: 0.5, color: '#0ce384' },
    { offset: 1, color: '#0ae07e' }
  ],
  global: false
}

灰色环形背景

拿到UI效果图的时候,看到后面还有一个灰色环,当时一脸懵逼,啥玩意,还以为是图片背景,最后整理下思路,用一个没有鼠标 悬浮 点击效果的 灰色圆环 不就OK

效果如下:

android灰色渐变背景色 浅灰渐变背景_数据_02


插入 series 系列中,代码:

// 灰色背景环
{
  type: 'pie',
  radius: ['30%', '58%'],
  center: ['50%', '50%'],
  selectedMode: false,
  hoverAnimation: false,
  data: [{ value: 1, name: '' }],
  itemStyle: {
    color: '#f7f7f7'
  },
  label: {
    show: false
  },
  labelLine: {
    show: false
  },
  tooltip: {
    show: false
  },
  animation: false,
  cursor: 'auto',
  emphasis: {
    itemStyle: {
      color: '#f7f7f7'
    }
  }
}

最后别忘记把实际要展示数据的 series 参数 z 设置比灰色背景大,让灰色背景渲染在实际要展示的数据图层后面

自适应

浏览器视口大小在改变,会导致echarts图形宽度过大或过小,让界面展示就不够友好,因此采取自适应,用window.onresize监听浏览器视口大小变化,让图形重新渲染
代码:

// charts 是图形第一次渲染时传入的数据 数据包括 myChart 、container、myChartContainer
// myChart  是echarts实例数据
// container 挂在echarts图形dom
// myChartContainer 给echarts图形dom的添加内联style样式(width和height)
window.onresize = function() {
   charts.myChartContainer(charts.container)
   charts.myChart.resize()
 }

完整代码

echarts 需要渲染的数据单独放在Pie.json 里面,然后在Pie.html导入 Pie.json 中数据。
另外Vue项目中,渲染 echarts 要放在 this.$nextTick 中,this.$nextTick 能监听 dom渲染完成,这样 echarts 初始化时,document.getElementById('id') 不会获取不到 dom 节点而报错

Pie.html 完整代码:

<html>
  <head>
    <title>Pie</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@4.5.0/dist/echarts.min.js"></script>

    <style>
      .echarts-wrap {
        border: 1px solid skyblue;
        border-radius: 5px;
        margin: 16px;
        padding: 16px;
      }
    </style>
  </head>

  <body>
    <div id="app">
      <div class="echarts-wrap">
        <div id="pieChart"></div>
      </div>
    </div>

    <script>
      new Vue({
        el: '#app',
        mounted() {
          this.readTextFile('Pie.json', text => {
            let pieData = JSON.parse(text)
            this.$nextTick(() => {
              this.drawPie(pieData)
            })
          })
        },

        methods: {
          // 读取文件数据
          readTextFile(file, callback) {
            var rawFile = new XMLHttpRequest()
            rawFile.overrideMimeType('application/json')
            rawFile.open('GET', file, true)
            rawFile.onreadystatechange = function() {
              if (rawFile.readyState === 4 && rawFile.status == '200') {
                callback(rawFile.responseText)
              }
            }
            rawFile.send(null)
          },

          // 饼图绘制
          drawPie(pieData) {
            let charts = {} // 接收echarts实例

            // 解决 display: none 没有宽高
            let obj = document.getElementsByClassName('echarts-wrap')[0]
            let style = null

            if (window.getComputedStyle) {
              style = window.getComputedStyle(obj, null) // 非IE
            } else {
              style = obj.currentStyle // IE
            }

            let myChartContainer = container => {
              let width = `calc(${style.width})`
              container.style.width = `calc(${width})`
              container.style.height = '660px'
            }

            // 基于准备好的dom,初始化echarts实例
            let container = document.getElementById(pieData.id)
            myChartContainer(container)

            let myChart = echarts.init(container)
            myChart.clear()

            // 绘制echarts图形
            myChart.setOption({
              color: pieData.itemStyle,
              title: {
                text: pieData.name,
                left: 'center',
                textStyle: {
                  fontSize: 16,
                  color: '#333333'
                }
              },
              tooltip: {
                trigger: 'item',
                formatter: '{b}<br/>{c}' + pieData.unit + '<br/>占比 : {d}%',
                backgroundColor: '#22a5fd',
                borderWidth: 0,
                padding: [10, 20],
                fontSize: 14,
                textStyle: {
                  color: '#ffffff'
                },
                extraCssText: 'box-shadow: 0 0 3px #a2c1f6;'
                // position: function(pos, params, el, elRect, size) {
                //   var obj = { top: 10 }
                //   obj[
                //     ['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]
                //   ] = 30
                //   return obj
                // }
              },
              legend: {
                orient: 'horizontal',
                top: 'bottom',
                bottom: 0,
                left: 'center',
                data: pieData.legend,
                itemWidth: 10,
                textStyle: {
                  fontSize: 12,
                  color: '#666666'
                },
                icon: 'circle'
              },
              grid: [
                {
                  left: 80,
                  right: 80,
                  top: 10,
                  bottom: 80,
                  containLabel: true
                }
              ],
              series: [
                {
                  type: 'pie',
                  radius: ['30%', '50%'],
                  center: ['50%', '50%'],
                  selectedMode: 'single',
                  data: pieData.serieData,
                  itemStyle: pieData.itemStyle,
                  label: {
                    position: 'outside',
                    formatter: '{d}%',
                    color: '#000000',
                    fontSize: 12,
                    fontFamily: '方正兰亭中粗黑简体',
                    distanceToLabelLine: 0,
                    align: 'right'
                  },
                  labelLine: {
                    show: false,
                    length: 10,
                    length2: 0
                  },
                  emphasis: {
                    label: {
                      color: '#218ced'
                    }
                  },
                  z: 9999
                },

                // 灰色背景环
                {
                  type: 'pie',
                  radius: ['30%', '58%'],
                  center: ['50%', '50%'],
                  selectedMode: false,
                  hoverAnimation: false,
                  data: [{ value: 1, name: '' }],
                  itemStyle: {
                    color: '#f7f7f7'
                  },
                  label: {
                    show: false
                  },
                  labelLine: {
                    show: false
                  },
                  tooltip: {
                    show: false
                  },
                  animation: false,
                  cursor: 'auto',
                  emphasis: {
                    itemStyle: {
                      color: '#f7f7f7'
                    }
                  }
                }
              ]
            })

            charts = { myChart, container, myChartContainer }
            this.handleOnResize(charts)
          },

          // onresize
          handleOnResize(charts) {
            window.onresize = function() {
              charts.myChartContainer(charts.container)
              charts.myChart.resize()
            }
          }
        }
      })
    </script>
  </body>
</html>

Pie.json 完整代码

{
  "name": "饼图(渐变、灰色背景、自适应)",
  "serieData": [
    {
      "name": "直接访问",
      "value": 20150
    },
    {
      "name": "邮件营销",
      "value": 6800.00
    },
    {
      "name": "联盟广告",
      "value": 10000
    },
    {
      "name": "视频广告",
      "value": 7000
    }
  ],
  "itemStyle": [
    {
      "type": "linear",
      "x": 0,
      "y": 0,
      "x2": 0,
      "y2": 1,
      "colorStops": [
        {
          "offset": 0,
          "color": "#15f1a9"
        },
        {
          "offset": 0.1,
          "color": "#13eea2"
        },
        {
          "offset": 0.2,
          "color": "#11eb99"
        },
        {
          "offset": 0.3,
          "color": "#0ee68e"
        },
        {
          "offset": 0.5,
          "color": "#0ce384"
        },
        {
          "offset": 1,
          "color": "#0ae07e"
        }
      ],
      "global": false
    },
    {
      "type": "linear",
      "x": 0,
      "y": 0,
      "x2": 0,
      "y2": 1,
      "colorStops": [
        {
          "offset": 0,
          "color": "#ca2efc"
        },
        {
          "offset": 0.1,
          "color": "#c12cfa"
        },
        {
          "offset": 0.2,
          "color": "#b529f8"
        },
        {
          "offset": 0.3,
          "color": "#a725f5"
        },
        {
          "offset": 0.5,
          "color": "#9b22f3"
        },
        {
          "offset": 1,
          "color": "#9220f1"
        }
      ],
      "global": false
    },
    {
      "type": "linear",
      "x": 0,
      "y": 0,
      "x2": 0,
      "y2": 1,
      "colorStops": [
        {
          "offset": 0,
          "color": "#ffc446"
        },
        {
          "offset": 0.1,
          "color": "#febd41"
        },
        {
          "offset": 0.2,
          "color": "#fcb33a"
        },
        {
          "offset": 0.3,
          "color": "#fba832"
        },
        {
          "offset": 0.5,
          "color": "#f99e2b"
        },
        {
          "offset": 1,
          "color": "#f89726"
        }
      ],
      "global": false
    },
    {
      "type": "linear",
      "x": 0,
      "y": 0,
      "x2": 0,
      "y2": 1,
      "colorStops": [
        {
          "offset": 0,
          "color": "#3093f9"
        },
        {
          "offset": 0.1,
          "color": "#2e8bf8"
        },
        {
          "offset": 0.2,
          "color": "#2a7ff7"
        },
        {
          "offset": 0.3,
          "color": "#2771f5"
        },
        {
          "offset": 0.5,
          "color": "#2365f4"
        },
        {
          "offset": 1,
          "color": "#215df3"
        }
      ],
      "global": false
    }
  ],
  "id": "pieChart",
  "unit": "人次",
  "legend": [
    "直接访问",
    "邮件营销",
    "联盟广告",
    "视频广告"
  ]
}