gpt4 book ai didi

javascript - D3 强制布局颜色和缩放

转载 作者:行者123 更新时间:2023-12-03 01:15:29 25 4
gpt4 key购买 nike

我正在使用以下代码片段,并尝试纠正链接行为的一些错误。

预期行为如下:

  • 默认情况下,链接根据链接的“类型”(“A”或“E”)着色
  • 将鼠标悬停在节点上时,该节点及其直接邻居保持完全不透明度和颜色,但其余节点和链接会降低不透明度,并且链接颜色会变为白色。
  • 鼠标移开时,节点和链接将恢复其原始的不透明度和颜色
  • 缩放时,节点和链接都会相应缩放。

不幸的是,我的代码不满足最后三个要点,并且在此过程中的某个地方,链接现在呈现在节点顶部,而不是相反。

谁能帮我指出我哪里出错了?

Codepen - https://codepen.io/quirkules/pen/BOKRjY

//create somewhere to put the force directed graph
var height = 650,
width = 950;

var svg = d3.select("body").append("svg")
.attr('width',width)
.attr('height',height);

var radius = 15;

var nodes_data = [
{"name": "Lillian", "sex": "F"},
{"name": "Gordon", "sex": "M"},
{"name": "Sylvester", "sex": "M"},
{"name": "Mary", "sex": "F"},
{"name": "Helen", "sex": "F"},
{"name": "Jamie", "sex": "M"},
{"name": "Jessie", "sex": "F"},
{"name": "Ashton", "sex": "M"},
{"name": "Duncan", "sex": "M"},
{"name": "Evette", "sex": "F"},
{"name": "Mauer", "sex": "M"},
{"name": "Fray", "sex": "F"},
{"name": "Duke", "sex": "M"},
{"name": "Baron", "sex": "M"},
{"name": "Infante", "sex": "M"},
{"name": "Percy", "sex": "M"},
{"name": "Cynthia", "sex": "F"},
{"name": "Feyton", "sex": "M"},
{"name": "Lesley", "sex": "F"},
{"name": "Yvette", "sex": "F"},
{"name": "Maria", "sex": "F"},
{"name": "Lexy", "sex": "F"},
{"name": "Peter", "sex": "M"},
{"name": "Ashley", "sex": "F"},
{"name": "Finkler", "sex": "M"},
{"name": "Damo", "sex": "M"},
{"name": "Imogen", "sex": "F"}
]

//Sample links data
//type: A for Ally, E for Enemy
var links_data = [
{"source": "Sylvester", "target": "Gordon", "type":"A" },
{"source": "Sylvester", "target": "Lillian", "type":"A" },
{"source": "Sylvester", "target": "Mary", "type":"A"},
{"source": "Sylvester", "target": "Jamie", "type":"A"},
{"source": "Sylvester", "target": "Jessie", "type":"A"},
{"source": "Sylvester", "target": "Helen", "type":"A"},
{"source": "Helen", "target": "Gordon", "type":"A"},
{"source": "Mary", "target": "Lillian", "type":"A"},
{"source": "Ashton", "target": "Mary", "type":"A"},
{"source": "Duncan", "target": "Jamie", "type":"A"},
{"source": "Gordon", "target": "Jessie", "type":"A"},
{"source": "Sylvester", "target": "Fray", "type":"E"},
{"source": "Fray", "target": "Mauer", "type":"A"},
{"source": "Fray", "target": "Cynthia", "type":"A"},
{"source": "Fray", "target": "Percy", "type":"A"},
{"source": "Percy", "target": "Cynthia", "type":"A"},
{"source": "Infante", "target": "Duke", "type":"A"},
{"source": "Duke", "target": "Gordon", "type":"A"},
{"source": "Duke", "target": "Sylvester", "type":"A"},
{"source": "Baron", "target": "Duke", "type":"A"},
{"source": "Baron", "target": "Sylvester", "type":"E"},
{"source": "Evette", "target": "Sylvester", "type":"E"},
{"source": "Cynthia", "target": "Sylvester", "type":"E"},
{"source": "Cynthia", "target": "Jamie", "type":"E"},
{"source": "Mauer", "target": "Jessie", "type":"E"},
{"source": "Duke", "target": "Lexy", "type":"A"},
{"source": "Feyton", "target": "Lexy", "type":"A"},
{"source": "Maria", "target": "Feyton", "type":"A"},
{"source": "Baron", "target": "Yvette", "type":"E"},
{"source": "Evette", "target": "Maria", "type":"E"},
{"source": "Cynthia", "target": "Yvette", "type":"E"},
{"source": "Maria", "target": "Jamie", "type":"E"},
{"source": "Maria", "target": "Lesley", "type":"E"},
{"source": "Ashley", "target": "Damo", "type":"A"},
{"source": "Damo", "target": "Lexy", "type":"A"},
{"source": "Maria", "target": "Feyton", "type":"A"},
{"source": "Finkler", "target": "Ashley", "type":"E"},
{"source": "Sylvester", "target": "Maria", "type":"E"},
{"source": "Peter", "target": "Finkler", "type":"E"},
{"source": "Ashley", "target": "Gordon", "type":"E"},
{"source": "Maria", "target": "Imogen", "type":"E"}

]


