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
Username:
Password:
Save Password
Forgot your Password? | Admin Options

 All Forums
 Origin Forum for Programming
 Forum for Origin C
 Selecting Datapoints Problem
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

bubbas

Germany
Posts

Posted - 02/07/2007 :  05:04:54 AM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
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

Mike Buess

USA
3037 Posts

Posted - 02/07/2007 :  05:55:14 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

bubbas

Germany
Posts

Posted - 02/07/2007 :  07:54:46 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

bubbas

Germany
Posts

Posted - 02/07/2007 :  08:21:12 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/07/2007 :  09:11:08 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

bubbas

Germany
Posts

Posted - 02/07/2007 :  09:19:08 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply

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
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/07/2007 :  09:24:26 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

bubbas

Germany
Posts

Posted - 02/07/2007 :  09:52:20 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
ok thx anyway. perhaps i rewrite tomorrow the code hoping to find the mistake.

bye

bubbas
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/07/2007 :  10:00:54 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Sometimes it helps to put it aside and look at it later with fresh eyes. :)

Mike Buess
Origin WebRing Member
Go to Top of Page

bubbas

Germany
Posts

Posted - 02/07/2007 :  11:39:19 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/07/2007 :  2:40:21 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

bubbas

Germany
Posts

Posted - 02/08/2007 :  04:53:23 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/08/2007 :  09:49:40 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

bubbas

Germany
Posts

Posted - 02/08/2007 :  11:55:40 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page
  Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000