D3.js:这是数据DOM绑定的好习惯吗? [英] D3.js: Is this good practise for data-DOM-binding?

查看:102
本文介绍了D3.js:这是数据DOM绑定的好习惯吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要掌握D3的基本知识。我知道获得绑定权是至关重要的。



所以我做了一个简单的网页与更新,进入和退出操作。每次数据更改(修改,添加,删除)我调用一个函数,其中数据绑定到svg对象在更新,输入和退出方式。



不知道我的方法是否是好的?

 < html> 
< head>

< style>
.drawarea {border-style:solid; }
< / style>

< script src =https://d3js.org/d3.v4.min.js>< / script>

< script>
var data,drawArea;

function init(){
data = [{px:25,py:25,s:5},{px:25,py :50,s:5},{px:25,py:75,s:10}];

drawArea = d3.select(#drawareadiv)。append(svg:svg)
.attr(class,drawarea)
.attr width,500)
.attr(height,250);

draw();
}

function draw(){
var domRects = drawArea.selectAll(rect);

//更新
domRects
.data(data)
.attr(x,function(d){return d.px;})
.attr(y,function(d){return d.py;})
.attr(width,function(d){return ds;})
.attr height,function(d){return ds;});

//输入
domRects
.data(data)
.enter()
.append(svg:rect)
.attr(x,function(d){return d.px;})
.attr(y,function(d){return d.py;})
.attr宽度函数(d){return ds;})
.attr(height,function(d){return ds;});

// exit
domRects
.data(data)
.exit()
.remove();
}

function updateDataAndBinding(){
for(i = 0; i data [i] .px + = 10;
draw();
}

function enterDataAndBinding(){
var px = 25;
var py = 25 *(data.length + 1);
var s = Math.floor(data.length / 2)* 5 + 5;
data.push({px:px,py:py,s:s});
draw();
}

function exitDataAndBinding(){
data.splice(data.length-1,1);
draw();
}

< / script>

< / head>

< body onload =init()>
< div id =drawareadiv>< / div>
< button onclick =updateDataAndBinding()> updateDataAndBinding< / button>
< button onclick =enterDataAndBinding()> enterDataAndBinding< / button>
< button onclick =exitDataAndBinding()> exitDataAndBinding< / button>
< / body>

< / html>


解决方案

我会建议两件事:


  1. 不要一次又一次绑定数据。这只是一次:

      var domRects = drawArea.selectAll(rect)。 


  2. 由于这是D3 v4.x,请使用 merge 一起处理输入和更新选择:

      //输入+ update 
    domRects.enter()
    .append(svg:rect)
    .attr(x,function(d){return d.px;})
    .attr y函数(d){return d.py;})
    .attr(width,function(d){return ds;})
    .attr d){return ds;})
    .merge(domRects)
    .attr(x,function(d){return d.px;})
    .attr(y ,function(d){return d.py;})
    .attr(width,function(d){return ds;})
    .attr return ds;});


snippet):



 < style& .drawarea {border-style:solid; }< / style>< script src =https://d3js.org/d3.v4.min.js>< / script>< script> var data,drawArea; function init(){data = [{px:25,py:25,s:5},{px:25,py:50,s:5},{px:25, py:75,s:10}]; drawArea = d3.select(#drawareadiv)。append(svg:svg).attr(class,drawarea).attr(width,500).attr(height,200); draw();} function draw(){var domRects = drawArea.selectAll(rect)。 // enter domRects.enter().append(svg:rect).attr(x,function(d){return d.px;}).attr(y,function(d){return d .attr(width,function(d){return ds;}).attr(height,function(d){return ds;}).merge(domRects) ,function(d){return d.px;}).attr(y,function(d){return d.py;}).attr(width,function(d){return ds;})。 attr(height,function(d){return ds;}); // exit domRects.exit().remove();} function updateDataAndBinding(){for(i = 0; i  

除此之外,你的方法似乎是一个很好的(和标准的)一个。


I'm trying to grasp the D3 basics. I understand that it's crucial to get the binding right.

So I did a simple web page with update, enter and exit operations. Every time the data changes (modified, added, removed) I call a function where the data is bound to svg-objects in the update, enter and exit ways.

I wonder if my approach is a good one?

<html>
<head>

<style>
  .drawarea { border-style: solid; }
</style>

<script src="https://d3js.org/d3.v4.min.js"></script>

<script>
var data, drawArea;

