【D3.js in Action 3 精译】1.2.2 可缩放矢量图形(三)

news2024/10/7 10:14:13

当前内容所在位置

  • 第一部分 D3.js 基础知识
    • 第一章 D3.js 简介
      • 1.1 何为 D3.js?
      • 1.2 D3 生态系统——入门须知
        • 1.2.1 HTML 与 DOM
        • 1.2.2 SVG - 可缩放矢量图形 ✔️
          • 第一部分
          • 第二部分
          • 【第三部分】✔️
        • 1.2.3 Canvas 与 WebGL(精译中 ⏳)
        • 1.2.4 CSS(待翻译)
        • 1.2.5 JavaScript(待翻译)
        • 1.2.6 Node 与 JavaScript 框架(待翻译)
        • 1.2.7 Observable 记事本(待翻译)

译注
(上接 1.2.2 小节(二))
…… 关于 SVG 描边(strokes)的位置

当对齐可视化项目中的图形时,需要特别注意:SVG 图形绘制出的描边是在内外边界上平均展布的。如下图所示,已知一个 width 属性为 40px 的矩形,令 stroke-width 的值为 1,则在视觉效果上会在矩形的左右两边各增加宽度为 0.5px 的描边(而不是下意识地以为的那样在各边均增加 1px),最终实际的总宽度为 41px;若令 stroke-width 的值为 2,则左右两边各增加 1px,以此类推。

描边宽度 stroke-width 对 SVG 图形实际宽度的影响描边宽度 stroke-width 对 SVG 图形实际宽度的影响

(……关于 SVG 描边(strokes)的位置)

5 圆与椭圆

在数据可视化中常常会用到圆形。它们天然吸引眼球,使可视化效果看起来更友好、更有趣。SVG 的圆是通过 <circle /> 元素绘制的,其必选属性包括圆心位置(cx, cy)与半径(r),如图 1.17 所示。圆的半径是从圆心到圆周上任意一点绘制的线的长度。将以下圆形添加到示例中,令圆心位于 (530, 80) 处,且半径为 50px

<circle cx="530" cy="80" r="50" />

图 1.17
图 1.17 在 SVG 容器的坐标系中定位圆和椭圆并调整其大小

还可以为圆设置填充(fill)与描边(stroke)属性(attribute)。要生成图 1.17 中的圆,令填充色为透明(transparent)、描边宽度为 3px、描边颜色为 #81c21c(译注:这里应该参考的是最终效果图 1.8,图 1.17 只是示意图)。

同理,<ellipse /> 元素必须指定圆心坐标(cx, cy),但不像圆有固定半径,椭圆的半径会变化,使其呈扁平状——这是通过声明椭圆的水平半径(rx)和垂直半径(ry)来实现的。将如下代码片段添加到示例中,将在圆的下方绘制一个椭圆,其水平半径为 50px、垂直半径为 30px

<ellipse cx="530" cy="205" rx="50" ry="30" />
6 路径

SVG 的路径(path)元素是目前为止所有 SVG 元素中最灵活的一种。在 D3 中,路径被广泛用于绘制几乎所有的复杂形状和曲线。这些形状和曲线是无法用目前讨论过的图形基元(线、矩形、圆和椭圆)来表示的。

路径元素通过声明 d 属性(这里的“d”代表“draw”,即“绘制”)来指示浏览器进行绘制。d 属性包含一系列命令:从开始绘制路径的位置,到使用的一系列曲线类型,一直到确定该路径是否为一个封闭图形为止。例如,在图形画廊示例中添加以下路径元素:

<path d="M680 150 C 710 80, 725 80, 755 150 S 810 220, 840 150" fill="none" stroke="#773b9a" stroke-width="3" />

如图 1.18 所示, d 属性以 M680 150 开头,表示“移动(M)到坐标(680,150)处”。接着从起点坐标(680 150)到 d 属性最后一个坐标(840 150)所指定的终点,绘制一条三阶贝塞尔曲线(cubic Bézier curve)。三阶贝塞尔曲线还需要设置控制点来定义曲线的陡峭程度和弯曲方向。这些控制点从字母 C(这里的“C”代表“cubic curve”,即“三次方曲线”)之后开始,直到字母 S(这里的“S”代表“stop”,即“停止”)之后结束。

图 1.18 一条简单的 SVG 路径及其控制点
图 1.18 一条简单的 SVG 路径及其控制点

注意

如需深入了解 SVG 路径,请参阅 MDN 的教程:https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths。

