App Inventor 2 数据可视化教程 - 折线图/曲线图/实时数据绘图

« 返回首页

一、概述

数据可视化是 App 开发中的常见需求——温度监测、运动轨迹、成绩走势、股票行情……都需要将数据以图表形式呈现。App Inventor 2 从 nb186 版本(2020 年)开始内置了 Chart(图表)组件,支持折线图、面积图、散点图、条形图和饼图五种类型,无需任何拓展即可使用。

本文聚焦折线图/曲线图场景,从零开始讲解 Chart 组件的核心概念、基础用法、实时数据绘图、多数据系列、样式自定义、数据导入导出等内容。

前置知识: 了解 App Inventor 2 的基本操作(拖拽组件、拼接积木块)。如需回顾,请参阅 连接调试指南


二、Chart 组件体系总览

App Inventor 2 的图表功能由以下三个核心组件协作完成:

组件 位置 作用
Chart(图表) 界面组件 → 图表 图表容器,决定图表类型、背景、网格等外观
ChartData2D(二维图表数据) 界面组件 → 图表 表示一条数据系列(如一条折线),管理数据点的增删改查
Trendline(趋势线) 界面组件 → 图表 基于数据系列自动计算并绘制最佳拟合线

关键理解: Chart 是”画布”,ChartData2D 是”画笔+颜料”。一个 Chart 可以挂载多个 ChartData2D(即多条折线),每个 ChartData2D 独立管理自己的数据和样式。

支持的图表类型

Chart 组件通过 类型 属性切换以下五种图表:

  1. 折线图(Line) —— 数据点用直线段连接(本文重点)
  2. 面积图(Area) —— 折线下方填充颜色
  3. 散点图(Scatter) —— 只显示数据点,不连线
  4. 条形图(Bar) —— 柱状图
  5. 饼图(Pie) —— 饼图

三、快速上手:第一个折线图

3.1 界面设计

  1. 打开 App Inventor 2 设计视图
  2. 从左侧组件面板 图表 分类中,将 Chart 组件拖入 Screen
  3. ChartData2D 组件拖入 Chart 组件内部(注意:必须拖到 Chart 上,不是 Screen 上)
  4. 设置 Chart 组件的属性:
    • 类型折线图
    • 描述我的第一个折线图(作为图表标题)
    • 启用网格勾选
  5. 设置 ChartData2D 的属性:
    • 颜色 → 选一个你喜欢的颜色(如蓝色)
    • 标签数据系列1

3.2 积木块:添加静态数据

使用 ChartData2D 的 添加数据点 方法,传入 x 和 y 值:

当 Screen1.初始化 时 执行:
  调用 ChartData2D1.添加数据点(x: "1", y: "3")
  调用 ChartData2D1.添加数据点(x: "2", y: "7")
  调用 ChartData2D1.添加数据点(x: "3", y: "4")
  调用 ChartData2D1.添加数据点(x: "4", y: "9")
  调用 ChartData2D1.添加数据点(x: "5", y: "6")

运行后,你将看到一条由 5 个数据点组成的折线图。

3.3 用 CSV 方式一次性导入数据

除了逐点添加,ChartData2D 还提供了 元素来自键值对 属性,可以直接在设计视图输入 CSV 格式的数据:

x1,y1,x2,y2,x3,y3

例如:

1,23,2,28,3,35,4,30,5,42,6,38

这会一次性添加 6 个数据点:(1,23), (2,28), (3,35), (4,30), (5,42), (6,38)。


四、实时数据绘图(动态折线图)

实时数据绘图是最常见的应用场景之一——传感器数据、实时监测、动态更新等。

4.1 使用计时器定时添加数据

核心思路:用 Clock(计时器) 组件定时触发,每次触发时向 ChartData2D 添加一个新的数据点。

界面设计:

  • 添加一个 Clock 组件,设置 计时间隔 为 1000(毫秒,即 1 秒)
  • 添加一个按钮用于开始/停止
  • Chart + ChartData2D(类型设为折线图)

