# 认识 ECharts

# ECharts 初体验

现在,我们来绘制一个简单的图表。

绘制之前我们需要定义一个具有宽高的 DOM 容器,在 index.html 文件中写入以下内容。

...
<body>
  <!-- 为 ECharts 准备一个宽为 600px,高为 400px 的 DOM -->
  <div id="main" style="width: 600px;height:400px;"></div>
</body>
...

然后,通过 echarts.init 方法初始化一个 echarts 实例,并通过 setOption 方法生成一个简单的折线图。

index.html 文件中写入内容。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="echarts.js"></script>
    <title>ECharts 快速上手</title>
  </head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    #main {
      margin: 20px;
      background-color: rgb(228, 255, 192);
    }
  </style>
  <body>
    <!-- 为 ECharts 准备一个宽为 600px,高为 400px 的 DOM -->
    <div id="main" style="width:600px;height:400px;"></div>
  </body>
  <script>
    var chartDom = document.getElementById("main");
    // 初始化实例对象 echarts.init (dom) 容器;
    var myChart = echarts.init(chartDom);
    // 指定配置项和数据
    var option = {
      xAxis: {
        type: "category",
        data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      },
      yAxis: {
        type: "value",
      },
      series: [
        {
          data: [150, 230, 224, 218, 135, 147, 260],
          type: "line",
        },
      ],
    };
    // 将配置项设置给 echarts 实例对象。
    myChart.setOption(option);
  </script>
</html>

index.html 文件上右击选择 Open with Live Server 打开 8080 端口。

打开 Web 服务即可看到如下效果。

1678292793848

# 基础知识介绍

知识点

  • ECharts 实例
  • series 与 dataset
  • ECharts 基础配置
  • 用 option 描述图表
  • 坐标系

# ECharts 实例

一个网页中可以创建多个 ECharts 实例。每个 ECharts 实例中可以创建多个图表和坐标系等等(用 option 来描述)。准备一个 DOM 节点(作为 ECharts 的渲染容器),就可以在上面创建一个 ECharts 实例。每个 ECharts 实例独占一个 DOM 节点。

1678293350295

# ECharts 基础配置

我们在官方文档的示例中,随便点击一个图,查看其代码,会发现有固定的代码结构形式。

例如,我们下面打开一个基础折线图

1678293409253

那么上面用红色矩形框圈起来的部分代表什么呢?🤔 这就是我们接下来要讲的基础配置。

option 相当于是存放组件的容器,而在 option 中的 seriesxAxisyAxis 都被称为 组件

# 组件

ECharts 中各种内容,都被抽象为 “组件”,像上面提到的 series 是专门绘制 “图” 的组件。

在 ECharts 中的组件很多,例如在后续内容中我们可能遇到, xAxis (直角坐标系 X 轴)、 yAxis (直角坐标系 Y 轴)、 grid (直角坐标系底板)、 angleAxis (极坐标系角度轴)、 radiusAxis (极坐标系半径轴)、 polar (极坐标系底板)、 geo (地理坐标系)、 dataZoom (数据区缩放组件)、 visualMap (视觉映射组件)、 tooltip (提示框组件)、 toolbox (工具栏组件)、 series (系列)等。

为了帮助同学们理解这些概念,我们看一看下图内容~

1678293555955

在图中右侧的 option 中声明了各个组件(包括 series ),各个组件就出现在图中了。

注意:因为系列是一种特殊的组件,所以有时候也会出现 “组件和系列” 这样的描述,这种语境下的 “组件” 是指:除了 “系列 series ” 以外的其他组件。

那么下面就为大家介绍一下常见的组件,包括 seriesdatasetxAxisyAxisgridtooltiptitlelegend

# series

系列( series )是很常见的名词。在 ECharts 里,系列( series )是指:一组数值以及这些数值映射成的图。“系列” 这个词可能来源于 “一系列的数据”,而在 ECharts 中取其扩展的概念,不仅表示数据,也表示数据映射成为的图。所以,一个系列包含的要素至少有:一组 数值图表类型series.type )、以及 (关于这些数据如何映射成图的) 参数

1678293837360

在 ECharts 里系列数据( series.data )就是图表的数据内容数组,系列类型( series.type )就是图表类型,其中,系列类型( series.type )至少有:line(折线图)、bar(柱状图)、pie(饼图)、scatter(散点图)、graph(关系图)、tree(树图)等等。在本课程中重点给大家介绍常用的四种(折线图、柱状图、饼形图、散点图)。

比如,我们把基础折线图示例代码中的 type:"line" 修改为 type:"pie" ,可以看到代码运行后,折线图变成了饼形图。

1678293973444

series 除了 datatype 外,常用的还有如下几个:

  • series.name 是系列的名字。
  • series.stack 是数据堆叠,同个类目轴上系列配置相同的 stack 值后,后一个系列的值会在前一个系列的值上相加。

看官网上折线图堆叠 的示例。

把官网上示例代码中的数据修改为如下图所示。

1678294023581

除了 series.data 可以用来设置数据,还有数据集的方式,我们来看看~

# dataset

虽然每个系列都可以在 series.data 中设置数据,数据一条一条的放在 series 中,但在 ECharts4 之后开始支持数据集了,现在我们也可以使用 数据集dataset)来管理数据。

下图对比了数据集( dataset )和 series.data 在使用上的不同。

1678294075307

通过对比我们不难发现,数据集( dataset )能比较集中地管理相同对象的数据,而不是把它们分散在不同的配置项中,使我们的代码阅读起来更加轻松,数据配置起来也比较简单。

这里只给大家展示两者在写法上的区别,因为我们还没有开始正式学习图表,所以暂时不做练习。

下面我们来看看这些组件吧~

# 用 option 描述图表

用 option 描述图表

上面已经出现了 option 这个概念。ECharts 的使用者,使用 option 来描述其对图表的各种配置,包括:有什么数据、要画什么图表、图表长什么样子、含有什么组件、组件能操作什么事情等等。通过 option 可以快速配置图表所需的数据,指定将数据以何种方式映射成图形,以及图表具备的交互行为。

接下来我们将会学习一些基础配置。

