引入

html中引入

1
<script src="https://cdn.bootcdn.net/ajax/libs/d3/5.16.0/d3.js"></script>

核心函数

d3.js是链式操作,和promise结构类似,函数执行的返回值都是函数本身

选择器

选择元素

D3提供了两种方法来选择元素

  • d3.select()
    返回单元素选择结果,没有匹配的则返回空,多个匹配只返回第一个匹配的元素
    • d3.select(selector)
    • d3.select(node) 选中指定节点,如果已经引用了一个节点.例如时间监听器的d3.select(this),或者一个全局对象,例如document.body,这个函数不会便利DOM树
  • d3.selectAll()
    返回选中的所有元素,按照文档的遍历顺序,从上到下选择,如果文档中没有匹配的元素则返回空的选择
    • d3.selectAll(selector)
    • d3.selectAll(nodes) 如果有元素已被引用,例如事件监听器中的d3.selectAll(this.childNodes),或者一个全局的document.links,节点参数不用恰好是数组,任何可以被转换为数据的伪数组都可以,这个函数不会遍历DOM树

操作选择

选择是一组元素,D3绑定额外的方法到数组上面,可以在选中的元素上进行操作,每一个细微的差别都是选择结果的分组,每一个选择都是元素数组中的一个数组,一个单一的元素选择看起来像[[node]] 而不是[node]

  • selection.attr(name[,value])
    如果指定了value参数,将为所有选中的元素通过指定的name为指定的value设置属性,如果value是一个常数,那么所有的元素都将设置为同样的属性值;如果value是一个函数,那么将会为没有选中的元素计算,入参是当前元素d和当前索引i以及代表当前DOM元素的this上下文,这个函数的返回值接下来用来设置每个元素的属性,null值将一处指定的属性.
    如果value参数没有指定,就会返回为选择中第一个非空(null)元素所指定的属性值。一般来说,只有当你知道选择中恰好包含一个元素时才有用
    指定的name参数也会含有一个前缀,例如xlink:href是用来指定Xlink命名空间中href属性的。默认情况下,D3支持svg、xhtml、xlink、xml和 xmlns命名空间。可以添加d3.ns.prefix来注册其他的命名空间
  • selection.classed(name[,value])
    selection.classed('foo', true)
    selection.classed('foo bar', true)
    selection.classed({'foo', true, 'bar': true})
    设置class属性值的便捷程序,他能识别class属性是一个按照空格分隔的标记集合,这样就能使用classList来方便地添加,移除,和切换css类
  • selection.style(name[,value[,priority]])
    selection.style({'stroke': 'black', 'stroke-width': 2})
  • selection.property(name[,value])
    selection.property({'checked':true,'disabled': false});
  • selection.text([value])
  • selection.html([value])
  • selection.appent(name)
    在当前选择的每个元素最后追加具有指定名称的新元素,返回包含追加元素的新选择
  • selection.inser(name[,before])
    在当前选择和指定的before选择器匹配的每个元素之前插入具有指定name的心愿,返回包含插入的元素的新的选择,如果before选择器不匹配任何元素,将会用append追加为最后一个子元素,子元素继承当前元素的数据
  • selection.remove()
    删除当前文档当前选中该的元素,返回屏幕外的当前选择,从DOM分离,但是目前被删除的元素无法重新添加,但是可以用append和insert重新添加元素

数据

  • selection.data([values,[,keys]])
    链接指定的一组数据和当前选择,指定的values是一组数据值,或者一个函数返回的一组值,如果没有指定key函数,则values的第一个数据被分配到当前选择中的第一个元素,第二个数据分配给但钱选择的第二个元素,依次类推.
    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
     <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/d3/5.16.0/d3.js"></script>
    <title>d3.js - 图形操作工具</title>
    </head>
    <body>
    <script>
    var matrix = [
    [11975, 5871, 8916, 2868],
    [ 1951, 10048, 2060, 6171],
    [ 8010, 16145, 8090, 8045],
    [ 1013, 990, 940, 6907]
    ];

    var tr = d3.select("body").append("table").selectAll("tr")
    .data(matrix)
    .enter().append("tr");

    var td = tr.selectAll("td")
    .data(function(d) { return d; })
    .enter().append("td")
    .text(function(d) { return d; });
    </script>
    </body>
    </html>
  • selection.enter()
    返回输入(enter)选择:当前选择中存在但是当前DOM元素中还不存在的每个数据元素的占位符节点,此方法只由data运算符返回的更新选择中定义,输入选择只定义了append,insert,select,call,你必须在使用这些操作符修改任何内容之前实例化输入元素

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     d3.select("body").selectAll("div")
    .data([4, 8, 15, 16, 23, 42])
    .enter().append("div")
    .text(function(d) { return d; });

    // 效果
    <div>4</div>
    <div>8</div>
    <div>15</div>
    <div>16</div>
    <div>23</div>
    <div>42</div>

    另一种方式考虑进入的占位符节点,他们是执行父节点,但是只支持追加和插入

    1
    2
    3
    4
    5
    var update_sel = svg.selectAll("circle").data(data)
    update_sel.attr(/* operate on old elements only */)
    update_sel.enter().append("circle").attr(/* operate on new elements only */)
    update_sel.attr(/* operate on old and new elements */)
    update_sel.exit().remove() /* complete the enter-update-exit pattern */
    • selection.exit()
      返回退出选择,找出在当前选择存在的DOM元素中没有新的数据方法,将现有的元素数组和一个含有新的和旧的新数组绑定
      1
      var div = d3.select("body").selectAll("div").data([1,2,4,8,16,32], function (d) {return d})
      离开这些元素原样,我们可以实例化并使用enter选择添加新的元素[1,2,32]
    1
    div.enter().append("div").text(function(d) {return d})

    删除退出的元素: div.exit().remove()

    1
    2
    3
    4
    5
    6
      <div>4</div>
    <div>8</div>
    <div>16</div>
    <div>1</div>
    <div>2</div>
    <div>32</div>

    使用索引将生成的元素和序列对上

    1
    div.selectAll("div").attr("index", function(d,i) => {return i})

    运行结果

    1
    2
    3
    4
    5
    6
      <div index="2">4</div>
    <div index="3">8</div>
    <div index="4">16</div>
    <div index="0">1</div>
    <div index="1">2</div>
    <div index="5">32</div>
    • selection.filter(selector)
    1
    var odds = selection.filter(function(d, i) { return i & 1; });
    • selection.sort([comparator])
    • selection.order()