ECharts 万字入门指南

同步至个人站点:ECharts 万字入门指南

ECharts 万字入门指南

本文将作为你的 ECharts 入门指南,带你系统性地梳理 ECharts 的核心知识体系,并通过一个贴近实际业务的"高三期末考试成绩分析"案例,手把手教你如何将数据转化为富有洞察力的图表。

前端,本质上就是把数据可视化的技术。如何将枯燥的数据,以一种更直观、更易于理解的方式呈现给用户,始终是一个重要的课题。

图表,无疑是这个问题的最佳答案之一。

小到健康 App 中记录一周睡眠变化的柱状图,大到金融应用的实时股票仪表板,图表作为一种强大的视觉语言,其传递信息的效率远超纯粹的文字或表格。它能帮助我们快速发现数据中的模式、趋势和异常点。

在众多选择中,Apache ECharts 无疑是当下最闪耀的产品之一。凭借其丰富的图表类型、强大的交互功能、灵活的配置项以及活跃的社区,成为了全球前端开发者的首选。

然而,和 GSAP 动画库 一样,很多人对 ECharts 的第一印象是"配置项繁多"、"学习曲线陡峭"。但事实果真如此吗?

当我们静下心来,深入探索 ECharts 的世界,会发现其核心概念并不复杂。万变不离其宗,所有的图表配置,都围绕着一些固定的核心模块展开:容器与大小、样式、数据集、坐标轴、视觉映射、图例等等。

ECharts 官网提供了海量的示例,几乎涵盖了你能想到的所有图表效果。甚至,它的配置项文档本身就是可交互的------你可以一边修改配置,一边实时预览效果。这极大地降低了学习门槛。

ECharts 初体验:绘制你的第一个图表

学习任何一门技术的最好方式,就是从一个"Hello World"开始。

引入方式

我们将使用最简单的方式:通过 CDN 引入。你只需要在 HTML 文件中加入一个 <script> 标签即可。这种方式无需构建工具,非常适合快速原型开发和学习。

html 复制代码
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>

完整示例

将下面的代码完整复制到一个 HTML 文件中,然后用浏览器打开它,你就能看到你的第一个 ECharts 图表了。

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>ECharts 入门示例</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
  </head>
  <body>
    <div id="main" style="width: 600px;height:400px;"></div>

    <script type="text/javascript">
      // 3. 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById("main"))

      // 4. 指定图表的配置项和数据
      var option = {
        // 标题
        title: {
          text: "我的第一个 ECharts 图表",
        },
        // 提示框
        tooltip: {},
        // X 轴
        xAxis: {
          data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
        },
        // Y 轴
        yAxis: {},
        // 系列(系列决定了图表类型和数据)
        series: [
          {
            name: "销量",
            type: "bar", // 'bar' 表示这是一个柱状图
            data: [5, 20, 36, 10, 10, 20],
          },
        ],
      }

      // 5. 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option)
    </script>
  </body>
</html>

这个简单的例子,已经揭示了 ECharts 的核心工作流程:引入脚本 -> 准备容器 -> 初始化实例 -> 设置配置项 。而所有 ECharts 图表的实现,都蕴含在那个巨大的 option 对象中。

核心概念解析:解构 option 对象

ECharts 的 option 对象是一个庞大而复杂的 JavaScript 对象,option 描述了图表的一切:数据、样式、交互、动画等等。理解了它的核心构成,就等于掌握了 ECharts 的精髓。

让我们像剥洋葱一样,一层一层地解析 option 的核心组件。

series:系列与图表类型

series 是 ECharts 中最重要的配置项,没有之一。它是一个数组,数组中的每一个对象都代表一个"系列"。

什么是"系列"?

你可以把它理解为一组相关的数据,以及这组数据如何被可视化的规则。一个图表中可以包含多个系列,每个系列会按照自己的规则(即 type)绘制成图。

比如,在上面的例子中:

