高度个性化定制的数据可视化图表工具-Apache ECharts 使用指南

宗政楚
2023-12-01

Apache ECharts 使用指南

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。

Apache ECharts 官网

柱状图

基本柱状图

```echarts
option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      type: 'bar',
      data: [23, 24, 18, 25, 18],
      showBackground: true,
      backgroundStyle: {
        color: 'rgba(220, 220, 220, 0.8)'
        },
      barGap: '20%',
      barCategoryGap: '40%'
    },
    
    {
      type: 'bar',
      data: [12, 14, 9, 9, 11]
    }
  ]
  
};
```

效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      type: 'bar',
      data: [23, 24, 18, 25, 18],
      showBackground: true,
      backgroundStyle: {
        color: 'rgba(220, 220, 220, 0.8)'
        },
      barGap: '20%',
      barCategoryGap: '40%'
    },
    
    {
      type: 'bar',
      data: [12, 14, 9, 9, 11]
    }
  ]
  
};

堆叠柱状图

有时候,我们不仅希望知道不同系列各自的数值,还希望知道它们之和的变化,这时候通常使用堆积柱状图图来表现。顾名思义,堆积柱状图就是一个系列的数值“堆积”在另一个系列上,因而从他们的高度总和就能表达总量的变化。

使用 EChart 实现堆积折线图的方法非常简单,只需要给一个系列的 stack 值设置一个字符串类型的值,这一个值表示该系列堆积的类别。也就是说,拥有同样 stack 值的系列将堆积在一组。

```echarts
option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 43, 49],
      type: 'bar',
      stack: 'x'
    },
    {
      data: [5, 4, 3, 5, 10],
      type: 'bar',
      stack: 'x'
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 43, 49],
      type: 'bar',
      stack: 'x'
    },
    {
      data: [5, 4, 3, 5, 10],
      type: 'bar',
      stack: 'x'
    }
  ]
};

stack 的取值用来表明哪些系列将被堆积在一起,理论上只要取值相同即可,具体的取值并没有什么区别。但在实际的应用中,我们建议使用一些有意义的字符串方便阅读。

比如,在一个统计男女人数的图中,有四个系列,“成年男性”和“男孩”系列需要进行堆积,“成年女性”和“女孩”系列需要堆积。这时,这两组的的 stack 值就建议分别设为 '男''女'。虽然使用 'a''b' 这样没有意义的字符串也能实现同样的效果,但是代码的可阅读性就差了。

动态排序柱状图

动态排序柱状图是一种展示随时间变化的数据排名变化的图表,从 ECharts 5 开始内置支持。

动态排序柱状图通常是横向的柱条,如果想要采用纵向的柱条,只要把本教程中的 X 轴和 Y 轴相反设置即可。

  1. yAxis.realtimeSort 设为 true,表示开启 Y 轴的动态排序效果
  2. yAxis.inverse 设为 true,表示 Y 轴从下往上是从小到大的排列
  3. yAxis.animationDuration 建议设为 300,表示第一次柱条排序动画的时长
  4. yAxis.animationDurationUpdate 建议设为 300,表示第一次后柱条排序动画的时长
  5. 如果想只显示前 n 名,将 yAxis.max 设为 n - 1,否则显示所有柱条
  6. xAxis.max 建议设为 'dataMax' 表示用数据的最大值作为 X 轴最大值,视觉效果更好
  7. 如果想要实时改变标签,需要将 series.label.valueAnimation 设为 true
  8. animationDuration 设为 0,表示第一份数据不需要从 0 开始动画(如果希望从 0 开始则设为和 animationDurationUpdate 相同的值)
  9. animationDurationUpdate 建议设为 3000 表示每次更新动画时长,这一数值应与调用 setOption 改变数据的频率相同
  10. animationDurationUpdate 的频率调用 setInterval,更新数据值,显示下一个时间点对应的柱条排序

完整的例子如下:

```echarts
var data = [];
for (let i = 0; i < 5; ++i) {
  data.push(Math.round(Math.random() * 200));
}