积木块:

// 全局变量
全局 x计数 ← 0

当 按钮_开始.被点击 时 执行:
  设置 Clock1.启用计时 为 true
  调用 ChartData2D1.清除数据序列()

当 Clock1.计时器事件 时 执行:
  x计数 ← x计数 + 1
  随机值 ← 取随机整数(从 1 到 100)
  调用 ChartData2D1.添加数据点(x: x计数, y: 随机值)

4.2 保持图表窗口滚动(只显示最近 N 个点)

如果数据持续增长,图表会越来越拥挤。常见做法是只保留最近的 N 个数据点:

当 Clock1.计时器事件 时 执行:
  x计数 ← x计数 + 1
  随机值 ← 取随机整数(从 1 到 100)
  调用 ChartData2D1.添加数据点(x: x计数, y: 随机值)

  所有数据 ← 调用 ChartData2D1.获取所有数据点()
  如果 长度(列表:所有数据) > 20 那么:
    第一个点 ← 列表中的第1项(所有数据)
    x旧 ← 列表中的第1项(第一个点)
    y旧 ← 列表中的第2项(第一个点)
    调用 ChartData2D1.删除数据点(x: x旧, y: y旧)

说明: 获取所有数据点 返回的列表中,每个元素是一个子列表 [x, y]

4.3 接入传感器数据实时绘图

Chart 组件支持直接绑定传感器作为数据源。以加速度传感器为例:

  1. 添加 AccelerometerSensor 组件
  2. 设置 ChartData2D 的属性:
    • 数据源 → 选择 AccelerometerSensor1
    • 数据源键标识符X(表示 X 轴加速度)

这样传感器每次产生新数据时,图表会自动更新。

支持的传感器数据源: 加速度传感器(X/Y/Z)、陀螺仪传感器(X/Y/Z)、位置传感器(纬度/经度/高度/速度)、方向传感器(俯仰角/方位角/横滚角)、计步器(行走步数/简单步数/距离)、距离传感器(距离)。


五、多数据系列(多条折线)

一个 Chart 容器可以挂载多个 ChartData2D 组件,实现多条折线同时显示。

5.1 界面设计

  1. 一个 Chart 组件(类型:折线图)
  2. 拖入两个(或更多) ChartData2D 到 Chart 内部
  3. 分别设置不同颜色和标签:
    • ChartData2D1:颜色=蓝色,标签=最高温度
    • ChartData2D2:颜色=红色,标签=最低温度

5.2 积木块

当 Screen1.初始化 时 执行:
  // 最高温度数据
  调用 ChartData2D1.添加数据点(x: "1月", y: "5")
  调用 ChartData2D1.添加数据点(x: "2月", y: "8")
  调用 ChartData2D1.添加数据点(x: "3月", y: "14")
  调用 ChartData2D1.添加数据点(x: "4月", y: "22")
  调用 ChartData2D1.添加数据点(x: "5月", y: "28")

  // 最低温度数据
  调用 ChartData2D2.添加数据点(x: "1月", y: "-3")
  调用 ChartData2D2.添加数据点(x: "2月", y: "-1")
  调用 ChartData2D2.添加数据点(x: "3月", y: "4")
  调用 ChartData2D2.添加数据点(x: "4月", y: "10")
  调用 ChartData2D2.添加数据点(x: "5月", y: "16")

Chart 会自动显示图例,区分两条折线。


六、曲线图(平滑折线)

ChartData2D 提供了 线型 属性,可以将折线图从直线变为平滑曲线:

  • 折线(默认)—— 数据点之间用直线连接
  • 曲线 —— 数据点之间用贝塞尔曲线平滑连接
  • 阶梯 —— 数据点之间用阶梯线连接

设计视图 中设置 ChartData2D 的 线型 属性为 曲线,或在积木块中动态设置。


七、样式自定义

7.1 Chart 容器属性

