javascript d3.js:使用brush.extent初始化画笔并停止溢出边距的数据

时间:2014-09-04 02:16:37

标签: javascript d3.js

我想用我当前的d3应用程序解决2个问题,这个问题基于this

这里是小提琴:http://jsfiddle.net/zoa5m20z/

  1. 我想初始化我的画笔,以便在应用程序启动时默认刷一小部分特定部分。我用.extent尝试了以下但没有运气。

    //date parsing function
    var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
    
    //setting up brush and defaultExtent
    var brush = d3.svg.brush()
    .x(x2)
    .extent([parseDate("2014-08-11 10:20:00"), parseDate("2014-08-11 18:20:00")]) //trying to intialize brush
    .on("brush", brushed);
    
  2. 我想阻止我的绘制圆圈与y轴重叠。我想在移动画笔时仅绘制/显示y轴右侧的圆圈。就像规范的Bostock Focus+Context via Brushing Block一样。我尝试使用边距和比例,范围,范围,但无济于事。

  3. 我想避免的事情:

    enter image description here

    我是d3.js的新手,所以所有提示&建议是值得欢迎和赞赏的!

2 个答案:

答案 0 :(得分:3)

对于您的第一个问题,您需要致电brush.event以使画笔获得新的范围。

  brush = d3.svg.brush()
      .x(x)
      .extent([config.start, d3.time.day.offset(config.start, config.range)])
      .on("brush", brushmove)
      .on("brushend", brushend);

  gBrush = svg.select('.brush')
    .call(brush);

  gBrush.call(brush.event);

对于第二个问题,我通常只过滤掉画笔范围之外的数据,这样我才会绘制可见数据。以下是刷子移动/缩放事件中要调用的示例:

  // update the data so that only visible points are shown
  var points= svg.selectAll('.point')
      .data(function(d) { return onScreen(d, brush.extent); },
            function(d) { return d.id; });

  // draw the points that are now onscreen
  var pointsEnter = points.enter().append('g').attr('class', 'point');

  // remove any points that are now offscreen
  points.exit().remove();

  // up date the x/y position of your points based on the new axis.
  // ... left up to you

为点设置一个唯一的ID是有帮助的,这样它们就可以在刷子移动时被翻译到新的位置,而不必破坏它们并重绘它们。

我有一个在http://bl.ocks.org/bunkat/1962173使用这些技术的例子。

答案 1 :(得分:2)

以下是基于您的代码的工作示例:http://jsfiddle.net/26sd8uc9/4/

1 - 你对.extent的看法是正确的,问题是你没有为x2规范指定域名。通过添加以下代码,它可以工作:

x2 = d3.time.scale()
   .domain([
     parseDate("2014-08-11 05:30:00"), 
     parseDate("2014-08-12 19:25:00")
   ])
   .nice(d3.time.minute)
   .range([0, width]);

要初始化圆圈,您还必须在创建画笔后通过添加.call(brush.event)来调用拉丝事件:

  // brush slider display
  context.append("g")
      .attr("class", "x brush")
      .call(brush)
      .call(brush.event)
      .selectAll("rect")
      .attr("y", -6)
      .attr("height", height2 + 7);

2 - 使用变量跟踪画笔下的当前范围,并通过将半径设置为零来隐藏不在范围内的圆(或者您可以设置可见性)

var currentRange;

var inRange = function(d) { 
    if(!currentRange || d.time < currentRange[0] || d.time > currentRange[1] ) {
        return 0;
    } else {
        return 5;
    }
}

function brushed() {

  currentRange = (brush.empty()? undefined : brush.extent());

  x.domain(brush.empty() ? x2.domain() : brush.extent());
  focus.select(".x.axis").call(xAxis);
  mydots.selectAll(".circle")
   .attr("cx", xMap)
   .attr("cy", yMap)
   .attr("r", inRange); // set radius to zero if it's not in range
  console.log(brush.extent())
}

对于比例定义,最好这样写:

        .domain([
            d3.min(dataset, function(d){ return d.time; }), 
            d3.max(dataset, function(d){ return d.time; })
        ])

在您的示例中,您必须确保在执行此操作之前解析并初始化数据。