option = {
  xAxis: {
    max: 'dataMax'
  },
  yAxis: {
    type: 'category',
    data: ['A', 'B', 'C', 'D', 'E'],
    inverse: true,
    animationDuration: 300,
    animationDurationUpdate: 300,
    max: 2 // only the largest 3 bars will be displayed
  },
  series: [
    {
      realtimeSort: true,
      name: 'X',
      type: 'bar',
      data: data,
      label: {
        show: true,
        position: 'right',
        valueAnimation: true
      }
    }
  ],
  legend: {
    show: true
  },
  animationDuration: 3000,
  animationDurationUpdate: 3000,
  animationEasing: 'linear',
  animationEasingUpdate: 'linear'
};

function update() {
  var data = option.series[0].data;
  for (var i = 0; i < data.length; ++i) {
    if (Math.random() > 0.9) {
      data[i] += Math.round(Math.random() * 2000);
    } else {
      data[i] += Math.round(Math.random() * 200);
    }
  }
  myChart.setOption(option);
}

setInterval(function() {
  update();
}, 3000);
```

效果如下:

var data = [];
for (let i = 0; i < 5; ++i) {
  data.push(Math.round(Math.random() * 200));
}

option = {
  xAxis: {
    max: 'dataMax'
  },
  yAxis: {
    type: 'category',
    data: ['A', 'B', 'C', 'D', 'E'],
    inverse: true,
    animationDuration: 300,
    animationDurationUpdate: 300,
    max: 2 // only the largest 3 bars will be displayed
  },
  series: [
    {
      realtimeSort: true,
      name: 'X',
      type: 'bar',
      data: data,
      label: {
        show: true,
        position: 'right',
        valueAnimation: true
      }
    }
  ],
  legend: {
    show: true
  },
  animationDuration: 3000,
  animationDurationUpdate: 3000,
  animationEasing: 'linear',
  animationEasingUpdate: 'linear'
};

function update() {
  var data = option.series[0].data;
  for (var i = 0; i < data.length; ++i) {
    if (Math.random() > 0.9) {
      data[i] += Math.round(Math.random() * 2000);
    } else {
      data[i] += Math.round(Math.random() * 200);
    }
  }
  myChart.setOption(option);
}

setInterval(function() {
  update();
}, 3000);

阶梯瀑布图

Apache ECharts 中并没有单独的瀑布图类型,但是我们可以使用堆叠的柱状图模拟该效果。

假设数据数组中的值是表示对前一个值的增减:

var data = [900, 345, 393, -108, -154, 135, 178, 286, -119, -361, -203];

也就是第一个数据是 900,第二个数据 345 表示的是在 900 的基础上增加了 345……将这个数据展示为阶梯瀑布图时,我们可以使用三个系列:第一个是不可交互的透明系列,用来实现“悬空”的柱状图效果;第二个系列用来表示正数;第三个系列用来表示负数。

```echarts
var data = [900, 345, 393, -108, -154, 135, 178, 286, -119, -361, -203];
var help = [];
var positive = [];
var negative = [];
for (var i = 0, sum = 0; i < data.length; ++i) {
  if (data[i] >= 0) {
    positive.push(data[i]);
    negative.push('-');
  } else {
    positive.push('-');
    negative.push(-data[i]);
  }

  if (i === 0) {
    help.push(0);
  } else {
    sum += data[i - 1];
    if (data[i] < 0) {
      help.push(sum + data[i]);
    } else {
      help.push(sum);
    }
  }
}

