【D3.js in Action 3 精译_038】4.2 D3 折线图的绘制方法及曲线插值处理

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 第一部分 D3.js 基础知识
    • 第一章 D3.js 简介(已完结)
      • 1.1 何为 D3.js?
      • 1.2 D3 生态系统——入门须知
      • 1.3 数据可视化最佳实践(上)
      • 1.3 数据可视化最佳实践(下)
      • 1.4 本章小结
    • 第二章 DOM 的操作方法(已完结)
      • 2.1 第一个 D3 可视化图表
      • 2.2 环境准备
      • 2.3 用 D3 选中页面元素
      • 2.4 向选择集添加元素
      • 2.5 用 D3 设置与修改元素属性
      • 2.6 用 D3 设置与修改元素样式
      • 2.7 本章小结
    • 第三章 数据的处理(已完结)
      • 3.1 理解数据
      • 3.2 准备数据
      • 3.3 将数据绑定到 DOM 元素
        • 3.3.1 利用数据给 DOM 属性动态赋值
      • 3.4 让数据适应屏幕
        • 3.4.1 比例尺简介(上篇)
        • 3.4.2 线性比例尺(中篇)
          • 3.4.2.1 基于 Mocha 测试 D3 线性比例尺(DIY 实战)
        • 3.4.3 分段比例尺(下篇)
          • 3.4.3.1 使用 Observable 在线绘制 D3 条形图(DIY 实战)
      • 3.5 加注图表标签(上篇)
        • 3.5.1 人物专访:Krisztina Szűcs(下篇)
      • 3.6 本章小结
    • 第四章 直线、曲线与弧线的绘制 ✔️
      • 4.1 坐标轴的创建(上篇)
        • 4.1.1 D3 中的边距约定(中篇)
        • 4.1.2 坐标轴的生成(中篇)
          • 4.1.2.1 比例尺的声明(中篇)
          • 4.1.2.2 坐标轴的添加(下篇)
          • 4.1.2.3 轴标签的添加(下篇)
      • 4.2 D3 折线图的绘制 ✔️
        • 4.2.1 直线生成工具的使用 ✔️
        • 4.2.2 对数据点作曲线插值处理 ✔️
      • 4.3 D3 面积图的绘制

文章目录

    • 4.2 折线图的绘制 Drawing a line chart
      • 4.2.1 直线生成工具的使用 Using the line generator
      • 4.2.2 对数据点作曲线插值处理 Interpolating data points into a curve

《D3.js in Action》全新第三版封面

《D3.js in Action》全新第三版封面

译者按
上一节我们学习了 D3 时间坐标轴与线性轴的绘制方法,这一节就可以正式开始折线图的绘制了,根据最终的示例效果,该折线图包含折线部分和面积图部分,本篇只涉及纯折线部分;面积图的实现则放到下一节介绍。

4.2 折线图的绘制 Drawing a line chart

下面实现数据可视化最常见的一类图表:折线图。折线图由连接各数据点的线段、或对这些数据点作插值计算而得到的曲线组成。它们通常用于展示某个现象随时间的演变过程。在 D3 中,这些线条和曲线由 SVG 路径元素(path elements)构建,其形状由 SVG 路径元素的 d 属性(attribute)决定。通过第 1 章的学习,我们知道了 d 属性是由一系列命令组成的;这些命令决定了绘制的形状。此外还提到过,d 属性很容易变得很复杂。所幸 d3-shape 模块提供了生成直线和曲线的工具函数,专门负责 d 属性的计算,从而简化了折线图的创建。

