Diagrammaktualisierungen mit Interaktion deaktivierenIch 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 Liste von Koordinaten.
Ich möchte Linien zwischen (ox, oy) und (dx, dy) ziehen und kann dies entweder mit Graph Builder oder Graph Box tun (Beispiel unten). Bei jeder Interaktion zeichnet JMP die Linien jedoch 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. das Grabber-Tool verwenden und die Leinwand ziehen, Achsen anpassen, die Größe des Diagramms ändern, die Größe des Fensters ändern), die Zeilen ändern sich. Gibt es eine Möglichkeit, JMP daran zu hindern, das Diagramm zu aktualisieren und die Skripts erneut auszuführen?
Ich konnte in Graph Builder (ich würde diese Plattform bevorzugen) oder Graph Box keinen Weg finden. ich fand die
<< Graph Updating( Per Mouse Up );
Nachricht, aber es gibt nur zwei Optionen; Soweit ich das beurteilen kann, gibt es keine Option "Nicht aktualisieren". Außerdem denke ich, dass diese Nachricht sowieso nicht mit Graph Box funktioniert.
Hier ist ein minimales Graph Box-Beispiel, das Linien zeichnen kann, aber die Linien werden bei jeder Interaktion aktualisiert:
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 Random Normal in diesem Graph Box-Skript nur hinzugefügt, um zu sehen, ob die Linien neu berechnet werden. Das eigentliche Problem hat feste Koordinaten.
Bonusfrage: Gibt es eine Möglichkeit, Linien hinzuzufügen, nachdem die Diagrammbox erstellt wurde? In den Beispielen habe ich es nicht gefunden. Ich habe die Theorie aufgestellt, dass sie vielleicht nicht bei jeder Mausinteraktion aktualisiert werden, konnte es aber nicht testen.
GrafikSkripterstellungBetreff: Diagrammaktualisierungen mit Interaktion deaktivierenIch denke, das Problem ist, dass die Framebox automatisch aktualisiert wird, wenn es eine Änderung gibt, also ist es am besten, alle Änderungen vor dem Rendern vorzunehmen. Außerdem können Sie die Operationen auch aus Geschwindigkeitsgründen vektorisieren, anstatt explizit mit der For()-Funktion zu iterieren. Grafische Segmente bieten auch einige Vorteile, die derzeit jedoch schlecht dokumentiert sind.
Siehe diesen Ansatz:
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, aber sie sollte den Ansatz dennoch veranschaulichen.)
Betreff: Diagrammaktualisierungen mit Interaktion deaktivierenIMHO 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), nicht nur beim Scrollen / Ändern der Fenstergröße.
Abgesehen davon habe ich festgestellt, dass die schnellste Methode, um so etwas zu tun, wie unten gezeigt ist.Ich erstelle einen SVG-Pfad (meiner Erfahrung nach ist dies zweifellos der schnellste Weg, um komplexe Pfade in JMP zu rendern) und habe einen Wächter, um zu bestimmen, ob der Pfad rekonstruiert werden soll oder nicht.Ich habe eine Schaltfläche eingefügt, um die Rekonstruktion des Pfads einfach als Beispiel zu erzwingen.
Ich hoffe, das hilft, aber noch besser wäre es, wenn die JMP-Entwickler ein System bereitstellen, 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 zu erhalten, die Größe des Grafikfelds zu überprüfen und, wenn sich die Größe nicht geändert hat, das gespeicherte Bild als anzuzeigendes Objekt zu verwenden.Dies ist, was JMP tun sollte und niemals hätte eingerichtet werden sollen, um das Grafikskript bei jeder möglichen Gelegenheit aggressiv auszuführen.Allerdings hatte ich mit dieser Methode nicht viel Glück, da JMP nicht die notwendigen Tools bereitstellt, damit dies richtig 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 deaktivierenIch wusste nicht, dass ich eine solche Vektorisierung in JSL durchführen kann. Also danke, dass du mir diese Methode beigebracht hast!
Sobald ich die Zufallsberechnung aus dem Diagrammfeld herausbewege, 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 die Grafik neu gezeichnet hat. Während diese Methode funktionierte, tat sie nicht ganz das, was ich tun wollte. Nachdem ich die Zufallsberechnung in das Diagrammfeld gezogen hatte, bewegten sich alle Linien immer noch. Aber ich habe definitiv etwas auf dem Weg gelernt. Danke!
Außerdem musste ich die Linienzeichnung 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 es mit meiner Datentabelle funktioniert und es ist unten. Ich werde die Tabelle an diese Nachricht anhängen, 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] )
)
)
);