在 React/Vue 项目中集成 d3-delaunay:工程化实践与 API 速查手册
在 React/Vue 项目中集成 d3-delaunay:工程化实践与 API 速查手册
【免费下载链接】d3-delaunayCompute the Voronoi diagram of a set of two-dimensional points.项目地址: https://gitcode.com/gh_mirrors/d3/d3-delaunay
d3-delaunay是一个基于 Delaunator 的高性能 JavaScript 库,专门用于计算二维点集的Voronoi 图(泰森多边形)与Delaunay 三角剖分。在 React/Vue 前端项目中,它常被用于热力图、最近邻查询、地图分块与数据可视化。本手册将带你从安装配置到工程化封装,并附上一份可直接查阅的d3-delaunay API 速查表,帮助新手快速上手。
d3-delaunay 是什么?为什么前端要用它?
Voronoi 图把平面划分成若干区域,每个区域内的任意点到该区域中心点的距离最近;而 Delaunay 三角剖分则是它的对偶结构,两者可互相转换。d3-delaunay 通过 sweep 算法一次性完成剖分,性能极强,几万个点也能在毫秒级完成计算,非常适合需要实时渲染的 Web 场景。
典型应用包括:
- 🗺️ 地理/地图数据的热区划分、距离最近的服务点计算
- 📊 大规模散点图的聚合与密度可视化
- 🎨 艺术化图片处理(把图片分解成彩色多边形单元)
- 🎮 游戏中的单位势力范围(战争迷雾、领土划分)
快速开始:npm 安装 d3-delaunay 与项目初始化
d3-delaunay 是纯 ESM 模块("type": "module"),可在任意现代前端构建工具(Vite / Webpack)中直接使用。在项目根目录执行安装命令即可:
npm install d3-delaunay安装后,在源码中导入两个核心类:
import { Delaunay, Voronoi } from "d3-delaunay";入口导出定义在 index.js,两个类的实现分别在 delaunay.js 与 voronoi.js。唯一运行时依赖是delaunator,体积很小,无需额外配置。
在 Vue 3 中集成 d3-delaunay 的完整步骤
Vue 3 的组合式 API 与 d3-delaunay 的纯函数风格非常契合。下面是生成并渲染 Voronoi 图的最简实现:
<template> <canvas ref="canvas" width="800" height="600"></canvas> </template> <script setup> import { ref, onMounted } from "vue"; import { Delaunay } from "d3-delaunay"; const canvas = ref(null); onMounted(() => { const points = Array.from({ length: 300 }, () => [ Math.random() * 800, Math.random() * 600 ]); const delaunay = Delaunay.from(points); const voronoi = delaunay.voronoi([0, 0, 800, 600]); const ctx = canvas.value.getContext("2d"); voronoi.renderCell(0, ctx); // 绘制某个单元 voronoi.render(ctx); // 绘制全部 Voronoi 边 ctx.stroke(); }); </script>核心步骤只有三步:构造点集 →Delaunay.from()剖分 →voronoi(bounds)生成区域,不需要引入任何渲染框架。
在 React 中封装 d3-delaunay 的 Hooks 实践
React 中建议用useMemo缓存计算结果,避免组件重渲染导致重复计算。下面封装一个通用 Hook:
import { useMemo } from "react"; import { Delaunay } from "d3-delaunay"; export function useVoronoi(points, bounds = [0, 0, 800, 600]) { return useMemo(() => { const delaunay = Delaunay.from(points); return delaunay.voronoi(bounds); }, [points, bounds]); }这样在组件里直接const voronoi = useVoronoi(data)即可。若点集坐标来自业务数据对象(如{lat, lng}),可给Delaunay.from传入取值函数:
Delaunay.from(geoData, d => d.lng, d => d.lat);from支持数组、可迭代对象和类数组对象,具体签名见 delaunay.js。
d3-delaunay API 速查手册:Delaunay 类常用方法
| API | 作用 | 返回值 |
|---|---|---|
Delaunay.from(points, fx, fy) | 从点集构建三角剖分 | Delaunay实例 |
delaunay.points | 平铺后的坐标(Float64Array) | 数组 |
delaunay.triangles | 三角形顶点索引(每 3 个一组) | Uint32Array |
delaunay.halfedges | 半边邻接信息 | Int32Array |
delaunay.hull | 凸包顶点索引 | Uint32Array |
delaunay.neighbors(i) | 第 i 个点的相邻点(生成器) | 迭代器 |
delaunay.find(x, y) | 查找离 (x, y) 最近的点 | 索引 |
delaunay.voronoi(bounds) | 生成 Voronoi 图 | Voronoi实例 |
delaunay.render(ctx) | 绘制三角剖分网格 | path 字符串或 undefined |
delaunay.renderHull(ctx) | 绘制凸包 | 同上 |
delaunay.renderPoints(ctx, r) | 绘制点集(r 为半径) | 同上 |
delaunay.trianglePolygon(i) | 第 i 个三角形的多边形坐标 | 点数组 |
delaunay.update() | 点坐标变化后增量更新 | this |
render系列非常灵活:传入 Canvas 2D context 会直接绘制;不传参数则返回 SVG path 字符串,可直接用于<path d="...">。测试中的典型用法可参考 delaunay-test.js。
Voronoi API 速查:从三角剖分到泰森多边形
通过delaunay.voronoi(bounds)得到 Voronoi 实例,bounds是[xmin, ymin, xmax, ymax]形式的边界数组,默认值为[0, 0, 960, 500](见 voronoi.js):
| API | 作用 | 返回值 |
|---|---|---|
voronoi.cellPolygon(i) | 第 i 个单元的多边形顶点 | 点数组或 null |
voronoi.cellPolygons() | 全部单元多边形(生成器) | 迭代器 |
voronoi.render(ctx) | 绘制全部单元边线 | path 字符串或 undefined |
voronoi.renderCell(i, ctx) | 绘制单个单元 | 同上 |
voronoi.renderBounds(ctx) | 绘制边界矩形 | 同上 |
voronoi.contains(i, x, y) | 判断点是否落在第 i 个单元内 | 布尔值 |
voronoi.neighbors(i) | 相邻单元索引(生成器) | 迭代器 |
voronoi.update() | 点更新后重建 | this |
voronoi.circumcenters | 各三角形外心坐标 | Float64Array |
cellPolygon返回的坐标是裁剪到边界内的多边形,非常适合配合 D3 或原生 Canvas 填充颜色。若你只想要三角剖分而不需要 Voronoi 图,直接使用 Delaunay 实例即可。
工程化实践:Canvas 渲染与性能优化技巧
1. 大数据量下的渲染优化
当点数量上万时,建议先渲染到离屏 Canvas 再合成,或使用render系列直接输出 path 字符串交给浏览器解析。避免在每次requestAnimationFrame中重建三角剖分。
2. 利用 update() 做增量更新
如果只有少量点坐标变化(如拖拽交互),直接修改delaunay.points(平铺的Float64Array)后调用update(),d3-delaunay 内部会增量更新,无需重建整个结构:
delaunay.points[0] = newX; // 修改第 0 个点的 x delaunay.points[1] = newY; delaunay.update(); voronoi.update();3. 处理退化情况
d3-delaunay 内部已处理共线点(自动加微扰)和重合点(对应单元返回 null)。测试覆盖了这些边界场景,可参考 voronoi-test.js 中的用例。注意bounds必须满足xmin <= xmax且ymin <= ymax,否则会抛出invalid bounds错误。
常见坑与避坑指南
- ⚠️坐标必须是数值:
find、contains会先把参数转成数字,NaN 会直接返回-1/false。 - ⚠️点为平铺格式:
delaunay.points是[x0, y0, x1, y1, ...]的Float64Array,遍历时步长是 2。 - ⚠️Voronoi 单元可能为空:重合点对应的
cellPolygon(i)返回null,渲染前需要判空。 - ⚠️ESM 模块:在 Node 环境使用需
"type": "module"或用构建工具处理,Node 版本建议 12+。
总结:让 d3-delaunay 成为你的数据可视化利器
d3-delaunay 用极小的体积提供了工业级的 Delaunay 三角剖分与 Voronoi 图计算能力。通过本文的安装步骤、Vue/React 集成方案和 API 速查表,你应该已经能在自己的前端项目中快速落地。想要深入阅读源码实现,可以git clone https://gitcode.com/gh_mirrors/d3/d3-delaunay后在本地运行yarn test查看完整测试,或直接阅读 delaunay.js 与 voronoi.js 的注释,进一步理解 sweep 算法与边界裁剪的实现细节。
【免费下载链接】d3-delaunayCompute the Voronoi diagram of a set of two-dimensional points.项目地址: https://gitcode.com/gh_mirrors/d3/d3-delaunay
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
