Отрисовка графов

166
24 января 2020, 06:40

Хочу задать параметры для графа в на web-странице, обработать их и отрисовать граф, за тем сформировать массив с данными(какая вершина с какой соединена и параметры например длинна соединительной линии) и перегнать например массив в текстовый файл и отправить в программу на с++ (уже написана) какой инструмент(библиотека) лучше всего подходит именно для отрисовки графа? P.S. с JS не особо знаком

Answer 1

Есть удачная во всех отношениях библиотека d3.js, в ней есть так называемый force layout, вот я собрал простенький пример использования.

Граф нарисован при помощи svg элементов <circle> и <line>, цвет круга зависит от группы узла, цвет и штриховка линий зависят от значения "силы" связи между узлами

UPD: подкрутил алгоритм генерации рандомного графа

let graph = { 
  groups: Array(11).fill(0).map(() => rnd(10)).map((d,i) => Array(11).fill(0).map(()=>({ 
    id: Math.random().toString(36).substring(2),  
    group: i 
  }))), 
  links: [] 
}; 
 
graph.nodes = graph.groups.reduce((acc, arr) => acc.concat(arr), []); 
 
graph.superNode = graph.nodes[rnd(graph.nodes.length)].id; 
 
graph.groups.forEach(nodes => { 
 
  nodes.forEach(n => { 
   
    for (var i=0;i<3;i++) { 
      let n2 = nodes[rnd(nodes.length)]; 
      graph.links.push({ 
        source: n.id,  
        target: n2.id,  
        value: rnd(10) 
      }); 
      checkLastLink(n, n2); 
    } 
     
  }); 
 
  for (var i=0;i<2;i++){ 
    let node = nodes[rnd(nodes.length)]; 
    let node2 =  graph.groups[rnd(graph.groups.length)][0]; 
    graph.links.push({ 
      source: node.id,  
      target:node2.id,  
      value: rnd(2) 
    }); 
    checkLastLink(node, node2); 
  } 
   
 
}) 
 
 
function checkLastLink(src, target) { 
  if (!src.highlight) { 
    src.highlight = target.id === graph.superNode; 
  } 
   
  if (!target.highlight) { 
    target.highlight = src.id === graph.superNode; 
  } 
} 
 
console.log(graph) 
 
// код выше нужен чтобы сгененрировать данные  
 
var svg = d3.select("svg"), 
    width = +svg.attr("width"), 
    height = +svg.attr("height"); 
 
var color = d3.scaleOrdinal(d3.schemeCategory10); 
 
var simulation = d3.forceSimulation() 
    .force("link", d3.forceLink().id(d => d.id)) 
    .force("charge", d3.forceManyBody().strength(-4)) 
    .force("center", d3.forceCenter(width / 2, height / 2)); 
 
var link = svg.append("g") 
    .selectAll("line") 
    .data(graph.links) 
    .enter() 
    .append("line") 
    .attr("stroke", 'red') 
    .attr("stroke-dasharray", d => (1+d.value*2) + ' ' + 3); 
 
var node = svg.append("g") 
    .selectAll("circle") 
    .data(graph.nodes) 
    .enter() 
      .append("circle") 
      .attr("r", d => d.id===graph.superNode ? 15: d.highlight?6:3) 
      .attr("fill", d => color(d.group)) 
      .attr("stroke", 'black') 
      .call(d3.drag() 
          .on("start", dragstarted) 
          .on("drag", dragged) 
          .on("end", dragended)); 
 
  simulation.nodes(graph.nodes) 
      .on("tick", ticked); 
 
  simulation.force("link") 
      .links(graph.links); 
 
function ticked() { 
  link.attr("x1", d => d.source.x) 
      .attr("y1", d => d.source.y) 
      .attr("x2", d => d.target.x) 
      .attr("y2", d => d.target.y); 
 
  node.attr("cx", d => d.x) 
      .attr("cy", d => d.y); 
} 
 
function dragstarted(d) { 
  if (!d3.event.active)  
    simulation.alphaTarget(1).restart(); 
  d.fx = d.x; 
  d.fy = d.y; 
} 
 
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 rnd(base){ 
  return Math.floor(Math.random() * base); 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> 
<svg width="700" height="500"></svg>

READ ALSO
htaccess rewrite rule

htaccess rewrite rule

Не получается сделать ЧПУСуть: Можно ли заменить такой УРЛ:

147
DropzoneJS, PHP, Ошибка 500 (Internal Server Error), при загрузке файлов

DropzoneJS, PHP, Ошибка 500 (Internal Server Error), при загрузке файлов

В консоли браузера выводиться ошибка 500 после загрузке файла:

172
Ошибка при компиляции заголовка в MCVS 2017 [закрыт]

Ошибка при компиляции заголовка в MCVS 2017 [закрыт]

Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском»

150
C++ Третий массив минимально возможного размера, в котором нужно собрать элементы массива A, которые не включаются в массив B

C++ Третий массив минимально возможного размера, в котором нужно собрать элементы массива A, которые не включаются в массив B

Необходимо создать третий массив минимально возможного размера, в котором нужно собрать элементы массива A, которые не включаются в массив...

150