数据可视化【免费下载链接】vegaA visualization grammar.项目地址https://gitcode.com/gh_mirrors/ve/vega点击查看免费下载vega-scenegraph 是 Vega 可视化语法体系中的渲染核心它定义了 Vega 场景图scenegraph的数据结构与序列化协议并提供基于 Canvas像素与 SVG矢量的两套渲染器以及事件处理器。读完本文你将掌握场景图 mark/item 的层级结构、sceneFromJSON/sceneToJSON序列化方法、全量重绘与脏项增量重绘的实现原理并了解如何使用 SVG 字符串渲染器导出静态图片以及如何在 Node.js 服务端借助 node-canvas 完成渲染与文本边界计算。场景图定义mark 与 item 交替的树形结构Vega 场景图是一个层级树形数据结构。树的层级在两种节点之间交替mark 定义外层节点描述一类图形标记的类型与整体属性item 实例内层节点mark 所包含的一组具体实例每个 item 携带该标记的几何、样式等属性。一个仅包含三个矩形的简单场景图如下见 README.md{ marktype: rect, items: [ {x: 0, y: 0, width: 50, height: 50, fill: steelblue}, {x: 100, y: 50, width: 50, height: 50, fill: firebrick}, {x: 50, y: 100, width: 50, height: 50, fill: forestgreen} ] }这里的marktype字段声明标记类型items数组则给出每个实例的绘制属性x、y、width、fill等。支持的标记类型vega-scenegraph 内置的标记类型见 marks/index.js包括标记类型含义rect矩形symbol绘图符号散点、点标记path一般路径或多边形arc圆弧饼图、环形图area填充区域line折线image图片text文本标签rule网格线或参考线group容器标记可包含其他 markshape形状trail轨迹线每种 item 所支持的属性x、y、width、fill、stroke、opacity等与其 mark 类型相匹配。从 serialize.js 的序列化键白名单 可以反推出各标记类型的完整属性面例如arc使用startAngle、endAngle、innerRadius、outerRadius、padAnglerect与group支持cornerRadius、cornerRadiusTopLeft等圆角属性area/line使用interpolate、tension、orient、definedimage使用url、aspect、smoothsymbol使用size、shapetext使用text、angle、dx、dy、font、fontSize等字体与排版属性。Group 标记场景的容器与图层场景图还可以包含group标记作为其他标记的容器。例如一个顶层 group 标记形如{ marktype: group, items: [ { x: 0, y: 0, width: 200, height: 200, items: [...] // 包含的子标记实例数组 } ] }在这个例子中groupmark只包含一个 groupitem。实践中一个 group mark 可以包含任意数量的 group item例如用多个图层或子图来组织整个场景。Scenegraph类在无参构造时就会自动创建一个名为root、角色为frame的根 group 标记见 Scenegraph.js并通过mark(markdef, group, index)方法向指定 group 追加子标记。更详细的标记属性说明可参见仓库内的 Vega marks 文档 及各标记类型的示例文件如 arc.vg.json、group.vg.json。场景图序列化sceneFromJSON 与 sceneToJSONvega-scenegraph 的顶层导出见 index.js提供了sceneFromJSON与sceneToJSON两个方法用于场景图的序列化与反序列化。sceneFromJSON(json)接收一个 JSON 字符串或已解析的对象作为输入即上文示例的形式然后为树结构补上父指针。具体地每个 item 会获得一个指向其父 mark 的mark属性每个 mark 会获得一个指向其父 group 的group属性如果存在。从 serialize.js 的 initialize 实现 可以看到反序列化过程还会为存在marktype的标记调用boundMark(scene)计算边界bounds并对 group 递归初始化子标记若 item 带有zindex还会将其父标记标记为zdirty以便后续按 z 序重绘。sceneToJSON(scene, indent)将场景图实例映射为 JSON 字符串剔除父指针等非标准属性。其实现方式非常巧妙JSON.stringify(scene, keys, indent)配合一个显式的属性白名单keysserialize.js只序列化marktype、items、各类几何与样式属性从而天然过滤掉mark/group父指针以及_svg等运行时附加状态。此外序列化相关的配套能力还包括sceneEqual/pathEqual场景与路径的深度比较equal.js以及sceneVisit/scenePickVisit/sceneZOrder等场景遍历工具visit.js后者常被事件命中测试picking使用。渲染器体系Canvas 与 SVG 双轨输出vega-scenegraph 同时支持**像素Canvas与矢量SVG**两种输出分别由CanvasRenderer与SVGRenderer实现二者都继承自抽象的Renderer基类Renderer.js。Renderer基类统一了渲染器的生命周期 APIinitialize(el, width, height, origin, scaleFactor)绑定 DOM 容器、设置画布尺寸、坐标原点与缩放因子resize(width, height, origin, scaleFactor)动态调整显示尺寸返回渲染器实例以支持链式调用background(bgcolor)读取/设置背景色dirty(item)标记一个脏项基类为空操作由子类实现增量重绘render(scene, markTypes)立即渲染renderAsync(scene, markTypes)返回 Promise在所有**异步资源如图片加载完成并完成重绘后 resolveRenderer.jsloadImage(uri)/sanitizeURL(uri)加载图片资源并对 URL 做安全校验同时跟踪加载进度以触发异步重绘Renderer.js。markTypes参数用于按标记类型过滤渲染传入数组时仅渲染其中列出的类型未指定则渲染全部类型CanvasRenderer.js。全量重绘与增量重绘渲染器既可以完整重新绘制整个场景也可以针对一组脏项dirty items做增量重绘CanvasRenderer在dirty(item)中把脏项的边界含逐级 group 的平移补偿并入一个累积的_dirtyBounds 对象CanvasRenderer.js。绘制时若存在脏项则将裁剪区域收缩到视图边界 ∩ 脏边界只重绘该区域避免整帧刷新同时在clipToBounds中做 1 像素膨胀、像素对齐与非整数缩放pixelRatio修正以消除渲染伪影CanvasRenderer.js。clear方法在 PDF 模式与外部 contextexternalContext下会跳过clearRect避免破坏矢量输出CanvasRenderer.js。SVGRenderer以脏标记item.dirty ! this._dirtyID驱动。_dirtyCheck会对脏项分类处理——EXIT退出动画的项从 DOM 中移除、ENTER新进入的项创建新节点并标记父链、IN-PLACE UPDATE的项就地更新属性SVGRenderer.js。每个 item 通过bind与 SVG DOM 节点一一绑定item._svg缓存节点引用属性更新由各标记的attr发射器与样式表共同完成SVGRenderer.js。SVG 字符串渲染器静态导出除 DOM 版SVGRenderer外还提供了一个高速的 SVG 字符串渲染器SVGStringRenderer它不操作 DOM而是借助轻量的 markup 工具markup.js直接拼装 SVG 文本用于导出静态 SVG。其_render一次性生成完整的svg字符串包括可选的背景矩形、根g内容组以及按需生成的渐变/裁剪defsSVGStringRenderer.js。多行文本在此以多个tspan输出href超链接则会先经sanitizeURL校验后再改写为xlink:href命名空间属性SVGStringRenderer.js。渐变与裁剪的跨渲染器一致Canvas 与 SVG 对径向渐变的坐标语义存在差异SVG 径向渐变默认映射到归一化 bbox难以在 Canvas 中复现。为保持两种渲染器输出一致SVG 渲染器将径向渐变包装在pattern元素中SVGRenderer.js、SVGStringRenderer.js并统一收集到defs缓存里渲染完成后按需输出。事件处理CanvasHandler 与 SVGHandler场景图不仅是渲染的数据源也是事件命中测试的对象。Handler基类Handler.js定义了事件处理器的通用协议通过on(type, handler)/off(type, handler)注册与移除事件回调支持click.foo这类带命名空间的事件名eventName负责剥离后缀handleHref负责 item 上href超链接的跳转经 loader 的sanitize校验handleTooltip则驱动默认的 tooltip 行为——将值写入容器元素的title属性Handler.js。CanvasHandler与SVGHandler分别是 Canvas 与 SVG 场景的事件实现前者依赖命中测试工具如 intersect.js 中的intersectPath、intersectPoint、intersectRule、intersectBoxLine后者则直接利用 SVG DOM 的原生事件与getBoundingClientRect类方法getItemBoundingClientRect定位场景项。服务端渲染与边界计算node-canvas 的角色场景图渲染并不局限于浏览器。在 Node.js 服务端vega-scenegraph 借助 node-canvas 完成 Canvas 渲染与文本边界计算。需要注意node-canvas 不是严格依赖SVG 渲染完全不需要它它依赖原生Cairo 图形库安装过程中可能尝试编译原生代码个别环境下会出现安装问题——此时直接搜索 node-canvas而非 vega-scenegraph的安装问题往往能更快解决边界bounds计算可以在没有 node-canvas 的情况下进行但文本标记text marks的边界会因近似文本尺寸估算而不够精确。文本测量相关的实现集中在 text.js导出的textMetrics、font、fontFamily、fontSize、lineHeight、multiLineOffset等函数见 index.js负责在有无 canvas 环境间切换测量策略。具体边界计算逻辑分布在 bound/ 目录boundMark、boundItem、boundClip、boundStroke、boundContext其中boundStroke用于计算描边stroke对边界的扩展量。测试套件跨平台渲染一致性验证vega-scenegraph 的测试套件test/同时比对CanvasPNG与SVG文本两种渲染输出涉及canvas-renderer-test.js、svg-renderer-test.js、svg-string-renderer-test.js、bounds-test.js、handler-test.js、intersect-test.js等 18 个测试文件SVG 输出还会通过xmllint校验其 XML 合法性见 package.json。需要特别留意的是由于平台差异node-canvas 的逐像素渲染结果在不同操作系统上可能不同。因此部分测试用例在非 Mac OS X官方测试标准平台上运行时可能失败——这并不一定说明 vega-scenegraph 有问题。若在 Linux 或 Windows 上遇到测试失败官方建议运行 node-canvas 仓库中的测试服务器npm run test-server来对比服务端与客户端渲染结果以甄别环境差异导致的像素偏差。小结vega-scenegraph 是 Vega 技术栈中场景描述与图形绘制之间的桥梁它用 mark/item 交替的树形结构统一描述可视化内容用sceneFromJSON/sceneToJSON完成可传输、可持久化的序列化协议并提供 Canvas、SVG、SVG 字符串三套渲染器覆盖交互展示、增量更新与静态导出场景。理解其场景图结构与渲染管线是深入定制 Vega 渲染行为、排查渲染问题、乃至自研可视化引擎的基础。赞分享数据可视化【免费下载链接】vegaA visualization grammar.项目地址https://gitcode.com/gh_mirrors/ve/vega点击查看免费下载相关推荐RATH可视化渲染技术vega-scenegraph与WebGL渲染器详解RATH可视化渲染技术vega scenegraph与WebGL渲染器详解 RATHReveal the Answer to the Truth是一个开源数据分析数据可视化BI机器学习d3-path 路径序列化器详解在 D3.js 中一套 Canvas 绘图代码同时渲染 SVG 与 Canvasd3 path 路径序列化器详解在 D3.js 中一套 Canvas 绘图代码同时渲染 SVG 与 Canvas 本篇基于 d3 官方文档 docs/d3 p前端数据可视化图表库如何让微信聊天记录真正属于你WeChatMsg三步实现数据永久保存如何让微信聊天记录真正属于你WeChatMsg三步实现数据永久保存 你是否曾为无法永久保存微信聊天记录而烦恼那些珍贵的对话、重要的信息、温暖的回忆是否因为创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?