グラフsvgの上にマウスを置いて上下にスクロールさせたときに、力向グラフを拡大したいと思います。私は本当にこれを行う方法がわかりません。私はsvgを選択して、擬似ズームのようなsvgのサイズを増減することができましたが、私が探しているものではないsvgのサイズと位置が変わります。 svgをスクロールすると、ノードとリンクを選択してサイズを大きくするにはどうすればよいですか?ズームを追加する方法のおかげ力のグラフをd3で拡大するにはどうすればいいですか?
var svg = d3.select("svg")
,
width = +svg.attr("width"),
height = +svg.attr("height");
var color = d3.scaleOrdinal(d3.schemeCategory20);
var forceParameter = 30
maxDistanceParameter = 100;
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().distance(forceParameter).strength(.5))
.force("charge", d3.forceManyBody().distanceMax(maxDistanceParameter))
.force("center", d3.forceCenter(width/2, height/2));
var linkMap = d3.map();
d3.json("courses.json", function(error, graph) {
if (error) throw error;
var nodes = graph.nodes,
nodeById = d3.map(nodes, function(d) { return d.id; }),
links = graph.links,
bilinks = [];
links.forEach(function(link) {
var s = link.source = nodeById.get(link.source),
t = link.target = nodeById.get(link.target),
i = {}; // intermediate node
nodes.push(i);
links.push({source: s, target: i}, {source: i, target: t});
bilinks.push([s, i, t]);
});
//Populate the map that keeps track of how many links a class node has
links.forEach(function(d){
if(linkMap.has(d.source.id))
linkMap.set(d.source.id, linkMap.get(d.source.id) + .5);
else
linkMap.set(d.source.id, .5);
});
var link = svg.selectAll(".link")
.data(bilinks)
.enter().append("path")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(nodes.filter(function(d) { return d.id; }))
.enter().append("circle")
.attr("class", "node")
//Size the node differently if the node represents a department
.attr("r", function(d){
return (d.group === "Department") ? 15 : (5 * linkMap.get(d.id));
})
//Color the node differently if the node represents a department
.attr("fill", function(d) {
return (d.group === "Department") ? "#3B4656" : color(d.group);
})
//Color the node outline differently if the node represents a department
.style("stroke", function(d){
return (d.group === "Department") ? "black" : "white";
})
//When a node is clicked, all nodes that are more than 1 link away are faded out
.on("click", function(d){
d3.event.stopPropagation();
onNodeClick(this, d, links);
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
//Unfade all nodes when whitespace is clicked
svg.on("click", function(){
d3.selectAll(".node")
.attr("opacity", "1");
});
//Force parameter buttons
d3.select("#forcesPlus")
.on("click", function(){
updateParameters(1);
});
d3.select("#forcesMinus")
.on("click", function(){
updateParameters(-1);
});
node.append("title")
.text(function(d) { return d.id; });
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
function ticked() {
link.attr("d", positionLink);
node.attr("transform", positionNode);
}
/** Updates the force parameters of the graph
*
* @param sign - Determines if we are increasing or decreasing the parameters
*/
function updateParameters(sign){
//Increase the passive jiggle of the nodes so that they visually update (expand/contract)
//when the parameter gets changed
simulation.alphaTarget(.1);
forceParameter += sign * 20;
maxDistanceParameter += sign * 20; //Need to update the max distance so that the
//links can actually get longer
simulation.nodes(nodes);
simulation.force("link", d3.forceLink().distance(forceParameter))
.force("charge", d3.forceManyBody().distanceMax(maxDistanceParameter));
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
//Hack so that the buttons don't break when the nodes settle down to a stand-still.
//Not sure why the buttons don't update once they are still, but this solves it.
//Need the nodes to move in order to see the change in force parameter.
setTimeout(function(){
simulation.alphaTarget(.01);
}, 2000);
}
});
//Fades out any nodes that are not connected to the clicked node
function onNodeClick(click, selectedNode, linkList){
var linkedNodes = d3.set();
linkList.forEach(function(v){
//If the node clicked is the link's source, add the link's target
if (selectedNode.id === v.source.id){
linkedNodes.add(v.target.id);
}
//If the node clicked is the link's target, add the link's source
else if (selectedNode.id === v.target.id){
linkedNodes.add(v.source.id);
}
});
d3.selectAll(".node")
.attr("opacity", function(d){
if (linkedNodes.has(d.id))
return "1";
else
return "0.1";
});
d3.select(click)
.attr("opacity", "1");
}
function positionLink(d) {
return "M" + d[0].x + "," + d[0].y
+ "S" + d[1].x + "," + d[1].y
+ " " + d[2].x + "," + d[2].y;
}
function positionNode(d) {
return "translate(" + d.x + "," + d.y + ")";
}
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;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(.01);
d.fx = null, d.fy = null;
}
function linkDistance(d){
console.log(d);
}
は明確な説明のためにありがとうございました!よく働く。 – awoh