实验中只会根据给出的示例来进行讲解,因为无法将每种示例配置的值都进行介绍,所以我会教大家如何根据手册来查找自己需要的东西。你也无需记住每一种配置,因为当你需要这些实例时,可以在官方文档进行查询。下面的实验基于 折线图堆叠数据聚合 来讲解。

# title

首先来看 option 中的第一个配置 title

1678294226030

我们将这个值修改为 折线图堆叠 2

1678294339502

此时图表的标题也跟着改变了,也就是说 title.text 配置是设置图表的标题。

你可以在配置项 title 中找到 title.text 甚至关于 title 配置项更多的内容。

由于后续我们会讲解很多配置项的内容,就不每一个都贴上配置项文档链接了,你可以在这个地方找到我们没有讲到的配置项内容:

1678294359809

# tooltip

当我们将鼠标放在折线的拐点处时会出现如下所示的提示框组件:

1678294512858

但是如果我们注释掉这个值。

tooltip: {
    trigger: 'axis'
},

此时将鼠标放在折线的拐点处时就不会出现提示框组件了。

1678294631816

此时的 tooltip.trigger = 'axis' 指的是触发类型,它的值是可选的,包括:

  • item :数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
  • axis :坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。
  • none :什么都不触发。

# legend 图例组件

legend.data 是图例的数据数组,也就是红框框起来的值。

1678294693267

# toolbox 工具栏

toolbox 工具栏,内置有导出图片( saveAsImage )、数据视图( dataView )、动态类型切换( magicType )、数据区域缩放( dataZoom )、重置( restore )等五个工具。

toolbox: {
    feature: {
        saveAsImage: {}
    }
},

toolbox.feature.saveAsImage 是保存为图片,也就是这个:

1678327280640

我们在 toolbox 中新增 dataView

1678327296448

显示效果如下图所示。

1678327336739

# 坐标轴

很多系列,例如 line (折线图)、 bar (柱状图)、 scatter (散点图)、 heatmap (热力图)等等,需要运行在 “坐标系” 上。坐标系用于布局这些图,以及显示数据的刻度等等。例如 ECharts 中至少支持这些坐标系:直角坐标系、极坐标系、地理坐标系(GEO)、单轴坐标系、日历坐标系等。

一个坐标系,可以由多个组件协作而成。我们以最常见的直角坐标系来举例。

在 ECharts 的直角坐标系中,有三个重要的组件,分别是:

  • xAxis :直角坐标系 X 轴。
  • yAxis :直角坐标系 Y 轴。
  • grid :直角坐标系网格。

X 轴和 Y 轴好理解,那么直角坐标系中的网格有什么用呢

网格( grid )是定义网格布局、大小和颜色的组件,用于定义直角坐标系整体的布局。

1678327416641

那下面我们用这三个直角坐标系组件来给大家演示一下绘制一个折线图的过程。

想象一下,我们在画画时肯定需要一张纸,在纸上确定好物体的大致位置,然后开始画。所以我们在绘制图表前,肯定需要一个坐标,有了坐标我们才知道折线上的每一个点对应着哪个坐标值。

现在我们准备好如下图所示的一个绘图坐标区域。

1678327472889

option = {
  xAxis: {
    type: "category",
    data: ["周一", "周二", "周三", "周四", "周五", "周六", "周天"],
  },
  yAxis: {
    type: "value",
  },
  series: [
    {
      data: [0, 0, 0, 0, 0, 0, 0],
      type: "line",
    },
  ],
  grid: {
    show: true,
  },
};

然后,在系列( series )中写入一些非 0 值,这样折线就绘制出来了。

series: [
    {
      data: [3,3,4,2,5,4,5],
      type: 'line'
    }
],

1678327517787

# grid

网格( grid )有几个常用的属性,分别是:

  • show 是否显示直角坐标系网格。
  • left 是 grid 组件离容器左侧的距离。
  • top 是 grid 组件离容器上侧的距离。
  • right 是 grid 组件离容器右侧的距离。
  • bottom 是 grid 组件离容器下侧的距离。

在上面的折线图中加入这些属性,我们来看看会有什么变化。

grid: {
    show: true,
    left: 200,
    top: 100,
    right: 200,
    bottom: 100
}

1678327585161

# xAxis 和 yAxis

那我们来看看上面举的折线图例子中的 xAxisyAxis 的属性值吧!

type 是坐标轴类型,其类型有以下几种:

  • value 是数值轴,适用于连续数据。
  • category 是类目轴,适用于离散的类目数据。
  • time 是时间轴,适用于连续的时序数据,与数值轴相比时间轴带有时间的格式化,在刻度计算上也有所不同。
  • log 是对数轴。适用于对数数据。

xAxis.data 是类目数据。

需要注意的是,它只在类目轴( type: 'category' )中有效。如果没有设置 type ,但是设置了 axis.data ,则认为 type'category' 。 如果设置了 type'category' ,但没有设置 axis.data ,则 axis.data 的内容会自动从 series.data 中获取。

如果我们互换两个的值:

1678327790585

显示效果就如下动图所示了。

1678327834941

1678327904571

在上图中,xAxis 的 type 和 data 无法相互满足,所以 xAxis 应该是去从 seris 中取数据了。

1678327910363

上图中将 yAxis 的 type 设置为 category 后,data 中的第一个 3 和第二个 3 是不同的 category。

# 实验总结

1678327856605

# 基本图表绘制

本节实验我们会通过示例来给大家介绍四种基础图表的绘制。

我们一起来学习吧~

# 知识点

  • 柱状图
  • 折线图
  • 饼形图
  • 散点图

# 柱状图

# 带背景色的柱状图

我们要实现的带背景颜色的柱状图如下所示:

1678329140153

注意:图中的数据非真实。

使用以下命令来获取我们的实验文件。

wget https://labfile.oss.aliyuncs.com/courses/5788/ECharts-bar.zip && unzip ECharts-bar.zip

文件中已经为大家设置好了页面结构和样式,我们只需要完成 JS 代码即可。

ECharts 的优点之一就是:我们不用从 0 开始写代码,只需要在官方文档中找到相似度高的示例,然后在示例代码的基础上进行修改即可。

观察效果图,我们可以发现与示例中的带背景颜色的柱状图相似,那我们就可以点进去把代码拷贝到 index.html 文件中。

