2017-08-02 1 views
0

Diese Frage ist ähnlich wie Unlock nodes on grab/mousedown event, can not move them immediately in Cytoscape.js, aber ertragen Sie mit mir. Meine Situation hat eine zusätzliche Falte, so dass die angenommene Antwort nicht zu mir passt; Ich möchte ein fortlaufendes Layout verwenden.Wie kann ich in Cytoscape.js verhindern, dass sich Knoten in einem fortlaufenden Layout bewegen, der Benutzer aber trotzdem darauf klicken und ziehen kann?

Ich erstelle einen interaktiven Grafikeditor mit Cytoscape. Ich möchte, dass das Diagramm mit einem federbasierten Layout, ähnlich dem Force-Layout von d3, kontinuierlich angelegt wird. Der Benutzer sollte in der Lage sein, jederzeit auf einen der Knoten zu klicken und ihn zu ziehen, um das Layout manuell zu optimieren, und nachdem er einen Knoten losgelassen hat, sollte die Position des Knotens fixiert werden; Es sollte nicht mehr vom Force-Layout beeinflusst werden, es sollte einfach dort bleiben, wo es ist, bis der Benutzer es erneut bewegt oder es entsperrt. .

Ein Beispiel für das gewünschte Verhalten finden Sie unter https://apo.adrian-jagusch.de/#/. Klicken Sie auf die Kreis- oder Quadratschaltfläche in der Symbolleiste, und klicken Sie dann mehrmals auf den weißen leeren Bereich, um einige Knoten zu platzieren. Klicken Sie dann auf die Fadenkreuz-Schaltfläche und versuchen Sie, die Knoten zu verschieben. Die gezogenen Objekte werden nicht mehr bewegt, bis Sie sie entsperren, indem Sie auf sie doppelklicken.

Ich habe es geschafft, Dinge einzurichten, so dass meine Knoten gesperrt werden, wenn ich sie loslassen. Das Problem, das ich mit dem Fragesteller der Frage, die ich oben verlinkt habe, gemeinsam habe, ist, dass es nach dem Sperren der Knoten nicht mehr möglich ist, sie zu klicken und zu ziehen, bis sie entsperrt sind. Wenn ich den Event-Handler cy.nodes().on('mousedown', (event) => event.target.unlock()) registriere, wird der Knoten beim Anklicken freigeschaltet, aber ich kann ihn nicht sofort verschieben; Ich muss die Maustaste loslassen und ein zweites Mal klicken, bevor der Knoten gezogen wird. Ich möchte es auf den ersten Klick ziehen können.

Ich habe ein paar Lösungen für das Problem betrachtet:

  1. maxkfranz Vorschlag Knoten sperren nur während des Layouts Nach und schalt sie danach, ich habe versucht, ein nicht-kontinuierliches Layout (Euler oder Cose) unter Verwendung von und einfach als Reaktion auf das "freie" Ereignis, das ausgelöst wird, wenn ein Benutzer den Knoten gezogen hat, erneut ausgeführt wird. Ich habe animate: "end" verwendet, um einen visuellen Übergang zu ermöglichen. Das funktioniert ziemlich genau so, wie ich es erwartet habe, aber es sieht nicht gut aus und fühlt sich nicht gut an, um damit zu interagieren. Ich möchte wirklich, dass das Layout kontinuierlich ist.

  2. Ich habe darüber nachgedacht, das fortlaufende Layout nur auf die Teilmenge von Knoten anzuwenden, die nicht vom Benutzer behoben wurden, zB cy.nodes('[!fixedByUser]').layout({ name: "cola" ...}), das bestehende Layout stoppt und jedes Mal ein neues Layout instanziiert, wenn ein Knoten repariert oder nicht fixiert wird vom Benutzer. Das Problem mit dieser Idee ist, dass die Knoten, deren Positionen vom Benutzer festgelegt wurden, nicht vollständig vom Layout ignoriert werden sollten. Sie sollten immer noch Kräfte auf nicht fixierte Knoten ausüben.

  3. Patch das Cola-Layout, so dass es die Positionen der Knoten nicht aktualisiert, deren Daten die Eigenschaft fixedByUser: true enthält. Das scheint einfach zu viel Arbeit zu sein. Ich würde eher eine Bibliothek verwenden, die diese Funktion unterstützt.

  4. Wechseln Sie zu einer anderen Grafikbibliothek, die meinen Anwendungsfall besser unterstützt.

Ich würde Ihre Gedanken dazu schätzen!

+0

Könnte eine schmutzige Lösung sein, aber was ist mit der Verwendung von mouseover/out, um die Knoten zu (un) sperren? –

+0

Danke für den Vorschlag, ich habe es gerade eben ausprobiert: 'cy.nodes(). On ('mouseover', funktion (ereignis) { if (event.target.data ('fixedByUser')) { event. target.unlock() } }) cy.nodes (.) am ('mouseout', function (event) { if (event.target.data ('fixedByUser')) { event.target.lock() } }) ' Das Problem damit ist, dass, sobald ich den Knoten entsperren, bewegt es sich unter dem Mauszeiger aus, so dass es schwierig ist, darauf zu klicken. Es ist, als würde es vom Cursor weglaufen. – Ann

Antwort

0

Wenn Sie nicht möchten, dass ein Knoten von einem Layout betroffen ist, fügen Sie ihn nicht in das Layout ein, indem Sie eles.layout() verwenden. Wenn Sie diese Bedingung ändern möchten, während das Layout ausgeführt wird, stoppen Sie das alte Layout, und starten Sie ein neues mit den neuen Elementen. Jedes Layout, das unbegrenzt ausgeführt werden kann, kann ohne Probleme ersetzt werden.

Verwandte Themen