option = {
  title: {
    text: 'Waterfall'
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    splitLine: { show: false },
    data: (function() {
      var list = [];
      for (var i = 1; i <= 11; i++) {
        list.push('Oct/' + i);
      }
      return list;
    })()
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      type: 'bar',
      stack: 'all',
      itemStyle: {
        normal: {
          barBorderColor: 'rgba(0,0,0,0)',
          color: 'rgba(0,0,0,0)'
        },
        emphasis: {
          barBorderColor: 'rgba(0,0,0,0)',
          color: 'rgba(0,0,0,0)'
        }
      },
      data: help
    },
    {
      name: 'positive',
      type: 'bar',
      stack: 'all',
      data: positive
    },
    {
      name: 'negative',
      type: 'bar',
      stack: 'all',
      data: negative,
      itemStyle: {
        color: '#f33'
      }
    }
  ]
};
```

效果如下:

var data = [900, 345, 393, -108, -154, 135, 178, 286, -119, -361, -203];
var help = [];
var positive = [];
var negative = [];
for (var i = 0, sum = 0; i < data.length; ++i) {
  if (data[i] >= 0) {
    positive.push(data[i]);
    negative.push('-');
  } else {
    positive.push('-');
    negative.push(-data[i]);
  }

  if (i === 0) {
    help.push(0);
  } else {
    sum += data[i - 1];
    if (data[i] < 0) {
      help.push(sum + data[i]);
    } else {
      help.push(sum);
    }
  }
}

option = {
  title: {
    text: 'Waterfall'
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    splitLine: { show: false },
    data: (function() {
      var list = [];
      for (var i = 1; i <= 11; i++) {
        list.push('Oct/' + i);
      }
      return list;
    })()
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      type: 'bar',
      stack: 'all',
      itemStyle: {
        normal: {
          barBorderColor: 'rgba(0,0,0,0)',
          color: 'rgba(0,0,0,0)'
        },
        emphasis: {
          barBorderColor: 'rgba(0,0,0,0)',
          color: 'rgba(0,0,0,0)'
        }
      },
      data: help
    },
    {
      name: 'positive',
      type: 'bar',
      stack: 'all',
      data: positive
    },
    {
      name: 'negative',
      type: 'bar',
      stack: 'all',
      data: negative,
      itemStyle: {
        color: '#f33'
      }
    }
  ]
};

折线图

基础折线图

最简单的折线图

如果我们想建立一个横坐标是类目型(category)、纵坐标是数值型(value)的折线图,我们可以使用这样的方式:

```echarts
option = {
  xAxis: {
    type: 'category',
    data: ['A', 'B', 'C']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      data: [120, 200, 150],
      type: 'line'
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    type: 'category',
    data: ['A', 'B', 'C']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      data: [120, 200, 150],
      type: 'line'
    }
  ]
};

在这个例子中,我们通过 xAxis 将横坐标设为类目型,并指定了对应的值;通过 typeyAxis 的类型设定为数值型。在 series 中,我们将系列类型设为 line,并且通过 data 指定了折线图三个点的取值。这样,就能得到一个最简单的折线图了。

这里 xAxisyAxistype 属性都可以隐去不写。因为坐标轴的默认类型是数值型,而 xAxis 指定了类目型的 data,所以 ECharts 也能识别出这是类目型的坐标轴。为了让大家更容易理解,我们特意写了 type。在实际的应用中,如果是 'value' 类型,也可以省略不写。

笛卡尔坐标系中的折线图

如果我们希望折线图在横坐标和纵坐标上都是连续的,即在笛卡尔坐标系中,应该如何实现呢?答案也很简单,只要把 seriesdata 每个数据用一个包含两个元素的数组表示就行了

```echarts
option = {
  xAxis: {},
  yAxis: {},
  series: [
    {
      data: [
        [20, 120],
        [50, 200],
        [40, 50]
      ],
      type: 'line'
    }
  ]
};    
```

效果如下:

option = {
  xAxis: {},
  yAxis: {},
  series: [
    {
      data: [
        [20, 120],
        [50, 200],
        [40, 50]
      ],
      type: 'line'
    }
  ]
};

折线图样式设置

折线的样式

折线图中折线的样式可以通过 lineStyle 设置。可以为其指定颜色、线宽、折线类型、阴影、不透明度等等,具体的可以参考配置项手册 series.lineStyle 了解。这里,我们以设置颜色(color)、线宽(width)和折线类型(type)为例说明。

