다음 단계에서는 데이터 테이블의 2열 데이터를 가져와서 이를 행렬로 변환하고 Graph Builder에서 다각형을 그리기 시작하고 싶습니다.
하지만 슬라이더를 움직이면 콘텐츠가 변경되지 않는다는 어려움이 있습니다.
1. 새 창에 텍스트 상자 하나를 추가하고 데이터 테이블의 열 값을 표시합니다.
2. 데이터 테이블의 좌표를 갖는 다각형은 그래프 빌더에서 변경되지 않습니다.
내 목적은 슬라이더를 움직이면 텍스트 상자와 그래프의 내용도 변경된다는 것입니다.
dt = Open("ww17_DATAALL_TRIAL.jmp");
//get malahanobis distance
multi = dt << Multivariate(
Y(:FORCEDROPTIME_3, :ACTUAL_MAXCHASEHOLDFORCE_4),
Variance Estimation("Row-wise"),
Scatterplot Matrix(1),
Pairwise Correlations(1)
);
multi << Mahalanobis Distances(1, Save Outlier Distances);
mahal_ucl = Column("Mahal. Distances") << Get Property("Mahal.Value");
mahal_max = Col Maximum(Column(dt, "Mahal. Distances"));
tri = Triangulation(X(:FORCEDROPTIME_3, :ACTUAL_MAXCHASEHOLDFORCE_4), Y(:BHT));
// get contour around all data point
hulledge = tri << Get Hull Edges;
hullpoint = tri << Get Hull Points;
{xx, yy} = tri << Get Points();
tri2 = tri << Subset(tri << Get Hull Points); // get data point of boundary
{tri2_xx, tri2_yy} = tri2 << Get Points();
centroid_x = Mean(tri2_xx); // calculate centroid x
centroid_y = Mean(tri2_yy); // calculate centroid y
centroid_tri2_xx_ang = []; // get distance between x and centroid
centroid_tri2_yy_ang = []; // get distance between x and centtroid
angles = {}; // angles
For(i = 1, i <= N Items(tri2_xx), i++,
x_diff = tri2_xx[i] - centroid_x;
Insert Into(centroid_tri2_xx_ang, x_diff);
y_diff = tri2_yy[i] - centroid_y;
Insert Into(centroid_tri2_yy_ang, y_diff);
);
//sort tri2_xx and tri2_yy to clockwise polygon
For(i = 1, i <= N Items(tri2_xx), i++,
If(
centroid_tri2_xx_ang[i] > 0,
angles[i] = ATan(centroid_tri2_yy_ang[i] / centroid_tri2_xx_ang[i]),
centroid_tri2_xx_ang[i] < 0 & centroid_tri2_yy_ang[i] >= 0,
angles[i] = ATan(centroid_tri2_yy_ang[i] / centroid_tri2_xx_ang[i]) + 3.14,
centroid_tri2_xx_ang[i] < 0 & centroid_tri2_yy_ang[i] < 0,
angles[i] = ATan(centroid_tri2_yy_ang[i] / centroid_tri2_xx_ang[i]) - 3.14,
centroid_tri2_xx_ang[i] == 0 & centroid_tri2_yy_ang[i] > 0, angles[i] = 3.14 / 2,
centroid_tri2_xx_ang[i] == 0 & centroid_tri2_yy_ang[i] < 0, angles[i] = -3.14 / 2,
)
);
Show(angles);
tb = New Table("tb",
Add Rows(N Items(tri2_xx)),
New Table Variable("scaleFactor", mahal_max),
New Column("X", Numeric, "Continuous", Set Values(tri2_xx)),
New Column("Y", Numeric, "Continuous", Set Values(tri2_yy)),
New Column("Angle", Numeric, "Continuous", Set Values(angles)),
New Column("MaxDistance", Numeric, "Continuous", Formula(mahal_max)),
New Column("OffSet", Numeric, "Continuous", Formula(:scaleFactor + mahal_max))
);
sliderValue = tb << Get Table Variable("scaleFactor");
//must be sorted the lists first
tb << Sort(replace table, By(:Angle), Order(Descending));
tri2_xx_sort = Column(tb, "X") << GetAsMatrix();
tri2_yy_sort = Column(tb, "Y") << GetAsMatrix();
x2 = Column(tb, "X") << GetAsMatrix();
y2 = Column(tb, "Y") << GetAsMatrix();
tb << New Column("OffSetX_temp",
Numeric,
"Continuous",
Formula(CalculateOffsetPoints_X(:scaleFactor))
);
tb << New Column("OffSetY_temp",
Numeric,
"Continuous",
Formula(CalculateOffsetPoints_Y(:scaleFactor))
);
CalculateOffsetPoints_X = Function({:scaleFactor},
For(i = 1, i <= N Items(x2), i++,
j = Mod(i, N Items(x2)) + 1; // Next point index
dx = x2[j] - x2[i];
dy = y2[j] - y2[i];
length = Sqrt(dx ^ 2 + dy ^ 2);
// Perpendicular vector
perp_dx = -dy / length;
perp_dy = dx / length;
// Offset points
offset_x[i] = x2[i] + :scaleFactor * perp_dx;
offset_y[i] = y2[i] + :scaleFactor * perp_dy;
);
Return(offset_x[Row()]);
);
CalculateOffsetPoints_Y = Function({:scaleFactor},
For(i = 1, i <= N Items(x2), i++,
j = Mod(i, N Items(x2)) + 1; // Next point index
dx = x2[j] - x2[i];
dy = y2[j] - y2[i];
length = Sqrt(dx ^ 2 + dy ^ 2);
// Perpendicular vector
perp_dx = -dy / length;
perp_dy = dx / length;
// Offset points
offset_x[i] = x2[i] + :scaleFactor * perp_dx;
offset_y[i] = y2[i] + :scaleFactor * perp_dy;
);
Return(offset_y[Row()]);
);
New Window("DrawData",
Outline Box("Polygon Shape Explorer",
Panel Box("Slider",
sb = Slider Box(
0,
100,
sliderValue,
tb << Set Table Variable("scaleFactor", sliderValue)
),
Lineup Box(N Col(32),
Text Box("Offset Value: "),
Text Box(sliderValue),
Text Box("Offset X: "),
Text Box((Column(tb, "OffSetX_temp") << GetAsMatrix())),
)
),
chartdisplay = dt << Graph Builder(
Size(725, 429),
Show Control Panel(0),
Variables(X(:FORCEDROPTIME_3), Y(:ACTUAL_MAXCHASEHOLDFORCE_4)),
Elements(Points(X, Y, Legend(3)), Smoother(X, Y, Legend(4))),
SendToReport(
Dispatch({}, "FORCEDROPTIME_3", ScaleBox,
{Format("Best", 12), Min(Min(xx) - 30), Max(Max(xx) + 30), Inc(200),
Minor Ticks(1)}
),
Dispatch({}, "ACTUAL_MAXCHASEHOLDFORCE_4", ScaleBox,
{Format("Best", 12), Min(Min(yy) - 30), Max(Max(yy) + 30), Inc(100),
Minor Ticks(4)}
),
Dispatch({}, "Graph Builder", FrameBox,
{Add Graphics Script(
2,
Description(""),
Transparency(0.5);
Fill Color({1.0, 0.5, 0.0});
Polygon(
(Column(tb, "OffSetX_temp") << GetAsMatrix()),
(Column(tb, "OffSetY_temp") << GetAsMatrix())
);
Transparency(0.5);
Fill Color("Red");
Polygon(
(Column(tb, "X") << GetAsMatrix()),
(Column(tb, "Y") << GetAsMatrix())
);
)}
)
)
);
)
);
sb << Set Function(
Function({thisBox},
((((thisBox) << sib) << child) << sib) << Set Text(Char(thisBox << Get))
)
);