十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

D3.js 中 d3.stratify 详解:把 CSV 表格与路径字符串转化为分层数据的实战指南

D3.js 中 d3.stratify 详解:把 CSV 表格与路径字符串转化为分层数据的实战指南 D3.js 中 d3.stratify 详解把 CSV 表格与路径字符串转化为分层数据的实战指南【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3本文基于 D3.js 官方文档 Stratify 章节 展开讲解d3.stratify如何将扁平的表格数据如 CSV 解析出的记录数组或 Unix 风格的分隔路径重建为可供树形、矩形树图等布局算法消费的层次结构hierarchy。读完本文你将掌握stratify、stratify(data)、stratify.id、stratify.parentId、stratify.path五个 API 的默认行为、参数约定与约束条件并能独立完成「CSV → 层级节点」这一 D3 层次数据可视化的标准预处理流程。为什么需要 stratify表格数据与层级数据之间的桥梁D3 的层次布局如 tidy 树、dendrogram、treemap、circle-packing都要求输入是一棵以根节点为起点的树。官方在 d3-hierarchy 模块说明 中把这一模块定位为「组织层次数据并可视化」而 Hierarchies 章节 开篇就点明了两条数据入口数据本身已经是嵌套结构如 JSON可以直接交给d3.hierarchy(data)数据是扁平的表格形式如 CSV则需要先用 stratify 把表格「重排」为层次结构。现实中的组织关系、文件清单、分类目录绝大多数以扁平表格形式存储——每行一条记录用「自身 id 父级 id」两列描述从属关系。d3.stratify正是把这类「父子邻接表」parent pointer table转换为树的操作算子。从关系表格到 CSV完整的输入示例官方文档以一张人物关系表作为贯穿始终的示例NameParentEveCainEveSethEveEnosSethNoamSethAbelEveAwanEveEnochAwanAzuraEve由于这些名字互不重复这份关系表可以无歧义地表示为一个 CSV 文件name,parent Eve, Cain,Eve Seth,Eve Enos,Seth Noam,Seth Abel,Eve Awan,Eve Enoch,Awan Azura,Eve用 csvParse 解析该文本const table d3.csvParse(text);它返回一个由{name, parent}对象组成的数组注意CSV 解析出的所有值默认都是字符串[ {name: Eve, parent: }, {name: Cain, parent: Eve}, {name: Seth, parent: Eve}, {name: Enos, parent: Seth}, {name: Noam, parent: Seth}, {name: Abel, parent: Eve}, {name: Awan, parent: Eve}, {name: Enoch, parent: Awan}, {name: Azura, parent: Eve} ]注意根节点 Eve 的parent是空字符串——这一点与后面stratify的约定直接相关。核心用法stratify(data) 构建层次结构拿到表格数据后调用 stratify 算子即可生成层次结构const root d3.stratify() .id((d) d.name) .parentId((d) d.parent) (table);返回的root就是一个标准的 hierarchy 根节点可以立即传给任意的层次布局算子例如 tree、treemap、pack 进行可视化。这里有一个值得留意的细节CSV 中 Eve 的parent是空字符串而stratify.parentId的约定是「空字符串与 null 等价于 undefined」因此空字符串恰好被识别为「无父节点」即根节点。表格中根行 parent 列留空的写法与 stratify 的语义天然吻合。API 详解五个方法及其默认值stratify 算子的完整 API 共五个方法全部实现在 d3-hierarchy 模块的src/stratify.js在本仓库中通过 package.json 以d3-hierarchy: ^3.1.2依赖引入并由 src/index.js 的export * from d3-hierarchy统一导出为全局d3.stratify。stratify()构造一个使用默认设置的 stratify 算子const stratify d3.stratify();它本身只是一个可配置的工厂真正执行转换要等到把数据传入算子。stratify(data)从给定的表格data生成一棵新的层次结构const root stratify(data);这是唯一「执行型」方法返回 hierarchy 根节点其内部会按id/parentId或path访问器建立节点间的父子指针。stratify.id(id)若传入id将 id 访问器设置为给定函数并返回该算子支持链式调用否则返回当前 id 访问器。默认访问器为function id(d) { return d.id; }id 访问器会对传入 stratify 算子的每条记录调用一次参数依次为当前数据项 (d) 和当前索引 (i)。返回值字符串用于结合 parent id 识别节点之间的从属关系。约束条件如下叶子节点的 id 可以为 undefined非叶子节点的 id必须唯一null 和空字符串等价于 undefined。默认访问器读的是记录的d.id字段如果数据里用别的字段名如示例中的name就必须像上文那样显式调用.id((d) d.name)覆盖。stratify.parentId(parentId)若传入parentId将父节点 id 访问器设置为给定函数并返回该算子否则返回当前访问器。默认访问器为function parentId(d) { return d.parentId; }parent id 访问器同样对每条记录调用参数为 (d,i)。返回值与 id 访问器配合确定节点的父子关系。关键约束根节点的 parent id 应为 undefined空字符串/null 等价于 undefined输入数据中必须恰好存在一个根节点不允许出现循环引用。这三条约束是排查 stratify 报错如找不到根、出现孤儿节点时的第一检查点常见原因是数据里混入了第二行 parent 为空的记录或 parent 指向了不存在于表中的 id。stratify.path(path)若传入path将路径访问器设置为给定函数并返回该算子否则返回当前路径访问器默认值为 undefined。一旦设置了 path 访问器id 与 parentId 访问器即被忽略stratify 改为基于路径访问器返回的斜杠/分隔字符串计算类 Unix 文件系统式的层次结构并在必要时自动补全中间层父节点和父节点 id——这是 path 模式与 id/parentId 模式最重要的行为差异表格里不需要显式列出每一层目录。path 模式实战把 find 命令输出变成目录树官方文档给出了一个非常典型的场景对当前目录执行 UNIXfind命令得到一组相对路径const paths [ axes.js, channel.js, context.js, legends.js, legends/ramp.js, marks/density.js, marks/dot.js, marks/frame.js, scales/diverging.js, scales/index.js, scales/ordinal.js, stats.js, style.js, transforms/basic.js, transforms/bin.js, transforms/centroid.js, warnings.js, ];一行即可构建目录层次const root d3.stratify().path((d) d)(paths);这里(d) d表示数据项本身就是字符串直接作为路径使用。stratify 会把marks/dot.js拆分为marks→marks/dot.js两级并自动推断出中间节点marks的 id 和父节点根。这种用法在本仓库的文档站点中就有真实应用。what-is-d3 页面 的源码脚本里先用侧边栏配置递归生成一组{path, link}路径数据随后计算树图宽度时直接组合了 stratify 的 path 模式与 tree 布局const root d3.tree().nodeSize([1, 1])(d3.stratify().path((d) d.path)(paths));这恰好演示了「路径数组 → stratify.path → 层次布局」的完整链路访问器改为(d) d.path从记录对象中取出路径字段即可。组合使用从 CSV 到可视化的完整管线把前面各节串起来一个典型的表格数据树状图管线为// 1. 解析 CSV 文本为记录数组 const table d3.csvParse(text); // 2. 用 id / parentId 访问器把表格转成层次结构 const root d3.stratify() .id((d) d.name) .parentId((d) d.parent) (table); // 3. 交给层次布局算子例如 tidy 树 d3.tree()(root);得到root之后就可以使用 Hierarchies 文档 中介绍的全部节点方法root.descendants()、root.links()、root.sum(...)、root.eachBefore(...)等驱动 SVG/Canvas 的绘制。小结与检查清单d3.stratify()是「扁平表格 → 树」的转换算子stratify(data)执行转换.id()/.parentId()配置两列 id.path()切换到按斜杠路径自动推断层级的模式id 默认读d.idparentId 默认读d.parentId字段名不同时必须显式指定访问器空字符串与 null 等价于 undefined因此 CSV 中根节点 parent 列留空即可输入必须恰好有一个根节点、非叶子节点 id 唯一、无循环引用设置了 path 访问器后id 与 parentId 访问器失效中间层节点会被自动补全输出是标准 hierarchy 根节点可直接接入 tree、cluster、treemap、partition、pack 等全部 d3-hierarchy 布局算法见 d3-hierarchy 模块总览 与 API 索引 中 d3.stratify 相关条目。【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表