cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
  • JMP 19 is here! See the new features at jmp.com/new.
  • Register to attend Discovery Summit 2025 Online: Early Users Edition, Sept. 24-25.
Choose Language Hide Translation Bar
PhamBao
Level III

[Help] - How to get graph builder with polygon updated as slider changes

Hi all,
I am quite new in JSL scripting. Currently, I added Slider to change some variable in data table. Data table gets updated as  the slider change

In the next step, I would like to get data 2 column in the data table to turn them into matrix and starting draw Polygon in Graph Builder

However , I face some difficulty that once I move sliders, the content does not change:

1. I add one text box in New window and display Column value of data table

2. Polygon with coordinates from data table does not change in graph builder

My purpose is once I move slider, the content in Text Box and graph changes as well

PhamBao_0-1752997200474.png

 


Here is my code:

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))
	)
);
 
 

Hopefully, I could get some help

Appreciates

 

1 REPLY 1
Craige_Hales
Super User

Re: [Help] - How to get graph builder with polygon updated as slider changes

  • the variables offset_x and _y need to be defined, possibly as arrays
  • the sb<<setfunction at the end is probably overriding (and throwing away) the important bit "tb << Set Table Variable( "scaleFactor", sliderValue )"
  • Possibly something like this will make it more interactive once the offsets are defined
sb << Set Function(
	Function( {thisBox},
		((((thisBox) << sib) << child) << sib) << Set Text( Char( thisBox << Get ) );
		tb << Set Table Variable( "scaleFactor", sliderValue );
		tb << rerunformulas;
		chartdisplay << inval << reshow;
	)
);

edit: added

offset_x = j(19999,1,0);
offset_y = j(19999,1,0);

near the top and it does look interesting.

 

Craige

Recommended Articles