2022_Q1 MakeOverChallenge:以各种方式对鼠标单击进行操作这是 2022 年第一季度的改造挑战。
目标是提出一个示例、脚本或指南来完成三个任务之一(所有这些都与您在 JMP 中单击某些内容后启动某些操作有关):
- 挑战一: (用于创建打开图像的初始数据表的图像和脚本附件:2022Q1_ChallengeA.zip)
- 您有: 包含图像或网站或文件链接(又名表达式)的数据表列
- 您想要:单击此列的一个单元格并在 JMP 之外打开链接或图像
- 总体目标:单击数据表单元格应启动某些操作
- 挑战 B : (打开数据表并创建报告的脚本:2022Q1_ChallengeB_starterScript.jsl)
- 您有:Big Class 和 Graph Builder 的身高体重报告(见脚本)
- 您想要:关闭 Graph Builder 报告应该打开一个“年龄”的分布报告,将此报告保存为图片并关闭分布报告。
- 总体目标:关闭窗口应该触发一些动作
- 挑战 C: (打开数据表并创建报告的脚本:2022Q1_ChallengeC_starterScript.jsl)
- 您有: 关于增长测量样本数据的图表生成器报告。
- 您希望:当单击一行或选择多行(或图例中的类别)时,您希望生成所选行的子集。
- 总体目标:点击图表或报告应该触发一些动作
您可以根据自己的喜好应对尽可能多的挑战。 您可以/应该直接提交您的答案作为对该主题的回复。
!!! 提交时,请从第一行开始,说明您的回复所指的挑战,例如
挑战一:
这是我的答案...
// this is my code
...
在下次会议(2022 年 5 月 18 日)中,我们将展示一些答案,我会将最佳答案标记为该主题的解决方案。
期待你的投稿:)
回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战 C
这是我的答案,请参阅下面的完整脚本。
下半部分将行状态处理程序添加到表中,以触发操作(参见脚本索引中的示例)。
Names Default To Here( 1 );
// Open Data Table
dt = Open( "$SAMPLE_DATA/Growth Measurements.jmp", invisible );
// Report snapshot: Growth Measurements - Graph Builder
gb = dt << Graph Builder(
Size( 522, 452 ),
Show Control Panel( 0 ),
Legend Position( "Bottom" ),
Graph Spacing( 8 ),
Variables( X( :Age ), Y( :Growth ), Overlay( :Subject ) ),
Elements( Line( X, Y, Legend( 13 ) ) )
);
// This is my code (Georg)
// (see Scripting Index "Make Row State Handler")
// Define a function, that does the action
f = Function( {a},
Current Data Table() << Subset( Selected Rows( 1 ), Selected columns only( 0 ) )
);
// Set up a row state handler, that triggers the execution of a function on any change of row states,
// a change on row selection by clicking on a line in Graph Builder is a change of row states in the table
rs = dt << make row state handler( f );回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战 C
使用鼠标框无法选择某些内容,因此我更改为行状态处理程序
Names Default To Here( 1 );
// Open Data Table
dt = Open( "$SAMPLE_DATA/Growth Measurements.jmp", invisible );
// Report snapshot: Growth Measurements - Graph Builder
gb = dt << Graph Builder(
Size( 522, 452 ),
Show Control Panel( 0 ),
Legend Position( "Bottom" ),
Graph Spacing( 8 ),
Variables( X( :Age ), Y( :Growth ), Overlay( :Subject ) ),
Elements( Line( X, Y, Legend( 13 ) ) )
);
active_subset = "";
first_subset = "false";
rsh = dt << make row state handler(
Function( {a},
subtbl = dt << Subset( Selected Rows( 1 ) );
gb << Bring Window To Front;
if(
first_subset == "true",
close(active_subset, no save)
);
active_subset = subtbl;
first_subset = "true";
)
);
回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战一:
笔记:我保留了这个旧版本,因为有些人已经看过它,但我发布了一个更清洁的解决方案作为回复到这个。
根本不是一个漂亮的解决方案,但它可以完成工作...... 期待更优雅的出现!
这要在 starterScript 之后添加:
// Defining the file name for an image placeholder for displaying on the OS when clicking:
pictFileName = Get Default Directory() || "verylonganduselessname.png"; //name for the temp image file (to be deleted at the end)
dtx:Picture << Set Property("tmpFileName", pictFileName); //saving the name so it can be retrieved from within the table
dtx << On Close( Delete File(pictFileName) ); //make sure we erase the temp image file at the end.
// Setting a Click event handler for the column of interest:
dtx:Picture << Set Property(
"Event Handler",
Event Handler(
Click(JSL Quote( Function(
{thisTable, thisColumn, iRow},
pictFileName = thisTable:thisColumn<< Get Property("tmpFileName"); //recover the path for a temp file
thisTable:thisColumn[iRow] << Save Image( pictFileName ); //save cell contents to temp file
Web( "file://" || pictFileName ) // open the image file
)
)
),
Tip(JSL Quote( Function(
{thisTable, thisColumn, iRow},
"click to open";
)
)
)
)
);
回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战A
很抱歉用我最初的解决方案开枪...... 这是一个更清洁的。
Names Default to Here ( 1 );
//path = <YOUR full="" path="" to="" where="" the="" images="" have="" been="" saved="">;
// eg.
// path = "C:\EventHandlerImages\";
path = "$DOCUMENTS\Scripting\2022Q1\ChallengeA\2022Q1_ChallengeA\";
//==========================================================================
//Multiple File Import is new in JMP 14
{dtx} = Multiple File Import(
<<SET folder=""></SET></YOUR>回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战 C
不幸的是,就挑战 A 和 B 而言,没有什么可做的了。 提供的解决方案似乎无可挑剔。 相比之下,我觉得挑战 C 仍有一些改进的可能。 关于我的回答的几句话
- 我基本上偷了必要的代码从这里( @txnelson就像许多其他编剧一样,对我来说是摇滚明星)
- 我通过包含可见数据点稍微修改了图表,因此更容易选择单个行
- 选择图形中的点后,不会立即打开带有子集的数据表。 这是通过在图表下方添加的按钮完成的
请参阅下面的完整脚本,包括修改后的图表。
// Open Data Table
dt = Open( "$SAMPLE_DATA/Growth Measurements.jmp",invisible );
// Report snapshot: Growth Measurements - Graph Builder
gb = dt << Graph Builder(
Size( 522, 452 ),
Show Control Panel( 0 ),
Legend Position( "Bottom" ),
Graph Spacing( 8 ),
Variables( X( :Age ), Y( :Growth ), Overlay( :Subject ) ),
Elements(
Points( X, Y, Legend( 17 ), Jitter Limit( 0 ) ), // added markers
Line( X, Y, Legend( 13 ) ) ),
SendToReport( // increased markers to decent size
Dispatch(
{},
"Graph Builder",
FrameBox,
{Marker Size( 6 ), Marker Drawing Mode( "Normal" )}
)
)
);
// my solution (stolen from here: https://community.jmp.com/t5/Discussions/Creating-a-Subset-from-an-Interactive-Graph/td-p/114459)
subsetButton = Button Box( "Dear user, Please press here to create a Subset of the Selected Points immediately",
If( N Rows( dt << get selected rows ) > 0,
dt << subset( selected rows( 1 ), selected columns( 0 ) )
)
);
Report( gb )["Graph Builder"] << append( subsetButton );
回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战一:
主要是 JMP 编写的带有添加列属性的代码。 还添加了如何添加和打开 URL 的示例
查看更多...
Names Default To Here(1);
// Challenge A
path = "2022Q1_ChallengeA"; // path to images
{dtx} = Multiple File Import(
<<SET folder=""></SET>
回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战 B
将此添加到脚本的底部:
gb << On Close(
dist = dt << Distribution( Nominal Distribution( Column( :age ) ) );
image = dist << Get Picture;
path = "$temp/age_dist.png";
image << Save Picture( path, "png" );
dist << Close Window();
Open( path );
);
回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战 B:
查看更多...
Names Default To Here(1);
// 2022_Q1 MakeOverChallenge: Action on mouse click in various ways
// Challenge B
dt = Open("$SAMPLE_DATA/Big Class.jmp");
//Use expression to make script a bit more clean IF this were to be expanded
create_dist = Expr(
dist = dt << Distribution(Nominal Distribution(Column(:age)), Histograms Only);
wait(1); // add wait so we can see that distribution is created
dist << Save Picture("$TEMP/Big_Class_age_dist.png", png);
dist << Close Window;
);
gb = dt << Graph Builder(
Size(528, 454),
Show Control Panel(0),
Variables(X(:height), Y(:weight)),
Elements(Points(X, Y, Legend(3)), Line Of Fit(X, Y, Legend(5)))
);
gb << On Close(create_dist);
// Open("$TEMP/Big_Class_age_dist.png"); // un-comment to open the image
回复:2022_Q1 MakeOverChallenge:以各种方式点击鼠标的动作挑战 C:
我绝对建议用按钮做这样的事情,因为它可以防止创建太多的子集。 但是在这里,我遵循给定的挑战并添加了简单的检查,即我们至少不会两次创建相同的子集。
查看更多...
Names Default To Here(1);
// Open Data Table
dt = Open("$SAMPLE_DATA/Growth Measurements.jmp", invisible);
gb = dt << Graph Builder(
Size(522, 452),
Show Control Panel(0),
Legend Position("Bottom"),
Graph Spacing(8),
Variables(X(:Age), Y(:Growth), Overlay(:Subject)),
Elements(Line(X, Y, Legend(13)))
);
//initialize some variables
prev_rows = [];
dt_list = {};
f = Function({rows_changed},
//Rowstate 1 is selected row
cur_rows = Loc(dt << Get Row States, 1);
//if no rows are selected, don't try to create subsets
If(N Items(cur_rows) == 0,
return()
);
//compare to previous to prevent opening extensive abmount of subsets
If(N Items(cur_rows) == N Items(prev_rows),
If(All(cur_rows == prev_rows),
return();
);
);
dt_subset = dt << Subset(Output table("selected_rows"), Rows(cur_rows), invisible);
Insert Into(dt_list, dt_subset); //keep list to make closing easier
//attempt to bring gb to front, this won't work perfectly without wait
gb << Bring Window To Front;
dt_subset << Show Window(1);
//it is enough if we update prev_rows only when subset was created
prev_rows = cur_rows;
);
rs = dt << make row state handler(f);
/* run this to close all data tables
For Each({dt_ref}, dt_list,
Try(Close(dt_ref, no save), Show(exception_msg));
);
Close(dt, no save);
*/
使用行状态处理程序,我们无法访问鼠标释放事件,因此如果用户从图中一一选择多行,我们仍将创建许多子集(可能有一种方法可以使用 Mouse Box() 来做到这一点,但我认为使用按钮会更简单,更容易)。