Ajout et suppression de scripts graphiquesJ'ai écrit une routine JSL dans laquelle plusieurs scripts graphiques sont ajoutés - et supprimés - du Graph Builder au cours d'une séquence d'animation relativement complexe. Les scripts qui doivent être ajoutés et supprimés dépendent de l'ensemble de données en cours d'analyse, donc je dois écrire beaucoup de choses comme ce qui suit (où gb est mon objet GraphBuilder, et myScript1 et myScript2 sont les deux expressions que j'ai définies autre part):
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 )} ));
Mon problème est que je perds la trace des scripts que je suis censé supprimer, car je m'y réfère par numéro - et les numéros qui leur sont attribués par le Graph Builder changent à chaque fois qu'un script est supprimé.
je sais que je devrait être potentiellement capable de combiner tous les scripts graphiques en un seul grand script dans lequel le contrôle est commuté entre les différentes sections par des clauses if-then-else, mais il y en a potentiellement des dizaines et le tout deviendrait probablement très désordonné.
Est-il possible de se référer aux scripts graphiques par leur nom ? En gros, je veux pouvoir faire quelque chose comme ça :
report(gb) << dispatch( {}, "Graph Builder", FrameBox, {Remove Graphics Script( myScript2 )} );
Ce qui précède ne fonctionne pas (évidemment, sinon je n'aurais pas de problème), mais je me demande s'il y a quelque chose de similaire que j'ai manqué.
Merci beaucoup pour toute suggestion.
Re : Ajouter et supprimer des scripts graphiquesCraige,
Merci pour l'exemple détaillé. L'exemple de script d'édition devrait être utile à beaucoup.
Cependant, je me concentre sur la façon dont il serait agréable d'avoir une balise de description et obtenir une poignée pour le script serait aussi simple que
thisOne = rbiv_fb << Xpath( "//TopSeg[@description='bluepoly'] ");
Peut-être JMP 15 ?
Re : Ajouter et supprimer des scripts graphiquesJ'aime aussi @gzmorgan0 2ème approche. Voici une autre idée qui recherche le script plutôt que de maintenir une liste. Dans un script JSL, une expression comme 0 ; ou "Fred" ; ne fait rien; il est évalué et jeté. Ainsi, un script graphique comme
"red"; fill color(...); circle(...);
peut avoir un identifiant au début qui pourra être étudié plus tard, en utilisant la fonction arg( script, 1 ) pour récupérer "rouge".
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 outTrois cercles remplis supprimés et un évidé
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 scriptUtilisez l'élément de menu contextuel de personnalisation pour voir les scripts ; c'est le script édité
Re : Ajouter et supprimer des scripts graphiquesSalut - c'est très utile - en particulier la deuxième méthode que vous décrivez, qui est ingénieuse. Les exemples qui illustrent le fonctionnement des constructions eval(substitute(expr(...))) dans le contexte où je voudrais les utiliser sont plutôt difficiles à trouver, donc j'ai tendance à finir par écrire plus lisible (au moins pour moi) mais des scripts beaucoup moins intelligents. Cependant, dans ce cas, je vais évidemment avoir besoin de quelque chose de beaucoup plus proche de votre exemple, que je vais adapter.
Souvent, la chose la plus importante dans des situations comme celle-ci est simplement de s'assurer au départ qu'une simple astuce n'a pas été manquée avant de tourner les armes lourdes sur le problème 
Merci beaucoup
Re : Ajouter et supprimer des scripts graphiquesFélicitations ou écriture de votre script. D'après votre syntaxe, je suppose que vous êtes assez nouveau pour JSL.
J'ai 2 exemples de scripts qui pourraient aider.La première utilise l'expression de script reference(name). Après avoir ajouté vos scripts, cliquez avec le bouton droit sur la framebox et sélectionnez personnaliser.Le JSL de votre script graphique n'est pas visible, seule la référence expr. Cela marche. Toutefois, si vous ou l'utilisateur journalisez le graphique, fermez le journal ultérieurement.Si vous ouvrez le journal dans une nouvelle session, ces expressions ne sont pas défnies et les graphiques ne seront pas dessinés. Cette méthode fonctionnera s'il n'y a pas de collisions de variables dans vos scripts graphiques et si le graphique n'est pertinent que dans la session en cours. Xpath est utilisé pour trouver la framebox TopSeq, les graphiques ajoutés par l'utilisateur, et dans ce cas uniquement la référence du 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 );Cette deuxième méthode intègre le script dans la framebox. Une fois les scripts ajoutés, faites un clic droit dans la framebox et sélectionnez personnaliser, cliquez sur un script pour voir la différence entre les deux méthodes. Après avoir ajouté un script, insérez dans une liste le nom du script. Et lors de la suppression d'un script, supprimez-le de la liste. La liste est une comptabilisation dynamique des scripts actifs et une fonction est utilisée pour localiser sa position.
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");Je suis d'accord avec l'élément de votre liste de souhaits : ajoutez une balise Description/Nom à ces scripts (TopSegs) framebox << Ajouter un script graphique (nom, script) est un avantage certain.