【发布时间】:2017-02-23 00:41:29
【问题描述】:
我有一个功能齐全的 d3.js 力有向图。有各种与图表相关的过滤器。
我现在正在尝试使用突出显示功能,即如果双击节点,那么与图表的其余部分相比,该节点及其所有邻居都处于更高的不透明度。再次双击任何节点,整个图表将变得可见。
这很好用:
var toggle = 0;
//Create an array logging what is connected to what
var linkedByIndex = {};
for (i = 0; i < d3GraphData.nodes.length; i++) {
linkedByIndex[i + "," + i] = 1;
};
d3GraphData.links.forEach(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.1;
});
link.style("opacity", function (o) {
return d.index==o.source.index | d.index==o.target.index ? 1 : 0.1;
});
//Reduce the op
toggle = 1;
} else {
//Put them back to opacity=1
node.style("opacity", 1);
link.style("opacity", 1);
toggle = 0;
}
}
现在,我还有另一个通过复选框控制的不透明度过滤器。取消选中复选框会使未选中的节点不可见。
有4种节点类型:
Agent,Customer,Phone,ID_Card
节点有一个属性
d.visible:true
visible 属性的当前状态取决于选中/取消选中的框,保留在不透明度过滤器的代码中。
下面是复选框部分的代码:
var circles = svg.selectAll(".node");
var lines = svg.selectAll(".link");
lines.style("opacity", function(d) {
return getOpacity(d.source) && getOpacity(d.target) ? 1 : 0;
})
var nodeTypes = ["Agent", "Customer", "Phone", "ID_Card"];
var checkBoxes = [];
for (let i = 0; i < nodeTypes.length; i++) {
checkBoxes.push(document.querySelectorAll('input[value="' + nodeTypes[i] + '"]')[0])
checkBoxes[i].checked = true;
checkBoxes[i].addEventListener("click", function() {
filterBy("type", checkBoxes[i].value, checkBoxes[i].checked);
});
}
var toggleOpacity = function(attribute, value, visible) {
circles.filter(function(d) { //filter circles by attribute value
return d[attribute] == value;
})
.each(function(d) { //modify visible attribute
d.visible = visible;
})
.style("opacity", function(d) { // get opacity
return getOpacity(d);
});
lines.filter(function(d) { // get links for attribute-value
return d.source[attribute] == value || d.target[attribute] == value;
})
.style("opacity", function(d) { // modify opacity
return getOpacity(d.source) && getOpacity(d.target) ? 1 : 0;
})
}
var filterBy = function(attribute, value, visible, highlightSelected) {
if (highlightSelected) {
circles.style("opacity", 0)
lines.style("opacity", 0)
toggleOpacity(attribute, value, visible)
circles.filter(function(d){return d.visible;}).transition()
.duration(2000)
.style("opacity", 1);
lines.filter(function(d){return d.source.visible && d.target.visible}).transition()
.duration(2000)
.style("opacity", 1);
}
else{
toggleOpacity(attribute, value, visible)
}
}
当某些复选框未选中时,节点的突出显示现在似乎不起作用。
例如当 Customer 和 Phone 被选中时,双击 Customer 节点应该只显示相邻的Customer 和 电话 节点。
但即使是其他不可见的相邻节点也会出现。
在connected nodes()函数中,我尝试使用节点的visible属性。
node.style("opacity", function (o) {
return neighboring(d.visible, o.visible) | neighboring(o.visible, d.visible) ? 1 : 0.1;
});
但这种方法似乎行不通。
由于 visible 属性的当前状态已经被计算出来,它只是一个正确使用它的问题。但我正在努力做到这一点。仍然是我在 d3.js 中的第一个项目,因此感谢您的投入。
工作fiddle
【问题讨论】:
标签: javascript d3.js