【D3.js in Action 3 精译_020】2.6 用 D3 设置与修改元素样式 + 名士专访(Nadieh Bremer)+ 2.7 本章小结

[复制链接]
发表于 2026-4-24 09:11:00 | 显示全部楼层 |阅读模式
当前内容地点位置
  

  • 第一部分 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 本章小结 ✔️


  2.6 用 D3 设置与修改元素样式

为了让可视化元素拥有想要的表面和感觉,必要为其设置样式。使用传统的 CSS 样式表就是一种不错的方案,通常也是思量后期可维护性时的优先方案。但偶然直接使用 D3 来设置与修改样式属性同样很方便,尤其是在样式随数据动态厘革的时间。
D3 通过 selection.style() 方法设置与修改元素的样式属性(attribute)。该方法必要两个参数:样式属性的名称及其属性值,如图 2.16 所示:

图 2.16 style() 方法

回到条形图示例,在 main.js 中,在 SVG 容器选择集上链式调用 style() 方法,即赋值到常量 svg 上的方法。如以下代码所示,使用 style() 方法为 SVG 容器应用边框样式,可以赋值为任何想要的属性值。本例中使用简写样式,设置一个宽度 1px 的玄色边框:
  1. const svg = d3.select(".responsive-svg-container")
  2.   .append("svg")
  3.     .attr("viewBox", "0 0 1200 1600")
  4.     .style("border", "1px solid black");
复制代码
SVG 容器附近的边框有助于直观相识当前所处的空间地区,并明确 style() 方法的工作原理。
生存项目并在欣赏器中检察效果。从 DOM 查抄工具中找到 SVG 容器,可以看到 border 属性(property)被添加到了 style 属性(attribute)中,如图 2.17 所示。也就是说 style() 方法注入了所谓的行内样式。

图 2.17 使用 style() 方法收效的边框样式

在处置惩罚 SVG 元素时,有些样式可以通过 attribute 属性或行内样式来收效,比方 fill 和 stroke 属性(properties)。至于应该使用 attr() 照旧 style() 方法来设置样式并没有严格的规定,但一些开辟职员更乐意保持同等,始终使用 CSS 样式表样式(或行内样式)来设置样式,而不是通过元素的 attribute 属性。这大概是一个不错的做法,尤其是在我们渴望分开创建形状的代码与设置表面的代码、使得层叠样式更易于管理的时间。本书将使用 attr() 和 style() 方法以及外部 CSS 文件来设置 SVG 元素的视觉属性。
比方,在 main.js 中,在矩形选择集上调用 style() 方法,并对该矩形设置与之前差别的添补色 "plum",如以下代码所示:
  1. svg
  2.   .append("rect")
  3.     .attr("x", 10)
  4.     .attr("y", 10)
  5.     .attr("width", 414)
  6.     .attr("height", 16)
  7.     .attr("fill", "turquoise")
  8.     .style("fill", "plum");
复制代码
然后打开 main.css 文件,为该矩形添加第三个 fill 属性(property),令其颜色值为 "orange":
  1. rect {
  2.   fill: orange;
  3. }
复制代码
此时该矩形拥有三种差别的添补样式:一个是通过元素 attribute 属性设置的青绿色 "turquoise";一个是通过行内样式应用设置的深紫色 "plum";末了是通过外部 CSS 样式设置的橙黄色 "orange"。固然,现实工作不会如许设置,本例仅供演示。
生存项目,留意观察借助 style 属性设置的 fill 样式是怎样覆盖另两种样式的。在图 2.18 中,您可以看到样式中的层叠规则是怎样收效的:行内样式覆盖了别的样式,其次是外部 CSS 样式表设置的样式,末了是通过 attribute 属性设置的 fill 样式。牢记这一规则将有助于订定得当本身风俗、团队和项目的计谋,同时也可以在遇到下面的题目时摆脱百思不得其解的窘境:为什么这种样式在屏幕上可见、而另一种偏偏就不可见呢?

图 2.18 添补样式 fill 同时在 attribute 属性、外部样式表及行内样式应用的效果对比

至此,我们已经知道怎样获取选择集、怎样在 DOM 中添加元素、以及怎样给这些元素设置方位与样式。但是,真要像示比方许逐一添加条形图的各个矩形条,服从肯定高不了。等下一章学了数据绑定的干系知识后,就能一次性添加全部的矩形条了。在此之前,必要删除 main.js 和 main.css 中与矩形干系的代码,让 main.js 文件只包罗如下所示的代码。第三章将从这里开始构建条形图:
代码清单 2.2 本章竣事时 main.js 的代码内容
  1. const svg = d3.select(".responsive-svg-container")
  2.   .append("svg")
  3.     .attr("viewBox", "0 0 1200 1600")
  4.     .style("border", "1px solid black");