手动设置 d 属性仅适用于简单的图形,随着图形复杂度增加,纯手动编写将会变得非常繁琐。所幸 D3 提供了强大的图形生成工具来专门处理 d 属性的计算。本书第 4 章将深入讨论。

路径还有一个需要牢记的重要知识点:无论路径元素是否闭合,只要其 fill 属性值不为 nonetransparent,浏览器就会默认填充为黑色,如本例所示。

7 文本

内联 SVG 图形的最大优势之一在于支持屏幕阅读器访问其包含的文本内容。这对于可访问性而言是一大优势。由于数据可视化通常包含多个标签,因此有必要了解如何使用 <text> 元素来操作 SVG 文本。通过往示例中添加标签可以了解 SVG 文本的基本工作原理。

目前为止我们讨论的 SVG 图形都使用了自闭合标签(如 <line /><rect /><path /> ……)。在使用 SVG 的 <text> 元素时,需要同时使用开标签和闭标签,并将待显示文本放置在这两个标签之间。例如,添加一个内容为“line”的文本元素:

<text>line</text>

保存并重新加载页面。您可能以为文本会出现在 SVG 容器的左上角,但却看不到……这是为什么呢?默认情况下,SVG 文本的位置是参照其基线计算得来的,通过 dominant-baseline 属性控制。如果文本基线的坐标是 (0, 0),如图 1.19 所示,实际文本最终将位于 SVG 容器之外。由于任何位于 SVG 容器之外的元素都是不可见的,所以看不到文本。

图 1.19 在 SVG 容器外定位文本
图 1.19 在 SVG 容器外定位文本

在使用 SVG 文本元素时,另一个需要考虑的问题是文本如何流动(flow)。常规 HTML 元素在页面上的位置是按照控制内容流动的特定规则来确定的。如果在页面中插入大量 <div> 元素,它们会自然地堆叠在一起,其内容也会回流(reflow),不会超出容器的范围;而 SVG 文本根本不会流动,开发人员必须单独设置每个文本元素的 xy 属性。例如通过它们将文本放在坐标点 (60, 260) 处,标签“line”才会出现在图形画廊示例中 SVG 直线段的下方:

<text x="60" y="260">line</text>

作为练习,再创建一个新的文本元素,并将标签“rect”置于矩形和正方形的下方。

至此,我们通过 xy 属性声明了文本元素 左下角 的位置。怎样设置文本中点位置呢?通过属性 text-anchor 来实现:令其值为 middle 即可,如图 1.20 所示。再比如,利用该属性还可以将圆形的文本标签居中。

<text x="530" y="155" text-anchor="middle">circle</text>

图 1.20图 1.20 text-anchor 属性对 SVG 文本对齐方式的影响。默认值为 start;根据其中间位置对齐,值为 middle;设置末尾对齐,值为 end

最后,分别为椭圆和路径元素各添加一个文本标签。SVG 文本默认为黑色,可以通过 fill 属性(attribute)进行更改。

8 分组元素

本小节要讨论的最后一个 SVG 元素为分组元素(group element)。分组元素(即 <g> 元素)与之前讨论过的其他 SVG 元素有所不同。它既没有视觉上的图形表示,也不存在具有边界的空间;相反,它是 SVG 各元素的逻辑分组,广泛应用于由多个图形和标签组成的可视化效果中。

如果希望正方形标签和“rect”文本标签一同显示,并在 SVG 容器中整体平移,可以如以下示例将它们放到一个 <g> 元素中。注意,<rect> 元素的左上角已变为了坐标原点 (0, 0)<text> 位于 (0, 85) 处,保持在 <rect> 的下方:

<g>
  <rect x="0" y="0" width="60" height="60" />
  <text x="0" y="85">rect</text>
</g>

此时,包含正方形及其文本标签的组出现在了 SVG 容器的左上角。我们可以在 SVG 容器中任意移动这个组及其包含的所有元素,始终保持正方形与文本标签之间的对齐方式不变。

使用 transform 属性可以在 SVG 容器中平移该分组。transform 属性比之前学过的其他属性略显复杂,但与 CSS 中 transform 属性的用法相同。它接受一个或一系列变换(transformation,如平移、旋转、缩放等)作为属性值。平移一个分组使用 translate(x, y) 变换。如果要将 <rect><text> 元素移回原位,需要令分组元素右移 260px 并下移 175px,即令 <g> 元素 transform 属性的值为 transform="translate(260,175)"

