Adición y eliminación de secuencias de comandos de gráficosHe escrito una rutina JSL en la que se agregan y eliminan varias secuencias de comandos de gráficos del Graph Builder durante una secuencia de animación relativamente compleja. Las secuencias de comandos que deben agregarse y eliminarse dependen del conjunto de datos que se analiza, por lo que tengo que crear muchas secuencias de comandos como las siguientes (donde gb es mi objeto GraphBuilder y myScript1 y myScript2 son expresiones que he definido en otra parte):
If( k == 5, Report( gb ) << dispatch( {}, "Graph Builder", FrameBox, {Add Graphics Script( 1, Description( "Script" ), myScript1 )} ));
If( k == 10, Report( gb ) << dispatch( {}, "Graph Builder", FrameBox, {Remove Graphics Script( 2 )} ));
If( k == 15, Report( gb ) << dispatch( {}, "Graph Builder", FrameBox, {Add Graphics Script( 1, Description( "Script" ), myScript2 )} ));
Mi problema es que pierdo la noción de qué secuencias de comandos se supone que debo eliminar, porque me refiero a ellas por número, y los números que les asigna Graph Builder cambian cada vez que se elimina una secuencia de comandos.
Sé que yo debería potencialmente podría combinar todas las secuencias de comandos de gráficos en una sola secuencia de comandos grande en la que el control se cambia entre las distintas secciones mediante cláusulas if-then-else, pero potencialmente hay docenas de ellas y todo probablemente se complicaría mucho.
¿Es posible referirse a scripts de gráficos por su nombre? Esencialmente quiero ser capaz de hacer algo como esto:
report(gb) << dispatch( {}, "Graph Builder", FrameBox, {Remove Graphics Script( myScript2 )} );
Lo anterior no funciona (obviamente, o no tendría ningún problema), pero me pregunto si hay algo similar que me haya perdido.
Muchas gracias por las sugerencias.
Re: Adición y eliminación de secuencias de comandos de gráficoscraig,
Gracias por el ejemplo detallado. El ejemplo de script de edición debería ser útil para muchos.
Sin embargo, me estoy fijando en lo bueno que sería tener una etiqueta de descripción y manejar el script sería tan simple como
thisOne = rbiv_fb << Xpath( "//TopSeg[@description='bluepoly'] " );
¿Quizás JMP 15?
Re: Adición y eliminación de secuencias de comandos de gráficostambién me gusta @gzmorgan0 2do enfoque. Aquí hay otra idea que busca el script en lugar de mantener una lista. En un script JSL, una expresión como 0; o "fredo"; no hace nada; se evalúa y se desecha. Entonces, un script de gráficos como
"red"; fill color(...); circle(...);
puede tener un identificador al principio que se puede estudiar más tarde, usando la función arg( script, 1 ) para volver a "rojo".
dt = Open( "$sample_data/big class.jmp" );
gb = dt << Graph Builder(
Size( 525, 452 ),
Show Control Panel( 0 ),
Variables( X( :weight ), Y( :height ) ),
Elements( Points( X, Y, Legend( 6 ) ) )
);
colors = {"red", "green", "blue", "yellow", "cyan", "magenta", "orange", "purple", "gray"};
For( i = 1, i <= N Items( colors ), i++,
Eval( // the "i" variable needs to be cast-in-stone so it will not be needed if the graph
Eval Expr( // is saved in a journal. EvalExpr will pre-eval the expr() below...
(Report( gb )[framebox( 1 )]) << addGraphicsScript(
1,
Expr( colors[i] ); // this will be the identifier for the script
Fill Color( Expr( colors[i] ) ); // pre-eval the color name, not just the subscript
Circle( {80 + 5 * Expr( i ), 50 + 2 * Expr( i )}, 1, "FILL" );
)
)
)
);
findSegById = Function( {frame, id}, // locate a graphics script by an id string
{child = frame << childSeg, script}, // the frame has a list of graphics scripts
While( !Is Empty( child ),
If( child << className == "TopSeg", // TopSeg is the className of a graphics script
script = child << getscript; // check the script to see if the first
If( Arg( script, 1 ) == id, // statement is the id name
Return( child )
);
);
child = child << sib;
);
Return( child ); // empty, not found
);
Wait( 1 );
thisOne = findSegById( Report( gb )[framebox( 1 )], colors[5] ); // the cyan script
thisOne << delete;
Wait( 1 );
thisOne = findSegById( Report( gb )[framebox( 1 )], "green" );
thisOne << delete;
Wait( 1 );
thisOne = findSegById( Report( gb )[framebox( 1 )], colors[9] ); // the gray script
thisOne << delete;
Wait( 1 );
// if needed, you can retrieve, edit, and replace the script
thisOne = findSegById( Report( gb )[framebox( 1 )], "blue" );
oldScript = thisOne << getscript;
newScript = Substitute( Name Expr( oldScript ), "FILL", Empty() ); // hollow black outline remains
Eval( Eval Expr( thisOne << setscript( Expr( Name Expr( newscript ) ) ) ) );
// gb << inval;
Print( If( Is Empty( findSegById( Report( gb )[framebox( 1 )], "argyle" ) ), "Good", "Bad" ) );
Three filled circles removed and one hollowed outThree filled circles removed and one hollowed outTres círculos rellenos eliminados y uno ahuecado
Use the customize popup menu item to see the scripts; this is the edited scriptUse the customize popup menu item to see the scripts; this is the edited scriptUse el elemento del menú emergente personalizar para ver los scripts; este es el guion editado
Re: Adición y eliminación de secuencias de comandos de gráficosHola, eso es muy útil, especialmente el segundo método que describe, que es ingenioso. Los ejemplos que ilustran cómo funcionan las construcciones eval(substitute(expr(...))) en el contexto en el que me gustaría usarlas son bastante difíciles de encontrar, por lo que tiendo a terminar escribiendo más legible (al menos para mí) pero mucho menos guiones inteligentes. Sin embargo, en este caso, evidentemente, voy a necesitar algo mucho más parecido a su ejemplo, que adaptaré.
A menudo, lo más importante en situaciones como esta es asegurarse desde el principio de que no se ha perdido un truco simple antes de convertir las armas pesadas en el problema 
Muchas gracias
Re: Adición y eliminación de secuencias de comandos de gráficosEnhorabuena o escribiendo tu guión. Por su sintaxis, supongo que es bastante nuevo en JSL.
Tengo 2 scripts de ejemplo que podrían ayudar.El primero usa la referencia de expresión de script (nombre). Después de agregar sus scripts, haga clic con el botón derecho en el marco y seleccione personalizar.El JSL para su secuencia de comandos de gráficos no está visible, solo la referencia expr. Esto funciona. Sin embargo, si usted o el usuario registran el gráfico en diario, luego cierran el diario.Si abre el diario en una nueva sesión, esas expresiones no se defnen y los gráficos no se dibujarán. Este método funcionará si no hay colisiones de variables en sus secuencias de comandos de gráficos y el gráfico solo es relevante en la sesión actual. Xpath se utiliza para encontrar el marco TopSeq, los gráficos agregados por el usuario y, en este caso, solo la referencia del script.
Names Default To Here( 1 );
Open( "$SAMPLE_DATA/Big Class.jmp" );
orangepoly = Expr( Transparency( 0.5 );
Fill Color( {1.0, 0.5, 0.0} );
Polygon( [60, 72, 57], [75, 120, 120] );
);
bluepoly = Expr(
Transparency( 0.5 );
Fill Color( {0.0, 0.5, 1.0} );
Polygon( [60, 72, 57], [150, 120, 120] );
);
biv = Bivariate( Y( :weight ), X( :height ), FitLine );
rbiv = biv << report;
rbiv_fb = rbiv[frame box( 1 )];
rbiv_fb << Add Graphics Script(orangepoly);
rbiv_fb << Add Graphics Script(bluepoly);
//right click on the framebox and select Customize
/*just the expr reference is visible
If this graph is journaled, the journal is closed and reopened the graphics from the script
will not appear. look up Freeze All for the journal. */
glist = (rbiv_fb << XPath("//TopSeg")) << get script;
idx = contains(glist, expr(bluepoly));
Wait( 3 );
rbiv_fb << Remove Graphics Script( idx );Este segundo método incrusta el script en el cuadro de marco. Después de agregar las secuencias de comandos, haga clic con el botón derecho en el marco y seleccione personalizar, haga clic en una secuencia de comandos para ver la diferencia entre los dos métodos. Después de agregar una secuencia de comandos, inserte en una lista el nombre de la secuencia de comandos. Y cuando elimine un script, elimínelo de la lista. La lista es una contabilidad dinámica de qué scripts están activos y se utiliza una función para ubicar su posición.
Names Default To Here( 1 );
Open( "$SAMPLE_DATA/Big Class.jmp" );
glist={};
orangepoly = Expr(
Transparency( 0.5 );
Fill Color( {1.0, 0.5, 0.0} );
Polygon( [60, 72, 57], [75, 120, 120] );
);
bluepoly = Expr(
Transparency( 0.5 );
Fill Color( {0.0, 0.5, 1.0} );
Polygon( [60, 72, 57], [150, 120, 120] );
);
addgraph = Function({gnme}, {gexpr}, //"orangepoly")
Eval(Parse("gexpr = NameExpr("||gnme||")" ) );
Eval(Substitute(Expr(rbiv_fb << Add Graphics Script(_xxx)), Expr(_xxx), NameExpr(gexpr) ) );
insert into(glist, gnme );
); //end addgraph
rmvgraph = Function({gnme}, {idx},
idx = contains(glist, gnme);
if(idx>0,
rbiv_fb << Remove Graphics Script(idx);
removefrom(glist, idx)
);
); //end rmvgrph
biv = Bivariate( Y( :weight ), X( :height ), FitLine );
rbiv = biv << report;
rbiv_fb = rbiv[frame box( 1 )];
addgraph("orangepoly");
addgraph("bluepoly");
//right click on the framebox and select Customize
//the actual script is embedded
Wait( 3 );
rmvgraph("bluepoly");Estoy de acuerdo con el elemento de su lista de deseos: agregue una etiqueta de Descripción/Nombre a estos scripts (TopSegs) framebox << Agregar script de gráficos (nombre, script) es definitivamente agradable de tener.