D3的API学习

d3-selection

Selections 允许强大的数据驱动文档对象模型 (DOM): 设置 attributes, styles, properties, HTML 或 text 内容等等。使用 data join 的 enter 和 exit 选择集可以用来根据具体的数据 add 或 remove 元素。

选择集的方法通常选择当前的选择集或者新的选择集,因此允许进行链式调用。例如为所有的 p 元素设置类和样式:

d3.selectAll("p")
    .attr("class", "graf")
    .style("color", "red");

等价于:

var p = d3.selectAll("p");
p.attr("class", "graf");
p.style("color", "red");

按照惯例,返回当前选择集的方法前设置 4 个空格缩进,返回新的选择集的则使用 2 个空格缩进。这种写法有助于在链式调用中发现选择集的变化:

d3.select("body")
  .append("svg")
    .attr("width", 960)
    .attr("height", 500)
  .append("g")
    .attr("transform", "translate(20,20)")
  .append("rect")
    .attr("width", 920)
    .attr("height", 460);

选择集是不可变的。影响被选中的元素 (或顺序) 的方法都会返回一个新的选择集,而不是在当前选择集上进行修改然后返回。但是请注意,元素必然是可变的,因为元素不变还谈什么数据驱动文档。

Selecting Elements

选择集接收 W3C selector strings(选择字符串) 比如 .fancy 用来选择类名为 fancy 的元素, div 可以用来选择 DIV 元素。选择元素有两种模式: select 和 selectAll: select 只会选中第一个符合条件的元素与,而 selectAll 则会选中所有符合条的元素。两个顶级的选择方法: d3.select 和 d3.selectAll 的查找范围为整个文档。两个子选择方法: selection.select 和 selection.selectAll 则会将查找范围限制为selection 的后代元素。

d3.select(selector)

选中符合条件的第一个元素,选择条件为 selector 字符串。如果没有元素被选中则返回空选择集。如果有多个元素都符合条件则返回包含第一个 (文档顺序) 匹配的元素的选择集。例如选择第一个 a 元素:

var anchor = d3.select("a");

selector 除是字符串之外还可以是指定的节点,在已经对节点有引用的时候是很有用的。比如在事件监听器回调内 this 指向节点时就可以使用这种方法将其转换为选择集实例:

d3.selectAll("p").on("click", function() {
  d3.select(this).style("color", "red");
});

d3.selectAll(selector)

选择所有与指定的 selector 匹配的元素。被选中的元素顺序会按其在文档中的顺序排列(从上到下)。如果没有元素被选中,或者 selector 为 null 或 undefined 则返回空选择集。例如选择所有的 p 元素:

var paragraph = d3.selectAll("p");

selector 除字符串之外还可以是节点数组。如果已经对节点有引用时会很有用,比如在事件回调内将 this.childNodes 或 document.links 传递给选择器。节点可以是一个伪数组,比如NodeList 或 arguments,比如将所有链接的颜色改为红色:

d3.selectAll(document.links).style("color", "red");

Joining Data

Handling Events
Control Flow
Local Variables
Namespaces

d3-scale比例尺

比例尺可以对任何视觉编码进行映射,比如颜色,描边的宽度或者符号的大小。比例尺也可以用来对任意类型的数据进行映射,比如分类数据或离散的数据。
这个模块不会提供颜色方案,可以参考 d3-scale-chromatic (opens new window) 来获取需要的颜色方案。

Continuous (Linear, Power, Log, Identity, Time)

Sequential

Diverging

Quantize

Quantile

Threshold

Ordinal (Band, Point)

序数比例尺的输出域和输入域都是离散的。例如序数比例尺可以将一组命名类别映射到一组颜色(例如:d3.scaleOrdinal(nodeGroups, colors))。或者确定一组条形图在水平方向的位置等等。

d3.scaleOrdinal([range])

使用空的输入域和指定的 range 构造一个序数比例尺。如果没有指定 range 则默认为空数组。序数比例尺在定义非空的输入域之前,总是返回 undefined。

d3-color颜色

浏览器可以解析很多种颜色, 但是不能帮你处理颜色. d3-color 模块提供各种空间的颜色表示, 并支持在各种颜色空间之间进行转换和操作.

d3.color(specifier) 

将 CSS Color Module Level 3指定的颜色字符串转换并返回 RGB 或 HSL 颜色表示. 如果指定的字符串不可用, 则返回null:

rgb(255, 255, 255)
rgb(10%, 20%, 30%)
rgba(255, 255, 255, 0.4)
rgba(10%, 20%, 30%, 0.4)
hsl(120, 50%, 20%)
hsla(120, 50%, 20%, 0.4)
#ffeeaa
#fea
steelblue由 CSS 支持的 named colors