1678329171928

现在,我们对代码进行修改,涉及到的需要修改的地方已经在下面为大家做了注释,代码如下:

option = {
  title: {
    text: "每天人流量", // 图标题
  },
  xAxis: {
    type: "category",
    data: ["周一", "周二", "周三", "周四", "周五", "周六", "周天"],
  },
  yAxis: {
    type: "value",
  },
  color: ["#b4fe98"], // 调色盘,改变柱子占比的显示颜色
  tooltip: {
    trigger: "axis", // 提示框
  },
  series: [
    {
      data: [200, 300, 150, 100, 400, 600, 480],
      type: "bar",
      showBackground: true, // 显示背景颜色
      backgroundStyle: {
        color: "#EAEAEA", // 柱子的背景颜色
      },
    },
  ],
};

下面我来为大家解释一下代码中的陌生配置项:

color 是绘制图表的调色盘的颜色列表,如果系列没有设置颜色,则会依次循环从该列表中取颜色作为系列颜色。 默认为:

['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc']

1678329376247

showBackground 是设置是否需要显示背景颜色的,取值为布尔类型,默认值为 false。

1678329476515

backgroundStyle 用于设置每一个柱条的背景样式,需要将 showBackground 设置为 true 时才会生效。

1678329484409

# 多列柱状图

有些时候我们可能在同一轴点上需要对多列数据进行对比,比如下图不同国家男女人口数量统计。

1678329566141

下面我们在官网上找找类似的图,发现可以用折柱混合图为模版。

1678329572954

ECharts-bar 文件夹中新建一个 index1.html 文件,页面结构和样式与 index.html 一样请自行拷贝。

我们在此基础上进行修改,其修改如下所示:

option = {
  tooltip: {
    trigger: "axis",
    axisPointer: {
      // 坐标轴指示器配置项
      type: "cross",
      crossStyle: {
        color: "red",
      },
    },
  },
  toolbox: {
    feature: {
      dataView: { show: true, readOnly: false },
      saveAsImage: { show: true }, // 保存图片
    },
  },
  legend: {
    data: ["男", "女"], // 图例的数据数组
  },
  xAxis: [
    {
      type: "category",
      data: ["中国", "美国", "古巴", "印度", "巴西", "不丹", "德国"],
      axisPointer: {
        type: "shadow",
      },
    },
  ],
  yAxis: [
    {
      type: "value",
      name: "人口数量",
      min: 0,
      max: 8000,
      interval: 1000,
      axisLabel: {
        formatter: "{value} 万",
      },
    },
  ],
  series: [
    {
      name: "男",
      type: "bar",
      data: [7113, 1619, 2340, 6987, 1046, 3783, 4145],
    },
    {
      name: "女",
      type: "bar",
      data: [6787, 1660, 2049, 6545, 1080, 4260, 3989],
    },
  ],
};

代码陌生配置项说明如下:

  • tooltip.axisPointer 是配置坐标轴指示器的全局公用设置,也就是说里面包含的属性都是与坐标轴的设置相关。
  • tooltip.axisPointer.type 是指示器类型,包含 line (直线指示器)、 shadow (阴影指示器)、 none (无指示器)、 cross (十字准星指示器)这四种类型。

1678410956996

  • tooltip.axisPointer.crossStyle.color 用于设置线的颜色。

1678411049168

  • legend.data 是图例的数据数组。

1678411042580

  • xAxis.axisPointer.type 是指示器类型,包含 line (直线指示器)、 shadow (阴影指示器)、 none (无指示器)这三种类型。

1678411084367

  • yAxis.min 用于设置 y 轴的最小值。

1678411112996

  • yAxis.max 用于设置 y 轴的最大值。

1678411147995

  • yAxis.axisLabel.formatter 是刻度标签的内容格式器。

1678411173701

注意,由于浏览器默认访问 index.html ,所有要访问其他页面请在 URL 后面加上文件名。

1678411186572

# 堆积条形图

有时候,我们想要在某些大类中将它们各自包含的小类也突出显示出来,这时候就可以使用堆积柱状图来表现。

那么什么是堆叠柱形图呢?

顾名思义,堆积柱状图就是一个系列的数值 “堆积” 在另一个系列上,而从表达总量的变化。

接下来我们要实现一个如下图所示的男女就业比的堆积条形图(图中数据非真实)。

1678411620581

ECharts-bar 文件夹中新建一个 index2.html 文件,页面结构和样式与 index.html 一样请自行拷贝。

分析好效果图的结构,我们在官网上,找到堆叠条形图,拷贝代码到 index2.html 文件中,对代码进行修改。

1678411627189

我们对代码进行以下修改:

option = {
  title: {
    text: "男女就业比",
  },
  tooltip: {
    trigger: "axis",
    axisPointer: {
      type: "shadow",
    },
  },
  legend: {},
  grid: {
    left: "3%",
    right: "4%",
    bottom: "3%",
    containLabel: true, //grid 区域是否包含坐标轴的刻度标签
  },
  xAxis: {
    type: "value",
    min: 0,
    max: 100,
    splitLine: {
      show: false, // 是否显示分隔线
    },
    axisLabel: {
      formatter: "{value} %",
      show: false, // 不显示刻度标签
    },
  },
  yAxis: {
    type: "category",
    axisLine: false, // 是否显示刻度线
    inverse: true, // 是否反向坐标轴
    data: ["前端", "后端", "运维", "测试", "UI", "AI"],
  },
  series: [
    {
      barWidth: 30, // 设置柱子的宽度
      name: "男",
      type: "bar",
      stack: "total",
      label: {
        show: true,
      },
      emphasis: {
        focus: "series", // 高亮的图表样式和标签样式
      },
      itemStyle: {
        color: "#a2d2ff", // 设置柱子的颜色
        borderRadius: [6, 0, 0, 6], // 设置圆角边框
      },
      data: [30, 65, 60, 25, 20, 35],
    },
    {
      name: "女",
      type: "bar",
      stack: "total",
      label: {
        show: true,
      },
      emphasis: {
        focus: "series",
      },
      itemStyle: {
        color: "#b1e693",
        borderRadius: [0, 6, 6, 0],
      },
      data: [60, 25, 20, 75, 70, 15],
    },
  ],
};

