我試圖創建一個網頁,用戶可以選擇節點(使用select2),並且他們選擇的每個節點都將被添加到網絡中。 我目前無法讓節點出現在左上角以外的SVG上。d3.js v4 - 節點卡在左上角
這是我在bl.ocks.org代碼: https://bl.ocks.org/shaief/2b4d5cfc7dcc0e03c59f0d6be3cc2913
我一直在尋找,看看有什麼其他人一樣,但我無法找到,說明我的問題的答案。
編輯: 在我看來,雖然代碼運行和滴答,在'勾號'功能它不影響節點對象。我不明白爲什麼。
EDIT2: 我創建了一個新文件,它是Mike Bostock修改Force Layout II(https://bl.ocks.org/mbostock/0adcc447925ffae87975a3a81628a196)的複製粘貼並添加了我的select2部分。其結果是一個完整的日誌:
Uncaught TypeError: Cannot create property 'vx' on string 'node-uuid-1234567890-5'
at n (d3.v4.min.js:2)
at d3.v4.min.js:2
at be.each (d3.v4.min.js:2)
at e (d3.v4.min.js:2)
at n (d3.v4.min.js:2)
at vn (d3.v4.min.js:2)
at _n (d3.v4.min.js:2)
這很奇怪,因爲麥克的例子並使用節點ID而不是序號索引和我不明白原因。
EDIT3: 我在這裏添加相關的代碼,因爲我用完全不同的代碼更新了我的要點。
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
</head>
<style>
.container {
margin-top: 10px;
display: flex;
}
.controls {
/* padding: 10px; */
width: 350px;
}
#select-node-names {
width: 100%;
}
.d3-container {
flex-grow: 1;
}
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
/* stroke-width: 1.5px; */
stroke-width: 0px;
}
text {
font: 10px sans-serif;
color: red;
pointer-events: none;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}
</style>
<div class='row'>
<select id="select-node-names" multiple="multiple">
</select>
<div class="container">
<div class="controls">
<div class="test-nodes"></div>
</div>
<div class="d3-container">
<svg width="960" height="600"></svg>
</div>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
d3.json("test.json", function(error, graph) {
if (error) throw error;
$("#select-node-names")
.select2();
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
// Color scale for node colors
var color = d3.scaleOrdinal(d3.schemeCategory10);
// Color scale for link colors
var linkColor = d3.scaleOrdinal(d3.schemeCategory10);
var simulation = d3.forceSimulation(graph.nodes)
.force("charge", d3.forceManyBody()
.strength(function(d) {
return d.degree;
}))
.force('x', d3.forceX())
.force('y', d3.forceY())
.force("collision", d3.forceCollide(20))
.force("centering", d3.forceCenter(width/2, height/2))
.force("link", d3.forceLink()
.id(function(d) {
return d.id
}))
.on("tick", ticked);
var nodes = [];
var links = [];
var nodeNames = Object.values(graph.nodes);
var listItem = d3.select("#select-node-names")
.selectAll("option")
.data(nodeNames)
.enter()
.append("option")
.text(function(d) {
return d.object_name;
})
.attr("id", function(d) {
return d.id;
})
.attr("value", function(d) {
return d.id;
});
linksID = [];
graph.links.forEach(function(e) {
var sourceNode = graph.nodes[e.source]["id"];
var targetNode = graph.nodes[e.target]["id"];
linksID.push({
source: sourceNode,
target: targetNode,
value: e.type
});
});
$(document.body)
.on("change", "#select-node-names", function() {
nodes = search($("#select-node-names")
.val(), "id", graph.nodes);
nodesID = nodes.map(function(d) {
return d.id;
});
linksSource = search(nodesID, "source", linksID);
linksTarget = search(nodesID, "target", linksID);
links = [];
links = links.concat(linksSource, linksTarget);
update();
});
var nodesG = svg.append("g");
var linksG = svg.append("g");
var node = nodesG
.selectAll(".nodes")
var link = linksG
.selectAll(".links")
update()
function update() {
var showSelectedNodes = d3.select(".test-nodes")
.html("");
var showSelectedNodes = d3.select(".test-nodes")
.selectAll("myText")
.data(nodes);
showSelectedNodes.exit()
.remove(); // EXIT
showSelectedNodes.enter()
.append("small") // ENTER
.text(function(d) {
return d.object_name + " // ";
})
.merge(showSelectedNodes) // ENTER + UPDATE
var node = nodesG
.selectAll("circle")
.data(nodes);
exitNode = node.exit()
.remove(); // EXIT
node = node.enter()
.append("circle") // ENTER
.attr("class", "nodes")
.attr("r", 10)
.attr("fill", function(d) {
return color(d.node_type);
})
.append("title")
.text(function(d) {
return "Node: " + d.id + "\nName: " + d.object_name +
"\nCoordinates: " + d.x + " - " + d.y;
})
.append("text")
.attr("dx", 8)
.attr("dy", ".31em")
.text(function(d) {
return d.object_name;
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.merge(node) // ENTER + UPDATE
link = link.enter()
.data(links)
.append("line")
.style('stroke', function(d) {
return linkColor(d.type);
})
.attr("stroke-width", 2)
.append("title")
.text(function(d) {
return "Source: " + d.source + "\nTarget: " + d.target +
"\nType: " + d.type;
});
// Update and restart the simulation.
simulation.nodes(nodes);
simulation.force("link", d3.forceLink()
.id(function(d) {
return d.id
}));
simulation.alphaTarget(1);
simulation.restart();
}
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("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
/* node.attr("transform", transform);*/
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3)
.restart();
d.fx = null;
d.fy = null;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
};
});
function search(valuesArray, prop, myArray) {
var res = [];
for (var i = 0; i < valuesArray.length; i++) {
for (var j = 0; j < myArray.length; j++) {
if (myArray[j][prop] == valuesArray[i]) {
res.push(myArray[j]);
break;
}
}
}
return res
}
</script>
謝謝!只是爲了澄清,這是一個模擬的JSON,但它有源碼和目標碼,因爲它正在通過Python的NetworkX。 –
好的。所以在我看來,我在我的代碼中跟隨links.id API - 我通過使用它們的ID而不是索引來引用節點的每個鏈接。當我將它改變爲默認行爲時,我得到這個:'''未捕獲的TypeError:無法在字符串'node-uuid-1234567890-2'上創建屬性'vx' ''' –
如果您使用字符串ID,則需要指定這樣的鏈接力:var simulation = d3.forceSimulation() .force(「link」,d3.forceLink().id(function(d){return d.id;})),這樣你的json鏈接是:{source:「node-uuid-1234567890-1」target:「node-uuid-1234567890-2」value:1}。vx是速度x的位置,它的基本意思是說,我無法弄清楚創建這個屬性來移動你的節點/鏈接 – Robatron