D3.js d3 v4 voronoi在充满(点/圆)的散点图svg中查找最近的邻居
我正试图利用下面所附的数据,在这个片段的帮助下,在散点图中找到最近的邻居-D3.js d3 v4 voronoi在充满(点/圆)的散点图svg中查找最近的邻居,d3.js,scatter-plot,nearest-neighbor,voronoi,quadtree,D3.js,Scatter Plot,Nearest Neighbor,Voronoi,Quadtree,我正试图利用下面所附的数据,在这个片段的帮助下,在散点图中找到最近的邻居- const voronoiDiagram = d3.voronoi() .x(d => d.x) .y(d => d.y)(data); data.forEach(function(d){ console.log(d, voronoiDiagram.find(d.x,
const voronoiDiagram = d3.voronoi()
.x(d => d.x)
.y(d => d.y)(data);
data.forEach(function(d){
console.log(d, voronoiDiagram.find(d.x, d.y, 50));
});
现在我使用的数据集是标准的虹膜萼片,花瓣长度数据
格式-
{"sepalLength":7.7,"sepalWidth":3,"petalLength":"6.1","petalWidth":"2.3","species":"virginica","index":135,"x":374.99999999999994,"y":33.75,"vy":0,"vx":0},
{"sepalLength":6.3,"sepalWidth":3.4,"petalLength":"5.6","petalWidth":"2.4","species":"virginica","index":136,"x":524.9999999999999,"y":191.25,"vy":0,"vx":0},
{"sepalLength":6.4,"sepalWidth":3.1,"petalLength":"5.5","petalWidth":"1.8","species":"virginica","index":137,"x":412.5,"y":179.99999999999994,"vy":0,"vx":0},
{"sepalLength":6,"sepalWidth":3,"petalLength":"4.8","petalWidth":"1.8","species":"virginica","index":138,"x":374.99999999999994,"y":225,"vy":0,"vx":0},
....
因此,本质上它是以
{d:{x,y,萼片长度,宽度,花瓣长度,宽度}
现在,我正试图找到最近的邻居与d3沃罗尼从
但是,我得到的只是结果-
让数据集中的点d=
{"sepalLength":5.9,"sepalWidth":3,"petalLength":"5.1","petalWidth":"1.8","species":"virginica","index":149,"x":374.99999999999994,"y":236.24999999999997,"vy":0,"vx":0}
现在,voronoiDiagram.find(d.x,d.y,50)
会导致-
"[375,236.25]"
即,坐标舍入的同一点,而不是另一点
那么,在这种情况下,如何从voronoi图中排除正在扫描的当前点呢。
另外,如果我排除这一点&重新计算所有内容,从性能角度来看,这是否有好处
有人能帮我从一组点中找到最近的邻居吗
使用d3 voronoi/quadtrees(我已经尝试了Mike Bostock提供的几个示例,但由于一些错误,无法在我的案例中使用它们,
因此,如果d3 voronoi没有帮助,将发布它们)。voronoiDiagram.find(y,x,r)将最多返回一次单元格。从API文档:
返回距离点[x,y]最近的场地。如果指定了半径,则只考虑半径距离内的场地。()
我以前读过复数形式,显然我从来没有仔细看过(我认为能够找到给定半径内的所有点有很大的实用性)
我们可以做的是相当容易地创建一个函数,该函数将:
voronoiDiagram.find()开始查找点所在的单元格
- 将邻居添加到点位于指定半径内的单元格列表中
- 使用邻居重复步骤2至4
findAll(x,y,r)
中)将指定距离内的点显示为橙色,最近的点将显示为红色(我已将函数设置为区分这两个点)
var宽度=500;
var高度=300;
var数据=d3.范围(200).映射(函数(d){
var x=Math.random()*宽度;
var y=Math.random()*高度;
var指数=d;
返回{x:x,y:y,index:index}
});
var svg=d3.选择(“主体”)
.append(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
var circles=svg.selectAll()
.data(数据,函数(d,i){返回d.index;});
圆=圆。输入()
.附加(“圆圈”)
.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;})
.attr(“r”,3)
.attr(“填充”、“钢蓝”)
.合并(圆圈);
var voronoi=d3.voronoi()
.x(函数(d){返回d.x;})
.y(函数(d){返回d.y;})
.尺寸([宽度、高度])(数据);
var结果=findAll(宽度/2,高度/2,30);
圆.data(results.nearest,函数(d){return d.index;})
.attr(“填充”、“橙色”);
circles.data([results.center],函数(d){return d.index;})
.attr(“填充”、“深红色”);
var circle=svg.append(“circle”)
.attr(“cx”,宽度/2)
.attr(“cy”,高度/2)
.attr(“r”,30)
.attr(“填充”、“无”)
.attr(“笔划”、“黑色”)
.attr(“笔划宽度”,1);
圆。过渡()
.attrTween(“r”,函数(){
var节点=这个;
返回函数(t){
var r=d3.插值(30148)(t);
var结果=findAll(宽度/2,高度/2,r);
圆.data(results.nearest,函数(d){return d.index;})
.attr(“填充”、“橙色”);
返回r;
}
})
.期限(2000年)
.延迟(1000);
函数findAll(x,y,r){
var start=voronoi.find(x,y,r);
if(!start)返回{center:[],nearest:[]};//无结果。
var queue=[start];
检查的var=[];
var结果=[];
对于(i=0;ir)。推送(n.index)//不检查单元格两次
否则{
queue.push(n);//添加到队列
results.push(n);//添加到结果
}
}
})
}
//中心:距离点x,y最近/重叠且在指定半径内的点/单元
//最近:点x、y的指定半径内的所有其他单元格
返回{中心:开始,最近:结果};
}
最近的邻居可以解释为紧邻的邻居(与目标共享一条边的单元格).为了澄清,你是在寻找某个半径范围内的单元格还是与给定单元格共享一条边的单元格?寻找半径范围内的单元格感谢此次更新。我已经阅读了更多关于voronois的内容,并了解了更多关于你的答案。嗨@andrew reid如果你知道d3平行坐标图的一些信息,你能帮助我们吗还有这些问题——或者我对平行坐标没有做太多的研究,但我可以看一看——可能要过一两天我才能有机会,我基本上离手机还有一段距离