【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— 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.5 加注图表标签(待翻译 ⏳)
      • 3.6 本章小结

文章目录

      • 3.4.3 分段比例尺 Band scale

《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 配置了分段比例尺但没有设置间距的条形图效果

【图 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 配置了分段比例尺并添加间隙后的条形图效果

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

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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发(NEXT/API 12)【状态查询与订阅】手机侧应用开发

注意 该接口的调用需要在开发者联盟申请设备基础信息权限与穿戴用户状态权限,穿戴用户状态权限还需获得用户授权。 实时查询穿戴设备可用空间、电量状态。订阅穿戴设备连接状态、低电量告警、用户心率告警。查询和订阅穿戴设备充电状态、佩戴状态、设备模式。 使…

基于大数据技术的颈椎病预防交流与数据分析及可视化系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…

【计算机网络】详解UDP协议格式特点缓冲区

一、UDP 协议端格式 16 位 UDP 长度, 表示整个数据报(UDP 首部UDP 数据)的最大长度;如果16位UDP检验和出错,报文会被直接丢弃。 1.1、检验和出错的几种常见情况 数据传输过程中的比特翻转:在数据传输过程中,由于物理介质或网络设…

python-FILIP/字符串p形编码/数字三角形

一:FILIP 题目描述 给你两个十进制正整数 a,b​,输出将这两个数翻转后的较大数。 「翻转」在本题中的定义详见「说明 / 提示」部分。输入 第一行,两个十进制正整数 a,b。输出 第一行,a 和 b 翻转后的较大数。样例输入1 734 893 样…

鸿蒙harmonyos next flutter通信之BasicMessageChannel获取app版本号

本文将通过BasicMessageChannel获取app版本号,以此来演练BasicMessageChannel用法。 建立channel flutter代码: //建立通道 BasicMessageChannel basicMessageChannel BasicMessageChannel("com.xmg.basicMessageChannel",StringCodec());…

Koa2+Vue2的简书后台管理系统

文章目录 项目实战:前(vue)后(koa)端分离1、创建简书项目2、创建数据库2.1 创建数据库2.2 连接数据库3、模型对象3.1 设计用户模块的Schema3.2 实现用户增删改查3.2.1 增加用户3.2.2 修改用户3.2.3 删除用户3.2.4 查询用户4、封装业务逻辑层5、封装CRUD6、创建Vue项目7、配…

(14)MATLAB莱斯(Rician)衰落信道仿真4

文章目录 前言一、改写莱斯分布概率密度函数的理论值二、仿真代码三、仿真结果总结 前言 本文通过将接收信号总功率设置为1,重写了莱斯衰落信道上接收信号幅度的理论PDF式。然后用MATLAB代码生成了在具有不同莱斯因子K的Ricean平坦衰落信道下接收到的信号样本&…

leetcode练习 路径总和II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum 22 输出&a…

day04笔试练习

1.Fibonacci数列 题目链接:Fibonacci数列_牛客题霸_牛客网 题目思路: 定义 a b c 三个变量 使 c 一直加到比 n 大的最近的斐波那契数 此时比较 c 和 b 哪个数离得最近就好 public static void main(String[] args) {Scanner sc new Scanner(System.in…

基于facefusion的换脸

FaceFusion是一个引人注目的开源项目,它专注于利用深度学习技术实现视频或图片中的面部替换。作为下一代换脸器和增强器,FaceFusion在人脸识别和合成技术方面取得了革命性的突破,为用户提供了前所未有的视觉体验。 安装 安装基础软件 安装…

深入探究:在双链表的前面进行插入操作的顺序

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言​📝惟有主动付出,才有丰富的果…

构建高效服装销售平台:Spring Boot与“衣依”案例

1系统概述 1.1 研究背景 如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传…

hystrix微服务部署

目录 一.启动nacos和redis 1.查看是否有nacos和redis 二.开始项目 1.hystrix1工程(修改一下工程的注册名字) 2.运行登录nacos网站查看运行效果(默认密码nacos,nacos) 3.开启第二个项目 hystrix2工程 4.关闭第二个项目 hyst…

UE4 材质学习笔记02(数据类型/扭曲着色器)

一.什么是数据类型 首先为啥理解数据类型是很重要的。一些节点的接口插槽只接受特定类型的数据,如果连接了不匹配的数据就会出现错误,有些接口可以接受任何数据类型,但是实际上只会使用到其中的一些。并且有时可以将多个数据流合并成一个来编…

选择排序:直接选择排序、堆排序

目录 直接选择排序 1.选择排序的基本思想 2.直接选择排序的基本思想 3.直接插入排序的代码思路步骤 4.直接选择排序代码 5.直接选择排序的特性总结 堆排序 一、排升序,建大堆 1.利用向上调整函数建大堆 1.1.建立大堆的思路 1.2.以下是具体步骤&#xff1a…

【人人保-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

C++系列-多态

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 多态 多态就是不同类型的对象,去做同一个行为,但是产生的结果是不同的。 比如说: 都是动物叫声,猫是喵喵,狗是汪汪&am…

Flink集群部署

本次部署1.17版本 需要修改的配置文件地方为 Job为指挥中心,只能有一台主机,集群中所有的配置文件都这样配置 Rest为客户端UI显示使用,集群中所有的配置文件都这样配置 Task是每个节点工作使用的,每个节点的Task各不相同 conf配…

【mmengine】配置器(config)(进阶)继承与导出,命令行修改配置

一、配置文件的继承 1.1 继承机制概述 新建optimizer_cfg.py: optimizer dict(typeSGD, lr0.02, momentum0.9, weight_decay0.0001)新建runtime_cfg.py: device "cuda" gpu_ids [0, 1] batch_size 64 epochs 100 num_workers 8新建resnet50.py: _base_ […

数据结构-3.9.栈在递归中的应用

一.函数被调用背后的过程:最后被调用的函数最先结束也符合栈的后进先出 1.main函数为主函数即程序入口,运行时主函数先入栈,然后存入主函数里的数据; 2.func1函数加载在栈中时他后面的代码的地址#1(调用返回地址,不是…