<g transform="translate(260,175)">
  <rect x="0" y="0" width="60" height="60" />
  <text x="0" y="85">rect</text>
</g>

<g> 元素的另一个特点,是其子元素可以继承它的样式属性(styling attributes)。下面举例说明。由于前面“rect”文本标签已经和正方形归为同一组,故先将其余文本元签统一放到另一个 <g> 元素内:

<g>
  <text x="60" y="260">line</text>
  <text x="530" y="155" style="text-anchor:middle">circle</text>
  <text x="530" y="260" style="text-anchor:middle">ellipse</text>
  <text x="730" y="260">path</text>
</g>

如果令 <g>fill 属性值为 #636466,则里面的每个 <text> 元素都将继承相同的颜色;同理,如果添加的是 font-familyfont-size 属性,同一组内的文本元素也将继承这些样式属性(properties)。

<g fill="#636466" style="font-size:16px; font-family:monospace">
  <text x="60" y="260">line</text>
  <text x="530" y="155" style="text-anchor:middle">circle</text>
  <text x="530" y="260" style="text-anchor:middle">ellipse</text>
  <text x="730" y="260">path</text>
</g>

最后一次再重新加载页面,注意观察分组内的标签继承的颜色和字体效果;再看看分组外的标签是否保持原来的外观不变。像这样在分组元素上应用共享样式的做法非常方便,可以帮助您在工作中遵循 DRY(即 Don’t Repeat Yourself,不要重复自己)原则。需要更新属性时,在分组容器上操作也会很简单。

恭喜您完成了本书的第一个练习!您可以在代码清单 1.2 及源码文件的 end 文件夹找到 SVG 图形画廊的完整代码。在构建首个 D3 项目时,该练习可以作为参考。

代码清单 1.2 SVG 图形画廊示例的完整 HTML 代码

<!DOCTYPE html>
<html>
<head> <!-- [略] --> </head>
<body>
  <div style="width:100%; max-width:1200px; margin:0 auto;">
    <svg viewBox="0 0 900 300" style="border:1px solid black;">
 
      <line x1="50" y1="45" x2="140" y2="225" stroke="black" />
 
      <rect x="260" y="25" width="120" height="60" fill="#6ba5d7" />
      <rect x="260" y="100" width="120" height="60" rx="20" ry="20" fill="#6ba5d7" /> 
      <g transform="translate(260, 175)">
        <rect x="0" y="0" width="60" height="60" fill="transparent"  stroke="#6ba5d7" />
        <text x="0" y="85">rect</text>
      </g>
 
      <circle cx="530" cy="80" r="50" fill="none" stroke="#81c21c" stroke- width="3" />
      <ellipse cx="530" cy="205" rx="50" ry="30" fill="#81c21c" />
 
      <path d="M680 150 C 710 80, 725 80, 755 150 S 810 220, 840 150" fill="none" stroke="#773b9a" stroke-width="3" />
 
      <g fill="#636466" style="font-size:16px; font-family:monospace">
        <text x="60" y="260">line</text>
        <text x="530" y="155" style="text-anchor:middle">circle</text>
        <text x="530" y="260" style="text-anchor:middle">ellipse</text>
        <text x="730" y="260">path</text>
      </g>
 
    </svg>
  </div>
</body>
</html>

强化练习:创建 SVG 图形

现在该您小试牛刀了——创建如下图所示的 SVG 图形。您可以在源码文件夹 02_SVG_exercise/start 中进行操作。具体要求如下:

  • 创建一个响应式 SVG 容器,宽高均为 400px(屏幕上留足空间)。
  • 绘制一个宽高均为 200px 的正方形。将其置于 SVG 容器的中心位置,并指定透明色填充及 5px 的黑色描边。
  • 在 SVG 容器的中心添加一个半径为 100px 的圆。将其 fill 属性设置为 CSS 颜色名称“plum”。
  • 绘制两条描边为 5px 的黑色对角线:一条从正方形的左上角画到右下角;另一条从正方形的右上角画到左下角。
  • 在正方形上方添加文本“SVG is awesome!”字样,并将其置于 SVG 容器的中心。其他文本样式:字号 18px、无衬线字体。

SVG 强化练习项目效果图
强烈建议通过练习该 SVG 图形来强化本小节介绍的知识点

该练手项目的完整参考代码,请参阅 附录 DD.1.1 小节或随书源码文件中的 02_SVG_exercise/end 文件夹中。建议尽量独立完成。

