使用列表框更改时间序列图中多个变量的根名称您好,我试图让用户能够选择标签名称,并创建以该标签名称作为根的多个变量的时间序列图。
然而,我正在努力解决如何动态更新它。
列表框包含标签列表,然后要绘制的变量将具有该标签名称,加上扩展名,在此示例中为 .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 嵌套在erieline2中,但在Organize(reparent (Lineup2(ChooseET))语句中定义。
当我运行我的脚本时,它几乎执行了我想要的所有操作,删除了旧的发行版“onchange”,但它在仪表板/应用程序之外创建了一个新的发行版,而不是嵌套在阵容框中。
我已附上完整的脚本。 希望有任何进一步的见解,我找不到有关 reparent/allocate 命令的任何参考资料。</CODE></P></LINGO-BODY><LINGO-SUB id="lingo-sub-277091" slang="en-US" mode="NONE">回复:使用列表框更改时间序列图中多个变量的根名称</LINGO-SUB><LINGO-BODY id="lingo-body-277091" slang="en-US" mode="NONE"><P><A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/18907" target="_blank">@斯普顿</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 ) ) )
);
选项:使用容器进行分发。 您需要在显示中为其设置一个占位符。 然后,当更改变量时,您可以删除该容器中的现有分布,然后添加一个新分布。 回想一下,我说过你的代码中有一些需要清理的项目。 我没有把它们全部清理干净。
该代码有一个空容器 Lineup2。 如果您制作Report3,则嵌套在该框中。 实际上,我会将其更改为 VListBox,因为您没有使用 LineupBox 的功能。
Lineup2 = Lineup Box();
Report3 = Platform(
DataTable1,
Distribution(
Continuous Distribution(
Column( :A04004DD ET_DELTA Ratio )
),
以下是脚本的一部分7_InteractiveDisplays.jsl写给JMP 脚本语言的 JSL 配套应用程序,第二版。
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" )
);
我知道您可能正在完成一项有截止日期的任务。 但试试这个脚本。 它提供了我在本次讨论的帖子中提到的几个功能的示例。 它提供了如何添加和删除发行版,即第二个选项。
祝你好运!
回复:使用列表框更改时间序列图中多个变量的根名称太好了,谢谢。
我已经用第二个时间序列图重复了该语法,效果很好。
我无法计算出在更改标签名称时更改分配框中的列的语法。
这应该适用于 Distribution 对象吗?
Eval( Eval Expr( Dstr3 << Remove Variable( {Expr( Column( dt, curr_TAG || " ET_DELTA Ratio" ) )} ) ) );
我已附上完整的脚本。
再次感谢您的帮助。 快要陷进去了!
回复:使用列表框更改时间序列图中多个变量的根名称@斯普顿,
我附上了在我的电脑上在您的桌子上运行的脚本。
您遇到的错误可能是您没有使用 JSL
curr_TAG = TAG[1];
TAG 是 ListBox << 被选中的结果;返回一个列表,您必须获取列表中的第一项。
哦,另一个问题是我生成的表使用了扩展名 ETARG。您在 cahnge ETARG to ETarg 中弹出的代码可能是另一个错误来源。
该脚本有一个注释行 show(curr_TAG) 。 取消注释并查看日志。
请注意,您将看到几行被注释掉。 我在昨天生成的表中编写了一些变量来测试它。
回复:使用列表框更改时间序列图中多个变量的根名称你好,再次感谢。 我附上了一个表,其中包含带有一些数据的所有列。
一旦我有了关于如何执行此操作的明确方法,我将删除硬编码的语句并按照您的建议进行一些内务处理。
我弹出了您的代码,但收到错误“jsl 参数应该是访问或评估‘Concat’中的字符”
问候
韦恩
回复:使用列表框更改时间序列图中多个变量的根名称@斯普顿
我看了你的代码。该脚本有第二个 GraphBuilder 的句柄。我必须进行一些更改,因为我没有可用的数据表。
您的代码有几个硬编码元素,我建议您删除,例如
- 发送到报告 X 轴日期范围
- 发送到报告图例项目(或者您需要维护它们)
看来你已经硬编码了你的起始标签。所以我将起始 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)} );
));
);
);
) ;
回复:使用列表框更改时间序列图中多个变量的根名称@斯普顿,
下面是一个带有列表框的应用程序的屏幕截图,当用户选择一个变量时,报告就会发生变化。 在此示例中,所有图表都是预先制作的(请参阅选项卡),并且 selesct 上的操作是更改可见选项卡。 您的选择操作是删除当前的“标签”并添加新标签,我猜测这将通过使用用于删除和添加变量到第二个 GraphBuilderBox 的消息来完成。

如果您将应用程序从 << Run 更改为 << Edit,
您应该会看到 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
回复:使用列表框更改时间序列图中多个变量的根名称@斯普顿,
有多种方法可以做到这一点。 您选择哪种方法取决于您期望 UI 执行的操作。
用户可以在列表中选择 1 个项目,然后使用 Control 选择其他项目,按住 Shift 可能是一个范围,然后删除一些项目。 我的想法是,您是否希望报告随着每次选择而更新,或者添加一个按钮,因此一旦选择,用户就可以按“执行”或“重新运行”或“执行”按钮来重做分析。
关于报告 GraphBuilder,您可以在图形生成器框中添加和删除变量。或者您可以添加一个“排除”的本地过滤器,其“可见性”为“折叠”,以捕获除用户选择之外的所有选择。 这些可能是选项而不是 Eval Expr。当编写 JSL Companion 2nd Edition 时,错过了 GraphBuilderBox 的使用。
我建议您使用过滤器制作图表并尝试不同的选项,以了解其工作原理。
就我个人而言,除非用户只能进行一项选择,否则我喜欢在可以进行多项选择的情况下使用按钮来启动任务。
我没有仔细阅读您的代码,但您可以使用窗口命名空间(可能是 window:GraphBuilderBox(2) )引用显示框或建立类似 (this<
因此,有多种选项可以实现您想要的效果,这取决于报告的当前树结构以及您想要的 UI 行为。