我想将多个条形图绘制到同一个可视化中。
绘制第一个条形图时,它对第二个、第三个等的域一无所知。在绘制第二个条形图时,y 刻度的域发生了变化。'因此需要重新绘制第一个条形图。问题是什么是连接重绘的好方法,因为比例/域没有更改通知机制。
我想将多个条形图绘制到同一个可视化中。
绘制第一个条形图时,它对第二个、第三个等的域一无所知。在绘制第二个条形图时,y 刻度的域发生了变化。'因此需要重新绘制第一个条形图。问题是什么是连接重绘的好方法,因为比例/域没有更改通知机制。
这是一个实现: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);