本节将绘制一条反映 2021 年纽约市平均气温变化趋势的直线/曲线,具体效果参考线上项目(http://mng.bz/5orB)或前面章节中的图 4.1。在此之前,先来绘制每个数据点。尽管折线图未必非要画出数据点,但它们有助于理解 D3 折线生成工具的工作原理。

由于专栏文章是分章节发表,这里直接给出图 4.1 的效果:

图 4.1 本章实现项目:2021 年纽约市温度变化及全年降水天数占比情况可视化

【图 4.1 本章实现项目:2021 年纽约市温度变化及全年降水天数占比情况可视化】

在函数 drawLineChart() 中,通过 D3 的数据绑定为数据集 weekly_temperature.csv 中的每一行创建一个 circle 元素,然后添加到选择集 innerChart 中,半径设为 4px。然后用 xy 方向的比例尺分别计算每个圆心的横纵坐标。

回忆一下第 3 章介绍的数据绑定相关知识点,这里需要用到访问器函数(accessor function)来访问每个圆上的绑定数据。在以下代码片段中,d 即为每个 circle 元素绑定的数据项。由于 data 是一个 JavaScript 对象,这里可以通过句点表示法拿到对应的日期和平均气温。相关知识点详见第 3 章 3.3.1 小节。

注意,这里特地声明了一个名为 aubergine (译注:读作 /ˈəʊbəʒiːn/,紫红色)的颜色常量,用于指定圆的 fill 属性值。因为示例项目还会多次用到该颜色,因此单独声明为一个常量。您也可以根据自己的喜好启用任意颜色:

const aubergine = "#75485E";
innerChart.selectAll("circle") // 利用数据绑定模式为数据集中的每一行添加一个圆.data(data)          .join("circle")      .attr("r", 4).attr("cx", d => xScale(d.date)) // 根据绑定数据使用比例尺来定位数据点.attr("cy", d => yScale(d.avg_temp_F)) .attr("fill", aubergine);

保存项目并在浏览器中查看图形,就能看到这些 circle 元素呈穹顶状分布于 29°F80°F 之间,如图 4.13 所示:

图 4.13 平均气温随时间变化的数据点绘制效果图

【图 4.13 平均气温随时间变化的数据点绘制效果图】

此处也可以绘制散点图(scatterplots)

走到这一步必须要强调的一个惊喜是,您已经在不知不觉间学会了 D3 散点图(scatterplots)的绘制!散点图 是一种简单的图表,用于展示 x 轴与 y 轴的数据点集合,可以直观地揭示两个或多个变量间的相关关系。

只要知道了坐标轴的绘制方法,再结合绑定数据定位屏幕上的每个数据点,您就完全可以绘制出一个散点图效果——这正是 D3 的魅力所在——不必特地去学怎样绘制特定的图表类型,而是通过创建并组合一些基本要素来构建可视化效果。对于散点图而言,这些基本要素甚至可以简单到仅仅包含两个坐标轴和一组 circle 元素。第 7 章我们还将实现一个散点图,让圆的面积根据变量的值而同步变化。

图 4.13.1 D3 散点图示例效果

【图 4.13.1 D3 散点图示例效果】

4.2.1 直线生成工具的使用 Using the line generator

至此,每个数据点的位置就画好了,接下来介绍 D3 的直线生成工具(line generator)。直线生成工具 d3.line() 是一个函数,它以各数据点的横纵坐标为输入,并将穿过这些数据点的 SVG 路径元素或折线(polyline)的 d 属性值作为输出。通常需要在直线生成器上链式调用 x()y() 两个访问器函数,并分别传入水平和垂直位置的坐标值,如图 4.14 所示:

图 4.14 直线生成工具 d3.line() 函数与访问器函数 x() 和 y() 的组合式写法。后者需分别将各数据点的横纵坐标作为参数传入。

【图 4.14 直线生成工具 d3.line() 函数与访问器函数 x() 和 y() 的组合式写法。后者需分别将各数据点的横纵坐标作为参数传入。】

下面来给折线图创建一个直线生成工具函数。首先调用 d3.line() 方法,然后分别链式调用访问器函数 x()y()x() 需要传入各数据点的水平坐标,这里通过参数 d 来访问每个绑定数据项,类似遍历数组时用到的循环变量。数据点的水平坐标可以通过对应的日期和水平比例尺函数 xScale() 计算得出;同理,垂直坐标则可以通过当天的平均气温结合纵向比例尺 yScale() 得到。最后将生成的工具函数赋给常量 lineGenerator 备用:

const lineGenerator = d3.line().x(d => xScale(d.date)) // 每个数据点的水平位置.y(d => yScale(d.avg_temp_F)); // 每个数据点的垂直位置

接着,调用该工具函数,并将数据集 data 作为参数传入,其结果作为 path 元素 d 属性的属性值。

SVG 路径元素默认按黑色渲染图形,如果只想看到一条折线,则需要令 fill 属性为 nonetransparent,并将 stroke 属性(attribute)指定为想要的描边色;本例中即为 aubergine 紫红色。绘制效果如图 4.15 所示:

innerChart.append("path").attr("d", lineGenerator(data)) // 利用行生成工具将数据集作为参数传入.attr("fill", "none").attr("stroke", aubergine);

图 4.15 利用 D3 直线生成工具创建的 SVG 路径元素穿过每个数据点,形成了一条折线

【图 4.15 利用 D3 直线生成工具创建的 SVG 路径元素穿过每个数据点,形成了一条折线】

4.2.2 对数据点作曲线插值处理 Interpolating data points into a curve

在这个示例折线图中,离散数据点分布在整个数据范围内,用普通的折线段来连接数据点就能实现既定目标;但偶尔也会在数据点之间对数据作插值处理 1。为此,D3 提供了多种插值函数(interpolation functions)来生成曲线。

曲线生成工具是以 d3.line() 的访问器函数的形式出现的。要将刚才的直线工具函数变为曲线工具函数,只需要再链式调用一个访问器函数 curve() 即可,参数为 D3 的某个内置插值函数。如以下代码片段所示,传入参数为 d3.curveCatmullRom 2,它可以生成一个 立方样条曲线(cubic spline) (根据各数据点并结合三阶多项式函数计算得到的平滑而灵活的图形)。其渲染效果如图 4.16 所示。

const curveGenerator = d3.line().x(d => xScale(d.date)).y(d => yScale(d.avg_temp_F).curve(d3.curveCatmullRom);

图 4.16 利用 Catmull-Rom 插值算法绘制的折线图效果

【图 4.16 利用 Catmull-Rom 插值算法绘制的折线图效果】

关于最佳插值算法 What’s the best interpolation?

插值处理会修改数据呈现方式,不同的插值函数会产生不同的可视化效果。数据的可视化方式多种多样,从编程角度理解,这些方式方法都是合理的;但关键是让可视化效果传递客观实际(actual phenomena)。

由于数据可视化涉及统计原理的视觉呈现,因此也面临着误用统计数据带来的风险(dangers of misusing statistics)。其中线性插值是数据误用的重灾区,因为它能将看似粗糙的直线段处理成平滑自然的曲线段。

如图 4.17 所示,同一组折线数据在不同的曲线插值处理下将呈现不同的视觉效果。选择适当的插值函数很大程度上取决于目标数据集。在本节演示的折线图中,d3.curveBasis 会拉直曲线段的同时减少其变化,这显然不适合我们的示例数据。如果不在图表上绘制出数据点作对比,就无从知晓曲线段与这些数据点的误差。因此,甄选和测试曲线插值函数就显得尤为重要了。

图 4.17 不同的曲线插值处理对数据都有不同程度地修改

【图 4.17 不同的曲线插值处理对数据都有不同程度地修改】

与此同时,函数 d3.curveMonotoneXd3.curveCatmullRom 创建的插值曲线则紧挨数据点,与原始折线图相似;此外,d3.curveStep 函数还可以在适当的情况下对数据作另类处理。图 4.17 只给出了部分插值情况对比,还有一些插值工具还可以设置一些影响最终曲线形状的参数,具体配置情况,详见 d3-shape 模块相关文档。

这样 D3 折线图的绘制就完成了!再复盘梳理一下:首先需要初始化一个直线生成工具函数,并设置其访问函数 x()y(),如图 4.18 所示。这两个函数分别用于计算每个数据点的水平与垂直坐标;接着可以链式调用 curve() 访问器函数并指定插值算法,将直线段改为曲线段;最后,在绘图区添加 SVG 路径元素 path,并通过调用直线生成工具函数、传入数据集 data 来设置路径元素的 d 属性。第 7 章还将利用工具提示(tooltip)组件提升折线图的可交互性。如果想立即学习,也可以直接跳到该章节(译注:待翻译)。

图 4.18 D3 折线图的实现步骤

【图 4.18 D3 折线图的实现步骤】


  1. 插值 是一个数学和统计学领域的专用术语,指的是在已知数据点之间估算出新的数据点,常用于图表或曲线的平滑处理。 ↩︎

  2. d3.curveCatmullRomCatmull-Rom 样条,也叫 卡特穆尔-罗姆插值,它在计算机图形学和数据可视化领域应用广泛,是一种能够有效生成平滑曲线的数学方法描述。所谓样条(Spline),则是一种由多段多项式函数组成的分段函数,用于平滑地连接一组给定的点(即控制点)。样条通过一组控制点来定义,它们通常是数据的离散采样值。 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/8433.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

测试-正交表与工具pairs的介绍使用(1)

目录 正交表 生成正交表 步骤 实操 注意事项 编写测试用例 根据正交表编写测试用例 补充遗漏的重要测试用例 正交表 关于长篇大论也不多介绍了,我们只需要知道正交法的⽬的是为了减少⽤例数⽬,⽤尽量少的⽤例覆盖输⼊的两两组合 正交表的构成&…

抗晃电马达保护器在工业厂房中的应用

安科瑞刘鸿鹏 摘要 随着工业自动化水平的提高,生产线上电动机作为关键设备的使用频率不断增加。然而,工厂生产环境中的电力波动,尤其是晃电现象,会对电动机的正常运转造成干扰,甚至导致设备停机和生产中断。抗晃电型…

linux之调度管理(2)-调度器 如何触发运行

一、调度器是如何在程序稳定运行的情况下进行进程调度的 1.1 系统定时器 因为我们主要讲解的是调度器,而会涉及到一些系统定时器的知识,这里我们简单讲解一下内核中定时器是如何组织,又是如何通过通过定时器实现了调度器的间隔调度。首先我们…

RHCE循环执行的例行性任务--crontab(周期性)

1.每分钟执行命令 2.每小时执行 3.每天凌晨3点半和12点半执行脚本 4.每隔6小时,相当于6,12,18,24点半执行脚本 5.30半点,8-18/2表示早上8点到下午18点之间每隔2小时执行脚本代表 6.每天晚上9点30重启nginx 7.每月1号和10号4点45执行脚本 8. 每周六和周日…

ETLCloud异常问题分析ai功能

在数据处理和集成的过程中,异常问题的发生往往会对业务运营造成显著影响。为了提高ETL(提取、转换、加载)流程的稳定性与效率,ETLCloud推出了智能异常问题分析AI功能。这一创新工具旨在实时监测数据流动中的潜在异常,自…

Java项目实战II基于Spring Boot的个人云盘管理系统设计与实现(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 基于Spring Boot的个人云盘管理系统设计…

还在为慢速数据传输苦恼?Linux 零拷贝技术来帮你!

前言 程序员的终极追求是什么?当系统流量大增,用户体验却丝滑依旧?没错!然而,在大量文件传输、数据传递的场景中,传统的“数据搬运”却拖慢了性能。为了解决这一痛点,Linux 推出了 零拷贝 技术&…

密码学是如何保护数据传输的安全性?

密码学通过一系列算法和协议来保护数据传输的安全性。 一、加密技术 对称加密算法 原理:使用相同的密钥进行加密和解密。应用:在数据传输过程中,发送方和接收方共享一个密钥,数据在传输前被加密,接收方使用相同的密钥…

python怎么打开py文件

1、首先在资源管理器里复制一下py文件存放的路径,按下windows键+r,在运行里输入cmd,回车打开命令行: 2、在命令行里,先切换到py文件的路径下面,接着输入“python 文件名.py ”运行python文件&a…

云计算——ACA学习 云计算核心技术

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​ 写在前面 本系列将会持续更新云计算阿里云ACA的学习,了解云计算及网络安全相关…

企业办公管理软件排名 | 九款企业管理软件助你制胜职场!(好用+实用+全面)

在寻找合适的企业办公管理软件时,你是否感到困惑不已,不知道从众多选项中选择哪一个? 一款好的管理软件不仅能简化工作流程,还能增强数据安全性,优化决策支持。 以下是九款备受推崇的企业管理软件,它们将助…

DNS服务器

DNS服务器 1、简介 DNS域名解析服务器,它作为将域名和IP地址相互映射的一个分布式数据库,端口号为53,通常使用UDP协议,但是在没有查询到完整的信息时,会以TCP这个协议来重新查询,所以在启动NDS服务器时&a…

顾荣辉在新加坡金融科技节发表主旨演讲:安全不仅是竞争优势,更是共同责任

在全球数字化和去中心化进程中,Web3的作用日益凸显,安全问题也日益成为行业的焦点。在这一背景下,顾荣辉教授于新加坡金融科技节(SFF)上发表主旨演讲《超越代码,引领信任》。顾教授在演讲中深入阐述了安全在…

Leetcode328奇偶链表,Leetcode21合并两个有序链表,Leetcode206反转链表 三者综合题

题目描述 思路分析 这题的思路就和我们的标题所述一样,可以看作是这3个题的合并,但是稍微还有一点点区别 比如:奇偶链表这道题主要是偶数链在了奇数后面,字节这个的话是奇偶链表分离了 所以字节这题的大概思路就是: …

「Mac玩转仓颉内测版1」入门篇1 - Cangjie环境的搭建

本篇详细介绍在Mac系统上快速搭建Cangjie开发环境的步骤,涵盖VSCode的下载与安装、Cangjie插件的离线安装、工具链的配置及验证。通过这些步骤,确保开发环境配置完成,为Cangjie项目开发提供稳定的基础支持。 关键词 Cangjie开发环境搭建VSC…

2023数学分析【南昌大学】

计算 求极限 lim ⁡ n → ∞ ( 1 n 2 + 1 2 + 1 n 2 + 2 2 + ⋯ + 1 n 2 + n 2 ) \mathop{\lim }\limits_{n \to \infty } \left( \frac{1}{{\sqrt {n^2 + 1^2} }} + \frac{1}{{\sqrt {n^2 + 2^2} }} + \cdots + \frac{1}{{\sqrt {n^2 + n^2} }} \right) n→∞lim​(n2+12 ​1…

从技术创新到商业应用,智象未来(HiDream.ai)创新不止步

在人工智能领域的最新动态中,智象未来(HiDream.ai)公司,作为全球领先的多模态生成式人工智能技术先驱,已经引起了广泛的行业瞩目。该公司专注于深度学习和计算机视觉技术的融合,致力于开发和优化视觉多模态…

ssm基于Vue的戏剧推广网站+vue

系统包含:源码论文 所用技术:SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习,获取源码看文章最下面 需要定制看文章最下面 目 录 摘 要 I Abstract II 第1章 绪论 1 1.1 课题背景 1 1.2 课题意义 1 1.3 研究内容 1 第2…

利用泰勒公式近似计算10的平方根

文章目录 1. 泰勒公式是什么2、利用泰勒公式计算 10 \sqrt{10} 10 ​第 1 步:泰勒级数展开第 2 步:计算各阶导数第 3 步:在 x 9 x 9 x9 处计算各阶导数第 4 步:构建各阶泰勒展开式第 5 步:计算 f ( 10 ) f(10) f(1…

AI芯片:推动高性能计算场景的关键力量

​ 大家好,我是Shelly,一个专注于输出AI工具和科技前沿内容的AI应用教练,体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具,拥抱AI时代的到来。 AI工具集1:大厂AI工具【共2…