```echarts
option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 23, 19],
      type: 'line',
      lineStyle: {
        normal: {
          color: 'green',
          width: 4,
          type: 'dashed'
        }
      }
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 23, 19],
      type: 'line',
      lineStyle: {
        normal: {
          color: 'green',
          width: 4,
          type: 'dashed'
        }
      }
    }
  ]
};

这里设置折线宽度时,数据点描边的宽度是不会跟着改变的,而应该在数据点的配置项中另外设置。

数据点的样式

数据点的样式可以通过 series.itemStyle 指定填充颜色(color)、描边颜色(borderColor)、描边宽度(borderWidth)、描边类型(borderType)、阴影(shadowColor)、不透明度(opacity)等。与折线样式的设置十分相似,这里不再展开说明。

在数据点处显示数值

在系列中,这数据点的标签通过 series.label 属性指定。如果将 label 下的 show 指定为 true,则表示该数值默认时就显示;如果为 false,而 series.emphasis.label.showtrue,则表示只有在鼠标移动到该数据时,才显示数值。

```echarts
option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 23, 19],
      type: 'line',
      label: {
        show: true,
        position: 'bottom',
        textStyle: {
          fontSize: 20
        }
      }
    }
  ]
};    
```

效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 23, 19],
      type: 'line',
      label: {
        show: true,
        position: 'bottom',
        textStyle: {
          fontSize: 20
        }
      }
    }
  ]
};

空数据

在一个系列中,可能一个横坐标对应的取值是“空”的,将其设为 0 有时并不能满足我们的期望–空数据不应被其左右的数据连接。

在 ECharts 中,我们使用字符串 '-' 表示空数据,这对其他系列的数据也是适用的。
echarts option = { xAxis: { data: ['A', 'B', 'C', 'D', 'E'] }, yAxis: {}, series: [ { data: [0, 22, '-', 23, 19], type: 'line' } ] };
效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [0, 22, '-', 23, 19],
      type: 'line'
    }
  ]
};

注意区别这个例子中,“空”数据与取值为 0 的数据。

堆叠折线图

与堆叠柱状图类似,堆叠折线图也是用系列的 stack 设置哪些系列堆叠在一起。

```echarts
option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 43, 49],
      type: 'line',
      stack: 'x'
    },
    {
      data: [5, 4, 3, 5, 10],
      type: 'line',
      stack: 'x'
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 43, 49],
      type: 'line',
      stack: 'x'
    },
    {
      data: [5, 4, 3, 5, 10],
      type: 'line',
      stack: 'x'
    }
  ]
};

但是不同的是,如果不加说明的话,我们很难判断出这是一个堆叠折线图,还是一个普通的折线图。所以,对于堆叠折线图而言,一般建议使用区域填充色以表明堆叠的情况。

```echarts
option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 43, 49],
      type: 'line',
      stack: 'x',
      areaStyle: {}
    },
    {
      data: [5, 4, 3, 5, 10],
      type: 'line',
      stack: 'x',
      areaStyle: {}
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 43, 49],
      type: 'line',
      stack: 'x',
      areaStyle: {}
    },
    {
      data: [5, 4, 3, 5, 10],
      type: 'line',
      stack: 'x',
      areaStyle: {}
    }
  ]
};

区域面积图

区域面积图将折线到坐标轴的空间设置背景色,用区域面积表达数据。相比普通的折线图,区域面积图的视觉效果更加饱满丰富,在系列不多的场景下尤其适用。

```echarts
option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 23, 19],
      type: 'line',
      areaStyle: {}
    },
    {
      data: [25, 14, 23, 35, 10],
      type: 'line',
      areaStyle: {
        color: '#ff0',
        opacity: 0.5
      }
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 23, 19],
      type: 'line',
      areaStyle: {}
    },
    {
      data: [25, 14, 23, 35, 10],
      type: 'line',
      areaStyle: {
        color: '#ff0',
        opacity: 0.5
      }
    }
  ]
};

通过 areaStyle 设置折线图的填充区域样式,将其设为为 {} 表示使用默认样式,即使用系列的颜色以半透明的方式填充区域。如果想指定特定的样式,可以通过设置 areaStyle 下的配置项覆盖,如第二个系列将填充区域的颜色设为不透明度为 0.5 的黄色。