(SVG 基础知识译完了,内容有点多,再自己做个小结吧)

本节 SVG 基础知识要点梳理
  • 圆(circle)与椭圆(ellipse):都具有圆心坐标(cx / cy)和半径,只是椭圆的半径有两个(rxry),圆只有一个(r);圆其实是椭圆的 特殊情况
  • 路径(path)是 SVG 图形中最复杂的几何基元,其属性 d 包含一系列命令,可借助 D3 的生成工具代替纯手工赋值;
  • 文本(text)——
    • 在 SVG 中不随常规 HTML 内容流动;
    • 其位置是基于文本基线计算得来的,需要手动设置(xy);
    • 文本对齐通过 text-anchor 属性调整,可选值:start | middle | end
  • 分组(g)元素——
    • 没有视觉图形表示,也不占据空间;
    • 放入同一分组的元素可整体移动;
    • 设置在 g 上的样式可被子元素继承:如 fillfont-sizefont-family 等;

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

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

相关文章

10.8K star!史上最强Web应用防火墙雷池WAF

长亭雷池SafeLine是长亭科技耗时近 10 年倾情打造的WAF(Web Application Firewall)&#xff0c; 一款敢打出口号 “不让黑客越雷池一步” 的 WAF&#xff0c;愿称之为史上最强的一款Web应用防火墙&#xff0c;足够简单、足够好用、足够强的免费且开源的 WAF&#xff0c;基于业…

全球首款商用,AI为视频自动配音配乐产品上线

近日&#xff0c;海外推出了一款名为Resona V2A的产品&#xff0c;这是全球首款商用视频转音频 (V2A) 技术产品。这项突破性技术利用AI&#xff0c;仅凭视频数据即可自动生成高质量、与上下文相关的音频&#xff0c;包括声音设计、音效、拟音和环境音&#xff0c;为电影制作人、…

单向链表结构

链表结构简介 链表结构是一种用比较特殊的数据结构类型&#xff0c;它也是线性数据结构中的一种&#xff0c;但是与栈结构等线性数据结构不同&#xff0c;它的内部结构并不是一个简单的存储空间&#xff0c;而是一个带有指向性质的单元。要理解链表结构要弄清楚两个问题&#x…

react_后台管理_项目

目录 1.运行项目 2. 项目结构 ①项目顶部导航栏 ②项目左侧导航栏 ③主页面-路由切换区 本项目使用的是 reacttsscss 技术栈。 1.运行项目 在当前页面顶部下载本项目&#xff0c;解压后使用编辑器打开&#xff0c;然后再终端输入命令&#xff1a; npm i 下载依赖后&am…

使用Python绘制动态螺旋线:旋转动画效果

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame绘制螺旋线函数主循环 完整代码 引言 螺旋线是一个具有美学和数学魅力的图形。通过编程&#xff0c;我们可以轻松创建动态旋转的螺旋线动画。在这篇博客中&#xff0c;我们将使用Python和Pygame库来实现…

【python脚本】批量检测sql延时注入

文章目录 前言批量检测sql延时注入工作原理脚本演示 前言 SQL延时注入是一种在Web应用程序中利用SQL注入漏洞的技术&#xff0c;当传统的基于错误信息或数据回显的注入方法不可行时&#xff0c;例如当Web应用进行了安全配置&#xff0c;不显示任何错误信息或敏感数据时&#x…

解决卡顿发热,超帧技术焕发中重载游戏动力

近几年&#xff0c;中国手游市场规模不断扩大&#xff0c;开发者通过在画面、玩法等方面的持续创新和打磨&#xff0c;推出更加精品化的产品。然而愈发精美的画质和复杂的玩法&#xff0c;也给硬件带来超高的负载&#xff0c;导致玩家在游戏过程中&#xff0c;频繁出现掉帧卡顿…

动态规划算法,完全零基础小白教程!不是计算机的都能学会!万字吐血详解。

目录 一、动态规划算法概念 题一 1、算法解析 1&#xff09;确定状态&#xff1a; ​2&#xff09;状态转移方程&#xff1a; ​3&#xff09;初始化&#xff1a; 4&#xff09;填表顺序&#xff1a; 5&#xff09;返回值&#xff1a; 2、代码 题二 1、算法解析 1、确…

你喜欢波段交易吗?

