3.1.4 Data Selection



Version Info

Minimum Origin Version Required: Origin8 SR0

Remark

DataRange class introduced from Origin8.0. The major advantage of this class is to avoid pass large data from workseet or matrix to do analysis, plot and so on, just need pass a data range, for example two columns with XY data, the whole matrix.

More details please reference to the following Origin C Reference sections:

DataRange Class

XYRange Class

XYZRange Class

Get Data from Worksheet by DataRange

void get_data_from_wks()
{
	Worksheet wks = Project.ActiveLayer();
	if( !wks )
	{
		out_str("Please keep a worksheet active with data");
		return;
	}	
    
	// The following settings to set range as whole worksheet, index offset is 0, -1 means last row/column.
	// Change r1, c1, r2, c2 to specify worksheet sub range, for example, 
	// r1 = 0, c1 = 1, r2 = -1, c2 = 2 to select all rows from column 2 to column 3.
    int r1 = 0; // first row
    int c1 = 0; // first column
    int r2 = -1; // last row
    int c2 = -1; // last column
    
    //construct a data range object from worksheet all data
    DataRange dr;
    dr.Add("X", wks, r1, c1, r2, c2); 
    
    // get data from worksheet to vector by column one by one    
    matrix mData; 
    dr.GetData(mData); // get all data to matrix
    
    for(int nColIndex = 0; nColIndex < mData.GetNumCols(); nColIndex++)
    {
    	vector vOneCol;
    	mData.GetColumn(vOneCol, nColIndex);
    	
    	double min, max;
    	vOneCol.GetMinMax(min, max);
    	
    	printf("Maximum value of %d column = %f\n", nColIndex+1, max);
    }	
}

Set Data to Worksheet by DataRange

Generate xy data and put to worksheet two columns.

void prepare_data()
{
	Worksheet wks;
	wks.Create("Origin");
	
	XYRange drIn;
	drIn.Add(wks, 0, "X"); // the first column as X
	drIn.Add(wks, 1, "Y"); // the second column as Y
	
	int nNumPoints = 100;
	vector vx;
	vx.Data(1, nNumPoints, 1);
	
	vector vy(nNumPoints);
	for(int ii=0; ii<nNumPoints; ii++)
		vy[ii] = rnd();
	vy.Sort();
	
	drIn.SetData(&vy, &vx);	// set vy to the second column, set vx to the first column.
}

Pass DataRange Reference as Argument

Before running calculate_with_xy_data please run the above prepare_data function to prepare xy data in worksheet.

void calculate_with_xy_data()
{
	Worksheet wks = Project.ActiveLayer();
	if( wks )
	{
		XYRange drIn;
		drIn.Add(wks, 0, "X");
		drIn.Add(wks, 1, "Y");
		
		double a, b;
		if( do_linear_fit(drIn, a, b) )
			printf("a=%f\nb=%f\n", a, b);
	}
}

// pass source xy data by DataRange reference to do linear fit, and then return a and b parameters.
bool do_linear_fit(XYRange& drIn, double& a, double& b)
{
	vector vx, vy;
	drIn.GetData(vy, vx);
	
	int nSize = vy.GetSize();
	if( 0 == nSize )
		return false;
	
	FitParameter stFitParameters[2];
	if( STATS_NO_ERROR == ocmath_linear_fit(vx, vy, nSize, stFitParameters) )
	{
		a = stFitParameters[0].Value;
    	b = stFitParameters[1].Value;
    	return true;
	}
	return false;
}

Plot by DataRange

Plot XY data as scatter.

void plot_scatter()
{
	Worksheet wks = Project.ActiveLayer();
	if( wks )
	{
		XYRange drIn;
		drIn.Add(wks, 0, "X");
		drIn.Add(wks, 1, "Y");
		
		GraphPage gp;
		gp.Create("Origin");
		GraphLayer gl = gp.Layers(0);
		if( 0 == gl.AddPlot(drIn, IDM_PLOT_SCATTER) )
			gl.Rescale();
	}	
}

Plot two columns data as box chart in one graph layer.

void plot_box_chart()
{
	Worksheet wks;
	wks.Create("Origin");
	
	vector vData;
	vData.Data(1, 20 ,1); 
	
	DataRange dr;
	dr.Add(wks, 0, "X"); // 0 means the first sub range
	dr.SetData(vData, false, 0); 
	
	vData = vData * 0.5;
	dr.Add(wks, 1, "X"); // 1: the second sub range
	dr.SetData(vData, false, 1); 
	
	GraphPage gp;
	gp.Create("Box");
	GraphLayer gl = gp.Layers(0); // get the first layer
	if( 0 == gl.AddPlot(dr, IDM_PLOT_BOX) )
		gl.Rescale();
}

Plot selected worksheet range.

// this example shows how to plot the selcted xy range from worksheet to a new graph 
void plot_selection()
{
	DataRange dr;
	if( EXIST_WKS == Project.GetSelection(dr) )
	{
		GraphPage gp;
		gp.Create();
		GraphLayer gl = gp.Layers();
				
		int nNumRanges = dr.GetNumRanges();		
		for(int nRange = 0; nRange < nNumRanges; nRange++)
		{
			Worksheet wks;
			int r1, c1, r2, c2;
			if( dr.GetRange(nRange, r1, c1, r2, c2, wks) // return true if has selection in worksheet
				&& ( c1 >=0 && c2 >=0 && c1+1 == c2 || c1 >= 0 && c2 < 0 && c1+1 == wks.GetNumCols() -1 ) ) // to check if two columns. One for X, another for Y
			{		
				XYRange xy;
				xy.Add("X", wks, r1, c1, r2, c1);
				xy.Add("Y", wks, r1, c2, r2, c2);
				
				if( gl.AddPlot(xy, IDM_PLOT_SCATTER) >= 0 )
					gl.Rescale();
			}
		}
	}
}