背景關系:我有這個管理設備的 Django 服務器,我想顯示這些設備之間的通信圖,我決定為此使用 D3 強制圖,Django 服務器將通過 Redis 發送一個帶有 websocket 的 json,我想要客戶端讀取 json 并列印圖形。
到目前為止,我已經能夠列印靜態圖,但我無法實時更新它。
有用的鏈接:
- 本示例的核心代碼。
- 試圖遵循This,但我認為這不是正確的方向。
目標:使用 websocket 實時更新力圖。
我的 JS 代碼:
var graph = {
"nodes": [
{"id": "Agent_1", "group": 1},
{"id": "Agent_2", "group": 2},
{"id": "Agent_3", "group": 1},
{"id": "Agent_4", "group": 3}
],
"links": []
};
const comSocket = new WebSocket(
'ws://'
window.location.host
'/ws/com/'
);
comSocket.onmessage = function (e) {
graph = JSON.parse(e.data).message;
console.log(graph);
simulation.nodes(graph.nodes);
simulation.force("link").links(graph.links);
simulation.alpha(1).restart();
};
var svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height");
var color = d3.scaleOrdinal(d3.schemeCategory20);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody().strength(-2500))
.force("center", d3.forceCenter(width / 2, height / 2));
var link = svg.append("g").attr("class", "links").selectAll("line")
.data(graph.links).enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("g")
.data(graph.nodes)
.enter().append("g")
var circles = node.append("circle")
.attr("r", 20)
.attr("fill", function(d) { return color(d.group); });
var lables = node.append("text").text(function(d) {return d.id;}).attr('x', 16).attr('y', 13);
node.append("title").text(function(d) { return d.id; });
simulation.nodes(graph.nodes).on("tick", ticked);
simulation.force("link").links(graph.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 ")";
})
};
使用上面的代碼會產生這個錯誤:
Uncaught TypeError: Cannot read properties of undefined (reading 'length')
在線:
simulation.nodes(graph.nodes);
在 onmessage()
資料值是一個與 var graph(第 1 行)具有相同結構的 json。所以我不知道為什么它可以正確初始化圖形但不能用相同的值重繪 ..:
{'nodes': [{'id': 'Agent_0', 'group': 1}, {'id': 'Agent_1', 'group': 2}, {'id': 'Agent_2', 'group': 1}, {'id': 'Agent_3', 'group': 3}], 'links': [{'source': 'Agent_0', 'target': 'Agent_2', 'value': 1}, {'source': 'Agent_0', 'target': 'Agent_1', 'value': 3}, {'source': 'Agent_0', 'target': 'Agent_3', 'value': 5}, {'source': 'Agent_1', 'target': 'Agent_3', 'value': 3}, {'source': 'Agent_2', 'target': 'Agent_3', 'value': 5}, {'source': 'Agent_1', 'target': 'Agent_2', 'value': 5}]}
uj5u.com熱心網友回復:
這是服務器端問題,發送了錯誤的型別。
最后,我還將代碼更新為最新版本(只需要更新顏色)。這是最終的作業版本:
var graph = {
"nodes": [
{"id": "Agent_0", "group": 1},
{"id": "Agent_1", "group": 2},
{"id": "Agent_2", "group": 1},
{"id": "Agent_3", "group": 3}
],
"links": []
};
var svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height");
var color = d3.schemeCategory10;
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody().strength(-2500))
.force("center", d3.forceCenter(width / 2, height / 2));
var link = svg.append("g").attr("class", "links").selectAll("line").data(graph.links).enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.append("g").attr("class", "nodes").selectAll("g").data(graph.nodes).enter().append("g")
var circles = node.append("circle").attr("r", 20).attr("fill", function(d) { return color[d.group]; });
var lables = node.append("text").text(function(d) {return d.id;}).attr('x', 16).attr('y', 13);
node.append("title").text(function(d) { return d.id; });
simulation.nodes(graph.nodes).on("tick", ticked);
simulation.force("link").links(graph.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 ")";
})
};
const comSocket = new WebSocket(
'ws://'
window.location.host
'/ws/com/'
);
comSocket.onmessage = function (e) {
graph = JSON.parse(e.data).message;
console.log(graph);
console.log(typeof graph);
svg.selectAll("*").remove();
link = svg.append("g").attr("class", "links").selectAll("line").data(graph.links).enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.value); });
node = svg.append("g").attr("class", "nodes").selectAll("g").data(graph.nodes).enter().append("g")
circles = node.append("circle").attr("r", 20).attr("fill", function(d) { return color[d.group]; });
lables = node.append("text").text(function(d) {return d.id;}).attr('x', 16).attr('y', 13);
node.append("title").text(function(d) { return d.id; });
simulation.nodes(graph.nodes).on("tick", ticked);
simulation.force("link").links(graph.links);
simulation.alpha(1).restart();
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/491661.html
標籤:javascript d3.js 网络套接字
下一篇:D3.js樹形圖錯誤的矩形大小
