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

当前内容所在位置

  • 第一部分 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 小节(一))
……正如您看到的那样,viewBox 属性由四个属性值组成。前两个数值指定了 viewBox 的坐标系原点(xy)。本书将统一使用 0 0,知道这些值可以调整 SVG 容器在屏幕的可见部分还是很有帮助的。viewBox 后两个数值分别指定了宽度(width)和高度(height)。它们定义了 SVG 的宽高比,并确保它能完美适应任何容器并作相应缩放而不致失真。

(……而不致失真。)这里的关键是让 SVG 的尺寸与容器相适应。此时 SVG 所在容器为 <body> 元素,而 <body> 的尺寸又常常与浏览器视口(viewport)相适应。如果视口变得非常大,SVG 也会相应变大。通常,SVG 需要一个最大宽度,以免宽度超过页面上的其他内容。因此,SVG 需要放进一个 div 里面,并让该 div 的宽度为 100%、最大宽度为 1200px。为简便起见,我们将这些样式设为行内样式;实际项目中,它们都应该来自某个 CSS 文件。注意,为了让 SVG 水平居中,还多加了一个值为 0 auto 的外边距:

<div style="width:100%; max-width:1200px; margin:0 auto;"><svg viewBox="0 0 900 300" style="border:1px solid black;"> ... </svg>
</div>

改好后,再次调整浏览器大小,看看 SVG 是否能在保持最大宽度的情况下优雅适应任意屏幕大小。该方案有助于将 D3 可视化模块注入到响应式网页中,本书后续都将采用该方案进行演示。

2 SVG 的坐标系

实现 SVG 的响应式设计后,接下来需要重点考虑 SVG 图形在容器内的定位问题。SVG 容器就像一个空白画布,我们可以在上面绘制矢量图形。矢量图形是根据基本几何原理定义的,并相对于 SVG 容器的坐标系进行定位。

SVG 坐标系类似于直角坐标系,其二维平面通过两个相互垂直的轴来定位元素,即 x 轴和 y 轴;这两个轴的起点均为 SVG 容器的 左上角,如图 1.11 所示。y 轴的正方向为 从上到下,记住它可以少走很多弯路。

图 1.11 SVG 容器坐标系与元素位置图 1.11 SVG 容器坐标系与元素位置

要在 SVG 容器内定位一个元素,可以从左上角的原点开始向右移动。这样就得到了元素的水平位置(即 x);垂直位置(即 y)则从顶部开始向下移动。这些位置信息均由 SVG 图形的呈现属性(presentational attributes)来定义。

下面来看看构建 D3 项目常见的 SVG 图形及其主要的呈现属性。我们的目标并不是编写一份涵盖所有 SVG 图形及其功能特性的全方位指南,而是希望这些基础知识不会在后续的 D3 学习中拖您后腿。

数据可视化小知识:几何基元(Geometric primitives)

出色的艺术家可以用矢量图形来绘制任何事物,但您可能是带着更实际的目标来学习 D3 的。从这个角度来看,理解几何基元(也称图形基元,graphical primitives)的概念至关重要。几何基元是一些简单的形状,如点、线、圆和矩形。这些图形可以组合成更复杂的图形,尤其便于直观地展示信息。

几何基元对于理解现实世界中复杂的信息可视化也很有用。比如本书第 11 章要构建的树形布局,在您意识到它们也不过是一些圆和线时,也就不会那么令人生畏了;当您把交互式时间线看作是矩形和点的集合时,它们就更容易理解和创建了;即使是主要以多边形、点和线的形式出现的地理数据,如果将其分解为最基本的图形结构,也就不会那么令人困惑了。

3 直线

直线元素可能是所有 SVG 图形中最简单的。它需要两个点的位置信息作属性值,并在它们之间绘制出一条直线。回到 index.html 示例文件,在 SVG 容器内添加一个 <line /> 元素,并令其 x1y1 属性分别为 5045。也就是说,该直线的起点位于 SVG 坐标系的 (50, 45)。如果从 SVG 容器的左上角开始,右移 50px、下移 45px,就会到达该起点;同理,利用属性 x2y2 可将该直线的终点坐标设为 (140, 225),如图 1.12 所示。

<svg><line x1="50" y1="45" x2="140" y2="225" />
</svg>

图 1.12 在 SVG 容器坐标系中定位直线元素图 1.12 在 SVG 容器坐标系中定位直线元素

如果保存并重新加载项目,会发现直线不可见——要让它可见,还需要设置其 stroke 属性(attribute)。stroke 用于控制直线段的描边颜色,其值与 CSS 的 color 属性(property)类似;该取值可以是一个颜色名称(blackblue …)、一个 RGB 颜色值(rgb(255,0,0))或一个十六进制值(#808080)。给直线段添加一个 stroke 描边属性,并选择合适的颜色(示例为黑色),应该就能显示了:

<line x1="50" y1="45" x2="140" y2="225" stroke="black" />

要设置线条宽度,使用 stroke-width 属性。该属性可接受一个绝对数(转换为像素)或一个相对值(%)。例如下面一行代码,直线的 stroke-width3px。如果未声明 stroke-width ,浏览器将默认取 1px

<line x1="50" y1="45" x2="140" y2="225" stroke="black" stroke-width="3" />

打开浏览器的检查工具(Inspect),找到 SVG 节点及其包含的直线。双击其中一个属性并修改它的值,观察新的属性值对直线起点或终点的影响。再尝试不同的值,以确认您充分理解了属性 x1y1x2y2 对直线位置和长度的影响。

接着,令 x1 属性值为 -20,如图 1.13 所示:

图 1.13 直线在 SVG 容器外的部分被隐藏图 1.13 直线在 SVG 容器外的部分被隐藏

看到直线的起点消失了吗? 在 SVG 中,任何位于 viewBox 之外的形状(或形状的一部分)在屏幕上都是不可见的。 此时该元素仍然在 DOM 中,并且可以访问和操作。当 SVG 元素不可见,而您又不清楚原因时,则需要首先检查该元素是否在 SVG 的 viewBox 之外!请牢牢记住,您可以随时通过开发工具查看 DOM 来找到它。前面讲过,在检查工具中只要将鼠标放到该元素上,就算它在 SVG 的 viewBox 之外,也会在视口中高亮显示。

注意

大多数 SVG 元素只需要一个自闭合标签即可(如使用 <line /> 而非 <line></line>)。与其他一些 HTML 标签一样,SVG 元素的固有结构在它们的自闭合标签内已经提供了所有必要的信息;但文本元素属于例外——其文本须放到开闭标签之间。

4 矩形

矩形元素 <rect />,顾名思义,会在屏幕上画出一个矩形。<rect /> 元素需要四个属性(attributes)才能正常显示。如图 1.14 所示,属性 xy 声明了矩形左上角的位置;属性 widthheight 分别控制其宽度和高度。在 SVG 容器中添加以下 <rect /> 元素及其属性:

<rect x="260" y="25" width="120" height="60"  fill="#6ba5d7" />

示例中,矩形的左上角位于 SVG 容器原点的右侧 260px ,下方 25px;该矩形宽 120px ,高 60px。与其他定位属性一样,这些属性值也可以用百分比来进行设置。例如将 width 设置为 50%,则该矩形将占据 SVG 容器宽度的一半。

图 1.14 在 SVG 坐标系中定位和调整矩形尺寸图 1.14 在 SVG 坐标系中定位和调整矩形尺寸

您或许注意到了,示例中的矩形被填充成了黑色。默认情况下,浏览器会将大多数 SVG 图形填充为黑色。要修改默认的填充色,可以设置元素的 fill 属性,令其值为任意 CSS 颜色值即可;要给矩形添加边框,则可以添加 stroke 属性。图 1.15 展示了几个例子。注意,如果不声明 stroke 属性,则矩形四周不会描边。此外,在最后一个示例矩形中,属性 fill-opacitystroke-opacity 可分别令 fillstroke 属性变为半透明效果。与 CSS 一样,不透明程度(opacity)可设为绝对值(介于 01 之间)或百分比(30%);与填充和描边相关的所有属性也都可以通过 CSS 文件进行设置或修改。

图 1.15 应用于矩形 SVG 图形的不同样式属性图 1.15 应用于矩形 SVG 图形的不同样式属性

如果想绘制带圆角的矩形,只需添加 rxry 属性即可,分别表示水平与垂直角半径。这些属性接受绝对值(像素)和相对值(百分比)。例如,下面矩形的每个角的半径都是 20px。将该矩形添加到示例中:

<rect x="260" y="100" width="120" height="60" rx="20" ry="20"  fill="#6ba5d7" />

讲到这您可能会问:SVG 中有没有专门画正方形的元素呢?答案是不需要——只要让 <rect /> 元素 widthheight 属性相同就行了。例如下面的 <rect /> 元素,最终将画出一个 60px × 60px 的正方形。在示例页中添加以下内容:

<rect x="260" y="175" width="60" height="60"  fill="transparent" stroke="#6ba5d7" />

作为参考,现在 SVG 画廊里有三种矩形:经典矩形、圆角矩形以及正方形。为了增添趣味性,先将颜色统一设为 #6ba5d7 ,再来玩玩它们的 strokefill 属性。注意,正方形上只有描边(stroke)是可见的,因为其 fill 属性值为 transparent(为 none 也是一样的)。这些矩形应该与图 1.16 相似,除非您更改了属性值,我们也希望您改改看!

<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" />
<rect x="260" y="175" width="60" height="60" fill="transparent" stroke="#6ba5d7" />

图 1.16 三种 SVG 矩形效果图 1.16 三种 SVG 矩形效果

关于 SVG 描边(strokes)的位置

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

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

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

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

相关文章

自动化任务:在IPython中创建和运行脚本

在数据科学和编程中&#xff0c;自动化任务是提高效率的关键。IPython提供了多种方法来创建和运行脚本&#xff0c;使得重复性任务可以被轻松自动化。本文将介绍如何在IPython中创建和运行脚本&#xff0c;帮助你更高效地完成工作。 1. 创建和保存IPython脚本 使用文本编辑器…

Spring Boot 中的微服务监控与管理

微服务的概述 微服务架构的优点和挑战 优点: 灵活性和可扩展性:微服务架构允许每个服务单独部署和扩展,这使得系统可以更灵活地适应不同的业务需求和负载变化。 使团队更加聚焦:每个微服务都有明确的职责,这使得开发团队可以更加聚焦,专注于开发他们的服务。 技术和框…

读AI新生:破解人机共存密码笔记16对人工智能的治理

1. 愚蠢的、情绪化的人类 1.1. 与完美理性所设定的不可企及的标准相比&#xff0c;我们都是极其愚蠢的&#xff0c;我们受制于各种情绪的起伏&#xff0c;这些情绪在很大程度上支配着我们的行为 1.2. 为了充分了解人类的认知&#xff0c;我们&#xff08;或者更确切地说&…

简易跨平台上传文件,前后端demo

前端文件 <!DOCTYPE html> <html> <head><title>文件上传</title> </head> <body> <h1>文件上传1-相对慢&#xff0c;需要等待本地选择的文件全部上传完成后&#xff0c;服务器再保存</h1> <form id"uploadForm…

ORA-01775: 同义词的循环链问题

一、问题描述 ORA-01775: 同义词的循环链问题 二、 原因分析 同义词对应的对象&#xff08;表等&#xff09;已删除&#xff0c;不存在了。 可能原因&#xff1a; 删除数据库对象&#xff0c;但是忘记删除同义词。删除一个用户&#xff0c;但忘记删除此用户中相关的同义词…

@Param参数

Param参数 当方法参数大于两个的时候必须传递&#xff0c;只有一个的时候可以不传。大于两个的时候也可以用#{arg0}和#{arg1}。。。来取值 Param&#xff08;&#xff09;括号里面的值对应sql语句中 # {} 里面的值 看AI的解释

模版方法模式详解:使用和实现的指南

目录 模版方法模式模版方法模式结构模版方法模式适合应用场景模版方法模式优缺点练手题目题目描述输入描述输出描述题解 模版方法模式 模板方法模式是一种行为设计模式&#xff0c; 它在超类中定义了一个算法的框架&#xff0c; 允许子类在不修改结构的情况下重写算法的特定步…

《昇思25天学习打卡营第3天|张量 Tensor》

文章目录 前言&#xff1a;今日所学&#xff1a;1. 创建张量2. 张量的属性3.张量索引与运算4. NumPy与Tensor的转换5. 稀疏张量 前言&#xff1a; 张量&#xff1f;张亮&#xff1f;张量是什么&#xff1f; 张量是一个可以用来表示在一些矢量、标量和其他张量之间的线性关系的…

高并发部署:基于 Gunicorn、Flask 和 Docker

一、准备工作 确保已经安装以下软件&#xff1a; DockerDocker ComposePython 3.x 二、创建 Flask 应用 首先&#xff0c;创建一个简单的 Flask 应用。创建一个新的目录并在其中创建以下文件&#xff1a; 1. app.py python fromflask importFlask, jsonifyapp Flask(__…

leetcode 第133场双周赛 100333.统计逆序对的数目【计数dp/滚动数组/前缀和优化】

分析&#xff1a; 先考虑如下问题。 求长度为n&#xff0c;逆序对为m的排列数量。 可以考虑dp&#xff0c;dp[i][j]定义为长度为i&#xff0c;逆序对为j的排列数量。 dp[1][0] 1; //枚举排列长度&#xff0c;或者认为枚举当前需要插到长度为i-1的排列中的数字 for(int i 1…

OpenAI封杀不支持地区API:违规封号,7月9日生效

OpenAI 在检测用户使用其 API 的地区后&#xff0c;提示所有不支持位置的用户 昨晚&#xff0c;很多大模型应用的开发者、程序员都收到了 OpenAI 的警告信&#xff0c;心里一惊。 OpenAI 在检测用户使用其 API 的地区后&#xff0c;提示所有不支持位置的用户&#xff1a;即将封…

冒泡排序、选择排序、插入排序~java版

1、冒泡排序&#xff08;Bubble Sort&#xff09; 冒泡排序的基本思想是多次遍历待排序序列&#xff0c;每次遍历时两两比较相邻元素&#xff0c;如果顺序不对则交换&#xff0c;直到整个序列有序为止。 public class BubbleSort {public static void bubbleSort(int[] arr) …

图书管理系统(附源码)

前言&#xff1a;前面一起和小伙伴们学习了较为完整的Java语法体系&#xff0c;那么本篇将运用这些知识连串在一起实现图书管理系统。 目录 一、总体设计 二、书籍与书架 书籍&#xff08;Book&#xff09; 书架&#xff08;Booklist&#xff09; 三、对图书的相关操作 I…

已解决问题 | 该扩展程序未列在 Chrome 网上应用店中,并可能是在您不知情的情况下添加的

在Chrome浏览器中&#xff0c;如果你看到“该扩展程序未列在 Chrome 网上应用店中&#xff0c;并可能是在您不知情的情况下添加的”这样的提示&#xff0c;通常是因为该扩展程序没有通过Chrome网上应用店进行安装。以下是解决这个问题的步骤&#xff1a; 解决办法&#xff1a;…

Spring Boot整合Redis缓存的最佳实践

Spring Boot整合Redis缓存的最佳实践 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代应用开发中&#xff0c;缓存是提升系统性能和响应速度的关键技术之…

kali/ubuntu安装vulhub

无须更换源&#xff0c;安装docker-compose apt install docker.io docker -vdocker-compose #提示没有&#xff0c;输入y安装mkdir -p /etc/docker vi /etc/docker/daemon.json #更换dockerhub国内源┌──(root㉿kali)-[/home/kali/vulhub-master/tomcat/CVE-2017-12615] …

【VScode】常规插件安装

以下是VScode常规插件安装&#xff1a; C/C C/C extension pack C/C themes Draw.io integration highlight 以上插件安装完毕后&#xff0c;可实现 字体高亮&#xff0c;自动补齐&#xff0c;函数跳转&#xff0c;主题切换&#xff0c;图表生成等常用功能。

中介子方程三十七

XXFXXuXXWXXuXXdXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXdXXuXWXπXXWXeXyXeXbXπXpXXNXXqXeXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXeXqXXNXXpXπXbXeXyXeXWXXπXWXuXXdXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXdXXuXXW…

【TensorFlow深度学习】对比学习的核心:实例与上下文的对抗

对比学习的核心&#xff1a;实例与上下文的对抗 对比学习概述实例与上下文的对抗&#xff1a;核心机制实战代码示例&#xff1a;使用PyTorch实现SimCLR结语 在深度学习的浩瀚星海中&#xff0c;对比学习作为自我监督学习的一个分支&#xff0c;正以破竹之势引领着无标注数据利用…

dledger原理源码分析系列(三)-选主

简介 dledger是openmessaging的一个组件&#xff0c; raft算法实现&#xff0c;用于分布式日志&#xff0c;本系列分析dledger如何实现raft概念&#xff0c;以及dledger在rocketmq的应用 本系列使用dledger v0.40 本文分析dledger的选主 关键词 Raft Openmessaging 心跳/选…