Objective Chart : PART II Programmer’s Guide : Chapter 24 Chart Combinations : Aligning the Axes of Multiple Displays
Aligning the Axes of Multiple Displays
Just like other Objective Chart components, multiple display components can be placed in a window using the SRGraphComponent::SetRect() function. SetRect() specifies the area that the component covers. However, it is often desirable to align the display axes rather than the component rectangles.
For example, several graphs plotting different variables during the same time period (or other independent variable) can be stacked one on top of the other. The horizontal axes of all the displays should be the same, but the y-axis labels may require different amounts of space. Therefore, the length of the horizontal axes may vary.
To align the axes of multiple displays, call SRGraphDisplay::SetDisplayRect(rectDisplay, TRUE)
SetDisplayRect() requires rectangle coordinates in pixels. Therefore, it is not compatible with the device independent measurement modes. Also, if the display window can be resized, the OnSize() handler is the logical place to set the rectangle.
The sample below shows the setup code from OnNewDocument(). It creates two display components that plot the same data with different graph types. The positioning of the components is deferred to the OnSize() member of the view class. In OnSize(), SetRect() places the component rectangles of the two displays, and SetDisplayRect() aligns the display rectangles by specifying the same left and right coordinates for both graphs. Note the use of SRGraph::GetComponentList() and GetComponent() to gain access to the display component.
 
BOOL CCCodeDoc::OnNewDocument()
{
if (!CGraphDoc::OnNewDocument())
return FALSE;
// handle positioning in OnSize() -- view class
SRGraphDisplay *pD=new SRGraphDisplay;
pD->GetStyle()->SetGraphStyle(CX_GRAPH_STRATAVBAR);
pD->GetStyle()->SetAxisStyle(CX_AXIS_CLASSIC);
SRGraphStyle* pS = pD->GetStyle();
pS->SetComponentFillStyle(CX_SOLID_FILL);
pS->SetColor(CXCLR_BLACK);
pD->SetTextColor(CXCLR_WHITE);
pS->SetFrameColor(CXCLR_WHITE);
m_Graph.AddComponent(pD);
 
pD=new SRGraphDisplay;
pD->GetStyle()->SetGraphStyle(CX_GRAPH_LINE);
pD->GetStyle()->SetAxisStyle(CX_AXIS_CLASSIC);
m_Graph.AddComponent(pD);
 
// set up the data
[not shown]
 
return TRUE;
}
 
void CCCodeView::OnSize(UINT nType, int cx, int cy)
{
//Handle auto positioning of the components
 
CCCodeDoc *pDoc=GetDocument();
 
CRect rectDisplay;
if(nType==SIZE_RESTORED
&& !pDoc-> m_Graph.GetComponentList()-> IsEmpty())
{
SRGraphDisplay *pD=(SRGraphDisplay *)pDoc->
m_Graph.GetComponent(0,IDS_SRG_DISPLAYTYPE);
pD->SetMeasurement( SRGraphComponent::PIXELS);
pD->SetRect(-1,-1,-1,cy/2);
rectDisplay = CRect(35,6,cx-10,cy/2-25);
pD->SetDisplayRect( rectDisplay, TRUE);
pD=(SRGraphDisplay *)pDoc->
m_Graph.GetComponent(1,IDS_SRG_DISPLAYTYPE);
pD->SetMeasurement( SRGraphComponent::PIXELS);
pD->SetRect(-1,cy/2+1,-1,-1);
rectDisplay = CRect(35,cy/2+6,cx-10,cy-25);
pD->SetDisplayRect( rectDisplay, TRUE);
}
SRGraphView::OnSize(nType, cx, cy);
}
If this sample is in an MDI application, OnSize() is not normally called by the framework after the document (graph) is created. So we call OnSize() from the view’s OnInitialUpdate() function.
 
void CCCodeView::OnInitialUpdate()
{
SRGraphView::OnInitialUpdate();
 
// have to call OnSize() in MDI app only
CRect rectWnd;
GetClientRect(&rectWnd);
OnSize(SIZE_RESTORED,rectWnd.Width(),rectWnd.Height());
}