Javascript d3.js散点图-缩放/拖动边界、缩放按钮、重置缩放、计算中值
我已经构建了一个具有缩放/平移功能的d3.js散点图。您可以在此处查看全部内容(单击“在新窗口中打开”查看全部内容): 有几个功能我还没弄清楚,如果有人能给我指出正确的方向,我希望能帮我一把:Javascript d3.js散点图-缩放/拖动边界、缩放按钮、重置缩放、计算中值,javascript,d3.js,zooming,drag,scatter-plot,Javascript,D3.js,Zooming,Drag,Scatter Plot,我已经构建了一个具有缩放/平移功能的d3.js散点图。您可以在此处查看全部内容(单击“在新窗口中打开”查看全部内容): 有几个功能我还没弄清楚,如果有人能给我指出正确的方向,我希望能帮我一把: 我想将X/Y缩放/平移边界应用于该区域,以便您不能将其拖动到某个点(例如零)以下 我也尝试过创建谷歌地图风格的+/-缩放按钮,但没有成功。有什么想法吗 更不重要的是,我也在几个方面找到了解决方案,但非常粗糙,因此如果您有更好的解决方案,请务必让我知道: 我添加了一个“重置缩放”按钮,但它只是删除图形并在
var xMed = median(_.map(data,function(d){ return d.TotalEmployed2011;}));
var yMed = median(_.map(data,function(d){ return d.MedianSalary2011;}));
function median(values) {
values.sort( function(a,b) {return a - b;} );
var half = Math.floor(values.length/2);
if(values.length % 2)
return values[half];
else
return (parseFloat(values[half-1]) + parseFloat(values[half])) / 2.0;
};
// Zoom in/out buttons:
d3.select('#zoomIn').on('click',function(){
d3.event.preventDefault();
if (zm.scale()< maxScale) {
zm.translate([trans(0,-10),trans(1,-350)]);
zm.scale(zm.scale()*2);
zoom();
}
});
d3.select('#zoomOut').on('click',function(){
d3.event.preventDefault();
if (zm.scale()> minScale) {
zm.scale(zm.scale()*0.5);
zm.translate([trans(0,10),trans(1,350)]);
zoom();
}
});
// Reset zoom button:
d3.select('#zoomReset').on('click',function(){
d3.event.preventDefault();
zm.scale(1);
zm.translate([0,0]);
zoom();
});
function zoom() {
// To restrict translation to 0 value
if(y.domain()[0] < 0 && x.domain()[0] < 0) {
zm.translate([0, height * (1 - zm.scale())]);
} else if(y.domain()[0] < 0) {
zm.translate([d3.event.translate[0], height * (1 - zm.scale())]);
} else if(x.domain()[0] < 0) {
zm.translate([0, d3.event.translate[1]]);
}
...
};
//放大/缩小按钮:
d3.选择('zoomIn')。打开('click',函数(){
d3.event.preventDefault();
如果(zm.scale()minScale){
zm.刻度(zm.刻度()*0.5);
翻译([trans(0,10),trans(1350)]);
缩放();
}
});
//重置缩放按钮:
d3.选择(“#zoomReset”)。在('单击',函数()上{
d3.event.preventDefault();
zm.标度(1);
zm.translate([0,0]);
缩放();
});
函数zoom(){
//将转换限制为0值的步骤
如果(y.domain()[0]<0和&x.domain()[0]<0){
zm.translate([0,高度*(1-zm.scale())]);
}如果(y.domain()[0]<0),则为else{
zm.translate([d3.event.translate[0],height*(1-zm.scale())]);
}else if(x.domain()[0]<0){
zm.translate([0,d3.event.translate[1]]);
}
...
};
我使用的缩放平移是非常特别的,基本上使用了一个常量来保持定位在正确的位置。这并不理想,我愿意接受关于更普遍的声音技术的建议。但是,它在这种情况下工作得足够好。从中值函数开始,只需要一个数组和一个可选的访问器。因此,您可以像使用max一样使用它:
var med = d3.median(data, function(d) { return +d.TotalEmployed2011; });
至于其他人,如果你拿出你的缩放行为,你可以更好地控制它一点。所以,比如说
var svg = d3.select()...call(d3.behavior.zoom()...)
尝试:
然后可以直接设置缩放级别和平移:
function zoomIn() {
zm.scale(zm.scale()*2);
// probably need to compute a new translation also
}
function reset() {
zm.scale(1);
zm.translate([0,0]);
}
限制平移范围有点棘手。当缩放功能中的平移或缩放不符合您的喜好时,您可以简单地不进行更新(或将缩放的“平移”设置为您需要的值)。比如(我想在你的情况下):
函数缩放(){
如果(y.domain()[0]<0){
//将转换限制为0值的步骤
zm.translate([d3.event.translate[0],height*(1-zm.scale())]);
}
....
}
请记住,如果您希望放大以允许轴上出现负片,但不希望平移,则会发现您陷入一些棘手的场景
这可能是过时的,但请检查
还要注意,缩放行为确实具有限制平移和缩放的功能。但是代码在稍后的一段时间内被删除。我不喜欢重新发明轮子。我正在搜索允许缩放的散点图。Highcharts是其中之一,但是plotly是基于D3的,不仅允许缩放,而且散点图上也可以有线条数据集,我希望我的一些数据集可以使用散点图,这在其他绘图库中很难找到。我想试试:
使用这么好的库可以为您节省大量的时间和痛苦。再次非常感谢!缩放/重置代码似乎有效,但缩放比例仅在下一次缩放事件(即拖动或鼠标滚轮)时更改。我很难在点击按钮时更新内容。这一定很简单,但我就是想不出来。我的按钮点击代码是:d3.select('#zoomIn').call(zoom).on('click',function(){d3.event.preventDefault();zm.scale(zm.scale()*2);});我尝试了.call()、zoom()和.on()的各种用法,但都没有效果。我在我的屏幕底部添加了一个快速的蓝色小缩放方块。您所缺少的只是在设置比例后调用zoom()。将您提供的缩放功能想象为应用由行为计算的缩放状态。好的!分类!事实证明,这正是我正在做的,但对我来说并不奏效。。。长话短说:当我使用版本2时,你使用的是d3版本3,这就是为什么当我在代码中删除你的蓝色方块时,它不起作用。已经升级到v3,现在可以使用了。干杯:)啊,很高兴知道!我知道他们重写了缩放行为,但我不想检查版本!不用担心:)。顺便说一句,我现在几乎已经发布了它,但是为了将来的参考(万一有人无意中发现了这个页面,想知道我是如何做到的,或者可以提出改进建议):我在计算translate函数时遇到了一些麻烦,所以我最后敲入了一些任意常数。它似乎工作得很好:函数trans(xy,constant){return zm.translate()[xy]+(constant*(zm.scale());}zm.translate([trans(0,-10),trans(1,-350)
var zm = d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom);
var svg = d3.select()...call(zm);
function zoomIn() {
zm.scale(zm.scale()*2);
// probably need to compute a new translation also
}
function reset() {
zm.scale(1);
zm.translate([0,0]);
}
function zoom() {
if(y.domain()[0] < 0) {
// To restrict translation to 0 value
zm.translate([d3.event.translate[0], height * (1 - zm.scale())]);
}
....
}