平滑曲线图

平滑曲线图也是折线图的一种变形,这种更柔和的样式也是一种不错的视觉选择。使用时,只需要将折线图系列的 smooth 属性设置为 true 即可

```echarts
option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 23, 19],
      type: 'line',
      smooth: true
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['A', 'B', 'C', 'D', 'E']
  },
  yAxis: {},
  series: [
    {
      data: [10, 22, 28, 23, 19],
      type: 'line',
      smooth: true
    }
  ]
};

阶梯线图

阶梯线图又称方波图,它使用水平和垂直的线来连接两个数据点,而普通折线图则直接将两个点连接起来。阶梯线图能够很好地表达数据的突变。

在 ECharts 中,系列的 step 属性用来表征阶梯线图的连接类型,它共有三种取值:'start''middle''end',分别表示在当前点,当前点与下个点的中间点,下个点拐弯。

```echarts
option = {
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: 'Step Start',
      type: 'line',
      step: 'start',
      data: [120, 132, 101, 134, 90, 230, 210]
    },
    {
      name: 'Step Middle',
      type: 'line',
      step: 'middle',
      data: [220, 282, 201, 234, 290, 430, 410]
    },
    {
      name: 'Step End',
      type: 'line',
      step: 'end',
      data: [450, 432, 401, 454, 590, 530, 510]
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: 'Step Start',
      type: 'line',
      step: 'start',
      data: [120, 132, 101, 134, 90, 230, 210]
    },
    {
      name: 'Step Middle',
      type: 'line',
      step: 'middle',
      data: [220, 282, 201, 234, 290, 430, 410]
    },
    {
      name: 'Step End',
      type: 'line',
      step: 'end',
      data: [450, 432, 401, 454, 590, 530, 510]
    }
  ]
};

请注意这个例子中不同的 step 取值对应的数据点和连线的区别。

饼图

基础饼图

饼图主要用于表现不同类目的数据在总和中的占比。每个的弧度表示数据数量的比例。

最简单的饼图

饼图的配置和折线图、柱状图略有不同,不再需要配置坐标轴,而是把数据名称和值都写在系列中。以下是一个最简单的饼图的例子。

```echarts
option = {
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 335,
          name: '直接访问'
        },
        {
          value: 234,
          name: '联盟广告'
        },
        {
          value: 1548,
          name: '搜索引擎'
        }
      ]
    }
  ]
};
```

效果如下:

option = {
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 335,
          name: '直接访问'
        },
        {
          value: 234,
          name: '联盟广告'
        },
        {
          value: 1548,
          name: '搜索引擎'
        }
      ]
    }
  ]
};

需要注意的是,这里是 value 不需要是百分比数据,ECharts 会根据所有数据的 value ,按比例分配它们在饼图中对应的弧度。

饼图样式设置

饼图的半径

饼图的半径可以通过 series.radius 设置,可以是诸如 '60%' 这样相对的百分比字符串,或是 200 这样的绝对像素数值。当它是百分比字符串时,它是相对于容器宽高中较小的一条边的。也就是说,如果宽度大于高度,则百分比是相对于高度的,反之则反;当它是数值型时,它表示绝对的像素大小。

```echarts
option = {
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 335,
          name: '直接访问'
        },
        {
          value: 234,
          name: '联盟广告'
        },
        {
          value: 1548,
          name: '搜索引擎'
        }
      ],
      radius: '50%'
    }
  ]
};
```

效果如下:

option = {
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 335,
          name: '直接访问'
        },
        {
          value: 234,
          name: '联盟广告'
        },
        {
          value: 1548,
          name: '搜索引擎'
        }
      ],
      radius: '50%'
    }
  ]
};

如果数据和为 0,不显示饼图

在默认情况下,如果数据值和为 0,会显示平均分割的扇形。比如,如果有 4 个数据项,并且每个数据项都是 0,则每个扇形都是 90°。如果我们希望在这种情况下不显示任何扇形,可以将 series.stillShowZeroSum 设为 false