javascript 复制代码
series: [
  {
    name: "销量",
    type: "bar", // 图表类型
    data: [5, 20, 36, 10, 10, 20], // 系列数据
  },
]
  • type: 'bar' 告诉 ECharts,这个系列要绘制成柱状图。
  • data: [...] 提供了这组柱状图的具体数值。

如果我想在同一个图表中,再增加一条折线图来表示"产量",只需要在 series 数组中再增加一个对象即可。

javascript 复制代码
series: [
  {
    name: "销量",
    type: "bar",
    data: [5, 20, 36, 10, 10, 20],
  },
  {
    name: "产量",
    type: "line", // 图表类型为折线图
    data: [15, 25, 30, 18, 15, 30],
  },
]

ECharts 支持的图表类型非常丰富,常见的有:

  • line: 折线图
  • bar: 柱状图
  • pie: 饼图
  • scatter: 散点图
  • radar: 雷达图
  • map: 地图
  • tree: 树图
  • graph: 关系图
  • ...等等

series 的强大之处在于,它不仅定义了图表的"形",更承载了图表的"魂"------数据。

xAxis & yAxis:坐标轴

对于绝大多数图表(如折线图、柱状图、散点图),坐标轴是必不可少的。ECharts 通过 xAxis (X 轴) 和 yAxis (Y 轴) 来进行配置。它们通常成对出现,共同定义了一个直角坐标系 (Grid)

坐标轴主要由轴线、刻度、刻度标签、轴名称等部分组成。

一个常见的 xAxis 配置如下:

javascript 复制代码
xAxis: {
  type: 'category', // 坐标轴类型
  data: ['一月', '二月', '三月', '四月', '五月'], // 类目数据
  name: '月份', // 轴名称
  axisLine: { show: true }, // 显示轴线
  axisTick: { show: true }, // 显示刻度
  axisLabel: {
    color: '#333',
    fontSize: 12
  } // 刻度标签样式
}

坐标轴的 type 是一个关键属性,它决定了坐标轴如何解析数据:

  • 'value': 数值轴 。适用于连续数据,会自动根据 series.data 的最大最小值来生成刻度。
  • 'category': 类目轴 。适用于离散的类目数据,类目数据需要通过 xAxis.data 来指定。
  • 'time': 时间轴。适用于连续的时序数据,能自动格式化时间标签。
  • 'log': 对数轴。适用于数据跨度非常大的情况。

yAxis 的配置与 xAxis 类似。在一个图表中,可以有多个 X 轴和 Y 轴,通过 xAxisIndexyAxisIndex 来关联 series

grid:绘图网格

grid 组件定义了直角坐标系在图表容器中的位置和大小。当你想调整图表主体部分(不包括标题、图例等)的位置时,就需要配置它。

javascript 复制代码
grid: {
  left: '3%', // 网格区域离容器左侧的距离
  right: '4%',
  bottom: '3%',
  top: '10%',
  containLabel: true // 防止标签溢出
}

containLabel: true 是一个非常实用的配置,它会自动计算坐标轴标签的宽度,并调整 grid 的位置,以确保标签能够完整显示。

title:标题

一个图表应该有一个明确的标题。title 组件用于配置主标题和副标题。

javascript 复制代码
title: {
  text: '网站月度访问量', // 主标题
  subtext: '数据来源:模拟数据', // 副标题
  left: 'center', // 标题水平居中
  textStyle: {
    color: '#c23531',
    fontSize: 20
  }
}

tooltip:提示框

当鼠标悬浮到图表的数据项上时,tooltip 组件可以显示详细的数据信息,这是图表交互的重要一环。

javascript 复制代码
tooltip: {
  trigger: 'axis', // 触发类型
  axisPointer: { // 坐标轴指示器配置
    type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' | 'cross'
  }
}

