ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Chart.js 数据集数据结构完全解析:从数组、对象到 parsing 配置与源码实现

Chart.js 数据集数据结构完全解析:从数组、对象到 parsing 配置与源码实现 Chart.js 数据集数据结构完全解析从数组、对象到 parsing 配置与源码实现【免费下载链接】Chart.jsSimple HTML5 Charts using thetag项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js本文以 Chart.js 官方文档《Data structures》为核心系统讲解数据集data属性的五种合法形式原始值数组、元组数组、对象数组、自定义键对象数组、单个对象并逐一结合src/下数据集控制器的解析源码说明每种结构在内部是如何被解析、缓存和排序检测的。读完本文你将能够根据图表类型与性能需求正确选择数据格式正确使用parsing配置含嵌套键与转义规则并在 TypeScript 中为自定义数据结构声明正确的ChartData泛型。一、data 属性的默认解析机制数据集的data属性可以传入多种格式。默认情况下data会按照关联的图表类型和**刻度scales**进行解析。从源码结构看这一过程发生在 core.datasetController.js 的parse(start, count)方法中。它会检查第一个数据项的类型来分派到三种解析路径// src/core/core.datasetController.jsparse 方法节选 if (this._parsing false) { meta._parsed data; // 禁用解析直接使用原始数据 meta._sorted true; parsed data; } else { if (isArray(data[start])) { parsed this.parseArrayData(meta, data, start, count); // 元组数组 } else if (isObject(data[start])) { parsed this.parseObjectData(meta, data, start, count); // 对象数组 } else { parsed this.parsePrimitiveData(meta, data, start, count); // 原始值数组 } // 随后逐项写入 meta._parsed并跟踪数据是否有序meta._sorted }解析结果统一存入meta._parsed后续坐标计算、命中检测、tooltip 取值都基于这份解析后的数据。另外meta._sorted会记录数据是否已按索引轴排序——这一点在 getMinMax 中被利用有序时只需从两端取首尾值即可确定范围而不必遍历全部数据。parsing的默认值在 core.defaults.js 中定义为true即默认开启解析。二、labels 与索引轴若主data属性中使用了labels它必须包含与数据最多的数据集相同数量的元素。这些标签用于标注索引轴默认x轴必须提供为数组。标签值应为string或number类型才能被正确渲染如需多行标签可提供数组每个数组项代表一行。三、原始值数组Primitive[]const cfg { type: bar, data: { datasets: [{ data: [20, 10], }], labels: [a, b] } }当data是数字数组时labels数组中同索引处的值会被用作索引轴垂直图表为x水平图表为y。源码印证见 parsePrimitiveData索引轴的值直接来自iScale.parse(labels[index], index)而数值轴的值来自vScale.parse(data[index], index)——这正是同一索引取 labels 对应项的实现细节。四、元组数组Array[]const cfg { type: line, data: { datasets: [{ data: [[10, 20], [15, null], [20, 10]] }] } }当data是数组的数组即 TypeScript 中的元组时每个元组的第一个元素是索引垂直图表为x水平图表为y第二个元素是值默认为y。对应实现见 parseArrayDataitem[0]交由xScale.parse、item[1]交由yScale.parse处理。注意散点、气泡等图表中元组顺序即为(x, y)语义。五、对象数组Object[]const cfg { type: line, data: { datasets: [{ data: [{x: 10, y: 20}, {x: 15, y: null}, {x: 20, y: 10}] }] } }const cfg { type: line, data: { datasets: [{ data: [{x: 2016-12-25, y: 20}, {x: 2016-12-26, y: 10}] }] } }const cfg { type: bar, data: { datasets: [{ data: [{x: Sales, y: 20}, {x: Revenue, y: 10}] }] } }对象数组同时也是内部解析数据的格式。在这种模式下可以通过在图表选项或数据集上指定parsing: false来禁用解析一旦禁用解析数据必须已经排序并且是关联图表类型与刻度内部使用的格式。提供的值必须能被关联刻度解析或者就是刻度的内部格式。例如category刻度的内部格式是整数每个整数代表 labels 数组中的一个索引但如果开启了解析它也可以解析字符串标签。null可用于表示跳过不绘制/不连线的值。实现上parseObjectData 从this._parsing中取出键名默认xAxisKey x、yAxisKey y再逐个数据项调用resolveObjectKey(item, key)取值后交给对应刻度解析。this._parsing在 configure() 中被赋值为解析后的数据集级options.parsing因此parsing支持图表级与数据集级两级配置。六、使用自定义属性的对象数组Object[] using custom properties当你的数据源是带有业务字段的 JSON 记录时可以用parsing指定键名映射const cfg { type: bar, data: { datasets: [{ data: [{id: Sales, nested: {value: 1500}}, {id: Purchases, nested: {value: 500}}] }] }, options: { parsing: { xAxisKey: id, yAxisKey: nested.value } } }对于 pie/doughnut、radar 或 polarArea 图表类型parsing对象应使用key字段指向要读取的值。以下示例中环形图将显示 1500 与 500 两个值const cfg { type: doughnut, data: { datasets: [{ data: [{id: Sales, nested: {value: 1500}}, {id: Purchases, nested: {value: 500}}] }] }, options: { parsing: { key: nested.value } } }半径类刻度radar / polarArea的这条路径由 helpers.config.ts 中的 _parseObjectDataRadialScale 实现const {key r} this._parsing;说明该模式下不写key时默认读取r属性取值后经iScale.parse解析为半径值radar 与 polarArea 控制器分别在 controller.radar.js 和 controller.polarArea.js 中复用了这个函数。键名包含点号时的转义如果键本身包含点号需要用双斜杠反斜杠转义const cfg { type: line, data: { datasets: [{ data: [{data.key: one, data.value: 20}, {data.key: two, data.value: 30}] }] }, options: { parsing: { xAxisKey: data\\.key, yAxisKey: data\\.value } } }这一转义规则由 helpers.core.ts 中的 _splitKey / resolveObjectKey 实现键按.分段若某一段以\结尾则把\去掉并把.拼回该段作为整体键名否则视为一层嵌套访问。解析器结果还会被缓存在keyResolvers中重复使用相同键名时避免重复构建闭包。注意在 radar 图表中使用对象写法时仍然需要提供labels数组图表才能正确显示。七、单对象Objectconst cfg { type: line, data: { datasets: [{ data: { January: 10, February: 20 } }] } }这种模式下属性名用作索引刻度属性值用作数值刻度对垂直图表而言索引刻度是x数值刻度是y。从源码看对象形态的数据在进入解析之前会先被归一化core.datasetController.js 中的convertObjectDataToArray把对象的每个键值对转换为{x: 属性名, y: 属性值}或按坐标轴方向选择x/y键的数组元素随后走标准的对象数组解析路径。该转换在 数据替换分支L374-L376中被调用这也解释了为什么对象数据同样支持parsing的键映射行为。八、Dataset Configuration数据集级配置数据集上还有一组与数据结构、渲染顺序直接相关的配置项名称类型说明labelstring数据集标签显示在图例和 tooltip 中clipnumber|object相对 chartArea 的裁剪方式。正值允许溢出负值表示在 chartArea 内侧裁剪相应像素数0表示在 chartArea 处裁剪也可逐边配置clip: {left: 5, top: false, right: -2, bottom: 0}ordernumber数据集的绘制顺序同时影响堆叠、tooltip 与图例的顺序stackstring数据集所属的分组 ID堆叠时每个分组形成独立的堆栈。默认为数据集的typeparsingboolean|object如何解析数据集。可在图表选项或数据集上指定parsing: false禁用解析禁用后数据必须已排序且是关联图表类型与刻度内部使用的格式hiddenboolean设置数据集可见性hidden: true将使其不参与图表渲染其中parsing是贯穿全文档的核心配置。TypeScript 中的类型定义见 types/index.d.ts 的 ParsingOptionsparsing可以是false也可以是{[key: string]: string}形式的键映射对象xAxisKey/yAxisKey/key均属于该索引签名的合法键。多个数据集复用同一份数据parsing 的典型实战parsing最实用的场景之一是多个数据集共享同一份记录数组各自映射不同的字段const data [{x: Jan, net: 100, cogs: 50, gm: 50}, {x: Feb, net: 120, cogs: 55, gm: 75}]; const cfg { type: bar, data: { labels: [Jan, Feb], datasets: [{ label: Net sales, data: data, parsing: { yAxisKey: net } }, { label: Cost of goods sold, data: data, parsing: { yAxisKey: cogs } }, { label: Gross margin, data: data, parsing: { yAxisKey: gm } }] }, };注意这里只覆盖了yAxisKeyxAxisKey沿用默认的x索引轴因此与labels一致。禁用解析parsing: false与性能如果数据已经按照内部格式排好序设置parsing: false可以让 parse() 直接把原始数组引用赋给meta._parsed并标记_sorted true省去逐项解析与排序检测的开销。使用前提是数据必须已按索引轴排序数据必须是关联图表类型与刻度内部使用的格式如category刻度要求整数索引linear刻度要求数值各数据集的索引必须一致类型定义文档中normalized: true选项的注释即针对这种唯一、已排序、跨数据集一致的规范化数据。解析行为的自动化验证可以参考 core.datasetController.tests.js 与 controller.bar.tests.js 中围绕parsing的用例。九、TypeScript 中的数据泛型在 TypeScript 中如果使用非默认的数据结构需要在声明数据变量时通过ChartData的泛型参数传入该项的类型import {ChartData} from chart.js; const datasets: ChartDatabar, {key: string, value: number}[] { datasets: [{ data: [{key: Sales, value: 20}, {key: Revenue, value: 10}], parsing: { xAxisKey: key, yAxisKey: value } }], };这样data中的每一项都获得完整的类型检查parsing的键映射也能与数据结构保持一致。十、结构选型小结简单数值 分类轴优先用Primitive[]labels写法最简索引轴自动对齐 labelsx 轴不是等距分类散点、时间、log用Object[]{x, y}或元组[[x, y], ...]把索引显式交给刻度解析业务 JSON 记录用parsing: {xAxisKey, yAxisKey}半径类图表用key映射字段支持a.b形式的嵌套键与\.转义已知数据已排序且格式规范设parsing: false换取解析开销的节省但须自行承担排序与内部格式的责任横向记录键为月份/类别直接传单个对象属性名自动成为索引轴值。所有行为的实现入口集中在 core.datasetController.js 的parse/parsePrimitiveData/parseArrayData/parseObjectData方法族键名解析工具在 helpers.core.ts半径刻度对象解析在 helpers.config.ts。官方文档源文件为 docs/general/data-structures.md可作为本文与仓库实现的对照基准。【免费下载链接】Chart.jsSimple HTML5 Charts using thetag项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表