欢迎光临
我们一直在努力

《ECharts入门》第 8 章 第一个图表:一个 HTML 文件画柱状图

【本章目标】

学完这一章,你能:

  • 写一个 HTML 文件,双击打开就看到柱状图——不需要 Node,不需要 npm,不需要命令行。
  • 说出 echarts.init() 和 chart.setOption() 各自做了什么,知道 option 里必须有哪些字段才能出图。
  • 独立排查「图不显示」的六个常见原因——这是前 10 章里最高频的 bug,这一章把它一次讲完。

  • 在这里插入图片描述

    【原理先行】

    ECharts 画图只需要两步

    ECharts 的工作模式极其简单:

    第一步:找到一块地方(init)
    第二步:告诉它画什么(setOption)

    第一步——echarts.init(dom) 做的是:

    • 在 DOM 里找到那个 dom 元素,读它的 width 和 height。
    • 在它内部插入一个 <canvas>(或 SVG,取决于渲染器配置),大小等于容器尺寸。
    • 返回一个 chart 对象,你以后用这个对象和图表交互。

    第二步——chart.setOption(option) 做的是:

    • 读 option 对象里的 xAxis、yAxis、series 等字段,算出坐标轴、刻度、数据点位置,把图形画进 <canvas>。
    • 如果你再次调用 setOption,ECharts 会合并新旧配置,而不是从头重画——这是 setOption 最容易被误解的行为,第 9 章专门讲。

    最小 option 只有三个字段

    {
    xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed'] },
    yAxis: { type: 'value' },
    series: [{ type: 'bar', data: [120, 200, 150] }]
    }

    这三行就能出一张有柱子、有横纵坐标轴的图。其他的——标题、提示框、图例、颜色——全都可以在这三步跑通之后再加。本章的节奏就是:先跑通这三行,再加别的。

    容器高度:为什么 0 高度等于「图不显示」

    ECharts 读容器尺寸来初始化画布。如果 <div> 没有显式高度,浏览器给它的默认高度是 0(块级元素没有内容时高度归零)。ECharts 拿到 0 高 0 宽,画布就是空白,不报错。

    这就是图不显示的头号原因——不是代码有 bug,是容器没高度。


    【最小可跑】

    建一个 ch08 文件夹,在里面写两个文件:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="UTF-8">
    <title>云顶咖啡季度销售额</title>
    </head>
    <body>
    <h1>云顶咖啡季度销售额</h1>
    <div id="chart" style="width:600px; height:400px;"></div>
    <script src="../../lib/echarts.min.js"></script>
    <script src="app.js"></script>
    </body>
    </html>

    const dom = document.getElementById('chart');
    const chart = echarts.init(dom);

    chart.setOption({
    title: { text: '云顶咖啡季度销售额(万元)' },
    tooltip: { trigger: 'axis' },
    legend: { data: ['季度销售额'] },
    xAxis: {
    type: 'category',
    data: ['第一季度', '第二季度', '第三季度', '第四季度']
    },
    yAxis: { type: 'value' },
    series: [{ name: '季度销售额', type: 'bar', data: [2180, 3226, 3814, 4506], itemStyle: { color: '#6b4f2a' } }]
    });

    window.addEventListener('resize', () => {
    chart.resize();
    });

    保存后双击 index.html——柱状图出来了。

    ../../lib/echarts.min.js 是什么路径?
    这是相对路径:从 ch08/index.html 出发,先退两层(../../)到仓库根,再进 lib/,找到 echarts.min.js。读者拿到的是完整仓库,这个路径永远对。

    CDN 写法(没有本地文件时),把 <script src="../../lib/echarts.min.js"> 换成下面三个地址之一(实测均可用,体积一致):

    https://cdn.jsdelivr.net/npm/echarts@6.1.0/dist/echarts.min.js
    https://unpkg.com/echarts@6.1.0/dist/echarts.min.js
    https://cdn.staticfile.net/echarts/6.1.0/echarts.min.js


    【逐步加料】

    第一步:去掉 title,图还画吗?

    把 option 里 title 那一行注释掉:

    const option = {
    // title: { text: '…' }, ← 注释掉
    xAxis: { type: 'category', data: ['第一季度', '第二季度', '第三季度', '第四季度'] },
    yAxis: { type: 'value' },
    series: [{ type: 'bar', data: [2180, 3226, 3814, 4506] }]
    };

    保存刷新——图照样在,只是左上角没有标题了。title 不是必需的,xAxis + yAxis + series 才是最小可跑三件套。

    第二步:鼠标移到柱子上,加 tooltip

    tooltip 是「鼠标移过去显示数值」的那个浮层。在 option 里加一行:

    tooltip: { trigger: 'axis' }

    trigger: 'axis' 的意思是:鼠标在 X 轴任何位置移动都会触发,不要求精确移到柱子上。对于柱状图、折线图这类有坐标轴的图,'axis' 比 'item' 好用。

    刷新,鼠标在图里左右移——浮层跟着走了。

    第三步:图例(legend),让多个系列可以开关

    以后会有「销售额」和「杯数」两个系列。图例让用户点一下就隐藏/显示某个系列。加这一行:

    legend: { data: ['季度销售额'] },

    但图例要有名字对应才有用——在 series[0] 里给系列起个名:

    series: [{ name: '季度销售额', type: 'bar', data: [2180, 3226, 3814, 4506] }]

    刷新——图上方出现了一个小方块加文字,点一下图例,柱子消失;再点,柱子回来。

    第四步:柱子改颜色

    itemStyle.color 控制单色系颜色。把咖啡深棕色换成品牌色:

    series: [{
    name: '季度销售额',
    type: 'bar',
    data: [2180, 3226, 3814, 4506],
    itemStyle: { color: '#6b4f2a' }
    }]

    '#6b4f2a' 是本书主线「云顶咖啡」的品牌深棕。刷新,柱子变色。

    第五步:浏览器缩放,图不跟着缩怎么办

    把浏览器窗口拉宽——柱子不会跟着变宽,图表大小固定在 600×400。

    为什么? echarts.init(dom) 只在创建时读一次容器尺寸。容器 CSS 写死了 width:600px,不会随窗口变。

    让图跟着窗口缩,需要两件事:

    一,把容器改成百分比宽度(改 index.html 里 <div id="chart" style="…"> 的 width):

    <div id="chart" style="width:100%; height:400px;"></div>

    二,在 app.js 末尾加监听:

    window.addEventListener('resize', () => {
    chart.resize();
    });

    chart.resize() 让 ECharts 重新读容器的当前尺寸,把画布改成那个大小。

    刷新,拖窗口边界——柱子跟着伸缩了。

    第六步:看看 ECharts 内部的完整 option

    打开开发者工具(F12),切到 Console,敲:

    document.getElementById('chart').__echarts_instance__

    按 Enter,会看到一个字符串——这是 ECharts 分配给这个容器的实例 ID。再敲:

    echarts.getInstanceById('<刚才那个字符串>')

    拿到实例后,调 .getOption():

    echarts.getInstanceById('e-0-').getOption()

    展开你看到的内容——比你写的多了一大堆!grid、animation、textStyle 全是 ECharts 填进来的默认值。这就是「setOption 合并机制」:你没写的字段,ECharts 会填上它的默认值,而不是留空。


    【参数速查】

    本章出现的 option 顶层字段:

    字段类型默认值说明
    title object — 图表标题;title.text 是标题文字
    tooltip object — 鼠标浮层;trigger: 'item' | 'axis' | 'none'
    legend object — 图例;data 数组要和 series[i].name 对应
    xAxis object | array — 横轴;type: 'category' 适合离散类目
    yAxis object | array — 纵轴;type: 'value' 自动算刻度
    series array [] 数据系列;type 决定图型('bar'/'line'/…)

    series 里本章用到的字段:

    字段类型默认值说明
    series.type string — 图型:'bar' 柱状图
    series.name string — 系列名,与 legend.data 对应
    series.data array — 数据数组;type:'bar' 时是数值数组
    series.itemStyle object — 图形样式;series.itemStyle.color 是填充色

    【常见坑】

    坑 1:容器高度为 0——图不显示,也没有报错

    现象:双击 HTML 打开,只有一个空白区域,没有图,Console 没有红色报错。

    根因:<div id="chart"> 没有写 height,或 height 设成了百分比但父元素没有固定高度。

    排查:开发者工具 Elements 面板,找到 #chart 节点,看 Computed 面板里的 height 是不是 0px。

    修法:

    <!– 用 px,或确保有高度 –>
    <div id="chart" style="width:600px; height:400px;"></div>


    坑 2:<script> 路径写错,echarts is not defined

    现象:Console 报红色错误 Uncaught ReferenceError: echarts is not defined。

    根因:<script src="../../lib/echarts.min.js"> 里的相对路径不对——比如你从桌面双击打开了 index.html,但 lib/ 不在上两层。

    排查:Network 面板(开发者工具),找到 echarts.min.js 那一行——红色 404 就是路径错了。

    修法:

    • 用本地仓库结构时,确认 lib/echarts.min.js 在 index.html 往上两层目录里。
    • 或者直接用 CDN 地址(见本章【最小可跑】)。

    坑 3:键名拼错了,ECharts 静默忽略

    现象:图出来了,但标题不显示、tooltip 不出来——没有任何报错。

    根因:title 写成了 titel,tooltip 写成了 tootip——ECharts 不认识错误键名,直接跳过,不抛错。注意方向:是「正确的键名被你写成了别的拼法」,不是「写错了键名会消失」——实测拼错的 titel 会原样留在 getOption() 的返回里(顶层键从 31 个变成 32 个),图上却什么都没有。

    排查:先在 Console 敲 chart.getOption() 展开看,但你只能靠「图上少了什么」定位,不能靠「键在不在返回里」——不认识的键一样会在里面。逐层核对键名与它挂的位置之后,再拿一份能跑的示例对一遍。要把它变成硬错误,得靠第 39 章用 TypeScript 在编译期抓住。


    坑 4:<script src="app.js"> 写在 <div id="chart"> 之前

    现象:Console 报错 Cannot read properties of null (reading 'xxx')。

    根因:浏览器从上往下解析,先执行 app.js,那时 <div id="chart"> 还没被创建,document.getElementById('chart') 返回 null,echarts.init(null) 报错。

    修法:把 <script src="app.js"> 移到 </body> 前——本章【最小可跑】就是这么写的。


    坑 5:在 file:// 协议下用 fetch 加载本地 JSON,报 CORS 错误

    现象:第 6 章开始从 data/*.json 取数据,双击打开报 Failed to fetch 或 CORS 错误。

    本章不受影响——数据写在 option 里,不需要 fetch。

    修法(从第 6 章开始):起一个本地 HTTP 服务:

    node tools/serve.mjs
    # 打开 http://127.0.0.1:18000/code/ch08/index.html


    坑 6:同一个 DOM 元素 init 了两次

    现象:Console 出现黄色警告 [ECharts] There is a chart instance already initialized on the dom.,然后后面的代码行为怪异。

    根因:每次触发某个事件(点击按钮之类)都重新 echarts.init(dom)——旧实例没销毁,又初始化了一个新的。

    修法:

    // 先检查是否已有实例
    let chart = echarts.getInstanceByDom(dom);
    if (!chart) {
    chart = echarts.init(dom);
    }
    chart.setOption(newOption); // 用 setOption 更新,不要重新 init


    【工程文件】

    ch08/
    ├── index.html ← 完整 HTML,双击即可运行(需 lib/ 在同仓库)
    └── app.js ← echarts.init + setOption,约 15 行

    两个文件加起来不到 30 行代码,就是你用 ECharts 画的第一张图。


    【练习】

    练习 1:把柱子换成折线

    app.js 里把 series[0].type 从 'bar' 改成 'line',刷新——柱子变成折线,数据没动。

    这验证了一件事:ECharts 里「图型」是 series.type 一个字段的事,数据格式不变。折线图需要「相同类目有相同 X 坐标的数据点」,你刚才的四个季度正好符合。


    练习 2:加第二个系列——杯数

    把 option 改成这样(注意 series 数组有两个对象了):

    const option = {
    title: { text: '云顶咖啡:季度销售额与杯数' },
    tooltip: { trigger: 'axis' },
    legend: { data: ['销售额(万元)', '杯数(万杯)'] },
    xAxis: { type: 'category', data: ['Q1', 'Q2', 'Q3', 'Q4'] },
    yAxis: { type: 'value' },
    series: [
    { name: '销售额(万元)', type: 'bar', data: [2180, 3226, 3814, 4506] },
    { name: '杯数(万杯)', type: 'line', data: [480, 702, 832, 985], itemStyle: { color: '#c8a27a' } }
    ]
    };

    刷新——一张图里同时有柱子和折线,图例出现两个可点击项。这就是 ECharts 多图型叠在同一个坐标系的方式。


    练习 3:用 getOption() 找出你没写但 ECharts 填了的默认值

    在浏览器 Console 里运行:

    const o = echarts.getInstanceByDom(document.getElementById('chart')).getOption();
    console.log(o.animationDuration); // 你没写过这个字段,它从哪来的?
    console.log(o.textStyle.fontSize); // 字体大小默认是多少?
    console.log(o.grid); // grid 对象你一行没写,长什么样?

    把输出的值抄下来——第 9 章会专门讲「配置优先级」,知道默认值是什么是理解覆盖机制的前提。


    【小结】

    本章把前七章学的所有东西(HTML 容器、JS 变量、函数调用)串成了一个完整的流程:

    建文件 → 写容器(有高度!)→ 引入 echarts.min.js → init → setOption → 看图

    下一章会深入 option 的结构——为什么 xAxis 可以是 {} 也可以是 [{}],setOption 的合并和替换有什么区别,getOption() 拿回来的对象为什么比你写的多了几十行。那些知识会让你以后调试图表问题时能直接看出「哪一层出了问题」。


    赞(0)
    未经允许不得转载:171主机测评 » 《ECharts入门》第 8 章 第一个图表:一个 HTML 文件画柱状图
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址