Hi,
From a table with two columns defining X and Y coordinates, I'm trying to create a graph box with an interactive handle for each point defined in the table. Adding handles one by one (see nw1 below) works perfectly, but when I try to automate the process by using ForEachRow or a For loop (see nw2 and nw3), I get a graph box with the points, but they can't be moved interactively. What would be the correct way to automate the creation of the handles?
Thanks, Ãtienne
dt = NewTable("DataPoints", AddRows(3),
NewColumn("xVar", Numeric, "Continuous", SetValues( [1, 2, 3])),
NewColumn("yVar", Numeric, "Continuous", SetValues( [1, 2, 3]))
);
CurrentDataTable(dt);
nw1 = NewWindow("Example 1",
gr1 = GraphBox(
FrameSize(400, 400), XScale(0, 5), YScale(0, 5),
Handle(:xVar[1], :yVar[1], :xVar[1] = x; :yVar[1] = y;);
Handle(:xVar[2], :yVar[2], :xVar[2] = x; :yVar[2] = y;);
Handle(:xVar[3], :yVar[3], :xVar[3] = x; :yVar[3] = y;);
);
);
nw2 = NewWindow("Example 2",
gr2 = GraphBox(
FrameSize(400, 400), XScale(0, 5), YScale(0, 5),
ForEachRow(
Handle(:xVar, :yVar, :xVar = x; :yVar = y;);
);
);
);
nw3 = NewWindow("Example 3",
gr3 = GraphBox(
FrameSize(400, 400), XScale(0, 5), YScale(0, 5),
For(i=1, i<=NRows(dt), i++,
Handle(:xVar[i], :yVar[i], :xVar[i] = x; :yVar[i] = y;);
);
);
);
Thanks @cwillden. Your solution works perfectly and it's scalable. It reminds me of SAS macro code, which is essentially what I was trying to do here, i.e. write out the for loop and then execute it.
Hi @rassart,
This one case where you need to hard-code in the row values from your table when adding the handles. The reason becomes apparent when you get the graphics script you just created back out of graph box from your window. For example, the graphics script from Example 3 looks like this afterward:
gr3 << Get Graphics Script;
/*:
{For( i = 1, i <= N Rows( dt ), i++,
Handle(
:xVar[i],
:yVar[i],
:xVar[i] = x;
:yVar[i] = y;
)
)}The final value of the variable 'i' will be set to 4 with your example, so none of the handles will work properly since the value of 'i' was not hard-coded in. Without hard-coding, the graphics script will always rely on the current value of 'i'.
Here's a way you can hard-code these values in using a for-loop:
nw4 = New Window( "Example 4", gr4 = Graph Box( FrameSize( 400, 400 ), X Scale( 0, 5 ), Y Scale( 0, 5 ), ) );
For( i = 1, i <= N Rows( dt ), i++,
Eval( Parse( Eval Insert( "gr4[framebox(1)] << Add Graphics Script(Handle(:xVar[^i^], :yVar[^i^], :xVar[^i^] = x; :yVar[^i^] = y;));" ) ) )
);
Apparently the Handle() function is not able to handle the parsing at the time of exectution. The following script will compensate for that
Current Data Table( dt );
nw1 = New Window( "Example 1",
gr1 = Graph Box(
FrameSize( 400, 400 ),
X Scale( 0, 5 ),
Y Scale( 0, 5 ),
Handle(
:xVar[1],
:yVar[1],
:xVar[1] = x;
:yVar[1] = y;
);
Handle(
:xVar[2],
:yVar[2],
:xVar[2] = x;
:yVar[2] = y;
);
Handle(
:xVar[3],
:yVar[3],
:xVar[3] = x;
:yVar[3] = y;
);
)
);