news 2026/9/12 23:34:59

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 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-strict=true)可强制在安装时校验版本。如果本机 Node 版本低于 20,建议先通过 nvm 等工具升级,否则npm install可能抛出 engine 警告,某些依赖(尤其是较新版本的构建工具链)也可能无法正常工作。可以在终端用node -vnpm -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.8:Vue CLI 构建服务,servebuildlint三个脚本都经由它执行;
  • 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/essential:Vue 官方推荐的必备规则集,能拦截模板中的明显错误写法;
  • eslint:recommended:ESLint 内置的推荐规则;
  • 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 实例并挂载到#app

import 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 id="app"> <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 class="hello"> <d3-network :net-nodes="nodes" :net-links="links" :options="options" /> </div> </template>

组件脚本的关键逻辑如下(逐段解读):

  1. 引入库与数据import D3Network from "vue-d3-network"引入网络图组件;import letters from "../assets/letters.json"引入信件数据;
  2. data 状态nodeslinks分别承载网络节点与连线;nodeSize控制节点尺寸;canvas控制渲染方式(false 表示使用 SVG 而非 Canvas);
  3. computed 的 options:向vue-d3-network传递力导向布局与显示选项(详见下节);
  4. created 生命周期:声明了小说中的 15 个人物名单(characters数组,包含"Vicomte de Valmont""Marquise de Merteuil""Cécile Volanges"等),随后调用this.createLinks(characters)生成连线,并遍历人物为每个节点设置idname_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_numfromtodatelocation等字段:

{ "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以降低复杂度。此外,ft未命中人物名单时会残留上一次循环的值,可考虑在匹配不到时跳过该信件或给出默认值——这些都属于在理解作业基础上的合理深化,不作为本课程的必做要求。

可视化选项解析: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负责力导向渲染与交互。通过本文,你应当已经掌握了这套工程的完整生命周期:

  1. Node >= 20.0.0为前提,用npm install安装依赖;
  2. npm run serve启动热重载开发服务器;
  3. src/components/Nodes.vue中补全createLinks(),把信件数据的from/to映射为{ sid, tid }连线;
  4. 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 23:34:43

Windows代码签名避坑指南:EV证书、时间戳与SmartScreen信任机制详解

1. 为什么普通代码签名证书已经扛不住Windows SmartScreen的“红屏警告”了&#xff1f; 去年底&#xff0c;我帮一家做PC端工具软件的创业团队上线新版本&#xff0c;打包完直接发给测试同事——结果三台不同配置的Win10/Win11机器&#xff0c;全部弹出醒目的红色SmartScreen…

作者头像 李华
网站建设 2026/9/12 23:31:40

高光谱混合像元分解:线性混合模型与端元提取完全指南

高光谱成像这几年在遥感、农业、医学影像、工业分选这些领域是真的火。跟普通 RGB 三波段成像完全不是一个量级&#xff0c;它动辄几十上百个连续波段&#xff0c;能把每个像元都展开成一条精细的光谱曲线。但问题也随之而来&#xff1a;空间分辨率有限&#xff0c;一个像元里往…

作者头像 李华
网站建设 2026/9/12 23:28:20

OSI会话层深度解析:从核心机制到NetBIOS/SIP实战与抓包排查

写这个系列写到第七篇&#xff0c;前边把物理层、数据链路层、网络层、传输层这些重头戏都过了一遍&#xff0c;今天轮到会话层。说句实话&#xff0c;会话层在整个OSI参考模型里属于存在感最低的一层&#xff0c;很多教材翻两页就带过去了&#xff0c;面试题里也顶多考一句“负…

作者头像 李华
网站建设 2026/9/12 23:25:29

电动自行车头盔检测:YOLOv5s轻量化部署实战

简介&#xff1a;本资源是一个基于深度学习的电动自行车头盔佩戴检测系统完整实现&#xff0c;面向人工智能初学者与计算机视觉实践者&#xff0c;聚焦交通安全管理中的实际识别需求&#xff0c;适用于课程设计、毕业设计及轻量级AI项目落地参考。压缩包共187个文件&#xff0c…

作者头像 李华