使用列錶框更改時間序列圖中多個變量的根名稱嗨,我正在嘗試讓用戶能夠選擇標籤名稱,並創建一個包含多個以該標籤名稱為根的變量的時間序列圖。
但是,我正在努力研究如何動態更新它。
列錶框包含標籤列表,然後要繪製的變量將具有該標籤名稱,加上擴展名,本例中為 .PV、.ETARG 等。

我解析以下語句以生成變量名稱
vars = {};
str = "Variables(
X( :Time ),
Y( :" || TAG || ".ETARG, Position (1) ),
Y( :" || TAG || ".LO, Position( 1 ) ),
Y( :" || TAG || ".PV, Position( 1 ) ),
Y( :" || TAG || ".UP, Position( 1 ) )
)";
vars = parse(str);然後圖形構建器引用這些,而不是有固定的標籤來繪製
Eval Expr(
DataTable1<<GRAPH builder=""></GRAPH>
我有一個列錶框,用戶可以在其中選擇變量的根名稱
ChooseET = List Box( ( ET_TAG_LIST ),
maxSelected( 1 ),
onChange(
TAG = ChooseET << Get Selected;但是圖形生成器中的變量名稱是靜態的。 我如何使這個動態? 我試過使列錶框成為圖形生成器中的表達式,但這不起作用。
列錶框和圖形生成器位於分配語句中。 我不確定這是什麼以及它有多重要。
在此先感謝,這是完整的代碼!
JMP App(
Set Name( "Application" ),
Set Description(
"An empty workspace for creating custom applications with one or more windows and scripts"
),
Auto Launch( 1 ),
Snap To Grid( 1 ),
Show Grid( 1 ),
Show Properties( 1 ),
Show Sources( 1 ),
Group By Category( 1 ),
Dashboard Mode( 0 ),
Parameters,
Tables(
DataTable1 = GuiTable(
Set Path( "" ),
Set Label( "Output Table" ),
Set Location( "Current Data Table" ),
Set Invisible( 0 )
)
),
Script(JSL Quote(// This script is executed when the application is run.
// Named objects have been created for the application modules
// (for example, "Module1") and the pre-defined object
// "thisApplication" refers to the application object itself.
// Variables and functions declared here are scoped to the
// Application namespace.
dt = Current data table();
ETSelected = "A04004DD";
TAG = ETSelected;;
vars = {};
str = "Variables(
X( :Time ),
Y( :" || TAG || ".ETARG, Position (1) ),
Y( :" || TAG || ".LO, Position( 1 ) ),
Y( :" || TAG || ".PV, Position( 1 ) ),
Y( :" || TAG || ".UP, Position( 1 ) )
)";
vars = parse(str);
show(vars);
PDChartproperties = "
{Legend Model(
3,
Properties( 0, {Line Color( 4 )}, Item ID( \!"" || TAG ||".ETarg\!", 1 ) ),
Properties( 1, {Line Color( 19 ), Marker Size( 1 )}, Item ID( \!"" || TAG ||".LO\!", 1 ) ),
Properties( 2, {Line Color( 53 )}, Item ID( \!"" || TAG ||".PV\!", 1 ) ),
Properties( 3, {Line Color( 19 ), Marker Size( 1 )},Item ID( \!"" || TAG ||".UP\!", 1 )
)
)}
";
props = parse(PDChartproperties);
show(props);
dt = Current Data Table();
ET_LIST = {};
ET_TAG_List = {};
For( i = N Col( dt ), i >= 1, i--,
ET_col = Column (dt, i) << Get Name ();
If(
(Col N Missing( Column( i ) ) / N Row()) != 1 &
Contains (ET_col, "ETarg"),
Insert Into(ET_LIST, ET_col);
);
);
Show (ET_LIST);
n = N Items( ET_LIST );
For( i = 1, i <= n, i++,
ETARG = ET_LIST[i] ;
NFull = Length(ETARG) ;
ETTAG = Left(ETARG,(NFull-6)) ;
Insert Into(ET_TAG_List, ETTAG);
);
Show(ET_TAG_List);
) ),
Allocate(
Module1 = Plan(
PreAllocate,
Script(JSL Quote(// This script is executed when a new module instance is
// created. The pre-defined object "thisModuleInstance" refers
// to the instance object, but other objects such as boxes and
// scripts have not yet been created. Variables declared here are
// scoped to the ModuleInstance namespace.
// This special function will receive parameters passed to CreateInstance()
OnModuleLoad({},
);
thisModuleInstance << Create Objects;
// After this point your module instance objects have been created
// and can be referred to by name (for example, "Button1").
ColList1Select=Function({this},{selectedIndices},
// This function is called when the List Box selection changes
selectedIndices = this << Get Selected Indices;
);
) ),
Allocate(
DataFilterContext1 = Data Filter Context Box();
Lineup2 = Lineup Box();
Report3 = Platform(
DataTable1,
Distribution(
Continuous Distribution(
Column( :A04004DD ET_DELTA Ratio )
),
SendToReport(
Dispatch(
{"A04004DD ET_DELTA Ratio"},
"1",
ScaleBox,
{Min( -5 ), Max( 5 ), Inc( 0.1 ), Minor Ticks( 0 )}
),
Dispatch(
{"A04004DD ET_DELTA Ratio"},
"Quantiles",
OutlineBox,
{Close( 1 )}
),
Dispatch(
{"A04004DD ET_DELTA Ratio"},
"Summary Statistics",
OutlineBox,
{Close( 1 )}
)
)
)
);
Report1 = Platform(
DataTable1,
Graph builder(
Size( 430, 370 ),
Show Control Panel( 0 ),
Fit to Window( "Maintain Aspect Ratio" ),
Variables(
X( :Time ),
Y( :ZZ ET Metric ),
Y( :A04004DD ET_Pass, Position( 1 ) ),
Y( :A04004DD ET_Pass Ave, Position( 1 ) )
),
Elements( Points( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 3 ) ) ),
SendToReport(
Dispatch(
{},
"Time",
ScaleBox,
{Min( 3675484152 ), Max( 3676021620 ),
Interval( "Day" ), Inc( 5 ), Minor Ticks( 0 )}
)
)
)
);
ChooseET = List Box( ( ET_TAG_LIST ),
maxSelected( 1 ),
onChange(
TAG = ChooseET << Get Selected;
If( N Items( TAG ) != 0,
Show( TAG );
);
) );
DataFilter1 = DataTable1 << Data Filter(
Local,
Add Filter(
columns( :Day ),
Display( :Day, Size( 0, 0 ), Height( 0 ) )
)
);
Report2 = Platform(
DataTable1,
gb = Eval(
Eval Expr(
DataTable1<<GRAPH builder=""></GRAPH>圖形腳本回复:使用列錶框更改時間序列圖中多個變量的根名稱實際上,我解決了這個問題,添加了另一個 vlist 框並在 onchange( 腳本中將分佈附加到它。
感謝您的建議!
回复:使用列錶框更改時間序列圖中多個變量的根名稱嗨,非常感謝,這澄清了一些事情,我已經投資了這本書。
我最初以圖形方式構建應用程序,我認為 Distribution 嵌套在 lineup2 中,但在 Organize(reparent (Lineup2(ChooseET)) 語句中定義。
當我運行我的腳本時,它幾乎完成了我想要的一切,刪除了舊的分發版“onchange”,但它在儀表板/應用程序之外創建了一個新的分發版,而不是嵌套在 Lineup 框中。
我附上了完整的腳本。 如果有任何進一步的見解,我將不勝感激,我找不到有關 reparent/allocate 命令的任何參考資料。</CODE></P></LINGO-BODY><LINGO-SUB id="lingo-sub-277091" slang="en-US">回复:使用列錶框更改時間序列圖中多個變量的根名稱</LINGO-SUB><LINGO-BODY id="lingo-body-277091" slang="en-US"><P><A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/18907" target="_blank">@spudton</A> ,</P>
<P> </P>
<P>適用於一個 JMP 平台的消息可能不適用於其他平台。 GraphBuilder 平台允許用戶通過 UI 拖放以添加和刪除變量。 因此,JSL 對 GraphBuilderBox 實施了 Add Variable() 和 Remove Variable()。</P>
<P> </P>
<P>Distribution 沒有這樣的接口,所以沒有添加和刪除變量的方法。幫助菜單下的 JMP 腳本索引將顯示平台可用的大部分(如果不是全部)消息。主菜單 > 幫助 > 腳本索引 > 對象(左上角字段)> 分佈。</P>
<P> </P>
<P>您會發現通常有不止一種方法可以使用 JSL 做某事。幾個選項是:</P>
<P><STRONG>選項</STRONG>:將您的分發平台更改為創建分發的 GraphBuilder。 它不會有相同的選項或看起來相同。 但是您可以添加和刪除變量</P>
<PRE><CODE class=" language-jsl">gbdist =Graph Builder(
Size( 534, 456 ),
Show Control Panel( 0 ),
Variables( Y( :A04004DD ET_DELTA Ratio ) ),
Elements( Histogram( Y, Legend( 3 ), Counts( 1 ) ) )
);
選項:使用容器進行分發。 你需要在你的顯示中有一個佔位符。 然後在更改變量時,刪除該容器中現有的 Distribution,然後添加一個新的。 回想一下,我說過您的代碼中有一些項目需要清理。 我沒有清理所有這些。
該代碼有一個空容器 Lineup2。 如果您製作 Report3,則嵌套在該框內。 實際上,我會將其更改為 VListBox,因為您沒有使用 LineupBox 的強大功能。
Lineup2 = Lineup Box();
Report3 = Platform(
DataTable1,
Distribution(
Continuous Distribution(
Column( :A04004DD ET_DELTA Ratio )
),
下面是腳本的一部分7_InteractiveDisplays.jsl寫給JMP 腳本語言的 JSL 配套應用,第 2 版.
clear globals();
orig_dt = Open( "$SAMPLE_DATA/Fitness.jmp" );
cnt = 0; Chosen Columns={}; //initiate values
//----Refresh display script---------------------------
refresh_script = Expr(
Try(dist_vlist << delete);
If( (cnt > 0 & N Items( Chosen Columns ) >= 1),
show(Chosen Columns);
dist_vlist = VListBox(
orig_dist = orig_dt << Distribution( Column( Eval( Chosen Columns ) ), invisible )
); //end VListBox
result_ob << append( dist_vlist );
) //end If
); //end Expr
//----Action to take for Add-----------------------------
add_script = Expr(
cnt = cnt + 1;
listocols << Append( selcol << Get Selected );
);
//----Action to take for Remove -----------------------------
remove_script= Expr(
cnt = cnt + 1;
listocols << Remove Selected;
);
//_______________________________________________________________________________
//-----Dialog Window layout---------------------------------
dist_win = New Window( "Create Distributions",
H List Box(
selcol = Col List Box( All, width( 100 ), nlines( 6 ) ),
Lineup Box( N Col( 1 ), Spacing( 3 ),
Button Box( "Add Column >>", add_script ),
Button Box( "<< Remove Column", remove_script )
),
// listocols is a Col List Box
listocols = Col List Box( width( 100 ), nlines( 6 ),
OnChange( Chosen Columns = listocols << Get Items;
refresh_script;)
) //end listocols
), //end HListBox
Text Box( " " ),
result_ob = Outline Box( "Current Selections" )
);
我知道您可能正在完成一項有截止日期的任務。 但是試試這個腳本。 它提供了我在本次討論的帖子中提到的幾個功能的示例。 它提供瞭如何添加和刪除發行版,第二個選項。
祝你好運!
回复:使用列錶框更改時間序列圖中多個變量的根名稱太好了,謝謝。
我已經用我的第二個時間序列圖重複了語法並且效果很好。
當 TAG 名稱更改時,我無法計算出更改分發框中列的語法。
這應該適用於 Distribution 對象嗎?
Eval( Eval Expr( Dstr3 << Remove Variable( {Expr( Column( dt, curr_TAG || " ET_DELTA Ratio" ) )} ) ) );
我附上了完整的腳本。
再次感謝您的幫助。 快陷進去了!
回复:使用列錶框更改時間序列圖中多個變量的根名稱@spudton ,
我在我的電腦上附上了在你的桌子上運行的腳本。
您收到的錯誤可能是您沒有使用 JSL
curr_TAG = TAG[1];
TAG 是 ListBox << get selected 的結果;返回一個列表,你必須得到列表中的第一項。
哦,另一個問題是我生成的表使用了擴展名 ETARG。您在 cahnge ETARG 中彈出的代碼到 ETarg 這可能是另一個錯誤來源。
該腳本有一個註釋行 show(curr_TAG) 。 取消註釋並查看日誌。
請注意,您會看到幾行被註釋掉了。 我在昨天生成的表中編了一些變量來測試它。
回复:使用列錶框更改時間序列圖中多個變量的根名稱您好,再次感謝。 我附上了一個表格,其中包含所有帶有一些數據的列。
一旦我對如何執行此操作有了明確的方法,我將刪除硬編碼語句並按照您的建議進行一些內務處理。
我輸入了您的代碼,但收到錯誤消息“jsl 參數應該是‘Concat’的訪問或評估中的字符”
問候
韋恩
回复:使用列錶框更改時間序列圖中多個變量的根名稱@spudton
我看了你的代碼。該腳本具有第二個 GraphBuilder 的句柄。我不得不做一些改變,因為我沒有數據表可以使用。
您的代碼有幾個硬編碼元素,我建議您刪除,例如
- 發送至報表 X 軸日期範圍
- 發送到報告圖例項(或者您需要維護它們)
看來您已經對起始 TAG 進行了硬編碼。所以我將起始 curr_TAG 設置為該值。下面我展示了要刪除的 JSL,將變量添加到 GraphBuilderBox。 我認為在 gb 周圍有一個容器可能更優雅,並且在更改時刪除 gb 然後添加一個新的 gb。
幾條評論你確定數據表總是有 PV、LO、UP 列嗎?這是你需要檢查的東西嗎?
如前所述,有多種方法可以達到相同的結果。祝你好運!
curr_TAG = "A04004DD";
ChooseET = List Box( ( ET_TAG_LIST ),
maxSelected( 1 ),
onChange(
TAG = ChooseET << Get Selected;
If( N Items( TAG ) != 0,
Show( TAG );
gbb2 = Report(gb)[GraphBuilderBox(1)];
Eval( EvalExpr(gbb2 << Remove Variable({Expr(column(dt,curr_TAG||".ETARG")), Role("Y"), Position(1)} );
gbb2 << Remove Variable({Expr(column(dt,curr_TAG||".LO")), Role("Y"), Position(1)} );
gbb2 << Remove Variable({Expr(column(dt,curr_TAG||".PV")), Role("Y"), Position(1)} );
gbb2 << Remove Variable({Expr(column(dt,curr_TAG||".UP")), Role("Y"), Position(1)} );
));
curr_TAG = TAG[1];
//show(curr_TAG);
wait(0);
Eval( EvalExpr(gbb2 << Add Variable({Expr(column(dt,curr_TAG||".ETARG")), Role("Y"), Position(1)} );
gbb2 << Add Variable({Expr(column(dt,curr_TAG||".LO")), Role("Y"), Position(1)} );
gbb2 << Add Variable({Expr(column(dt,curr_TAG||".PV")), Role("Y"), Position(1)} );
gbb2 << Add Variable({Expr(column(dt,curr_TAG||".UP")), Role("Y"), Position(1)} );
));
);
);
) ;
回复:使用列錶框更改時間序列圖中多個變量的根名稱@spudton ,
下面是一個帶有列錶框的應用程序的屏幕截圖,用戶選擇一個變量然後報告發生變化。 在此示例中,所有圖形都是預製的(請參閱選項卡),選擇上的操作是更改可見選項卡。 您的選擇操作將是刪除當前的“標籤”並添加新標籤,我想這將通過使用消息來刪除和添加變量到您的第二個 GraphBuilderBox 來完成。

如果您將應用程序從 << 運行更改為 << 編輯,
您應該會看到 ApplicationBuilder UI。 列錶框 (cart_lb) 突出顯示,紅色輪廓顯示在何處添加函數/腳本,以便在進行選擇時執行 trh 操作

這是此應用程序的列錶框的腳本
Local({idx, nme, tList},
tlist = (cart_lb << get selected);
if(nitems(tlist) >0,
nme = tlist[1];
//show(nme);
idx = var_tabs << index of tab(nme);
var_tabs << set selected(idx);
//show(idx);
); //end if
); //end Local
如該應用程序所述,我得到了列表的索引。 選項卡與列表對齊,因此一旦知道索引,就會顯示關聯的選項卡。
不知道你是否命名了第二個 GraphBuilder 顯示,我無法幫助腳本。 我沒有嘗試過您的應用程序,因為我沒有包含預期列名的數據表。
也許這對您來說並不新鮮。只是想給你一些線索,以防萬一。
回复:使用列錶框更改時間序列圖中多個變量的根名稱感謝您的回复。
我不希望用戶必須選擇多個標籤。 我希望他們從列表中選擇一項,然後應用程序顯示多列的時間序列圖,所有列都以該標籤作為名稱的根。
所以選擇TAG ABC123,時間序列會顯示ABC123.ETARG、ABC123.UP、ABC123.LO和ABC123.PV
回复:使用列錶框更改時間序列圖中多個變量的根名稱@spudton ,
有多種方法可以做到這一點。 您選擇哪種方法取決於您對 UI 的預期操作。
用戶可以在您的列表中選擇 1 個項目,然後使用控件,選擇其他項目,並保持 shift 可能是一個範圍,然後刪除一些。 我的意思是你希望報告隨著每次選擇而更新,或者添加一個按鈕,所以一旦選擇,用戶按下 Go 或 Rerun 或 Do It 按鈕來重做分析。
關於報告 GraphBuilder,您可以在 Graph Builder Box 中添加和刪除變量。或者您可以添加 Exclude 的本地過濾器,其 Visibility 為 collapse 以捕獲除用戶選擇之外的所有內容。 這些可能是選項而不是 Eval Expr。在編寫 JSL Companion 2nd Edition 時,沒有使用 GraphBuilderBox。
我建議您使用過濾器製作圖表並嘗試不同的選項,以了解其工作原理。
就個人而言,除非用戶只能進行一次選擇,否則我喜歡在可以進行多項選擇的情況下使用按鈕來啟動任務。
我沒有仔細閱讀您的代碼,但您可以使用窗口名稱空間可能是 window:GraphBuilderBox(2) 來引用顯示框或建立類似 (this<< parent) 等的關係。
因此,有多種選擇可以實現您想要的效果,這取決於報告的當前樹結構和您希望從 UI 獲得的行為。