trigger 属性决定了提示框的触发方式:

  • 'item': 数据项触发。鼠标悬浮到单个数据项(如柱状图的某个柱子、饼图的某个扇区)时触发。
  • 'axis': 坐标轴触发。鼠标悬浮到坐标轴的某个刻度上时,会同时显示该刻度下所有系列的数据。常用于折线图和柱状图。
  • 'none': 不触发。

你可以通过 formatter 函数来自定义提示框显示的内容,支持 HTML 字符串和回调函数,给予了极高的灵活度。

legend:图例

当图表包含多个系列时,legend (图例) 组件用于区分不同的系列。

javascript 复制代码
legend: {
  data: ['销量', '产量'], // 图例项的名称,需要与 series 的 name 对应
  top: 'bottom' // 图例位置
}

legendseries 是通过 name 属性关联的。点击图例项,可以控制对应系列的显示和隐藏,这是 ECharts 内置的交互行为。

dataset:数据集

从 ECharts 4 开始,引入了 dataset 组件,这是一个非常重要的概念,它实现了数据与配置的分离

在之前的例子中,我们的数据是直接写在 series.data 里的。当数据量较大,或者多个系列需要共用同一份数据时,这种方式就显得很臃肿。

dataset 允许我们统一定义数据源,然后在 series 中通过 encode 来映射数据。

javascript 复制代码
var option = {
  dataset: {
    // 提供一份数据。
    source: [
      ["product", "2015", "2016", "2017"],
      ["Matcha Latte", 43.3, 85.8, 93.7],
      ["Milk Tea", 83.1, 73.4, 55.1],
      ["Cheese Cocoa", 86.4, 65.2, 82.5],
      ["Walnut Brownie", 72.4, 53.9, 39.1],
    ],
  },
  // 声明一个 X 轴,类目轴(category)。默认情况下,类目轴对应到 dataset 第一列。
  xAxis: { type: "category" },
  // 声明一个 Y 轴,数值轴。
  yAxis: {},
  // 声明多个 series。
  series: [{ type: "bar" }, { type: "bar" }, { type: "bar" }],
}

在这个例子中,dataset.source 定义了一个二维数组。ECharts 会默认将第一行/第一列作为维度(dimension)。series 中甚至不需要写 data,ECharts 会自动从 dataset 中取数据。第一列 product 映射到 xAxis,后续的 '2015', '2016', '2017' 三列数据,依次映射到三个 series

使用 dataset 的好处是:

  1. 数据复用 :一份数据可以被多个系列、多个组件(如 visualMap)使用。
  2. 数据转换 :可以配合 data-transform 对数据进行筛选、聚合等预处理。
  3. 代码清晰:将数据逻辑和样式配置分离开,更易于维护。

强烈推荐在开发中优先使用 dataset 来管理数据。

实战:高三年级期末考试多维分析

理论知识总是枯燥的,让我们通过一个综合案例,将前面学到的知识点串联起来。

背景:假设我们是某高中的数据分析师,拿到了一份高三年级本次期末考试的成绩单。我们需要通过数据可视化的方式,从多个维度对这次考试进行分析,为教学工作提供数据支持。

数据维度:班级、学生姓名、各科成绩(语文、数学、英语、物理、化学、生物)、总分。

场景一:各班级平均总分对比(柱状图)

