Deaktivieren Sie Diagrammaktualisierungen mit InteraktionIch habe eine Datentabelle mit den Spalten ox, oy, dx und dy. Zu Demonstrationszwecken können Sie davon ausgehen, dass alle Spalten zufällig sind, mit der Formel: Random Normal(0, 10). Das eigentliche Problem ist ein Netzwerk mit einer Koordinatenliste.
Ich möchte Linien zwischen (ox, oy) und (dx, dy) zeichnen und kann dies entweder mit Graph Builder oder Graph Box tun (Beispiel unten). Allerdings zeichnet JMP bei jeder Interaktion die Linien neu, was meine Visualisierung sehr langsam macht (ich habe >10.000 Zeilen in der Datentabelle). Ich habe dies getestet, indem ich einen kleinen zufälligen Teil zu den Ursprungs- und Zielkoordinaten im Diagrammskript hinzugefügt habe und sobald es eine Interaktion gibt (z. B. Verwendung des Grabber-Werkzeugs und Ziehen der Leinwand, Anpassen der Achsen, Ändern der Diagrammgröße, Ändern der Fenstergröße), Die Zeilen ändern sich. Gibt es eine Möglichkeit, JMP daran zu hindern, das Diagramm zu aktualisieren und die Skripte erneut auszuführen?
Ich konnte im Graph Builder (ich würde lieber diese Plattform verwenden) oder Graph Box keine Möglichkeit finden. ich fand die
<< Graph Updating( Per Mouse Up );
Nachricht, aber es gibt nur zwei Optionen; Soweit ich weiß, gibt es keine Option „Nicht aktualisieren“. Außerdem denke ich, dass diese Meldung mit Graph Box sowieso nicht funktioniert.
Hier ist ein minimales Beispiel für ein Diagrammfeld, das Linien zeichnen kann, die Linien jedoch bei jeder Interaktion aktualisiert werden:
New Window( "Example",
Graph Box(
Frame Size( 300, 300 ),
Pen Color( "Blue" );
o_x = :ox << Get Values();
o_y = :oy << Get Values();
d_x = :dx << Get Values();
d_y = :dy << Get Values();
For( i=1, i<=N Items(o_x), i++,
origin = Eval List({o_x[i]*Random Normal( 1, 0.1 ), o_y[i]*Random Normal( 1, 0.1 )});
destination = Eval List({d_x[i]*Random Normal( 1, 0.1 ), d_y[i]*Random Normal( 1, 0.1 )});
Line(origin, destination);
);
);
);Zur Erinnerung: Ich habe die Zufallsnormale nur in dieses Diagrammfeld-Skript eingefügt, um zu sehen, ob die Linien neu berechnet werden. Das eigentliche Problem sind feste Koordinaten.
Bonusfrage: Gibt es eine Möglichkeit, Linien hinzuzufügen, nachdem das Diagrammfeld erstellt wurde? Ich konnte es in den Beispielen nicht finden. Ich vermutete, dass sie möglicherweise nicht bei jeder Mausinteraktion aktualisiert werden, konnte es aber nicht testen.
Automatisierung und SkripterstellungDatenmischung und -bereinigungMassenanpassungBetreff: Diagrammaktualisierungen mit Interaktion deaktivierenDas ist eine wirklich interessante Idee. Leider hatte die Grafik mit den 20.000 Punkten, die der Pfad mit den Moves und Lines durchlaufen musste, noch mehr Probleme und es war noch langsamer.
Aber ich werde dies für zukünftige Probleme im Hinterkopf behalten, weil mir die Idee gefällt, dass es hier technisch gesehen einen einzigen Pfad gibt und keine Schleifen im Grafikcode erforderlich sind.
Betreff: Diagrammaktualisierungen mit Interaktion deaktivierenIch wusste nicht, dass ich in JSL eine solche Vektorisierung durchführen kann. Vielen Dank, dass Sie mir diese Methode beigebracht haben!
Sobald ich die Zufallsberechnung aus dem Diagrammfeld verschiebe, werden die Zahlen nicht aktualisiert, aber das ist irreführend. Ich habe die Zufälligkeit nur eingefügt, um mich davon zu überzeugen, dass JMP das Diagramm neu zeichnet. Obwohl diese Methode funktionierte, erfüllte sie nicht ganz das, was ich tun wollte. Als ich die Zufallsberechnung in das Diagrammfeld zog, bewegten sich alle Linien noch immer. Aber ich habe auf jeden Fall etwas dabei gelernt. Danke!
Außerdem musste ich die Linienzeichnung immer noch for-loopen, da meine Linien keine verbundenen Pfade sein sollten. Ich konnte also nicht einfach ein einzelnes Paar x- und y-Matrizen erstellen und sie an Line oder Line Seg übergeben.
Ich habe Ihren Code verwendet, damit er mit meiner Datentabelle funktioniert, und er ist unten aufgeführt. Ich hänge die Tabelle an diese Nachricht an, falls jemand anderes diese Lösung benötigt.
Names Default To Here( 1 );
// origin
o_x = :ox << Get As Matrix;
o_y = :oy << Get As Matrix;
// destination
d_x = :dx << Get As Matrix;
d_y = :dy << Get As Matrix;
n = N Items( o_x );
// plot segments
New Window( "Example",
gb = Graph Box(
Frame Size( 300, 300 ),
Pen Color( "Blue" );
seg_x = (o_x :*</img> J( n, 1, Random Normal( 1, 0.1 ) )) || (d_x :*</img> J( n, 1, Random Normal( 1, 0.1 ) ));
seg_y = (o_y :*</img> J( n, 1, Random Normal( 1, 0.1 ) )) || (d_y :*</img> J( n, 1, Random Normal( 1, 0.1 ) ));
For( i=1, i<=n, i++,
Line( seg_x[i, -1], seg_y[i, -1] )
)
)
);
Betreff: Diagrammaktualisierungen mit Interaktion deaktivierenMeiner Meinung nach muss JMP diese Funktionalität wirklich _SEHR_ dringend aktualisieren.Ich bin mehrmals auf dieses Problem gestoßen und es gibt ganz einfach keine gültige Problemumgehung.JMP sollte das Grafikskript nur dann erneut ausführen, wenn sich etwas ändert (z. B. die Größe des Diagramms), und nicht nur beim Scrollen/Ändern der Fenstergröße.
Abgesehen davon habe ich herausgefunden, dass die schnellste Methode, so etwas zu tun, die unten gezeigte ist.Ich erstelle einen SVG-Pfad (meiner Erfahrung nach ist dies zweifellos die schnellste Möglichkeit, komplexe Pfade in JMP darzustellen) und habe einen Wächter, der bestimmt, ob der Pfad rekonstruiert werden soll oder nicht.Ich habe nur als Beispiel eine Schaltfläche eingefügt, um die Rekonstruktion des Pfades zu erzwingen.
Ich hoffe, das hilft, aber noch besser wäre es, wenn die JMP-Entwickler ein System bereitstellen würden, das sich wie alle anderen Display-Manager-Systeme verhält (einschließlich Multithreading, Signal/Slots, Rückrufe usw.).
Ich habe auch mit dieser Methode herumgespielt, um ein Bild des gewünschten Renderings aufzunehmen, die Größe des Grafikfelds zu überprüfen und, wenn sich die Größe nicht geändert hat, das gespeicherte Bild als Anzeigeobjekt zu verwenden.Das ist es, was JMP tun sollte und niemals so eingerichtet sein sollte, dass es das Grafikskript bei jeder sich bietenden Gelegenheit aggressiv ausführt.Allerdings hatte ich mit dieser Methode nicht viel Glück, da JMP nicht die notwendigen Tools bereitstellt, damit dies ordnungsgemäß funktioniert
self = New Namespace();
self:table = Current Data Table();
self:redraw = 1;
self:path = "";
self:build path = Function( {},
{Default Local},
self:path = "";
For Each Row( self:table,
self:path ||= Eval Insert( "\[M^:ox * Random Normal( 1, 0.1 )^,^oy * Random Normal( 1, 0.1)^ L^dx * Random Normal( 1, 0.1 )^,^:dy * Random Normal( 1, 0.1 )^]\" )
);
);
Eval( Eval Expr(
New Window( "Example",
<<ON close=""></ON>
Betreff: Diagrammaktualisierungen mit Interaktion deaktivierenMeiner Meinung nach besteht das Problem darin, dass die Rahmenbox bei jeder Änderung automatisch aktualisiert wird. Daher ist es am besten, alle Änderungen vor dem Rendern vorzunehmen. Außerdem können Sie die Vorgänge aus Gründen der Geschwindigkeit auch vektorisieren, anstatt sie explizit mit der Funktion For() zu iterieren. Auch grafische Segmente bieten einige Vorteile, diese sind jedoch derzeit nur unzureichend dokumentiert.
Sehen Sie sich diesen Ansatz an:
Names Default to Here( 1 );
// origin
o_x = :ox << Get As Matrix;
o_y = :oy << Get As Matrix;
// destination
d_x = :dx << Get As Matrix;
d_y = :dy << Get As Matrix;
n = N Items( o_x );
// vectorize for line segments
seg = (o_x :*</img> J( n, 1, Random Normal( 1, 0.1 ))) || (o_y f:* J( n, 1, Random Normal( 1, 0.1 ))) ||
(d_x :*</img> J( n, 1, Random Normal( 1, 0.1 ))) || (d_y f:* J( n, 1, Random Normal( 1, 0.1 )));
// plot segments
New Window( "Example",
gb = Graph Box(
Frame Size( 300, 300 ),
Pen Color( "Blue" );
Line Seg( seg );
)
);
// later, update seg, then send gb << Reshow message to graph box
(Ich habe Ihre Datentabelle nicht, daher konnte ich sie nicht testen, sie sollte aber dennoch den Ansatz veranschaulichen.)