function init(){
  data = [{"px" : 25, "py" : 25, "s" : 5}, {"px" : 25, "py" : 50, "s" : 5}, {"px" : 25, "py" : 75, "s" : 10} ];

  drawArea = d3.select("#drawareadiv").append("svg:svg")
    .attr("class", "drawarea")
    .attr("width", 500)
    .attr("height", 250);

  draw();
}

function draw(){
  var domRects = drawArea.selectAll("rect");

  // update
  domRects
    .data(data)
    .attr("x", function(d) { return d.px; })
    .attr("y", function(d) { return d.py; })
    .attr("width", function(d) { return d.s; })
    .attr("height", function(d) { return d.s; });

  // enter
  domRects
    .data(data)
    .enter()
    .append("svg:rect")
    .attr("x", function(d) { return d.px; })
    .attr("y", function(d) { return d.py; })
    .attr("width", function(d) { return d.s; })
    .attr("height", function(d) { return d.s; });

   // exit
   domRects
     .data(data)
     .exit()
     .remove();
}

function updateDataAndBinding(){
  for(i=0; i<data.length; i++)
    data[i].px += 10;
  draw();
}

function enterDataAndBinding(){
  var px = 25;
  var py = 25 * (data.length+1);
  var s = Math.floor(data.length/2)*5+5;
  data.push({"px" : px, "py" : py, "s" : s});
  draw();
}

function exitDataAndBinding(){
  data.splice(data.length-1, 1);
  draw();
}

</script>

</head>

<body onload="init()">
<div id="drawareadiv"></div>
<button onclick="updateDataAndBinding()">updateDataAndBinding</button>
<button onclick="enterDataAndBinding()">enterDataAndBinding</button>
<button onclick="exitDataAndBinding()">exitDataAndBinding</button>
</body>

</html>

解决方案

I'd suggest two things:

  1. Don't bind the data again and again. Do this just one time:

    var domRects = drawArea.selectAll("rect").data(data);
    

  2. As this is D3 v4.x, use merge to deal with the "enter" and "update" selections together:

    // enter + update
    domRects.enter()
        .append("svg:rect")
        .attr("x", function(d) { return d.px; })
        .attr("y", function(d) { return d.py; })
        .attr("width", function(d) { return d.s; })
        .attr("height", function(d) { return d.s; })
        .merge(domRects)
        .attr("x", function(d) { return d.px; })
        .attr("y", function(d) { return d.py; })
        .attr("width", function(d) { return d.s; })
        .attr("height", function(d) { return d.s; });
    

Here is the demo (click "run code snippet"):

<style>
  .drawarea { border-style: solid; }
</style>

<script src="https://d3js.org/d3.v4.min.js"></script>

<script>
var data, drawArea;

function init(){
  data = [{"px" : 25, "py" : 25, "s" : 5}, {"px" : 25, "py" : 50, "s" : 5}, {"px" : 25, "py" : 75, "s" : 10} ];

  drawArea = d3.select("#drawareadiv").append("svg:svg")
    .attr("class", "drawarea")
    .attr("width", 500)
    .attr("height", 200);

  draw();
}

function draw(){
  var domRects = drawArea.selectAll("rect").data(data);

  // enter
  domRects.enter()
    .append("svg:rect")
    .attr("x", function(d) { return d.px; })
    .attr("y", function(d) { return d.py; })
    .attr("width", function(d) { return d.s; })
    .attr("height", function(d) { return d.s; })
		.merge(domRects)
		.attr("x", function(d) { return d.px; })
    .attr("y", function(d) { return d.py; })
    .attr("width", function(d) { return d.s; })
    .attr("height", function(d) { return d.s; });

   // exit
   domRects.exit()
     .remove();
}

function updateDataAndBinding(){
  for(i=0; i<data.length; i++)
    data[i].px += 10;
  draw();
}

function enterDataAndBinding(){
  var px = 25;
  var py = 25 * (data.length+1);
  var s = Math.floor(data.length/2)*5+5;
  data.push({"px" : px, "py" : py, "s" : s});
  draw();
}

function exitDataAndBinding(){
  data.splice(data.length-1, 1);
  draw();
}

</script>

</head>

<body onload="init()">
<div id="drawareadiv"></div>
<button onclick="updateDataAndBinding()">updateDataAndBinding</button>
<button onclick="enterDataAndBinding()">enterDataAndBinding</button>
<button onclick="exitDataAndBinding()">exitDataAndBinding</button>
</body>

Other than that, your approach seems to be a good (and standard) one.

这篇关于D3.js:这是数据DOM绑定的好习惯吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