Używam d3.js i jquery z back-endem PHP (opartym na framework yii), aby utworzyć dynamiczny wykres ukierunkowany na siłę, aby przedstawić aktualny stan hostów i usług w sieci, które monitorują za pomocą Nagios.Aktualizacja D3 Force Directed Graph ajax
Wykres pokazuje root -> hostgroups -> hosts -> services. Stworzyłem funkcję po stronie serwera, aby powrócić obiekt JSON w następującym formacie
{
"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"
}
]
}
Węzły zawierać identyfikator obiektu, który jest używany w linkach i kolorów do wyświetlania stanu węzła (OK = zielony, OSTRZEŻENIE = żółty, itp.) Łącza mają identyfikator obiektu źródłowego i identyfikator obiektu docelowego dla węzłów. Węzły i połączenia mogą zmieniać się nowych gospodarze są dodawane lub usuwane z systemu monitorowania
I mają następujące kod, który ustawia początkową SVG i następnie co 10 sekund
- Pobiera aktualny obiekt JSON
- tworzy mapę powiązań
- Wybiera bieżących węzłów i łączy i wiąże je z danymi JSON
- Wprowadzanie linki są dodawane i usuwane są linki wychodzące
- górę przestarzałe i dodane węzły zmienią kolor wypełnienia i mają etykietka z nazwą dodany
Force rozpoczęła
$ .ajaxSetup ({cache: false}); szerokość = 960, wysokość = 500; węzeł = []; link = []; siła = d3.layout.force() .char (-1000) .linkDistance (1) .size ([szerokość, wysokość]);
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);
Przykładem wyjścia można zobaczyć na Network Visualization
Wszystkie powyższe działa poprawnie z wyjątkiem tego, że za każdym razem kod pętle to przyczynia się do ponownego uruchomienia wizualizacji i węzłów wszystko odrzuceń dopóki nie rozstrzygną. Potrzebuję, aby obecne przedmioty pozostały takie, jakie są, ale do wizualizacji są dodawane nowe węzły i łącza, które można klikać i przeciągać, itp.
Jeśli ktokolwiek może pomóc, będę wdzięczny za wszystko.
tak się dzieje, ponieważ w rzeczywistości przeładowywania danych i przeliczenie każdym razem układ . Zamiast ponownego ładowania nowego JSON za każdym razem, myślę, że powinieneś znaleźć sposób na sprawdzenie zmian po stronie serwera i znaleźć sposób na połączenie ich z aktualizacjami. Na przykład utwórz JSON z tylko nowymi węzłami i łączami i popchnij te obiekty do '.nodes' i' .links' kiedy wywołasz 'force.on (" tick ", function())' – Joum
Naprawdę byłem mając nadzieję na sposób uniknięcia konieczności zajmowania się przekazywaniem bieżących obiektów wizualizacyjnych z powrotem do serwera, ponieważ sprawia, że całe rozwiązanie jest o wiele bardziej złożone. Powodem, dla którego zacząłem patrzeć na d3.js było to, że przekazujesz dane d3 i działa to, co zostało wprowadzone i zakończyło zapisywanie danych, co nie wymaga ręcznego wykonywania tych czynności. Czy nie ma alternatywnych metod? – d9705996
Właściwie ponownie przeczytałem Twój komentarz, a d3.js ** nie ** wykreśla to, co wpisano i usunięto w danych. Oblicza wszystko, co powiesz na podstawie dostarczonych danych. Jeśli chcesz zmienić używane dane, musisz je zmienić samodzielnie. :) – Joum