使用列表框更改时间序列图中多个变量的根名称嗨,我正在尝试让用户能够选择标签名称,并创建一个包含多个以该标签名称为根的变量的时间序列图。
但是,我正在努力研究如何动态更新它。
列表框包含标签列表,然后要绘制的变量将具有该标签名称,加上扩展名,本例中为 .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 获得的行为。