添加和刪除圖形腳本我編寫了一個 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)框架框添加描述/名稱標籤<<添加圖形腳本(名稱,腳本)絕對是一個很好的選擇。