代码陌生配置项目说明如下:

  • grid.containLabel 设置 grid 区域是否包含坐标轴的刻度标签,默认为 false。

1678411677243

  • xAxis.splitLine.show 设置是否显示分隔线。

1678411706097

  • xAxis.axisLabel.show 设置是否显示刻度。

1678411758922

  • yAxis.axisLine.show 设置是否显示坐标轴线。

1678411791120

  • yAxis.inverse 设置是否反向坐标轴。

1678411837131

  • series-bar.barWidth 设置条柱的宽度。

1678411874272

  • series-bar.emphasis.focus 设置高亮的图表样式和标签样式,在高亮图表时,它支持三种配置: none 不淡出其它图表,默认使用该配置; self 只聚焦(不淡出)当前高亮的数据的图表; series 聚焦当前高亮的数据所在的系列的所有图表。

1678411983018

  • series-bar.itemStyle.color 设置图表的颜色,如果不设置颜色,就默认从调色盘依次取色。

1678411964474

  • series-bar.itemStyle.borderRadius 设置圆角半径。

1678412019995

# 折线图

使用以下命令获取我们需要的实验文件。

wget https://labfile.oss.aliyuncs.com/courses/5788/ECharts-line.zip && unzip ECharts-line.zip && rm ECharts-line.zip

我们先分析一下效果图的样式和结构,到官网示例中找一个类似的线图,通过比较,发现堆叠面积图比较接近。

将堆叠面积图的代码复制到 ECharts-line/index.html 文件中,我们在此基础上进行修改。

对比一下示例的效果图和我们要实现的效果图,图中只有两条线两轴的数据不同。那我们先把页面结构大致改一改吧~

1678412033267

修改代码如下:

option = {
  tooltip: {
    trigger: "axis",
    axisPointer: {
      type: "cross",
      label: {
        backgroundColor: "#6a7985",
      },
    },
  },
  legend: {
    data: ["播放量", "转发量"],
  },
  grid: {
    left: "3%",
    right: "4%",
    bottom: "3%",
    containLabel: true,
  },
  xAxis: [
    {
      type: "category",
      boundaryGap: false,
      data: [
        "01",
        "02",
        "03",
        "04",
        "05",
        "06",
        "07",
        "08",
        "09",
        "10",
        "11",
        "12",
        "13",
        "14",
        "15",
      ],
    },
  ],
  yAxis: [
    {
      type: "value",
    },
  ],
  series: [
    {
      name: "播放量",
      type: "line",
      stack: "Total",
      areaStyle: {},
      emphasis: {
        focus: "series",
      },
      data: [30, 40, 30, 40, 30, 40, 10, 60, 35, 24, 55, 40, 30, 40, 50],
    },
    {
      name: "转发量",
      type: "line",
      stack: "Total",
      areaStyle: {},
      emphasis: {
        focus: "series",
      },
      data: [50, 30, 55, 40, 15, 60, 30, 70, 20, 10, 50, 60, 50, 30, 20],
    },
  ],
};

修改之后,当前显示效果如下所示:

1678412066674

下面我们就要开始定制线图了~之前讲过的配置项,我在这里就不会赘述,忘记的同学们可以查看之前的文档(实验名:基础知识介绍)或者去官方文档

# 定制线图

目前我们实现的效果图,文字颜色和大小、指示器的类型与我们最终的效果图是不一样的,那么下面我们将图例组件的颜色更换为 rgba(255,255,255,.5) ,文字大小改为 12。

ECharts-line/index.html 文件做如下修改:

<script>
  var option = {
    // 这不是完整代码,只给出了代码的修改部分
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        lineStyle: {
          color: '#dddc6b',
        },
      },
    },
    legend: {
      top: '0%',
      textStyle: {
        color: 'rgba(255,255,255,.5)',
        fontSize: '12',
      },
    },
    grid: {
      left: '10',
      top: '30',
      right: '10',
      bottom: '10',
      containLabel: true,
    },
  };
</script>

修改之后,效果如下所示:

1678412138615

现在我们很明显看出,X 轴和 Y 轴的文本颜色、文字大小、线的颜色与最终效果图是不一致的,所以下面我们对 X 轴和 Y 轴进行相关设置。

# X 轴相关设置

根据之前给出的效果图,我们来修改 X 轴相关设置,在 index.html 文件中写入以下代码:

<script>
  var option = {
    // 只给出修改部分的代码
    xAxis: [
      {
        type: 'category',
        boundaryGap: false, // 去除轴内间距
        axisLabel: {
          textStyle: {
            color: 'rgba(255,255,255,.6)', // 文本颜色
            fontSize: 12,
          },
        },
        axisLine: {
          lineStyle: {
            color: 'rgba(255,255,255,.2)', // X 轴线颜色
          },
        },
        data: [
        '01', '02', '03',
        '04', '05', '06',
        '07', '08', '09',
        '10', '11', '12',
        '13', '14', '15',
        ]
      },
    ],
  };
</script>

在上面代码中,xAxis.boundaryGap 是坐标轴两边留白策略,在类目轴和非类目轴的设置和表现是不一样的。

  • 在类目轴中, boundaryGap 配置为布尔类型,当设置为 true 时,坐标轴上的刻度只会作为分隔线,标签和数据会处于两个刻度之间的中间。
  • 在非类目轴中, boundaryGap 配置为具有两个值的数组,这两个值代表数据的最大值和最小值的延伸范围。

1678412173116

# Y 轴相关设置

根据之前给出的效果图,我们来修改 Y 轴相关设置,在 index.html 文件中写入以下代码

<script>
  var option = {
    // 只给出修改部分代码
    yAxis: [
      {
        type: 'value',
        axisTick: { show: false }, // 去除刻度
        axisLine: {
          lineStyle: {
            color: 'rgba(255,255,255,.1)', // Y 轴线颜色
          },
        },
        axisLabel: {
          textStyle: {
            color: 'rgba(255,255,255,.6)', // 文字颜色
            fontSize: 12, // 文字大小
          },
        },
        splitLine: {
          lineStyle: {
            color: 'rgba(255,255,255,.1)', // 分割线颜色
          },
        },
      },
    ],
  };
</script>

修改 X 轴和 Y 轴之后,显示效果如下所示:

1678412187106

# 修改两个线模块配置

目前区别最大的就是这两个线模块了,我们来分析一下这个折线图的特殊之处(左图为最终效果,右图为当前效果)。

1678412261010

根据观察,你会发现,这两条线的特点是拥有它们自己的填充区域。

最终效果与当前效果的区别可以归纳为以下三条:

  • 线条是圆滑的。
  • 填充区域是渐变色。
  • 拐点大小、颜色和边框不同。

根据需求我们去官方文档查找相应的配置。

series-line.smooth 设置是否平滑曲线显示。

1678412283517

series-line.areaStyle 设置区域填充样式的容器。

1678412308443

series-line.areaStyle.color 设置填充的颜色,包括不同的渐变。

1678412337172

series-line.showSymbol 是否显示 symbol,也就是图上的数据点,默认为 true。

1678412364453

了解了需要的配置项之后,那我们来对代码进行修改吧!

修改代码如下:

<script>
  var option = {
    // 你给出修改部分代码
    series: [
      {
        name: '播放量',
        type: 'line',
        smooth: true, // 线是圆滑
        symbol: 'circle', // 设置拐点为小圆点
        symbolSize: 5, // 拐点大小
        showSymbol: false, // 开始不显示拐点, 鼠标经过显示
        // 单独修改线的样式
        lineStyle: {
          normal: {
            color: '#0184d5',
            width: 2,
          },
        },
        // 填充区域
        areaStyle: {
          normal: {
            // 渐变色,只需要复制即可
            color: new echarts.graphic.LinearGradient(
              0,
              0,
              0,
              1,
              [
                {
                  offset: 0,
                  // 渐变色的起始颜色
                  color: 'rgba(1, 132, 213, 0.4)',
                },
                {
                  offset: 0.8,
                  // 渐变线的结束颜色
                  color: 'rgba(1, 132, 213, 0.1)',
                },
              ],
              false
            ),
            shadowColor: 'rgba(0, 0, 0, 0.1)',
          },
        },
        // 设置拐点颜色以及边框
        itemStyle: {
          normal: {
            color: '#0184d5',
            borderColor: 'rgba(221, 220, 107, .1)',
            borderWidth: 12,
          },
        },
        data: [120, 132, 101, 134, 90, 230, 210],
      },
      {
        name: '转发量',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 5,
        showSymbol: false,
        lineStyle: {
          normal: {
            color: '#00d887',
            width: 2,
          },
        },
        areaStyle: {
          normal: {
            color: new echarts.graphic.LinearGradient(
              0,
              0,
              0,
              1,
              [
                {
                  offset: 0,
                  color: 'rgba(0, 216, 135, 0.4)',
                },
                {
                  offset: 0.8,
                  color: 'rgba(0, 216, 135, 0.1)',
                },
              ],
              false
            ),
            shadowColor: 'rgba(0, 0, 0, 0.1)',
          },
        },
        itemStyle: {
          normal: {
            color: '#00d887',
            borderColor: 'rgba(221, 220, 107, .1)',
            borderWidth: 12,
          },
        },
        data: [220, 182, 191, 234, 290, 330, 310],
      },
    ],
  };
</script>

修改之后,最终效果就实现啦~

1678412385454

想了解更多类型的折线图,请看官方文档。

# 饼形图

使用以下命令获取我们需要的实验文件。

wget https://labfile.oss.aliyuncs.com/courses/5788/ECharts-pie.zip && unzip ECharts-pie.zip && rm ECharts-pie.zip

我们先分析一下效果图的图样式和结构,到官网示例中找一个类似的线图,通过比较,选择了基础南丁格尔玫瑰图

1678412429695

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

将基础南丁格尔玫瑰图的代码复制到 ECharts-pie/index.html 文件中,我们在此基础上进行修改。

对比一下示例的效果图和我们要实现的效果图。

1678412454170

根据给出的需求,我们先调整一下表中的数据和扇面配色吧!

修改代码如下所示:

option = {
  color: [
    "#7DCEA0",
    "#A9DFBF",
    "#F9E79F",
    "#F4D03F",
    "#B7950B",
    "#F8C471",
    "#E59866",
    "#E67E22",
    "#D68910",
    "#F1948A",
    "#E74C3C",
  ],
  title: {
    text: "全球新冠疫情部分数据",
    left: "center",
    textStyle: {
      color: "#fff",
    },
  },
  legend: {
    top: "bottom",
  },
  series: [
    {
      name: "面积模式",
      type: "pie",
      radius: [50, 250], // 饼图的半径。
      center: ["50%", "50%"], // 饼图中心坐标
      roseType: "area", // 设置是否展示成南丁格尔图
      itemStyle: {
        borderRadius: 8, //
      },
      data: [
        { value: 109, name: "巴林" },
        { value: 117, name: "马来西亚" },
        { value: 160, name: "新加坡" },
        { value: 176, name: "挪威" },
        { value: 239, name: "比利时" },
        { value: 248, name: "瑞典" },
        { value: 319, name: "英国" },
        { value: 321, name: "荷兰" },
        { value: 337, name: "瑞士" },
        { value: 522, name: "日本" },
        { value: 572, name: "美国" },
      ],
    },
  ],
};

陌生配置说明如下:

  • series.radius 设置饼形的半径。

1678412483415

  • series.center 设置饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标。

1678412509060

  • series.roseType 设置是否展示成南丁格尔图,通过半径区分数据大小,有两种模式:

  • radius 区圆心角展现数据的百分比,半径展现数据的大小。

  • area 所有扇区圆心角相同,仅通过半径展现数据大小。

1678412562826

  • series.itemStyle.borderRadius 用于指定饼图扇形区块的内外圆角半径。

1678412604550

1678412591491

下面我们就来定制饼状图了~具体的配置项,我们在之前的实验中已经为大家详细讲解,这里就不再赘述,忘记的同学们可以查看之前的文档或者去官方文档

# 定制饼状图

我们来看一下当前效果(左图)与最终效果(右图)的对比图。

1678412626069

通过比较我们可以看出页面的形状不同、文字颜色不同。

