【问题标题】:D3 Redraw BrushD3 重绘笔刷
【发布时间】:2013-04-25 03:05:27
【问题描述】:

我有一个问题已经好几周没能解决了。我正在处理这个示例的修改版本:http://bl.ocks.org/mbostock/1667367 我最初定义了画笔,因此它的画笔范围在 0.5 和 0.8 之间。

var brush = d3.svg.brush()
    .x(x2)
    .extent([0.5, 0.8])
    .on("brush", brushed);

画笔选择显示在正确的位置(在上下文图上),但焦点区域的初始视图仍设置为整个数据集的范围(而不是画笔的剪切区域)。我读过定义画笔不会自动强制重绘该区域,但我似乎无法弄清楚如何使焦点区域的视图自动缩放到画笔范围。有人可以就此提供一些意见吗?

更新 1 我目前有一个名为 Brushed 的函数,它执行以下操作:

function brushed() {
  x.domain(brush.empty() ? x2.domain() : brush.extent());
  focus.select("path").attr("d", Light_area);
  focus.select(".x.axis").call(xAxis);
  Light_line_overlay.select("path").attr("d", Light_area);

  rules.select(".y.grid").call(make_x_axis_light()
          .tickSize(-height, 0, 0)
          .tickFormat("")
      );

  var xx0=brush.x()(brush.extent()[0]);
  var xx1=brush.x()(brush.extent()[1]);

  brushfill.attr("x", xx0);
  brushfill.attr("width", xx1-xx0);
}

它与示例略有不同...因为我一直在对其进行修改以执行与基本示例不同的操作。但是,第一条评论建议我应该在声明画笔后调用这个画笔函数(参见第一篇文章)。然而,调用这个函数并没有做任何事情(或者至少,它不会将焦点区域更新到画笔的范围)。你有什么建议吗?

【问题讨论】:

    标签: d3.js brush


    【解决方案1】:

    对于迟到两年才回答这个问题,我深表歉意,但我遇到了同样的情况,这是我在该主题上找到的唯一资源。我能够弄明白,所以希望这会帮助其他任何偶然发现它的人。

    原始问题中的代码几乎一直存在,只是在范围初始化时没有正确缩放。

    我使用的数据是一个对象数组,带有一个 ts 键(即纪元毫秒),我将其用于我的 x 值。

    // These are needed for the brush construction to know how to scale
    x2.domain(x.domain());
    y2.domain(y.domain());
    
    // Pick out the ~50% and ~80% marks from the data
    var N = data.length;
    var cx0 = new Date(data[Math.floor(N*0.50)].ts);
    var cx1 = new Date(data[Math.floor(N*0.80)].ts);
    
    // Construct with that extent, which will leave the
    // context box started in the correct position.
    var brush = d3.svg.brush()
                      .x(x2)
                      .extent([cx0, cx1])
                      .on("brush", brushed)
    ;
    
    // This is just the original brushed example 
    function brushed() {
        x.domain(brush.empty() ? x2.domain() : brush.extent());
        focus.select(".area").attr("d", line);
        focus.select(".x.axis").call(xAxis);
    }
    
    ...
    
    var focus = svg.append("g")
                   .attr("class", "focus")
                   .attr("transform",
                         "translate(" + margin.left + "," + margin.top + ")")
    ;
    
    // Now that focus is defined we can manually update it
    brushed();
    

    我实际上在设置的最后保留了对brushed 的调用,只是为了保持美观,但这里的重点只是说明一旦定义了focus,您就可以调用brushed 来做任何事情你想要的更新。

    最终,您的主要问题似乎是在该范围内获得正确的类型。使用[0.5, 0.8] 进行初始化,但如果您检查何时调用brushed 以实际使用鼠标滑动焦点,brush.extent() 将是[Date(), Date()]。这是有道理的,因为我们将这个范围传递给x.domain。所以这在初始化画笔之前设置了所有的缩放,这样初始化范围可以是Date,然后其他的都是肉汁。

    【讨论】:

      【解决方案2】:

      每当以编程方式更改画笔范围时,您都需要执行类似于画笔功能的操作。调整 x.domain 的大小,刷新视图。

      function brushed() {
        x.domain(brush.empty() ? x2.domain() : brush.extent());
        focus.select("path").attr("d", area);
        focus.select(".x.axis").call(xAxis);
      }
      

      如果这不能解决您的问题,请考虑提供一些代码示例。

      【讨论】:

        猜你喜欢
        • 2020-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多