2022_Q1 MakeOverChallenge: マウスクリック時のさまざまなアクションこれは 2022 年第 1 四半期の変身チャレンジです。
目標は、次の 3 つのタスクのいずれかを実行するための例、スクリプト、またはガイドを作成することです (すべてのタスクは、JMP で何かをクリックした後に何らかのアクションを開始することに関係しています)。
- 課題 A: (添付画像を開くための初期データテーブルを作成する画像とスクリプト: 2022Q1_ChallengeA.zip)
- 画像または Web サイトまたはファイルへのリンク (別名式) を含むデータ テーブル列
- 目的: この列の 1 つのセルをクリックして、JMP の外でリンクまたは画像を開きます。
- 全体的な目標: データ テーブルのセルをクリックすると、何かが開始されるはずです。
- チャレンジB : (データテーブルを開いてレポートを作成するためのスクリプトが添付されています: 2022Q1_ChallengeB_starterScript.jsl)
- Big Class と身長別体重のグラフ ビルダー レポート (スクリプトを参照)
- 希望: グラフ ビルダー レポートを閉じると、「年齢」の分布レポートが開き、このレポートを画像として保存して分布レポートを閉じる必要があります。
- 全体的な目標: ウィンドウを閉じると何らかのアクションがトリガーされるようにする
- 課題 C: (データテーブルを開いてレポートを作成するためのスクリプトが添付されています: 2022Q1_ChallengeC_starterScript.jsl)
- 成長測定サンプル データに関するグラフ ビルダー レポート。
- 目的: 行をクリックするか、複数の行 (または凡例内のカテゴリ) を選択するときに、選択した行のサブセットを生成したいと考えています。
- 全体的な目標: グラフまたはレポートをクリックすると、何らかのアクションがトリガーされる必要があります。
好きなだけ課題に取り組むことができます。 このスレッドへの返信として回答を直接送信できます/送信する必要があります。
!!! 送信するときは、最初の行で返信がどのようなチャレンジに言及しているかを記述してください。例:
課題 A:
これが私の答えです...
// this is my code
...
次回の会議 (2022 年 5 月 18 日) では、回答の一部を提示し、最良の回答をこのスレッドの解決策としてマークします。
皆様のご応募をお待ちしております:)
Re: 2022_Q1 MakeOverChallenge: マウスクリック時のさまざまなアクション今日の会議で話した内容を簡単に書きます。 私の完全なソリューションは、このトピックの以前の投稿でご覧いただけます。 JMP の SAMPLE_IMAGE フォルダーを使用するようにチャレンジ A ソリューションを変更するので、直接実行できるはずです。
課題 A: データ テーブルのセルをクリックすると、何かが開始されるはずです<BR />
概念: イベント ハンドラー列プロパティの使用
これは、JMP にスクリプトを実行させることで非常に簡単に実行できます。 たとえば、Web ページにイベント ハンドラーを追加し、ニーズに合わせてスクリプトを変更します。 以下は、セル内の画像を開く方法に関する私のソリューション例です。
Column(dtx, "Picture") << Add Column Properties(
Set Property(
"Event Handler",
Event Handler(
Click(JSL Quote(Function({thisTable, thisColumn, iRow}, {},
New Window(Char(thisTable:"File Name"n[iRow]), New Image(thisTable:thisColumn[iRow]));
))),
Tip(JSL Quote(Function({thisTable, thisColumn, iRow}, {},
"Enlarge image " || Char(thisTable:"File Name"n[iRow]);
)))
)
)
);
イベント ハンドラーは、たとえばセルのクリック時にデータベースのデータをクエリできるため、非常に強力です。
課題 B: ウィンドウを閉じると何らかのアクションがトリガーされる必要がある
コンセプト: 使用<< 閉じる時()</CODE></P>
<P><CODE class=" language-jsl">
このチャレンジのアイデアは、グラフ ビルダーが閉じているときにアクションを実行することでした。 これは、<< On Close() を使用して実行する非常に簡単なタスクです。 以下は、によって提供されるソリューションのわずかに変更されたバージョンです。 @ロブ
gb << On Close(
dist = dt << Distribution(Nominal Distribution(Column(:age)));
image = dist << Get Picture;
image << Save Picture($temp/age_dist.png, "png");
dist << Close Window();
);
これに関して考慮すべき点の 1 つは、データ テーブル (この場合は dt) への参照を使用している場合、gb を閉じる前に新しいテーブルを開いた場合、間違ったテーブルを閉じる可能性が高いということです。
この問題は、次のサンプル スクリプトで確認できます。
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Bivariate(Y(:Weight), X(:Height), Nonpar Density);
biv << On Close(
close(dt, no save);
);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
そして、このスクリプトは、Eval(EvalExpr()) と Expr() を使用してテーブルへの明示的な参照を取得することで、考えられる解決策の 1 つを提供します。
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Bivariate(Y(:Weight), X(:Height), Nonpar Density);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
Eval(EvalExpr(
biv << On Close(
Close(Expr(biv << Get Data Table), no save)
);
));
On Close で関数を使用することもできますが、この場合、二変量プラットフォームの参照にはアクセスできず、二変量を持つウィンドウにアクセスできるため、より複雑なコードが生成されるため、ウィンドウを解析する必要があります。名前は機能する場合と機能しない場合があります (ウィンドウ内でプラットフォームへの参照を取得する方法がある可能性があります)。
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Bivariate(Y(:Weight), X(:Height), Nonpar Density);
biv << On Close(function({this},
table_name = Trim Whitespace(Word(1, (this << Get Window Title), "-"));
If(Contains(Get Data Table List() << get name, table_name),
Close(Datatable(table_name), no save);
);
));
課題 C: グラフまたはレポートをクリックすると、何らかのアクションがトリガーされる必要があります
コンセプト: 使用<< 行状態ハンドラーの作成()
</CODE></P>
<P>これにはほとんどの異なる解決策があり、すべてが少し異なりました。 <STRONG>このタイプのスクリプトの大きな課題は、絶えず変化する行の状態をどのように管理するかを決定することです。</STRONG> 1 つのオプションは、ボタンを使用してアクションをトリガーすることです (例:<A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/15435" target="_blank"> @レッセル</A>しました)行状態ハンドラーの代わりに、これがこの場合最も堅牢なオプションであると私は考えています。</P>
<P> </P>
<P>残りのソリューションでは、行状態ハンドラーと、常に変更される選択された行を管理するさまざまな方法 (または使用しない) が使用されていました。 <STRONG>Row State Handler で注意すべき点の 1 つは、変更された行を返すことです。</STRONG>選択された行だけではありません。 したがって、選択した列のみに興味がある場合は、そのことを考慮する必要があります。</P>
<P> </P>
<P>ほとんどの単純なケースでは、次のようなものを使用できます<A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/9474" target="_blank">@ゲオルグ</A>と答えました。</P>
<PRE><CODE class=" language-jsl">f = Function({a},
dt << Subset(Selected Rows(1), Selected columns only(0))
);
rs = dt << make row state handler(f);
行を管理するための 1 つのオプションは、連想配列 ( JMP では行列を連想配列のキーとして使用できます) で、サブセットがすでに作成されている行を収集します。 これは、行の順序を変更したり、行を追加/削除したりしない限り、機能します。
以下は、連想配列を使用してサブセット化された行を収集する簡単な例です。 この例では、行状態 1 (選択された行) を持つ行をチェックし、まだ作成されていない場合はそれらのサブセットを作成します。 これの利点の 1 つは、データテーブル参照を連想配列に保存し、次のコマンドを使用してそれらすべてにすばやくアクセスできることです。 aa_subset_rows << 値を取得;ただし、マウスを押したままドラッグして多数の行を選択している場合、この解決策にはまだ少しバグがある可能性があります。
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)))
);
aa_subset_rows = Associative Array();
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(Contains(aa_subset_rows , cur_rows),
return();
);
dt_subset = dt << Subset(Output table("selected_rows"), Rows(cur_rows));
aa_subset_rows[cur_rows] = dt_subset;
);
rs = dt << make row state handler(f);
Re: 2022_Q1 MakeOverChallenge: マウスクリック時のさまざまなアクション課題 C:
あまりにも多くのサブセットが作成されるのを防ぐため、ボタンを使用してこのようなことを行うことを強くお勧めします。 ただし、ここでは指定された課題に従い、少なくとも同じサブセットを 2 回作成しないという単純なチェックを追加しました。
もっと見る...
Row State Handler を使用すると、マウスを離したイベントにアクセスできないため、ユーザーがグラフから複数の行を 1 つずつ選択した場合でも、多くのサブセットが作成されます (Mouse Box() を使用してこれを行う方法があるかもしれませんが、ボタンを使用すると思います)はるかにシンプルで簡単になります)。
Re: 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
名前のデフォルトはここ(1)です。 // 2022_Q1 MakeOverChallenge: さまざまな方法でのマウスクリック時のアクション // チャレンジ B dt = Open("$SAMPLE_DATA/Big Class.jmp"); // これを展開する場合は、式を使用してスクリプトをもう少しわかりやすくします create_dist = Expr( dist = dt << Distribution(Nominal Distribution(Column(:age)), Histograms Only); wait(1); // addディストリビューションが作成されたことが確認できるまで待ちます。 dist << Save Picture("$TEMP/Big_Class_age_dist.png", png); dist << Close Window; ); gb = dt << グラフ ビルダー( サイズ(528, 454), コントロール パネルの表示(0), 変数(X(:高さ), Y(:重量)), 要素(ポイント(X, Y, 凡例(3)) , フィット線(X, Y, Legend(5))) ); gb << 閉じる時(create_dist); // Open("$TEMP/Big_Class_age_dist.png"); // コメントを解除して画像を開きます
Re: 2022_Q1 MakeOverChallenge: マウスクリック時のさまざまなアクション課題 A:
大部分は、列プロパティの追加を使用して JMP で記述されたコードです。 URLを追加して開く方法の例も追加されました
もっと見る...
Names Default To Here(1);
// Challenge A
path = "2022Q1_ChallengeA"; // path to images
{dtx} = Multiple File Import(
<<SET folder=""></SET>
名前のデフォルトはここ(1)です。 // チャレンジ A path = "2022Q1_ChallengeA"; // 画像へのパス {dtx} = Multiple File Import( <
SAMPLE_IMAGES パス変数の使用 (これは、スクリプト作成時に変更がいかに簡単であるかを示す例としても機能します。1 つの変数を変更するだけでスクリプトは引き続き機能します (空の行が他の列に追加されないように、リストから 1 つの URL を削除しました) )):
Names Default To Here(1);
// Challenge A
path = Get Path Variable("$SAMPLE_IMAGES");
{dtx} = Multiple File Import(
<<SET folder=""></SET>
Re: 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 );
Re: 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>Re: 2022_Q1 MakeOverChallenge: マウスクリック時のさまざまなアクション課題 A:
注記:すでに何人かの人が見ているため、この古いバージョンはそのままにしておきましたが、よりクリーンな解決策を投稿しました。返事これに。
まったくきれいな解決策ではありませんが、機能します... もっとエレガントなものが登場することを期待しています!
これを 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";
)
)
)
)
);
Re: 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";
)
);
Re: 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 );Re: 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 );
);