2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresIl s'agit du Makeover Challenge Q1 2022.
L'objectif est de proposer un exemple, un script ou un guide pour accomplir l'une des trois tâches (toutes concernent le lancement d'une action après avoir cliqué sur quelque chose dans JMP) :
- Défi A : (images et script pour créer le tableau de données initial pour ouvrir les images jointes : 2022Q1_ChallengeA.zip)
- Vous avez : Une colonne de table de données avec des images ou des liens vers un site Web ou un fichier (alias expressions)
- Vous souhaitez : cliquer sur une cellule de cette colonne et ouvrir le lien ou l'image en dehors de JMP
- L'objectif général : cliquer dans une cellule du tableau de données devrait déclencher quelque chose
- Défi B : (script pour ouvrir la table de données et créer le rapport joint : 2022Q1_ChallengeB_starterScript.jsl)
- Vous avez : Big Class et un rapport Graph Builder de poids par taille (voir script)
- Vous voulez : La fermeture du rapport Graph Builder doit ouvrir un rapport de distribution de "l'âge", enregistrer ce rapport en tant qu'image et fermer le rapport de distribution.
- L'objectif global : la fermeture d'une fenêtre doit déclencher une action
- Défi C : (script pour ouvrir la table de données et créer le rapport joint : 2022Q1_ChallengeC_starterScript.jsl)
- Vous disposez des éléments suivants : Un rapport du Générateur de graphiques sur les exemples de données de mesures de croissance.
- Vous souhaitez : Lorsque vous cliquez sur une ligne ou que vous sélectionnez plusieurs lignes (ou catégories dans la légende), vous souhaitez générer un sous-ensemble des lignes sélectionnées.
- L'objectif global : cliquer sur un graphique ou un rapport doit déclencher une action
Vous pouvez travailler sur autant de défis que vous le souhaitez. Vous pouvez/devriez soumettre vos réponses directement en réponse à ce fil de discussion.
!!! Lors de la soumission, veuillez commencer à la première ligne par le défi auquel votre réponse fait référence, par exemple
DÉFI A :
C'est ma réponse...
// this is my code
...
Lors de la prochaine réunion (18 mai 2022), nous présenterons certaines des réponses et je marquerai les meilleures réponses comme solution à ce fil.
Dans l'attente de vos soumissions 
Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDÉFI C
Ceci est ma réponse, voir le script complet ci-dessous.
La partie inférieure ajoute un gestionnaire d'état de ligne à la table, qui déclenche l'action (voir l'exemple dans 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 );Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDÉFI C
Avec une boîte de souris, il n'était pas possible de sélectionner quelque chose, j'ai donc changé pour un gestionnaire d'état de ligne
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";
)
);
Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDÉFI A :
REMARQUE: J'ai gardé cette ancienne version car certaines personnes l'avaient déjà vue, mais j'ai posté une solution plus propre en tant que Répondre à celui-ci.
Pas du tout une jolie solution, mais ça fait le travail... En espérant en voir un plus élégant !
Ceci à ajouter après le starterScript :
// 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";
)
)
)
)
);
Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDÉFI UN
Désolé d'avoir sauté le pas avec ma solution initiale... En voici un plus propre.
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>Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDéfi C
Il n'y avait malheureusement pas grand-chose d'autre à faire en ce qui concerne les défis A et B. Les solutions apportées semblaient impeccables. En revanche, j'ai estimé qu'une certaine amélioration était encore possible pour le défi C. Quelques mots sur ma réponse
- J'ai essentiellement volé le code nécessaire d'ici ( @txnelson est, comme beaucoup d'autres scénaristes, une rock star pour moi)
- J'ai légèrement modifié le graphique en incluant des points de données visibles, il est donc plus facile de sélectionner des lignes individuelles
- Après avoir sélectionné les points dans le graphique, la table de données avec le sous-ensemble ne s'ouvre pas immédiatement. Cela se fait via le bouton ajouté sous le graphique
Voir ci-dessous le script complet, y compris le graphique modifié.
// 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 );
Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDéfi A :
Principalement du code écrit par JMP avec Ajouter des propriétés de colonne. Ajout également d'un exemple d'ajout et d'ouverture d'URL
Voir plus...
Names Default To Here(1);
// Challenge A
path = "2022Q1_ChallengeA"; // path to images
{dtx} = Multiple File Import(
<<SET folder=""></SET>
Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDÉFI B
Ajoutez ceci au bas du script :
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 );
);
Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDéfi B :
Voir plus...
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
Re : 2022_Q1 MakeOverChallenge : action sur le clic de la souris de différentes manièresDéfi C :
Je suggère définitivement de faire des choses comme ça avec des boutons car cela empêche la création de trop de sous-ensembles. Mais ici, j'ai suivi le défi donné et ajouté une simple vérification que nous ne créerons pas au moins le même sous-ensemble deux fois.
Voir plus...
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);
*/
Avec Row State Handler, nous ne pouvons pas accéder à l'événement de libération de la souris, nous allons donc créer de nombreux sous-ensembles si l'utilisateur sélectionne plusieurs lignes une par une à partir du graphique (il pourrait y avoir un moyen de le faire avec Mouse Box(), mais je pense que l'utilisation du bouton serait être beaucoup plus simple et facile).