【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法

server/2024/12/23 1:20:51/

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

  • 第一部分 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.5 加注图表标签(待翻译 ⏳)
      • 3.6 本章小结

文章目录

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

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

3.4.3 分段比例尺 Band scale

绘制示例条形图要用到的第二种比例尺为 分段比例尺(band scale)。它属于之前介绍的第四类(详见 3.4.1 节内容):接受离散型输入、返回连续型输出。要在可用空间内处理离散的各矩形条的分布,这正是 D3 分段比例尺的强项。

声明一个分段比例尺,需要调用 d3.scaleBand() 函数。在以下代码片段中,分段比例尺赋给了常量 yScale,表示它将负责 y 轴方向的元素排布。该比例尺的定义域,是一个包含数据集所有技术(technology)名称的数组,可通过 JavaScriptmap() 函数生成(关于 map() 的用法,可参考前面的 1.2.5 节内容)。至于比例尺的值域,则覆盖所有可用的垂直空间,即从 SVG 容器顶部的 0 像素一直到其底部的 700px

const yScale = d3.scaleBand().domain(data.map(d => d.technology)).range([0, 700]);

createViz() 内部加入该比例尺,并写在数据绑定逻辑的代码前面。当使用数据集中的某项技术调用该函数时,会得到该技术对应的矩形条垂直坐标。例如,将字符串 "Excel" 传给 yScale,将得到 0,因为与 Excel 对应的矩形条是条形图中的第一个矩形,位于最上方;同理,若传入 "D3.js",则返回 272.72,它代表 D3 对应的矩形条左上角的垂直坐标:

yScale("Excel")   // => 0
yScale("D3.js")   // => 272.72

之前每个矩形条的 y 属性值是通过手动计算得到的,还有印象吗?现在有了分段比例尺,我们可以非常轻松地用它来算出各矩形条的实际纵坐标:

svg.selectAll("rect").data(data).join("rect")....attr("y", d => yScale(d.technology))...

分段比例尺还提供了一个非常方便的工具方法:bandwidth()。它会返回矩形条的厚度。该厚度与矩形条的数量和可用空间成正比。本例中,该厚度即为矩形条的 height 属性值。如以下代码段所示,可以通过分段比例尺bandwidth() 方法来设置 height 属性:

svg.selectAll("rect").data(data).join("rect")....attr("height", yScale.bandwidth())...

保存项目并在浏览器中查看,会看到如图 3.27 所示的效果。条形图填满了 SVG 容器所有可用的垂直空间。由于各矩形条间没有间隙,条形图看起来十分拥挤,阅读体验极差。

图 3.27 配置了<a class=分段比例尺但没有设置间距的条形图效果" />

【图 3.27 配置了分段比例尺但没有设置间距的条形图效果】

间距的问题可以通过分段比例尺paddingInner() 属性(property)来解决。该属性专门用于指定各矩形条间的内边距(padding)大小,并接受一个 01 之间的值,这里设置为 0.2,表示大小为矩形条高度的 20%

const yScale = d3.scaleBand().domain(data.map(d => d.technology)).range([0, 700]).paddingInner(0.2);

完成以上设置后,重新加载示例页面,条形图的布局看起来就好多了,如图 3.28 所示:

图 3.28 配置了<a class=分段比例尺并添加间隙后的条形图效果" />

【图 3.28 配置了分段比例尺并添加间隙后的条形图效果】

而图 3.29 则梳理并复盘了 D3 分段比例尺的工作原理。首先是接受一个定义域,即数据集中的技术列表,并令其均匀分布到指定的值域内(即 SVG 容器垂直方向上的可用空间)。各矩形条的左上角垂直坐标可以通过调用分段比例尺函数计算得到(如 yScale("PowerPoint"));同理,调用该比例尺的 bandwidth() 方法可以得到矩形条的高度值(即 yScale.bandwidth())。最后是各矩形条的间距,默认情况下为 0,手动设置间距可以通过指定分段比例尺paddingInner() 属性实现(property)。它接受一个 01 之间的值,代表当前每个矩形条间的内边距大小(同时也表示其相对于矩形条高度 height 的百分比值)。

图 3.29 <a class=分段比例尺在垂直方向的可用空间内均匀排布技术列表时的原理图" />

【图 3.29 分段比例尺在垂直方向的可用空间内均匀排布技术列表时的原理图】

译注
虽然作者没有提及,但本节附带的练习源码中我也加入了 Mocha.js 相关的测试代码,可以对分段比例尺的相关特性展开测试。感兴趣的小伙伴可以下载到本地试试,这里就不展开了。我本人实测过程中,发现最后的条形图并未居中,原来是上一次练习线性比例尺时忘了修改 x 属性的值,将 0 更正为 100 就和书中截图一样了。特此说明。


http://www.ppmy.cn/server/130492.html

相关文章

不继承Mono的单例模式基类

1. 为什么要写写单例模式基类 用面向对象的思想避免代码冗余&#xff08;多余、重复&#xff09; 2. 实现不继承MonoBehaviour的单例模式基类 单例模式的基类 using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 单…

SpringSecurity实现自定义登录接口

SpringSecurity实现自定义登录接口 1、配置类 ConfigClazz&#xff08;SpringSecuriey的&#xff09; //首先就是要有一个配置类Resourceprivate DIYUsernamePasswordAuthenticationFilter diyUsernamePasswordAuthenticationFilter;/*SpringSecurity配置*/Beanpublic Securit…

使用kubeadm的方式部署k8s-1.22

一、环境准备 角色地址系统版本集群版本安装软件Master01192.168.89.164centos7.91.22.2kubeadm、kubelet、kubectl、docker、nginx、keepalivedMaster02192.168.89.165centos7.91.22.2kubeadm、kubelet、kubectl、docker、nginx、keepalivedMaster03192.168.89.166centos7.91…

Unity3D FixedUpdate处理物理模拟详解

前言 在Unity3D游戏开发中&#xff0c;FixedUpdate是一个特殊的方法&#xff0c;它专门用于处理物理模拟和与时间相关的逻辑。与Update方法不同&#xff0c;FixedUpdate是以固定的时间间隔被调用的&#xff0c;这个间隔可以在Unity编辑器中的“项目设置”&#xff08;Project …

git将本地分支推送至远程

要将本地分支推送到远程仓库&#xff0c;你可以按照以下步骤操作。假设你已经安装了 Git 并且本地仓库已经初始化。 1. 配置远程仓库&#xff08;如果尚未配置&#xff09; 首先&#xff0c;你需要确保你的本地仓库已经关联了一个远程仓库。如果还没有关联&#xff0c;你可以…

LabVIEW开关磁阻电机特性测量系统

基于LabVIEW软件和特定硬件组件的开关磁阻电机&#xff08;SRM&#xff09;特性测量系统&#xff0c;结合多功能数据采集卡&#xff0c;统能够准确地测量并分析SRM的电磁特性&#xff0c;从而支持电机模型的精确建立和性能优化。 项目背景 在工业生产和家用电器领域&#xff0…

什么是SQLite?

一、什么是SQLite? SQLite是一个进程内的软件库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的SQL数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其他数据库不一样&#xff0c;您不需要在系统中配置。 就像其它数据库&#xff0c;SQLite引擎不是…

3种常用的缓存读写策略详解

在详解3种常用的缓存读写之前&#xff0c;我们先要了解什么事缓存读写。 缓存读写是指在使用缓存技术时&#xff0c;对数据进行读取和更新的操作过程。缓存是一种用于提高系统性能和可扩展性的技术&#xff0c;通过减少对慢速存储&#xff08;如数据库&#xff09;的访问次数&…