复制代码
  人物专访:纳迪埃·布雷默(Nadieh Bremer)

  纳迪埃·布雷默 是一位数据可视化艺术家。

  【问】能否先容一下您的配景,以及您是怎样进入数据可视化范畴的?

  【Nadieh】 我结业时是一名天文学家,之后开始从事数据科学方面的工作。然而,几年后,我意识到本身缺少了工作中富有创意的一面。当我看到别人称他们本身为“数据可视化专家”时,我立即意识到这正是我可以分身的地方:在观察数据、探寻故事、玩转数学的同时发挥本身的创造力。

  【问】在没有 Web 开辟配景的环境下,是什么促使您学习 D3?遇到的紧张挑衅是什么,又是怎样降服的呢?

  【Nadieh】 我到场了一次 D3.js 研讨会(2013 年),会上人们展示了包罗交互在内的 D3 的各种大概性。尤其是在其时,我从未见过如许的新事物,我知道本身也想创建出如许的交互式数据可视化效果。于是便买了一本斯科特·穆雷(Scott Murray)写的书《网络交互式数据可视化》(Interactive Data Visualization for the Web,O’Reilly,2017 年),并从那本书开始了 D3 的学习。其时面对的紧张挑衅是,HTML / CSS / JavaScript 对我来说都是全新的(只管我知道怎样用 R 语言编程)。因此除了 D3 外,我还必须学习这些语言;而且,由于我的无知,我都不知道 D3 的独特之处在哪儿,什么又叫原生 JavaScript(vanilla JavaScript),以致于常常会被卡在一些细枝末节上,不知道怎样从网上搜索答案。总的来说,依附极致的毅力,并确信其时所从事的是本身真正热衷的项目,才让我终极对峙了下来。不知不觉地,我对这些知识的明确也越来越透彻。我花了整整一年的时间才明确了 D3 的“进入-更新-退出”(enter-update-exit)流程,哈哈。

  【问】除了 D3,您还使用其他可视化工具吗?D3 在您当前的数据可视化工作流程中处于什么位置?我看到您在项目中常常用到 R 语言。

  【Nadieh】 D3 确实是我的紧张工具。我 90% 的数据可视化项目都会在开始制作终极视觉效果时加载 D3。别的,我还会使用 JavaScript 和其他一些库,如用于处置惩罚颜色的 Chroma.js 以及用于处置惩罚噪声函数(noise functions)的 SimplexNoise。我总是先用 R 语言举行数据分析和数据准备,创建大量简朴的图表,以便对这些数据产生独到而深入的明确。但我从不把这些图表作为终极的视觉效果。

  

  • Nadieh 佳构项目《太空大战》(www.visualcinnamon.com/portfolio/space-wars/)
  

发表在《科学美国人》杂志的纳迪埃·布雷默的作品《太空卫星的可视化效果》(Visualization of satellites in space)


  【问】再来聊聊您为 2020 年 11 月版的《科学美国人》创作的《太空大战》这部作品吧?

  【Nadieh】 《太空大战》可视化展示了(其时)仍在太空中活动的全部卫星环境,紧张目的是为了体现谁拥有这些卫星、以及可以在哪些轨道上找到它们。通过将每颗卫星视为单独的小圆圈,再按国家和轨道举行分组,可以非常直观地展示卫星本身的详细环境,如重量、年限、所属分类等等。

  【问】能再先容一下这个项目的创作过程吗?

  【Nadieh】 幸好数据是由一位卫星专家网络的,以是我不必要做任何数据处置惩罚,只必要举行一些数据分析,就能相识我所把握的环境。我在一个小册子上记载了一些想法。我知道要在国家和轨道分类上做文章。不外,关于每颗卫星的元数据着实太多,只能分别展示每颗卫星。也不知道从那里冒出来的想法,但在某个时候,我绘制了一幅用圆圈体现卫星的树形舆图。当最初的想法渐渐明了起来后,剩下的工作就分成了两个部分:一个是技能部分——怎样在树形舆图中使用圆圈;另一个是怎样让团体操持看起来更雅观。一开始效果看起来很糟糕,但厥后我花了一些时间从最喜欢的科幻影戏中探求色彩灵感,才找到真正想要的视觉效果。

  【问】在外人看来,您好像是将 D3 的树形图的绘制伎俩与力导向图的布局相联合来天生这种可视化效果的,是如许吗?将差别模块的方法有机联合来创建前所未见的布局效果,这也是我最喜欢 D3 的缘故起因之一。看了您在 Skillshare 平台的主讲课程《数据可视化:通过自界说图表得到美感与影响力》(Data Visualization: Customizing Charts for Beauty & Impact),内里也发起各人组合差别范例的图表。

  【Nadieh】 没错,就是如许。我使用树形舆图的方法来获取每组卫星的预定地区(用 x、y 坐标和宽度、高度来形貌)。然后,在每个矩形地区内用力导向图的布局来举行模仿,以便对全部的圆举行定位,确保它们不会相互重叠。想要知道树状舆图的每个方框的公道巨细,必要用每个圆的外貌积(与卫星重量成比例)与一个转换系数相加,偶然还必要手动界说一些“秘密数值”(译注:magic number,意指步调中出现的没有任何注解或标明出处的数字),要么这儿改改,要么那儿调调。
  你说得很对,可以或许创造性地使用 D3 也是我最喜欢它的缘故起因之一!

  

