【译】Learn D3 入门文档:Joins

2024-06-01 03:18
文章标签 文档 入门 learn d3 joins

本文主要是介绍【译】Learn D3 入门文档:Joins,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引子

继 Learn D3: Animation 第七篇,只是英文翻译,可修改代码的部分用静态图片替代了,想要实时交互请阅读原文。

  • 原文:Learn D3: Joins

  • 版本:Published Mar 24, 2020

  • Origin

  • My GitHub

正文

如果你熟悉此教程中的 D3 ,你可能会惊讶于 D3 选择器被提及的如此之少。

那是因为你可能不需要它们!

D3 选择器适用一个特殊的定位:快速,动态图表的增量更新。如果你关注的是静态图表,或者每帧都可以从头开始重新绘制的图表,那么你可能更喜欢不同的抽象。另一方面,如果你想要动画过渡或从现代浏览器中榨取最佳性能,选择器适合你。

(即使你决定不使用选择器,请记住 D3 还有大量其它有用的可视化工具。比例尺、形状、插值器、颜色、地图投影和许多其它功能可用于 Canvas、WebGL 或其它 DOM 抽象,如 Observable 的 HTML 标记模板文字、React 或 Svelte 。D3 还可以使用统计、分组和聚合、时间序列和解析的方法,协助数据清理和分析。)

本质上,D3 选择器指定的是转换而不是表示。你可以指定将当前状态转换为所需状态所做的更改(插入、更新和删除),而不是表示图表(DOM)的所需状态。这有时很乏味,但允许你设置过渡动画,并最小化对 DOM 的更改,从而提高性能。

让我们看看如何做。

假设我们想显示字母表中的字母。虽然不是很直观,但我们将保持简单,以专注于技术(有关实际的示例,请参见 D3 图库 的动画和交互部分。)

92-1

这个图表是静态的,因为它是在每次单元运行时从头开始创建的,这使得 D3 代码在本质上等同于 HTML 文本。

92-2

那么,何必要用选择器呢?对,对于静态图表,没有什么理由这样做。

但假设你想更新此图表以响应不断变化的数据。并且你不想从头开始重新绘制,希望应用最小的更新集来反映新数据。你希望重用现有元素,添加需要的元素,删除不需要的元素。只需将上述代码移动到一个在数据更改时调用的方法中,你就可以获得高性能的增量更新!😲

92-3

让我们把代码分析一下。

text 是一组文本元素,最初为空,其父元素是 SVG 元素。这个父项决定了输入的文本元素稍后将附加到何处。

通过调用 selection.data ,text 被绑定到一个新的数据数组 letters 。这将计算 text 选择集的三个子集:enter 选择集表示在新数据中,去除已存在元素与新数据的交集之后,剩下的数据;update 选择集表示新数据与已存在元素的交集;exit 选择集表示在已存在元素中,去除已存在元素与新数据的交集之后,剩下的元素。

作为图示如下:

92-4

(这些选择集隐藏在代码中:selection.data 返回 update 选择集,从中可以调用 selection.enter 或 selection.exit 访问其它选择集。)

我们可以手动处理这三种情况,但 selection.join 本就能方便的处理。enter 选择集添加进来;exit 选择集被移除;最后, updateenter 选择集被合并、排序并返回。然后,我们可以为这些加入或更新元素分配属性和文本。

我们观察到只要字母和文本元素之间的关联保持不变,就不需要在更新元素时重新分配某些属性和文本内容,这样就可以更高效。要保留此关联,selection.data 需要一个键函数;为了对 enterupdateexit 的精确操作,selection.join 需要相应的函数。如果 update 比 enter 和 exit 更常见,这将大大提高性能!

92-5

与前面一样,selection.join 返回合并的 enter 和 update 选择集,因此我们可以共享应用于两者的代码,例如设置 x 属性。

传递给 selection.data 的键函数用于计算每个新数据和已选元素数据的(字符串)键,确定哪个数据绑定到哪个元素:如果元素和数据具有相同的键,则该数据绑定到元素,并且元素被放入 update 选择集。字母是很好的键,因此标识函数(d => d)在这里是合适的。

(如果未指定键函数,则数据由索引绑定:第一个数据绑定到第一个元素,依此类推。作为练习,尝试重写上面的代码以通过索引联接。你将会也想把设置 x 属性与设置文本内容交换!)

然而,选择器真正闪耀的地方是过渡!✨

在下面,字母从顶部进入,更新时水平滑动,然后从底部退出。这比上面的瞬时转变更容易理解。

92-6

好的过渡不仅仅是为了吸引注意力而让图表“舞动”;它们帮助观看者通过变动了解数据是如何变化的