分析目标:直观对比各个班级的平均总分,了解班级间的整体学习水平差异。

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>场景一:各班级平均总分对比</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
  </head>
  <body>
    <div id="bar-chart" style="width: 100%; height: 500px;"></div>

    <script type="text/javascript">
      // --- 数据准备 ---
      function generateMockData() {
        const classes = [
          "高三(1)班",
          "高三(2)班",
          "高三(3)班",
          "高三(4)班",
          "高三(5)班",
          "高三(6)班",
        ]
        const subjects = ["语文", "数学", "英语", "物理", "化学", "生物"]
        const studentsPerClass = 50
        let data = []
        let studentId = 1

        classes.forEach((className) => {
          for (let i = 0; i < studentsPerClass; i++) {
            let student = { 班级: className, 姓名: `学生${studentId}` }
            let totalScore = 0
            subjects.forEach((subject) => {
              const score = Math.floor(Math.random() * 101) + 50
              student[subject] = score
              totalScore += score
            })
            student["总分"] = totalScore
            data.push(student)
            studentId++
          }
        })
        return data
      }

      const examData = generateMockData()

      function calculateClassAverage(data) {
        const classScores = {}
        data.forEach((student) => {
          const className = student["班级"]
          if (!classScores[className]) {
            classScores[className] = { total: 0, count: 0 }
          }
          classScores[className].total += student["总分"]
          classScores[className].count++
        })

        const averageData = Object.keys(classScores).map((className) => ({
          className: className,
          averageScore: (
            classScores[className].total / classScores[className].count
          ).toFixed(2),
        }))
        averageData.sort((a, b) => b.averageScore - a.averageScore)
        return averageData
      }

      const classAverageData = calculateClassAverage(examData)

      // --- ECharts 配置 ---
      var barChart = echarts.init(document.getElementById("bar-chart"))
      var barChartOption = {
        title: {
          text: "高三各班级期末考试平均总分对比",
          left: "center",
        },
        tooltip: { trigger: "axis", axisPointer: { type: "shadow" } },
        grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true },
        xAxis: {
          type: "category",
          data: classAverageData.map((item) => item.className),
          axisLabel: { interval: 0, rotate: 30 },
        },
        yAxis: { type: "value", name: "平均分" },
        series: [
          {
            name: "平均总分",
            type: "bar",
            barWidth: "60%",
            data: classAverageData.map((item) => item.averageScore),
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: "#83bff6" },
                { offset: 0.5, color: "#188df0" },
                { offset: 1, color: "#188df0" },
              ]),
            },
            emphasis: {
              itemStyle: {
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  { offset: 0, color: "#2378f7" },
                  { offset: 0.7, color: "#2378f7" },
                  { offset: 1, color: "#83bff6" },
                ]),
              },
            },
            label: { show: true, position: "top" },
          },
        ],
      }
      barChart.setOption(barChartOption)
    </script>
  </body>
</html>

通过这个柱状图,我们可以一目了然地看出哪个班级的平均成绩最高,哪个最低。

场景二:单科成绩分布情况(饼图 & 玫瑰图)

