d3.js:基于数据对动态SVG元素进行分组

时间:2017-07-11 15:17:43

标签: d3.js

我有一个d3.scaleTime()作为x轴和带有日期的JSON数据,应该在这个x轴上表示为rect,以便将日期标记为“保留”。

简单的方法是

this.svg.selectAll('rect').data(dates).enter().each(function(d) {
   d3.select(this)
    .append("rect")
    .attr('height', desiredHeight) 
    .attr('width', desiredWidthFromTickToTick) 
    .attr('x', x(d.date));
}

但我想将rects分组,如果它们有连续的日期,以便能够在x轴上移动组。

我所做/尝试的是在输入/每个功能中检查,如果已经有一个组具有当前日期的“下一个”日期。 如果没有,请创建一个新组并附加当前日期 - rect。 如果有一个组,请获取该组并将date-rect附加到现有组。

但现在问题是rects没有保留他们的数据和/或我无法正确地将rect添加到组中。

一些(伪)代码:

var rects = this.svg.selectAll('rect') .data(dates, function(dataElement) {
    return dataElement.id;
});

// add new date rects
rects.enter().each(function(dataElement) {

   var isNewDateGroup = true / false; // detect if date is "next" to another one

   if (isNewDateGroup)
   {
      var group = svg.append("g");

      var dateRect = d3.select(this)
                    .append("rect")
                    .attr('height', desiredHeight) 
                    .attr('width', desiredWidthFromTickToTick);

     group.append(function() {
        // works correctly, appends the rect and sets the data 
        return dateRect.select('rect').node();
     });

     // translate group to desired x(d.date)
   }

   else
   {
      var group = getGroupForDate();

      var dateRect = d3.select(this)
                    .append("rect")
                    .attr('height', desiredHeight) 
                    .attr('width', desiredWidthFromTickToTick) 
                    .attr('x', offsetToLastRectInGroup);

     group.append(function() {
        // does not work correctly, does not append the rect and does not set the data 
        return dateRect.select('rect').node();
     });
   }
});

基本上,如果我追加多个SVG元素,则输入函数不起作用,因为数据会混淆并附加。 任何提示,我如何分组我的作品?

1 个答案:

答案 0 :(得分:0)

this question上的答案帮助我解决了我的问题: 由于.select()将数据传播到所选元素,我只需要摆脱选择:

var dateRect = d3.select(this)
                    .append("rect")
                    .attr('height', desiredHeight) 
                    .attr('width', desiredWidthFromTickToTick) 
                    .attr('x', offsetToLastRectInGroup);

     group.append(function() {
        return dateRect.node();
     });