在修改代码之前,先给大家介绍一下饼图相关的配置。

  • legend.itemWidthlegend.itemHeight 分别是图例标记的图表宽度和高度,也就是最下方小图标的宽高。

1678412670096

  • series-pie.labelLine.length 是视觉引导线第一段的长度。

1678412714932

  • series-pie.labelLine.length2 是视觉引导项第二段的长度。

1678412731616

修改代码如下:

options = {
    legend: {
        left: 'center',
        top: 'bottom',
        itemWidth: 20,
        itemHeight: 10,
        textStyle: {
            color: '#faedf0',
            fontSize: '14',
        },
    },
}
// 删去 series.itemStyle.borderRadius 配置
label: {
     fontSize: 15,
},
labelLine: {
    // 连接到图表的线长度
    length: 10,
    // 连接到文字的线长度
    length2: 15,
},

修改之后,最终效果就实现啦~

1678412737693

# 散点图

使用以下命令获取我们需要的实验文件。

wget https://labfile.oss.aliyuncs.com/courses/5788/ECharts-scatter.zip && unzip ECharts-scatter.zip && rm ECharts-scatter.zip

我们先分析一下效果图的图样式和结构,到官网示例中找一个类似的线图,通过比较,选择了 AQI 气泡图

1678412757820

我们把 AQI 气泡图的代码拷贝到 ECharts-scatter/index1.html 文件中,对比最终效果调整页面结构。

1678412767507

修改代码如下:

const dataBJ = [
  [1, 55, 9, 56, 0.46, 18, 6, "良"],
  [2, 25, 11, 21, 0.65, 34, 9, "优"],
  [3, 56, 7, 63, 0.3, 14, 5, "良"],
  [4, 33, 7, 29, 0.33, 16, 6, "优"],
  [5, 42, 24, 44, 0.76, 40, 16, "优"],
  [6, 82, 58, 90, 1.77, 68, 33, "良"],
  [7, 74, 49, 77, 1.46, 48, 27, "良"],
  [8, 78, 55, 80, 1.29, 59, 29, "良"],
  [9, 267, 216, 280, 4.8, 108, 64, "重度污染"],
  [10, 185, 127, 216, 2.52, 61, 27, "中度污染"],
  [11, 39, 19, 38, 0.57, 31, 15, "优"],
  [12, 41, 11, 40, 0.43, 21, 7, "优"],
  [13, 64, 38, 74, 1.04, 46, 22, "良"],
  [14, 108, 79, 120, 1.7, 75, 41, "轻度污染"],
  [15, 108, 63, 116, 1.48, 44, 26, "轻度污染"],
  [16, 33, 6, 29, 0.34, 13, 5, "优"],
  [17, 94, 66, 110, 1.54, 62, 31, "良"],
  [18, 186, 142, 192, 3.88, 93, 79, "中度污染"],
  [19, 57, 31, 54, 0.96, 32, 14, "良"],
  [20, 22, 8, 17, 0.48, 23, 10, "优"],
  [21, 39, 15, 36, 0.61, 29, 13, "优"],
  [22, 94, 69, 114, 2.08, 73, 39, "良"],
  [23, 99, 73, 110, 2.43, 76, 48, "良"],
  [24, 31, 12, 30, 0.5, 32, 16, "优"],
  [25, 42, 27, 43, 1, 53, 22, "优"],
  [26, 154, 117, 157, 3.05, 92, 58, "中度污染"],
  [27, 234, 185, 230, 4.09, 123, 69, "重度污染"],
  [28, 160, 120, 186, 2.77, 91, 50, "中度污染"],
  [29, 134, 96, 165, 2.76, 83, 41, "轻度污染"],
  [30, 52, 24, 60, 1.03, 50, 21, "良"],
  [31, 46, 5, 49, 0.28, 10, 6, "优"],
];
const dataGZ = [
  [1, 26, 37, 27, 1.163, 27, 13, "优"],
  [2, 85, 62, 71, 1.195, 60, 8, "良"],
  [3, 78, 38, 74, 1.363, 37, 7, "良"],
  [4, 21, 21, 36, 0.634, 40, 9, "优"],
  [5, 41, 42, 46, 0.915, 81, 13, "优"],
  [6, 56, 52, 69, 1.067, 92, 16, "良"],
  [7, 64, 30, 28, 0.924, 51, 2, "良"],
  [8, 55, 48, 74, 1.236, 75, 26, "良"],
  [9, 76, 85, 113, 1.237, 114, 27, "良"],
  [10, 91, 81, 104, 1.041, 56, 40, "良"],
  [11, 84, 39, 60, 0.964, 25, 11, "良"],
  [12, 64, 51, 101, 0.862, 58, 23, "良"],
  [13, 70, 69, 120, 1.198, 65, 36, "良"],
  [14, 77, 105, 178, 2.549, 64, 16, "良"],
  [15, 109, 68, 87, 0.996, 74, 29, "轻度污染"],
  [16, 73, 68, 97, 0.905, 51, 34, "良"],
  [17, 54, 27, 47, 0.592, 53, 12, "良"],
  [18, 51, 61, 97, 0.811, 65, 19, "良"],
  [19, 91, 71, 121, 1.374, 43, 18, "良"],
  [20, 73, 102, 182, 2.787, 44, 19, "良"],
  [21, 73, 50, 76, 0.717, 31, 20, "良"],
  [22, 84, 94, 140, 2.238, 68, 18, "良"],
  [23, 93, 77, 104, 1.165, 53, 7, "良"],
  [24, 99, 130, 227, 3.97, 55, 15, "良"],
  [25, 146, 84, 139, 1.094, 40, 17, "轻度污染"],
  [26, 113, 108, 137, 1.481, 48, 15, "轻度污染"],
  [27, 81, 48, 62, 1.619, 26, 3, "良"],
  [28, 56, 48, 68, 1.336, 37, 9, "良"],
  [29, 82, 92, 174, 3.29, 0, 13, "良"],
  [30, 106, 116, 188, 3.628, 101, 16, "轻度污染"],
  [31, 118, 50, 0, 1.383, 76, 11, "轻度污染"],
];
const schema = [
  { name: "date", index: 0, text: "日" },
  { name: "AQIindex", index: 1, text: "AQI指数" },
  { name: "PM25", index: 2, text: "PM2.5" },
  { name: "PM10", index: 3, text: "PM10" },
  { name: "CO", index: 4, text: "一氧化碳(CO)" },
  { name: "NO2", index: 5, text: "二氧化氮(NO2)" },
  { name: "SO2", index: 6, text: "二氧化硫(SO2)" },
];
const itemStyle = {
  opacity: 0.8,
  shadowBlur: 10,
  shadowOffsetX: 0,
  shadowOffsetY: 0,
  shadowColor: "rgba(0,0,0,0.3)",
};
option = {
  color: ["#dd4444", "#fec42c", "#80F1BE"],
  legend: {
    top: 10,
    data: ["北京", "上海", "广州"],
    textStyle: {
      fontSize: 16,
    },
  },
  grid: {
    left: "10%",
    right: 150,
    top: "18%",
    bottom: "10%",
  },
  tooltip: {
    backgroundColor: "rgba(255,255,255,0.7)",
    formatter: function (param) {
      var value = param.value;
      return (
        '<div style="border-bottom: 1px solid rgba(255,255,255,.3); font-size: 18px;padding-bottom: 7px;margin-bottom: 7px">' +
        param.seriesName +
        " " +
        value[0] +
        "日:" +
        value[7] +
        "</div>" +
        schema[1].text +
        ":" +
        value[1] +
        "<br>" +
        schema[2].text +
        ":" +
        value[2] +
        "<br>" +
        schema[3].text +
        ":" +
        value[3] +
        "<br>" +
        schema[4].text +
        ":" +
        value[4] +
        "<br>" +
        schema[5].text +
        ":" +
        value[5] +
        "<br>" +
        schema[6].text +
        ":" +
        value[6] +
        "<br>"
      );
    },
  },
  xAxis: {
    type: "value",
    name: "日期",
    nameGap: 16,
    nameTextStyle: {
      fontSize: 16,
    },
    max: 31,
    splitLine: {
      show: false,
    },
  },
  yAxis: {
    type: "value",
    name: "AQI指数",
    nameLocation: "end",
    nameGap: 20,
    nameTextStyle: {
      fontSize: 16,
    },
    splitLine: {
      show: false,
    },
  },
  visualMap: [
    {
      left: "right",
      top: "10%",
      dimension: 2,
      min: 0,
      max: 250,
      itemWidth: 30,
      itemHeight: 120,
      calculable: true,
      precision: 0.1,
      text: ["圆形大小:PM2.5"],
      textGap: 30,
      inRange: {
        symbolSize: [10, 70],
      },
      outOfRange: {
        symbolSize: [10, 70],
        color: ["rgba(255,255,255,0.4)"],
      },
      controller: {
        inRange: {
          color: ["#c23531"],
        },
        outOfRange: {
          color: ["#999"],
        },
      },
    },
  ],
  series: [
    {
      name: "北京",
      type: "scatter",
      itemStyle: itemStyle,
      data: dataBJ,
    },
    {
      name: "广州",
      type: "scatter",
      itemStyle: itemStyle,
      data: dataGZ,
    },
  ],
};

