如何在 D3 v4 力图中只有一些边缘对“鼠标悬停”做出反应
How to have only some edges react to `mouseover` in a D3 v4 force graph
我正在开发 D3 v4 中的 this force graph。
当用户点击节点时,只有与其相连的节点可见。此外,连接这些节点的边缘变得更粗,用户可以将鼠标悬停在上面,以便查看更多信息(出现在右侧的工具提示)。
这是我在点击后突出显示连接节点的方式
//Highlight on click
function highlighting () {
//Toggle stores whether the highlighting is on
var node = d3.selectAll('circle');
var link = d3.selectAll('line');
var toggle = 0;
//Create an array logging what is connected to what
var linkedByIndex = {};
for (i = 0; i < dataset.nodes.length; i++) {
linkedByIndex[i + "," + i] = 1;
};
d3.selectAll('line').each(function (d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
//This function looks up whether a pair are neighbours
function neighboring(a, b) {
return linkedByIndex[a.index + "," + b.index];
}
function connectedNodes() {
if (toggle == 0) {
//Reduce the opacity of all but the neighbouring nodes
d = d3.select(this).node().__data__;
node.style("opacity", function (o) {
return neighboring(d, o) | neighboring(o, d) ? 1 : 0.0;
});
link.style("opacity", function (o) {
return d.index==o.source.index | d.index==o.target.index ? 1 : 0.0;
});
link.attr('stroke-width' , 4);
toggle = 1;
interactivityHighlight();
//Change navigation div
d3.select('#click01').classed('hidden', true);
d3.select('#click02').classed('hidden', false);
} else {
//Put them back to starting opacity
node.style("opacity", 1);
link.style("opacity", function (d) {return edgeOpacityScale(d.collaborations);});
link.attr('stroke-width', 1);
link.attr('class', null);
toggle = 0;
//Change navigation
d3.select('#click01').classed('hidden', false);
d3.select('#click02').classed('hidden', true);
}
}
node.on('click', connectedNodes);
}
这是我点击后调用的函数
function interactivityHighlight () {
graph.selectAll('line').on('mouseover', function (d) {
if (d3.select(this).style('opacity') == 1) {
d3.select(this)
.attr('stroke', 'red')
.attr('stroke-width', 6);
d3.select('#tooltip')
.classed('hidden', false);
d3.select('#tooltip')
.append('p')
.attr('id', 'org_names')
.text('Collaborations between ' + d.source.name + ' and ' + d.target.name);
d3.select('#tooltip')
.append('p')
.attr('id', 'collaborations')
.text('Worked together on ' + d.collaborations + ' projects');
d3.select('#tooltip')
.append('p')
.attr('id', 'collBudget')
.text('Total budget: '+ commafy(d.collBudget));
}})
graph.selectAll('line').on('mouseout', function (d) {
if (d3.select(this).style('opacity') == 1) {
d3.select(this)
.attr('stroke', 'black')
.attr('stroke-width', 4);
d3.select('#tooltip')
.selectAll('p')
.remove();
d3.select('#tooltip')
.classed('hidden', true);
}})
}
基本上所有未连接的节点都会得到opacity=0
,从而变得不可见。但是,它们仍然出现在图表上:悬停在一条线上可能不会触发 interactivityHighlight()
,因为鼠标实际上悬停在一条不可见的边缘上。
有没有办法让不可见的边缘真正消失,或者让所有其他边缘可见的 "get on top"?
添加包含此指针事件规则的 css class,例如:
.hidden {
pointer-events: none;
}
然后在链接上设置 class
.classed("hidden", function(d) {
/* return true/false, decide using the same logic you use for opacity */
});
与隐藏 class 的链接将让指针事件传递到下面的任何内容
使用您用于定义 "opacity" 的相同规则来定义 "pointer-events":
link.attr("pointer-events", function (o) {
return d.index==o.source.index | d.index==o.target.index ? "all" : "none";
});
我正在开发 D3 v4 中的 this force graph。
当用户点击节点时,只有与其相连的节点可见。此外,连接这些节点的边缘变得更粗,用户可以将鼠标悬停在上面,以便查看更多信息(出现在右侧的工具提示)。
这是我在点击后突出显示连接节点的方式
//Highlight on click
function highlighting () {
//Toggle stores whether the highlighting is on
var node = d3.selectAll('circle');
var link = d3.selectAll('line');
var toggle = 0;
//Create an array logging what is connected to what
var linkedByIndex = {};
for (i = 0; i < dataset.nodes.length; i++) {
linkedByIndex[i + "," + i] = 1;
};
d3.selectAll('line').each(function (d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
//This function looks up whether a pair are neighbours
function neighboring(a, b) {
return linkedByIndex[a.index + "," + b.index];
}
function connectedNodes() {
if (toggle == 0) {
//Reduce the opacity of all but the neighbouring nodes
d = d3.select(this).node().__data__;
node.style("opacity", function (o) {
return neighboring(d, o) | neighboring(o, d) ? 1 : 0.0;
});
link.style("opacity", function (o) {
return d.index==o.source.index | d.index==o.target.index ? 1 : 0.0;
});
link.attr('stroke-width' , 4);
toggle = 1;
interactivityHighlight();
//Change navigation div
d3.select('#click01').classed('hidden', true);
d3.select('#click02').classed('hidden', false);
} else {
//Put them back to starting opacity
node.style("opacity", 1);
link.style("opacity", function (d) {return edgeOpacityScale(d.collaborations);});
link.attr('stroke-width', 1);
link.attr('class', null);
toggle = 0;
//Change navigation
d3.select('#click01').classed('hidden', false);
d3.select('#click02').classed('hidden', true);
}
}
node.on('click', connectedNodes);
}
这是我点击后调用的函数
function interactivityHighlight () {
graph.selectAll('line').on('mouseover', function (d) {
if (d3.select(this).style('opacity') == 1) {
d3.select(this)
.attr('stroke', 'red')
.attr('stroke-width', 6);
d3.select('#tooltip')
.classed('hidden', false);
d3.select('#tooltip')
.append('p')
.attr('id', 'org_names')
.text('Collaborations between ' + d.source.name + ' and ' + d.target.name);
d3.select('#tooltip')
.append('p')
.attr('id', 'collaborations')
.text('Worked together on ' + d.collaborations + ' projects');
d3.select('#tooltip')
.append('p')
.attr('id', 'collBudget')
.text('Total budget: '+ commafy(d.collBudget));
}})
graph.selectAll('line').on('mouseout', function (d) {
if (d3.select(this).style('opacity') == 1) {
d3.select(this)
.attr('stroke', 'black')
.attr('stroke-width', 4);
d3.select('#tooltip')
.selectAll('p')
.remove();
d3.select('#tooltip')
.classed('hidden', true);
}})
}
基本上所有未连接的节点都会得到opacity=0
,从而变得不可见。但是,它们仍然出现在图表上:悬停在一条线上可能不会触发 interactivityHighlight()
,因为鼠标实际上悬停在一条不可见的边缘上。
有没有办法让不可见的边缘真正消失,或者让所有其他边缘可见的 "get on top"?
添加包含此指针事件规则的 css class,例如:
.hidden {
pointer-events: none;
}
然后在链接上设置 class
.classed("hidden", function(d) {
/* return true/false, decide using the same logic you use for opacity */
});
与隐藏 class 的链接将让指针事件传递到下面的任何内容
使用您用于定义 "opacity" 的相同规则来定义 "pointer-events":
link.attr("pointer-events", function (o) {
return d.index==o.source.index | d.index==o.target.index ? "all" : "none";
});