Graph.cpp
资源名称:OSDemo [点击查看]
上传用户:tianjwyx
上传日期:2007-01-13
资源大小:813k
文件大小:288k
源码类别:
操作系统开发
开发平台:
Visual C++
- //Graph.cpp - Version 3.0 (Brian Convery, May, 2001)
- #include "stdafx.h"
- #include "afxtempl.h"
- #include "GraphSeries.h"
- #include "GraphLegend.h"
- #include "math.h"
- #include "Graph.h"
- #include "GraphDataColor.h"
- #include "GraphPieLabel.h" //for pie labels
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CGraph
- CGraph::CGraph()
- {
- graphSeries = new CObList();
- seriesSize = 0;
- minTick = 0;
- maxTick = 100;
- numTicks = 10;
- tickSpace = 10;
- graphHasLegend = FALSE;
- legendWidth = 0;
- legendMaxText= 0;
- graphAlignment = VERTICAL_ALIGN;
- graphType = 0;
- xAxisAlign = 0; //horizontal
- xAxisLabelLength = 0;
- xTickFontSize = 12;
- yTickFontSize = 12;
- legendFontSize = 12;
- depth = 0;
- depthRatio = 0.05;
- line3DXBase = 0;
- line3DYBase = 0;
- SetGridLines(FALSE);
- graphQuadType = 1;
- quadSetManually = FALSE;
- }
- CGraph::CGraph(int type)
- {
- graphSeries = new CObList();
- colorList = new CObList();
- seriesSize = 0;
- minTick = 0;
- maxTick = 100;
- numTicks = 10;
- tickSpace = 10;
- graphHasLegend = FALSE;
- legendWidth = 0;
- legendMaxText= 0;
- graphAlignment = VERTICAL_ALIGN;
- graphType = type;
- xAxisAlign = 0; //in degrees == horizontal
- xAxisLabelLength = 0;
- xTickFontSize = 12;
- yTickFontSize = 12;
- legendFontSize = 12;
- depth = 0;
- depthRatio = 0.05;
- line3DXBase = 0;
- line3DYBase = 0;
- SetGridLines(FALSE);
- graphQuadType = 1;
- if(type != BAR_GRAPH)
- quadSetManually = TRUE;
- else
- quadSetManually = FALSE;
- }
- CGraph::~CGraph()
- {
- POSITION pos;
- CGraphSeries* pSeries;
- for( pos = graphSeries->GetHeadPosition(); pos != NULL; )
- {
- pSeries = (CGraphSeries*) graphSeries->GetNext( pos );
- graphSeries->RemoveAt(pos);
- delete pSeries;
- }
- graphSeries->RemoveAll();
- delete graphSeries;
- CGraphDataColor* dataColor;
- for( pos = colorList->GetHeadPosition(); pos != NULL; )
- {
- dataColor = (CGraphDataColor*) colorList->GetNext( pos );
- colorList->RemoveAt(pos);
- delete dataColor;
- }
- colorList->RemoveAll();
- delete colorList;
- }
- BEGIN_MESSAGE_MAP(CGraph, CStatic)
- //{{AFX_MSG_MAP(CGraph)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CGraph message handlers
- void CGraph::SetGraphType(int gType)
- {
- graphType = gType;
- }
- void CGraph::SetXAxisAlignment(int alignValue)
- {
- xAxisAlign = alignValue;
- }
- int CGraph::GetXAxisAlignment()
- {
- return xAxisAlign;
- }
- void CGraph::SetColor(int dataGroup, COLORREF groupColor)
- {
- CGraphDataColor *dataColor = new CGraphDataColor(dataGroup, groupColor);
- colorList->AddTail(dataColor);
- }
- COLORREF CGraph::GetColor(int dataGroup)
- {
- POSITION pos;
- if((colorList->GetCount() <= dataGroup) || (colorList->GetCount() == 0))
- return BLACK;
- CGraphDataColor* dataColor;
- pos = colorList->GetHeadPosition();
- for(int i = 0; i < dataGroup; i++)
- colorList->GetNext(pos);
- dataColor = (CGraphDataColor*) colorList->GetAt( pos );
- return dataColor->GetColor();
- }
- void CGraph::DrawGraph(CDC* pDC)
- {
- CString tickLabel;
- CWnd* graphWnd = pDC->GetWindow();
- CRect graphRect;
- graphWnd->GetClientRect(&graphRect);
- TEXTMETRIC tm;
- //reset graph to be clear background
- COLORREF backColor;
- pDC->SetBkMode(TRANSPARENT);
- backColor = RGB(214,223,247); //replace with desired background color
- CBrush backBrush (backColor);
- CBrush* pOldBackBrush;
- pOldBackBrush = pDC->SelectObject(&backBrush);
- //pDC->Rectangle(0, 0, graphRect.Width(), graphRect.Height());
- pDC->SelectObject(pOldBackBrush);
- maxHeight = graphRect.Height() - 20; //for frame window and status bar
- maxWidth = graphRect.Width() - 5; //for frame window
- //draw graph title
- CFont titleFont;
- int tFontSize = 20;
- while((graphTitle.GetLength() * (tFontSize / 2)) > maxWidth)
- {
- tFontSize -= 2;
- }
- titleFont.CreateFont(tFontSize, 0, 0, 0, 500, FALSE, FALSE, 0,
- DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH ,"楷体_GB2312");
- CFont* pOldFont = (CFont*) pDC->SelectObject(&titleFont);
- pDC->GetTextMetrics(&tm);
- int charWidth = tm.tmAveCharWidth;
- //next line is centered....trust me !!
- pDC->TextOut((graphRect.Width() / 2) - ((graphTitle.GetLength() / 2) * charWidth),
- 10, graphTitle);
- pDC->SelectObject(pOldFont);
- if((graphType == PIE_GRAPH) || (graphType == PIE_GRAPH_3D))
- {
- //since pie does not have axis lines, set to full size minus 5 on each side
- //these are needed for legend to plot itself
- xAxisWidth = maxWidth - 10;
- yAxisHeight = maxHeight - 50; //10 buffer, 20 for title, and 20 for series label
- xApexPoint = 5;
- yApexPoint = maxHeight - 5;
- }
- else
- {
- //compute label size for axis alignment
- CFont sideFont, axisFont;
- int tFontSize = 16;
- if(maxWidth > maxHeight)
- {
- while((axisYLabel.GetLength() * (tFontSize / 2)) > maxHeight)
- {
- tFontSize -= 2;
- }
- }
- else
- {
- while((axisXLabel.GetLength() * (tFontSize / 2)) > maxWidth)
- {
- tFontSize -= 2;
- }
- }
- axisFont.CreateFont(tFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- sideFont.CreateFont(tFontSize, 0, 900, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- CFont* pOldFont = (CFont*) pDC->SelectObject(&sideFont);
- pDC->GetTextMetrics(&tm);
- int charWidth = tm.tmAveCharWidth;
- int labelHeight = tm.tmHeight + 10;
- if(graphAlignment)
- {
- if(axisYLabel.GetLength() == 0)
- labelHeight = 0;
- }
- else
- {
- if(axisXLabel.GetLength() == 0)
- labelHeight = 0;
- }
- pDC->SelectObject(pOldFont);
- tickLabel.Format("%d", maxTick);
- //determine axis specifications
- if(graphAlignment)
- {
- if(graphType == SCATTER_GRAPH)
- {
- xApexPoint = 5 + (xAxisLabelLength * charWidth) + labelHeight; //labelHeight added for y-axis label height
- yApexPoint = (maxHeight - 15) - tm.tmHeight;
- yAxisHeight = yApexPoint - 40;
- xAxisWidth = (maxWidth - 5) - xApexPoint;
- }
- else
- {
- xApexPoint = 5 + (tickLabel.GetLength() * (yTickFontSize / 2)) + 45;
- if(!xAxisAlign) //horizontal
- yApexPoint = (maxHeight - 5) - 45; //apex points are the cross section of axis lines
- else
- yApexPoint = (maxHeight - 5) - (xAxisLabelLength * (xTickFontSize / 2)) - 10;
- yAxisHeight = yApexPoint - 40;
- xAxisWidth = (maxWidth - 5) - xApexPoint;
- }
- }
- else
- {
- xApexPoint = 5 + (xAxisLabelLength * charWidth) + labelHeight; //labelHeight added for y-axis label height
- yApexPoint = (maxHeight - 15) - tm.tmHeight;
- yAxisHeight = yApexPoint - 40;
- xAxisWidth = (maxWidth - 5) - xApexPoint;
- }
- }
- //draw legend
- if(graphHasLegend)
- {
- int legendLeft = DrawLegend(pDC);
- xAxisWidth = legendLeft - 10 - xApexPoint;
- }
- if((!quadSetManually) && (graphType == BAR_GRAPH))
- {
- //computer number of quadrants needed based on data
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- int minXValue = 0;
- int minYValue = 0;
- for(int x = 1; x <= graphSeries->GetCount(); x++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- for(int s = 0; s < seriesSize; s++)
- {
- //to allow scalability (height may be less than tickRange)
- int curXValue = tmpSeries->GetXDataValue();
- int curYValue = tmpSeries->GetYDataValue();
- if(curXValue < minXValue)
- minXValue = curXValue;
- if(curYValue < minYValue)
- minYValue = curYValue;
- }
- }
- graphQuadType = 1;
- if((minXValue < 0) && (minYValue < 0))
- graphQuadType = 4;
- if((minXValue < 0) && (minYValue >= 0))
- graphQuadType = 2;
- if((minXValue >= 0) && (minYValue < 0))
- graphQuadType = 3;
- }
- if(graphType == BAR_GRAPH)
- {
- switch(graphQuadType)
- {
- case 2 :
- xApexPoint += xAxisWidth / 2;
- break;
- case 3 :
- yApexPoint -= yAxisHeight / 2;
- break;
- case 4 :
- xApexPoint += xAxisWidth / 2;
- yApexPoint -= yAxisHeight / 2;
- break;
- }
- }
- if((graphType != 2) && (graphType != 32)) //pie & 3d pie
- {
- inRedraw = FALSE;
- //draw axis lines
- DrawAxis(pDC);
- }
- //draw series data and labels
- DrawSeries(pDC);
- //lines below are commented for doing redraw. If you
- //want the axis lines on top of the other graph elements
- //uncomment this functionality...I may add it back later
- //but there were some bugs doing it this way.
- //redraw axis lines in case graph elements overwrote the axis lines
- // if((graphType != 2) && (graphType != 32) && (graphQuadType > 1)) //pie & 3d pie
- // {
- // inRedraw = TRUE;
- //draw axis lines
- // DrawAxis(pDC);
- // }
- }
- void CGraph::DrawAxis(CDC* pDC)
- {
- TEXTMETRIC tm;
- pDC->SetTextColor(BLACK);
- CFont sideFont, axisFont, dummyFont;
- int charWidth, labelHeight;
- double tickScale;
- int tickXLocation, tickYLocation;
- int seriesSpace;
- CFont* pOldFont;
- int x, y;
- COLORREF axisLineColor;
- axisLineColor = BLACK;
- CPen axisPen (PS_SOLID, 2, axisLineColor);
- dummyFont.CreateFont(12, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pOldFont = (CFont*)pDC->SelectObject(&dummyFont);
- switch(graphType)
- {
- case BAR_GRAPH :
- case LINE_GRAPH :
- case SCATTER_GRAPH :
- case BOX_WHISKER_GRAPH :
- // case RADAR_GRAPH :
- case STACKED_BAR_GRAPH :
- case XY_LINE_GRAPH :
- CPen* pOldAxisPen;
- pOldAxisPen = pDC->SelectObject(&axisPen);
- switch(graphQuadType)
- {
- case 1 :
- //draw y axis
- pDC->MoveTo(xApexPoint, yApexPoint);
- pDC->LineTo(xApexPoint, yApexPoint - yAxisHeight);
- //draw x axis
- pDC->MoveTo(xApexPoint, yApexPoint);
- pDC->LineTo(xApexPoint + xAxisWidth, yApexPoint);
- break;
- case 2 :
- //draw y axis
- pDC->MoveTo(xApexPoint, yApexPoint);
- pDC->LineTo(xApexPoint, yApexPoint - yAxisHeight);
- //draw x axis
- pDC->MoveTo(xApexPoint - (xAxisWidth / 2), yApexPoint);
- pDC->LineTo(xApexPoint + (xAxisWidth / 2), yApexPoint);
- break;
- case 3 :
- //draw y axis
- pDC->MoveTo(xApexPoint, yApexPoint + (yAxisHeight / 2));
- pDC->LineTo(xApexPoint, yApexPoint - (yAxisHeight / 2));
- //draw x axis
- pDC->MoveTo(xApexPoint, yApexPoint);
- pDC->LineTo(xApexPoint + xAxisWidth, yApexPoint);
- break;
- case 4 :
- //draw y axis
- pDC->MoveTo(xApexPoint, yApexPoint + (yAxisHeight / 2));
- pDC->LineTo(xApexPoint, yApexPoint - (yAxisHeight / 2));
- //draw x axis
- pDC->MoveTo(xApexPoint - (xAxisWidth / 2), yApexPoint);
- pDC->LineTo(xApexPoint + (xAxisWidth / 2), yApexPoint);
- break;
- }
- pDC->SelectObject(pOldAxisPen);
- int tFontSize;
- //draw labels
- tFontSize = 16;
- if(maxWidth > maxHeight)
- {
- while((axisYLabel.GetLength() * (tFontSize / 2)) > maxHeight)
- {
- tFontSize -= 2;
- }
- }
- else
- {
- while((axisXLabel.GetLength() * (tFontSize / 2)) > maxWidth)
- {
- tFontSize -= 2;
- }
- }
- axisFont.CreateFont(tFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- sideFont.CreateFont(tFontSize, 0, 900, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(graphAlignment)
- {
- switch(graphQuadType)
- {
- case 1 :
- case 2 :
- pDC->TextOut(10, (yApexPoint - (yAxisHeight / 2)) + ((axisYLabel.GetLength() * charWidth) / 2), axisYLabel);
- break;
- case 3 :
- case 4 :
- pDC->TextOut(10, yApexPoint + ((axisYLabel.GetLength() * charWidth) / 2), axisYLabel);
- break;
- }
- pDC->SelectObject(&axisFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- switch(graphQuadType)
- {
- case 1 :
- pDC->TextOut(xApexPoint + (xAxisWidth / 2) - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisXLabel);
- break;
- case 2 :
- pDC->TextOut(xApexPoint - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisXLabel);
- break;
- case 3 :
- pDC->TextOut(xApexPoint + (xAxisWidth / 2) - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisXLabel);
- break;
- case 4 :
- pDC->TextOut(xApexPoint - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisXLabel);
- break;
- }
- pDC->SelectObject(pOldFont);
- tickScale = 0.00;
- tickScale = (yAxisHeight - 10) / numTicks;
- //draw y axis ticks
- if(!inRedraw)
- {
- switch(graphQuadType)
- {
- case 1 :
- for(y = 1; y <= numTicks; y++)
- {
- tickYLocation = (int)(yApexPoint - (y * tickScale));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(xApexPoint, tickYLocation);
- pDC->LineTo(xApexPoint + xAxisWidth, tickYLocation);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- pDC->SelectObject(pOldFont);
- topYTick = tickYLocation;
- }
- break;
- pDC->SelectObject(pOldFont);
- case 2 :
- if(graphType == SCATTER_GRAPH)
- {
- double oldTickScale;
- int oldNumTicks;
- oldNumTicks = numTicks;
- oldTickScale = tickScale;
- numTicks /= 2;
- tickScale *= 2;
- for(y = 1; y <= numTicks; y++)
- {
- tickYLocation = (int)(yApexPoint - (y * tickScale));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = LIGHT_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(xApexPoint - (xAxisWidth / 2), tickYLocation);
- pDC->LineTo(xApexPoint + (xAxisWidth / 2), tickYLocation);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- pDC->SelectObject(pOldFont);
- topYTick = tickYLocation;
- }
- //draw the 0
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - 10 - (yTickFontSize / 2), yApexPoint - 6, "0");
- //reset numTicks and tickScale back to normal
- tickScale = oldTickScale;
- numTicks = oldNumTicks;
- }
- else
- {
- for(y = 1; y <= numTicks; y++)
- {
- tickYLocation = (int)(yApexPoint - (y * tickScale));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(xApexPoint - (xAxisWidth / 2), tickYLocation);
- pDC->LineTo(xApexPoint + (xAxisWidth / 2), tickYLocation);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- topYTick = tickYLocation;
- }
- //draw the 0
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - 10 - (yTickFontSize / 2), yApexPoint - 6, "0");
- }
- pDC->SelectObject(pOldFont);
- break;
- case 3 :
- for(y = 0; y <= numTicks / 2; y++)
- {
- tickYLocation = (int)(yApexPoint + 5 - (yAxisHeight / 2) + (y * tickScale));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(xApexPoint, tickYLocation);
- pDC->LineTo(xApexPoint, tickYLocation);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", maxTick - (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- topYTick = tickYLocation;
- }
- //draw the 0
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - 10 - (yTickFontSize / 2), yApexPoint - 6, "0");
- for(; y <= numTicks; y++)
- {
- tickYLocation = (int)(yApexPoint + 5 - (yAxisHeight / 2) + (y * tickScale));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(xApexPoint, tickYLocation);
- pDC->LineTo(xApexPoint, tickYLocation);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + ((numTicks - y) * tickSpace));
- pDC->TextOut(xApexPoint - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- topYTick = tickYLocation;
- }
- pDC->SelectObject(pOldFont);
- break;
- pDC->SelectObject(pOldFont);
- case 4 :
- for(y = 1; y <= numTicks / 2; y++)
- {
- tickYLocation = (int)(yApexPoint - (y * tickScale));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(xApexPoint - (xAxisWidth / 2), tickYLocation);
- pDC->LineTo(xApexPoint + (xAxisWidth / 2), tickYLocation);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- topYTick = tickYLocation;
- }
- //draw the 0
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - 10 - (yTickFontSize / 2), yApexPoint - 6, "0");
- for(; y <= numTicks; y++)
- {
- tickYLocation = (int)(yApexPoint - (yAxisHeight / 2) + (y * tickScale));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(xApexPoint - (xAxisWidth / 2), tickYLocation);
- pDC->LineTo(xApexPoint + (xAxisWidth / 2), tickYLocation);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + ((numTicks - y) * tickSpace));
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- topYTick = tickYLocation;
- }
- pDC->SelectObject(pOldFont);
- break;
- }
- }
- //draw X axis tick marks
- switch(graphQuadType)
- {
- case 1 :
- if(graphType != SCATTER_GRAPH)
- {
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- for(int x = 1; x <= graphSeries->GetCount(); x++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- seriesSpace = xAxisWidth / graphSeries->GetCount();
- tickXLocation = xApexPoint + ((x * seriesSpace) - (seriesSpace / 2));
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- //draw tick label
- CString tickLabel;
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + 8, tickLabel);
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- rightXTick = tickXLocation;
- }
- }
- else
- {
- //scatter graphs will use the same tick marking on both axis lines
- seriesSpace = (xAxisWidth - 20) / numTicks;
- for(int x = 1; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint + (x * seriesSpace);
- //draw tick mark
- pDC->MoveTo(tickXLocation, yApexPoint - 3);
- pDC->LineTo(tickXLocation, yApexPoint + 3);
- //draw tick label
- CString tickLabel;
- CFont xFont;
- tickLabel.Format("%d", x * tickSpace);
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (tickLabel.GetLength() * charWidth / 2), yApexPoint + 8, tickLabel);
- rightXTick = tickXLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- break;
- case 2 :
- if(graphType != SCATTER_GRAPH)
- {
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- seriesSpace = xAxisWidth / graphSeries->GetCount();
- for(x = 1; x <= graphSeries->GetCount() / 2; x++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickXLocation = xApexPoint - (xAxisWidth / 2) + ((x * seriesSpace) - (seriesSpace / 2));
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- if((graphSeries->GetCount() % 2) > 0)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickXLocation = xApexPoint;
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- x++;
- }
- for(; x <= graphSeries->GetCount(); x++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickXLocation = xApexPoint - (xAxisWidth / 2) + ((x * seriesSpace) - (seriesSpace / 2));
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- }
- else
- {
- //scatter graphs will use the same tick marking on both axis lines
- seriesSpace = xAxisWidth / numTicks;
- for(x = 0; x <= numTicks / 2; x++)
- {
- tickXLocation = xApexPoint + 5 - (xAxisWidth / 2) + (x * seriesSpace);
- //draw tick mark
- pDC->MoveTo(tickXLocation, yApexPoint - 3);
- pDC->LineTo(tickXLocation, yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (x * tickSpace));
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (tickLabel.GetLength() * charWidth / 2), yApexPoint + 8, tickLabel);
- }
- rightXTick = tickXLocation;
- pDC->SelectObject(pOldFont);
- }
- //draw the 0
- tickXLocation = xApexPoint;
- if(!inRedraw)
- {
- //draw tick label
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (charWidth / 2), yApexPoint + 8, "0");
- }
- for(; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (x * seriesSpace);
- //draw tick mark
- pDC->MoveTo(tickXLocation, yApexPoint - 3);
- pDC->LineTo(tickXLocation, yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", (x / 2) * tickSpace);
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (tickLabel.GetLength() * charWidth / 2), yApexPoint + 8, tickLabel);
- }
- rightXTick = tickXLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- break;
- case 3 :
- if(graphType != SCATTER_GRAPH)
- {
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- for(int x = 1; x <= graphSeries->GetCount(); x++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- seriesSpace = xAxisWidth / graphSeries->GetCount();
- tickXLocation = xApexPoint + ((x * seriesSpace) - (seriesSpace / 2));
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + (yAxisHeight / 2) + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- }
- else
- {
- //scatter graphs will use the same tick marking on both axis lines
- seriesSpace = (xAxisWidth - 20) / numTicks;
- for(int x = 1; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint + (x * seriesSpace);
- //draw tick mark
- pDC->MoveTo(tickXLocation, yApexPoint - 3);
- pDC->LineTo(tickXLocation, yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", x * tickSpace);
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (tickLabel.GetLength() * charWidth / 2), yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- }
- rightXTick = tickXLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- break;
- case 4 :
- if(graphType != SCATTER_GRAPH)
- {
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- seriesSpace = xAxisWidth / graphSeries->GetCount();
- for(x = 1; x <= graphSeries->GetCount() / 2; x++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickXLocation = xApexPoint - (xAxisWidth / 2) + ((x * seriesSpace) - (seriesSpace / 2));
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + (yAxisHeight / 2) + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- if((graphSeries->GetCount() % 2) > 0)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickXLocation = xApexPoint;
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + (yAxisHeight / 2) + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- x++;
- }
- for(; x <= graphSeries->GetCount(); x++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickXLocation = xApexPoint - (xAxisWidth / 2) + ((x * seriesSpace) - (seriesSpace / 2));
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + (yAxisHeight / 2) + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- }
- else
- {
- //scatter graphs will use the same tick marking on both axis lines
- seriesSpace = (xAxisWidth - 20) / numTicks;
- for(x = 1; x <= numTicks / 2; x++)
- {
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (x * seriesSpace);
- //draw tick mark
- pDC->MoveTo(tickXLocation, yApexPoint + (yAxisHeight / 2) - 3);
- pDC->LineTo(tickXLocation, yApexPoint + (yAxisHeight / 2) + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", x * tickSpace);
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (tickLabel.GetLength() * charWidth / 2), yApexPoint + 8, tickLabel);
- }
- rightXTick = tickXLocation;
- pDC->SelectObject(pOldFont);
- }
- //draw the 0
- for(; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (x * seriesSpace);
- //draw tick mark
- pDC->MoveTo(tickXLocation, yApexPoint + (yAxisHeight / 2) - 3);
- pDC->LineTo(tickXLocation, yApexPoint + (yAxisHeight / 2) + 3);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", x * tickSpace);
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (tickLabel.GetLength() * charWidth / 2), yApexPoint + 8, tickLabel);
- }
- rightXTick = tickXLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- break;
- }
- }
- else
- {
- //reverse above stuff and treat as horizontal graph
- switch(graphQuadType)
- {
- case 1 :
- pDC->TextOut(10, (yApexPoint - (yAxisHeight / 2)) + (axisYLabel.GetLength() / 2), axisXLabel);
- pDC->SelectObject(&axisFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- labelHeight = tm.tmHeight + 10;
- if(axisYLabel.GetLength() == 0)
- labelHeight = 0;
- pDC->TextOut(xApexPoint + (xAxisWidth / 2) - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisYLabel);
- pDC->SelectObject(pOldFont);
- //to allow scalability (height may be less than tickRange)
- tickScale = 0.00;
- //draw y axis ticks
- if(graphType != SCATTER_GRAPH)
- {
- tickScale = (yAxisHeight - 10) / seriesSize;
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- for(y = 1; y <= graphSeries->GetCount(); y++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- seriesSpace = yAxisHeight / graphSeries->GetCount();
- tickYLocation = yApexPoint - ((y * seriesSpace) - (seriesSpace / 2));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - (xAxisLabelLength * charWidth) - 5, tickYLocation - (tm.tmHeight / 2), tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- else
- {
- //scatter graphs will use the same tick marking on both axis lines
- for(y = 1; y <= numTicks; y++)
- {
- tickScale = (yAxisHeight - 10) / numTicks;
- tickYLocation = yApexPoint - (int)(y * tickScale);
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", y * tickSpace);
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- //draw X axis tick marks
- tickScale = (xAxisWidth - 10) / numTicks;
- for(x = 1; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint + (int)(x * tickScale);
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(tickXLocation, yApexPoint);
- pDC->LineTo(tickXLocation, yApexPoint - yAxisHeight);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (x * tickSpace));
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * charWidth) / 2), yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- break;
- case 2 :
- pDC->TextOut(10, (yApexPoint - (yAxisHeight / 2)) + (axisYLabel.GetLength() / 2), axisXLabel);
- pDC->SelectObject(&axisFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- labelHeight = tm.tmHeight + 10;
- if(axisYLabel.GetLength() == 0)
- labelHeight = 0;
- pDC->TextOut(xApexPoint - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisYLabel);
- pDC->SelectObject(pOldFont);
- //to allow scalability (height may be less than tickRange)
- tickScale = 0.00;
- seriesSpace = yAxisHeight / graphSeries->GetCount();
- //draw y axis ticks
- if(graphType != SCATTER_GRAPH)
- {
- tickScale = (yAxisHeight - 10) / seriesSize;
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- for(y = 1; y <= graphSeries->GetCount(); y++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickYLocation = yApexPoint - ((y * seriesSpace) - (seriesSpace / 2));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - (xAxisLabelLength * charWidth) - 5, tickYLocation - (tm.tmHeight / 2), tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- else
- {
- //scatter graphs will use the same tick marking on both axis lines
- int oldNumTicks;
- oldNumTicks = numTicks;
- numTicks /= 2;
- for(y = 0; y <= numTicks; y++)
- {
- tickScale = (yAxisHeight - 10) / numTicks;
- tickYLocation = yApexPoint - (int)(y * tickScale);
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - (tickLabel.GetLength() * (yTickFontSize / 2)) - 6, tickYLocation - 6, tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- numTicks = oldNumTicks;
- }
- //draw X axis tick marks
- tickScale = (xAxisWidth - 10) / numTicks;
- for(x = 0; x <= numTicks / 2; x++)
- {
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (int)(x * tickScale) + 5;
- if(!inRedraw)
- {
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(tickXLocation, yApexPoint - yAxisHeight);
- pDC->LineTo(tickXLocation, yApexPoint);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (x * tickSpace));
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * charWidth) / 2), yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- //draw the 0 location
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (int)(x * tickScale);
- if(!inRedraw)
- {
- //draw tick label
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (charWidth / 2), yApexPoint + 8, "0");
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), "0");
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, "0");
- pDC->SelectObject(pOldFont);
- }
- }
- for(; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (int)(x * tickScale);
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(tickXLocation, yApexPoint - yAxisHeight);
- pDC->LineTo(tickXLocation, yApexPoint);
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (x * tickSpace));
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * charWidth) / 2), yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- break;
- case 3 :
- pDC->TextOut(10, yApexPoint - (axisYLabel.GetLength() / 2), axisXLabel);
- pDC->SelectObject(&axisFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- labelHeight = tm.tmHeight + 10;
- if(axisYLabel.GetLength() == 0)
- labelHeight = 0;
- pDC->TextOut(xApexPoint + (xAxisWidth / 2) - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisYLabel);
- pDC->SelectObject(pOldFont);
- //to allow scalability (height may be less than tickRange)
- tickScale = 0.00;
- seriesSpace = yAxisHeight / graphSeries->GetCount();
- //draw y axis ticks
- if(graphType != SCATTER_GRAPH)
- {
- tickScale = (yAxisHeight - 10) / seriesSize;
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- for(y = 1; y <= graphSeries->GetCount() / 2; y++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickYLocation = yApexPoint - (yAxisHeight / 2) + ((y * seriesSpace) - (seriesSpace / 2));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - 5 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- //draw the 0 location
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickYLocation = yApexPoint;
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - 5 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- y++;
- for(; y <= graphSeries->GetCount(); y++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickYLocation = yApexPoint - (yAxisHeight / 2) + ((y * seriesSpace) - (seriesSpace / 2));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - 5 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- else
- {
- //scatter graphs will use the same tick marking on both axis lines
- for(y = 0; y < numTicks / 2; y++)
- {
- tickScale = (yAxisHeight - 10) / numTicks;
- tickYLocation = yApexPoint - (yAxisHeight / 2) + (int)(y * tickScale) + 5;
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", maxTick - (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - (tickLabel.GetLength() * (yTickFontSize / 2)) - 8, tickYLocation - 6, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- //draw the 0 location
- tickYLocation = yApexPoint;
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - (yTickFontSize / 2) - 8, tickYLocation - 6, "0");
- pDC->SelectObject(pOldFont);
- }
- y++;
- for(; y <= numTicks; y++)
- {
- tickScale = (yAxisHeight - 10) / numTicks;
- tickYLocation = yApexPoint - (yAxisHeight / 2) + (int)(y * tickScale) + 5;
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", maxTick - (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - (tickLabel.GetLength() * (yTickFontSize / 2)) - 5, tickYLocation - 6, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- topYTick = tickYLocation;
- }
- }
- //draw X axis tick marks
- int oldNumTicks;
- oldNumTicks = numTicks;
- numTicks /= 2;
- tickScale = (xAxisWidth - 10) / numTicks;
- for(x = 0; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint + (int)(x * tickScale);
- if(!inRedraw)
- {
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(tickXLocation, yApexPoint - (yAxisHeight / 2));
- pDC->LineTo(tickXLocation, yApexPoint + (yAxisHeight / 2));
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", (x * tickSpace * 2));
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * charWidth) / 2), yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + (yAxisHeight / 2) + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- }
- numTicks = oldNumTicks;
- rightXTick = tickXLocation;
- break;
- case 4 :
- pDC->TextOut(10, yApexPoint - (axisYLabel.GetLength() / 2), axisXLabel);
- pDC->SelectObject(&axisFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- labelHeight = tm.tmHeight + 10;
- if(axisYLabel.GetLength() == 0)
- labelHeight = 0;
- pDC->TextOut(xApexPoint - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisYLabel);
- pDC->SelectObject(pOldFont);
- //to allow scalability (height may be less than tickRange)
- tickScale = 0.00;
- seriesSpace = yAxisHeight / graphSeries->GetCount();
- //draw y axis ticks
- if(graphType != SCATTER_GRAPH)
- {
- tickScale = (yAxisHeight - 10) / seriesSize;
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- for(y = 1; y <= graphSeries->GetCount() / 2; y++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickYLocation = yApexPoint - (yAxisHeight / 2) + ((y * seriesSpace) - (seriesSpace / 2));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - (xAxisLabelLength * charWidth) - 5, tickYLocation - (tm.tmHeight / 2), tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- //draw the 0 location
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickYLocation = yApexPoint;
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - (xAxisLabelLength * charWidth) - 5, tickYLocation - (tm.tmHeight / 2), tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- y++;
- for(; y <= graphSeries->GetCount(); y++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- tickYLocation = yApexPoint - (yAxisHeight / 2) + ((y * seriesSpace) - (seriesSpace / 2));
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - (xAxisLabelLength * charWidth) - 5, tickYLocation - (tm.tmHeight / 2), tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- else
- {
- //scatter graphs will use the same tick marking on both axis lines
- for(y = 1; y <= numTicks; y++)
- {
- tickScale = (yAxisHeight - 10) / numTicks;
- tickYLocation = yApexPoint - (yAxisHeight / 2) + (int)(y * tickScale);
- //draw tick mark
- pDC->MoveTo(xApexPoint - 3, tickYLocation);
- pDC->LineTo(xApexPoint + 3, tickYLocation);
- if(!inRedraw)
- {
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", y * tickSpace);
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - (xAxisWidth / 2) - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- }
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- }
- //draw X axis tick marks
- tickScale = (xAxisWidth - 10) / numTicks;
- for(x = 0; x <= numTicks / 2; x++)
- {
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (int)(x * tickScale) + 5;
- if(!inRedraw)
- {
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(tickXLocation, yApexPoint - (yAxisHeight / 2));
- pDC->LineTo(tickXLocation, yApexPoint + (yAxisHeight / 2));
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (x * tickSpace));
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * charWidth) / 2), yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + (yAxisHeight / 2) + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- //draw the 0 location
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (int)(x * tickScale);
- if(!inRedraw)
- {
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(tickXLocation, yApexPoint - (yAxisHeight / 2));
- pDC->LineTo(tickXLocation, yApexPoint + (yAxisHeight / 2));
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - (charWidth / 2), yApexPoint + (yAxisHeight / 2) + 8, "0");
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + (yAxisHeight / 2) + 8 + (xAxisLabelLength * charWidth), "0");
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + (yAxisHeight / 2) + 8, "0");
- pDC->SelectObject(pOldFont);
- }
- }
- x++;
- for(; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint - (xAxisWidth / 2) + (int)(x * tickScale);
- pDC->MoveTo(tickXLocation,yApexPoint - 3);
- pDC->LineTo(tickXLocation,yApexPoint + 3);
- if(!inRedraw)
- {
- if(graphHasGridLines)
- {
- //draw grid lines
- COLORREF gridLineColor;
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- CPen* pOldPen;
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(tickXLocation, yApexPoint - (yAxisHeight / 2));
- pDC->LineTo(tickXLocation, yApexPoint + (yAxisHeight / 2));
- pDC->SelectObject(pOldPen);
- }
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", (x / 2) * tickSpace);
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * charWidth) / 2), yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + (yAxisHeight / 2) + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + (yAxisHeight / 2) + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- }
- rightXTick = tickXLocation;
- }
- break;
- }
- }
- break;
- case BAR_GRAPH_3D :
- case LINE_GRAPH_3D :
- case STACKED_BAR_GRAPH_3D :
- depth = (int)(yAxisHeight * depthRatio);
- xApexPoint += depth;
- yApexPoint -= depth;
- xAxisWidth -= depth;
- yAxisHeight -= depth;
- //draw y axis
- pDC->MoveTo(xApexPoint, yApexPoint);
- pDC->LineTo(xApexPoint, yApexPoint - yAxisHeight);
- //draw x axis
- pDC->MoveTo(xApexPoint, yApexPoint);
- pDC->LineTo(xApexPoint + xAxisWidth, yApexPoint);
- //adjust graph settings for 3D look
- yApexPoint += depth;
- xApexPoint -= depth;
- //foreground axis
- pDC->MoveTo(xApexPoint, yApexPoint + (int)(depth * .2));
- pDC->LineTo(xApexPoint, yApexPoint - yAxisHeight);
- pDC->MoveTo(xApexPoint - (int)(depth * .2), yApexPoint);
- pDC->LineTo(xApexPoint + xAxisWidth, yApexPoint);
- //connecting line at apex
- pDC->MoveTo(xApexPoint, yApexPoint);
- pDC->LineTo(xApexPoint + depth, yApexPoint - depth);
- //connecting line at height
- pDC->MoveTo(xApexPoint, yApexPoint - yAxisHeight);
- pDC->LineTo(xApexPoint + depth, yApexPoint - yAxisHeight - depth);
- //connecting line at width
- pDC->MoveTo(xApexPoint + xAxisWidth, yApexPoint);
- pDC->LineTo(xApexPoint + xAxisWidth + depth, yApexPoint - depth);
- //top and right border lines
- pDC->MoveTo(xApexPoint + depth, yApexPoint - yAxisHeight - depth);
- pDC->LineTo(xApexPoint + xAxisWidth + depth, yApexPoint - yAxisHeight - depth);
- pDC->LineTo(xApexPoint + xAxisWidth + depth, yApexPoint - depth);
- //Tick marks ... and labels too
- //draw labels
- tFontSize = 16;
- if(maxWidth > maxHeight)
- {
- while((axisYLabel.GetLength() * (tFontSize / 2)) > maxHeight)
- {
- tFontSize -= 2;
- }
- }
- else
- {
- while((axisXLabel.GetLength() * (tFontSize / 2)) > maxWidth)
- {
- tFontSize -= 2;
- }
- }
- axisFont.CreateFont(tFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- sideFont.CreateFont(tFontSize, 0, 900, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(graphAlignment)
- {
- pDC->TextOut(10, (yApexPoint - (yAxisHeight / 2)) + ((axisYLabel.GetLength() * charWidth) / 2), axisYLabel);
- pDC->SelectObject(&axisFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint + (xAxisWidth / 2) - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisXLabel);
- pDC->SelectObject(pOldFont);
- tickScale = 0.00;
- tickScale = yAxisHeight / numTicks;
- //draw y axis ticks
- for(int y = 1; y <= numTicks; y++)
- {
- tickYLocation = yApexPoint - (int)(y * tickScale);
- //draw tick mark
- pDC->MoveTo(xApexPoint - (int)(depth * .2), tickYLocation);
- pDC->LineTo(xApexPoint, tickYLocation);
- COLORREF gridLineColor;
- CPen* pOldPen;
- //draw grid lines
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(xApexPoint, tickYLocation);
- pDC->LineTo(xApexPoint + depth, tickYLocation - depth);
- if(graphHasGridLines)
- {
- pDC->LineTo(xApexPoint + xAxisWidth + depth, tickYLocation - depth);
- }
- pDC->SelectObject(pOldPen);
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (y * tickSpace));
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- pDC->TextOut(xApexPoint - 10 - (tickLabel.GetLength() * (yTickFontSize / 2)), tickYLocation - 6, tickLabel);
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- //draw 1/2 tick line (grey)
- int midTickYLocation;
- midTickYLocation = yApexPoint - (int)(y * tickScale * .5) - (int)((y - 1) * tickScale * .5);
- //draw tick mark
- pDC->MoveTo(xApexPoint - (int)(depth * .2), midTickYLocation);
- pDC->LineTo(xApexPoint, midTickYLocation);
- //draw grid lines
- gridLineColor = LIGHT_GREY;
- CPen midGridPen (PS_SOLID, 1, gridLineColor);
- pOldPen = pDC->SelectObject(&midGridPen);
- pDC->MoveTo(xApexPoint, midTickYLocation);
- pDC->LineTo(xApexPoint + depth, midTickYLocation - depth);
- if(graphHasGridLines)
- {
- pDC->LineTo(xApexPoint + xAxisWidth + depth, midTickYLocation - depth);
- }
- pDC->SelectObject(pOldPen);
- }
- //draw X axis tick marks
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- for(int x = 1; x <= graphSeries->GetCount(); x++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- seriesSpace = xAxisWidth / graphSeries->GetCount();
- tickXLocation = xApexPoint + ((x * seriesSpace) - (seriesSpace / 2));
- //unlike normal series, we put ticks here
- //on the outsides of the series
- pDC->MoveTo(xApexPoint + (x * seriesSpace),yApexPoint + (int)(depth * .2));
- pDC->LineTo(xApexPoint + (x * seriesSpace),yApexPoint);
- pDC->LineTo(xApexPoint + (x * seriesSpace) + depth,yApexPoint - depth);
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- if(!xAxisAlign) //horizontal
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * 8) / 2), yApexPoint + 8, tickLabel);
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- rightXTick = tickXLocation;
- }
- }
- else
- {
- //reverse above stuff and treat as horizontal graph
- pDC->TextOut(10, (yApexPoint - (yAxisHeight / 2)) + (axisYLabel.GetLength() / 2), axisXLabel);
- pDC->SelectObject(&axisFont);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- labelHeight = tm.tmHeight + 10;
- if(axisYLabel.GetLength() == 0)
- labelHeight = 0;
- pDC->TextOut(xApexPoint + (xAxisWidth / 2) - ((axisXLabel.GetLength() / 2) * charWidth), maxHeight - 5 - 6, axisYLabel);
- pDC->SelectObject(pOldFont);
- tickScale = 0.00;
- //draw y axis ticks
- tickScale = (yAxisHeight - 10) / seriesSize;
- POSITION pos;
- pos = graphSeries->GetHeadPosition();
- CGraphSeries* tmpSeries;
- for(int y = 1; y <= graphSeries->GetCount(); y++)
- {
- tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
- seriesSpace = yAxisHeight / graphSeries->GetCount();
- tickYLocation = yApexPoint - (y * seriesSpace);
- //draw tick mark
- //unlike normal series, we put ticks here on the
- //outside of the series
- pDC->MoveTo(xApexPoint - (int)(depth * .2), tickYLocation);
- pDC->LineTo(xApexPoint, tickYLocation);
- pDC->LineTo(xApexPoint + depth,yApexPoint - (y * seriesSpace) - depth);
- //draw tick label
- CString tickLabel;
- tickLabel = tmpSeries->GetLabel();
- CFont yFont;
- yFont.CreateFont(yTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&yFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(xApexPoint - (xAxisLabelLength * charWidth) - 5, tickYLocation - (tm.tmHeight / 2), tickLabel);
- topYTick = tickYLocation;
- pDC->SelectObject(pOldFont);
- }
- //draw X axis tick marks
- tickScale = (xAxisWidth - 10) / numTicks;
- for(int x = 1; x <= numTicks; x++)
- {
- tickXLocation = xApexPoint + (int)(x * tickScale);
- pDC->MoveTo(tickXLocation,yApexPoint + (int)(depth * .2));
- pDC->LineTo(tickXLocation,yApexPoint);
- COLORREF gridLineColor;
- CPen* pOldPen;
- //draw grid lines
- gridLineColor = DARK_GREY;
- CPen gridPen (PS_SOLID, 1, gridLineColor);
- pOldPen = pDC->SelectObject(&gridPen);
- pDC->MoveTo(tickXLocation, yApexPoint);
- pDC->LineTo(tickXLocation + depth, yApexPoint - depth);
- if(graphHasGridLines)
- {
- pDC->LineTo(tickXLocation + depth, yApexPoint - yAxisHeight - depth);
- }
- pDC->SelectObject(pOldPen);
- //draw tick label
- CString tickLabel;
- tickLabel.Format("%d", minTick + (x * tickSpace));
- if(!xAxisAlign) //horizontal
- {
- CFont xFont;
- xFont.CreateFont(xTickFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&xFont);
- charWidth = tm.tmAveCharWidth;
- pDC->TextOut(tickXLocation - ((tickLabel.GetLength() * charWidth) / 2), yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- else
- {
- CFont sideFont2;
- sideFont2.CreateFont(xTickFontSize, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pDC->SelectObject(&sideFont2);
- pDC->GetTextMetrics(&tm);
- charWidth = tm.tmAveCharWidth;
- if(xAxisAlign < 180)
- pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * charWidth), tickLabel);
- else
- pDC->TextOut(tickXLocation + 2, yApexPoint + 8, tickLabel);
- pDC->SelectObject(pOldFont);
- }
- rightXTick = tickXLocation;
- //draw 1/2 tick line (grey)
- int midTickXLocation;
- midTickXLocation = xApexPoint + (int)(x * tickScale * .5) + (int)((x - 1) * tickScale * .5);
- //draw tick mark
- pDC->MoveTo(midTickXLocation,yApexPoint + (int)(depth * .2));
- pDC->LineTo(midTickXLocation,yApexPoint);
- //draw grid lines
- gridLineColor = LIGHT_GREY;
- CPen midGridPen (PS_SOLID, 1, gridLineColor);
- pDC->SelectObject(&midGridPen);
- pDC->MoveTo(midTickXLocation, yApexPoint);
- pDC->LineTo(midTickXLocation + depth, yApexPoint - depth);
- if(graphHasGridLines)
- {
- pDC->LineTo(midTickXLocation + depth, yApexPoint - yAxisHeight - depth);
- }
- pDC->SelectObject(pOldPen);
- }
- }
- break;
- }
- }
- void CGraph::AddSeries(CGraphSeries* dataSet)
- {
- int numData = 0;
- numData = dataSet->GetDataCount();
- if(numData > seriesSize)
- seriesSize = numData;
- graphSeries->AddTail(dataSet);
- }
- void CGraph::SetXAxisLabel(CString label)
- {
- axisXLabel = label;
- xAxisLabelLength = axisXLabel.GetLength();
- }
- void CGraph::SetYAxisLabel(CString label)
- {
- axisYLabel = label;
- yAxisLabelLength = axisYLabel.GetLength();
- }
- void CGraph::DrawSeries(CDC* pDC)
- {
- switch(graphType)
- {
- case BAR_GRAPH :
- DrawBarSeries(pDC);
- break;
- case LINE_GRAPH :
- DrawLineSeries(pDC);
- break;
- case PIE_GRAPH :
- DrawPieSeries(pDC);
- break;
- case SCATTER_GRAPH :
- DrawScatterSeries(pDC);
- break;
- case BOX_WHISKER_GRAPH :
- DrawBoxWhiskerSeries(pDC);
- break;
- case STACKED_BAR_GRAPH :
- DrawStackedBarSeries(pDC);
- break;
- case XY_LINE_GRAPH :
- DrawXYLineSeries(pDC);
- break;
- // case RADAR_GRAPH :
- // DrawRadarSeries(pDC);
- // break;
- case BAR_GRAPH_3D :
- Draw3DBarSeries(pDC);
- break;
- case LINE_GRAPH_3D :
- Draw3DLineSeries(pDC);
- break;
- case STACKED_BAR_GRAPH_3D :
- Draw3DStackedBarSeries(pDC);
- break;
- case PIE_GRAPH_3D :
- Draw3DPieSeries(pDC);
- break;
- default :
- AfxMessageBox("No graph type to display");
- break;
- }
- }
- void CGraph::SetLegend(int datagroup, CString label)
- {
- if(graphType != SCATTER_GRAPH) //scatter graphs don't need legends
- {
- graphLegend.SetLegendText(datagroup, label);
- graphHasLegend = TRUE;
- if(legendMaxText < label.GetLength())
- legendMaxText = label.GetLength();
- }
- }
- int CGraph::DrawLegend(CDC* pDC)
- {
- //determine size of legend
- //12 chars per seriesSize + 6 for spacing (3 top and bottom)
- //+ 1 set for label title(3+12+6) + rectangle (2 chars) + 3 for final bottom buffer
- int legendHeight = 23 + (seriesSize * 18) + 3;
- int legendL, legendT, legendR, legendB;
- int barL, barT, barR, barB;
- TEXTMETRIC tm;
- legendT = (maxHeight / 2) - (legendHeight / 2);
- legendB = legendT + legendHeight;
- legendR = maxWidth - 5;
- legendL = legendR - ((graphLegend.GetLegendLength() * (int)(legendFontSize * .66)) + 25);
- //allows 50 pixels for display of legend bar 45 + 5 space.
- legendWidth = legendR - legendL;
- pDC->Rectangle(legendL, legendT, legendR, legendB);
- CFont legendTitleFont;
- legendTitleFont.CreateFont(15, 0, 0, 0, 500, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- CFont* pOldFont = (CFont*) pDC->SelectObject(&legendTitleFont);
- pDC->GetTextMetrics(&tm);
- int charWidth = tm.tmAveCharWidth;
- pDC->TextOut(legendL + (legendWidth / 2) - (3 * charWidth),
- legendT + 3, "图例");
- pDC->SelectObject(pOldFont);
- for(int i = 0; i < seriesSize; i++)
- {
- //top "Legend" text will use 12 + 3 top + 6 bottom (21 total)
- //each legend label will need 3 chars on top, so the 24 in the offset
- //each label than uses 12 + 3 below + 3 above next label, so 18
- // in the i * offset.
- CFont legendFont;
- legendFont.CreateFont(legendFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- pOldFont = (CFont*) pDC->SelectObject(&legendFont);
- pDC->TextOut(legendL + 5, legendT + 24 + (i * 18) + 1, graphLegend.GetLegendText(i));
- pDC->SelectObject(pOldFont);
- //draw bar
- COLORREF barColor;
- barColor = GetColor(i);
- CBrush brush (barColor);
- CBrush* pOldBrush;
- pOldBrush = pDC->SelectObject(&brush);
- barL = legendL + 5 + (legendMaxText * (legendFontSize / 2)) + 5;
- barT = legendT + 24 + (i * 18) + 1, graphLegend.GetLegendText(i);
- barR = legendR - 5;
- barB = barT + 12;
- pDC->Rectangle(barL, barT, barR, barB);
- pDC->SelectObject(pOldBrush);
- }
- return legendL;
- }
- void CGraph::SetGraphTitle(CString title)
- {
- graphTitle = title;
- }
- void CGraph::SetXTickFontSize(int size)
- {
- xTickFontSize = size;
- }
- void CGraph::SetYTickFontSize(int size)
- {
- yTickFontSize = size;
- }
- void CGraph::SetLegendFontSize(int size)
- {
- legendFontSize = size;
- }
- int CGraph::PrintGraph(CDC* pDC, CPrintInfo* pInfo)
- {
- CString str;
- CFont graphTitleFont, textFont;
- TEXTMETRIC tm;
- CString tickLabel;
- maxHeight = pGraphT - pGraphB;
- maxWidth = pGraphR - pGraphL;
- //titleFont is 24 point, bold
- graphTitleFont.CreateFont(-480, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI_CHARSET,
- OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH || FF_ROMAN,
- "Times New Roman");
- //textFont is 12 point
- textFont.CreateFont(-240, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI_CHARSET,
- OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH || FF_ROMAN,
- "Times New Roman");
- pDC->SetMapMode(MM_TWIPS);
- CFont* pOldFont = (CFont*) pDC->SelectObject(&graphTitleFont);
- pDC->GetTextMetrics(&tm);
- int charWidth = tm.tmAveCharWidth;
- int charHeight = tm.tmHeight;
- //next line is centered....trust me !!
- pDC->TextOut(pGraphL + (maxWidth / 2) - ((graphTitle.GetLength() / 2) * charWidth), pGraphT - 50, graphTitle);
- pDC->SelectObject(pOldFont);
- if((graphType == PIE_GRAPH) || (graphType == PIE_GRAPH_3D))
- {
- xAxisWidth = pGraphR - pGraphL - 200;
- yAxisHeight = maxHeight - 600 - charHeight;
- xApexPoint = pGraphL + 500;
- yApexPoint = pGraphB + 500;
- }
- else
- {
- //compute label size for axis alignment
- CFont sideFont, axisFont;
- int tFontSize;
- tFontSize = 16;
- if(maxWidth > maxHeight)
- {
- while((axisYLabel.GetLength() * (tFontSize / 2)) > maxHeight)
- {
- tFontSize -= 2;
- }
- }
- else
- {
- while((axisXLabel.GetLength() * (tFontSize / 2)) > maxWidth)
- {
- tFontSize -= 2;
- }
- }
- //set tFontSize for printer
- tFontSize *= -20;
- axisFont.CreateFont(tFontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- sideFont.CreateFont(tFontSize, 0, 900, 0, 700, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
- CFont* pOldFont = (CFont*) pDC->SelectObject(&sideFont);
- pDC->GetTextMetrics(&tm);
- int charWidth = tm.tmAveCharWidth;
- int labelHeight = tm.tmHeight + 50;
- if(graphAlignment)
- {
- if(axisXLabel.GetLength() == 0)
- labelHeight = 0;
- }
- else
- {
- if(axisYLabel.GetLength() == 0)
- labelHeight = 0;
- }
- pDC->SelectObject(pOldFont);
- tickLabel.Format("%d", maxTick);
- //determine axis specifications
- if(graphAlignment)
- {
- xApexPoint = pGraphL + (tickLabel.GetLength() * charWidth) + labelHeight + 100;
- if(!xAxisAlign) //horizontal
- {
- yApexPoint = pGraphB + 50 + (labelHeight * 2);
- }
- else
- {
- yApexPoint = pGraphB + labelHeight + (xAxisLabelLength * labelHeight);
- }
- yAxisHeight = pGraphT - 200 - charHeight/*this is title height*/ - yApexPoint;
- xAxisWidth = (maxWidth - 100) - xApexPoint;
- }
- else
- {
- xApexPoint = pGraphL + (xAxisLabelLength * charWidth) + labelHeight;
- yApexPoint = pGraphB + 50 + (labelHeight * 2);
- yAxisHeight = pGraphT - 200 - charHeight/*this is title height*/ - yApexPoint;
- xAxisWidth = (maxWidth - 100) - xApexPoint;
- }
- }
- //draw legend
- if(graphHasLegend)
- {
- int legendL = PrintLegend(pDC);
- xAxisWidth = legendL - 200 - xApexPoint;
- }
- if(graphType != 2) //not pie
- {
- //draw axis lines
- PrintAxis(pDC);
- }
- //draw series data and labels
- PrintSeries(pDC);
- //update pGraphB value to pad some space below the graph
- pGraphB -= 90;
- return pGraphB;
- }
- int CGraph::PrintLegend(CDC *pDC)
- {
- CFont legendLabelFont, legendTitleFont;
- TEXTMETRIC tm;
- int legendL, legendT, legendR, legendB;
- int barL, barT, barR, barB;
- //legendLabelFont is 10 point
- legendLabelFont.CreateFont(-200, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI_CHARSET,
- OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH || FF_ROMAN,
- "Times New Roman");
- //legendTitleFont is 12 point
- legendTitleFont.CreateFont(-240, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI_CHARSET,
- OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH || FF_ROMAN,
- "Times New Roman");
- CFont* pOldFont = (CFont*) pDC->SelectObject(&legendTitleFont);
- pDC->GetTextMetrics(&tm);
- int legendCharWidth = tm.tmAveCharWidth;
- legendT = (((pGraphB - pGraphT) / 2) + pGraphT) + (((seriesSize + 1) / 2) * 240 + 300);
- legendB = (((pGraphB - pGraphT) / 2) + pGraphT) - (((seriesSize + 1) / 2) * 240 + 300);
- legendR = pGraphR - 100;
- legendL = legendR - ((graphLegend.GetLegendLength() * legendCharWidth) + 1000);
- legendWidth = legendR - legendL;
- pDC->Rectangle(legendL, legendT, legendR, legendB);
- pDC->TextOut(legendL + (legendWidth / 2) - 360,
- legendT - 160, "图例");
- pDC->SelectObject(pOldFont);
- for(int i = 0; i < seriesSize; i++)
- {
- pOldFont = (CFont*) pDC->SelectObject(&legendLabelFont);
- pDC->GetTextMetrics(&tm);
- int charWidth = tm.tmMaxCharWidth;
- int charHeight = tm.tmHeight;
- CString valuStr;
- pDC->TextOut(legendL + 100, legendT - 500 - (i * charHeight), graphLegend.GetLegendText(i));
- pDC->SelectObject(pOldFont);
- //draw bar
- COLORREF barColor;
- barColor = GetColor(i);
- CBrush brush (barColor);
- CBrush* pOldBrush;
- pOldBrush = pDC->SelectObject(&brush);