更有效的方式来处理 Mouseevent
More efficient way to handle Mouseevent
我实现了桑基图,能够通过图表跟踪节点路径。然而,就功能而言,用户必须 mouseenter
一个节点才能突出显示和删除节点路径的突出显示。在 mouseenter 上突出显示节点路径然后删除该突出显示(通过不透明度更改)mouseout
的好方法是什么?顺便说一句,我试图只调用函数来使用 mouseenter
和 mouseout
的组合,但这似乎并没有解决问题。这是我的代码:
function highlightNodeLinks(node, i) {
var remainingNodes = [],
nextNodes = [],
strokeOpacity = 0,
traverse;
if ( d3.select(this).attr('data-hover') === '1' ) {
d3.select(this).attr('data-hover', '0');
strokeOpacity = 0.2;
} else {
d3.select(this).attr('data-hover', '1');
strokeOpacity = 0.5;
}
traverse = [{
linkType : 'sourceLinks',
nodeType : 'target'
}, {
linkType : 'targetLinks',
nodeType : 'source'
}];
traverse.forEach(function (step) {
node[step.linkType].forEach(function (link) {
remainingNodes.push(link[step.nodeType]);
highlightLink(link.id, strokeOpacity);
});
while (remainingNodes.length) {
nextNodes = [];
remainingNodes.forEach(function (node) {
node[step.linkType].forEach(function (link) {
nextNodes.push(link[step.nodeType]);
highlightLink(link.id, strokeOpacity);
});
});
remainingNodes = nextNodes;
}
});
}
function highlightLink(id, opacity) {
d3.select('#link-' + id).style('stroke-opacity', opacity);
}
它的名字是这样的:
.on('mouseover', highlightNodeLinks)
一如既往地感谢您的考虑和建议。
分两步:首先进行预处理,使每个节点 "knows" 鼠标悬停时必须突出显示的链接集。这对内存来说很重(它不会针对非常大的图形进行缩放),但响应速度应该更快
//call this once after loading the data and first drawing of the links
node.forEach(function(n) {
linkIds= []; //add this field to each node
traverse.forEach(function (step) {
node[step.linkType].forEach(function (link) {
remainingNodes.push(link[step.nodeType]);
linkIds.push(link.id);
});
while (remainingNodes.length) {
nextNodes = [];
remainingNodes.forEach(function (node) {
node[step.linkType].forEach(function (link) {
nextNodes.push(link[step.nodeType]);
linkIds(link.id);
});
});
remainingNodes = nextNodes;
}
//add the list of links to a new field in the node
//& transform already ids into d3 selections
n.linksToHighlight = linkIds.map(function(id) {return d3.select("link-"+id)})
});
然后,接着高亮代码:
function highlighter(ratio) {
return function(node) {
node.linksToHighlight.forEach(function (s) {s.style("stroke-opacity",ratio})
}
}
[select nodes]
.on('mouseenter', highlighter(0.5) )
.on('mouseout', highlighter(1) )
我刚刚使用 d3 实现了一个指令,我想你会找到你正在寻找的例子,你可以在 github https://github.com/amgadfahmi/angular-bubbletree
上查看代码
我实现了桑基图,能够通过图表跟踪节点路径。然而,就功能而言,用户必须 mouseenter
一个节点才能突出显示和删除节点路径的突出显示。在 mouseenter 上突出显示节点路径然后删除该突出显示(通过不透明度更改)mouseout
的好方法是什么?顺便说一句,我试图只调用函数来使用 mouseenter
和 mouseout
的组合,但这似乎并没有解决问题。这是我的代码:
function highlightNodeLinks(node, i) {
var remainingNodes = [],
nextNodes = [],
strokeOpacity = 0,
traverse;
if ( d3.select(this).attr('data-hover') === '1' ) {
d3.select(this).attr('data-hover', '0');
strokeOpacity = 0.2;
} else {
d3.select(this).attr('data-hover', '1');
strokeOpacity = 0.5;
}
traverse = [{
linkType : 'sourceLinks',
nodeType : 'target'
}, {
linkType : 'targetLinks',
nodeType : 'source'
}];
traverse.forEach(function (step) {
node[step.linkType].forEach(function (link) {
remainingNodes.push(link[step.nodeType]);
highlightLink(link.id, strokeOpacity);
});
while (remainingNodes.length) {
nextNodes = [];
remainingNodes.forEach(function (node) {
node[step.linkType].forEach(function (link) {
nextNodes.push(link[step.nodeType]);
highlightLink(link.id, strokeOpacity);
});
});
remainingNodes = nextNodes;
}
});
}
function highlightLink(id, opacity) {
d3.select('#link-' + id).style('stroke-opacity', opacity);
}
它的名字是这样的:
.on('mouseover', highlightNodeLinks)
一如既往地感谢您的考虑和建议。
分两步:首先进行预处理,使每个节点 "knows" 鼠标悬停时必须突出显示的链接集。这对内存来说很重(它不会针对非常大的图形进行缩放),但响应速度应该更快
//call this once after loading the data and first drawing of the links
node.forEach(function(n) {
linkIds= []; //add this field to each node
traverse.forEach(function (step) {
node[step.linkType].forEach(function (link) {
remainingNodes.push(link[step.nodeType]);
linkIds.push(link.id);
});
while (remainingNodes.length) {
nextNodes = [];
remainingNodes.forEach(function (node) {
node[step.linkType].forEach(function (link) {
nextNodes.push(link[step.nodeType]);
linkIds(link.id);
});
});
remainingNodes = nextNodes;
}
//add the list of links to a new field in the node
//& transform already ids into d3 selections
n.linksToHighlight = linkIds.map(function(id) {return d3.select("link-"+id)})
});
然后,接着高亮代码:
function highlighter(ratio) {
return function(node) {
node.linksToHighlight.forEach(function (s) {s.style("stroke-opacity",ratio})
}
}
[select nodes]
.on('mouseenter', highlighter(0.5) )
.on('mouseout', highlighter(1) )
我刚刚使用 d3 实现了一个指令,我想你会找到你正在寻找的例子,你可以在 github https://github.com/amgadfahmi/angular-bubbletree
上查看代码