```echarts
option = {
  series: [
    {
      type: 'pie',
      stillShowZeroSum: false,
      data: [
        {
          value: 0,
          name: '直接访问'
        },
        {
          value: 0,
          name: '联盟广告'
        },
        {
          value: 0,
          name: '搜索引擎'
        }
      ]
    }
  ]
};
```

效果如下:

option = {
  series: [
    {
      type: 'pie',
      stillShowZeroSum: false,
      data: [
        {
          value: 0,
          name: '直接访问'
        },
        {
          value: 0,
          name: '联盟广告'
        },
        {
          value: 0,
          name: '搜索引擎'
        }
      ]
    }
  ]
};

如果希望扇形对应的标签也不显示,可以将 series.label.show 设为 false

```echarts
option = {
  series: [
    {
      type: 'pie',
      stillShowZeroSum: false,
      label: {
        show: false
      },
      data: [
        {
          value: 0,
          name: '直接访问'
        },
        {
          value: 0,
          name: '联盟广告'
        },
        {
          value: 0,
          name: '搜索引擎'
        }
      ]
    }
  ]
};
```

效果如下:

option = {
  series: [
    {
      type: 'pie',
      stillShowZeroSum: false,
      label: {
        show: false
      },
      data: [
        {
          value: 0,
          name: '直接访问'
        },
        {
          value: 0,
          name: '联盟广告'
        },
        {
          value: 0,
          name: '搜索引擎'
        }
      ]
    }
  ]
};

圆环图

圆环图同样可以用来表示数据占总体的比例,相比于饼图,它中间空余的部分可以用来显示一些额外的文字等信息,因而也是一种常用的图表类型。

基础圆环图

在 ECharts 中,饼图的半径除了上一小节提到的,可以是一个数值或者字符串之外,还可以是一个包含两个元素的数组,每个元素可以为数值或字符串。当它是一个数组时,它的前一项表示内半径,后一项表示外半径,这样就形成了一个圆环图。

从这个角度上来说,可以认为饼图是一个内半径为 0 的圆环图,也就是说,饼图是圆环图的特例。

```echarts
option = {
  title: {
    text: '圆环图的例子',
    left: 'center',
    top: 'center'
  },
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 335,
          name: 'A'
        },
        {
          value: 234,
          name: 'B'
        },
        {
          value: 1548,
          name: 'C'
        }
      ],
      radius: ['40%', '70%']
    }
  ]
};
```

效果如下:

option = {
  title: {
    text: '圆环图的例子',
    left: 'center',
    top: 'center'
  },
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 335,
          name: 'A'
        },
        {
          value: 234,
          name: 'B'
        },
        {
          value: 1548,
          name: 'C'
        }
      ],
      radius: ['40%', '70%']
    }
  ]
};

如果半径是数组,其中的两项也可以一项是数值,另一项是百分比形式的字符串。但是这样可能导致在某些分辨率下,内半径小于外半径。ECharts 会自动使用小的一项作为内半径,但是仍应小心这样可能会导致的非预期效果。

在圆环图中间显示高亮扇形对应的文字

上面的例子展现了在圆环图中间显示固定文字的例子,下面我们要介绍,如何在圆环图中间显示鼠标高亮的扇形对应的文字。实现这一效果的思路是,利用系列的 label(默认用扇形颜色显示数据的 name),显示在圆环图中间。在默认情况下不显示系列的 label,在高亮时显示。具体的代码如下

```echarts
option = {
  legend: {
    orient: 'vertical',
    x: 'left',
    data: ['A', 'B', 'C', 'D', 'E']
  },
  series: [
    {
      type: 'pie',
      radius: ['50%', '70%'],
      avoidLabelOverlap: false,
      label: {
        show: false,
        position: 'center',
        emphasis: {
          show: true
        }
      },
      labelLine: {
        show: false
      },
      emphasis: {
        label: {
          show: true,
          fontSize: '30',
          fontWeight: 'bold'
        }
      },
      data: [
        { value: 335, name: 'A' },
        { value: 310, name: 'B' },
        { value: 234, name: 'C' },
        { value: 135, name: 'D' },
        { value: 1548, name: 'E' }
      ]
    }
  ]
};
```

