如何在y域更改后连接路径/图表重绘

时间:2013-07-22 14:30:04

标签: d3.js

我想在同一个可视化中绘制多个条形图。

当绘制第一个条形图时,它不会显示第2个,第3个等的域。在绘制第2个条形图时,y比例的域会发生变化。因此,第一个条形图需要重新绘制。问题是什么是连接重绘的好方法,因为规模/域没有变更通知机制。

http://bl.ocks.org/markfink/4d8f1c183e6cd9d6ea07

1 个答案:

答案 0 :(得分:2)

以下是一个实现:http://jsfiddle.net/tBHyD/2/

我只是试图解决问题中的设置,而不是评论中提到的完整实现。有很多方法可以实现这一目标;这个使用事件驱动的模型,使用d3.dispatch

    var evt = d3.dispatch("change");

这里的关键是全局更新比例范围,然后在事件发生变化时触发事件。在这里,我使用函数updateExtent来实现此目的:

    var x0 = Infinity,
        x1 = -Infinity,
        y0 = Infinity,
        y1 = -Infinity;
    function updateExtent(data) {
        var extx = d3.extent(data, function(d) { return d[0]; }),
            exty = d3.extent(data, function(d) { return d[1]; }),
            changed;
        // update
        if (extx[0] < x0) { x0 = extx[0]; changed = true; }
        if (extx[1] > x1) { x1 = extx[1]; changed = true; }
        if (exty[0] < y0) { y0 = exty[0]; changed = true; }
        if (exty[1] > y1) { y1 = exty[1]; changed = true; }
        // if changed, update scales and fire event
        if (changed) {
            // update scales
            x.domain([x0, x1]);
            y.domain([y1, y0]);
            // update axes
            vis.select(".x.axis").call(xAxis);
            vis.select(".y.axis").call(yAxis);
            // fire event
            evt.change();
        }
    }

然后redraw函数设置一个监听器:

    function redraw(selection, data, style) {
        var bar = selection.selectAll(".bar")
            .data(data);

        // enter
        bar.enter().append("rect")
            .attr('class', "bar")
            .attr("width", 5)
            .style(style);

        function updateBar() {
            // update
            bar
                .attr("x", function(d) { return x(d[0]) - .5; })
                .attr("y", function(d) { return y(d[1]); })
                .attr("height", function(d) { return height - y(d[1]);  });
        }
        // initial call
        updateBar();
        // handler call
        evt.on("change", updateBar);
    };

请注意,现在您无需明确设置范围:

    var data1 = [[2,0.5], [4,0.8], [6,0.6], [8,0.7], [12,0.8]];
    updateExtent(data1);