2022_Q1 MakeOverChallenge: Acción al hacer clic con el mouse de varias manerasEste es el Desafío de cambio de imagen del primer trimestre de 2022.
El objetivo es crear un ejemplo, script o guía para cumplir una de las tres tareas (todas tienen que ver con iniciar alguna acción después de hacer clic en algo en JMP):
- Desafío A: (imágenes y script para crear una tabla de datos inicial para abrir imágenes adjuntas: 2022Q1_ChallengeA.zip)
- Tiene: Una columna de tabla de datos con imágenes o enlaces a un sitio web o un archivo (también conocido como expresiones)
- Quiere: hacer clic en una celda de esta columna y abrir el enlace o la imagen fuera de JMP
- El objetivo general: hacer clic en una celda de la tabla de datos debería iniciar algo
- Desafío B : (script para abrir la tabla de datos y crear el informe adjunto: 2022Q1_ChallengeB_starterScript.jsl)
- Tienes: Big Class y un informe Graph Builder de peso por altura (ver guión)
- Lo que desea: Cerrar el informe de Graph Builder debería abrir un informe de distribución de "edad", guardar este informe como una imagen y cerrar el informe de distribución.
- El objetivo general: cerrar una ventana debería desencadenar alguna acción
- Desafío C: (script para abrir la tabla de datos y crear el informe adjunto: 2022Q1_ChallengeC_starterScript.jsl)
- Tiene: Un informe de Graph Builder sobre datos de muestra de medidas de crecimiento.
- Lo que desea: al hacer clic en una línea o seleccionar varias líneas (o categorías en la leyenda), desea generar un subconjunto de las filas seleccionadas.
- El objetivo general: hacer clic en un gráfico o informe debería desencadenar alguna acción
Puedes trabajar en tantos desafíos como quieras. Puedes/debes enviar tus respuestas directamente como respuesta a este hilo.
!!! Al enviar, comience en la primera línea con el desafío al que se refiere su respuesta, por ejemplo
DESAFÍO A:
Esta es mi respuesta...
// this is my code
...
En la próxima reunión (18 de mayo de 2022) presentaremos algunas de las respuestas y marcaré las mejores respuestas como solución a este hilo.
Esperamos sus envíos 
Re: 2022_Q1 MakeOverChallenge: Acción al hacer clic con el mouse de varias manerasEscribiré un breve resumen de lo que hablé hoy en la reunión. Puede ver mis soluciones completas en mis publicaciones anteriores sobre este tema. Modificaré mi solución Challenge A para usar la carpeta SAMPLE_IMAGE de JMP, por lo que deberías poder ejecutarla directamente.
Desafío A: hacer clic en una celda de la tabla de datos debería iniciar algo<BR />
Concepto: uso de la propiedad de columna del controlador de eventos
Esto es bastante fácil de hacer dejando que JMP lo escriba por usted. Agregue el controlador de eventos para la página web, por ejemplo, y luego modifique el script para que se ajuste mejor a sus necesidades. A continuación se muestra mi solución de ejemplo sobre cómo abrir una imagen en una celda.
Column(dtx, "Picture") << Add Column Properties(
Set Property(
"Event Handler",
Event Handler(
Click(JSL Quote(Function({thisTable, thisColumn, iRow}, {},
New Window(Char(thisTable:"File Name"n[iRow]), New Image(thisTable:thisColumn[iRow]));
))),
Tip(JSL Quote(Function({thisTable, thisColumn, iRow}, {},
"Enlarge image " || Char(thisTable:"File Name"n[iRow]);
)))
)
)
);
Los controladores de eventos pueden ser bastante poderosos ya que, por ejemplo, podrían consultar datos de la base de datos al hacer clic en la celda.
Desafío B: Cerrar una ventana debería desencadenar alguna acción
Concepto: Usar << Al cerrar()</CODE></P>
<P><CODE class=" language-jsl">
La idea en este desafío era realizar una acción cuando Graph Builder está cerrado. Esta es una tarea bastante sencilla de realizar utilizando << On Close(). A continuación se muestra una versión ligeramente modificada de la solución proporcionada por @Robb
gb << On Close(
dist = dt << Distribution(Nominal Distribution(Column(:age)));
image = dist << Get Picture;
image << Save Picture($temp/age_dist.png, "png");
dist << Close Window();
);
Una cosa a considerar con esto es que cuando usa referencias a una tabla de datos (en este caso dt), si abre una nueva tabla antes de cerrar gb, lo más probable es que cierre la tabla incorrecta.
Puede ver este problema en este script de ejemplo:
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Bivariate(Y(:Weight), X(:Height), Nonpar Density);
biv << On Close(
close(dt, no save);
);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
Y este script proporciona una posible solución mediante el uso de Eval(EvalExpr()) y Expr() para obtener una referencia explícita a la tabla.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Bivariate(Y(:Weight), X(:Height), Nonpar Density);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
Eval(EvalExpr(
biv << On Close(
Close(Expr(biv << Get Data Table), no save)
);
));
También podrías usar la función con On Close, pero en este caso generará un código más complicado, ya que no tendrás acceso a la referencia de la plataforma bivariada sino a la ventana que tiene la bivariada, por lo que tendrás que analizar la ventana. nombre que podría funcionar o no (puede haber una manera de obtener una referencia a la plataforma dentro de la ventana).
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Bivariate(Y(:Weight), X(:Height), Nonpar Density);
biv << On Close(function({this},
table_name = Trim Whitespace(Word(1, (this << Get Window Title), "-"));
If(Contains(Get Data Table List() << get name, table_name),
Close(Datatable(table_name), no save);
);
));
Desafío C: hacer clic en un gráfico o informe debería desencadenar alguna acción
Concepto: Usar << Crear controlador de estado de fila()
</CODE></P>
<P>Esto tenía soluciones muy diferentes y todas eran un poco diferentes. <STRONG>El gran desafío con este tipo de secuencia de comandos es decidir cómo desea gestionar los estados de fila en constante cambio.</STRONG> Una opción es usar un botón para activar la acción (como<A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/15435" target="_blank"> @Ressel</A> did) en lugar de Row State Handler, esta es, en mi opinión, la opción más sólida en este caso.</P>
<P> </P>
<P>El resto de las soluciones utilizaron un controlador de estado de fila y diferentes formas (o no) de administrar las filas seleccionadas se cambiaron todo el tiempo. <STRONG>Una cosa a tener en cuenta con Row State Handler es que devolverá filas modificadas,</STRONG> no solo filas seleccionadas. Entonces, si solo estás interesado en columnas seleccionadas, debes tenerlo en cuenta.</P>
<P> </P>
<P>En la mayoría de los casos simples puedes usar algo como<A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/9474" target="_blank"> @Georg</A> dio como respuesta.</P>
<PRE><CODE class=" language-jsl">f = Function({a},
dt << Subset(Selected Rows(1), Selected columns only(0))
);
rs = dt << make row state handler(f);
Una opción para administrar las filas sería crear una matriz asociativa ( JMP permite usar Matrix como clave en una matriz asociativa ) en el que se recopilan las filas que ya tenían un subconjunto creado. Esto debería funcionar siempre y cuando no cambie el orden de las filas ni agregue o elimine filas.
A continuación se muestra un ejemplo rápido que utiliza una matriz asociativa para recopilar filas que se han subconjunto. En el ejemplo, estoy buscando filas que tengan el estado de fila 1 (fila seleccionada) y luego creo un subconjunto de ellas si aún no se ha creado. Un beneficio de esto es que también puede guardar las referencias de la tabla de datos en la matriz asociativa y acceder rápidamente a todas ellas con aa_subset_rows << Obtener valores; pero esta solución aún puede tener algunos errores si se seleccionan muchas líneas manteniendo presionado y arrastrando el mouse sobre ellas.
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)))
);
aa_subset_rows = Associative Array();
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(Contains(aa_subset_rows , cur_rows),
return();
);
dt_subset = dt << Subset(Output table("selected_rows"), Rows(cur_rows));
aa_subset_rows[cur_rows] = dt_subset;
);
rs = dt << make row state handler(f);
Re: 2022_Q1 MakeOverChallenge: Acción al hacer clic con el mouse de varias manerasDesafío C:
Definitivamente sugiero hacer cosas como esta con botones, ya que evita la creación de demasiados subconjuntos. Pero aquí seguí el desafío dado y agregué una verificación simple de que al menos no crearemos el mismo subconjunto dos veces.
Ver más...
Con Row State Handler no podemos acceder al evento de liberación del mouse, por lo que aún crearemos muchos subconjuntos si el usuario selecciona varias líneas una por una del gráfico (podría haber una manera de hacer esto con Mouse Box(), pero creo que usar el botón ser mucho más simple y fácil).
Re: 2022_Q1 MakeOverChallenge: Acción al hacer clic con el mouse de varias manerasDesafío B:
Ver más...
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
Nombres predeterminados aquí (1); // 2022_Q1 MakeOverChallenge: Acción al hacer clic con el mouse de varias maneras // Desafío B dt = Open("$SAMPLE_DATA/Big Class.jmp"); //Usa la expresión para hacer el script un poco más limpio SI esto se expandiera create_dist = Expr( dist = dt << Distribution(Nominal Distribution(Column(:age)), Histograms Only); wait(1); // add espere para que podamos ver que se crea la distribución dist << Guardar imagen("$TEMP/Big_Class_age_dist.png", png); dist << Cerrar ventana; ); gb = dt << Generador de gráficos (Tamaño (528, 454), Mostrar panel de control (0), Variables (X (: altura), Y (: peso)), Elementos (Puntos (X, Y, Leyenda (3)) , Línea de ajuste(X, Y, Leyenda(5))) ); gb << Al cerrar (create_dist); // Abrir("$TEMP/Big_Class_age_dist.png"); // descomentar para abrir la imagen
Re: 2022_Q1 MakeOverChallenge: Acción al hacer clic con el mouse de varias manerasDesafío A:
Principalmente código escrito JMP con Agregar propiedades de columna. También se agregó un ejemplo de cómo agregar y abrir URL.
Ver más...
Names Default To Here(1);
// Challenge A
path = "2022Q1_ChallengeA"; // path to images
{dtx} = Multiple File Import(
<<SET folder=""></SET>
Nombres predeterminados aquí (1); // Desafío A ruta = "2022Q1_ChallengeA"; // ruta a las imágenes {dtx} = Importación de archivos múltiples( <
Usando la variable de ruta SAMPLE_IMAGES (esto también funciona como un ejemplo de lo fácil que puede ser hacer cambios cuando estás creando una secuencia de comandos, simplemente cambiando una variable y la secuencia de comandos aún funciona (eliminé una URL de la lista para que no se agregue ninguna fila vacía a otras columnas). )):
Names Default To Here(1);
// Challenge A
path = Get Path Variable("$SAMPLE_IMAGES");
{dtx} = Multiple File Import(
<<SET folder=""></SET>
Re: 2022_Q1 MakeOverChallenge: Acción al hacer clic con el mouse de varias manerasDesafío C
Lamentablemente, poco más se podía hacer en lo que respecta a los desafíos A y B. Las soluciones aportadas me parecieron impecables. Por el contrario, sentí que todavía era posible realizar algunas mejoras en el desafío C. Algunas palabras sobre mi respuesta.
- Básicamente he robado el código necesario. de aquí ( @txnelson es, como muchos otros guionistas, una estrella de rock para mí)
- Modifiqué ligeramente el gráfico al incluir puntos de datos visibles, por lo que es más fácil seleccionar filas individuales.
- Después de seleccionar los puntos en el gráfico, la tabla de datos con el subconjunto no se abre inmediatamente. Esto se hace a través del botón agregado debajo del gráfico.
Vea a continuación el guión completo, incluido el gráfico modificado.
// 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: Acción al hacer clic con el mouse de varias manerasRETO A
Perdón por apresurarme con mi solución inicial... Aquí hay uno más limpio.
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: Acción al hacer clic con el mouse de varias manerasDESAFÍO A:
NOTA: Mantuve esta versión anterior porque algunas personas ya la habían visto, pero publiqué una solución más limpia como resultado. Responder a este.
No es una solución nada bonita, pero funciona... ¡Esperamos que aparezca uno más elegante!
Esto se agregará después del script de inicio:
// 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: Acción al hacer clic con el mouse de varias manerasRETO C
Con un cuadro de mouse no era posible seleccionar algo, así que cambié a un controlador de estado de fila
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: Acción al hacer clic con el mouse de varias manerasRETO C
Esta es mi respuesta, vea el guión completo a continuación.
La parte inferior agrega un controlador de estado de fila a la tabla, que desencadena la acción (ver ejemplo en Índice de secuencias de comandos).
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: Acción al hacer clic con el mouse de varias manerasRETO B
Agregue esto al final del 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 );
);