D3.Graf skierowany siłą js, zmniejsz przekroje krawędzi, sprawiając, że krawędzie odpychają się nawzajem

Więc Mam już stronę, która rysuje wykres skierowany siłą, jak ten pokazany Tutaj .

I to działa dobrze. Używam JS z tutaj , z kilkoma poprawkami, aby rozłożyć węzły nieco ładniej.

Są to mniej więcej jedyne różnice:

d3.json("force.json", function(json) {
  var force = d3.layout.force()
      .gravity(0.1)
      .charge(-2000)
      .linkDistance(1)
      .linkStrength(0.1)
      .nodes(json.nodes)
      .links(json.links)
      .size([w, h])
      .start();

Gdzie redukcja siły ogniwa wydaje się bardziej przypominać sprężyny, więc staje się podobna do często stosowanej techniki Fruchterman & Reingold . Działa to w miarę dobrze, ale tylko dla dość małych Wykresów. Przy większych wykresach liczba przejść po prostu rośnie - jak można się spodziewać, ale rozwiązanie, na którym ląduje, jest zwykle dalekie od optymalnego. Nie szukam metody, aby uzyskać optymalne rozwiązanie, wiem, że to bardzo trudne. Chciałbym tylko, aby miał jakiś prymitywny dodatek, który próbuje zmusić linie od siebie, jak również węzły.

Czy istnieje sposób na dodanie odpychania między łączami, a także między węzłami? nie znam się na sposób działania siły D3 i nie mogę znaleźć niczego, co mówi, że jest to możliwe...

Author: VividD, 2012-08-17

4 answers

Niestety, odpowiedź na twoje pytanie nie istnieje.

W D3 nie ma wbudowanego mechanizmu, który odpycha krawędzie lub minimalizuje przekroje krawędzi. Można by pomyśleć, że nie będzie tak trudno wdrożyć szarżę na krawędzi, ale oto jesteśmy.

Poza tym nie istnieje żaden mechanizm w żadnym miejscu, który redukuje przekroczenia krawędzi w ogóle. Przejrzałem dziesiątki bibliotek wizualizacji i algorytmów układu i żaden z nich nie zajmuje się redukcją przekroje krawędziowe na ogólnym, nieskierowanym wykresie.

Istnieje wiele algorytmów, które dobrze sprawdzają się w przypadku wykresów planarnych, dwupoziomowych lub innych uproszczeń. dagre działa dobrze w teorii dla 2-poziomowych grafów, chociaż całkowity brak dokumentacji sprawia, że prawie niemożliwe do pracy z.

Jednym z powodów jest to, że układanie Wykresów jest trudne . W szczególności minimalizowanie przekroczeń krawędzi jest NP-trudne, więc podejrzewam, że większość projektantów layoutu uderzyła w to problem, uderz kilka razy głową w klawiaturę i poddaj się.

Jeśli ktoś wymyśli do tego dobrą bibliotekę, proszę ją opublikować dla reszty z nas:)

 10
Author: GreySage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 23:08:57

Czymś, co może być łatwiejsze niż próba silnego odparcia krawędzi, jest poruszanie węzłami wokół, aż ilość przecinających się linii w systemie będzie niższa.

Http://en.wikipedia.org/wiki/Simulated_annealing

Zacznij od węzłów z najmniejszą liczbą połączeń i poruszaj się w dół.

Jeśli spróbujesz użyć krawędzi jako węzłów, podejrzewam, że będziesz miał te same problemy z blokowaniem przestrzennym. Rozwiązaniem jest ustalenie, gdzie znajdują się krawędzie skrzyżowań i jeśli można je rozwiązać. Może się okazać, że rozwiązywanie wielu przejść granicznych nie jest możliwe

Bardziej bocznym podejściem do wizualizacji jest animowanie jej w taki sposób, aby pokazywała tylko podzbiór węzłów i połączeń naraz. Lub aby krawędzie były przezroczyste, dopóki użytkownik nie umieści ostrości myszy nad węzłem, co oznacza, że powiązane krawędzie stają się bardziej widoczne.

 5
Author: VoronoiPotato,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-29 19:43:54

Poszedłem za przykładem edytora Force i zobaczyłem, że ustawienie wartości charge i linkDistance rozwiązuje problem.

  ...
  .charge(-200)
  .linkDistance(50)
  ...

Zrzut ekranu:

Tutaj wpisz opis obrazka

 1
Author: Ionică Bizău,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-08 07:16:15

Mam "rozwiązany" problem z tym:

nodes[0].x = width / 2;
nodes[0].y = 100;
nodes[0].fixed = true;
force.on("tick", function(e) {

    var kx = .4 * e.alpha, ky = 1.4 * e.alpha;
    links.forEach(function(d, i) {
      d.target.x += (d.source.x - d.target.x) * kx;
      d.target.y += (d.source.y + 80 - d.target.y) * ky;
    });
    [...]
 }

Http://mbostock.github.io/d3/talk/20110921/parent-foci.html

To nie jest dokładnie to, czego chcieliśmy, ale lepiej jak wcześniej. Importend jest, że zdefiniujesz "root" - węzeł i naprawiono go.
nodes[0].fixed = true;
Wygląda bardziej jak drzewo, ale jest jaśniejsze.
 -1
Author: Baum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-13 09:00:32