cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
JMP is taking Discovery online, April 16 and 18. Register today and join us for interactive sessions featuring popular presentation topics, networking, and discussions with the experts.
matlag
Level III

Dispatch to dynamically generated piled charts

Hi all,

I try to generate a report in which I have 2 charts per "parameter" for median and stdev, and I'm struggling adding lines in it.

 

The "Summary.jmp" file contains multiple columns with a "Lot" (I use it as the X axis), and then several parameters, each of them having a column for median with suffix "_Q50" and one with suffix "_StdDev".

I have a list of parameters that have in addition Target, LowerSpecsLimit and UpperSpecsLimits (TGT, LSL, USL). I don't have them directly in the columns as they can change based on the "Lot" set I select and I would actually prefer not touching the file at all, to make sure I don't leave a mess behind if the script fails for whatever reason.

I also have Dispatch to replace the titles and axes labels.

 

I then have a function that generates the median and stdev charts on top of each other, charts are fine.

 

But no matter what I put in the dispatch section, I get an error

"Cannot find ScaleBox ... at {}"

and all the TextEditor dispatch seem to do nothing (not even an error, but I assume the function stops at the first dispatch error?)

 

I generated the charts and made manual modification to check the resulting script, and it didn't help. It uses "Param1_Q50" directly, and even that does not work when I put it back in the script!

 

Here is the code:

 

NamesDefaultToHere(1);

Open("Summary.jmp");

GraphXSize = 800;
GraphYSize = 600;

ParamsList = {
	{"Param1", "Name1", 0, -10, 10},
	{"Param2", "Name2", 50, 25, 75}
};

ParamGraph = Function (
	{parameter, title, tgt=".", lsl=".", usl="."},
	LOCAL(
		{Default Local},
		medianCol = parameter || "_Q50";
		stdevCol = parameter || "_StdDev";
		gb = Graph Builder(
			Size(GraphXSize,GraphYSize),
			Show Control Panel(0),
			Show Footer(0),
			Show Legend(0),
			Variables(
				X(:Name("Lot")),
				Y(Column(medianCol)),
				Y(Column(stdevCol)),
				Color(:Lot)
			),
			Elements(
				Points(X, Y, Legend(6))	
			),
			SendToReport(
				Dispatch(
					{},
					medianCol,
					ScaleBox,
					{IF(tgt != ".", Add Ref Line(tgt, "Solid", "Black", "TARGET", 1)),
					IF(lsl != ".", Add Ref Line(lsl, "Solid", "Purple", "LSL", 1)),
					IF(usl != ".", Add Ref Line(usl, "Solid", "Red", "USL", 1))}
				),
				Dispatch({}, "graph title", TextEditor, {Set Text(title)}),
				Dispatch({}, "Y title", TextEditor, {Set Text("Median")}),
				Dispatch({}, "Y 1 title", TextEditor, {Set Text("Std Dev")})
			),
		);
	);
);
	

New Window("Summary - Report", 
	For(i=1, i<=Length(ParamsList), i++,
		ParamGraph(ParamsList[i][1], ParamsList[i][2], ParamsList[i][3], ParamsList[i][4], ParamsList[i][5])
	)
) << Set Window Icon("Trellis")

I even tried to replace medianCol in the Dispatch section with "Param1_Q50", to see if that was a substitution issue, expecting the first chart would get the lines and not the others, but... it didn't work!

 

I also tried getting reference to the report

 

rgb = gb << report;
rgb[TextEditBox(5)] << Set Text("Median");

But I get an error message again:

 

Cannot subscript Display Box in access or evaluation of 'Subscript' , rgb[/*###*/"TextEditor"]

 

Does anyone know how I can address the elements of these charts??

 

Thanks in advance!!

1 ACCEPTED SOLUTION

Accepted Solutions
txnelson
Super User

Re: Dispatch to dynamically generated piled charts

I ran my script with your summary table under JMP 12.2 and it ran without error.  Below is the script that includes your summary table, and my reworked script

Names Default To Here( 1 );

//Open("Summary.jmp");
dtsumm = New Table( "Summary",
	Add Rows( 6 ),
	New Column( "Lot",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [1, 2, 3, 4, 5, 6] )
	),
	New Column( "Param1_Q50",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [-3, 7, 8, -12, 5, 0] )
	),
	New Column( "Param1_StdDev",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [0.2, 1, 0.6, 2, 0.2, 0.3] )
	),
	New Column( "Param2_Q50",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [23, 18, 54, 62, 78, 45] )
	),
	New Column( "Param2_StdDev",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [0.9, 1.2, 7, 3.6, 4.2, 1] )
	)
);