属性 说明
背景颜色 图表背景色(RGBA)
描述 图表标题文字
启用网格 是否显示网格线(适用于折线图、面积图、散点图、条形图)
启用图例 是否显示图例(多数据系列时有用)
标签列表 自定义 X 轴标签,如 ["周一","周二","周三","周四","周五"]
CSV字符串标签 以逗号分隔的字符串设置 X 轴标签,如 "周一,周二,周三,周四,周五"
类型 切换图表类型
宽度/高度 尺寸设置

7.2 ChartData2D 数据系列属性

属性 说明
颜色 数据系列颜色
颜色列表 多色交替显示
标签 数据系列名称(图例文字)
线型 折线/曲线/阶梯(适用于折线图和面积图)
点型 圆形/方形/三角/十字/叉号(适用于散点图)
元素来自键值对 CSV 格式静态数据

7.3 自定义 X 轴标签示例

使用 标签列表 属性可以让 X 轴显示有意义的文字标签:

当 Screen1.初始化 时 执行:
  设置 Chart1.标签列表 为 ["1月","2月","3月","4月","5月","6月"]
  调用 ChartData2D1.从列表导入(list: [ [1,120],[2,200],[3,150],[4,280],[5,230],[6,310] ])

八、数据导入

除了逐点添加,ChartData2D 还支持从多种数据源批量导入数据。

8.1 从列表导入

调用 ChartData2D1.从列表导入(list: [[1,30],[2,45],[3,28],[4,60],[5,52]])

列表格式为 [[x1,y1],[x2,y2],...]注意:此方法不会清除已有数据。

8.2 从微数据库导入

调用 ChartData2D1.从微数据库导入(tinyDB: TinyDB1, 标签: "temperature_data")

TinyDB 中存储的数据应该是列表格式:[[x1,y1],[x2,y2],...]

8.3 从云数据库导入

调用 ChartData2D1.从云数据库导入(云数据库: CloudDB1, 标签: "sensor_data")

8.4 从数据文件导入(CSV/JSON)

调用 ChartData2D1.从数据文件导入(数据文件: DataFile1, x值列: "time", y值列: "temperature")

数据文件示例(CSV 格式):

time,temperature
08:00,22.5
09:00,23.1
10:00,25.0
11:00,26.3
12:00,28.1

8.5 从 Web 客户端导入

// 先发起网络请求
调用 Web1.获取(url: "https://api.example.com/data.json")

// 在 Web1.收到内容 事件中
当 Web1.收到内容(响应代码: code, 响应内容: content) 时 执行:
  调用 ChartData2D1.从Web客户端导入(web: Web1, xValueColumn: "time", yValueColumn: "value")

8.6 从电子表格导入

// 先读取电子表格数据
调用 Spreadsheet1.读取工作表()

// 然后导入到图表
调用 ChartData2D1.从电子表格导入(sheet: Spreadsheet1, xColumn: "A", yColumn: "B", useHeaders: true)

九、趋势线(最佳拟合线)

Chart 组件内置了 Trendline 子组件,可以自动计算并绘制趋势线,支持以下模型:

模型 公式 适用场景
线性 y = m*x + b 线性增长趋势
二次 y = ax² + bx + c 先升后降/先降后升
对数 y = a + b*ln(x) 递增趋缓
指数 y = a*b^x 加速增长/衰减

使用方法:

  1. Trendline 组件拖入 Chart 内部
  2. 设置 图表数据 属性 → 选择要关联的 ChartData2D
  3. 设置 模型 → 如 线性
  4. 设置 颜色线条宽度

Trendline 还提供了以下只读属性供程序使用:

  • 拟合系数(RSquared) —— 拟合优度(越接近 1 越好)
  • 线性系数 / 二次系数 / 对数系数 / 指数系数
  • Y轴交点
  • 预测 —— 基于模型进行预测

注意: Trendline 组件要求 AI 伴侣 v2.70 及以上版本。


