2022_Q1 MakeOverChallenge: Aktion per Mausklick auf verschiedene ArtenDas ist die Makeover-Challenge Q1 2022.
Das Ziel ist es, ein Beispiel, Skript oder eine Anleitung zu entwickeln, um eine der drei Aufgaben zu erfüllen (alle haben mit dem Einleiten einer Aktion zu tun, nachdem Sie in JMP auf etwas geklickt haben):
- Herausforderung A: (Bilder und Skript zum Erstellen einer anfänglichen Datentabelle zum Öffnen von Bildern im Anhang: 2022Q1_ChallengeA.zip)
- Sie haben: Eine Datentabellenspalte mit Bildern oder Links zu einer Website oder einer Datei (auch bekannt als Ausdrücke)
- Sie möchten: auf eine Zelle dieser Spalte klicken und den Link oder das Bild außerhalb von JMP öffnen
- Das übergeordnete Ziel: Das Klicken in eine Datentabellenzelle sollte etwas auslösen
- Herausforderung B : (Skript zum Öffnen der Datentabelle und zum Erstellen des angehängten Berichts: 2022Q1_ChallengeB_starterScript.jsl)
- Sie haben: Big Class und einen Graph Builder-Bericht von Gewicht nach Größe (siehe Skript)
- Sie möchten: Das Schließen des Graph Builder-Berichts sollte einen Verteilungsbericht von "Alter" öffnen, diesen Bericht als Bild speichern und den Verteilungsbericht schließen.
- Das übergeordnete Ziel: Das Schließen eines Fensters sollte eine Aktion auslösen
- Herausforderung C: (Skript zum Öffnen der Datentabelle und zum Erstellen des angehängten Berichts: 2022Q1_ChallengeC_starterScript.jsl)
- Sie haben: Einen Graph Builder-Bericht mit Beispieldaten für Wachstumsmessungen.
- Sie möchten: Wenn Sie auf eine Zeile klicken oder mehrere Zeilen (oder Kategorien in der Legende) auswählen, möchten Sie eine Teilmenge der ausgewählten Zeilen generieren.
- Das übergeordnete Ziel: Das Klicken auf ein Diagramm oder einen Bericht sollte eine Aktion auslösen
Sie können an so vielen Herausforderungen arbeiten, wie Sie möchten. Du kannst/solltest deine Antworten direkt als Antwort auf diesen Thread einreichen.
!!! Beginnen Sie beim Absenden bitte in der ersten Zeile damit, auf welche Herausforderung sich Ihre Antwort bezieht, z
HERAUSFORDERUNG A:
Das ist meine Antwort...
// this is my code
...
Beim nächsten Treffen (18. Mai 2022) werden wir einige der Antworten präsentieren und ich werde die besten Antworten als Lösung für diesen Thread markieren.
Freue mich auf eure Einsendungen 
Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHERAUSFORDERUNG C
Dies ist meine Antwort, siehe vollständiges Skript unten.
Der untere Teil fügt der Tabelle einen Row State Handler hinzu, der die Aktion auslöst (siehe Beispiel im Scripting Index).
Names Default To Here( 1 );
// Open Data Table
dt = Open( "$SAMPLE_DATA/Growth Measurements.jmp", invisible );
// Report snapshot: Growth Measurements - Graph Builder
gb = dt << Graph Builder(
Size( 522, 452 ),
Show Control Panel( 0 ),
Legend Position( "Bottom" ),
Graph Spacing( 8 ),
Variables( X( :Age ), Y( :Growth ), Overlay( :Subject ) ),
Elements( Line( X, Y, Legend( 13 ) ) )
);
// This is my code (Georg)
// (see Scripting Index "Make Row State Handler")
// Define a function, that does the action
f = Function( {a},
Current Data Table() << Subset( Selected Rows( 1 ), Selected columns only( 0 ) )
);
// Set up a row state handler, that triggers the execution of a function on any change of row states,
// a change on row selection by clicking on a line in Graph Builder is a change of row states in the table
rs = dt << make row state handler( f );Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHERAUSFORDERUNG C
Mit einer Mausbox war es nicht möglich, etwas auszuwählen, also wechselte ich zu einem Row State Handler
Names Default To Here( 1 );
// Open Data Table
dt = Open( "$SAMPLE_DATA/Growth Measurements.jmp", invisible );
// Report snapshot: Growth Measurements - Graph Builder
gb = dt << Graph Builder(
Size( 522, 452 ),
Show Control Panel( 0 ),
Legend Position( "Bottom" ),
Graph Spacing( 8 ),
Variables( X( :Age ), Y( :Growth ), Overlay( :Subject ) ),
Elements( Line( X, Y, Legend( 13 ) ) )
);
active_subset = "";
first_subset = "false";
rsh = dt << make row state handler(
Function( {a},
subtbl = dt << Subset( Selected Rows( 1 ) );
gb << Bring Window To Front;
if(
first_subset == "true",
close(active_subset, no save)
);
active_subset = subtbl;
first_subset = "true";
)
);
Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHERAUSFORDERUNG A:
HINWEIS: Ich habe diese ältere Version beibehalten, da einige Leute sie bereits gesehen hatten, aber ich habe eine sauberere Lösung als Antwort zu diesem.
Keine schöne Lösung, aber sie erfüllt ihren Zweck... In der Hoffnung, dass ein eleganteres auftaucht!
Dies muss nach dem starterScript hinzugefügt werden:
// Defining the file name for an image placeholder for displaying on the OS when clicking:
pictFileName = Get Default Directory() || "verylonganduselessname.png"; //name for the temp image file (to be deleted at the end)
dtx:Picture << Set Property("tmpFileName", pictFileName); //saving the name so it can be retrieved from within the table
dtx << On Close( Delete File(pictFileName) ); //make sure we erase the temp image file at the end.
// Setting a Click event handler for the column of interest:
dtx:Picture << Set Property(
"Event Handler",
Event Handler(
Click(JSL Quote( Function(
{thisTable, thisColumn, iRow},
pictFileName = thisTable:thisColumn<< Get Property("tmpFileName"); //recover the path for a temp file
thisTable:thisColumn[iRow] << Save Image( pictFileName ); //save cell contents to temp file
Web( "file://" || pictFileName ) // open the image file
)
)
),
Tip(JSL Quote( Function(
{thisTable, thisColumn, iRow},
"click to open";
)
)
)
)
);
Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHERAUSFORDERUNG A
Tut mir leid, dass ich mit meiner ursprünglichen Lösung voreilig bin ... Hier ist ein sauberer.
Names Default to Here ( 1 );
//path = <YOUR full="" path="" to="" where="" the="" images="" have="" been="" saved="">;
// eg.
// path = "C:\EventHandlerImages\";
path = "$DOCUMENTS\Scripting\2022Q1\ChallengeA\2022Q1_ChallengeA\";
//==========================================================================
//Multiple File Import is new in JMP 14
{dtx} = Multiple File Import(
<<SET folder=""></SET></YOUR>Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHerausforderung C
Bei den Herausforderungen A und B war leider wenig anderes zu tun. Die angebotenen Lösungen schienen einwandfrei. Im Gegensatz dazu hatte ich das Gefühl, dass bei Herausforderung C noch eine Verbesserung möglich war. Ein paar Worte zu meiner Antwort
- Ich habe im Grunde den notwendigen Code gestohlen von hier ( @txnelson ist, wie viele andere Scripter, für mich ein Rockstar)
- Ich habe das Diagramm leicht modifiziert, indem ich sichtbare Datenpunkte aufgenommen habe, sodass es einfacher ist, einzelne Zeilen auszuwählen
- Nach Auswahl der Punkte im Diagramm wird die Datentabelle mit der Teilmenge nicht sofort geöffnet. Dies erfolgt über die unterhalb der Grafik hinzugefügte Schaltfläche
Unten sehen Sie das vollständige Skript, einschließlich des geänderten Diagramms.
// Open Data Table
dt = Open( "$SAMPLE_DATA/Growth Measurements.jmp",invisible );
// Report snapshot: Growth Measurements - Graph Builder
gb = dt << Graph Builder(
Size( 522, 452 ),
Show Control Panel( 0 ),
Legend Position( "Bottom" ),
Graph Spacing( 8 ),
Variables( X( :Age ), Y( :Growth ), Overlay( :Subject ) ),
Elements(
Points( X, Y, Legend( 17 ), Jitter Limit( 0 ) ), // added markers
Line( X, Y, Legend( 13 ) ) ),
SendToReport( // increased markers to decent size
Dispatch(
{},
"Graph Builder",
FrameBox,
{Marker Size( 6 ), Marker Drawing Mode( "Normal" )}
)
)
);
// my solution (stolen from here: https://community.jmp.com/t5/Discussions/Creating-a-Subset-from-an-Interactive-Graph/td-p/114459)
subsetButton = Button Box( "Dear user, Please press here to create a Subset of the Selected Points immediately",
If( N Rows( dt << get selected rows ) > 0,
dt << subset( selected rows( 1 ), selected columns( 0 ) )
)
);
Report( gb )["Graph Builder"] << append( subsetButton );
Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHerausforderung A:
Hauptsächlich JMP-geschriebener Code mit Add Column Properties. Außerdem wurde ein Beispiel zum Hinzufügen und Öffnen von URLs hinzugefügt
Mehr sehen...
Names Default To Here(1);
// Challenge A
path = "2022Q1_ChallengeA"; // path to images
{dtx} = Multiple File Import(
<<SET folder=""></SET>
Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHERAUSFORDERUNG B
Fügen Sie dies am Ende des Skripts hinzu:
gb << On Close(
dist = dt << Distribution( Nominal Distribution( Column( :age ) ) );
image = dist << Get Picture;
path = "$temp/age_dist.png";
image << Save Picture( path, "png" );
dist << Close Window();
Open( path );
);
Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHerausforderung B:
Mehr sehen...
Names Default To Here(1);
// 2022_Q1 MakeOverChallenge: Action on mouse click in various ways
// Challenge B
dt = Open("$SAMPLE_DATA/Big Class.jmp");
//Use expression to make script a bit more clean IF this were to be expanded
create_dist = Expr(
dist = dt << Distribution(Nominal Distribution(Column(:age)), Histograms Only);
wait(1); // add wait so we can see that distribution is created
dist << Save Picture("$TEMP/Big_Class_age_dist.png", png);
dist << Close Window;
);
gb = dt << Graph Builder(
Size(528, 454),
Show Control Panel(0),
Variables(X(:height), Y(:weight)),
Elements(Points(X, Y, Legend(3)), Line Of Fit(X, Y, Legend(5)))
);
gb << On Close(create_dist);
// Open("$TEMP/Big_Class_age_dist.png"); // un-comment to open the image
Betreff: 2022_Q1 MakeOverChallenge: Aktion bei Mausklick auf verschiedene ArtenHerausforderung C:
Ich empfehle auf jeden Fall, solche Dinge mit Schaltflächen zu tun, da dies die Erstellung zu vieler Teilmengen verhindert. Aber hier bin ich der gegebenen Herausforderung gefolgt und habe eine einfache Überprüfung hinzugefügt, dass wir nicht mindestens zweimal dieselbe Teilmenge erstellen.
Mehr sehen...
Names Default To Here(1);
// Open Data Table
dt = Open("$SAMPLE_DATA/Growth Measurements.jmp", invisible);
gb = dt << Graph Builder(
Size(522, 452),
Show Control Panel(0),
Legend Position("Bottom"),
Graph Spacing(8),
Variables(X(:Age), Y(:Growth), Overlay(:Subject)),
Elements(Line(X, Y, Legend(13)))
);
//initialize some variables
prev_rows = [];
dt_list = {};
f = Function({rows_changed},
//Rowstate 1 is selected row
cur_rows = Loc(dt << Get Row States, 1);
//if no rows are selected, don't try to create subsets
If(N Items(cur_rows) == 0,
return()
);
//compare to previous to prevent opening extensive abmount of subsets
If(N Items(cur_rows) == N Items(prev_rows),
If(All(cur_rows == prev_rows),
return();
);
);
dt_subset = dt << Subset(Output table("selected_rows"), Rows(cur_rows), invisible);
Insert Into(dt_list, dt_subset); //keep list to make closing easier
//attempt to bring gb to front, this won't work perfectly without wait
gb << Bring Window To Front;
dt_subset << Show Window(1);
//it is enough if we update prev_rows only when subset was created
prev_rows = cur_rows;
);
rs = dt << make row state handler(f);
/* run this to close all data tables
For Each({dt_ref}, dt_list,
Try(Close(dt_ref, no save), Show(exception_msg));
);
Close(dt, no save);
*/
Mit dem Row State Handler können wir nicht auf das Ereignis der Mausfreigabe zugreifen, sodass wir immer noch viele Teilmengen erstellen, wenn der Benutzer mehrere Zeilen nacheinander aus dem Diagramm auswählt (möglicherweise gibt es eine Möglichkeit, dies mit Mouse Box() zu tun, aber ich denke, die Verwendung der Schaltfläche würde es tun viel einfacher und einfacher sein).