【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 本章小结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 PyCharm 构建 FastAPI 项目:零基础入门 Web API 开发

使用 PyCharm 构建 FastAPI 项目:零基础入门 Web API 开发 本文提供了一份完整的 FastAPI 入门指南,涵盖从环境搭建、依赖安装到创建并运行一个简单的 FastAPI 应用的各个步骤。通过 FastAPI 和 Uvicorn,开发者可以快速构建现代化的 Web API…

【综合算法学习】(第十六篇)

目录 岛屿的最⼤⾯积(medium) 题目解析 讲解算法原理 编写代码 被围绕的区域(medium) 题目解析 讲解算法原理 编写代码 岛屿的最⼤⾯积(medium) 题目解析 1.题目链接:. - 力扣&#xf…

qt QTabWidget详解

1、概述 QTabWidget是Qt框架中的一个控件,它提供了一个标签页式的界面,允许用户在不同的页面(或称为标签)之间切换。每个页面都可以包含不同的内容,如文本、图像、按钮或其他小部件。QTabWidget非常适合用于创建具有多…

用ChatGPT提升工作效率:从理论到实际应用

伴人工智能技术的迅速演进,像ChatGPT这类语言模型已成为提升工作效率的关键工具。这类模型不仅具备处理海量数据的能力,还能自动化许多日常任务,从而提高决策的准确性。本文将深入探讨如何在工作中利用ChatGPT等AI工具提升效率,涵…

VScode调试

VScode只是一个代码编辑器,下面我们使用VScode调试运行在远端连接Linux服务器的代码。 打断点 编译代码,要确保已经安装gdb,可以使用指令gdb --version 来检查 GDB 是否已安装以及安装的版本,确认安装后在编译时要加上选项&…

成都睿明智科技有限公司正规吗靠谱吗?

在这个短视频风起云涌的时代,抖音电商以其独特的魅力,成为了无数商家竞相追逐的新蓝海。而在这片浩瀚的商海中,成都睿明智科技有限公司犹如一艘装备精良的航船,引领着众多企业破浪前行,探索抖音电商的无限可能。今天&a…

Web Broker(Web服务应用程序)入门教程(1)

1、介绍 Web Broker 组件(位于工具面板的“Internet”选项卡中)可以帮助您创建与特定统一资源标识符(URI)相关联的事件处理程序。当处理完成后,您可以通过编程方式构建 HTML 或 XML 文档,并将它们传输给客…

<HarmonyOS第一课>HarmonyOS SDK开放能力简介的课后习题

不出户&#xff0c;知天下&#xff1b; 不窥牖&#xff0c;见天道。 其出弥远&#xff0c;其知弥少。 是以圣人不行而知&#xff0c;不见而明&#xff0c;不为而成。 本篇<HarmonyOS第一课>HarmonyOS SDK开放能力简介是简单介绍了HarmonyOS SDK&#xff0c;不需要大家过多…

【Java并发】乐观锁、悲观锁、CAS、版本号机制

前言 在现代计算机系统中&#xff0c;处理并发操作时&#xff0c;锁机制是至关重要的。本文将介绍乐观锁、悲观锁以及CAS&#xff08;Compare and Swap&#xff09;这三种常见的并发控制技术&#xff0c;帮助理解它们的原理和应用场景。 1.悲观锁 1.1 定义 悲观锁是一种在访…

三层交换技术,eNSP实验讲解

三层交换技术&#xff0c;eNSP实验讲解 一、简要介绍1、概念2、工作原理3、优点4、应用场景5、与路由器的区别 二、eNSP仿真实验1、步骤一&#xff1a;创建连接&#xff0c;明确参数。2、步骤二&#xff1a;设置PC1和PC2参数3、步骤三&#xff1a;配置交换机&#xff0c;通过命…

C++设计模式创建型模式———生成器模式