良好的过渡保持对象的恒定性:在过渡之前表示特定事物(如字母 C )的图表元素应在整个过渡过程中和过渡之后表示相同的事物,从而允许观看者连续跟踪。相反,如果给定元素的含义在过渡期间发生变化,那么变动将毫无意义。

举个更实际的例子怎么样?

下图显示了按特定年龄组人口百分比排列的前十个州(以及华盛顿特区,外地居住者)。这表明犹他州的年轻人口比例过高,反映了 LDS 教会对养育家庭的重视。相比之下,佛罗里达州退休人口众多,许多人都在 70 岁或以上。

当你更改选定的年龄组时,请观察图表如何重新排序以反映排名的变化。x 轴同时重新缩放以适应新数据。

92-7

chart = {const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);console.info(data)// For the initial render, reference the current age non-reactively.const agedata = viewof agedata.value;const x = d3.scaleLinear().domain([0, d3.max(agedata, d => d.value)]).rangeRound([margin.left, width - margin.right]);const y = d3.scaleBand().domain(agedata.map(d => d.name)).rangeRound([margin.top, margin.top + 20 * data.names.length]);let bar = svg.append("g").attr("fill", "steelblue").selectAll("rect").data(agedata, d => d.name).join("rect").style("mix-blend-mode", "multiply").attr("x", x(0)).attr("y", d => y(d.name)).attr("width", d => x(d.value) - x(0)).attr("height", y.bandwidth() - 1);const gx = svg.append("g").call(xAxis, x);const gy = svg.append("g").call(yAxis, y);return Object.assign(svg.node(), {update(agedata) {const t = svg.transition().duration(750);gx.transition(t).call(xAxis, x.domain([0, d3.max(agedata, d => d.value)]));gy.transition(t).call(yAxis, y.domain(agedata.map(d => d.name)));bar = bar.data(agedata, d => d.name).call(bar => bar.transition(t).attr("width", d => x(d.value) - x(0)).attr("y", d => y(d.name)));}});
}

92-9

只有前 10 条可见,因为其余的隐藏在图表下方。因此,selection.join 是不需要的,因为没有条形加入或移除,它们只会更新。这不仅简化了代码,而且使过渡更有意义,因为进入或退出条形图的速度现在暗示它们在展示外的位置。

动画过渡通常由读者点击或在寻找答案时点击触发。接下来,让我们看看如何让图表响应此类查询。

Next

附录

92-10

根据源码,去除了平台依赖,提取了主要代码,有以下示例:

  • 示例 1
  • 示例 2

参考资料

  • Learn D3: Joins

这篇关于【译】Learn D3 入门文档:Joins的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1019842

相关文章

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python实现合并与拆分多个PDF文档中的指定页

《Python实现合并与拆分多个PDF文档中的指定页》这篇文章主要为大家详细介绍了如何使用Python实现将多个PDF文档中的指定页合并生成新的PDF以及拆分PDF,感兴趣的小伙伴可以参考一下... 安装所需要的库pip install PyPDF2 -i https://pypi.tuna.tsingh

Python FastAPI入门安装使用

《PythonFastAPI入门安装使用》FastAPI是一个现代、快速的PythonWeb框架,用于构建API,它基于Python3.6+的类型提示特性,使得代码更加简洁且易于绶护,这篇文章主要介... 目录第一节:FastAPI入门一、FastAPI框架介绍什么是ASGI服务(WSGI)二、FastAP

Python批量调整Word文档中的字体、段落间距及格式

《Python批量调整Word文档中的字体、段落间距及格式》这篇文章主要为大家详细介绍了如何使用Python的docx库来批量处理Word文档,包括设置首行缩进、字体、字号、行间距、段落对齐方式等,需... 目录关键代码一级标题设置  正文设置完整代码运行结果最近关于批处理格式的问题我查了很多资料,但是都没

Python自动化Office文档处理全攻略

《Python自动化Office文档处理全攻略》在日常办公中,处理Word、Excel和PDF等Office文档是再常见不过的任务,手动操作这些文档不仅耗时耗力,还容易出错,幸运的是,Python提供... 目录一、自动化处理Word文档1. 安装python-docx库2. 读取Word文档内容3. 修改

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

SpringBoot3集成swagger文档的使用方法

《SpringBoot3集成swagger文档的使用方法》本文介绍了Swagger的诞生背景、主要功能以及如何在SpringBoot3中集成Swagger文档,Swagger可以帮助自动生成API文档... 目录一、前言1. API 文档自动生成2. 交互式 API 测试3. API 设计和开发协作二、使用