效果如下:

option = {
  legend: {
    orient: 'vertical',
    x: 'left',
    data: ['A', 'B', 'C', 'D', 'E']
  },
  series: [
    {
      type: 'pie',
      radius: ['50%', '70%'],
      avoidLabelOverlap: false,
      label: {
        show: false,
        position: 'center',
        emphasis: {
          show: true
        }
      },
      labelLine: {
        show: false
      },
      emphasis: {
        label: {
          show: true,
          fontSize: '30',
          fontWeight: 'bold'
        }
      },
      data: [
        { value: 335, name: 'A' },
        { value: 310, name: 'B' },
        { value: 234, name: 'C' },
        { value: 135, name: 'D' },
        { value: 1548, name: 'E' }
      ]
    }
  ]
};

其中,avoidLabelOverlap 是用来控制是否由 ECharts 调整标签位置以实现防止标签重叠。它的默认值是 true,而在这里,我们不希望标签位置调整到不是中间的位置,因此我们需要将其设为 false

这样,圆环图中间会显示高亮数据的 name 值。

南丁格尔图(玫瑰图)

南丁格尔图又称玫瑰图,通常用弧度相同但半径不同的扇形表示各个类目。

ECharts 可以通过将饼图的 series.roseType 值设为 'area' 实现南丁格尔图,其他配置项和饼图是相同的。

```echarts
option = {
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 100,
          name: 'A'
        },
        {
          value: 200,
          name: 'B'
        },
        {
          value: 300,
          name: 'C'
        },
        {
          value: 400,
          name: 'D'
        },
        {
          value: 500,
          name: 'E'
        }
      ],
      roseType: 'area'
    }
  ]
};
```

效果如下:

option = {
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 100,
          name: 'A'
        },
        {
          value: 200,
          name: 'B'
        },
        {
          value: 300,
          name: 'C'
        },
        {
          value: 400,
          name: 'D'
        },
        {
          value: 500,
          name: 'E'
        }
      ],
      roseType: 'area'
    }
  ]
};

散点图

基础散点图

散点图,也是一种常见的图表类型。散点图由许多“点”组成,有时,这些点用来表示数据在坐标系中的位置(比如在笛卡尔坐标系下,表示数据在 x 轴和 y 轴上的坐标;在地图坐标系下,表示数据在地图上的某个位置等);有时,这些点的大小、颜色等属性也可以映射到数据值,用以表现高维数据。

最简单的散点图

下面是一个横坐标为类目轴、纵坐标为数值轴的最简单的散点图配置:

