📜  D3.js 轮廓 API 完整参考(1)

📅  最后修改于: 2023-12-03 14:40:35.584000             🧑  作者: Mango

D3.js 轮廓 API 完整参考

D3.js Logo

D3.js 是一个流行的 JavaScript 数据可视化库。它提供了一系列的API,使得用户可以轻松地创建各种形式的可视化效果。D3.js 轮廓 API 是其中的一个重要模块,主要用于生成包括点、线、面等等不同几何图形的轮廓及其相应的边界框、偏移量和插值。

前置知识

在了解 D3.js 轮廓 API 之前,你需要了解以下几个概念:

  1. SVG: SVG 是可缩放矢量图形,是一种使用 XML 描述 2D 图形的语言。在 D3.js 中,我们使用 SVG 元素来创建各种类型的图形。

  2. 投影: 投影是将球面地理坐标系转换为平面坐标系的方式。D3.js 提供了众多的投影方式,如 Albers 等锥形等面积投影,以及 Mercator 等圆柱投影。

  3. 几何体: 在 D3.js 中,几何体是指具有一定几何形状属性(如穷点、线、面)的对象。在轮廓 API 中,我们主要使用 Point-对象(点)、Line-对象(线)和Area-对象(面)。

使用轮廓 API

D3.js 轮廓 API 主要用于生成从几何数据到 SVG 路径字符串的映射。在 D3.js 中,轮廓 API 由 d3.geo 命名空间提供。要使用 D3.js 轮廓 API,你需要引入 D3.js 库(可以从官方网站下载),然后使用下面语句:

import { geoPath } from "d3-geo";

或者,你可以通过 script 标签将 D3.js 库引入到 HTML 页面:

<script src="https://d3js.org/d3.v6.min.js"></script>

<script>
// your code here
</script>

在引入 D3.js 库之后,你就可以使用 geoPath 方法生成到 SVG 路径字符串的映射了。

const path = geoPath();

默认情况下,geoPath 会返回一个针对 Mercator 投影的映射函数。如果你需要使用其他的投影方式,可以使用 projection 方法:

const projection = d3.geoAlbers();
const path = geoPath().projection(projection);

在生成到 SVG 路径字符串的映射之后,你可以使用 path 方法将不同几何体对象映射为 SVG 路径字符串:

const point = { type: "Point", coordinates: [100, 200]};
const line = { type: "LineString", coordinates: [[100, 200], [300, 400]]};
const area = { type: "Polygon", coordinates: [[[100, 200], [300, 400], [200, 300]]]};

console.log(path(point)); // M-446301.38788093314 3953419.299551408Z
console.log(path(line)); // M-446301.38788093314 3953419.299551408L-362077.5913586409 3728016.417625346Z
console.log(path(area)); // M-446301.38788093314 3953419.299551408L-362077.5913586409 3728016.417625346L-401466.0724482739 3740934.369663345Z

除了生成基本的 SVG 路径字符串之外,D3.js 轮廓 API 还支持更加丰富的路径链式操作,如生成边界框、偏移量、插值等。下面,我们将介绍这些路径链式操作。

轮廓 API 详解
基本使用

D3.js 轮廓 API 支持以下类型的几何对象:

| 几何类型 | 描述 | 示例 | |-------------------------|-----------|--------------------------------------------------------| | Point<Coordinates> | 点 | {type: "Point", coordinates: [100, 200]} | | LineString<Coordinates> | 线 | {type: "LineString", coordinates: [[100,200],[300,400]]} | | Polygon<Coordinates> | 面、多边形 | {type: "Polygon", coordinates: [[[100,200],[300,400],...]]} | | MultiPoint<Coordinates> | 对象数组,每个对象为点 | {type: "MultiPoint", coordinates:[[100,200],[300,400]]} | | MultiLineString<Coordinates> | 对象数组,每个对象为线 | {type: "MultiLineString", coordinates:[[[100,200],[300,400]],...]]} | | MultiPolygon<Coordinates> | 对象数组,每个对象为面 | {type: "MultiPolygon", coordinates:[[[[100,200],[300,400],...]]]} |

其中,Coordinates 是指具有 longitudelatitude 属性的对象,或者是一个由 longitudelatitude 组成的坐标数组。

生成边界框

在 D3.js 轮廓 API 中,你可以使用 bounds 方法为几何体对象生成边界框数据。边界框是一个包含四个值的数组,依次分别表示左上角和右下角的经纬度坐标。你可以使用以下方式进行调用:

const bounds = path.bounds(geometry);

这里的 geometry 指的是一个由轮廓 API 支持的几何体对象。例如,你可以使用如下方式生成一个简单的矩形:

const geometry = { type: "Polygon", coordinates: [[[100, 200], [300, 400]]]};
const bounds = path.bounds(geometry);
console.log(bounds); // [[-446301.38788093314, 3728016.417625346], [-362077.5913586409, 3953419.299551408]]

通过上述方式,你可以获取到包含左上角和右下角坐标的边界框数据,然后可以根据需要进行不同类型的操作。

生成插值元素

D3.js 轮廓 API 还支持一些用于生成插值元素的方法,用于为不同的几何体对象生成相应的插值元素。例如,你可以使用 centroid 方法为多点几何体对象生成中心点:

const geometry = { type: "MultiPoint", coordinates:[[100,200],[300,400]]};
const centroid = path.centroid(geometry);
console.log(centroid); // [791777.6460446373, 4673730.389201153]

可以看到,这里返回的值是一个数组,依次代表生成的插值元素的 x 和 y 坐标。D3.js 还支持 measure, length, area 等方法,这里不做过多介绍,有兴趣的读者可以自行阅读 D3.js 官方文档。

生成图形

最后,我们来看一个完整的示例。下面的代码将使用 D3.js 轮廓 API 创建一个 SVG 元素,并在其中绘制一个简单的地图。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>D3.js Example</title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
  </head>
  
  <body>
    <svg width="500" height="500"></svg>
    <script type="text/javascript">
      const projection = d3.geoMercator();
      const path = d3.geoPath().projection(projection);
      const svg = d3.select("svg");

      d3.json("https://d3js.org/world-110m.v1.json").then(data => {
        svg.append("g")
          .attr("class", "countries")
          .selectAll("path")
          .data(data.features)
          .enter()
          .append("path")
            .attr("d", path)
            .style("fill", "gray")
            .style("stroke", "white")
            .style("stroke-width", 0.5);
      });
    </script>
  </body>
</html>

在上面的代码中,我们首先创建了一个调用了 Mercator 投影的 projection 对象,然后在 SVG 元素中创建了一个 countries 的组元素,并为其中的每一个路径元素设置颜色、描边、描边宽度等属性。最终,我们在 SVG 元素中成功地绘制了一个简单的地图。

至此,我们介绍了 D3.js 轮廓 API 的主要用法和相关概念,希望对你有所帮助。