2022_Q1 MakeOverChallenge: 마우스 클릭 시 다양한 방식의 액션2022년 1분기 메이크오버 챌린지입니다.
목표는 세 가지 작업 중 하나를 수행하기 위한 예제, 스크립트 또는 가이드를 만드는 것입니다(모두 JMP에서 항목을 클릭한 후 일부 작업을 시작하는 것과 관련이 있습니다).
- 과제 A: (이미지 오픈을 위한 초기 데이터 테이블 생성을 위한 이미지 및 스크립트 첨부 : 2022Q1_ChallengeA.zip)
- 당신은 다음을 가지고 있습니다: 이미지나 웹 사이트 또는 파일에 대한 링크(표현식이라고도 함)가 포함된 데이터 테이블 열
- 원하는 것: 이 열의 한 셀을 클릭하고 JMP 외부의 링크나 이미지 열기
- 전반적인 목표: 데이터 테이블 셀을 클릭하면 무언가가 시작됩니다.
- 챌린지 B : (데이터 테이블을 열고 첨부된 보고서를 생성하는 스크립트: 2022Q1_ChallengeB_starterScript.jsl)
- 당신은 다음을 가지고 있습니다: Big Class 및 키에 따른 무게에 대한 Graph Builder 보고서(스크립트 참조)
- 원하는 점: 그래프 빌더 보고서를 닫으면 "연령" 분포 보고서가 열리고 이 보고서를 그림으로 저장한 다음 분포 보고서를 닫습니다.
- 전반적인 목표: 창을 닫으면 일부 작업이 실행되어야 합니다.
- 챌린지 C: (데이터 테이블을 열고 첨부된 보고서를 생성하는 스크립트: 2022Q1_ChallengeC_starterScript.jsl)
- 성장 측정 샘플 데이터에 대한 그래프 빌더 보고서가 있습니다.
- 원하는 점: 선을 클릭하거나 여러 선(또는 범례의 범주)을 선택할 때 선택한 행의 하위 집합을 생성하려고 합니다.
- 전반적인 목표: 그래프나 보고서를 클릭하면 일부 작업이 실행되어야 합니다.
원하는 만큼 많은 도전 과제를 수행할 수 있습니다. 답변을 이 스레드에 대한 답변으로 직접 제출할 수 있거나 제출해야 합니다.
!!! 제출할 때 답변이 언급하는 챌린지를 첫 번째 줄부터 시작하세요. 예:
챌린지 A:
이것이 내 대답입니다 ...
// this is my code
...
다음 회의(2022년 5월 18일)에서 우리는 답변 중 일부를 제시할 것이며 가장 좋은 답변을 이 스레드에 대한 솔루션으로 표시하겠습니다.
여러분의 제출을 기대합니다 
Re: 2022_Q1 MakeOverChallenge: 마우스 클릭 시 다양한 방식으로 동작오늘 회의에서 이야기한 내용을 간략하게 요약해서 적어보겠습니다. 이 주제의 이전 게시물에서 전체 솔루션을 볼 수 있습니다. JMP의 SAMPLE_IMAGE 폴더를 사용하도록 Challenge A 솔루션을 수정하므로 직접 실행할 수 있을 것입니다.
과제 A: 데이터 테이블 셀을 클릭하면 무언가가 시작되어야 합니다.<BR />
개념: 이벤트 핸들러 열 속성 사용
JMP가 이를 스크립트하도록 함으로써 이 작업을 매우 쉽게 수행할 수 있습니다. 예를 들어 웹 페이지에 대한 이벤트 처리기를 추가한 다음 필요에 맞게 스크립트를 수정하세요. 다음은 셀에서 이미지를 여는 방법에 대한 예제 솔루션입니다.
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();
);
이와 관련하여 고려해야 할 한 가지는 데이터 테이블(이 경우 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()을 사용하여 테이블에 대한 명시적인 참조를 얻음으로써 가능한 한 가지 솔루션을 제공합니다.
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> 한 가지 옵션은 버튼을 사용하여 작업(예:<A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/15435" target="_blank"> @레셀</A> 했다) Row State Handler 대신에 이것이 이 경우에 가장 강력한 옵션이라고 생각합니다.</P>
<P> </P>
<P>나머지 솔루션은 행 상태 처리기와 항상 변경되는 선택된 행을 관리하는 다양한 방법을 사용했습니다. <STRONG>행 상태 처리기에서 주목해야 할 점은 수정된 행을 반환한다는 것입니다.</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);
행을 관리하는 한 가지 옵션은 연관 배열( JMP에서는 연관 배열의 키로 Matrix를 사용할 수 있습니다. ) 이미 생성된 하위 집합이 있는 행을 수집합니다. 행 순서를 변경하거나 행을 추가/제거하지 않는 한 이는 작동합니다.
다음은 연관 배열을 사용하여 부분 집합된 행을 수집하는 간단한 예입니다. 이 예에서는 행 상태 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:
너무 많은 하위 집합이 생성되는 것을 방지하므로 버튼을 사용하여 이와 같은 작업을 수행하는 것이 좋습니다. 그러나 여기서는 주어진 과제를 따르고 최소한 동일한 하위 집합을 두 번 생성하지 않을 것이라는 간단한 검사를 추가했습니다.
더보기...
Row State Handler를 사용하면 마우스 놓기 이벤트에 액세스할 수 없으므로 사용자가 그래프에서 여러 줄을 하나씩 선택하면 여전히 많은 하위 집합을 생성하게 됩니다(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: 마우스 클릭 시 다양한 동작 // Challenge 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 << 창 닫기; ); gb = dt << 그래프 빌더( 크기(528, 454), 제어판 표시(0), 변수(X(:height), Y(:weight)), 요소(점(X, Y, 범례(3)) , 맞춤선(X, Y, 범례(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 경로 = "2022Q1_ChallengeA"; // 이미지 경로 {dtx} = 다중 파일 가져오기( << 폴더 설정( 경로 ), << 이름 필터 설정( "*.jpg; *.png;" ), << 이름 설정 활성화( 1 ), << 파일 이름 추가 열 설정( 1 ), << 파일 크기 추가 열 설정( 1 ) // 끝에 표시 크기에 대해 ) << 데이터 가져오기; // 이미지가 이미 데이터 테이블에 있으므로 드라이브에서 이미지를 열 필요가 없으며 이미지를 새 창으로 로드하면 됩니다. Column(dtx, "Picture") << Add Column Properties( Set Property( "Event Handler ", 이벤트 핸들러( Click(JSL Quote(Function({thisTable, thisColumn, iRow}, {}, New Window(Char(thisTable:"파일 이름"n[iRow]), New Image(thisTable:thisColumn[iRow])) ); ))), Tip(JSL Quote(Function({thisTable, thisColumn, iRow}, {}, "이미지 확대" || Char(thisTable:"파일 이름"n[iRow]); ))) ) ) ) ; // 일부 URL이 포함된 새 열 new_col = dtx << New Column("URL", Character, Nominal, Values( {"
www.jmp.com","
www.google.com","community.jmp.com", "
https://www.jmp.com/support/help/en/16.2/"} )); // 코드 jmp가 생성되었으며, 과도한 양의 주석만 제거되었습니다. new_col << Add Column Properties( Set Property( "Event Handler", Event Handler( Click(JSL Quote(Function({thisTable, thisColumn, iRow}, {} , Web(Char(thisTable:thisColumn[iRow])); ))), Tip(JSL Quote(Function({thisTable, thisColumn, iRow}, {}, "Open " || Char(thisTable:thisColumn[iRow]) || "브라우저에서."; ))), Color(JSL Quote(Function({thisTable, thisColumn, iRow}, {}, RGBColor("link"); ))) ) ) ); 쓰다(); // 마지막으로 실행된 행을 기록하는 귀찮은 인쇄를 피하기 위해
SAMPLE_IMAGES 경로 변수 사용(이는 스크립팅할 때 변경하는 것이 얼마나 쉬운지에 대한 예이기도 합니다. 하나의 변수만 변경해도 스크립트는 계속 작동합니다. (목록에서 하나의 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 );
);