Graph Builder is extremely complicated platform and we don't have easy access what it has from just a frame box (where the graphic script is). If I had to make this as dynamic as possible when using column properties, something like this is one option:
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Semiconductor Capability.jmp");
gb = dt << Graph Builder(
Size(789, 594),
Show Control Panel(0),
Fit to Window("On"),
Variables(X(:PNP1), Y(:NPN1)),
Elements(Points(X, Y, Legend(3))),
Column Switcher(
:NPN1,
{:NPN1, :PNP2, :NPN2, :PNP3, :IVP1, :PNP4, :NPN3, :IVP2, :NPN4, :SIT1, :INM1,
:INM2, :VPM1, :VPM2, :VPM3, :PMS1, :SNM1, :SPM1, :NPN5, :EP2, :ZD6, :PBA,
:PLG, :CAP, :PBA3, :PLG2, :PNP5, :NPN6, :PNP6, :PNP7, :NPN7, :PNP8, :IVP3,
:IVP4, :IVP5, :IVP6, :PNP9, :NPN8, :NPN9, :IVP7, :NPN10, :N_1, :PBA1, :WPR1,
:B10, :PLY10, :VBE210, :VTN210, :VTP210, :SIT2, :SIT3, :INV2, :INV3, :INV4,
:INV5, :FST1, :FST2, :RES1, :RES2, :PNM1, :PPM1, :FNM1, :FPM1, :FST3, :FST4,
:RES3, :RES4, :A1, :B1, :A2N, :A2P, :A2P1, :IVP8, :IVP9, :DE_H1, :NF_H1,
:ESM1, :ESM2, :ESP1, :YFU1, :VPM4, :PBA2, :PBB1, :LYA1, :LYB1, :DEM1, :DEP1,
:NFM1, :PLY1, :VDP1, :VDP2, :SNW1, :RSP2, :PLY2, :RSP1, :VDP3, :PBL1, :PLG1,
:VDP4, :SPW1, :VIA1, :INM3, :VPM5, :VPM6, :INM4, :VPM7, :M1_M1, :M2_M2,
:P1_P1, :E2A1, :E2B1, :NPN11, :IVP10, :PNP10, :INM5, :VPM8, :VPM9, :INM6,
:VPM10, :N2A1, :N2B1, :NM_L1, :P2A1, :P2B1, :PM_L1, :P1, :M1},
Layout(1)
),
Column Switcher(
:PNP1,
{:PNP1, :PNP2, :NPN2, :PNP3, :IVP1, :PNP4, :NPN3, :IVP2, :NPN4, :SIT1, :INM1,
:INM2, :VPM1, :VPM2, :VPM3, :PMS1, :SNM1, :SPM1, :NPN5, :EP2, :ZD6, :PBA,
:PLG, :CAP, :PBA3, :PLG2, :PNP5, :NPN6, :PNP6, :PNP7, :NPN7, :PNP8, :IVP3,
:IVP4, :IVP5, :IVP6, :PNP9, :NPN8, :NPN9, :IVP7, :NPN10, :N_1, :PBA1, :WPR1,
:B10, :PLY10, :VBE210, :VTN210, :VTP210, :SIT2, :SIT3, :INV2, :INV3, :INV4,
:INV5, :FST1, :FST2, :RES1, :RES2, :PNM1, :PPM1, :FNM1, :FPM1, :FST3, :FST4,
:RES3, :RES4, :A1, :B1, :A2N, :A2P, :A2P1, :IVP8, :IVP9, :DE_H1, :NF_H1,
:ESM1, :ESM2, :ESP1, :YFU1, :VPM4, :PBA2, :PBB1, :LYA1, :LYB1, :DEM1, :DEP1,
:NFM1, :PLY1, :VDP1, :VDP2, :SNW1, :RSP2, :PLY2, :RSP1, :VDP3, :PBL1, :PLG1,
:VDP4, :SPW1, :VIA1, :INM3, :VPM5, :VPM6, :INM4, :VPM7, :M1_M1, :M2_M2,
:P1_P1, :E2A1, :E2B1, :NPN11, :IVP10, :PNP10, :INM5, :VPM8, :VPM9, :INM6,
:VPM10, :N2A1, :N2B1, :NM_L1, :P2A1, :P2B1, :PM_L1, :P1, :M1},
Layout(1)
)
);
fb = Report(gb)[FrameBox(1)];
// Graphic script doesn't even know where it is -> we have to evaluate that
// to make this evaluation a bit easier, we could evaluate the graph builder reference
Eval(EvalExpr(
fb << Add Graphics Script(
mygb = Expr(gb); // with gb we can access Y and X axis. This is assuming uiser might be using Column Switcher
xcol = "";
ycol = "";
For Each({var}, mygb << get variables,
If(var["Role"] == "X",
xcol = var[1] << get name;
, var["Role"] == "Y",
ycol = var[1] << get name;
);
);
xspecs = Column(mygb << Get Data Table, xcol) << Get Property("Spec Limits");
yspecs = Column(mygb << Get Data Table, ycol) << Get Property("Spec Limits");
Pen Color("Red");
Pen Size(2);
Rect(xspecs["LSL"], yspecs["USL"], xspecs["USL"], yspecs["LSL"], 0);
Fill Color("Green");
Transparency(0.2);
Rect(xspecs["LSL"], yspecs["USL"], xspecs["USL"], yspecs["LSL"], 1);
/*
// You might want to add dynamic scaling to X/Y axis as JMP isn't able to handle it
// if column properties do not have Show as Graph Reference lines enabled
// on problem is that user cannot really "scale" the axis if this is used
// as it will be always scaled back
// this can also "break"
xmin = Min(xspecs["LSL"], Col Min(Column(mygb << Get Data Table, xcol)));
xmax = Max(xspecs["USL"], Col Max(Column(mygb << Get Data Table, xcol)));
ymin = Min(yspecs["LSL"], Col Min(Column(mygb << Get Data Table, ycol)));
ymax = Max(yspecs["USL"], Col Max(Column(mygb << Get Data Table, ycol)));
xmin *= If(xmin < 0, 1.1, 0.9);
xmax *= If(xmax < 0, 0.9, 1.1);
ymin *= If(ymin < 0, 1.1, 0.9);
ymax *= If(ymax < 0, 0.9, 1.1);
myfb = Report(mygb)[FrameBox(1)];
myfb << X Axis(Min(xmin), Max(xmax));
myfb << Y Axis(Min(ymin), Max(ymax));
// Other option could be to enable show graph reference lines
// and then dynamically try to hide the lines/text (not sure how well this would work)
*/
);
));
Write();
This can be most likely made much simpler and faster depending on the real use case. The simplest option (in my opinion) is to use Eval(EvalExpr()) (or Substitute() to evaluate the values inside graphic script which utilizes Rect() (like I did show in my first response)
-Jarmo