梦入琼楼寒有月,行过石树冻无烟

D3 路径与线段生成器

线段


线段生成器(Line segment generator)的主要作用就是,让原本只有两个点的线段,可以被划分成无数点,通过设置通过设置线段生成器可以使得绘画出各样形状,而仅仅通过[x1,y1],[x2,y2]的方法是无法达到的,在这个情况和需求的情况下,D3 提供了路径生成器(Path Generator)的概念,可以自动根据数据生成路径,而用于生成线段的过程被称之为线段生成器(Line Generator)

line

1
2
3
4
5
6
7
8
9
10
11
12
var svg = d3.select("body")
.append("svg")
.attr("width",800)
.attr("height",800)

svg.append("line")
.attr("x1",0)
.attr("y1",400)
.attr("x2",200)
.attr("y2",10)
.attr("stroke","black")
.attr("stroke-width","3px")

path

1
2
3
4
5
6
7
8
9
var svg = d3.select("body")
.append("svg")
.attr("width",800)
.attr("height",800)

svg.append("path")
.attr("d","M20,201L300,20")
.attr("stroke","black")
.attr("stroke-width","3px")

线段生成器

线段生成器(Line Generator),主要可以通过使用d3.svg.line()方法进行创建,通过线段的点数据,和每一项的[x,y]来进行定义坐标,对于线段生成器,D3 提供了如下方法:

ID DA FA
d3.svg.line() 创建一个线段生成器
line() 使用线段生成器绘制数据
line.x() 设置或获取线段x坐标访问器(使用什么作为线段的x坐标)
line.y() 设置或获取 y坐标的访问器
line.interpolate() 设置或获取线段的插值模式
line.tension() 设置或获取张力系数 需要插值模式为:cardinal、cardinal-open、cardinal-closed时有效
line.defined 设置或获取一个访问器,用于确定线段是否存在 只有当数据存在时会被绘制

d3.svg.line()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var svg = d3.select("body")
.append("svg")
.attr("width",800)
.attr("height",800)

var lines = [[100,100],[200,200],[400,200],[500,100]]

var linePath = d3.svg.line()

svg.append("path")
.attr("d",linePath(lines))
.attr("stroke","black")
.attr("stroke-width","1px")
.attr("fill","none")

在上述的 code 中,主要提供了四个点,即他此时我们可以通过使用 d3.svg.line(lines)让其通过使用线段生成器进行创建,之后自动生成了路径为M100,100L200,200L400,200L500,100的折线路径。

访问器与 interpolate()

访问器

在D3中,访问器即line.x()line.y(),主要通过使用:

1
2
3
4
5
6
7
function x(d) {
return d[0]
}

function y(d) {
return d[1]
}

通常访问器主要的作用就是对xy坐标进行一些修改,通过使用访问器,我们可以达到经过调教很久的坐标数据,如:

1
2
3
4
5
6
7
8
9
var lines = [100,200,300,400]

var linePath = d3.svg.line()
.x(function(d) {
return d;
})
.y(function(d,i) {
return i%2==0 ? 50 : 0
})

因此我们会得到M100,50L200,0L300,50L400,0的SVG路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var padding = {
width: 1800,
height: 1800
}

var svg = d3.select("body")
.append("svg")
.attr("width",padding.width)
.attr("height",padding.height)

var lines = [100,200,300,400]

var linePath = d3.svg.line()
.x(function(d) {
return d;
})
.y(function(d,i) {
return i%2==0 ? 50 : 10
})

svg.append("path")
.attr("d", linePath(lines))
.attr("stroke", "black")
.attr("stroke-width","2px")
.attr("fill","none")

那么根据上述的lineslinePath,将会组成一组坐标即:”[100,50],[200,0],[300,50],[400,0]“,而他们的组成主要与line以及linePath有关:

interpolate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

| ID | DA |
| --- | --- |
| interpolate("```basis"```) | ![](https://49812933408852955071488026628034-1301075051.cos.ap-nanjing.myqcloud.com/20210401014352.png) |
| interpolate("```cardinal```") | ![](https://49812933408852955071488026628034-1301075051.cos.ap-nanjing.myqcloud.com/20210401014101.png) |
| interpolate("```stop```) | ![](https://49812933408852955071488026628034-1301075051.cos.ap-nanjing.myqcloud.com/20210401014259.png) |
```js
var padding = {
width: 1800,
height: 1800
}

var svg = d3.select("body")
.append("svg")
.attr("width",padding.width)
.attr("height",padding.height)

var lines = [100,200,300,400]

var linePath = d3.svg.line()
.x(function(d) {
return d;
})
.y(function(d,i) {
return i%2==0 ? 50 : 0
})
.interpolate("basis")

svg.append("path")
.attr("d", linePath(lines))
.attr("stroke", "black")
.attr("stroke-width","2px")
.attr("fill","none")
⬅️ Go back