ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

用 Vue.js 与 D3 打造可交互的社交网络可视化:Data-Science-For-Beginners 课程 Dangerous Liaisons 项目从搭建到运行

用 Vue.js 与 D3 打造可交互的社交网络可视化:Data-Science-For-Beginners 课程 Dangerous Liaisons 项目从搭建到运行 用 Vue.js 与 D3 打造可交互的社交网络可视化Data-Science-For-Beginners 课程 Dangerous Liaisons 项目从搭建到运行【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners导读本文面向想要快速上手「数据可视化」实战的开发者完整讲解 Data-Science-For-Beginners 课程第 13 课「有意义的可视化Making Meaningful Visualizations」配套的 Dangerous Liaisons 项目这是一个基于 Vue.js 3 与 D3 网络可视化库vue-d3-network的单页应用用于将法国书信体小说《危险关系Les Liaisons Dangereuses》中的 1261 行信件数据渲染为一幅可拖拽、可交互的社交网络图。读完本文你将掌握该 Vue CLI 工程从环境准备、依赖安装、开发运行、生产构建到补全核心连线逻辑createLinks的完整流程并理解每个 npm 脚本与关键源码文件的职责。项目背景为什么用一封信件的网络图做练习《危险关系》是法国作家肖代洛·德·拉克洛Choderlos de Laclos于 1782 年出版的书信体小说故事以瓦勒蒙子爵Vicomte de Valmont与梅尔特伊侯爵夫人Marquise de Merteuil两位主角的通信为线索展开。小说全文由人物之间往来的信件组成天然带有「发信人from」与「收信人to」的结构化关系——这正是构建社交网络图Social Network Graph的理想数据来源。课程的第 13 课正是围绕「如何做出有意义的可视化」展开选择正确的图表类型、避免误导性图表、正确处理颜色、提升可读性以及如何构建动效与 3D 可视化。而 Dangerous Liaisons 项目就是该课的收尾实战把信件数据映射为节点人物与连线信件往来在浏览器中以动画方式呈现这出 18 世纪法国贵族社会的关系图谱。项目运行后你可以用鼠标拖动节点实时观察「谁在给谁写信」的社交结构直观地定位故事中的核心人物。本次要讲解的 starter 工程 是一个已经搭好框架、留有一处待补全逻辑createLinks()方法的 Vue CLI 项目仓库内还提供了 solution 完整版 供对照参考。环境准备Node.js 与 npm 版本要求在安装依赖之前请先确认本机已具备 Node.js 与 npm 环境。项目对 Node 版本有明确要求Node 20.0.0。这一约束同时出现在工程根目录的 starter/README.md 与 package.json 的engines字段中engines: { node: 20.0.0 }engines字段是 npm 生态中声明运行时兼容性的标准方式配合.npmrc如engine-stricttrue可强制在安装时校验版本。如果本机 Node 版本低于 20建议先通过 nvm 等工具升级否则npm install可能抛出 engine 警告某些依赖尤其是较新版本的构建工具链也可能无法正常工作。可以在终端用node -v与npm -v快速确认当前版本。项目安装npm install进入3-Data-Visualization/13-meaningful-visualizations/starter目录后运行npm install该命令会依据 package.json 拉取全部依赖。从依赖清单可以了解这个工程的技术栈构成dependencies: { core-js: ^3.6.5, vue: ^3.5.16, vue-d3-network: 0.1.28 }, devDependencies: { vue/cli-plugin-babel: ~5.0.8, vue/cli-plugin-eslint: ~5.0.8, vue/cli-service: ~5.0.8, babel-eslint: ^10.1.0, eslint: ^9.34.0, eslint-plugin-vue: ^10.4.0, vue-template-compiler: ^2.6.11 }vue ^3.5.16应用主体框架本工程采用 Composition 风格较早期的 Options API 写法详见下文源码解析vue-d3-network 0.1.28核心可视化库它基于 Vue.js 与 D3 封装将节点nodes与连线links数据渲染为可拖拽的力导向网络图vue/cli-service ~5.0.8Vue CLI 构建服务serve、build、lint三个脚本都经由它执行core-js为低版本浏览器提供 ES 新特性的 polyfill与 Babel 配置配合工作。值得留意的是package.json末尾还有一段overrides配置将若干传递依赖锁定到较新的安全版本overrides: { qs: 6.14.2, braces: 3.0.3, webpack-dev-server: { ws: 8.21.0 }, webpack-bundle-analyzer: { ws: 7.5.11 }, serialize-javascript: 7.0.5 }从配置内容可以推断这是为了修复 Webpack 工具链中传递依赖的已知安全问题而统一锁定的版本——这也是工程维护者保证可复现、可安全构建的一种常见做法。开发模式运行npm run serve安装完成后启动本地开发服务器npm run serve该脚本执行vue-cli-service serve其作用包括编译与热重载hot-reload修改src/下的.vue、.js文件后页面会自动刷新或局部更新无需手动重启非常适合边改边调试可视化效果启动本地开发服务器本仓库未提供vue.config.js自定义配置因此端口、代理等均采用 Vue CLI 默认行为默认监听 8080 端口终端会打印可访问的本地地址编译错误与警告提示若代码存在语法错误终端会即时反馈便于快速定位问题。启动成功后浏览器打开终端提示的地址即可看到 Dangerous Liaisons 信件网络图。注意此刻连线还是空的因为 Nodes.vue 中的createLinks()尚未补全——这是本项目的核心作业下文会详细讲解。生产构建npm run build当可视化逻辑完成后可以为部署生成优化产物npm run build该脚本执行vue-cli-service build会完成以下工作编译并压缩minify将所有.vue单文件组件、JavaScript 与样式打包为压缩后的静态资源按 browserslist 目标优化package.json中的browserslist字段声明了兼容目标browserslist: [ 1%, last 2 versions, not dead ]即「全球使用率超过 1% 的浏览器、各主流浏览器的最近两个大版本、仍处于维护期的浏览器」——Babel 与 Autoprefixer 会据此决定哪些语法需要转译、哪些 CSS 属性需要加前缀从而在兼容性与产物体积之间取得平衡产物输出到dist/目录dist/是纯静态文件可直接托管到任意静态 Web 服务器这正是 assignment.md 中建议的「尝试将其部署为静态 Web 应用」的依据。代码检查与修复npm run lint项目内置了 ESLint 代码规范检查npm run lint该脚本执行vue-cli-service lint依据package.json中的eslintConfig配置进行校验并自动修复可修复的问题eslintConfig: { root: true, env: { node: true }, extends: [ plugin:vue/essential, eslint:recommended ], parserOptions: { parser: babel-eslint }, rules: {} }plugin:vue/essentialVue 官方推荐的必备规则集能拦截模板中的明显错误写法eslint:recommendedESLint 内置的推荐规则parser: babel-eslint让 ESLint 能解析 Vue 单文件组件中的现代 JavaScript 语法。项目结构从入口到核心组件的源码解析为了理解「在哪里补全代码」先梳理starter/的目录结构starter/ ├── public/ │ ├── favicon.ico # 站点图标 │ └── index.html # HTML 入口模板 ├── src/ │ ├── assets/ │ │ └── letters.json # 小说全部信件数据1261 行含 from / to / date / location │ ├── components/ │ │ └── Nodes.vue # 网络可视化核心组件待补全 createLinks │ ├── App.vue # 根组件挂载 Nodes │ └── main.js # Vue 应用入口 ├── README.md # 项目说明与命令清单 ├── babel.config.js # Babel 转译配置 └── package.json # 依赖与脚本定义启动链路非常清晰。入口 main.js 创建 Vue 实例并挂载到#appimport Vue from vue; import App from ./App.vue; Vue.config.productionTip false; new Vue({ render: h h(App) }).$mount(#app);根组件 App.vue 只做一件事——渲染Nodes组件template div idapp Nodes / /div /template script import Nodes from ./components/Nodes; export default { name: App, components: { Nodes, }, }; /script真正的核心是 Nodes.vue。模板部分直接使用vue-d3-network提供的d3-network组件把节点、连线和选项绑定进去template div classhello d3-network :net-nodesnodes :net-linkslinks :optionsoptions / /div /template组件脚本的关键逻辑如下逐段解读引入库与数据import D3Network from vue-d3-network引入网络图组件import letters from ../assets/letters.json引入信件数据data 状态nodes与links分别承载网络节点与连线nodeSize控制节点尺寸canvas控制渲染方式false 表示使用 SVG 而非 Canvascomputed 的 options向vue-d3-network传递力导向布局与显示选项详见下节created 生命周期声明了小说中的 15 个人物名单characters数组包含Vicomte de Valmont、Marquise de Merteuil、Cécile Volanges等随后调用this.createLinks(characters)生成连线并遍历人物为每个节点设置id、name、_size与随机颜色_color。其中getCount(name)方法统计某个人物收到的信件数用于决定节点大小getCount(name) { var count 0; for (var i 0; i letters.length; i) { if (letters[i].to name) { count; } } return count; }核心作业补全 createLinks() 让连线出现启动项目后网络图「只有节点没有连线」的原因就在于 starter 版 Nodes.vue 中的createLinks()是空实现methods: { createLinks(characters) { //complete this code }, ... }数据源 letters.json 的结构非常简单每条记录包含letter_num、from、to、date、location等字段{ letter_num: 1, from: Cécile de Volanges, to: Sophie Carnay, date: 8/3/17**, location: Ursulines }而vue-d3-network期望的连线对象是{ sid: 源节点id, tid: 目标节点id }形式。因此任务可以拆解为两步把每个人物映射为其在characters数组中的下标再遍历每封信构造{ sid, tid }对象 push 进links。课程给出的嵌套循环解法如下createLinks(characters) { //loop through letters let f 0; let t 0; for (var i 0; i letters.length; i) { for (var j 0; j characters.length; j) { if (characters[j] letters[i].from) { f j; } if (characters[j] letters[i].to) { t j; } } this.links.push({ sid: f, tid: t }); } }该实现与 solution 完整版 中的写法完全一致。补全后重新保存文件热重载会自动生效画布上便会绘制出人物之间的信件往来连线你还可以拖动节点观察力导向布局如何重新排布整个网络。进阶思考可自行尝试的优化方向上述循环对每封信都执行了一次 O(n×m) 的双层遍历若人物数量或信件规模增大可将人物名到下标的映射提前构建为Map以降低复杂度。此外f、t未命中人物名单时会残留上一次循环的值可考虑在匹配不到时跳过该信件或给出默认值——这些都属于在理解作业基础上的合理深化不作为本课程的必做要求。可视化选项解析force、size 与标签Nodes.vue的 computedoptions对象直接控制网络图的物理仿真与显示效果computed: { options() { return { force: 3000, // 力导向布局的斥力强度数值越大节点越分散 size: { w: 600, h: 600 }, // 画布宽高像素 offset: { x: 0, y: 0 }, // 画布偏移量 nodeLabels: true, // 是否显示节点上的姓名标签 linkLabels: true, // 是否显示连线上的标签 canvas: this.canvas, // false使用 SVG 渲染true切换为 Canvas 渲染 }; }, },force力导向图force-directed graph的核心参数控制节点间的排斥力数值越大节点之间的间距越大、布局越松散nodeLabels / linkLabels开启后节点旁会标注人物姓名、连线上会标注对应内容极大提升可读性——这正是第 13 课「为可读性而设计Styling your charts for readability」的实践体现canvasfalse时走 SVG 渲染便于样式定制与 DOM 调试true时切换为 Canvas适合海量节点的高性能场景。本组件在data()中声明了canvas: false因此默认采用 SVG。配合 Nodes.vue 内置的样式表如节点悬停高亮stroke-width: 5px、选中态描边#caa455、连线半透明绿色等整个网络图已经具备较好的交互反馈与视觉层次。自定义配置与后续扩展starter/README.md 最后提到「Customize configuration」。由于本工程未提供vue.config.js文件所有 Vue CLI 行为均使用默认值若需调整端口、公共路径、代理等可在工程根目录新建vue.config.js并按 Vue CLI 官方配置参考修改——注意这是对工程的自定义扩展不是本仓库既有的内容。完成可视化补全后课程给出了进一步的挑战练习见 assignment.md参考本项目中的社交网络示例为「你自己的社交互动」构造数据——可以是你的社交媒体使用记录也可以是家庭成员关系图打造一个展示独特社交网络可视化的 Web 应用。评分标准强调代码能正常运行可尝试部署为静态 Web 应用、提供带注释说明的 README。因此一个完整交付物应当包含可运行的工程、清晰的文档以及通过npm run build产物部署到静态托管的能力。此外第 13 课正文3-Data-Visualization/13-meaningful-visualizations/README.md还给出了更具挑战性的方向自己上网搜集「误导性图表」并尝试修正以此巩固「有意义可视化」的判读能力。小结Dangerous Liaisons 项目虽然只是一个 Vue CLI 脚手架工程却完整覆盖了「数据 → 结构 → 可视化」的典型链路letters.json是结构化的信件数据createLinks()完成从原始数据到图结构nodes links的转换vue-d3-network负责力导向渲染与交互。通过本文你应当已经掌握了这套工程的完整生命周期以Node 20.0.0为前提用npm install安装依赖用npm run serve启动热重载开发服务器在src/components/Nodes.vue中补全createLinks()把信件数据的from/to映射为{ sid, tid }连线用npm run lint维持代码规范用npm run build产出可直接部署的静态产物。在此基础上参考 solution 版本 对照检查再动手完成「自建社交网络」的 作业你就能把本课学到的「选择合适图表、为可读性设计、用交互增强表达」真正落到自己的可视化作品里。【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进