Я использую d3.js и jquery с фреймворком PHP (на основе структуры yii), чтобы создать диаграмму динамической силы, предназначенную для представления текущего состояния хостов и служб в сети, которые мы контролируем с помощью Nagios.
На графике показаны команды root → hostgroups → hosts → . Я создал функцию на стороне сервера, чтобы вернуть объект JSON в следующем формате
{
"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"
}
]
}
Узлы содержат идентификатор объекта, который используется в ссылках и цвете для отображения состояния node (OK = зеленый, WARNING = желтый и т.д.). Ссылки имеют идентификаторы исходного объекта и идентификаторы целевого объекта для узлы. Узлы и ссылки могут меняться по мере добавления или удаления новых узлов из системы мониторинга.
У меня есть следующий код, который устанавливает исходный SVG, а затем каждые 10 секунд
- Извлекает текущий объект JSON
- Создает карту ссылок
- Выбирает текущие узлы и ссылки и связывает их с данными JSON.
- Ввод ссылок добавлен и удаляются ссылки.
- обновленные и добавленные узлы изменят свой цвет заливки и всплывающая подсказка с добавленным именем.
-
Сила запущена
$. ajaxSetup ({cache: false}); width = 960, высота = 500; node= []; link = []; force = d3.layout.force() .charge(-1000) .linkDistance(1) .size([ширина, высота]);
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);
Пример вывода можно увидеть в Сетевая визуализация
Все вышеизложенное работает правильно, за исключением того, что каждый раз, когда петли кода заставляют визуализацию перезапускаться, а все узлы откатываются до тех пор, пока они не опустится. Мне нужно, чтобы все текущие элементы оставались такими, какими они есть, но все новые узлы и ссылки добавляются к визуализации и доступны для просмотра и перетаскивания и т.д.
Если кто-то может помочь, я буду вечно благодарен.