分析目标:以高三(1)班为例,分析数学单科成绩的分布情况(如:优秀、良好、及格、不及格)。

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>场景二:单科成绩分布</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
  </head>
  <body>
    <div id="pie-chart" style="width: 100%; height: 500px;"></div>

    <script type="text/javascript">
      // --- 数据准备 (复用上面的 generateMockData) ---
      function generateMockData() {
        /* ... 同上 ... */
        const classes = [
          "高三(1)班",
          "高三(2)班",
          "高三(3)班",
          "高三(4)班",
          "高三(5)班",
          "高三(6)班",
        ]
        const subjects = ["语文", "数学", "英语", "物理", "化学", "生物"]
        const studentsPerClass = 50
        let data = []
        let studentId = 1
        classes.forEach((className) => {
          for (let i = 0; i < studentsPerClass; i++) {
            let student = { 班级: className, 姓名: `学生${studentId}` }
            let totalScore = 0
            subjects.forEach((subject) => {
              const score = Math.floor(Math.random() * 101) + 50
              student[subject] = score
              totalScore += score
            })
            student["总分"] = totalScore
            data.push(student)
            studentId++
          }
        })
        return data
      }
      const examData = generateMockData()

      function analyzeSubjectDistribution(data, className, subject) {
        const classData = data.filter(
          (student) => student["班级"] === className
        )
        const distribution = {
          "优秀 (120+)": 0,
          "良好 (100-119)": 0,
          "及格 (90-99)": 0,
          "不及格 (<90)": 0,
        }
        classData.forEach((student) => {
          const score = student[subject]
          if (score >= 120) distribution["优秀 (120+)"]++
          else if (score >= 100) distribution["良好 (100-119)"]++
          else if (score >= 90) distribution["及格 (90-99)"]++
          else distribution["不及格 (<90)"]++
        })
        return Object.keys(distribution).map((level) => ({
          name: level,
          value: distribution[level],
        }))
      }

      const mathDistributionData = analyzeSubjectDistribution(
        examData,
        "高三(1)班",
        "数学"
      )

      // --- ECharts 配置 ---
      var pieChart = echarts.init(document.getElementById("pie-chart"))
      var pieChartOption = {
        title: {
          text: "高三(1)班数学成绩分布",
          subtext: "期末考试",
          left: "center",
        },
        tooltip: { trigger: "item", formatter: "{a} <br/>{b} : {c}人 ({d}%)" },
        legend: {
          orient: "vertical",
          left: "left",
          data: mathDistributionData.map((item) => item.name),
        },
        series: [
          {
            name: "成绩分布",
            type: "pie",
            radius: "50%",
            center: ["50%", "60%"],
            data: mathDistributionData,
            // 可选:将 type: 'pie' 改为南丁格尔玫瑰图,视觉效果更强
            // roseType: 'area',
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: "rgba(0, 0, 0, 0.5)",
              },
            },
          },
        ],
      }
      pieChart.setOption(pieChartOption)
    </script>
  </body>
</html>

饼图清晰地展示了各个分数段的人数占比。如果将 series.roseType 设置为 'area',它会变成一个南丁格尔玫瑰图,扇区的半径会根据数据大小进行调整,视觉冲击力更强。

场景三:理科综合成绩关联性分析(散点图)

分析目标:探究学生的物理成绩和化学成绩之间是否存在关联性。比如,是不是物理好的学生,化学也普遍不错?

::: details 完整代码

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>场景三:理科综合成绩关联性分析</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
  </head>
  <body>
    <div id="scatter-chart" style="width: 100%; height: 500px;"></div>

    <script type="text/javascript">
      // --- 数据准备 (复用上面的 generateMockData) ---
      function generateMockData() {
        /* ... 同上 ... */
        const classes = [
          "高三(1)班",
          "高三(2)班",
          "高三(3)班",
          "高三(4)班",
          "高三(5)班",
          "高三(6)班",
        ]
        const subjects = ["语文", "数学", "英语", "物理", "化学", "生物"]
        const studentsPerClass = 50
        let data = []
        let studentId = 1
        classes.forEach((className) => {
          for (let i = 0; i < studentsPerClass; i++) {
            let student = { 班级: className, 姓名: `学生${studentId}` }
            let totalScore = 0
            subjects.forEach((subject) => {
              const score = Math.floor(Math.random() * 101) + 50
              student[subject] = score
              totalScore += score
            })
            student["总分"] = totalScore
            data.push(student)
            studentId++
          }
        })
        return data
      }
      const examData = generateMockData()

      function getSubjectCorrelationData(data, subjectX, subjectY) {
        // 返回格式: [物理成绩, 化学成绩, 学生姓名, 班级]
        return data.map((student) => [
          student[subjectX],
          student[subjectY],
          student["姓名"],
          student["班级"],
        ])
      }
      const correlationData = getSubjectCorrelationData(
        examData,
        "物理",
        "化学"
      )

      // --- ECharts 配置 ---
      var scatterChart = echarts.init(document.getElementById("scatter-chart"))
      var scatterChartOption = {
        title: { text: "高三年级物理-化学成绩关联性分析", left: "center" },
        grid: { left: "3%", right: "7%", bottom: "3%", containLabel: true },
        xAxis: {
          type: "value",
          name: "物理成绩",
          splitLine: { lineStyle: { type: "dashed" } },
        },
        yAxis: {
          type: "value",
          name: "化学成绩",
          splitLine: { lineStyle: { type: "dashed" } },
        },
        tooltip: {
          trigger: "item",
          formatter: function (params) {
            // params.data 是一个数组 [物理成绩, 化学成绩, 姓名, 班级]
            return `${params.data[3]} - ${params.data[2]}<br/>物理: ${params.data[0]}<br/>化学: ${params.data[1]}`
          },
        },
        series: [
          {
            name: "学生",
            type: "scatter",
            symbolSize: 6,
            data: correlationData,
            itemStyle: { color: "rgba(25, 100, 150, 0.6)" },
          },
        ],
      }
      scatterChart.setOption(scatterChartOption)
    </script>
  </body>