十、数据交互与查询

10.1 数据点点击事件

Chart 和 ChartData2D 都提供了数据点点击事件:

当 ChartData2D1.数据点被点击(x坐标: x, y坐标: y) 时 执行:
  调用 Label1.设置文本(文本: "点击了数据点:x=" + x + ", y=" + y)

10.2 查询数据

// 检查某个数据点是否存在
存在 ← 调用 ChartData2D1.数据点是否存在(x: "3", y: "45")

// 获取所有数据
所有数据 ← 调用 ChartData2D1.获取所有数据点()

// 按 X 值查找
匹配数据 ← 调用 ChartData2D1.获取X值数据点(x: "3")

// 按 Y 值查找
匹配数据 ← 调用 ChartData2D1.获取Y值数据点(y: "45")

10.3 清除与删除

// 删除单个数据点
调用 ChartData2D1.删除数据点(x: "3", y: "45")

// 清除所有数据
调用 ChartData2D1.清除数据序列()

十一、完整实战案例:温度监测应用

下面通过一个完整的温度监测案例,串联前面所学知识。

11.1 功能需求

  • 模拟每秒采集一次温度数据(25°C ± 随机波动)
  • 折线图实时显示最近 30 个数据点
  • 显示当前温度值和最高/最低温度
  • 支持暂停/继续

11.2 界面设计

Screen1 (标题: 温度监测)
├── 水平布局1
│   ├── Label_当前温度 (文本: "--°C")
│   ├── Label_最高温度 (文本: "最高: --°C")
│   └── Label_最低温度 (文本: "最低: --°C")
├── Chart1 (类型: 折线图, 描述: 实时温度, 启用网格: ✓, 宽度: 充满, 高度: 300px)
│   └── ChartData2D1 (颜色: 蓝色, 标签: 温度, 线型: 曲线)
├── 水平布局2
│   ├── Button_开始 (文本: "开始监测")
│   └── Button_停止 (文本: "停止监测")
└── Clock1 (计时间隔: 1000, 启用计时: false)

11.3 积木块

// ========== 全局变量 ==========
全局 x计数 ← 0
全局 最高温度 ← 0
全局 最低温度 ← 100

// ========== 开始监测 ==========
当 Button_开始.被点击 时 执行:
  设置 Clock1.启用计时 为 true
  设置 x计数 为 0
  设置 最高温度 为 0
  设置 最低温度 为 100
  调用 ChartData2D1.清除数据序列()

// ========== 停止监测 ==========
当 Button_停止.被点击 时 执行:
  设置 Clock1.启用计时 为 false

// ========== 定时采集数据 ==========
当 Clock1.计时器事件 时 执行:
  x计数 ← x计数 + 1
  当前温度 ← 25 + (取随机小数 × 10) - 5   // 20~30°C 之间随机
  当前温度 ← 四舍五入(当前温度, 小数位数: 1)

  // 更新图表
  调用 ChartData2D1.添加数据点(x: x计数, y: 当前温度)

  // 保持窗口大小为30个点
  所有数据 ← 调用 ChartData2D1.获取所有数据点()
  如果 长度(列表:所有数据) > 30 那么:
    旧点 ← 列表中的第1项(所有数据)
    调用 ChartData2D1.删除数据点(x: 列表中的第1项(旧点), y: 列表中的第2项(旧点))

  // 更新统计
  如果 当前温度 > 最高温度 那么:
    最高温度 ← 当前温度
  如果 当前温度 < 最低温度 那么:
    最低温度 ← 当前温度

  // 更新显示
  设置 Label_当前温度.文本 为 (当前温度 + "°C")
  设置 Label_最高温度.文本 为 ("最高: " + 最高温度 + "°C")
  设置 Label_最低温度.文本 为 ("最低: " + 最低温度 + "°C")

十二、进阶:使用 ECharts 拓展实现更丰富的图表

