当前位置: 首页 > news >正文

【D3.js in Action 3 精译_039】4.3 D3 面积图的绘制方法及其边界标签的添加

当前内容所在位置:

  • 第四章 直线、曲线与弧线的绘制 ✔️
    • 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.3.1 面积图生成工具的用法 ✔️
      • 4.3.2 用标签提高图表的可读性 ✔️
    • 4.4 D3 弧形图的绘制

文章目录

    • 4.3 面积图的绘制 Drawing an area
      • 4.3.1 面积图生成工具的用法 Using the area generator
      • 4.3.2 用标签提高图表的可读性 Enhancing readability with labels

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

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

译者按
由于 D3 的折线图和面积图在实现方式上相似度极高,这一篇就趁热打铁,将示例折线图剩下的面积图部分一并学完。看似复杂的面积图在作者精心绘制的示意图的帮助下变得非常简单(至少比我的其他专栏要容易很多),曾在 MSOffice 中盛行的“字不如表、表不如图”的说法用到 D3 数据可视化上依然适用。如果早几年出现这样的扫盲级 D3 参考书,如今国内数据可视化领域 ECharts 一手遮天的局面没准还真能被打破。一起学起来吧!

4.3 面积图的绘制 Drawing an area

本节将实现示例折线图后方的面积图部分,用于展示每个日期最低气温与最高气温的波动范围。D3 绘制面积图的方法与绘制折线图类似,也是通过 SVG 的路径元素来创建。D3 还专门提供了面积图生成工具函数 d3.area() 来处理路径 d 属性的复杂运算。

动手绘制前还需要注意一点:示例中的面积图位于折线图的 后方(behind the line chart)。鉴于屏幕元素的渲染顺序与添加到 SVG 父容器的元素顺序保持一致,因此该面积区域的实现代码应该添加到创建折线图的代码 前面

4.3.1 面积图生成工具的用法 Using the area generator

首先声明一个面积图生成工具函数(area generator function),并赋给常量 areaGenerator。根据以下示例代码,面积生成工具至少需要三个访问器函数(accessor functions)。一是 x(),用于计算数据点的水平坐标,与直线生成工具完全相同;垂直方向上则略有不同,数据点从一组变为了两组,分别对应面积区域的上下边缘,因此需要设置 y0()y1() 两个访问器函数。注意,示例面积图中的上下边缘数据点具有相同的水平坐标:

const areaGenerator = d3.area().x(d => xScale(d.date)).y0(d => yScale(d.min_temp_F)).y1(d => yScale(d.max_temp_F));

图 4.19 生动直观地展示了面积区域的下边界和上边界情况,以及面积生成工具对相关数据的计算处理过程:

图 4.19 面积生成工具 d3.area() 与三个及更多访问器函数的组合用法示意图。绘制最高最低气温构成的温差区域,需要用到 x()、y0() 和 y1(),分别用于计算各数据点的水平坐标、面积区下边界(即当日最低气温)的垂直坐标、以及面积区上边界(即当日最高气温)的垂直坐标。

【图 4.19 面积生成工具 d3.area() 与三个及更多访问器函数的组合用法示意图。绘制最高最低气温构成的温差区域,需要用到 x()、y0() 和 y1(),分别用于计算各数据点的水平坐标、面积区下边界(即当日最低气温)的垂直坐标、以及面积区上边界(即当日最高气温)的垂直坐标。】

与折线图类似,我们同样可以在面积生成工具函数上链式调用访问器函数 curve() 来对面积图的上下边缘作曲线插值处理,这里还是沿用上一节介绍过的 D3 内置插值函数 d3.curveCatmullRom,如以下代码所示:

const areaGenerator = d3.area().x(d => xScale(d.date)).y0(d => yScale(d.min_temp_F)).y1(d => yScale(d.max_temp_F)).curve(d3.curveCatmullRom);

面积生成器准备就绪后,就可以在内部图表选择集上添加一个 SVG 路径元素。该元素的 d 属性,可以通过刚才备好的面积生成器计算得到,传入参数为数据集 data。剩下的都是一些与审美相关的属性设置:填充色通过 fill 属性实现,属性值就是前面声明过的紫红色常量 aubergine;为了让面积区域与折线部分清晰可辨,可以给面积图加一点透明度,指定其 fill-opacity 属性为 20%,最终渲染效果如图 4.20 所示。注意,颜色常量 aubergine 必须先声明再使用:

