带有传单和 D3.js [问题] 的气泡图:气泡重叠
Bubble Map with leaflet and D3.js [problem] : bubbles overlapping
我这里有一张带有虚拟数据的基本地图。基本上是气泡图。
问题是我有多个点(例如:20)具有完全相同的 GPS 坐标。
下图是我的带有虚拟数据的 csv,在此基本示例中,蓝色突出显示重叠点。那是因为很多公司都有相同的城市gps坐标。
这是一个 fiddle,其中包含我正在处理的代码:
https://jsfiddle.net/MathiasLauber/bckg8es4/45/
后来研究了很多,发现d3.js加上这个力模拟功能,可以避免点碰撞。
// Avoiding bubbles overlapping
var simulationforce = d3.forceSimulation(data)
.force('x', d3.forceX().x(d => xScale(d.longitude)))
.force('y', d3.forceY().y(d => yScale(d.latitude)))
.force('collide', d3.forceCollide().radius(function(d) {
return d.radius + 10
}))
simulationforce
.nodes(cities)
.on("tick", function(d){
node
.attr("cx", function(d) { return projection.latLngToLayerPoint([d.latitude, d.longitude]).x; })
.attr("cy", function(d) {return projection.latLngToLayerPoint([d.latitude, d.longitude]).y; })
});
问题是我无法进行强制布局,而且我的点仍然在彼此之上。 (第 188-200 行在 fiddle).
如果您有任何提示、建议,或者如果您发现我的代码中存在基本错误,请告诉我 =D
一堆代码接近我想要实现的目标
https://d3-graph-gallery.com/graph/circularpacking_group.html
https://jsbin.com/taqewaw/edit?html,output
有3个问题:
- 为了将圆定位在其原始位置附近,需要在传递给
simulation.nodes()
调用的数据中指定 x
和 y
初始位置。
- 进行力模拟时,需要在on tick回调中提供要模拟的选择(参见
on('tick')
回调函数中的node
)。
- 模拟需要使用之前的
d.x
和 d.y
模拟计算的值
相关代码片段如下
// 1. Add x and y (cx, cy) to each row (circle) in data
const citiesWithCenter = cities.map(c => ({
...c,
x: projection.latLngToLayerPoint([c.latitude, c.longitude]).x,
y: projection.latLngToLayerPoint([c.latitude, c.longitude]).y,
}))
// citiesWithCenter will be passed to selectAll('circle').data()
// 2. node selection you forgot
const node = selection
.selectAll('circle')
.data(citiesWithcenter)
.enter()
.append('circle')
...
// let used in simulation
simulationforce.nodes(citiesWithcenter).on('tick', function (d) {
node
.attr('cx', function (d) {
// 3. use previously computed x value
// on the first tick run, the values in citiesWithCenter is used
return d.x
})
.attr('cy', function (d) {
// 3. use previously computed y value
// on the first tick run, the values in citiesWithCenter is used
return d.y
})
})
完整的工作演示在这里:https://jsfiddle.net/b2Lhfuw5/
我这里有一张带有虚拟数据的基本地图。基本上是气泡图。
问题是我有多个点(例如:20)具有完全相同的 GPS 坐标。
下图是我的带有虚拟数据的 csv,在此基本示例中,蓝色突出显示重叠点。那是因为很多公司都有相同的城市gps坐标。
这是一个 fiddle,其中包含我正在处理的代码:
https://jsfiddle.net/MathiasLauber/bckg8es4/45/
后来研究了很多,发现d3.js加上这个力模拟功能,可以避免点碰撞。
// Avoiding bubbles overlapping
var simulationforce = d3.forceSimulation(data)
.force('x', d3.forceX().x(d => xScale(d.longitude)))
.force('y', d3.forceY().y(d => yScale(d.latitude)))
.force('collide', d3.forceCollide().radius(function(d) {
return d.radius + 10
}))
simulationforce
.nodes(cities)
.on("tick", function(d){
node
.attr("cx", function(d) { return projection.latLngToLayerPoint([d.latitude, d.longitude]).x; })
.attr("cy", function(d) {return projection.latLngToLayerPoint([d.latitude, d.longitude]).y; })
});
问题是我无法进行强制布局,而且我的点仍然在彼此之上。 (第 188-200 行在 fiddle).
如果您有任何提示、建议,或者如果您发现我的代码中存在基本错误,请告诉我 =D
一堆代码接近我想要实现的目标
https://d3-graph-gallery.com/graph/circularpacking_group.html
https://jsbin.com/taqewaw/edit?html,output
有3个问题:
- 为了将圆定位在其原始位置附近,需要在传递给
simulation.nodes()
调用的数据中指定x
和y
初始位置。 - 进行力模拟时,需要在on tick回调中提供要模拟的选择(参见
on('tick')
回调函数中的node
)。 - 模拟需要使用之前的
d.x
和d.y
模拟计算的值
相关代码片段如下
// 1. Add x and y (cx, cy) to each row (circle) in data
const citiesWithCenter = cities.map(c => ({
...c,
x: projection.latLngToLayerPoint([c.latitude, c.longitude]).x,
y: projection.latLngToLayerPoint([c.latitude, c.longitude]).y,
}))
// citiesWithCenter will be passed to selectAll('circle').data()
// 2. node selection you forgot
const node = selection
.selectAll('circle')
.data(citiesWithcenter)
.enter()
.append('circle')
...
// let used in simulation
simulationforce.nodes(citiesWithcenter).on('tick', function (d) {
node
.attr('cx', function (d) {
// 3. use previously computed x value
// on the first tick run, the values in citiesWithCenter is used
return d.x
})
.attr('cy', function (d) {
// 3. use previously computed y value
// on the first tick run, the values in citiesWithCenter is used
return d.y
})
})
完整的工作演示在这里:https://jsfiddle.net/b2Lhfuw5/