添加和删除图形脚本我编写了一个 JSL 例程,其中在相对复杂的动画序列期间将多个图形脚本添加到图形生成器或从图形生成器中删除。 需要添加和删除的脚本取决于正在分析的数据集,因此我必须编写很多类似以下内容的脚本(其中 gb 是我的 GraphBuilder 对象,myScript1 和 myScript2 都是我定义的表达式别处):
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 )} ));
我的问题是,我不知道应该删除哪些脚本,因为我是按编号引用它们的,并且每次删除脚本时,图形生成器分配给它们的编号都会发生变化。
我知道我应该可能能够将所有图形脚本组合成一个大脚本,其中控制通过 if-then-else 子句在各个部分之间切换,但可能有数十个,整个事情可能会变得非常混乱。
是否可以通过名称引用图形脚本? 本质上我希望能够做这样的事情:
report(gb) << dispatch( {}, "Graph Builder", FrameBox, {Remove Graphics Script( myScript2 )} );
上面的方法不起作用(显然,或者我不会有问题),但我想知道是否有类似的东西我错过了。
非常感谢您的任何建议。
回复:添加和删除图形脚本克雷格,
感谢您提供详细的示例。 编辑脚本示例应该对很多人有用。
然而,我专注于拥有一个描述标签该有多好,并且获取脚本的句柄将像下面一样简单
thisOne = rbiv_fb << Xpath( "//TopSeg[@description='bluepoly'] " );
也许是 JMP 15?
回复:添加和删除图形脚本我也喜欢@gzmorgan0第二种方法。 这是另一个想法,搜索脚本而不是维护列表。 在 JSL 脚本中,类似 0 的表达式;或“弗雷德”;不做任何事;它被评估并被丢弃。 所以像这样的图形脚本
"red"; fill color(...); circle(...);
可以在开头有一个标识符,稍后可以使用 arg( script, 1 ) 函数返回“red”来研究。
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 out删除三个实心圆,一个挖空
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 script使用自定义弹出菜单项查看脚本;这是编辑后的脚本
回复:添加和删除图形脚本嗨 - 这确实非常有帮助 - 特别是你描述的第二种方法,这是巧妙的。 说明 eval(substitute(expr(...))) 构造如何在我想要使用它们的上下文中工作的示例相当困难,因此我倾向于最终编写更具可读性的代码(至少对我来说)但智能脚本却少得多。 然而,在这种情况下,我显然需要一些更接近您的示例的东西,我将对其进行调整。
通常,在这种情况下,最重要的事情就是从一开始就确保在用重枪解决问题之前没有错过一个简单的技巧:)
非常感谢
回复:添加和删除图形脚本恭喜你或者正在写你的剧本。 从你的语法来看,我猜你对 JSL 还很陌生。
我有两个示例脚本可能会有所帮助。第一个使用脚本表达式引用(名称)。 添加脚本后,右键单击框架框并选择自定义。图形脚本的 JSL 不可见,只有 expr 引用。 这有效。 但是,如果您或用户记录该图表,则稍后会关闭该日记。如果您在新会话中打开日志,则不会定义这些表达式,也不会绘制图形。 如果图形脚本中没有变量冲突并且图形仅与当前会话相关,则此方法将起作用。 Xpath 用于查找框架框 TopSeq、用户添加的图形,在本例中仅查找脚本引用。
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 );第二种方法将脚本嵌入到框架框中。 添加脚本后,在框架框中右键单击并选择“自定义”,单击某个脚本即可查看两种方法的差异。 添加脚本后,将脚本名称插入到列表中。 删除脚本时,请将其从列表中删除。 该列表是对哪些脚本处于活动状态的动态统计,并且使用一个函数来定位其位置。
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");我同意您的愿望清单项目:向这些脚本(TopSegs)框架框添加描述/名称标签<<添加图形脚本(名称,脚本)绝对是一个很好的选择。