修改之后,显示效果如下:

1678412803540

在定制散点图之前,我先给大家介绍一下上面代码中的陌生配置。

  • tooltip.backgroundColor 是提示框浮层的背景颜色。

1678412828630

  • tooltip.formatter 是用来设置提示浮层内容显示的格式,它支持字符串模板回调函数两种形式。

1678412874012

  • xAxis.nameGap 用于设置坐标轴名称与轴线之间的距离,默认值为 15。

1678412933448

  • xAxis.nameTextStyle.fontsize 是用来设置坐标轴名称文字的字体大小,默认值为 12。

1678412973600

  • xAxis.nameLocation 是用来设置坐标轴名称显示位置,可选值有 start (开头)、 middlecenter (居中)、 end (末尾)。

1678413021612

  • visualMap 是视觉映射组件。

1678413014459

  • visualMap.leftvisualMap.top 设置 visualMap 组件离容器左侧和顶部的距离。

1678413057027

  • visualMap.dimension 用来指定数据的哪个维度映射到视觉元素上。

1678413082677

1678413100901

  • visualMap.minvisualMap.max 用来设置 visualMap 组件允许的最小值和最大值。

1678413133474

  • visualMap.itemWidthvisualMap.itemHeight 设置 visualMap 组件图表的宽度和高度。

1678413162901

  • visualMap.calculable 设置是否显示拖拽用的手柄(手柄能拖拽调整选中范围)。

1678413190234

  • visualMap.precision 是设置数据展示的小数精度,默认为 0,无小数点。

1678413223708

  • visualMap.textvisualMap.textGap 用来设置 visualMap 组件图表上两端的文字和设置文字与图表之间的距离。

1678413249236

  • visualMap.inRange.symbolSize 设置选中范围内散点的大小。

1678413312460

  • visualMap.outOfRange.symbolSize 设置选中范围外散点的大小。

1678413357948

  • visualMap.outOfRange.color 设置选中范围外散点的颜色。

1678413404314

  • visualMap.controller 是 visualMap 组件中,控制器的 inRange、outOfRange 设置。

1678413449165

下面我们就来定制散点图了~具体的配置项,我们在之前的实验中已经为大家详细讲解,这里就不再赘述,忘记的同学们可以查看之前的文档或者去官方文档

# 定制散点图

我们来一下当前效果(右图)与最终效果(左图)的对比图。

1678413464891

观察上图,可以看出它们之间的区别:坐标轴的字体样式不同、散点的颜色不同、visualMap 组件的样式不同。

接下来我们,对代码做如下修改:

