【d3.js实战】青蛇劫起影评数据可视化

南宋末年,小白为救许仙,水漫金山,终被法海压在雷峰塔下。小青心生救姐, 执念死死纠缠法海,由此被法海痛下杀手,但因其执念落入修罗城幻境经历考验。几次危机 中小青被神秘蒙面少年所救,小青带着去救出小白、打倒法海、掀翻雷峰塔的执念历经劫难 与成长。强大的执念支撑着她必须要在弱肉强食的修罗城中活下去,带着一世的记忆走出修 罗城... ...一幕幕是否很熟悉呢?没错,这就是被誉为国产动画作品顶峰的电影《白蛇 2:青 蛇劫起》的剧情梗概。正所谓"一千个读者有一千个哈姆雷特",对于这部电影,大家也是 众说纷纭,现在需要我们把大家的意见综合起来,进行可视化分析。

准备工作

准备一份数据集,这里我们采用CSV文件。CSV文件相比js常用的json和xml格式相比有不少优点。

  1. 简单易用:CSV 格式是一种非常简单、易于使用和理解的文件格式,适合各种编程语言和工具进行读写和处理。它没有复杂的数据结构或格式限制,可以轻松地在不同的应用和系统之间传输和共享数据。
  2. 轻量级高效:CSV 格式文件通常比类似 Excel 或 SQL 数据库等其他格式文件更小、更轻量级,因此在网络传输和存储方面更加高效。同时,由于没有复杂的数据结构,CSV 格式的数据处理速度也非常快。
  3. 可读性强:由于 CSV 格式是文本格式,因此非常容易阅读和理解。相比于二进制格式文件,CSV 格式文件更容易进行数据分析和处理。
  4. 可移植性强:CSV 格式是一种基于文本的格式,因此可以轻松地在不同的操作系统和软件之间传输和共享数据。无论是 Windows、Mac 还是 Linux 系统,都可以使用 CSV 格式文件进行数据处理和传输。
  5. 可自定义性强:虽然 CSV 格式的数据结构很简单,但是可以通过自定义文件分隔符、文本编码、行结束符等参数进行更加灵活和定制化的设置。这使得 CSV 格式可以适应不同的数据处理需求和环境。

下面是准备好的CSV文件的部分内容:

csv 复制代码
id,用户名,城市,评分,评论,评论时间
1142669584,淇桐糯米饭啦,来宾,5,剧情非常有吸引力,看个动画片给了我惊喜,2021-08-31 23:56:30
1142662178,LnV14610189,西宁,5,画面感超强!,2021-08-31 23:36:00
1142666877,Alo861902585,广州,5,和一衔接的很不错,精彩,2021-08-31 23:34:41

加载CSV文件

在 D3.js 中,可以使用 d3.csv() 函数加载 CSV 文件。该函数返回一个 Promise 对象,可以使用 then() 方法或 await 关键字处理异步加载的数据。以下是一个示例代码:

javascript 复制代码
d3.csv("data.csv").then(function(data) {
  console.log(data);
});

在上面的代码中,我们使用 d3.csv() 函数加载名为 "data.csv" 的 CSV 文件,并在加载成功后将数据打印到控制台中。

解析 CSV 数据

使用 d3.csv() 函数加载 CSV 文件后,D3.js 会自动将文件内容解析成 JavaScript 对象数组。每个对象对应一行数据,每个属性对应一列数据。例如,如果我们加载了上面提到的 CSV 文件,D3.js 将返回以下数组:

javascript 复制代码
[
  {
    "id": "1142669584",
    "用户名": "淇桐糯米饭啦",
    "城市": "来宾",
    "评分": "5",
    "评论": "剧情非常有吸引力,看个动画片给了我惊喜",
    "评论时间": "2021-08-31 23:56:30"
   }
]

在解析 CSV 数据后,我们可以对其进行操作和处理。看的出来数据集很大,有20584条数据。

数据可视化

可视化要求:

  1. 从 1.5 分开始,每 0.5 分设置一个等级,分别统计每个评分等级下的人数,绘制柱状。
  2. 要求柱状图添加比例尺、坐标轴和渐变颜色标尺。
  3. 将每个等级的人数与总人数的占比计算出来,绘制饼图。并添加标注即可。
js 复制代码
const div = d3.select('#svg-container');
let svg = div
    .append('svg')
    .attr('width', 1000)
    .attr('height', 500)

// 定义一个对象,key是评分,value是对应的等级
const levelMap = {
    '5': 7,
    '4.5': 6,
    '4': 5,
    '3.5': 4,
    '3': 3,
    '2.5': 2,
    '2': 1,
    '1.5': 0
};

