在d3中的for循环中绘制多行 [英] Plot multiple lines in a for loop in d3

查看:153
本文介绍了在d3中的for循环中绘制多行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在线上有很多情况,如果仅添加svg对象一次,如何在d3中绘制几条线,例如

There are many cases online how to plot couple of lines in d3 if you add svg object only once, such as

   svg.selectAll("line")
   .data(dataset)
   .enter().append("line")
   .style("stroke", "black")  // colour the line
   .attr("x1", function(d) { console.log(d); return xScale(d.x1); })
   .attr("y1", function(d) { return yScale(d.y1); })
   .attr("x2", function(d) { return xScale(d.x2); })
   .attr("y2", function(d) { return yScale(d.y2); }); 

此图创建一行.我想在像

This plot create one line. I want to create many different lines in an array smth like

   var svg = d3.select("body")
   .append("svg")
   .attr("width", w)
   .attr("height", h);

   for (a_ind=1; a_ind<3; a_ind++){
   dataset_a=dataset.filter(function(d) { return (d.a==a_ind)})

   svg.selectAll("line")
   .data(dataset_a) - //!!! using new dataset in each cycle
   .enter().append("line")
   .style("stroke", "black")  // colour the line
   .attr("x1", function(d) { console.log(d); return xScale(d.x1); })
   .attr("y1", function(d) { return yScale(d.y1); })
   .attr("x2", function(d) { return xScale(d.x2); })
   .attr("y2", function(d) { return yScale(d.y2); }); 
   }

有人告诉我这是不可能的.也许有办法?还有,如果我想用鼠标单击将其删除,该如何访问然后从dataset_a行?

I was told it's impossible. Or maybe there is the way? And also how to access then line from dataset_a if i want to delete it with the click of the mouse?

推荐答案

好吧,如果您想绘制线条,建议您附加... <line> s!

Well, if you want to plot lines, I suggest that you append...<line>s!

具有D3输入选择的内容非常简单:附加元素的数量是数据数组中与任何元素都不匹配的对象的数量.

The thing with a D3 enter selection is quite simple: the number of appended elements is the number of objects in the data array that doesn't match any element.

因此,您只需要一个包含多个对象的数据数组.例如,让我们创建其中的50个:

So, you just need a data array with several objects. For instance, let's create 50 of them:

var data = d3.range(50).map(function(d) {
  return {
    x1: Math.random() * 300,
    x2: Math.random() * 300,
    y1: Math.random() * 150,
    y2: Math.random() * 150,
  }
});

并且,正如下面的演示中一样,我选择null,所有这些都将在回车选择中.这是演示:

And, as in the below demo I'm selecting null, all of them will be in the enter selection. Here is the demo:

var svg = d3.select("svg");
var data = d3.range(50).map(function(d) {
  return {
    x1: Math.random() * 300,
    x2: Math.random() * 300,
    y1: Math.random() * 150,
    y2: Math.random() * 150,
  }
});
var color = d3.scaleOrdinal(d3.schemeCategory20);
var lines = svg.selectAll(null)
  .data(data)
  .enter()
  .append("line")
  .attr("x1", function(d) {
    return d.x1
  })
  .attr("x2", function(d) {
    return d.x2
  })
  .attr("y1", function(d) {
    return d.y1
  })
  .attr("y2", function(d) {
    return d.y2
  })
  .style("stroke", function(_, i) {
    return color(i)
  })
  .style("stroke-width", 1);

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

最后一个提示:由于这是JavaScript,因此您可以在任意位置使用for循环.但是,请勿使用for循环在D3代码中附加元素.这是不必要的,不是惯用的.

Finally, a tip: as this is JavaScript you can use for loops anywhere you want. However, do not use for loops to append elements in a D3 code. It's unnecessary and not idiomatic.

话虽这么说,无论谁告诉你这是不可能都是错的,这显然是可能的.这是一个演示(但不要这样做,这是一个非常麻烦且丑陋的代码):

That being said, whoever told you that it is impossible was wrong, it's clearly possible. Here is a demo (but don't do that, it's a very cumbersome and ugly code):

var svg = d3.select("svg");
var data = d3.range(50).map(function(d, i) {
  return {
    x1: Math.random() * 300,
    x2: Math.random() * 300,
    y1: Math.random() * 150,
    y2: Math.random() * 150,
    id: "id" + i
  }
});
var color = d3.scaleOrdinal(d3.schemeCategory20);

for (var i = 0; i < data.length; i++) {

  var filteredData = data.filter(function(d) {
    return d.id === "id" + i
  });

  var lines = svg.selectAll(null)
    .data(filteredData)
    .enter()
    .append("line")
    .attr("x1", function(d) {
      return d.x1
    })
    .attr("x2", function(d) {
      return d.x2
    })
    .attr("y1", function(d) {
      return d.y1
    })
    .attr("y2", function(d) {
      return d.y2
    })
    .style("stroke", function() {
      return color(i)
    })
    .style("stroke-width", 1);

}

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

这篇关于在d3中的for循环中绘制多行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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