Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
d3.js中svg和画布的区别_D3.js_Svg_Canvas - Fatal编程技术网

d3.js中svg和画布的区别

d3.js中svg和画布的区别,d3.js,svg,canvas,D3.js,Svg,Canvas,我是d3.js的新手。我发现有两种方法可以绘制对象——SVG和Canvas。 我的用例是关于链接问题/答案中列出的差异说明了svg和画布(矢量/光栅等)之间的一般差异。然而,对于d3,这些差异还有其他含义,特别是考虑到d3的核心部分是数据绑定 数据绑定 也许d3最核心的特性是数据绑定。Mike Bostock表示,一旦将数据加入元素,他就需要创建d3: 决定性的时刻是我第一次让数据连接工作的时候 时间这是魔法。我甚至不确定我是否理解它是如何工作的,但是 这是一个爆炸使用。我意识到可能有一个实用的

我是d3.js的新手。我发现有两种方法可以绘制对象——SVG和Canvas。
我的用例是关于链接问题/答案中列出的差异说明了svg和画布(矢量/光栅等)之间的一般差异。然而,对于d3,这些差异还有其他含义,特别是考虑到d3的核心部分是数据绑定

数据绑定 也许d3最核心的特性是数据绑定。Mike Bostock表示,一旦将数据加入元素,他就需要创建d3:

决定性的时刻是我第一次让数据连接工作的时候 时间这是魔法。我甚至不确定我是否理解它是如何工作的,但是 这是一个爆炸使用。我意识到可能有一个实用的工具 没有不必要地限制图像类型的可视化 你可以做的想象

使用SVG,数据绑定很容易-我们可以将一个数据分配给单个SVG元素,然后使用该数据设置其属性/更新它/等等。这是建立在SVG状态的基础上的-我们可以重新选择一个圆并修改它或访问它的属性

对于画布,画布是无状态的,因此我们无法将数据绑定到画布中的形状,因为画布仅包含像素。因此,我们不能在画布中选择和更新元素,因为画布没有任何可选择的元素

基于以上内容,我们可以看到惯用D3中的svg需要输入/更新/退出循环(或基本append语句):我们需要输入元素来查看它们,并且我们经常根据它们的数据对它们进行样式设置。使用canvas,我们不需要输入任何内容,退出/更新也一样。没有要附加以查看的元素,因此如果需要,我们可以在不使用enter/update/exit或d3svg可视化中使用的append/insert方法的情况下绘制可视化

无数据绑定的画布

我将在您的最后一个问题中使用bl.ock示例。因为我们根本不需要追加元素(或向元素追加数据),所以我们使用forEach循环来绘制每个特性(这与使用SVG的惯用D3相反)。由于没有要更新的元素,我们必须在每个记号重新绘制每个特征-重新绘制整个帧(注意清除每个记号的画布)。关于拖动,d3.drag和d3.force具有一些预期与canvas一起使用的功能,并允许我们通过拖动事件直接修改数据数组-绕过DOM中的节点元素直接与鼠标交互的任何需要(d3.force也直接修改数据数组-但它在中也这样做)

没有数据绑定,我们直接基于数据绘制元素:

data.forEach(function(d) {
    // drawing instructions:
    context.beginPath()....
})
如果数据发生变化,我们可能会重新绘制数据

带数据绑定的画布

也就是说,您可以使用canvas实现数据绑定,但它需要使用虚拟元素的不同方法。我们经历了常规的更新/退出/进入循环,但由于我们使用了虚拟元素,因此没有任何内容被呈现。我们可以随时重新渲染画布(如果使用转换,则可能会连续渲染),并基于虚拟元素绘制内容

要制作虚拟父容器,我们可以使用:

// container for dummy elements:
var faux = d3.select(document.createElement("custom"));
然后,我们可以根据需要使用enter/exit/update/append/remove/transition等进行选择:

// treat as any other DOM elements:
var bars = faux.selectAll(".bar").data(data).enter()....
但由于这些选择中的元素没有渲染,我们需要指定如何以及何时绘制它们。没有数据绑定和画布,我们直接基于数据绘制元素,使用数据绑定和画布,我们基于faux DOM中的选择/元素绘制:

bars.each(function() {
  var selection = d3.select(this);
  context.beginPath();
  context.fillRect(selection.attr("x"), selection.attr("y")...
  ...
})
在这里,我们可以在退出/进入/更新等时重新绘制元素,这可能有一些优势。这也允许D3转换,在转换人造元素上的属性时连续重画

下面的示例有一个完整的进入/退出/更新循环,其中包含转换,演示了具有数据绑定的画布:

var canvas=d3.选择(“主体”)
.append(“画布”)
.attr(“宽度”,600)
.attr(“高度”,200);
var context=canvas.node().getContext(“2d”);
var数据=[1,2,3,4,5];
//虚拟元素的容器:
var faux=d3.select(document.createElement(“自定义”);
//使用虚拟元素的正常更新退出选择:
函数更新(){
//修改数据:
操纵数据();
var selection=faux.selectAll(“圆圈”)
.data(数据,函数(d){返回d;});
var exit=selection.exit().size();
var exit=selection.exit()
.transition()
.attr(“r”,0)
.attr(“cy”,70)
.attr(“填充”、“白色”)
.持续时间(1200)
.remove();
var enter=selection.enter()
.附加(“圆圈”)
.attr(“cx”,函数(d,i){
返回(i+退出)*20+20;
})
.attr(“cy”,50)
.attr(“r”,0)
.attr(“填充”,函数(d){返回[“橙色”、“钢蓝色”、“深红色”、“紫色”、“黄色”][d%5];});
enter.transition()
.attr(“r”,8)
.attr(“cx”,函数(d,i){
返回i*20+20;
})
.期限(1 200);
选择
.transition()
.attr(“cx”,函数(d,i){
返回i*20+20;
})
.期限(1 200);
}
//每1.3秒更新一次
设置间隔(更新,1300);
//渲染函数,重复调用:
函数render(){
clearRect(0,0600200);
人造。选择全部(“圆”)。每个(函数(){
var sel=d3。选择(本);
context.beginPath();
弧(选择属性(“cx”)、选择属性(“cy”)、选择属性(“r”)、0,2*数学PI);
context.fillStyle=sel.attr(“填充”);
context.fill();
stroke();
})
window.requestAnimationFrame(渲染)
}
window.requestAnimationFrame(渲染)
//要操作数据,请执行以下操作:
var指数=6;//跟踪元素。
函数操纵数据(){
data.forEach(函数(d,i){
var r=Math.random();
如果(r<0.5&&data.length>1){
数据拼接(i,1);
}
否则{
数据推送(index++);
}
})
}

值得一提的是,一些D3功能/m