innerChart.append("path").attr("d", areaGenerator(data)).attr("fill", aubergine) // 即 "#75485E".attr("fill-opacity", 0.2);

图 4.20 由折线图表示的日均气温与面积图表示的当日气温波动范围的绘制效果图

【图 4.20 由折线图表示的日均气温与面积图表示的当日气温波动范围的绘制效果图】

可以看出,D3 面积图的绘制过程与折线图的绘制十分类似。二者的主要区别在于,折线图只有一组数据点,用直线段进行绘制;而面积图需要处理上下两个边缘,每个边缘对应一组数据点。这就是直线生成器函数只需要两个访问器函数(即 x()y())、而面积生成器需要至少三个访问器函数(本例即为 x()y0()y1())的根本原因,如图 4.21 所示:

图 4.21 D3 面积图的绘制步骤

【图 4.21 D3 面积图的绘制步骤】

4.3.2 用标签提高图表的可读性 Enhancing readability with labels

至此,我们实现了 2021 年纽约市日均气温的折线图的绘制,并同步展示了当日最低气温与最高气温的变化区域,效果看上去已经很不错了;但我们还需要确保看到这张图表的人们能够轻松准确地理解折线与面积的含义。添加图表标签(label)就是个不错的想法。

前面学过,图表标签不过是放置在可视化作品里的 SVG 文本元素。在本例中,不妨创建三个标签,分别用于表示折线图末尾的平均气温、位置靠下的当日最低气温、以及靠上放置的当日最高气温。

先从折线图标签开始。先将 SVG 文本元素添加到内部图表选择集中,然后调用 text() 方法设置标签文本为 "Average temperature"(即“平均气温”);接着通过 xy 属性设置标签在绘图区内的坐标。

我们希望标签位于折线图末尾,也就是最后一个数据点的后面;其水平坐标可以通过先前声明的常量 lastDate 由水平比例尺函数 xScale() 算得;另外可以再给标签一个 10px 的间距。

而垂直坐标的计算还需要一个当天的平均气温值,可以先通过 data[data.length - 1] 获取到最后一个数据点;然后利用句点标识符拿到对应的平均气温;接着再调用垂直比例尺函数 yScale() 算得该数据点的垂直坐标。最后复用颜色常量 aubergine,通过 fill 属性来指定标签文本的颜色,如以下代码所示:

innerChart.append("text").text("Average temperature").attr("x", xScale(lastDate) + 10).attr("y", yScale(data[data.length - 1].avg_temp_F)).attr("fill", aubergine);

如果保存项目并在浏览器中查看效果,会发现文本标签的底边与折线图最后一个数据点的中心垂直对齐了。默认情况下,SVG 文本元素的基准线(baseline)位于文本的底边位置,如图 4.22 (左图)所示。这时可以使用 dominant-baseline 属性来手动修改。如以下代码所示,将该属性值设为 middle,基准线就改到了文本的中心位置:

innerChart.append("text").text("Average temperature").attr("x", xScale(lastDate) + 10).attr("y", yScale(data[data.length - 1].avg_temp_F)).attr("dominant-baseline", "middle").attr("fill", aubergine);

图 4.22 SVG 文本元素的 y 属性可设置其基准线在垂直方向的位置,默认位置在文本底边。可通过 dominant-baseline 进行修改,值为 middle 时基准线与文本中心对齐;值为 hanging 时基准线则位于文本顶部。

【图 4.22 SVG 文本元素的 y 属性可设置其基准线在垂直方向的位置,默认位置在文本底边。可通过 dominant-baseline 进行修改,值为 middle 时基准线与文本中心对齐;值为 hanging 时基准线则位于文本顶部。】

接着再给面积图的下边界添加一个文本标签,代表最低温度的变化趋势。具体做法与刚才一样,先添加一个 SVG 文本元素,并指定文本内容为 "Minimum temperature",即最低气温。

至于标签的坐标方位,可以参考最后一个下凹点(downward protuberance),即下边缘倒数第三个数据点。将该位置的数据值传入垂直坐标尺函数,算得其垂直坐标,然后再下移 20px、右移 13px。这些位移量都是通过在页面上不断尝试不同的位置得到的;借助浏览器的检查工具(inspector tool)是处理这类微调操作的绝佳工具。注意,此时文本标签的 dominant-baseline 属性值改为了 hanging,如图 4.22 所示,表示 y 属性值是相对于文本的顶部而言的。

最后,根据以下代码片段,就能再给图表标签新增一条指示线,将面积图的下凹拐点与标签进行关联,进一步明确标签所代表的含义,如图 4.23 所示。同理,可以使用比例尺分别计算指示线的 x1y1x2y2 属性值,最终确定出线段的起点和终点位置:

innerChart.append("text").text("Minimum temperature").attr("x", xScale(data[data.length - 3].date) + 13).attr("y", yScale(data[data.length - 3].min_temp_F) + 20).attr("alignment-baseline", "hanging").attr("fill", aubergine);
innerChart.append("line").attr("x1", xScale(data[data.length - 3].date)).attr("y1", yScale(data[data.length - 3].min_temp_F) + 3).attr("x2", xScale(data[data.length - 3].date) + 10).attr("y2", yScale(data[data.length - 3].min_temp_F) + 20).attr("stroke", aubergine).attr("stroke-width", 2);

同理也可以给面积区的上边缘添加类似的文本标签,用以表示当日最高气温的变化情况。上边缘标签的定位可以参考其倒数第四个数据点的上凸拐点。然后用相同的手法在标签和上凸拐点间绘制一条指示线,如以下代码片段所示:

innerChart.append("text").text("Maximum temperature").attr("x", xScale(data[data.length - 4].date) + 13).attr("y", yScale(data[data.length - 4].max_temp_F) - 20).attr("fill", aubergine);
innerChart.append("line").attr("x1", xScale(data[data.length - 4].date)).attr("y1", yScale(data[data.length - 4].max_temp_F) - 3).attr("x2", xScale(data[data.length - 4].date) + 10).attr("y2", yScale(data[data.length - 4].max_temp_F) - 20).attr("stroke", aubergine).attr("stroke-width", 2);

这样就完成了折线图部分的绘制:

图 4.23 绘制完毕的 2021 年纽约市全年日均气温及其变化趋势效果图

【图 4.23 绘制完毕的 2021 年纽约市全年日均气温及其变化趋势效果图】



另附:专栏文章连载期间 完全免费,后续 不排除 调整为收费专栏。对 D3.js 感兴趣、或者想要从零开始彻底掌握 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 本章小结

相关文章:

【D3.js in Action 3 精译_039】4.3 D3 面积图的绘制方法及其边界标签的添加

当前内容所在位置: 第四章 直线、曲线与弧线的绘制 ✔️ 4.1 坐标轴的创建(上篇) 4.1.1 D3 中的边距约定(中篇)4.1.2 坐标轴的生成(中篇) 4.1.2.1 比例尺的声明(中篇)4.1…...

布谷直播源码部署服务器关于数据库配置的详细说明