// 定义一个数组,用来存储每个等级的人数 
let level = [
    { name: '1.5', count: 0, dy: -30 },
    { name: '2.0', count: 0, dy: 0 },
    { name: '2.5', count: 0, dy: 30 },
    { name: '3.0', count: 0, dy: 60 },
    { name: '3.5', count: 0, dy: 80 },
    { name: '4.0', count: 0, dy: 75 },
    { name: '4.5', count: 0, dy: 0 },
    { name: '5.0', count: 0, dy: 0 }
];

// 遍历数据,将每个等级的人数加1
data.forEach(d => {
    let score = d.评分;
    let levelIndex = levelMap[score];
    level[levelIndex] && level[levelIndex].count++;
});
// 定义一个div,用来显示提示信息
const tips = div.append("div")
    .style("position", "absolute")
    .style("border-radius", "5px")
    .style("padding", "10px")
    .style("opacity", 0)
    .style("font-size", "12px")
    .style("color", "#fff")
    .style("background", "rgba(0,0,0,0.6)")
    .style("pointer-events", "none")
    .style("border", "1px solid #666")
  1. 使用d3.csv()方法读取数据文件data.csv,并在读取成功后调用回调函数。
  2. 在回调函数中,首先使用console.log()方法打印读取到的数据data,以便查看数据。
  3. 接着定义一个对象levelMap,用来将每个评分映射为对应的等级。例如,5分评分对应等级7,4.5分评分对应等级6,以此类推。
  4. 定义一个数组level,用来存储每个等级的人数,并为每个等级添加对应的名称、人数和dy属性。
  5. 遍历数据,对于每个数据项,根据其评分获取对应的等级索引,然后将该等级的人数加1。
  6. 定义一个div元素tips,用来显示鼠标悬停提示信息,并设置其样式。

绘制柱状图

  1. 使用level.reverse()方法将等级数组level翻转,以便按从高到低的顺序显示等级。

  2. 定义画布的宽度、高度和内边距。

  3. 使用svg.append('defs')方法定义一个线性渐变,用来填充矩形的颜色。

  4. 使用svg.append('text')方法添加标题、坐标轴标签和单位标签。

  5. 使用d3.max()方法获取等级数组中人数最多的等级,并使用d3.scaleLinear()和d3.scaleBand()方法定义x轴和y轴的比例尺。

  6. 使用d3.axisBottom()和d3.axisLeft()方法定义x轴和y轴的刻度,并使用svg.append('g')方法添加坐标轴。

  7. 使用svg.append('g')方法添加矩形和文本元素,并使用d3.event对象和鼠标事件监听器实现鼠标悬停提示功能。

绘制饼图

  1. 定义变量和数据:首先,代码定义了一些变量,如宽度、高度、半径等,并创建了一个包含数据的数组。

  2. 创建饼状图数据和形状:接下来,代码使用d3.pie()函数根据数据创建了饼状图的数据,然后使用d3.arc()函数创建了饼状图的形状。

  3. 设置颜色比例尺:代码定义了一个颜色比例尺,用于根据数据的名称设置每个部分的颜色。

  4. 绘制饼状图:在绘制饼状图的过程中,代码使用了mousemove和mouseout事件监听器,当鼠标在饼状图上移动时,会更新提示框的内容和位置;当鼠标离开饼状图时,提示框会被隐藏。同时,还使用了polyline和text元素绘制了饼状图的边框和标签。

  5. 创建图例:最后,代码创建了一个图例(legend),用于显示每个部分的名称。图例中的矩形和文本元素分别表示饼状图的各个部分和它们的名称。

参考文章

关于图的绘制和交互效果文章不再描述,可以参考我之前发布的文章。

  1. 【d3.js入门】基本柱状图
  2. 【d3.js入门】基本柱状图动画
  3. 【d3.js入门】使用Tooltip增强数据可视化效果

建议

多翻翻我的《D3.js可视化实战》专栏的文章,点赞 关注 收藏。


相关推荐
一袋米扛几楼989 分钟前
【Git】规范化协作:详解 GitHub 工作流中的 Issue、Branch 与 Pull Request 最佳实践
前端·git·github·issue
网络点点滴22 分钟前
前端与后端的区别与联系
前端
EnCi Zheng1 小时前
M5-markconv自定义CSS样式指南 [特殊字符]
前端·css·python
kyriewen1 小时前
你的网页慢,用户不说直接走——前端性能监控教你“读心术”
前端·性能优化·监控
广州华水科技1 小时前
北斗GNSS变形监测在大坝安全监测中的应用与优势分析
前端
前端老石人1 小时前
前端开发中的 URL 完全指南
开发语言·前端·javascript·css·html
CAE虚拟与现实1 小时前
五一假期闲来无事,来个前段、后端的说明吧
前端·后端·vtk·three.js·前后端
Sarvartha1 小时前
三目运算符
linux·服务器·前端
晓晨的博客1 小时前
ROS1录制的bag包转换为ROS2格式
前端·chrome
Wect1 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·typescript