文章目录 一、引言二、生成器/建造者模式三、总结 一、引言 上一篇文章我们介绍了工厂模式&#xff0c;工厂模式的主要特点是生成对象。当对象较简单时&#xff0c;可以使用简单工厂模式或工厂模式&#xff1b;而当对象相对复杂时&#xff0c;则可以选择使用抽象工厂模式。 工…

Python 如何在 Web 环境中使用 Matplotlib 进行数据可视化

Python Matplotlib 在 Web 环境中的可视化 数据可视化是数据科学和分析中一个至关重要的部分&#xff0c;它能帮助我们更好地理解和解释数据。在现代应用中&#xff0c;越来越多的开发者希望能够将数据可视化结果展示在网页上。Matplotlib 是 Python 中最常用的数据可视化库之…

模型部署流程

神经网络部署流程 工业界应用神经网络时&#xff0c;往往要对学术界产出的模型进行优化&#xff0c;才能在推理设备/服务器上实现更高的效率&#xff0c;从而降低成本&#xff0c;这整个过程也一般称之为模型部署&#xff08;Deployment&#xff09;。 部署的目的 模型部署目…

vue2中使用vue-awesome-swiper实现轮播

swiper官方文档&#xff1a;Swiper中文网-轮播图幻灯片js插件,H5页面前端开发 1.安装 注意&#xff1a;swiper和vue-awesome-swiper的版本一定一定一定要相对应&#xff0c;版本对应如下&#xff1a; Swiper 5-6 vue-awesome-swiper4.1.1(vue2) Swiper 4.x vue-awesome-swi…

less解决function中return写法在浏览器被识别成Object导致样式失败的问题

问题描述&#xff1a; 一开始写的是: baseFontSize: 37.5px;//基于屏幕尺寸/10得出的基准font-size// return失败,浏览器显示为[object Object],[object Object] .pxToRem(px){value: px / baseFontSize * 1rem;return value; } 使用height: .pxToRem(40px);之后浏览器却是这…

【04】【Maven项目热部署】将Maven项目热部署到远程tomcat服务器上

1.虽然现在Maven中央仓库中支持的tomcat插件只支持到tomcat7这个版本&#xff0c;但是可以利用这个插件对Web项目进行热部署&#xff0c;热部署到远程服务器的tomcat服务器上&#xff0c;远程服务器上的tomcat版本可以是更高的版本&#xff0c;比如说tomcat8、9、10或更高的版本…

开源一款前后端分离的企业级网站内容管理系统,支持站群管理、多平台静态化,多语言、全文检索的源码

大家好&#xff0c;我是一颗甜苞谷&#xff0c;今天分享一款前后端分离的企业级网站内容管理系统&#xff0c;支持站群管理、多平台静态化&#xff0c;多语言、全文检索的源码。 前言 在当今的数字化时代&#xff0c;企业网站和个人博客已成为信息传播和品牌建设的重要渠道。…

mfc | mfc集成opencv,实现摄像头监控、拍照、视频图像处理(亮度、对比度、色调、饱和度)功能

这里是引用 文章目录 一、开发环境二、MFC项目创建三、集成opencv3.1 opencv安装3.2 添加项目属性3.3 测试OpenCV&#xff08;打开摄像头&#xff09;3.4 OPENCV视频嵌入到弹框中 四、关闭摄像头、拍照功能实现4.1 添加按钮4.2 添加全局静态变量4.3 关闭摄像头功能实现4.4 拍照…

Rust 力扣 - 289. 生命游戏

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们记录上一行和当前行转换之后的状态&#xff0c;当前行转换之后的状态计算完毕后调整上一行状态&#xff0c;直至最后一行状态计算完毕后调整最后一行状态 题解代码 pub fn game_of_life(board: &mut V…

【eNSP】华为ensp快速入门实验

一、安装准备 1. 检查和卸载已安装的软件 检查是否已经安装 eNSP 和依赖软件&#xff1a; 打开控制面板&#xff0c;点击“程序和功能”。 搜索列表中是否存在 eNSP 或依赖软件&#xff08;如 WinPcap、Wireshark&#xff09;。 卸载已安装的软件&#xff1a; 如果找到 e…