안녕하세요, (JMP Pro의) SEM 및 신뢰성 블록 다이어그램에서 사용되는 드래그 앤 드롭 인터페이스와 같은 것을 만들려고 하는데 어려움을 겪고 있습니다.
화면 왼쪽 편에 "상자"들이 일렬로 늘어서 있는 형태입니다. 저는 그중 한 상자를 집어서 화면 중앙으로 끌어다 놓고, 다시 다른 상자를 집어서 끌어다 놓는 과정을 반복하고 싶습니다.
손잡이나 쥐덫 같은 여러 가지 방법을 시도해 봤어요. 어느 정도는 열 수 있는데, 완전히는 안 되네요.
아래는 Mousetrap을 사용한 최신 코드입니다. GraphBox의 왼쪽 상단에 있는 상자를 잡아서 화면 어디든 원하는 위치로 끌어다 놓을 수 있습니다. (놓으면 상자가 검은색으로 바뀝니다.) 하지만 그 후에는 다른 상자를 잡아서 추가할 수가 없습니다. 방금 놓은 상자만 이동할 수 있고, 다른 상자를 추가할 수는 없습니다.
현재는 애플리케이션으로 개발 중이지만, 필요하다면 개발 방식을 변경할 의향이 있습니다.
아래 스크립트는 Application Builder에서 제가 작성한 코드입니다. 첨부 파일에는 전체 애플리케이션이 포함되어 있습니다.
Mousetrap, GraphBoxes, Add Graphics Scripts 같은 프로그램들을 제대로 이해하지 못하는 부분이 있는 것 같습니다. 혹시 도움을 주실 수 있는 분이 계실까요?
// 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").
x0=5;
y0=95;
winref = (this module instance << Get Box);
// set graph box scales
winref[framebox(1)] << xaxis(0,100);
winref[framebox(1)] << yaxis(0,100);
// draw box in upper left corner.
pen color("Green");
winref[framebox(1)] << add graphics script(
pen color("Green");
Line({0,90}, {10,90},{10,100}, {0,100},{0,90}));
winref[framebox(1)] << Add Graphics Script(
Mousetrap(
// drag script (mouse down)
(
// if mouse location is within box in upper left corner, then OK to drag.
if(
and(
x>=x0-5,
y>=y0-5,
x<=x0+5,
y<=y0+5
),
(
// set x0 and y0 if that were true
x0 = x;
y0 = y;
// redraw the box at current mouse location while mouse button is down
winref[framebox(1)] << add graphics script(
"Front",
pen color("Green");
Line({x0-5, y0-5}, {x0+5, y0-5}, {x0+5, y0+5}, {x0-5, y0+5}, {x0-5, y0-5}));
)
);
),
(
// mouse up script
// draw a polygon centered at the current mouse location
winref[framebox(1)] << add graphics script(
polygon({x0-5,y0-5},{x0+5,y0-5},{x0+5,y0+5},{x0-5,y0+5},{x0-5,y0-5})
);
// at this point I want to manually reposition the mouse over the original box in the
// upper left, and grab another box.
// Instead, all I can do is grab the box I just created and drag it somewhere else.
)
);
);
그래픽 스크립트를 계속 추가하면 If() 함수가 덮어쓰여 프레임박스가 가득 차게 될 가능성이 높으므로, 그렇게 하지 않는 것이 좋습니다.

