尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

perspective-viewer Web Component 实战指南:Perspective 数据可视化组件的前端集成、主题与配置持久化

perspective-viewer Web Component 实战指南:Perspective 数据可视化组件的前端集成、主题与配置持久化 perspective-viewer Web Component 实战指南Perspective 数据可视化组件的前端集成、主题与配置持久化【免费下载链接】perspectiveA data visualization and analytics component, especially well-suited for large and/or streaming datasets.项目地址: https://gitcode.com/GitHub_Trending/pe/perspectiveperspective-viewer是 Perspective 数据可视化与分析库的官方 UI 组件它以 Web ComponentCustom Element的形式为浏览器应用提供完整的图形化配置界面可直接绑定本地 Web Worker、远程 WebSocket 服务端或虚拟数据源中的table()并将查询结果渲染为数据表格与图表。阅读本文后你将掌握如何引入并注册该组件、加载与共享数据表、切换主题、通过save()/restore()序列化与恢复视图配置以及监听更新与点击事件实现可直接复用的大数据量、流式数据可视化前端方案。perspective-viewerCustom Element 库perspective-viewer为配置perspective库并格式化其输出到各类可视化插件提供了完整的图形化界面。该组件位于 rust/perspective-viewer 包中npm 包名为perspective-dev/viewer版本信息见 rust/perspective-viewer/package.json与其配套的插件包还包括perspective-dev/viewer-datagrid数据表格与perspective-dev/viewer-charts图表。引入与注册机制如果你使用esbuild或其他支持 ES6 模块的打包器只需在应用的任意位置导入perspective-viewer相关库即可——这些模块不导出任何实际内容导入的副作用是注册 Custom Element供站点中的普通 HTML 直接使用import perspective-dev/viewer; import perspective-dev/viewer-datagrid; import perspective-dev/viewer-charts;这一“无导出、仅注册”的设计在源码中有明确体现在 rust/perspective-viewer/src/ts/perspective-viewer.ts 的模块注释中说明导入该模块的副作用是将PerspectiveViewerElement类注册为 custom element由于 WebAssembly 编译使该模块成为动态模块为保证 Custom Element 的扩展方法随包导入同步注册所有 API 方法都被设计为async必须等待 wasm 模块实例就绪。导入完成后perspective-viewerWeb Component 即可用于站点任意标准 HTML 中。一个最简单的例子perspective-viewer idview1/perspective-viewer或者在 JavaScript 中以编程方式创建const viewer document.createElement(perspective-viewer);从源码结构看组件的主入口custom element 定义、load/save/restore/reset等 API 实现位于 rust/perspective-viewer/src/rust/custom_elements/viewer.rs前端引导逻辑在 rust/perspective-viewer/src/ts/bootstrap.ts 与 rust/perspective-viewer/src/ts/perspective-viewer.ts。Theming 主题系统perspective-viewer及其配套插件支持主题Theming。perspective-viewer内置了多套主题你可以直接在应用中导入任意主题所有perspective-viewer将随之应用对应主题// 基于 Thought Merchantss Prospective 设计的主题 import perspective-dev/viewer/dist/css/pro.css; import perspective-dev/viewer/dist/css/pro-dark.css; // 其他主题 import perspective-dev/viewer/dist/css/solarized.css; import perspective-dev/viewer/dist/css/solarized-dark.css; import perspective-dev/viewer/dist/css/monokai.css; import perspective-dev/viewer/dist/css/vaporwave.css;或者使用打包了所有默认主题的themes.cssimport perspective-dev/viewer/dist/css/themes.css;仓库中的主题源文件集中存放在 rust/perspective-viewer/src/themes除上述主题外还包含botanical.css、dracula.css、gruvbox.css、gruvbox-dark.css、phosphor.css、defaults.css、icons.css、intl.css以及聚合入口themes.css你可以在该目录下查看每个主题的完整 CSS 定义。如果你选择不自行打包主题也可以通过 CDN 直接引用并在 HTML 中通过link引入link relstylesheet crossoriginanonymous hrefhttps://cdn.jsdelivr.net/npm/perspective-dev/viewer/dist/css/pro.css /主题自动检测与 resetThemes()注意上述link标签中的crossoriginanonymous属性。当从跨域上下文引入主题时该属性可能是让perspective-viewer检测到主题所必需的。如果检测失败——例如在perspective-viewer初始化之后才向document添加额外的主题或因其他任何原因导致主题自动检测失败——你可以通过.resetThemes()方法手动告知perspective-viewer可用的主题名称// 重新自动检测主题 viewer.resetThemes(); // 显式设置可用主题这些主题仍必须先作为 CSS 导入 viewer.resetThemes([Pro Light, Pro Dark]);resetThemes()的实现位于 rust/perspective-viewer/src/rust/custom_elements/viewer.rs传入None时重新解析document中的 CSS 以自动检测主题传入字符串数组时则显式限定可用主题集合调用后组件会同步当前激活主题若新集合中不包含当前主题则可能触发主题切换。与之配套的还有getThemes()方法同文件第 1704 行用于查询当前可用的主题名称列表。主题配置的底层状态管理见 rust/perspective-viewer/src/rust/config/viewer_config.rs 与 rust/perspective-viewer/src/rust/presentation.rs 中的reset_available_themes。初始主题设置perspective-viewer初始化时会默认使用第一个加载的主题。你可以通过.restore()覆盖默认值或通过设置theme属性来提供初始主题perspective-viewer themePro Light/perspective-viewer或const viewer document.querySelector(perspective-viewer); await viewer.restore({ theme: Pro Dark });向perspective-viewer加载数据数据可以通过load()方法以Table()或PromiseTable的形式加载到perspective-viewer中// 创建一个新的 worker然后在 worker 上创建 table promise。 const worker await perspective.worker(); const table await worker.table(data); // 将 viewer 元素绑定到这个 table。 await viewer.load(table);load()的绑定逻辑见 rust/perspective-viewer/src/rust/custom_elements/viewer.rs它接受一个JsClientLoad既可以是本地/Worker 端 client也可以是远程虚拟表 client并建立会话。在多个perspective-viewer之间共享一个table()多个perspective-viewer可以通过把同一个table()传入每个 viewer 的load()方法来共享该表。当底层table()被更新时每个perspective-viewer都会同步更新但table.delete()在所有引用它的perspective-viewer实例也被删除之前会失败const viewer1 document.getElementById(viewer1); const viewer2 document.getElementById(viewer2); // 创建一个新的 WebWorker const worker await perspective.worker(); // 在该 worker 中创建 table const table await worker.table(data); // 将同一个 table 加载到两个不同的 perspective-viewer 元素中 await viewer1.load(table); await viewer2.load(table); // viewer1 和 viewer2 都会反映这次更新 await table.update([{ x: 5, y: e, z: true }]);通过WebSocketServer()与 Node.js 实现仅服务端模式加载一个虚拟的仅服务端Table与加载本地/Web Worker 的Table完全一样——只需将虚拟Table传给viewer.load()在浏览器端const elem document.getElementsByTagName(perspective-viewer)[0]; // 绑定到服务器的 worker而不是实例化一个 Web Worker。 const websocket await perspective.websocket( window.location.origin.replace(http, ws), ); // 将 viewer 绑定到预加载的数据源。table 和 view 对象都驻留在服务器上。 const server_table await websocket.open_table(table_one); await elem.load(server_table); // 或者通过 view 加载 table 的数据。浏览器此时在其自身的 table 中 // 也拥有一份该 view 的副本其更新通过 Apache Arrow 传输到浏览器。 const worker await perspective.worker(); const server_view await server_table.view(); const client_table worker.table(server_view); await elem.load(client_table);以这种方式绑定的perspective-viewer实例与依赖 Web Worker 的perspective-viewer在其余方面没有区别甚至可以与依赖 Web Worker 绑定的table()共处同一个宿主应用中。二者都使用相同的基于 promise 的 API 与服务器端实例化的view()通信只是此处通过 websocket 进行。仓库中关于服务端集成的完整说明可参见 docs/md/explanation/virtual_servers.md 与 docs/md/explanation/architecture.md。通过save()/restore()持久化perspective-viewer配置perspective-viewer是**持久化persistent**的它除数据本身之外的整个状态都可以被序列化或反序列化。这包括所有列columns、过滤器filters、透视pivots、表达式expressions等属性以及数据表格的样式设置、配置面板的可见性等。这个重载功能覆盖了一系列使用场景在load()调用之后设置perspective-viewer的初始状态。更新单个或部分属性而不修改其他属性。将部分或全部属性重置为与数据相关的默认值。将用户的配置持久化到localStorage或服务器。序列化与反序列化 viewer 状态要获取整个状态的 JSON-ready JavaScript 对象使用save()方法。save()还支持其他格式如arraybuffer和stringbase64而非 JSON你可以在占用空间与迁移/手工编辑便利性之间做出取舍const json_token await elem.save(); const string_token await elem.save(string);save()的 Rust 侧实现见 rust/perspective-viewer/src/rust/custom_elements/viewer.rs它通过get_viewer_config读取面板当前的ViewerConfig并编码返回。对于任何格式序列化得到的 token 都可以通过restore()方法恢复到任何具有相同 schema 的Table的perspective-viewer上。需要注意的是save()返回的 token 中的数据可能不同但其 schema 一般不能不同因为许多其他设置依赖于列名和类型await elem.restore(json_token); await elem.restore(string_token);由于restore()是根据 token 的类型进行分派的因此务必保证这些类型匹配一个常见的错误来源是将 JSON-stringified 的 token 传给restore()此时字符串 token 会被假定为 base64 编码的 msgpack// 这将会报错 await elem.restore(JSON.stringify(json_token));restore()的实现含suppress_errors选项与单面板/全面板的分派逻辑见 rust/perspective-viewer/src/rust/custom_elements/viewer.rs。更新单个属性使用 JSON 格式perspective-viewer配置的每一个方面都可以通过 JavaScript 的restore()方法进行操作。属性的合法结构由ViewerConfig与内嵌的ViewConfig类型声明描述前者见 rust/perspective-viewer/src/ts/ts-rs/ViewerConfig.d.ts后者见 rust/perspective-js/src/rust 下 client/view 相关类型关于每个ViewConfig属性的交互式示例可参阅文档的 View 章节。// 设置插件同时会把 columns 更新为插件默认值 await elem.restore({ plugin: X Bar }); // 更新插件和列只绘制一次 await elem.restore({ plugin: X Bar, columns: [Sales] }); // 打开配置面板 await elem.restore({ settings: true }); // 创建表达式 await elem.restore({ columns: [Sales 100], expressions: { New Column: Sales 100 }, }); // 如果列不存在于 schema 或 expressions 中则报错 // await elem.restore({columns: [\Sales\ 100], expressions: {}}); // 添加过滤器 await elem.restore({ filter: [[Sales, , 100]] }); // 添加排序但不移除过滤器 await elem.restore({ sort: [[Prodit, desc]] }); // 只重置过滤器保留排序 await elem.restore({ filter: undefined }); // 将全部属性重置为默认值例如在 load() 之后 await elem.reset();reset()的实现位于 rust/perspective-viewer/src/rust/custom_elements/viewer.rsreset_all参数为true时还会清除表达式和列样式设置可通过{panel: p1}选项只重置指定面板省略时重置所有面板。另一种快速生成目标配置 token 的有效方式是在浏览器中手动设置好视图后直接复制save()返回的 token。JSON 格式是人类可读的且save()会返回所有属性的默认设置因此生成的 token 非常容易手工微调。你可以在应用代码中调用save()也可以通过 Chrome 开发者控制台调用// 复制到剪贴板 copy(await document.querySelector(perspective-viewer).save());对于多面板workspace场景perspective-viewer还提供了saveWorkspace()/restoreWorkspace()对用于序列化/恢复整个 workspace 配置包括布局、面板与调色板实现见 rust/perspective-viewer/src/rust/custom_elements/viewer.rs。更新事件 Update events每当perspective-viewer底层的table()通过load()或update()方法发生变化时会触发perspective-view-updateDOM 事件。类似地通过 Attribute API 或用户交互触发的view()更新会触发perspective-config-update事件elem.addEventListener(perspective-config-update, function (event) { var config elem.save(); console.log(The view() config has changed to JSON.stringify(config)); });从源码看事件系统基于 PubSub 通道向 JavaScriptCustomEvent的扇出机制实现核心代码在 rust/perspective-viewer/src/rust/custom_events.rswire_element_events第 209 行起负责元素级事件主题变化、设置面板开关等wire_panel_events第 326 行起负责单个面板的session/renderer通道所有perspective-*事件均以bubblescomposed方式派发perspective-config-update的detail为裸的ViewerConfig第 147-202 行dispatch_config_update可直接用于viewer.restore(e.detail)的往返操作。除本文涉及的事件外该文件还实现了layout-update、active-panel-update、global-filter-update、select、column-style-change、table-delete等事件。点击事件 Click events每当perspective-viewer的表格或图表被点击时会触发perspective-clickDOM 事件其 detail 对象包含config、column_names和row三个字段。config对象包含一组filters可以通过restore()应用到perspective-viewer使其显示过滤后的数据子集。column_names属性包含匹配列的数组row属性返回对应的行数据。elem.addEventListener(perspective-click, function (event) { var config event.detail.config; elem.restore(config); });在源码中perspective-click监听器也被用于 master/detail 联动点击 master 面板如柱状图的柱子、平面表格的单元格被视为一次选区贡献会路由为MasterContribution消息见 rust/perspective-viewer/src/rust/components/viewer/wiring.rs 与 rust/perspective-viewer/src/rust/components/viewer/msg.rs从而驱动全局过滤联动——这意味着你可以在自己的应用中基于perspective-click构建跨图表的交互式筛选体验。结语与延伸阅读至此你已经掌握了perspective-dev/viewer组件从引入注册、数据加载与共享、服务端 WebSocket 绑定、主题定制到配置序列化持久化与事件响应的完整用法。以上 API 全部建立在asyncpromise 模型之上既适用于单页应用内的本地 Worker 模式也适用于与 Python/Rust 服务端配合的远程模式。如果你想进一步深入可以继续阅读仓库中的以下资料docs/md/explanation/view.mdViewConfig各属性的交互式示例docs/md/how_to/javascript/virtual_server.mdJavaScript 端虚拟服务器接入docs/md/how_to/javascript/save_restore.md保存与恢复状态的进阶用法docs/md/how_to/javascript/theming.md主题定制的详细说明docs/md/how_to/javascript/events.md完整事件清单rust/perspective-viewer/src/ts组件 TypeScript 侧入口与类型声明rust/perspective-viewer/src/rust组件 Rust 侧实现源码【免费下载链接】perspectiveA data visualization and analytics component, especially well-suited for large and/or streaming datasets.项目地址: https://gitcode.com/GitHub_Trending/pe/perspective创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表