App Inventor 2 内置 Chart 组件满足基础需求。如果需要更强大的图表效果(如 3D 图表、复杂交互、动画效果等),可以使用 ECharts 拓展

详见 ECharts 拓展文档

ECharts 折线图示例

ECharts 拓展的 Line 方法可以绘制平滑曲线折线图:

当 Screen1.初始化 时 执行:
  调用 ECharts1.初始化(layout: 水平布局1)
  调用 ECharts1.画折线图(
    title: "月度销售数据",
    legends: ["线上","线下"],
    labels: ["1月","2月","3月","4月","5月","6月"],
    datas: [[120,200,150,280,230,310],[80,150,120,200,180,250]],
    smooth: true
  )

ECharts 的优势:

  • 支持 7 种主题风格
  • 支持平滑曲线(smooth 参数)
  • 支持图表点击事件回调
  • 支持导出图片
  • 支持 3D 曲面图等高级图表

十三、常见问题与解答

Q1:Chart 组件的最低版本要求?

Chart 组件从 nb186 版本开始内置。Trendline 组件要求 AI 伴侣 v2.70 及以上。建议始终使用最新版本的 AI 伴侣。

Q2:折线图可以显示多少个数据点?

Chart 组件本身没有硬性限制,但从性能角度,建议单个数据系列不超过 1000 个数据点。超过时建议只保留最近的数据。

Q3:如何实现折线图的 X 轴显示时间?

可以用字符串作为 X 值:

调用 ChartData2D1.添加数据点(x: "08:00", y: "22")
调用 ChartData2D1.添加数据点(x: "09:00", y: "23")

Q4:如何保存图表数据?

使用 获取所有数据点 获取数据列表,然后存入 TinyDB:

当 Button_保存.被点击 时 执行:
  所有数据 ← 调用 ChartData2D1.获取所有数据点()
  调用 TinyDB1.保存标签(标签: "chart_data", 值为: 所有数据)

下次启动时用 从列表导入从微数据库导入 恢复。

Q5:折线图和面积图的区别?

面积图是折线图的填充版本——折线下方会填充颜色。两者使用相同的数据结构,只需将 Chart 类型从”折线图”切换为”面积图”即可。

Q6:如何实现动态切换图表类型?

当 Button_切换.被点击 时 执行:
  设置 Chart1.类型 为 "条形图"   // 或其他类型

十四、ChartData2D 方法速查表

方法 参数 说明
添加数据点 x, y 添加一个数据点
删除数据点 x, y 删除指定数据点
清除数据序列 清除所有数据
数据点是否存在 x, y 返回布尔值
获取所有数据点 返回 [[x1,y1],[x2,y2],…]
获取X值数据点 x 返回匹配 x 值的所有数据点
获取Y值数据点 y 返回匹配 y 值的所有数据点
从列表导入 list 从列表批量导入
从微数据库导入 tinyDB, tag 从 TinyDB 导入
从云数据库导入 cloudDB, tag 从 CloudDB 导入
从数据文件导入 dataFile, xCol, yCol 从 CSV/JSON 文件导入
从Web客户端导入 web, xCol, yCol 从 Web 请求结果导入
从电子表格导入 sheet, xCol, yCol, useHeaders 从电子表格导入
改变数据源 source, keyValue 动态切换数据源
删除数据源 移除数据源绑定

十五、总结

App Inventor 2 内置的 Chart 组件已经能覆盖大部分数据可视化需求:

  • 折线图 适合展示趋势变化
  • 曲线图 通过设置线型为”曲线”即可实现平滑效果
  • 实时数据 通过 Clock + 添加数据点 + 滚动窗口实现
  • 多数据系列 通过多个 ChartData2D 组件实现
  • 趋势线 内置支持线性/二次/对数/指数拟合
  • 数据导入 支持 TinyDB、CloudDB、CSV、JSON、Web API、电子表格等
  • ECharts 拓展 提供更高级的图表效果

完整组件属性和方法请参考 图表组件参考文档


MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理

文档反馈