我有一些代码可以使用D3渲染具有可拖动节点的网络图。该代码类似于以下示例https://bl.ocks.org/mbostock/4557698
我的图的区别在于节点的颜色根据实时数据而变化。每秒从Web服务器轮询一次此数据,我使用selection.join()
函数来处理状态更改。
问题在于,当用户拖动节点并且状态改变时,拖动停止(即,被拖动的元素被释放)。我不确定为什么会这样,因为我实际上没有重新渲染元素。
我想到的一种方法是在拖动节点时阻止轮询。但是,这意味着在拖动停止之前,节点的颜色不会更新。这不是一个大问题,但是理想情况下,我希望实时数据和拖动数据能够同时工作。处理此案的正确方法是什么?
let nodes = svg
.select('#node-group')
.selectAll('.'+styles['node'])
.data(graphNodes, function(d) {
return d ? d.id : this.id
})
.join(
enter => enter.append('g')
.attr('class', styles['node'])
.append('circle')
.style('fill', getCircleColor)
.attr('r', 25),
update => update
.select('circle')
.style('fill', getCircleColor)
.attr('r', 25)
)
function getCircleColor(d) {
switch (d.state) {
case 'ready': return 'green'
case 'down': return 'red'
default: return 'darkgrey'
}
}
nodes
.call(d3.drag()
.on('start', dragStart)
.on('drag', dragMove)
.on('end', dragEnd))
.on('mouseover',
function(d) {
d3.select(this).style('cursor', 'grab')
})
function dragStart() {
d3.select(this).style('cursor', 'grabbing')
}
function dragEnd() {
d3.select(this).style('cursor', 'grab')
}
function dragMove(d) {
d.x = d3.event.x
d.y = d3.event.y
ticked()
}