布谷直播源码搭建部署配置接口数据库 /public/db.php(2019年8月后的系统在该路径下配置数据库,老版本继续走下面的操作) 在项目代码中执行命令安装依赖库(⚠️注意:如果已经有了vendor内的依赖文件的就不用执行了&am…...

Xfce桌面设置右键菜单:用右键打开VSCode

前言 AlmaLinux安装VSCode之后始终没有找到如何用右键菜单打开VSCode,比Windows麻烦多了。每次都需要先找到文件夹,然后用系统自带的Open In Terminal打开终端,再输入code .,才能够在当前文件夹中快速打开VSCode。那么&#xff0…...

【NLP自然语言处理】深入探索Self-Attention:自注意力机制详解

目录 🍔 Self-attention的特点 🍔 Self-attention中的归一化概述 🍔 softmax的梯度变化 3.1 softmax函数的输入分布是如何影响输出的 3.2 softmax函数在反向传播的过程中是如何梯度求导的 3.3 softmax函数出现梯度消失现象的原因 &…...

Pytorch训练时报nan

0. 引言 Pytorch训练时在batchN时loss为nan。经过断点检查发现在batchN-1时,网络参数非nan,输出非nan,但梯度为nan,导致网络参数已经全部被更新为nan,遇到这种情况应该如何排查,如何避免?由于导…...

JavaScript定时器详解:setTimeout与setInterval的使用与注意事项

在JavaScript中,定时器用于在指定的时间间隔后或周期性地执行代码。JavaScript 提供了两种主要的定时器函数:setTimeout 和 setInterval。以下是它们的详细解释和实现方式: 1. setTimeout setTimeout 函数用于在指定的毫秒数后执行一次函数…...

CSS——选择器、PxCook软件、盒子模型

选择器 结构伪类选择器 作用&#xff1a;根据元素的结构关系查找元素。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…...

Mysql 大表limit查询优化原理实战

文章目录 1 大表查询无条件优化&原理(入门)2 大表查询带 条件 优化&原理(进阶)2.1 where 后面的查询字段只有一个时&#xff0c;要求该字段是索引字段2.2 where 后面的查询字段有多个时&#xff0c;尽量让查询字段为索引字段且字段值基数大 3 大表查询带 排序 优化&…...

在vscode中开发运行uni-app项目

确保电脑已经安装配置好了node、vue等相关环境依赖 进行项目的创建 vue create -p dcloudio/uni-preset-vue 项目名 vue create -p dcloudio/uni-preset-vue uni-app 选择模版 这里选择【默认模版】 项目创建成功后在vscode中打开 第一次打开项目 pages.json 文件会报错&a…...

【JavaEE初阶 — 多线程】Thread的常见构造方法&属性

目录 Thread类的属性 1.Thread 的常见构造方法 2.Thread 的几个常见属性 2.1 前台线程与后台线程 2.2 setDaemon() 2.3 isAlive() Thread类的属性 Thread 类是JVM 用来管理线程的一个类&#xff0c;换句话说&#xff0c;每个线程都有一个唯一的Thread 对象与之关联&am…...

ctfshow(316)--XSS漏洞--反射性XSS

Web316 进入界面&#xff1a; 审计 显示是关于反射性XSS的题目。 思路 首先想到利用XSS平台解题&#xff0c;看其他师傅的wp提示flag是在cookie中。 当前页面的cookie是flagyou%20are%20not%20admin%20no%20flag。 但是这里我使用XSS平台&#xff0c;显示的cookie还是这样…...

ubuntu22.04安装conda

在 Ubuntu 22.04 上安装 Conda 可以通过以下步骤进行&#xff1a; 下载 Miniconda&#xff08;轻量级版本的 Conda&#xff09;&#xff1a; 打开终端并运行以下命令以下载 Miniconda 安装脚本&#xff1a; wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-…...

D58【python 接口自动化学习】- python基础之异常

day58 异常捕获 学习日期&#xff1a;20241104 学习目标&#xff1a;异常 -- 74 自定义异常捕获&#xff1a;如何定义业务异常&#xff1f; 学习笔记&#xff1a; 自定义异常的用途 自定义异常的方法 # 抛出一个异常 # raise ValueError(value is error) # ValueError: val…...

Java项目实战II基于Spring Boot的便利店信息管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在快节奏的…...

Java-日期计算工具类DateCalculator

DateCalculator是用于日期计算的工具类。这个工具类将包括日期的加减、比较、周期计算、日期 范围生成等功能。 import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Period; import java.time.temporal.ChronoUnit;…...

单片机串口接收状态机STM32

单片机串口接收状态机stm32 前言 项目的芯片stm32转国产&#xff0c;国产芯片的串口DMA接收功能测试不通过&#xff0c;所以要由原本很容易配置的串口空闲中断触发DMA接收数据的方式转为串口逐字节接收的状态机接收数据 两种方式各有优劣&#xff0c;不过我的芯片已经主频跑…...

ipv6的 fc00(FC00::/7) 和 fec0(FEC0::/10)

ipv6的 fc00(FC00::/7)&#xff08;唯一本地地址&#xff09; 替代了 fec0(FEC0::/10) &#xff08;站点本地地址&#xff0c;已弃用&#xff09; ipv6的 fc00(FC00::/7) 替代了 fec0(FEC0::/10) , 在IPv6地址中&#xff0c;FC00::/7&#xff08;通常简写为FC00&#xff09;和…...

Chat GPT英文学术写作指令

目录 Chat GPT英文学术写作指令 Chat GPT英文学术写作指令 1."为我捉供一些建议和技巧,以提高我的学术写作质最和风格" (Provide me with some suggestions andtips to improve the quality andstyleofmyacademic writing.) 2."帮我提写一个清晰而有逻辑的…...

超详细Pycharm安装汉化教程,Python环境配置和使用指南,Python零基础入门看这个就够了!

包含编程资料、学习路线图、源代码、软件安装包等&#xff01;【[点击这里]】&#xff01; PyCharm 是由 JetBrains 打造的一款 Python IDE &#xff08;集成开发环境&#xff0c;Integrated Development Environment&#xff09;&#xff0c;带有一整套可以帮助用户在使用 Py…...

react-native:解决使用webView后部分场景在安卓10崩溃闪退问题

app闪退问题原因&#xff1a; 安卓7以上版本&#xff08;7和7以下版本不会出现闪退&#xff09;&#xff1a;在屏幕不可视区域加载webView或者webView不在可视区域内切换页面时app崩溃闪退&#xff08;在屏幕可视区域加载webView或者webView在可视区域内切换页面不会闪退&…...

大数据工具 flume 的安装配置与使用 (详细版)

参考网址&#xff1a;Flume 1.9用户手册中文版 — 可能是目前翻译最完整的版本了 1&#xff0c;上传安装包 安装包链接&#xff1a;文件下载-奶牛快传 Download &#xff5c;CowTransfer 口令&#xff1a;x8bhcg 1&#xff0c;切换盘符到安装目录 cd /opt/moudles 解压文件…...

智慧城市智慧城市项目方案-大数据平台建设技术方案(原件Word)

第1章 总体说明 1.1 建设背景 1.2 建设目标 1.3 项目建设主要内容 1.4 设计原则 第2章 对项目的理解 2.1 现状分析 2.2 业务需求分析 2.3 功能需求分析 第3章 大数据平台建设方案 3.1 大数据平台总体设计 3.2 大数据平台功能设计 3.3 平台应用 第4章 政策标准保障…...

C语言比较两个字符串是否相同

在不使用string.h中的内置函数的情况下 #include <stdio.h> #include <string.h> void main(){char arr1[]"hello world";char arr2[]"hello world";int i,a0;if(strlen(arr1)!strlen(arr2)){print("不相等");return 0;}for(i0;arr…...

丹摩征文活动|FLUX.1图像生成模型:AI工程师的创新实践

文章目录 一、对"FLUX.1"系列模型版本分析 二、AI工程师与FLUX.1系列模型 三、ComfyUI在线部署四、FLUX.1在线部署五、添加工作流呈现效果图展示六、总结 黑森林实验室&#xff08;Black Forest Labs&#xff09;推出的FLUX.1图像生成模型&#xff0c;凭借120亿参数的…...

ZABBIX API获取监控服务器OS层信息

Zabbix 是一款强大的开源监控解决方案,能够通过其 API 接口自动化管理和获取监控数据。在这篇文章中,详细讲解如何通过 Zabbix API 批量获取服务器的系统名称、IP 地址及操作系统版本信息,并将数据保存到 CSV 文件中。本文适合对 Python 编程和 Zabbix 监控系统有一定基础的…...

SpringBoot基础系列学习(五):JdbcTemplate 访问数据库

文章目录 一丶介绍二丶引入依赖三丶配置配置文件四丶创建表五丶java代码 一丶介绍 Spring Boot作为Spring的集大成者&#xff0c;自然会将JdbcTemplate集成进去。Spring Boot针对JDBC的使用提供了对应的Starter包&#xff1a;spring-boot-starter-jdbc&#xff0c;它其实就是在…...

JavaEE-多线程初阶(3)

目录 1.线程的状态 1.1 NEW、RUNNABLE、TERMINATED 1.2 TIMED_WAITING 1.3 WAITING 1.4 BLOCKED 2.多线程带来的风险-线程安全&#xff08;重点&#xff09; 2.1 观察线程不安全的现象 2.2 分析产生该现象的原因 2.3 产生线程安全问题的原因 2.3.1 抢占式执行&#x…...

从入门到精通:如何在Vue项目中有效运用el-image-viewer

Element UI之el-image-viewer组件详解 引言 在现代 Web 应用中,高质量的用户体验是不可或缺的一环。Element UI 作为一款基于Vue.js 2.0 的桌面端组件库,以其丰富的组件集、良好的文档和支持赢得了广大开发者的好评。本文将深入探讨el-image-viewer组件,这是一个用于在网页…...

uniapp组件实现省市区三级联动选择

1.导入插件 先将uni-data-picker组件导入我们的HBuilder项目中&#xff0c;在DCloud插件市场搜索uni-data-picker 点击下载插件并导入到我们的项目中 2.组件调用 curLocation &#xff1a;获取到的当前位置&#xff08;省市区&#xff09; <uni-data-picker v-slot:defa…...

【C++】异常处理机制(对运行时错误的处理)

&#x1f308; 个人主页&#xff1a;谁在夜里看海. &#x1f525; 个人专栏&#xff1a;《C系列》《Linux系列》 ⛰️ 天高地阔&#xff0c;欲往观之。 目录 引言 1.编译器可以处理的错误 2.编译器不能处理的错误 3.传统的错误处理机制 assert终止程序 返回错误码 一、…...