var option = {
  // 只给出修改部分的代码
  backgroundColor: "#2e4c6d",
  color: ["#ffC4E1", "#71DFE7"],
  legend: {
    data: ["晴天", "雨天"],
    textStyle: {
      color: "#fff",
      fontSize: 16,
    },
  },
  xAxis: {
    nameTextStyle: {
      color: "#fff",
      fontSize: 14,
    },
    axisLine: {
      lineStyle: {
        color: "#777",
      },
    },
    axisTick: {
      lineStyle: {
        color: "#777", // 刻度线的颜色
      },
    },
    axisLabel: {
      formatter: "{value}",
      textStyle: {
        color: "#fff",
      },
    },
  },
  yAxis: {
    name: "心情指数",
    nameTextStyle: {
      color: "#fff",
      fontSize: 16,
    },
    axisLine: {
      lineStyle: {
        color: "#777",
      },
    },
    axisTick: {
      lineStyle: {
        color: "#777",
      },
    },
    splitLine: {
      show: false,
    },
    axisLabel: {
      textStyle: {
        color: "#fff",
      },
    },
  },
  visualMap: [
    {
      left: "right", // 组件在图的右侧显示
      top: "40%", // 组件与顶部的距离
      dimension: 2, // 映射数据的维度
      itemWidth: 30, // 组件的宽度
      itemHeight: 120, // 组件的高度
      calculable: true, // 是否显示拖拽用的手柄
      precision: 0.1, // 数据展示的小数精度
      text: ["指数范围"], // 组件的文本内容
      textGap: 30, // 两端文字主体之间的距离
      textStyle: {
        color: "#fff",
      },
      controller: {
        inRange: {
          color: ["#77e4d4"],
        },
      },
    },
  ],
  series: [
    {
      name: "晴天",
    },
    {
      name: "雨天",
    },
  ],
};

修改代码之后,效果如下所示:

1678413483415

由于当前还没有修改数据,所以没有修改指数范围的最大值和最小值。

# 设置数据

页面显示已经和最终结果差不多相同了,我们再来对比一下,最终效果(左图)和当前效果(右图)。

1678413534152

通过观察我们可以看出,提示框浮层的样式和文字内容不同。所以接下来的重点是修改图表数据和提示框的文字内容、样式。

修改代码如下:

/* 只给出修改部分的代码 */
// 晴天心情指数的数据
var sun = [
  [1, 80, 3, "良"],
  [2, 95, 6, "极好"],
  [3, 82, 4, "良"],
  [4, 90, 4, "极好"],
  [5, 98, 6, "极好"],
  [6, 85, 5, "良"],
  [7, 74, 2, "良"],
  [8, 59, -1, "良"],
  [9, 40, -3, "重度污染"],
  [10, 60, 4, "中度污染"],
  [11, 100, 6, "极好"],
  [12, 98, 5, "极好"],
  [13, 88, 3, "良"],
  [14, 78, 2, "轻度污染"],
  [15, 74, 2, "轻度污染"],
  [16, 100, 6, "极好"],
  [17, 70, 1, "良"],
  [18, 30, -4, "中度污染"],
  [19, 62, -1, "良"],
  [20, 33, -3, "极好"],
  [21, 99, 4.5, "极好"],
  [22, 94.5, 4, "良"],
  [23, 99, 7, "良"],
  [24, 31, -5, "极好"],
  [25, 55.5, -3, "极好"],
  [26, 35.5, -5, "中度污染"],
  [27, 49.8, -3, "重度污染"],
  [28, 91, 5, "中度污染"],
  [29, 83, 4, "轻度污染"],
  [30, 50, -2, "良"],
  [31, 100, 6, "极好"],
];
// 雨天心情指数的数据
var rain = [
  [1, 80, 4, "极好"],
  [2, 50, 1, "良"],
  [3, 55, -1, "良"],
  [4, 81.2, 4, "极好"],
  [5, 81, 1, "极好"],
  [6, 92, 6, "良"],
  [7, 51, -2, "良"],
  [8, 75.5, 2, "良"],
  [9, 77, 3, "良"],
  [10, 56, -3, "良"],
  [11, 25, -10, "良"],
  [12, 64, 1, "良"],
  [13, 70, 2, "良"],
  [14, 77, 3, "良"],
  [15, 74, 4, "轻度污染"],
  [16, 51, 1, "良"],
  [17, 53, -2, "良"],
  [18, 51, -3, "良"],
  [19, 91, 6, "良"],
  [20, 73, 1, "良"],
  [21, 31, -2, "良"],
  [22, 68, 3, "良"],
  [23, 53, 1, "良"],
  [24, 55, 1, "良"],
  [25, 40, 1, "轻度污染"],
  [26, 48, 2, "轻度污染"],
  [27, 26, -19, "良"],
  [28, 87, 6, "良"],
  [29, 94, 6, "良"],
  [30, 70, 3.2, "轻度污染"],
  [31, 83.4, 4, "轻度污染"],
];
// 空气质量的各项指标
var schema = [
  { name: "day", index: 0, text: "日" },
  { name: "mood", index: 1, text: "心情指数" },
  { name: "dopamine", index: 2, text: "多巴胺" },
  { name: "air", index: 3, text: "空气质量" },
];
var option = {
  tooltip: {
    padding: 10,
    backgroundColor: "#222",
    borderColor: "#777",
    borderWidth: 1,
    formatter: function (obj) {
      var value = obj.value;
      return (
        '<div style="border-bottom: 1px solid rgba(255,255,255,.3); font-size: 18px;padding-bottom: 7px;margin-bottom: 7px">' +
        "2021 年" +
        " " +
        value[0] +
        " 日 " +
        obj.seriesName +
        "</div>" +
        schema[1].text +
        ":" +
        value[1] +
        "<br>" +
        schema[2].text +
        ":" +
        value[2] +
        "<br>" +
        schema[3].text +
        ":" +
        value[3] +
        "<br>"
      );
    },
  },
  series: [
    {
      name: "晴天",
      type: "scatter",
      data: sun,
    },
    {
      name: "雨天",
      type: "scatter",
      data: rain,
    },
  ],
};

修改之后,最终效果就实现啦!

# 实验总结

本节实验给大家介绍了四种基本图表的绘制,同时通过图表绘制的示例告诉大家学习 ECharts 的方法。同学们打开官方文档的配置项可以看到种类之多,我们肯定不可能把每种配置项都记下来,只有在用的时候去查找。所以,学习 ECharts 的方法就是:

  • 你要确定好你想绘制图表的效果;
  • 找到类似的图,在所给代码的基础上加以修改;
  • 需要添加什么属性,可以再去配置项库中查找;
  • 如果是从未接触过的配置项,建议在网上搜索,一般会找到答案