이것을 훨씬 더 나은 방법으로 만들 수 있지만, 아래는 가능한 한 가지 예시입니다.
Names Default To Here(1);
rects = {};
x0 = 5;
y0 = 95;
x = .;
y = .;
nw = New Window("Example",
Graph Box(
Frame Size(200, 200),
Mousetrap(
x0 = x;
y0 = y;
,
p = EvalExpr(Polygon(
{Expr(x0+5), Expr(y0-5)},
{Expr(x0+5), Expr(y0+5)},
{Expr(x0-5), Expr(y0+5)},
{Expr(x0-5), Expr(y0-5)}
));
Insert Into(rects, Name Expr(p));
);
Pen color("Green");
Line({0,90}, {10,90},{10,100}, {0,100},{0,90});
If(x >= x0 - 5 & y >= y0 - 5 & x <= x0 + 5 & y <= y0 + 5,
Pen color("Green");
Line({x0-5, y0-5}, {x0+5, y0-5}, {x0+5, y0+5}, {x0-5, y0+5}, {x0-5, y0-5});
);
For(i = 1, i <= N Items(rects), i++,
Pen Color("Black");
Eval(rects[i]);
);
);
);
</CODE></P>
<P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_1-1766523967638.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1766523967638.png" style="width: 260px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1766523967638.png" style="width: 260px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1766523967638.png" style="width: 260px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1766523967638.png" style="width: 260px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1766523967638.png" style="width: 260px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1766523967638.png" style="width: 260px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1766523967638.png" style="width: 260px;"><span class="lia-inline-image-display-wrapper" image-alt="jthi_1-1766523967638.png" style="width: 260px;"><img src="https://us.v-cdn.net/6038925/uploads/images/89563i0F98FCB07A4441BC/jthi_1-1766523967638.png" role="button" title="jthi_1-1766523967638.png" alt="jthi_1-1766523967638.png" /></span></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></P>
<BR />
<P>수정: x와 y에 대한 초기화 코드를 추가했습니다.</P>
</LINGO-BODY>
<LINGO-SUB id="lingo-sub-921160" slang="en-US" mode="UPDATE" translate="no">Re: 드래그 앤 드롭 스크립트 만들기</LINGO-SUB>
<LINGO-BODY id="lingo-body-921160" slang="en-US" mode="UPDATE">
<P>제가 얻는 것은 다음과 같습니다:</P>
<P><FONT face="courier new,courier">DisplayBox[EvalContextBox]</FONT><BR /><FONT face="courier new,courier">'x'에 대한 접근 또는 평가에서 이름이 확인되지 않았습니다: x/*###*/</FONT></P>
<P><FONT face="courier new,courier">26번째 줄에서</FONT><BR /><BR /></P>
<P>x와 y는 쥐덫 밖에서도 지속되나요?</P>
<P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="hogi_0-1766525524905.png" style="width: 999px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="hogi_0-1766525524905.png" style="width: 784px;"><span class="lia-inline-image-display-wrapper" image-alt="hogi_0-1766525524905.png" style="width: 784px;"><img src="https://us.v-cdn.net/6038925/uploads/images/89564iE967B41113B5D41E/hogi_0-1766525524905.png" role="button" title="hogi_0-1766525524905.png" alt="hogi_0-1766525524905.png" /></span></SPAN></SPAN></P>
<P><STRONG>편집하다</STRONG> :<BR /> 그들은 "쥐덫 밖에서 끈질기게 버틴다"<BR /> 하지만 영구적인 것은 아닙니다. 마우스 버튼을 놓으면 설정이 초기화되는 것 같습니다.<BR /> <A href="https://community.jmp.com/t5/Discussions/Can-JMP-graphics-have-this-effect/m-p/921213/highlight/true#M107999" target="_blank">https://community.jmp.com/t5/Discussions/Can-JMP-graphics-have-this-effect/mp/921213/highlight/true#M107999</A></P>
<BR />
<P>멋지네요! 초록색 사각형 덕분에 "끌어당기는" 듯한 착시 효과가 아주 잘 살아나요 ; )<BR /> 초록색 사각형이 없으면 마치 마우스 클릭할 때마다 검은색 사각형이 추가되는 것처럼 느껴집니다.</P>
<P></P>
<iframe src="https://players.brightcove.net/6058004218001/default_default/index.html?videoId=6386912122112" width="280" height="280" allowfullscreen allow="encrypted-media"></iframe>
<P></P>
</LINGO-BODY>
<LINGO-SUB id="lingo-sub-921187" slang="en-US" mode="CREATE" translate="no">Re: 드래그 앤 드롭 스크립트 만들기</LINGO-SUB>
<LINGO-BODY id="lingo-body-921187" slang="en-US" mode="CREATE">
<P>아마도 x와 y가 메모리에 초기화되어 있어서 제대로 작동하지 않았던 것 같습니다. 스크립트를 수정하여 x와 y를 초기화하도록 했더니 새 JMP 세션에서 정상적으로 작동하는 것 같습니다.</P>
</LINGO-BODY>
<LINGO-SUB id="lingo-sub-921211" slang="en-US" mode="CREATE" translate="no">Re: 드래그 앤 드롭 스크립트 만들기</LINGO-SUB>
<LINGO-BODY id="lingo-body-921211" slang="en-US" mode="CREATE">
<P><A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/14366" target="_blank">@jthi 님</A> (그리고 <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/26800" target="_blank">@hogi 님</A> 도 기여해 주셔서 감사합니다!) 덕분에 제 목적에 맞게 활용할 수 있을 것 같습니다. 덕분에 Mousetrap, Add Graphics Script, Name Expr에 대해서도 알게 되었습니다.</P>
<P>JMP 커뮤니티의 빠른 응답과 지식에 늘 감탄합니다. 정말 감사합니다!</P>
</LINGO-BODY>
<LINGO-SUB id="lingo-sub-921219" slang="en-US" mode="UPDATE" translate="no">Re: 드래그 앤 드롭 스크립트 만들기</LINGO-SUB>
<LINGO-BODY id="lingo-body-921219" slang="en-US" mode="UPDATE">
<P>이것은 <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/14366" target="_blank">@jthi</A> 님의 스크립트의 고급 버전입니다.</P>
<P>- 기존 상자를 드래그할 수 있습니다.</P>
<P>- 사용자가 상자가 없는 영역을 클릭해도 상자가 생성되거나 이동되지 않습니다.</P>
<P>- 맨 위에 있는 첫 번째 상자는 무한히 많은 상자를 저장할 수 있는 저장소 역할을 합니다.</P>
<P></P>
<iframe src="https://players.brightcove.net/6058004218001/default_default/index.html?videoId=6386914707112" width="276" height="280" allowfullscreen allow="encrypted-media"></iframe>
<P></P>
<BR />
<PRE><CODE class=" language-jsl">Names Default To Here( 1 );
squares = {{5, 95}};
x = .;
y = .;
mouseDown = 1;
foundOne = 0;
nw = New Window( "Example",
Graph Box(
Frame Size( 200, 200 ),
Mousetrap(
// find a neighboring square
If( mouseDown,
x0 = x;
y0 = y;
If( N Items( squares ),
kt = KDTable( Matrix( squares ) );
{row, dist} = kt << K nearest rows( {1, 10}, Matrix( {x0, y0} ) );
If( N Items( row ) & dist[1] < 10,
If( row > 1, // keep the one at the top corner
Remove From( squares, row[1] )
);
foundOne = 1;
);
);
);
mouseDown = 0;,
// mouse relesed -> save the square
If( foundOne,
Insert Into( squares, Eval List( {Eval List( {x, y} )} ) )
);
//reset
mouseDown = 1;
foundOne = 0;
);
Pen Color( "Green" );
Line( {0, 90}, {10, 90}, {10, 100}, {0, 100}, {0, 90} ); // 1st square to start with
// dragged square
If( Not( Is Missing( x ) ) & foundOne,
Line( {x - 5, y - 5}, {x + 5, y - 5}, {x + 5, y + 5}, {x - 5, y + 5}, {x - 5, y - 5} )
);
For( i = 1, i <= N Items( squares ), i++,
Pen Color( "Black" );
Eval(
{x0, y0} = squares[i];
Polygon( {x0 + 5, y0 - 5}, {x0 + 5, y0 + 5}, {x0 - 5, y0 + 5}, {x0 - 5, y0 - 5} );
);
);
)
);