// Run the script
GraphXSize = 800;
GraphYSize = 600;

ParamsList = {{"Param1", "Name1", 0, -10, 10},
 {"Param2", "Name2", 50, 25, 75}};

ParamGraph = Function( {parameter, title, tgt = ., lsl = ., usl = .},
	Local( {Default Local},
		medianCol = parameter || "_Q50";
		stdevCol = parameter || "_StdDev";
		Eval(
			Substitute(
					Expr(
						gb = dtSumm << Graph Builder(
							Size( __GraphXSize__, __GraphYSize__ ),
							Show Control Panel( 0 ),
							Show Legend( 0 ),
							Show Footer( 0 ),
							Variables( X( :lot ), Y( __Q50__ ), Y( __Std__ ), Color( :lot ) ),
							Elements( Position( 1, 1 ), Points( X, Y, Legend( 6 ) ) ),
							Elements( Position( 1, 2 ), Points( X, Y, Legend( 7 ) ) ),
							SendToReport(
								Dispatch( {}, "graph title", TextEditBox, {Set Text( __title__ )} ),
								Dispatch( {}, "Y title", TextEditBox, {Set Text( "Median" )} ),
								Dispatch( {}, "Y 1 title", TextEditBox, {Set Text( "Std Dev" )} )
							)
						)
					),
				Expr( __GraphXSize__ ), GraphXSize,
				Expr( __GraphYSize__ ), GraphYSize,
				Expr( __Q50__ ), Parse( MedianCol ),
				Expr( __Std__ ), Parse( stdevCol ),
				Expr( __Title__ ), title
			)
		);

		If( Is Missing( tgt ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( tgt, "Solid", Black, "TARGET", 1 )
		);
		If( Is Missing( lsl ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( lsl, "Solid", Purple, "LSL", 1 )
		);
		If( Is Missing( usl ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( usl, "Solid", Red, "USL", 1 )
		);
	)
);
	

New Window( "Summary - Report",
	For( i = 1, i <= Length( ParamsList ), i++,
		ParamGraph( ParamsList[i][1], ParamsList[i][2], ParamsList[i][3], ParamsList[i][4], ParamsList[i][5] )
	)
) << Set Window Icon( "Trellis" );
Jim

View solution in original post

11 REPLIES 11
David_Burnham
Super User (Alumni)

Re: Dispatch to dynamically generated piled charts

It would be a lot easier to help youif you can provide us with code that we can run.  Which means either providing the table 'summary.jmp' or rewriting the code to work with one of the sample data tables that come with JMP.  

-Dave
matlag
Level III

Re: Dispatch to dynamically generated piled charts

Hi David,

 

Here's a summary.jmp.

David_Burnham
Super User (Alumni)

Re: Dispatch to dynamically generated piled charts

Thanks - looks like Jim has you covered

-Dave
txnelson
Super User

Re: Dispatch to dynamically generated piled charts

You have a mismatch in data types for your limits.  The "Add Ref Line" requires that the line value(first value) needs to be a numeric value.  In your function, you are setting it to a character string.  

ParamGraph = Function( {parameter, title, tgt = ".", lsl = ".", usl = "."}

and in your If statement

If( tgt != ".",

The element list needs to be changed to numeric 

ParamGraph = Function( {parameter, title, tgt = ".", lsl = ., usl = .}

and the If statement needs to be changed to:

If( IsMissing(tgt) == 0,
Jim
matlag
Level III

Re: Dispatch to dynamically generated piled charts

Hi Jim,

 

Thanks! I did the correction, but it didn't fix my issue.

 

Cannot find ScaleBox["medianCol"] at {}

 

or if I hard code it":

Cannot find ScaleBox["Param1_Q50"] at {}

 

Note that if I remove the second Y axis chart, then suddenly the ref lines work, but not titles and axes renaming.

matlag
Level III

Re: Dispatch to dynamically generated piled charts

After a lot of try and fails, I managed to do it (not very intuitive!)

 

So, I didn't use SendToReport, but I used subscripting.

If I have it inside the function, it does not work. I had to take it out:

 

NamesDefaultToHere(1);

Open("Summary.jmp");

GraphXSize = 800;
GraphYSize = 600;

ParamsList = {
	{"Param1", "Name1", 0, -10, 10},
	{"Param2", "Name2", 50, 25, 75}
};

ParamGraph = Function (
	{parameter, title, tgt=., lsl=., usl=.},
	LOCAL(
		{Default Local},
		medianCol = parameter || "_Q50";
		stdevCol = parameter || "_StdDev";
		return = Graph Builder(
			Size(GraphXSize,GraphYSize),
			Show Control Panel(0),
			Show Footer(0),
			Show Legend(0),
			Variables(
				X(:Name("Lot")),
				Y(Column(medianCol)),
				Y(Column(stdevCol)),
				Color(:Lot)
			),
			Elements(
				Points(X, Y, Legend(6))	
			)
		);
	);
);


wind = New Window("Summary - Report", 
	For(i=1, i<=Length(ParamsList), i++,
		gb= ParamGraph(ParamsList[i][1], ParamsList[i][2], ParamsList[i][3], ParamsList[i][4], ParamsList[i][5]);
		rgb = gb << report;
		rgb << showtreestructure;
		IF(
			IsMissing(ParamsList[i][3]) == 0,
			rgb[PictureBox(1), GraphBuilderBox(1), GraphBuilderAxisBox(2)] << Add Ref Line(ParamsList[i][3], "Solid", "Black", "TARGET", 1);
		);
		IF(
			IsMissing(ParamsList[i][4]) == 0,
			rgb[PictureBox(1), GraphBuilderBox(1), GraphBuilderAxisBox(2)] << Add Ref Line(ParamsList[i][4], "Solid", "Purple", "LSL", 1);
		);
		IF(
			IsMissing(ParamsList[i][5]) == 0,
			rgb[PictureBox(1), GraphBuilderBox(1), GraphBuilderAxisBox(2)] << Add Ref Line(ParamsList[i][5], "Solid", "Red", "USL", 1);
		);
		rgb[PictureBox(1), GraphBuilderBox(1), GraphBuilderTitleBox(1)] << Set Text(ParamsList[i][2]);
		rgb[PictureBox(1), GraphBuilderBox(1), GraphBuilderTitleBox(3)] << Set Text ("Median");
		rgb[PictureBox(1), GraphBuilderBox(1), GraphBuilderTitleBox(4)] << Set Text ("Standard Deviation");	
	)
) << Set Window Icon("Trellis");

Also note the line:

		rgb << showtreestructure;

If I don't have it, it does not work!

 

And that's quite annoying since I don't know how to automatically close it after, but at least, it works now!

txnelson
Super User

Re: Dispatch to dynamically generated piled charts

I think you will find this example a more straight forward way of handling what you want

I am not sure of the final format being exactly correct, but I believe you can easily modify it to meet your needs

Names Default To Here( 1 );

//Open("Summary.jmp");

// Create a Sample data table
dt = Open( "$SAMPLE_DATA\semiconductor capability.jmp" );

dt:npn1 << delete property( "spec limits" );
dt:pnp1 << delete property( "spec limits" );

dt:npn1 << set name( "Param1" );
dt:pnp1 << set name( "Param2" );
dt:lot_id << set name( "lot" );

dtSumm = dt << Summary(
	Group( :lot ),
	Median( :Param1 ),
	Std Dev( :Param1 ),
	Median( :Param2 ),
	Std Dev( :Param2 ),
	Freq( "None" ),
	Weight( "None" ),
	statistics column name format( "column stat" )
);
dtSumm:Param1 Median << set name( "Param1_Q50" );
dtSumm:Param2 Median << set name( "Param2_Q50" );
dtSumm:Param1 Std Dev << set name( "Param1_StdDev" );
dtSumm:Param2 Std Dev << set name( "Param2_StdDev" );

// Run the script
GraphXSize = 800;
GraphYSize = 600;

ParamsList = {{"Param1", "Name1", 0, -10, 10},
 {"Param2", "Name2", 50, 25, 75}};

ParamGraph = Function( {parameter, title, tgt = ., lsl = ., usl = .},
	Local( {Default Local},
		medianCol = parameter || "_Q50";
		stdevCol = parameter || "_StdDev";
		Eval(
			Substitute(
					Expr(
						gb = dtSumm << Graph Builder(
							Size( __GraphXSize__, __GraphYSize__ ),
							Show Control Panel( 0 ),
							Show Legend( 0 ),
							Show Footer( 0 ),
							Variables( X( :lot ), Y( __Q50__ ), Y( __Std__ ), Color( :lot ) ),
							Elements( Position( 1, 1 ), Points( X, Y, Legend( 6 ) ) ),
							Elements( Position( 1, 2 ), Points( X, Y, Legend( 7 ) ) ),
							SendToReport(
								Dispatch( {}, "graph title", TextEditBox, {Set Text( __title__ )} ),
								Dispatch( {}, "Y title", TextEditBox, {Set Text( "Median" )} ),
								Dispatch( {}, "Y 1 title", TextEditBox, {Set Text( "Std Dev" )} )
							)
						)
					),
				Expr( __GraphXSize__ ), GraphXSize,
				Expr( __GraphYSize__ ), GraphYSize,
				Expr( __Q50__ ), Parse( MedianCol ),
				Expr( __Std__ ), Parse( stdevCol ),
				Expr( __Title__ ), title
			)
		);

		If( Is Missing( tgt ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( tgt, "Solid", Black, "TARGET", 1 )
		);
		If( Is Missing( lsl ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( lsl, "Solid", Purple, "LSL", 1 )
		);
		If( Is Missing( usl ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( usl, "Solid", Red, "USL", 1 )
		);
	)
);
	

New Window( "Summary - Report",
	For( i = 1, i <= Length( ParamsList ), i++,
		ParamGraph( ParamsList[i][1], ParamsList[i][2], ParamsList[i][3], ParamsList[i][4], ParamsList[i][5] )
	)
) << Set Window Icon( "Trellis" );


Jim
matlag
Level III

Re: Dispatch to dynamically generated piled charts

Hi Jim,

 

I tried it on my ref summary.jmp file, and...

Cannot find TextEditBox[ "graph title" ] at {}
Cannot find TextEditBox[ "Y title" ] at {}
Cannot find TextEditBox[ "Y 1 title" ] at {}
Cannot subscript Display Box in access or evaluation of 'Subscript' , Report( gb )[/*###*/AxisBox( 3 )]

So, if this is a bug, I should mention I am on JMP 12.1.0 64bits.

 

But anyway, it works with my (dirty) code, so I'll deal with it. I will just have a ton of tree structure windows to close...

txnelson
Super User

Re: Dispatch to dynamically generated piled charts

I ran my script with your summary table under JMP 12.2 and it ran without error.  Below is the script that includes your summary table, and my reworked script

Names Default To Here( 1 );

//Open("Summary.jmp");
dtsumm = New Table( "Summary",
	Add Rows( 6 ),
	New Column( "Lot",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [1, 2, 3, 4, 5, 6] )
	),
	New Column( "Param1_Q50",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [-3, 7, 8, -12, 5, 0] )
	),
	New Column( "Param1_StdDev",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [0.2, 1, 0.6, 2, 0.2, 0.3] )
	),
	New Column( "Param2_Q50",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [23, 18, 54, 62, 78, 45] )
	),
	New Column( "Param2_StdDev",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [0.9, 1.2, 7, 3.6, 4.2, 1] )
	)
);


// Run the script
GraphXSize = 800;
GraphYSize = 600;

ParamsList = {{"Param1", "Name1", 0, -10, 10},
 {"Param2", "Name2", 50, 25, 75}};

ParamGraph = Function( {parameter, title, tgt = ., lsl = ., usl = .},
	Local( {Default Local},
		medianCol = parameter || "_Q50";
		stdevCol = parameter || "_StdDev";
		Eval(
			Substitute(
					Expr(
						gb = dtSumm << Graph Builder(
							Size( __GraphXSize__, __GraphYSize__ ),
							Show Control Panel( 0 ),
							Show Legend( 0 ),
							Show Footer( 0 ),
							Variables( X( :lot ), Y( __Q50__ ), Y( __Std__ ), Color( :lot ) ),
							Elements( Position( 1, 1 ), Points( X, Y, Legend( 6 ) ) ),
							Elements( Position( 1, 2 ), Points( X, Y, Legend( 7 ) ) ),
							SendToReport(
								Dispatch( {}, "graph title", TextEditBox, {Set Text( __title__ )} ),
								Dispatch( {}, "Y title", TextEditBox, {Set Text( "Median" )} ),
								Dispatch( {}, "Y 1 title", TextEditBox, {Set Text( "Std Dev" )} )
							)
						)
					),
				Expr( __GraphXSize__ ), GraphXSize,
				Expr( __GraphYSize__ ), GraphYSize,
				Expr( __Q50__ ), Parse( MedianCol ),
				Expr( __Std__ ), Parse( stdevCol ),
				Expr( __Title__ ), title
			)
		);

		If( Is Missing( tgt ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( tgt, "Solid", Black, "TARGET", 1 )
		);
		If( Is Missing( lsl ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( lsl, "Solid", Purple, "LSL", 1 )
		);
		If( Is Missing( usl ) == 0,
			report(gb)[AxisBox( 3 )] << Add Ref Line( usl, "Solid", Red, "USL", 1 )
		);
	)
);
	

New Window( "Summary - Report",
	For( i = 1, i <= Length( ParamsList ), i++,
		ParamGraph( ParamsList[i][1], ParamsList[i][2], ParamsList[i][3], ParamsList[i][4], ParamsList[i][5] )
	)
) << Set Window Icon( "Trellis" );
Jim