//set up the simulation and add forces
var simulation = d3.forceSimulation()
.nodes(nodes_data);

var link_force = d3.forceLink(links_data)
.id(function(d) { return d.name; });

var charge_force = d3.forceManyBody()
.strength(-100);

var center_force = d3.forceCenter(width / 2, height / 2);

simulation
.force("charge_force", charge_force)
.force("center_force", center_force)
.force("link",link_force)
;


//add tick instructions:
simulation.on("tick", tickActions );

//add encompassing group for the zoom
var g = svg.append("g")
.attr("class", "everything");

//draw circles for the nodes
var node = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes_data)
.enter()
.append("circle")
.attr("r", radius)
.attr("fill", circleColour)
.on("mouseover", mouseOver(.1))
.on("mouseout", mouseOut);

// add the curved links to our graphic
var link = svg.selectAll(".link")
.data(links_data)
.enter()
.append("path")
.attr("class", "link")
.style('stroke', linkColour)
.attr('stroke-width', 2);

//add drag capabilities
var drag_handler = d3.drag()
.on("start", drag_start)
.on("drag", drag_drag)
.on("end", drag_end);

drag_handler(node);


//add zoom capabilities
var zoom_handler = d3.zoom()
.on("zoom", zoom_actions);

zoom_handler(svg);

/** Functions **/

//Function to choose what color circle we have
//Let's return blue for males and red for females
function circleColour(d){
if(d.sex =="M"){
return "blue";
} else {
return "pink";
}
}

//Function to choose the line colour and thickness
//If the link type is "A" return green
//If the link type is "E" return red
function linkColour(d){
if(d.type == "A"){
return "green";
} else {
return "red";
}
}

//Drag functions
//d is the node
function drag_start(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}

//make sure you can't drag the circle outside the box
function drag_drag(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function drag_end(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}

//Zoom functions
function zoom_actions(){
g.attr("transform", d3.event.transform)
}

function tickActions() {
//update circle positions each tick of the simulation
node
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });

//update link positions
link.attr("d", positionLink);
}

// links are drawn as curved paths between nodes,
// through the intermediate nodes
function positionLink(d) {
var offset = 30;

var midpoint_x = (d.source.x + d.target.x) / 2;
var midpoint_y = (d.source.y + d.target.y) / 2;

var dx = (d.target.x - d.source.x);
var dy = (d.target.y - d.source.y);

var normalise = Math.sqrt((dx * dx) + (dy * dy));

var offSetX = midpoint_x + offset * (dy / normalise);
var offSetY = midpoint_y - offset * (dx / normalise);

return "M" + d.source.x + "," + d.source.y +
"S" + offSetX + "," + offSetY +
" " + d.target.x + "," + d.target.y;
}

// links are drawn as curved paths between nodes,
// through the intermediate nodes
function positionLink(d) {
var offset = 30;

var midpoint_x = (d.source.x + d.target.x) / 2;
var midpoint_y = (d.source.y + d.target.y) / 2;

var dx = (d.target.x - d.source.x);
var dy = (d.target.y - d.source.y);

var normalise = Math.sqrt((dx * dx) + (dy * dy));

var offSetX = midpoint_x + offset * (dy / normalise);
var offSetY = midpoint_y - offset * (dx / normalise);

return "M" + d.source.x + "," + d.source.y +
"S" + offSetX + "," + offSetY +
" " + d.target.x + "," + d.target.y;
}

// build a dictionary of nodes that are linked
var linkedByIndex = {};
links_data.forEach(function(d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});

// check the dictionary to see if nodes are linked
function isConnected(a, b) {
return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index] || a.index == b.index;
}

// fade nodes on hover
function mouseOver(opacity) {
return function(d) {
// check all other nodes to see if they're connected
// to this one. if so, keep the opacity at 1, otherwise
// fade
node.style("stroke-opacity", function(o) {
thisOpacity = isConnected(d, o) ? 1 : opacity;
return thisOpacity;
});
node.style("fill-opacity", function(o) {
thisOpacity = isConnected(d, o) ? 1 : opacity;
return thisOpacity;
});
// also style link accordingly
link.style("stroke-opacity", function(o) {
return o.source === d || o.target === d ? 1 : opacity;
});
link.style("stroke", function(o) {
return o.source === d || o.target === d ? o.source.colour : "#ddd";
});
};
}

function mouseOut() {
node.style("stroke-opacity", 1);
node.style("fill-opacity", 1);
link.style("stroke-opacity", 1);
link.style("stroke", "#ddd");
}

最佳答案

看起来您在第 #116 行有一个简单的拼写错误:

// add the curved links to our graphic
var link = svg.selectAll(".link")
.data(links_data)
.enter()
.append("path")
.attr("class", "link")
.style('stroke', linkColour)
.attr('stroke-width', 2);

此代码将所有链接放置在根 <svg> 下元素,而不是组。如果您更改 svg.selectAll(...)g.selectAll(...) ,看起来工作正常。

关于javascript - D3 强制布局颜色和缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52035748/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com