波段交易的核心在于精准捕捉市场中的长期趋势波动&#xff0c;以实现更为稳健的收益。与剥头皮和日内交易不同&#xff0c;波段交易者更倾向于持有交易头寸数日乃至数周&#xff0c;以更宽广的视角把握市场动态。 这种交易方式的优势在于&#xff0c;它降低了对即时市场反应的…

C - Popcorn(abs358)

题意&#xff1a;有n个摊子&#xff0c;m个爆米花&#xff0c;想花费最少去的店铺买到所有的口味的爆米花&#xff0c;找到每一列都为‘o’的最少行数。 分析&#xff1a;用dfs寻找最少路径 #include<bits/stdc.h> using namespace std; typedef long long ll; char x;…

【面试系列】AI研究员高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

内网渗透第四天!!!冲冲冲!!怎么绕过uac以及你会all劫持???不安全的服务路径以及服务权限,你会吗???

在第三天我们简单的说了一下绕过uac&#xff0c;但是我们使用的msf模块ask要对方管理员跟我们一起来进行操作&#xff0c;才可以进行提权的操作&#xff0c;这点就限制住了我们。我们今天来讲一下不用钓鱼的绕过的操作。 绕过uac&#xff1a; 使用uacme项目和msf联动来进行绕过…

和小红书一起参会! 了解大模型与大数据融合的技术趋势

在过去的两年中&#xff0c;“大模型”无疑成为互联网行业的焦点话题&#xff0c;曾经炙手可热的大数据架构似乎淡出公众视野。然而&#xff0c;大数据领域并未停滞不前&#xff0c;反而快速演进&#xff0c;传统依赖众多开源组件的大数据平台正逐步过渡到以融合与简化为核心特…

Xorbits inference操作实战

1.操作环境 序号软件版本备注1Windows1.版本&#xff1a;Windows 10 专业版2.版本号&#xff1a;21H23.操作系统内部版本&#xff1a;19044.18892Docker Desktop4.24.2 (124339)3WSLUbuntu 22.04 LTS4Python3.105CUDA12.16Dify0.6.6 Xorbits inference 是一个强大且通用的分布…

那些好用的 Vue3 的工具搭子!!【送源码】

2020 年 9 月 18 日 Vue3 的正式发布已经过去了大约 3 年 9 个月左右&#xff01;&#xff01;&#xff01; 随着 Vue3 版本的逐渐成熟&#xff0c;我们的前端世界也迎来了一系列令人振奋的更新和工具。Vue 生态圈的持续扩大&#xff0c;无疑为前端开发人员带来了前所未有的便…

C盘清理和管理

本篇是C盘一些常用的管理方法&#xff0c;以及定期清理C盘的方法&#xff0c;大部分情况下都能避免C盘爆红。 C盘清理和管理 C盘存储管理查看存储情况清理存储存储感知清理临时文件清理不需要的 迁移存储 磁盘清理桌面存储管理应用存储管理浏览器微信 工具清理 C盘存储管理 查…

鸿蒙开发设备管理:【@ohos.multimodalInput.touchEvent (触摸输入事件)】

触摸输入事件 设备上报的触屏事件。 说明&#xff1a; 本模块首批接口从API version 9开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import {Action,ToolType,SourceType,Touch,TouchEvent} from ohos.multimodalInput.touchEvent;…

【Redis7】零基础篇

1 课程概述 2 Redis入门概述 2.1 是什么 Redis是基于内存的KV键值对内存数据库 Redis&#xff1a;Remote Dictionary Server(远程字典服务)是完全开源的&#xff0c;使用ANSIC语言编写遵守BSD协议&#xff0c;是一个高性能的Key-Value数据库提供了丰富的数据结构&#xff0c…

STM32F1+HAL库+FreeTOTS学习3——任务创建(动态和静态两种)

STM32F1HAL库FreeTOTS学习3——任务创建&#xff08;动态和静态两种&#xff09; 任务创建API函数任务创建流程代码实现1. 动态任务创建和删除2. 静态任务创建和删除 上期我们学习了STM32移植FreeRTOS搭建基准工程&#xff0c;现在我们来学习任务创建 任务创建API函数 前面我们…

RK3568平台(USB篇)USB HID设备

一.USB HID设备简介 USB HID设备主要用于和计算机进行交互通信&#xff0c;典型的USB HID类设备包括USB键盘、USB鼠标、USB游戏手柄等等&#xff0c;这些都是日常生活中常见的设备。以USB接口的鼠标为例&#xff0c;打开计算机的“设备管理器”&#xff0c;可以在“鼠标和其他…