</html>

通过观察散点图的分布趋势,我们可以做出初步判断。如果点主要集中在从左下到右上的对角线区域,则说明物理和化学成绩呈正相关关系。我们还可以轻易地发现那些"偏科"的异常点(比如物理很高但化学很低的学生)。

场景四:尖子生各科能力模型(雷达图)

分析目标:选取总分排名前三的学生,用雷达图对比他们的各科能力,分析他们的学科优势与短板。

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>场景四:尖子生各科能力模型</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
  </head>
  <body>
    <div id="radar-chart" style="width: 100%; height: 500px;"></div>
    <script type="text/javascript">
      // --- 数据准备 (复用上面的 generateMockData) ---
      function generateMockData() {
        /* ... 同上 ... */
        const classes = [
          "高三(1)班",
          "高三(2)班",
          "高三(3)班",
          "高三(4)班",
          "高三(5)班",
          "高三(6)班",
        ]
        const subjects = ["语文", "数学", "英语", "物理", "化学", "生物"]
        const studentsPerClass = 50
        let data = []
        let studentId = 1
        classes.forEach((className) => {
          for (let i = 0; i < studentsPerClass; i++) {
            let student = { 班级: className, 姓名: `学生${studentId}` }
            let totalScore = 0
            subjects.forEach((subject) => {
              const score = Math.floor(Math.random() * 101) + 50
              student[subject] = score
              totalScore += score
            })
            student["总分"] = totalScore
            data.push(student)
            studentId++
          }
        })
        return data
      }
      const examData = generateMockData()

      function getTopStudentsData(data, topN = 3) {
        const sortedData = [...data].sort((a, b) => b["总分"] - a["总分"])
        const topStudents = sortedData.slice(0, topN)
        const subjects = ["语文", "数学", "英语", "物理", "化学", "生物"]
        const indicator = subjects.map((s) => ({ name: s, max: 150 }))
        const seriesData = topStudents.map((student) => ({
          value: subjects.map((s) => student[s]),
          name: `${student["姓名"]} (${student["班级"]})`,
        }))
        return { indicator, seriesData }
      }
      const radarData = getTopStudentsData(examData, 3)

      // --- ECharts 配置 ---
      var radarChart = echarts.init(document.getElementById("radar-chart"))
      var radarChartOption = {
        title: { text: "年级顶尖学生学科能力雷达图", left: "center" },
        tooltip: { trigger: "item" },
        legend: {
          data: radarData.seriesData.map((item) => item.name),
          bottom: 5,
          textStyle: { fontSize: 14 },
        },
        radar: {
          indicator: radarData.indicator,
          center: ["50%", "50%"],
          radius: "65%",
        },
        series: [
          {
            name: "学科能力对比",
            type: "radar",
            data: radarData.seriesData,
            areaStyle: { opacity: 0.2 },
          },
        ],
      }
      radarChart.setOption(radarChartOption)
    </script>
  </body>
</html>

雷达图能够非常直观地展示出每个学生的学科均衡性。面积越大的学生,综合实力越强;在某个坐标轴上特别突出的,说明该学科是其优势学科。

进阶话题与技巧

