当前位置: 首页 > news >正文

【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 图形实际宽度的影响

相关文章:

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

当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知 1.2.1 HTML 与 DOM1.2.2 SVG - 可缩放矢量图形 ✔️ 第一部分【第二部分】✔️第三部分&#xff08;精译中 ⏳&#xff09; 1.2.3 Canvas 与 WebGL&#x…...

Java中的Monad设计模式及其实现

Java中的Monad设计模式及其实现 在函数式编程中&#xff0c;Monad是一种重要的设计模式&#xff0c;用于处理包含隐含计算信息&#xff08;如计算顺序、环境、状态、错误处理等&#xff09;的计算。Monad提供了一种结构&#xff0c;使得可以将计算链式连接起来&#xff0c;每一…...

Dahlia Hart: Stylized Casual Character(休闲角色模型)

此包包含两个发型和两个服装&#xff0c;每个都有多种颜色选择。每个发型都适合与物理资源一起使用&#xff0c;并包含各种表情和音素混合形状。 下载&#xff1a;​​Unity资源商店链接资源下载链接 效果图&#xff1a;...

vector容器

以下是关于vector容器的总结 1、构造容器 2、容器赋值 3、获取容量capacity和大小size 4、插入和删除 5、数据存取 6、互换容器和预留空间 #include <iostream> #include <vector>using namespace std; // vector数据结构和数组非常相似&#xff0c;也称为单端数组…...

二进制常用知识整理<java>

1、进制转换&#xff1a; int转二进制&#xff1a; public static void main(String[] args) {int a 0b100;//0b表示后面的为二进制表示&#xff0c;0开始表示八进制System.out.println(a);System.out.println(Integer.toBinaryString(a));System.out.println(Integer.toStr…...

基于Docker的淘客返利平台部署

基于Docker的淘客返利平台部署 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在本文中&#xff0c;我们将探讨如何利用Docker技术来部署一个淘客返利平台。Doc…...

【涵子来信科技潮流】——WWDC24回顾与暑假更新说明

期末大关&#xff0c;即将来袭。在期末之前&#xff0c;我想发一篇文章&#xff0c;介绍有关WWDC24的内容和暑假中更新的说明。本篇文章仅为个人看法和分享&#xff0c;如需了解更多详细内容&#xff0c;请通过官方渠道或者巨佬文章进行进一步了解。 OK, Lets go. 一、WWDC24 …...

重温react-08(createContext使用方式)

react中的createContext使用方式 简介一下&#xff0c;就是组件之间可以互相通信的比较好用的传值方式&#xff0c;话不多说直接上代码。 以下介绍的是类组件中的方式&#xff0c;在函数组件中不是如此使用的。 定义一个通用的方法 import { createContext } from "react…...

LInux后台运行程序

测试c代码 #include <stdio.h> #include <unistd.h> int main() {for (int i;; i) {printf("b数值 %d\n", i);fflush(stdout);sleep(3);} }使用CtrlZ可以将当前正在运行的程序放到后台并暂停它。如果你想要继续这个暂停的程序&#xff0c;可以使用fg命令…...

DEBOPIE框架:打造最好的ChatGPT交易机器人

本文介绍了如何利用 DEBOPIE 框架并基于 ChatGPT 创建高效交易机器人&#xff0c;并强调了在使用 AI 辅助交易时需要注意的限制以及操作步骤。原文: Build the Best ChatGPT Trading Bots with my “DEBOPIE” Framework 如今有大量文章介绍如何通过 ChatGPT 帮助决定如何以及在…...

C++ Thead多线程 condition_variable 与其使用场景---C++11多线程快速学习

std::condition_variable 的步骤如下&#xff1a; 创建一个 std::condition_variable 对象。 创建一个互斥锁 std::mutex 对象&#xff0c;用来保护共享资源的访问。 在需要等待条件变量的地方 使用 std::unique_lock<std::mutex> 对象锁定互斥锁 并调用 std::conditio…...

什么是前端开发?

前端开发是什么一种工作&#xff1f;这里以修房子举例&#xff1a; jquery根据数据去生成对应的html代码。首先得有一个html代码的“房屋构造”&#xff0c;然后根据数据去填充“房屋构造”的“血肉”&#xff0c;最后JavaScript通过事件等方法给一砖一瓦修好的房屋添加“灵魂…...

大数据面试题之Spark(1)

目录 Spark的任务执行流程 Spark的运行流程 Spark的作业运行流程是怎么样的? Spark的特点 Spark源码中的任务调度 Spark作业调度 Spark的架构 Spark的使用场景 Spark on standalone模型、YARN架构模型(画架构图) Spark的yarn-cluster涉及的参数有哪些? Spark提交jo…...

Spring Boot 和 Spring Framework 的区别是什么?

SpringFramework和SpringBoot都是为了解决在Java开发过程中遇到的各种问题而出现的。了解它们之间的差异&#xff0c;能够更好的帮助我们使用它们。 SpringFramework SpringFramework是一个开源的Java平台&#xff0c;它提供了一种全面的架构和基础设施来支持Java应用程序的开…...

JVM原理(四):JVM垃圾收集算法与分代收集理论

从如何判定消亡的角度出发&#xff0c;垃圾收集算法可以划分为“引用计数式垃圾收集”和“追踪式垃圾收集”两大类。 本文主要介绍的是追踪式垃圾收集。 1. 分代收集理论 当代垃圾收集器大多遵循“分代收集”的理论进行设计&#xff0c;它建立在两个假说之上&#xff1a; 弱分…...

1961 Springboot自习室预约系统idea开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 自习室预约管理系统是一套完善的信息系统&#xff0c;结合springboot框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库…...

前端面试题(12)答案版

1. H5的新特性&#xff1f; 1) 更加语义化的标签,如<header>、<nav>、<article>等,便于网页结构的表达。 2) 新的多媒体标签,如<video>和<audio>,支持本地视频和音频的播放。 3) 本地存储API,如localStorage和sessionStorage,用于在客户端保存数…...

SpringMVC 域对象共享数据

文章目录 1、使用ServletAPI向request域对象共享数据2、使用ModelAndView向request域对象共享数据3、使用Model向request域对象共享数据4、使用map向request域对象共享数据5、使用ModelMap向request域对象共享数据6、Model、ModelMap、Map的关系7、向session域共享数据8、向app…...

每天五分钟深度学习框架pytorch:tensor向量之间常用的运算操作

本文重点 在数学中经常有加减乘除运算,在tensor中也不例外,也有类似的运算,本节课程我们将学习tensor中的运算 常见运算 加法+或者add import torch import numpy as np a=torch.rand(16,3,28,28) b=torch.rand(1,3,28,28) print(a+b) import torch import numpy as np a…...

【数据结构】(C语言):栈

栈&#xff1a; 线性的集合。后进先出&#xff08;LIFO&#xff0c;last in first out&#xff09;。两个指针&#xff1a;指向栈顶和栈底。栈顶指向最后进入且第一个出去的元素。栈底指向第一个进入且最后一个出去的元素。两个操作&#xff1a;入栈&#xff08;往栈尾添加元素…...

扩散浓度曲线计算:从实例看 Pandat 代算与自行操作

扩散浓度曲线计算(Pandat代算或自己操作) 实例33: Al-4.06at%Mg/Al扩散偶在781K下退火36960s&#xff0c;Mg元素浓度随距离的变化曲线及实验数据对比如图a所示&#xff1b;Al-11at%Mg/Al扩散偶在773K下退火86400s&#xff0c;Mg元素浓度随距离的变化曲线及实验对比如图b所示&am…...

嵌入式SD卡文件处理轻量级工具库LC_SDTools

1. LC_SDTools 库概述LC_SDTools 是一个面向嵌入式 SD 卡文件系统应用的轻量级工具库&#xff0c;专为解决裸机或 RTOS 环境下 SD 卡文件操作中高频缺失的基础能力而设计。其核心定位并非替代 FatFs、LittleFS 或 ChibiOS FAT 模块等完整文件系统栈&#xff0c;而是作为上层应用…...

【空气涡轮发动机Matlab_simulink动态仿真模型 ✔【空气涡轮发动机Matlab_simulink动态仿真模型】 1、部件级模型;进气道,涡轮,气室,压气机,尾喷管,转子模块,容积模块 2、

【空气涡轮发动机Matlab/simulink动态仿真模型 ✔【空气涡轮发动机Matlab/simulink动态仿真模型】 1、部件级模型;进气道&#xff0c;涡轮&#xff0c;气室&#xff0c;压气机&#xff0c;尾喷管&#xff0c;转子模块&#xff0c;容积模块 2、PID控制器: 输出扭矩阶跃扰动下&am…...

onnx之优化器

之前的OpenPPL有个章节讲到过优化器&#xff0c;onnx里面也有个优化器&#xff0c;相关介绍如下一、优化器的本质ONNX Core Optimizer 是在图级别工作的&#xff0c;与EP&#xff08;Execution Provider&#xff09;无关。textONNX模型&#xff08;计算图&#xff09;→ Optimi…...

无线通信天线与MIMO技术解析

1. 无线通信中的天线基础认知所有依赖无线通信的电子设备&#xff0c;其信号传输质量都取决于一个核心部件——天线。作为电磁波与电信号之间的转换器&#xff0c;天线性能直接决定了数据传输的稳定性和速率。在消费电子领域&#xff0c;我们最常见的天线形态主要有三种&#x…...

IC设计新手必看:Formality形式验证从入门到精通的5个关键步骤

IC设计新手必看&#xff1a;Formality形式验证从入门到精通的5个关键步骤 在芯片设计流程中&#xff0c;形式验证&#xff08;Formal Verification&#xff09;是确保设计功能正确性的重要环节。不同于传统的仿真验证&#xff0c;形式验证通过数学方法穷举所有可能的输入组合&a…...

Qwen3.5-35B-AWQ-4bit企业应用指南:教育题图解析、医疗影像初筛、办公文档理解

Qwen3.5-35B-AWQ-4bit企业应用指南&#xff1a;教育题图解析、医疗影像初筛、办公文档理解 1. 引言&#xff1a;当AI学会“看图说话”&#xff0c;企业效率能提升多少&#xff1f; 想象一下这样的场景&#xff1a;一位老师需要快速从几十张试卷中找出典型错题&#xff0c;一位…...

5个Adobe-GenP实用技巧:从安装到完美运行Photoshop

5个Adobe-GenP实用技巧&#xff1a;从安装到完美运行Photoshop 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP Adobe-GenP是一款强大的Adobe Creative Cloud通用补丁…...

OpenClaw局域网访问配置

根据OpenClaw最新官方文档&#xff08;截至2026年3月&#xff09;&#xff0c;以下是更新后的局域网访问配置指南&#xff0c;整合了网络架构、安全加固和自动化配对等新特性&#xff1a;一、核心配置命令&#xff08;基于新版网关协议&#xff09;启用LAN多接口监听 使用新参数…...

Java 使用国密算法实现数据加密传输

本文是混合加密&#xff1a;前端 SM2 SM4&#xff0c;后端 Spring Boot Hutool 解密的完整示例。 方案的逻辑是&#xff1a; 前端随机生成一个 SM4 key 用 SM4 加密整个业务 JSON 用后端提供的 SM2 公钥 加密这个 SM4 key 后端先用 SM2 私钥 解出 SM4 key 再用 SM4 解出…...