代表卫星的圆圈根据树状舆图中的控制地区和轨道范例分组,再使用 D3 的力导向布局盘算它们简直切位置


  【问】关于用 D3 为纸媒等印刷前言天生静态可视化作品,您能再分享一下这方面的看法吗?我以为我们在这类题目上的讨论还远远不敷!

  【Nadieh】 我喜欢创建静态视觉效果,在创作过程中我也险些不停在用 D3.js。对于印刷版视觉效果的创作,有一点很紧张,那就是大概应该用 SVG 来完成创作,而不是使用 HTML5 的 canvas 画布。如许,杂志编辑们拿在手里的就是一个可以自由缩放巨细的矢量文件。别的,字体和标题这些内容也可以举行调解(比如更换字体)和润色(比如修改文案说话)。如果将欣赏器中的视觉效果带入矢量编辑器,那么绝大部分样式都会被复制过来(我发现 Illustrator 在复制 CSS 样式与设置方面做得最好)。

  【问】您与 Shirley Wu 相助完成的项目和《数据草图》一书(Data Sketches,由 A K Peters 出书社于 2021 年出书),开导了我们中的许多人,让我们在数据的处置惩罚方面更有创造力。您对初涉该范畴的新人有什么发起吗?

  【Nadieh】 听到这本书能带给各人开导和灵感,我感到无比欣慰。追念起来尚有些奇怪,当初我和 Shirley 开始编著《数据草图》时,曾一度以为它大概是个只有我们和一些密切的朋侪才会去欣赏的愚笨项目(silly project)呢。

  至于发起,紧张有两方面。一个是创作(to create)。尽大概多地去创作可视化作品。每创作一个新的作品,你都会学到新的东西(偶然以致是在不知不觉中);遇到新的题目或陷阱(pitfalls),要想出新的独具创意的办理方案来降服它们。当我回顾本身在这条蹊径上的旅程以及沿途创作的可视化作品时,都会清晰地看到本身是怎样在编码和创意方面变得更加自尊。这些履历和劳绩又进一步对我的创作产生积极的影响。

  第二个发起,是实验研讨你真正感爱好的数据和主题,即便这些数据不是现成的,而是必要(手工)网络的。对本身真正感爱好的主题举行数据分析,纵然遇到技能上或操持上的困难,也会更轻易对峙下去。这一点你也可以在《数据草图》一书中得到印证。在数据方面,我们从来不去选那条好走的路,而是不停实验让爱好来引导我们。险些在全部环境下,数据都会不知不觉地出现在某个地方。
  2.7 本章小结



  • D3 项目要有一个 Web 服务器才华正常运行。使用 VS Code 的 Live Server 扩展,可以简朴快速地在当地开辟环境中搭建一个 Web 服务器。
  • 有两种方法将 D3 库加载到项目中:一是在 index.html 中添加 script 标签;二是使用 NPM 模块引入 D3 库。为简朴起见,本书前几章使用 script 标签的方法。
  • D3 既可以完备加载整个库,也可以按需加载须要的 D3 模块,从而进步项目性能。
  • 通过 script 标记加载文件和库时,script 标签收效的次序与欣赏器读取脚本的次序雷同。也就是说,引入 D3 的 script 标签,必须放到使用 D3 的 JavaScript 文件所对应的 script 标签前面。否则,欣赏器将无法访问 JavaScript 文件中的 D3 方法而导致报错。
  • D3 使用 d3.select() 和 d3.selectAll() 方法从 DOM 中选择元素。前者只返回第一个元素,而后者返回与其选择器匹配的全部 DOM 元素。
  • 作为参数传给 select() 和 selectAll() 方法的字符串选择器,与 CSS 中的选择器雷同,均使用标署名、类名、ID 或这些名称的组合来标识 DOM 元素。
  • append() 方法可以将新增元素添加为该选择集的末了一个子元素。
  • attr() 方法用于添加或修改元素的 attribute 属性。它继承两个参数:属性名称与属性值。
  • style() 方法可以设置和修改 DOM 元素的 style 属性(attribute),也必要传两个参数:样式的 property 属性名与属性值。
  • style() 方法可以设置行内样式,并覆盖通过外部 CSS 样式表及 attribute 视觉属性设置的样式。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表