入门d3.js,根据官网部分教程学习,发现因为版本更新,有些api和概念可能不适用,但总体思想未变。本文思路跟随此篇blogLet’s Make a Bar Chart学习,加上自己的理解,并且查阅了部分更新资料

元素选择

d3通过d3.select()或者d3.selectAll()获取元素,这两个API返回selection对象,我们可以通过selection对象操控元素

    <div class="chart"></div>
    <div class="chart"></div>
    <div class="chart"></div>
    <div class="chart"></div>
    <div class="chart"></div>
    <script>
        console.log(d3.select('.chart'));
        console.log(d3.selectAll('.chart'));
    </script>

通过selection操作dom有一个好处是可以不用写太多的for循环,比如我想给所有的chart DIV添加内容只需

let section = d3.selectAll('.chart');
let div = section.append('div');
div.html('Hi!')

就可以向所有的div加入内容,无需for循环

链式写法

selection的另一个方便之处就是链式写法,selection的方法会返回对应selection,这样就可以使用简洁的链式写法了

d3.selectAll('.chart')
  .append('div')
  .html('Hi')

使用html与d3创建条形图

首先列出css与data,下面都用这一配置

.chart div{
  font: 10px sans-serif;
  background-color: steelblue;
  text-align: right;
  padding: 3px;
  margin: 1px;
  color: white;
}
<div class="chart"></div>
const data = [4, 8, 15, 16, 23, 42];

接下来使用d3创建条形图

    d3.select('.chart')
        .selectAll('div')
        .data(data)
        .enter().append('div')
        .style('width',  d => d * 10 + 'px')
        .text( d => d)

接下来分步说明,其中会涉及到一个叫data join(数据绑定)的概念。有了data join,当数据发生改变时,可以通过数据创建,更新,销毁元素,后文再提及
首先获取元素并初始化要绑定数据的元素

    let chart = d3.select('.chart')//选择元素
    let bar = chart.selectAll('div') //要进行数据绑定的元素,chart中无此元素,此时返回的selection为空

接着绑定数据

    let barUpdate = bar.data(data)
    console.log(barUpdate)

selection.data()方法会将数据绑定于选择的元素之中,并返回一个代表update的新的selection,并且在其中定义了enter selectionsexit selections

clipboard.png

(这部分用文字难以一言两语解释清楚,于是写在另一篇blog里

_groups(这里是代表update的selection):表示成功绑定上数据的元素,若无对应元素,则由empty表示,所以这里有6个empty

enter selections:表示有数据无元素,对应元素用EnterNode替代,若对应数据有元素,则由empty表示

exit selections: 表示无数据有元素,因为chart中没有元素,所以这里的数组为空;若有数据对应元素,元素也用empty表示,无则用元素本身表示

接下来我们获取所有EnterNode,对其插入div

    let barEnter = barUpdate.enter().append('div'); //enter()返回EnterNode

接着对这些div设置条形宽度,因为有data join(数据绑定),所以我们直接通过绑定的数据设置宽度就可以了

barEnter.style("width", d => d * 10 + 'px');

最后,text文字设置同理

barEnter.text(d => d);

使用比例尺

上面的例子中我们使用了magic number => 10,让bar的像素宽度=数值*10,使得bar的宽度看起来容易对比,但是正常情况下使用magic number会很麻烦且不易调试,而且不仅有放大像素数值的情况,也有缩小像素数值的情况,所以引入了比例尺
这里使用线性比例尺

let x = d3.scaleLinear()
          .domain([0, d3.max(data)]) //输入域
          .range([0, 420]); //输出域,这里可理解为柱形图最大长度
d3.select('.chart')
  .selectAll('div')
  .data(data)
  .enter().append('div')
  .style('width',  d => x(d) + 'px') //使用比例尺,比例尺是个函数
  .text( d => d);

clipboard.png

总结

初步入门,有不对请大佬指出

参考资料

Let’s Make a Bar Chart I
selection.data()
selection.enter()
selection.exit()
selection.join()
[译]D3.js 之 d3-selection 原理


Jonithan
249 声望12 粉丝

GitHub:[链接]