注意:这个方法可以通过 instanceof 来判断一个对象是否为颜色实例. 各个颜色子类也是如此, 可以用来判断一个对象是否为指定的颜色空间实例.

color.opacity
设置 color 的透明度, 范围 [0,1].
color.rgb()
返回颜色的 RGB 表示. 对于RGB颜色则返回自身.
color.brighter([k])
返回基于某个颜色的更亮的副本. 如果指定了 k 则表示调整的亮度系数. 如果没有指定 k 则默认为 1. 这个操作的实现依赖于具体的颜色空间.
color.darker([k])
返回基于某个颜色的更暗的副本. 如果指定了 k 则表示调整的暗度系数. 如果没有指定 k 则默认为 1. 这个操作的实现依赖于具体的颜色空间.
color.displayable()
当且仅当在标准的硬件上支持显示该颜色时才会返回 true. 例如当使用 RGB 颜色空间时, 其中一个颜色通道值小于 0 或大于 255 或者透明度值不在 [0, 1] 范围内都会返回 false.
color.toString()
根据 CSS Object Model specification(对象模型规范)返回颜色的字符串标识, 比如 rgb(247, 234, 186). 如果颜色不可显示, 则会返回一个经过调整的可显示的值. 比如 RGB 颜色空间中某个通道值大于 255 时会自动将其调整为 255.

d3.rgb(r, g, b[, opacity]) 
d3.rgb(specifier)
d3.rgb(color)
d3.hsl(h, s, l[, opacity]) 
d3.hsl(specifier)
d3.hsl(color)

d3.lab(l, a, b[, opacity])
d3.lab(specifier)
d3.lab(color)

d3.hcl(h, c, l[, opacity])
d3.hcl(specifier)
d3.hcl(color)

d3.cubehelix(h, s, l[, opacity])
d3.cubehelix(specifier)
d3.cubehelix(color)

Color Schemes (d3-scale-chromatic)

这个模块提供了用来表示序列、发散以及分类的颜色方案,它的设计是用来和 d3-scale的 d3.scaleOrdinal 和 d3.scaleSequential 结合使用。

Categorical

d3.schemeCategory10 -十个分类颜色的数组,表示为 RGB 十六进制字符串。
d3.schemeAccent -八个分类颜色的数组,表示为 RGB 十六进制字符串。
d3.schemeDark2 -八个分类颜色的数组,表示为 RGB 十六进制字符串。
d3.schemePaired -
d3.schemePastel1 -
d3.schemePastel2 -
d3.schemeSet1 -
d3.schemeSet2 -
d3.schemeSet3 -

Diverging

d3.interpolateBrBG -
d3.interpolatePiYG -
d3.interpolatePRGn -
d3.interpolatePuOr -
d3.interpolateRdBu -
d3.interpolateRdGy -
d3.interpolateRdYlBu -
d3.interpolateRdYlGn -
d3.interpolateSpectral -
d3.schemeBrBG -
d3.schemePiYG -
d3.schemePRGn -
d3.schemePuOr -
d3.schemeRdBu -
d3.schemeRdGy -
d3.schemeRdYlBu -
d3.schemeRdYlGn -
d3.schemeSpectral -

Sequential (Single Hue)

d3.interpolateBlues -
d3.interpolateGreens -
d3.interpolateGreys -
d3.interpolateOranges -
d3.interpolatePurples -
d3.interpolateReds -
d3.schemeBlues -
d3.schemeGreens -
d3.schemeGreys -
d3.schemeOranges -
d3.schemePurples -
d3.schemeReds -

Sequential (Multi-Hue)

d3.interpolateBuGn -
d3.interpolateBuPu -
d3.interpolateCool -
d3.interpolateCubehelixDefault -
d3.interpolateGnBu -
d3.interpolateInferno -
d3.interpolateMagma -
d3.interpolateOrRd -
d3.interpolatePlasma -
d3.interpolatePuBu -
d3.interpolatePuBuGn -
d3.interpolatePuRd -
d3.interpolateRdPu -
d3.interpolateViridis -
d3.interpolateWarm -
d3.interpolateYlGn -
d3.interpolateYlGnBu -
d3.interpolateYlOrBr -
d3.interpolateYlOrRd -
d3.schemeBuGn -
d3.schemeBuPu -
d3.schemeGnBu -
d3.schemeOrRd -
d3.schemePuBu -
d3.schemePuBuGn -
d3.schemePuRd -
d3.schemeRdPu -
d3.schemeYlGn -
d3.schemeYlGnBu -
d3.schemeYlOrBr -
d3.schemeYlOrRd -

Cyclical

d3.interpolateRainbow

(opens new window) - the “less-angry” rainbow
d3.interpolateSinebow

(opens new window) - the “sinebow” smooth rainbow

集合d3-collection

几种常用的键值对类型的数据结构

map

与 ES6 Maps类似, 但是有以下几点不同:

d3.maps 的 Keys 会被强制转为字符串.
使用 map.each 遍历, 而不是 map.forEach. (并且没有 thisArg 参数.)
使用 map.remove, 而不是 map.delete
map.entries 返回 {key, value} 对象数组而不是 [key, value] 迭代器.
map.size 是一个方法而不是 property; 
map.empty 同样也是方法不是属性.
d3.map([object[, key]]) 

构建一个新的 map. 如果指定了 object 则将其所有的可枚举对象复制到 map 中. object 可以是一个数组也可以是其他的 map 对象.可选的 key 方法用来指定使用哪个属性作为key, 比如:

var map = d3.map([{name: "foo"}, {name: "bar"}], function(d) { return d.name; });
map.get("foo"); // {"name": "foo"}
map.get("bar"); // {"name": "bar"}
map.get("baz"); // undefined

参考 nests.

map.has(key)
当且仅当 map 中包含指定的 key 的时候返回 true, 要注意其对应的 value 可能为 null 或者 undefined
map.get(key)
返回指定的 key 对应的值,如果 map 中不包含指定的 key 则返回 undefined
map.set(key, value)
设置 map 中指定的 key 为 value, 如果已经有相同的 key 字符串则会被覆盖,此方法返回 map 对象因此可以链式调用. 例如:
map.remove(key)
如果 map 中包含指定的 key 则将其删除并返回 true, 否则什么都不做并返回 false.
map.clear()
清空 map 中所有的项
map.keys()
以数组的形式返回 map 中所有的 keys, 顺序是不可靠的.
map.values()
以数组的形式返回 map 中所有的 value, 顺序是不可靠的.
map.entries()
将 map 中所有的项重组为 key-value 数组. 顺序是随意的.每一项中 key 必须是字符串, 但是对应的 value 可以是任意的类型.
map.each(function)
遍历 map 中的每一项, 并对每一项执行 function, 当前项的 value 和 key 作为参数, 随后是 map 本身, 返回 undefined.
map.empty()
当且仅当 map 中没有任何项时返回 true.
map.size()
返回 map 中项的个数.

Sets

拖拽d3-drag

将指针指向目标对象,按下并且拖动它到一个新的位置,然后释放。D3 的 drag behavior 提供了方便灵活并且抽象的拖拽交互。

d3.drag()

创建一个新的拖拽行为并返回自身。drag 既是一个对象,也是一个函数,通常通过 selection.call 被应用在选中的元素上。

drag(selection)

将拖拽应用到指定的selection。通常不适用这个方法应用拖拽,而是通过 selection.call。例如,将拖拽实例应用到一个选择集上:

d3.selectAll(".node").call(d3.drag().on("start", started));

Drag Events

当 drag event listener 被调用时, d3.event会被设置为当前的拖拽事件,event 对象暴露以下属性:

target - 相关联的drag behavior.
type - 字符串 “start”, “drag” 或 “end”; 参考 drag.on.
subject - 通过 drag.subject定义的subject.
x - subject 的 x-坐标; 参考 drag.container.
y - subject 的 y-坐标; 参考 drag.container.
dx - 与上一次拖拽相比 x-坐标 的变化.
dy - 与上一次拖拽相比 y-坐标 的变化.
identifier - 字符串 “mouse”, 或者表示 touch identifier的数字.
active - 当前活动的拖拽手势的数量(在start和end, 不包含这个).
sourceEvent - 底层原始事件比如 mousemove 或 touchmove.

event.active 属性对判断并发的拖拽手势序列中的 start 事件和 end 事件: 在拖拽手势开始时为0,在拖拽结束最后一个手势事件时为0。
event 对象也暴露了 event.on 方法.

d3-force

这个模块实现了用以模拟粒子物理运动的 velocity Verlet
(opens new window) 数值积分器。仿真思路如下: 它假设任意单位时间步长 Δt = 1,所有的粒子的单位质量常量 m = 1。作用在每个粒子上的合力 F 相当于在单位时间 Δt 内的恒定加速度 a。并且可以简单的通过为每个粒子添加速度并计算粒子的位置来模拟仿真。

Forces

force(力模型) 是一个用以修改节点位置和速度的函数;在力模型上下文中,force 可以施加电荷或重力之类的经典物理力学,也可以用来解决几何约束,例如将节点保持在边界框内或者保持节点之间的相对距离。例如将节点移动到原点 ⟨0,0⟩ 的简单力学模型可以实现如下:

function force(alpha) {
  for (var i = 0, n = nodes.length, node, k = alpha * 0.1; i < n; ++i) {
    node = nodes[i];
    node.vx -= node.x * k;
    node.vy -= node.y * k;
  }
}

// 只在初始化时被调用,可选的
force.initialize = function (nodes) {
  // do something
}

const simulation = d3.forceSimulation()
  .force('myForce', force)

仿真通常需要多个力学模型的组合,下面是内置的几种力学模型:

Centering(向心力)
Collision(碰撞检测)
Links(弹簧力)
Many-Body(电荷力)
Positioning

Links

link froce(弹簧模型) 可以根据 link distance 将有关联的两个节点拉近或者推远。力的强度与被链接两个节点的距离成比例,类似弹簧力。

d3.forceLink([links])

根据指定的 links 以及默认参数创建一个弹簧力模型。如果没有指定 links 则默认为空数组。

link.links([links])

如果指定了 links 则将其设置为该弹簧力模型的关联边数组,并重新计算每个边的 distance 和 strength 参数,返回当前力模型。如果没有指定 links 则返回当前力模型的边数组,默认为空。
每个边都是都是一个包含以下属性的对象:

source - 边的源节点; 参考 simulation.nodes
target - 边的目标节点; 参考 simulation.nodes
index - 基于 0 的在 links 中的索引, 会自动分配

为方便起见,边的源和目标节点可以在初始时使用索引或者字符串标识符,而不一定非要为对象引用。参考 link.id。当弹簧力被 initialized(或者重新初始化,节点或者边改变),任何不是引用的 link.source or link.target 都会根据指定的标识符被转为 node 引用形式。
如果指定的 links 数组被修改,比如添加或者移除边,这个方法必须使用新的数组重新调用一次,这个方法不会创建指定数组的副本。

link.id([id])

如果指定了 id 则将节点的 id 访问器设置为指定的函数并返回弹簧模型。如果 id 没有指定则返回当前的节点 id 访问器,默认为数值类型的节点索引 node.index:

function id(d) {
  return d.index;
}

默认的 id 访问器允许每个边的源节点和目标节点为基于 0 的 nodes 数组的节点索引。例如:

var nodes = [
  {"id": "Alice"},
  {"id": "Bob"},
  {"id": "Carol"}
];

var links = [
  {"source": 0, "target": 1}, // Alice → Bob
  {"source": 1, "target": 2} // Bob → Carol
];

现在可以使用字符串 id 来表示节点:

function id(d) {
  return d.id;
}

使用 id 访问器可以将源和目标属性设置为字符串:

var nodes = [
  {"id": "Alice"},
  {"id": "Bob"},
  {"id": "Carol"}
];

var links = [
  {"source": "Alice", "target": "Bob"},
  {"source": "Bob", "target": "Carol"}
];

这个方法在使用 JSON 表示图数据时特别有用,因为 JSON 数据不允许引用。参考 this example.
id 访问器会在力模型初始化时为每个节点调用,与修改 nodes 或 links 一样,并传递当前节点以及基于 0 的索引。

link.distance([distance])

如果指定了 distance 则将距离访问器设置为指定的数值或者方法,并重新计算每个边的距离访问器,返回当前力模型。如果没有指定 distance 则返回当前的距离访问器,默认为:

function distance() {
  return 30;
}

距离访问器会为每个 link 调用,并传递 link 以及基于 0 的索引。返回数值会被存储在内部,这样只有在初始化以及重新设置新的 distance 时才会重新计算,而不会在每次应用力模型的时候重复计算。

link.strength([strength])

如果指定了 strength 则将强度访问器设置为指定的数值或者方法,并重新计算每个边的强度访问器,返回当前力模型。如果没有指定 strength 则返回当前的强度访问器,默认为:

function strength(link) {
  return 1 / Math.min(count(link.source), count(link.target));
}

其中 count(node) 是一个根据指定节点计算其出度和入度的函数。使用这种方法设置会自动降低连接到度大的节点的边的强度,有利于提高稳定性。

强度访问器会为每个 link 调用,并传递 link 以及基于 0 的索引。返回数值会被存储在内部,这样只有在初始化以及重新设置新的 strength 时才会重新计算,而不会在每次应用力模型的时候重复计算。

link.iterations([iterations])

如果指定了 iterations 则将迭代次数设置为指定的值并返回当前力模型。如果没有指定 iterations 则返回当前的迭代次数,默认为 1。增加迭代次数会增加约束的刚性,这对于 complex structures such as lattices 会有用,但是同时也会增加程序运行消耗。

参考

官网:https://www.d3js.org.cn/document/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weightOneMillion

感谢看官们的供粮~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值