```echarts
option = {
  xAxis: {
    data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
  },
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [220, 182, 191, 234, 290, 330, 310]
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
  },
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [220, 182, 191, 234, 290, 330, 310]
    }
  ]
};

笛卡尔坐标系下的散点图

在上文的例子中,散点图的横坐标都是离散的类目轴,而纵坐标都是连续的数值轴。而对于散点图而言,另一种常见的场景是,两个坐标轴均为连续的数值轴,也就是笛卡尔坐标系。这时的系列形式略有不同,数据的横坐标和纵坐标一同写在 data 中,而非坐标轴中。

```echarts
option = {
  xAxis: {},
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [
        [10, 5],
        [0, 8],
        [6, 10],
        [2, 12],
        [8, 9]
      ]
    }
  ]
};
```

效果如下:

option = {
  xAxis: {},
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [
        [10, 5],
        [0, 8],
        [6, 10],
        [2, 12],
        [8, 9]
      ]
    }
  ]
};

散点图样式设置

图形的形状

图形(symbol)指的是散点图中数据“点”的形状。有三类图形可选,一种是 ECharts 内置形状,第二种是图片,第三种是 SVG 的路径。

ECharts 内置形状包括:圆形、矩形、圆角矩形、三角形、菱形、大头针形、箭头形,分别对应'circle''rect''roundRect''triangle''diamond''pin''arrow'。使用内置形状时,只要将 symbol 属性指定为形状名称对应的字符串即可。

如果想要将图形指定为任意的图片,以 'image://' 开头,后面跟图片的绝对或相对地址。形如:'image://http://example.com/xxx.png''image://./xxx.png'

除此之外,还支持 SVG 的路径作为矢量图形,将 symbol 设置为以 'path://' 开头的 SVG 路径即可。使用矢量图形的好处是,图片不会因为缩放而产生锯齿或模糊,并且通常而言比图片形式的文件大小更小。路径的查看方法为,打开一个 SVG 文件,找到形如 <path d="M… L…"></path> 的路径,将 d 的值添加在 'path://' 后即可。

下面,我们展示一个将图形设置为矢量爱心形状的方式。

首先,我们需要一个爱心的 SVG 文件,可以使用矢量编辑软件绘制,或者从网上下载到相关资源。其内容如下:

<?xml version="1.0" encoding="iso-8859-1"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 51.997 51.997" style="enable-background:new 0 0 51.997 51.997;" xml:space="preserve">
    <path d="M51.911,16.242C51.152,7.888,45.239,1.827,37.839,1.827c-4.93,0-9.444,2.653-11.984,6.905 c-2.517-4.307-6.846-6.906-11.697-6.906c-7.399,0-13.313,6.061-14.071,14.415c-0.06,0.369-0.306,2.311,0.442,5.478 c1.078,4.568,3.568,8.723,7.199,12.013l18.115,16.439l18.426-16.438c3.631-3.291,6.121-7.445,7.199-12.014 C52.216,18.553,51.97,16.611,51.911,16.242z"/>
</svg>

在 ECharts 的 symbol 配置项中,我们使用 d 的值作为路径。

```echarts
option = {
  xAxis: {
    data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
  },
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [220, 182, 191, 234, 290, 330, 310],
      symbolSize: 20,
      symbol:
        'path://M51.911,16.242C51.152,7.888,45.239,1.827,37.839,1.827c-4.93,0-9.444,2.653-11.984,6.905 c-2.517-4.307-6.846-6.906-11.697-6.906c-7.399,0-13.313,6.061-14.071,14.415c-0.06,0.369-0.306,2.311,0.442,5.478 c1.078,4.568,3.568,8.723,7.199,12.013l18.115,16.439l18.426-16.438c3.631-3.291,6.121-7.445,7.199-12.014 C52.216,18.553,51.97,16.611,51.911,16.242z'
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
  },
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [220, 182, 191, 234, 290, 330, 310],
      symbolSize: 20,
      symbol:
        'path://M51.911,16.242C51.152,7.888,45.239,1.827,37.839,1.827c-4.93,0-9.444,2.653-11.984,6.905 c-2.517-4.307-6.846-6.906-11.697-6.906c-7.399,0-13.313,6.061-14.071,14.415c-0.06,0.369-0.306,2.311,0.442,5.478 c1.078,4.568,3.568,8.723,7.199,12.013l18.115,16.439l18.426-16.438c3.631-3.291,6.121-7.445,7.199-12.014 C52.216,18.553,51.97,16.611,51.911,16.242z'
    }
  ]
};

这样,就能得到爱心形状的图形作为点的形状了。

图形的大小

图形大小可以使用 series.symbolSize 控制。它既可以是一个表示图形大小的像素值,也可以是一个包含两个 number 元素的数组,分别表示图形的宽和高。

除此之外,它还可以是一个回调函数,其参数格式为:

(value: Array | number, params: Object) => number | Array;

第一个参数为数据值,第二个参数是数据项的其他参数。

在下面的例子中,我们将散点图点的大小设置为与其数据值成正比。

```echarts
option = {
  xAxis: {
    data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
  },
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [220, 182, 191, 234, 290, 330, 310],
      symbolSize: function(value) {
        return value / 10;
      }
    }
  ]
};
```

效果如下:

option = {
  xAxis: {
    data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
  },
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [220, 182, 191, 234, 290, 330, 310],
      symbolSize: function(value) {
        return value / 10;
      }
    }
  ]
};
 类似资料: