本文介绍了D3.js:结合缩放/画笔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究Mike Bostock的

解决方案

在示例中,您已经删除了用于放大图表的矩形,但是尚未替换其所有功能.

虽然在其他某些元素(可能是面积图)上调用了 zoom ,但在此处进行刷牙时不会更新该缩放:

  svg.select(.zoom").call(zoom.transform,d3.zoomIdentity.scale(width/(selection [1]-selection [0])).translate(-selection [0],0)); 

您需要为图表分配缩放类别,否则这是一个空选择(或不相关元素的选择).如果不这样做,笔刷的更改不会更改缩放比例和平移,这意味着先刷然后缩放将导致沿笔刷跳跃",从而丢失您的位置.

进行此更改后,您应该可以使用此功能:示例./p>

I'm currently working off of Mike Bostock's Brush & Zoom example although instead of having an overlayed rect object over the svg, I have it attached to my chart so that I can still use mouseover events and whatnot.

I'm having great difficulty combining both brush and zoom functionalities. Both work fine but do not "remember" their current state. For instance, if I'm to pan/resize the brush, all is fine with zoom but if I was to then use mouse/touchpad events to zoom, it would jump along the brush and completely lose where I was in the chart.

How would I get the zoom to "remember" where it was in the brush viewport, and to work fluidly?

function brushed() {
    if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") return;
    var selection = d3.event.selection;
    x.domain(selection.map(x2.invert, x2));
    focus.selectAll(".point")
        .attr("cx", function(d){
            var time = timeParser(d.timestamp);
            return x(time);
        })
        .attr("cy", function(d){
            return y(d.value);
        });
    focus.selectAll(".trendline")
        .attr("d", function(d){
            return line(d);
        });
    focus.selectAll(".area")
        .attr("d", function(d){
            return area(d);
        });
    focus.select(".axis.x").call(xAxis);
    svg.select(".zoom").call(zoom.transform, d3.zoomIdentity
        .scale(width / (selection[1] - selection[0]))
        .translate(-selection[0], 0));
}

function zoomed() {
    if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return;
    var t = d3.event.transform;
    x.domain(t.rescaleX(x2).domain());
    focus.selectAll(".point")
        .attr("cx", function(d){
            var time = timeParser(d.timestamp);
            return x(time);
        })
        .attr("cy", function(d){
            return y(d.value);
        });
    focus.selectAll(".trendline")
        .attr("d", function(d){
            return line(d);
        });
    focus.selectAll(".area")
        .attr("d", function(d){
            return area(d);
        });
    focus.select(".axis.x").call(xAxis);
    context.select(".brush").call(brush.move, x.range().map(t.invertX, t));
}

And here's how the chart looks to give a sort of rough idea:

解决方案

You've taken away the rectangle which was used to zoom the chart in your example, but you haven't replaced all of its functionality.

While you call zoom on some other element (presumably your area graph), you don't update that zoom when brushing here:

svg.select(".zoom").call(zoom.transform, d3.zoomIdentity
    .scale(width / (selection[1] - selection[0]))
    .translate(-selection[0], 0));

You need to assign the zoom class to your chart, otherwise this is an empty selection (or a selection of an irrelevant element). Without doing this, the brush changes don't modify the zoom's scale and translate, which means brushing and then zooming will result in a "jump along the brush", losing where you were.

With that change you should be able to get this working: example.

这篇关于D3.js:结合缩放/画笔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 14:25