DataJoin(数据连接)是D3中很重要的一个概念。上一章有提到D3是基于数据操作DOM的js库,DataJoin使我们能够根据现有HTML文档中的数据集注入、修改和删除元素。
上一章中我们用forEach循环的方式,画了三个圆,那么在D3中该怎样优雅的处理呢?
constcircles=[{text:1,color:"red"},{text:2,color:"green"},{text:3,color:"blue"}];svg.selectAll("circle").data(circles)//绑定数据.enter()//获取有数据没dom的集合.append("circle").attr("class","circle").attr("id",(d)=>`circle${d.text}`)//d表示data绑定的数据中的一项.attr("cx",(d)=>50*d.text).attr("cy",50).attr("r",20).attr("fill",(d)=>d.color);
因为有5个p标签,所以从1开始渲染到5。
enter返回的是有数据没有dom的集合,也就是数据比dom多,所以enter和append基本上都是成对出现的。
d3.select("#dataEnter").selectAll("p").data(arr).enter().append("p").text((d)=>d);
exit返回的是有dom没有数据的集合,也就是dom比数据多,所以exit和remove基本上也是成对出现的。
constarr=[1,2,3]d3.select("#dataEnter").selectAll("p").data(arr).text((d)=>d).exit().remove();
如果datum()绑定的值是数组,那么整个数组会绑定到每个被选择的元素上。
而使用data()的话,那么会依次绑定数据。
constdatumDom=d3.select("#datum").selectAll("p").datum(circles).text((d)=>{console.log(d);returnJSON.stringify(d);});
selection.datum().append()如果选择集是空的,那么并不会添加元素,所以使用datum要确保选择项(dom)存在。实际项目中,图表都是从0到1绘制,所以一般都是使用data().append()。
constarr=[1,2,3];svg.selectAll("circle").data(arr).join("circle").attr("cx",(d)=>d*50).attr("cy",(d)=>d*50).attr("r",16).attr("fill","#F89301");join根据需要追加、删除和重新排列元素,以匹配先前通过选择绑定的数据,返回合并后的enter和update集合。
也就是说join是一个简化操作,我们可以把join分解一下:
constcircle=svg.selectAll("circle").data(arr);constnewCircle=circle.enter().append("circle").merge(circle).attr("cx",(d)=>d*50).attr("cy",(d)=>d*50).attr("r",16).attr("fill","#F89301");
这里有一个示例动态的显示了enter(绿色)、update(灰色)、exit(红色)效果: