The Origin Forum
File Exchange
Try Origin for Free
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
 All Forums
 Origin Forum for Programming
 Forum for Origin C
 Selecting Datapoints Problem

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

Screensize:
UserName:
Password:
Anti-Spam Code:
Format Mode:
Format: BoldItalicizedUnderlineStrikethrough Align LeftCenteredAlign Right Horizontal Rule Insert HyperlinkUpload FileInsert Image Insert CodeInsert QuoteInsert List
   
Message:

* HTML is OFF
* Forum Code is ON
Smilies
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Clown [:o)]
Black Eye [B)] Eight Ball [8] Frown [:(] Shy [8)]
Shocked [:0] Angry [:(!] Dead [xx(] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
bubbas Posted - 02/07/2007 : 05:04:54 AM
Origin Version (Select Help-->About Origin): 7.5E SR6
Operating System: Win Xp Pro

Hey,

i want to let the user manually select a datapoint from a plot. The y-value of this datapoint is then used for later calculations.

So first i want to maximize the Graph where the user should select the Point.

For that i use a modified function found here in the forum:

void getdatapointfromgraph(string graphname, double& max, int& indexofpoint)
{
GraphPage pg;
pg = Project.GraphPages(graphname);


if( pg.IsValid() )
{
string setcmd;
GraphLayer gl = pg.Layers(); // Get active layer
printf("%s has %d layer(s)\n", pg.GetName(), pg.Layers.Count());
setcmd.Format("win -a %s", graphname);
LT_execute(setcmd); //Set graph active
setcmd.Format("win -z %s", graphname);
LT_execute(setcmd); //Maximize Graph
//DataPlot dp = gl.DataPlots(0);
//dp.SetActive(0,20);


int nPts=1;
// Declare vectors to hold coordinates
vector vecX, vecY, vecIndex;

// Call function to get points
int iRet = get_screen_reader_points(nPts, vecX, vecY, vecIndex, graphname);
if( iRet < 0 )
printf("Function call to get screen points returned error: %d\n", iRet);

printf("User clicked on %d points\n", iRet);

if( 0 != iRet )
{
printf("X, Y coordinates of points are:\n");
for(int ii = 0; ii < iRet; ii++)
{
indexofpoint = vecIndex[ii];
max=vecY[ii];
printf(" %d: X = %f, Y = %f Index= %d\n", ii, vecX[ii], vecY[ii], indexofpoint);
}
}

setcmd.Format("win -ia %s", graphname);
LT_execute(setcmd); //Minimize Graph and activate previous window



}
else
{
printf("Invalid Graphwindow (%s) for selecting Maximum ", graphname)
}


}

static int get_screen_reader_points(int nPts, vector& vecX, vector& vecY, vector& vecIndex, string graphname)
{
// Return error if number of points not appropriate
// Arbitrary upper limit of 99 - change as desired
if( nPts < 1 || nPts > 99) return -1;

// Run the LabTalk section in this file to give user control to click points
string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenPts,%d,%s)", strThisFile, nPts, graphname);
LT_execute(strCMD);

// On return, the LabTalk variable tmp_scr_count has number of points user clicked + 1
double dCount;
LT_get_var("tmp_scr_count", &dCount);
int nCount = (int) (dCount - 1);
if( 0 == nCount ) return 0;

// Get values of x, y coordinates from LabTalk variables and delete the vars
vecX.SetSize(nCount);
vecY.SetSize(nCount);
vecIndex.SetSize(nCount);
string strX, strY, strIndex;
double dX, dY, dIndex;
for(int ii = 1; ii <= nCount; ii++)
{
strX.Format("tmp_scr_pos_x%d", ii);
strY.Format("tmp_scr_pos_y%d", ii);
strIndex.Format("tmp_scr_pos_index%d", ii);
LT_get_var(strX, &vecX[ii - 1]);
LT_get_var(strY, &vecY[ii - 1]);
LT_get_var(strIndex, &vecIndex[ii - 1]);
strCMD.Format("del -v %s", strX);
LT_execute(strCMD);
strCMD.Format("del -v %s", strY);
LT_execute(strCMD);
strCMD.Format("del -v %s", strIndex);
LT_execute(strCMD);
}

// Delete the count LabTalk variable
LT_execute("del -v tmp_scr_count;");

// Return the number of points clicked by user
return nCount;
}



// This section of LabTalk will be ignored by compiler since it is contained within an ifdef block.
// The section of script within this block can then be successfully called by a run.section LabTalk command.
#ifdef LABTALK
[GetScreenPts]
// Number of points to get is passed as 1st parameter
// Select screen reader tool
dotool 3; // 2 screen Reader, 3 data reader

// Main loop to accept points
tmp_scr_count = 1;
def quittoolbox
{
// Check if user has clicked required number of points
if( 1 == tmp_scr_count )
done = 1;
if( %1 != tmp_scr_count )
return;
}


// Get points and store in temp string variables
def pointproc
{
tmp_scr_pos_x$(tmp_scr_count)=x;
tmp_scr_pos_y$(tmp_scr_count)=y;
tmp_scr_pos_index$(tmp_scr_count)=index;
if( tmp_scr_count >= %1 )
{
dotool 0;
// Set the variable to break the infinite loop
done = 1;
}
tmp_scr_count += 1;
}

// Set up an "infinite loop" so code waits for user to click points
for( done = 0; done == 0; )
{
// wait a while
sec -p 0.1;
}
#endif


But i have got the problem. That the Graph to select the point appears maximized, but if i try to select a datapoint it is not possible. It doesn't accept a doubleclick on the curve. It always selects a point far away from where i click. If i minimize the graph manually i can select without a problem, but that is not a solution ... Tried to minimize/maximize from script but it doesn't helps.

Thanks in advance

greetings

bubbas

13   L A T E S T    R E P L I E S    (Newest First)
bubbas Posted - 02/08/2007 : 11:55:40 AM
yes :)

thank you, that did the job now, finally ;)

didn't knew about SetPage. Thank you!

now i can think about other things *g*

Regards

bubbas
Mike Buess Posted - 02/08/2007 : 09:49:40 AM
Hi bubbas,

Beginning the LabTalk section with a brief delay appears to fix the problem...

[GetScreenPts]
// Number of points to get is passed as 1st parameter
// Select screen reader tool
sec -p 0.1; // wait
dotool 3; // 2 screen Reader, 3 data reader
// more commands

Your testdataget() and getdatapointfromgraph() functions both work and the latter works regardless of the initial state (normal, minimized or maximized) of the graph window.

FYI: Your script was apparently written for Origin 7. While it still works in 7.5 a few shortcuts are now available. For example, you can use PageBase::SetShow to minimize or maximize a window.

GraphPage pg(graphname);
pg.SetShow(PAGE_MAXIMIZED);
pg.SetShow(PAGE_MINIMIZED);

Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/08/2007 09:50:36 AM
bubbas Posted - 02/08/2007 : 04:53:23 AM
hi my getdatapointfromgraph(string graphname, double& max, int& indexofpoint) function is called by another originC function xrmr_ausl() ...

xrmr_ausl() is then called via script window but doesn't contain any & referenced arguments.

In my reduced version of the problem i would call testdataget() from script window. later i wan't to call it from a button on a worksheet via labtalk.

thx

bubbas
Mike Buess Posted - 02/07/2007 : 2:40:21 PM
Hi bubbas,

I can finally reproduce your problem using your original script. If the graph is minimized or maximized the script works fine. If graph is in between (restored) then I see the behaviour you described. Haven't figured out why yet.

One question: do you normally execute the function from the script window or another Origin C function. Must be the latter because I just get command error if I try from the script window. That's because of the referenced arguments: double& max, int& indexofpoint. Ampersands (&) must be removed for use in script window.

Mike Buess
Origin WebRing Member
bubbas Posted - 02/07/2007 : 11:39:19 AM
Yes sometimes ;) But i couldn't forget about it *g*

So i have reduced the problem to the minimum code i think!


void testdataget()
{
//Create wks
Worksheet wks1;
wks1.Create();
wks1.GetPage().Rename("wks1");


//Fill col1
Dataset ds1(wks1,0);
wks1.Columns(0).SetName("col1");
ds1.SetSize(20);

for(int ii=0; ii<20; ii++)
{
ds1[ii] = ii;
}

//Fill col2
Dataset ds2(wks1,1);
wks1.Columns(1).SetName("col2");
ds2.SetSize(20);
for(ii=0; ii<20; ii++)
{
ds2[ii] = ii;
}


string strTemplate = "origin.otp" ;


GraphPage grphData;
bool thegrph = grphData.Create(strTemplate);
GraphLayer grphLayer = grphData.Layers();
Curve crvData(wks1, 0, 1);
int nPlot = grphLayer.AddPlot(crvData, IDM_PLOT_LINE);
grphLayer.Rescale();
grphData.Rename("Graph1");

LT_execute("win -a Graph1");
LT_execute("win -z Graph1");
read_screen_points();


}







void read_screen_points(int nPts = 1)
{
// Declare vectors to hold coordinates
vector vecX, vecY;
// Call function to get points
int iRet = get_screen_reader_points(nPts, vecX, vecY);
if( iRet < 0 )
printf("Function call to get screen points returned error: %d\n", iRet);

printf("User clicked on %d points\n", iRet);
if( 0 != iRet )
{
printf("X, Y coordinates of points are:\n");
for(int ii = 0; ii < iRet; ii++)
printf(" %d: X = %f, Y = %f\n", ii, vecX[ii], vecY[ii]);
}
}




// This static function handles calling LabTalk to get user to click on the screen.
// Parameters:
// nPts: no. of points that user should click
// vecX: vector to hold x coordinates of points, passed by reference
// vecX: vector to hold y coordinates of points, passed by reference
// Return:
// -1: no. of points inappropriate
// >=0: no. of points user actually clicked
static int get_screen_reader_points(int nPts, vector& vecX, vector& vecY)
{
// Return error if number of points not appropriate
// Arbitrary upper limit of 99 - change as desired
if( nPts < 1 || nPts > 99) return -1;

// Run the LabTalk section in this file to give user control to click points
string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenPts,%d)", strThisFile, nPts);
LT_execute(strCMD);

// On return, the LabTalk variable tmp_scr_count has number of points user clicked + 1
double dCount;
LT_get_var("tmp_scr_count", &dCount);
int nCount = (int) (dCount - 1);
if( 0 == nCount ) return 0;

// Get values of x, y coordinates from LabTalk variables and delete the vars
vecX.SetSize(nCount);
vecY.SetSize(nCount);
string strX, strY;
double dX, dY;
for(int ii = 1; ii <= nCount; ii++)
{
strX.Format("tmp_scr_pos_x%d", ii);
strY.Format("tmp_scr_pos_y%d", ii);
LT_get_var(strX, &vecX[ii - 1]);
LT_get_var(strY, &vecY[ii - 1]);
strCMD.Format("del -v %s", strX);
LT_execute(strCMD);
strCMD.Format("del -v %s", strY);
LT_execute(strCMD);
}

// Delete the count LabTalk variable
LT_execute("del -v tmp_scr_count;");

// Return the number of points clicked by user
return nCount;
}

// This section of LabTalk will be ignored by compiler since it is contained within an ifdef block.
// The section of script within this block can then be successfully called by a run.section LabTalk command.
#ifdef LABTALK
[GetScreenPts]
// Number of points to get is passed as 1st parameter
// Select screen reader tool
dotool 3;

// Main loop to accept points
tmp_scr_count = 1;
def quittoolbox
{
// Check if user has clicked required number of points
if( 1 == tmp_scr_count )
done = 1;
if( %1 != tmp_scr_count )
return;
}

// Get points and store in temp string variables
def pointproc
{
tmp_scr_pos_x$(tmp_scr_count)=x;
tmp_scr_pos_y$(tmp_scr_count)=y;
if( tmp_scr_count >= %1 )
{
dotool 0;
// Set the variable to break the infinite loop
done = 1;
}
tmp_scr_count += 1;
}
// Set up an "infinite loop" so code waits for user to click points
for( done = 0; done == 0; )
{
// wait a while
sec -p 0.1;
}
#endif



The data on the curve is not selectable! if i minimize and maximize again manually then it is. Its really strange. Without setting a template it doesn't seem to appear .. but i need a template in the real project ...

thx again

bubbas
Mike Buess Posted - 02/07/2007 : 10:00:54 AM
Sometimes it helps to put it aside and look at it later with fresh eyes. :)

Mike Buess
Origin WebRing Member
bubbas Posted - 02/07/2007 : 09:52:20 AM
ok thx anyway. perhaps i rewrite tomorrow the code hoping to find the mistake.

bye

bubbas
Mike Buess Posted - 02/07/2007 : 09:24:26 AM
Sorry bubba, your correction is OK but I still can't reproduce your problem. Some other bug must have crept into your code.

Mike Buess
Origin WebRing Member
bubbas Posted - 02/07/2007 : 09:19:08 AM

string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenPts,%d)", strThisFile, nPts);
LT_execute(strCMD);



I made the correction ... I can remove the graphname option passed and it still behaves the same :(

thx

bubbas
Mike Buess Posted - 02/07/2007 : 09:11:08 AM
I don't think you made the correction. After pasting your original code to a new C file it behaved for me as you described. After removing the comma I can double-click on a point after which the graph will minimize and the following message is printed to the script window...

User clicked on 1 points
X, Y coordinates of points are:
0: X = 10.000000, Y = 10.000000 Index= 10

The coordinates are correct.

...The comma should be replaced by a space ' '.

Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/07/2007 09:16:47 AM
bubbas Posted - 02/07/2007 : 08:21:12 AM
no that didn't help ...

i think it is related to something y did before ...
 
if( MessageBox( GetWindow(), "Manual Selection of Maxima?", "Attention!" ,
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1 ) == IDYES )
{
setmanual=1;
}

if (setmanual==1)
{
double maxN=0;
int indexN=0;
double maxS=0;
int indexS=0;

//Korrfkt Nord
LT_execute("win -a grph_Ausl_AbsTheta_Nord");
LT_execute("win -z grph_Ausl_AbsTheta_Nord");
getdatapointfromgraph("grph_Ausl_AbsTheta_Nord", maxN, indexN);
printf("Maximum N Y=%f Index=%d\n", maxN, indexN);


dsXRMRKorrfktN_AbsTheta=dsXRMRnormAuslN_AbsTheta/maxN;

int iRowN=indexN;
int sizeN=dsXRMRKorrfktN_AbsTheta.GetSize();
for (int ii = iRowN+1; ii < sizeN ; ii++)
{
dsXRMRKorrfktN_AbsTheta[ii] = 1.0;
}

// Korrfkt Sued
LT_execute("win -a grph_Ausl_AbsTheta_Sued");
LT_execute("win -z grph_Ausl_AbsTheta_Sued");
getdatapointfromgraph("grph_Ausl_AbsTheta_Sued", maxS, indexS);
printf("Maximum S Y=%f Index=%d\n", maxS, indexS);


dsXRMRKorrfktS_AbsTheta=dsXRMRnormAuslS_AbsTheta/maxS;

int iRowS=indexS;
int sizeS=dsXRMRKorrfktS_AbsTheta.GetSize();
for (ii = iRowS+1; ii < sizeS ; ii++)
{
dsXRMRKorrfktS_AbsTheta[ii] = 1.0;
}

//Doubleplot of the functions used to normalize
colx = wks2.Columns("AbsTheta");
coly1 = wks2.Columns("Korrfkt.N");
coly2 = wks2.Columns("Korrfkt.S");
strColNameX = colx.GetName();
strColNameY1 = coly1.GetName();
strColNameY2 = coly2.GetName();
GraphTemplate = "Ausl";
GraphName = "Ausl_SAbs_KorrFkt";
xColNum = colx.GetIndex();
y1ColNum = coly1.GetIndex();
y2ColNum = coly2.GetIndex();
CreateDoublePlot(wks2, xColNum, y1ColNum, y2ColNum, GraphName, GraphTemplate, strPathToTemplate);
}
else
{
dsXRMRKorrfktN_AbsTheta=dsXRMRnormAuslN_AbsTheta;
dsXRMRKorrfktS_AbsTheta=dsXRMRnormAuslS_AbsTheta;
}


Previously i called the getdatapointfromgraph() function from the
 
if( MessageBox( GetWindow(), "Manual Selection of Maxima?", "Attention!" ,
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1 ) == IDYES )



I thought it could be a problem of the appearing messagebox. so i have
put it now separate. The first call now works well:
 
LT_execute("win -a grph_Ausl_AbsTheta_Nord");
LT_execute("win -z grph_Ausl_AbsTheta_Nord");
getdatapointfromgraph("grph_Ausl_AbsTheta_Nord", maxN, indexN);
The window appears maximized and accepts the selection. The next call
LT_execute("win -a grph_Ausl_AbsTheta_Sued");
LT_execute("win -z grph_Ausl_AbsTheta_Sued");
getdatapointfromgraph("grph_Ausl_AbsTheta_Sued", maxS, indexS);

doesn't work . The window appears maximized but i can't click on the curve. If I click somewhere else it accepts a point which is not on the curve. Moving the point around with the cursors shows that it walks on a curve which is shifted towards the curve shown on the graph. i don't know if it is the right one or one of the other graphs in the background perhaps ??

thx in advance

bubbas
bubbas Posted - 02/07/2007 : 07:54:46 AM
Oh thank you!

I will try that :)

Yes i only need one point to be selected. But didn't had time to change it everywhere. So i just set nPts = 1.

Regards

Bubbas
Mike Buess Posted - 02/07/2007 : 05:55:14 AM
Hi bubbas,

The odd data reader behaviour is due to an extra comma in the get_screen_reader_points function...

string strCMD;
//strCMD.Format("run.section(%s,GetScreenPts,%d,%s)", strThisFile, nPts, graphname); // wrong: red comma doesn't belong
strCMD.Format("run.section(%s,GetScreenPts,%d %s)", strThisFile, nPts, graphname); // correct: replace red comma with space

BTW, you declare int nPts=1 in the getdatapointfromgraph function and do not change it later. That means you can only get one point a time. Is that intentional?

Mike Buess
Origin WebRing Member

The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000