Tôi đang sử dụng d3.js và jquery với một back-end PHP (dựa trên yii framework) để tạo ra một đồ thị động lực đạo để biểu diễn trạng thái hiện tại của máy chủ và dịch vụ trên mạng mà chúng tôi đang theo dõi bằng Nagios.D3 Force Chỉ thị đồ thị ajax cập nhật
Biểu đồ hiển thị gốc -> nhóm máy chủ -> máy chủ -> dịch vụ. Tôi đã tạo ra một chức năng phía máy chủ để trả về một đối tượng JSON theo định dạng sau
{
"nodes": [
{
"name": "MaaS",
"object_id": 0
},
{
"name": "Convergence",
"object_id": "531",
"colour": "#999900"
},
{
"name": "maas-servers",
"object_id": "719",
"colour": "#999900"
},
{
"name": "hrg-cube",
"object_id": "400",
"colour": "#660033"
}
],
"links": [
{
"source": 0,
"target": "531"
},
{
"source": 0,
"target": "719"
},
{
"source": "719",
"target": "400"
}
]
}
Các nút chứa một đối tượng id được sử dụng trong các liên kết và màu sắc để hiển thị trạng thái của nút (OK = màu xanh lá cây, CẢNH BÁO = màu vàng, vv) Các liên kết có id đối tượng nguồn và id đối tượng mục tiêu cho các nút. Các nút và các liên kết có thể thay đổi khi chủ nhà mới được thêm vào hoặc loại bỏ khỏi hệ thống giám sát
Tôi đã đoạn mã sau đó thiết lập các SVG ban đầu và sau đó mỗi 10 giây
- Lấy đối tượng JSON hiện
- tạo bản đồ trong các liên kết
- Chọn nút hiện hành và các liên kết và liên kết chúng với dữ liệu JSON
- liên kết Bước vào được thêm vào và liên kết thoát được loại bỏ
- lên ngày và bổ sung các nút sẽ thay đổi màu sắc lấp đầy của họ và có một tooltip với tên của họ thêm
Force được bắt đầu
$ .ajaxSetup ({cache: false}); chiều rộng = 960, chiều cao = 500; node = []; link = []; force = d3.layout.force() .charge (-1000) .linkDistance (1) .size ([chiều rộng, chiều cao]);
svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g"); setInterval(function(){ $.ajax({ url: "<?php echo $url;?>", type: "post", async: false, datatype: "json", success: function(json, textStatus, XMLHttpRequest) { json = $.parseJSON(json); var nodeMap = {}; json.nodes.forEach(function(x) { nodeMap[x.object_id] = x; }); json.links = json.links.map(function(x) { return { source: nodeMap[x.source], target: nodeMap[x.target], }; }); link = svg.selectAll("line") .data(json.links); node = svg.selectAll("circle") .data(json.nodes,function(d){return d.object_id}) link.enter().append("line").attr("stroke-width",1).attr('stroke','#999'); link.exit().remove(); node.enter().append("circle").attr("r",5); node.exit().remove(); node.attr("fill",function(d){return d.colour}); node.append("title") .text(function(d) { return d.name; }); node.call(force.drag); force .nodes(node.data()) .links(link.data()) .start() force.on("tick", function() { 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 = Math.max(5, Math.min(width - 5, d.x)); }) .attr("cy", function(d) { return d.y = Math.max(5, Math.min(height - 5, d.y)); }); }); } }); },10000);
Một ví dụ về đầu ra có thể được nhìn thấy ở Network Visualization
Tất cả các công trình trên một cách chính xác với ngoại lệ mà mỗi lần mã vòng nó làm cho trực quan để khởi động lại và các nút tất cả các thư bị trả lại cho đến khi họ ổn định. Những gì tôi cần là cho bất kỳ mặt hàng hiện tại nào để ở, nhưng bất kỳ nút và liên kết mới nào được thêm vào hình ảnh và có thể nhấp và có thể kéo, v.v.
Nếu ai có thể giúp tôi biết ơn mãi mãi.
Điều đó xảy ra bởi vì bạn đang thực sự tải lại dữ liệu và tính toán lại các mọi bố trí . Thay vì tải lại một JSON mới mọi lúc, tôi nghĩ bạn nên tìm cách kiểm tra các thay đổi phía máy chủ và tìm cách kết nối chúng với những gì bạn có khi cập nhật. Ví dụ, tạo một JSON chỉ với các nút _new_ và các liên kết và đẩy các đối tượng đó vào '.nodes' và' .links' khi bạn gọi hàm 'force.on (" tick ", function())' – Joum
Tôi đã thực sự hy vọng cho một cách để tránh phải đối phó với đi qua các đối tượng trực quan hiện tại trở lại máy chủ vì nó làm cho toàn bộ giải pháp phức tạp hơn nhiều. Lý do tôi bắt đầu xem d3.js là bạn chuyển d3 dữ liệu và nó làm việc ra những gì đã nhập và thoát khỏi dữ liệu giúp bạn không phải làm điều này bằng tay. Không có phương pháp thay thế nào? – d9705996
Thực ra, tôi đã đọc lại nhận xét của bạn và d3.js ** không ** làm việc ra những gì đã nhập và exited_ trong dữ liệu. Nó tính toán bất cứ điều gì bạn nói với dữ liệu bạn cung cấp. Nếu bạn muốn thay đổi dữ liệu đang được sử dụng, bạn phải tự thay đổi nó. :) – Joum