问题描述
我已经尝试过许多解决此问题的方法,但是我不知道该怎么做...
I've tried many solutions given around this problem, but i can not figure how to do that...
我的目标是在鼠标悬停该节点时更改链接到该节点的链接的颜色和.
My goal is to change the color of links and arrows connected to a node when this node is hovered by mouse.
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
.node { font: 12px sans-serif;}
.link { stroke: black; stroke-opacity: .4; stroke-width: 2px; }
</style>
</head>
<body>
<svg width="1500" height="1000"></svg>
<script src="http://d3js.org/d3.v4.min.js" type="text/javascript"></script>
<script src="http://d3js.org/d3-selection-multi.v1.js"></script>
<script type="text/javascript">
var colors = d3.scaleOrdinal(d3.schemeCategory20);
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
node,
link;
svg.append('defs').append('marker')
.attrs({'id':'arrowhead',
'viewBox':'-0 -5 10 10',
'refX':15,
'refY':0,
'orient':'auto',
'markerWidth':6,
'markerHeight':6,
'xoverflow':'visible'})
.append('svg:path')
.attr('d', 'M 0,-5 L 10 ,0 L 0,5')
.style('fill', 'black')
.style('stroke', 'black');
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function (d) {return d.id;}).distance(500).strength(1))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
var jsonstring = '{"nodes": [{"name": "25", "id": "25"},{"name": "16", "id": "16"},{"name": "12", "id": "12"},{"name": "20", "id": "20"},{"name": "21", "id": "21"},{"name": "9", "id": "9"},{"name": "24", "id": "24"},{"name": "5", "id": "5"},{"name": "23", "id": "23"},{"name": "13", "id": "13"},{"name": "14", "id": "14"},{"name": "15", "id": "15"},{"name": "18", "id": "18"},{"name": "2", "id": "2"},{"name": "3", "id": "3"},{"name": "4", "id": "4"},{"name": "6", "id": "6"},{"name": "7", "id": "7"},{"name": "10", "id": "10"},{"name": "11", "id": "11"},{"name": "1", "id": "1"},{"name": "22", "id": "22"},{"name": "17", "id": "17"},{"name": "19", "id": "19"},{"name": "8", "id": "8"}],"links": [{"source": "25", "target": "16"},{"source": "25", "target": "12"},{"source": "25", "target": "20"},{"source": "25", "target": "21"},{"source": "25", "target": "9"},{"source": "25", "target": "24"},{"source": "25", "target": "12"},{"source": "16", "target": "16"},{"source": "16", "target": "12"},{"source": "16", "target": "12"},{"source": "12", "target": "16"},{"source": "12", "target": "12"},{"source": "12", "target": "5"},{"source": "12", "target": "12"},{"source": "20", "target": "16"},{"source": "20", "target": "12"},{"source": "20", "target": "23"},{"source": "20", "target": "13"},{"source": "20", "target": "14"},{"source": "20", "target": "5"},{"source": "20", "target": "15"},{"source": "20", "target": "12"},{"source": "21", "target": "16"},{"source": "21", "target": "12"},{"source": "21", "target": "15"},{"source": "21", "target": "13"},{"source": "21", "target": "18"},{"source": "21", "target": "2"},{"source": "21", "target": "12"},{"source": "9", "target": "16"},{"source": "9", "target": "12"},{"source": "9", "target": "23"},{"source": "9", "target": "21"},{"source": "9", "target": "13"},{"source": "9", "target": "3"},{"source": "9", "target": "12"},{"source": "24", "target": "16"},{"source": "24", "target": "12"},{"source": "24", "target": "23"},{"source": "24", "target": "18"},{"source": "24", "target": "4"},{"source": "24", "target": "6"},{"source": "24", "target": "7"},{"source": "24", "target": "12"},{"source": "5", "target": "16"},{"source": "5", "target": "12"},{"source": "5", "target": "12"},{"source": "5", "target": "4"},{"source": "5", "target": "15"},{"source": "5", "target": "10"},{"source": "5", "target": "12"},{"source": "23", "target": "16"},{"source": "23", "target": "12"},{"source": "23", "target": "6"},{"source": "23", "target": "10"},{"source": "23", "target": "12"},{"source": "13", "target": "16"},{"source": "13", "target": "12"},{"source": "13", "target": "20"},{"source": "13", "target": "10"},{"source": "13", "target": "14"},{"source": "13", "target": "5"},{"source": "13", "target": "11"},{"source": "13", "target": "1"},{"source": "13", "target": "16"},{"source": "13", "target": "12"},{"source": "14", "target": "16"},{"source": "14", "target": "12"},{"source": "14", "target": "2"},{"source": "14", "target": "13"},{"source": "14", "target": "4"},{"source": "14", "target": "5"},{"source": "14", "target": "12"},{"source": "15", "target": "16"},{"source": "15", "target": "12"},{"source": "15", "target": "6"},{"source": "15", "target": "10"},{"source": "15", "target": "22"},{"source": "15", "target": "20"},{"source": "15", "target": "12"},{"source": "18", "target": "16"},{"source": "18", "target": "12"},{"source": "18", "target": "2"},{"source": "18", "target": "12"},{"source": "2", "target": "16"},{"source": "2", "target": "12"},{"source": "2", "target": "13"},{"source": "2", "target": "17"},{"source": "2", "target": "12"},{"source": "2", "target": "11"},{"source": "2", "target": "12"},{"source": "3", "target": "16"},{"source": "3", "target": "12"},{"source": "3", "target": "16"},{"source": "3", "target": "18"},{"source": "3", "target": "10"},{"source": "3", "target": "12"},{"source": "4", "target": "16"},{"source": "4", "target": "12"},{"source": "4", "target": "14"},{"source": "4", "target": "5"},{"source": "4", "target": "13"},{"source": "4", "target": "10"},{"source": "4", "target": "12"},{"source": "4", "target": "12"},{"source": "6", "target": "16"},{"source": "6", "target": "12"},{"source": "6", "target": "20"},{"source": "6", "target": "13"},{"source": "6", "target": "3"},{"source": "6", "target": "19"},{"source": "6", "target": "12"},{"source": "7", "target": "16"},{"source": "7", "target": "12"},{"source": "7", "target": "20"},{"source": "7", "target": "21"},{"source": "7", "target": "12"},{"source": "7", "target": "8"},{"source": "7", "target": "9"},{"source": "7", "target": "11"},{"source": "7", "target": "12"},{"source": "10", "target": "16"},{"source": "10", "target": "12"},{"source": "10", "target": "1"},{"source": "10", "target": "5"},{"source": "10", "target": "17"},{"source": "10", "target": "22"},{"source": "10", "target": "16"},{"source": "10", "target": "4"},{"source": "10", "target": "13"},{"source": "10", "target": "12"},{"source": "11", "target": "16"},{"source": "11", "target": "12"},{"source": "11", "target": "7"},{"source": "11", "target": "3"},{"source": "11", "target": "12"},{"source": "11", "target": "22"},{"source": "11", "target": "12"},{"source": "1", "target": "16"},{"source": "1", "target": "12"},{"source": "1", "target": "16"},{"source": "1", "target": "22"},{"source": "1", "target": "9"},{"source": "1", "target": "15"},{"source": "1", "target": "12"},{"source": "22", "target": "16"},{"source": "22", "target": "12"},{"source": "22", "target": "5"},{"source": "22", "target": "2"},{"source": "22", "target": "17"},{"source": "22", "target": "12"},{"source": "22", "target": "8"},{"source": "22", "target": "12"},{"source": "19", "target": "16"},{"source": "19", "target": "12"},{"source": "19", "target": "24"},{"source": "19", "target": "15"},{"source": "19", "target": "16"},{"source": "19", "target": "23"},{"source": "19", "target": "12"},{"source": "8", "target": "16"},{"source": "8", "target": "12"},{"source": "8", "target": "20"},{"source": "8", "target": "15"},{"source": "8", "target": "12"},{"source": "8", "target": "12"}]}';
var graph=JSON.parse(jsonstring);
//d3.json("graph.json", function (error, graph) {
//if (error) throw error;
update(graph.links, graph.nodes);
//})
function update(links, nodes) {
link = svg.selectAll(".link")
.data(links)
.enter()
.append("line")
.attr("class", "link")
.attr('marker-end','url(#arrowhead)')
link.append("title")
.text(function (d) {return d.type;});
edgepaths = svg.selectAll(".edgepath")
.data(links)
.enter()
.append('path')
.attrs({
'class': 'edgepath',
'fill-opacity': 0,
'stroke-opacity': 0,
'id': function (d, i) {return 'edgepath' + i}
})
.style("pointer-events", "none");
edgelabels = svg.selectAll(".edgelabel")
.data(links)
.enter()
.append('text')
.style("pointer-events", "none")
.attrs({
'class': 'edgelabel',
'id': function (d, i) {return 'edgelabel' + i},
'font-size': 10,
'fill': '#aaa'
});
edgelabels.append('textPath')
.attr('xlink:href', function (d, i) {return '#edgepath' + i})
.style("text-anchor", "middle")
.style("pointer-events", "none")
.attr("startOffset", "50%")
.text(function (d) {return d.type});
node = svg.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
//.on("end", dragended)
);
node.append("circle")
.attr("r", 8)
.style("fill", function (d, i) {return colors(i);})
node.append("title")
.text(function (d) {return d.id;});
node.append("text")
.attr("dy", -4)
.attr("dx", 10)
.text(function (d) {return d.name;});
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
}
function ticked() {
link
.attr("x1", function (d) {return d.source.x;})
.attr("y1", function (d) {return d.source.y;})
.attr("x2", function (d) {return d.target.x;})
.attr("y2", function (d) {return d.target.y;});
node
.attr("transform", function (d) {return "translate(" + d.x + ", " + d.y + ")";});
edgepaths.attr('d', function (d) {
return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y;
});
edgelabels.attr('transform', function (d) {
if (d.target.x < d.source.x) {
var bbox = this.getBBox();
rx = bbox.x + bbox.width / 2;
ry = bbox.y + bbox.height / 2;
return 'rotate(180 ' + rx + ' ' + ry + ')';
}
else {
return 'rotate(0)';
}
});
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart()
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
// On node hover, examine the links to see if their
// source or target properties match the hovered node.
node.on('mouseover', function(d) {
link.style('stroke', function(l) {
if (d === l.source || d === l.target)
return "red";
else
return "black";
});
});
// Set the stroke width back to normal when mouse leaves the node.
node.on('mouseout', function() {
link.style('stroke', "black");
});
// function dragended(d) {
// if (!d3.event.active) simulation.alphaTarget(0);
// d.fx = undefined;
// d.fy = undefined;
// }
</script>
</body>
</html>
就目前而言,我实现了更改链接颜色的功能,但我也无法弄清楚如何更改箭头.我注意到更改悬停时的 stroke-width 会影响链接和箭头,但是更改任何其他属性(fill,stroke ...)只会影响链接.
For now, I achieved to change links color, but i can't figure out how to change arrows too. I noticed changing stroke-width on hover affects both links and arrows, but changing any other property (fill, stroke...) only affects links.
也许答案很明显,但是我在JS中是一个新手.有什么帮助吗?
Maybe the answer is obvious, but I'm quite new in JS.Any help ?
推荐答案
在mouseover
回调中选择标记,并更改其样式.另外,命名您的选择也是个好主意.
Select the marker in the mouseover
callback and change its style as well. Also, it's a good idea naming your selections.
这是一个非常基本的演示,请注意,在mouseover
事件(以及在mouseout
中),我同时更改了路径和标记样式:
Here is a very basic demo, notice that on the mouseover
event (and in the mouseout
as well) I'm changing both the path and the marker styles:
var svg = d3.select("svg");
var defs = svg.append("defs");
var marker = defs.append("marker")
.attr("id", "marker")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 0)
.attr("refY", 0)
.attr("markerWidth", 30)
.attr("markerHeight", 30)
.attr("orient", "auto")
.attr("markerUnits", "userSpaceOnUse")
.append("path")
.attr("d", "M0,-5L10,0L0,5")
.style("fill", "firebrick");
var path = svg.append("path")
.attr("d", "M50,50 L250,50")
.style("stroke", "firebrick")
.style("stroke-width", "8px")
.attr("marker-end", "url(#marker)");
path.on("mouseover", function() {
d3.select(this).style("stroke", "blue");
marker.style("fill", "blue");
}).on("mouseout", function() {
d3.select(this).style("stroke", "firebrick")
marker.style("fill", "firebrick");
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
这篇关于鼠标悬停时更改链接和箭头颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!