掌握了以上内容,你已经可以应对 80% 的常见图表需求了。但 ECharts 的世界远不止于此。

事件与行为

ECharts 实例支持监听鼠标事件。你可以通过 myChart.on('click', ...) 来捕捉用户的点击行为,实现图表下钻、联动等复杂交互。

javascript 复制代码
// myChart 变量来自前面的初始化实例
myChart.on("click", function (params) {
  // 打印点击的系列名称、数据、数据索引
  console.log(params.seriesName, params.name, params.dataIndex)
  // 在这里可以触发其他操作,比如弹出一个对话框显示详细信息
  alert("你点击了:" + params.name)
})

响应式布局

当浏览器窗口大小变化时,你可能希望图表也能自适应调整。只需要监听 resize 事件,并调用 ECharts 实例的 resize 方法即可。

javascript 复制代码
// myChart 变量来自前面的初始化实例
window.addEventListener("resize", function () {
  myChart.resize()
})

结合 gridlegend 等组件的百分比布局配置,可以轻松实现完美的响应式图表。

视觉映射 visualMap

visualMap 是一个非常强大的组件,用于将数据的大小映射到视觉元素上,如颜色、大小、透明度等。

例如,在上面的散点图中,我们可以用 visualMap 将学生的总分映射到散点的颜色上,从而在二维关系中引入第三个维度的信息。只需要修改散点图示例的 option 和数据处理函数即可实现。

动画配置

ECharts 内置了流畅的动画效果。你可以在 option 的根级别对动画进行全局配置,也可以在 series 级别进行单独配置,以控制动画的时长、缓动效果等。

javascript 复制代码
{
  // 全局动画配置
  animation: true,
  animationDuration: 1000, // 初始动画时长
  animationEasing: 'cubicOut', // 缓动效果
  // ...
  series: [{
    // 系列动画配置
    animationDelay: function (idx) {
      return idx * 10;
    }
  }]
}

总结

行文至此,我们从 ECharts 的安装、第一个"Hello World"案例开始,系统性地剖析了其核心配置项,如 series, xAxis, yAxis, grid, tooltip, legenddataset。更重要的是,我们通过一个贯穿始终的"高三成绩分析"实战项目,将这些知识点融会贯通,应用到了具体的业务场景中,绘制了柱状图、饼图、散点图和雷达图。

希望你现在回过头再看 ECharts,不再觉得它是一堆望而生畏的配置项,而是把它看作一套强大而灵活的"可视化积木"。每一个配置项都是一块积木,只要我们理解了每块积木的作用,就能按照自己的蓝图,搭建出任何想要的图表大厦。

数据可视化的征途是星辰大海。本文只是一个起点,ECharts 还有更多高级的功能(如图形组件、自定义系列、GL 三维图表等)等待你去探索。

(完)

相关推荐
X01动力装甲2 小时前
@scqilin/phone-ui 手机外观组件库
前端·javascript·ui·智能手机·数据可视化
Dontla3 小时前
Edge浏览器CSDN文章编辑时一按shift就乱了(Edge shift键)欧路翻译问题(按Shift翻译鼠标所在段落)
前端·edge
lggirls3 小时前
私有证书不被edge浏览器认可的问题的解决-Debian13环境下
前端·edge
野木香4 小时前
tdengine笔记
开发语言·前端·javascript
数字冰雹5 小时前
图观端渲染场景服务器
运维·服务器·数据可视化
Cosolar5 小时前
Coze-JS WsChatClient 实时语音对话源码解析
前端
郝学胜-神的一滴5 小时前
享元模式(Flyweight Pattern)
开发语言·前端·c++·设计模式·软件工程·享元模式
zheshiyangyang5 小时前
Sass开发【四】
前端·css·sass
讨厌吃蛋黄酥5 小时前
🔥 面试必考题:手写数组扁平化,5种方法全解析(附代码+图解)
前端·javascript·面试