📄 graph.cpp
字号:
{
return dataColor[group];
}
void CGraph::DrawSeries(CDC* pDC)
{
int barWidth;
int dataPlotSize; //used to plot rects of data
int barL, barT, barR, barB;
int tickXLocation;
int seriesSpace;
double barHeight; //for scalability
POSITION pos;
CGraphSeries* tmpSeries;
if(graphType == 0) //bar
{
//determine width of barchart data blocks
if(graphHasLegend)
seriesSpace = (xAxisWidth - legendWidth - 10) / graphSeries->GetCount();
else
seriesSpace = xAxisWidth / graphSeries->GetCount();
barWidth = (seriesSpace * .6) / seriesSize;
dataPlotSize = seriesSize * barWidth;
pos = graphSeries->GetHeadPosition();
for(int x = 1; x <= graphSeries->GetCount(); x++)
{
tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
tickXLocation = xApexPoint + ((x * seriesSpace) - (seriesSpace / 2));
for(int s = 0; s < seriesSize; s++)
{
barHeight = 0.00;
//to allow scalability (height may be less than tickRange)
double dataScale = 0.00;
if(tickRange > yAxisHeight)
dataScale = (yAxisHeight * 1.00) / (tickRange * 1.00);
else dataScale = 1;
barHeight = (tmpSeries->GetData(s) * 1.00) * dataScale;
barL = 15+tickXLocation - (dataPlotSize / 2) + (s * barWidth);
barT = yApexPoint - barHeight*2;
barR = barL + barWidth-30;
barB = yApexPoint;
COLORREF barColor;
barColor = GetColor(s);
CBrush brush (barColor);
CBrush* pOldBrush;
pOldBrush = pDC->SelectObject(&brush);
pDC->Rectangle(barL, barT, barR, barB);
pDC->SelectObject(&pOldBrush);
}
}
}
if(graphType == 1) //line
{
int lastXLoc, lastYLoc;
for(int s = 0; s < seriesSize; s++)
{
//determine width of barchart data blocks
if(graphHasLegend)
seriesSpace = (xAxisWidth - legendWidth - 10) / graphSeries->GetCount();
else
seriesSpace = xAxisWidth / graphSeries->GetCount();
barWidth = (seriesSpace * .6) / seriesSize;
dataPlotSize = seriesSize * barWidth;
pos = graphSeries->GetHeadPosition();
for(int x = 1; x <= graphSeries->GetCount(); x++)
{
tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
tickXLocation = xApexPoint + ((x * seriesSpace) - (seriesSpace / 2));
barHeight = 0.00;
//to allow scalability (height may be less than tickRange)
double dataScale = 0.00;
if(tickRange > yAxisHeight)
dataScale = (yAxisHeight * 1.00) / (tickRange * 1.00);
else dataScale = 1;
barHeight = (tmpSeries->GetData(s) * 1.00) * dataScale;
int yDataLocation = yApexPoint - barHeight;
//now have x and y location of center of ellipse
COLORREF barColor;
barColor = GetColor(s);
CBrush brush (barColor);
CBrush* pOldBrush;
pOldBrush = pDC->SelectObject(&brush);
//draw line back to last data member
if(x > 1)
{
CPen* pOldPen;
CPen linePen (PS_SOLID, 1, barColor);
pOldPen = pDC->SelectObject(&linePen);
pDC->MoveTo(lastXLoc + 2, lastYLoc - 1);
pDC->LineTo(tickXLocation - 3, yDataLocation - 1);
pDC->SelectObject(pOldPen);
}
//now draw ellipse...
pDC->Ellipse(tickXLocation - 3, yDataLocation - 3,
tickXLocation + 3, yDataLocation + 3);
lastXLoc = tickXLocation;
lastYLoc = yDataLocation;
pDC->SelectObject(&pOldBrush);
}
}
}
if(graphType == 2) //pie
{
double dataSum = 0.00; //for storing cumulative sum
int lastXLocation, lastYLocation;
int newXLocation, newYLocation;
double percent = 0.00;
int degrees;
double totalSum = 0.00;
int deltaXY;
int radius;
lastXLocation = 0;
lastYLocation = 0;
//determine width of pie display area
if(graphHasLegend)
if(((xAxisWidth - legendWidth - 10) / graphSeries->GetCount())
> (yAxisHeight - 10))
seriesSpace = (yAxisHeight - 10) / graphSeries->GetCount();
else
seriesSpace = (xAxisWidth - legendWidth - 10) / graphSeries->GetCount();
else
if(xAxisWidth > yAxisHeight)
seriesSpace = yAxisHeight / graphSeries->GetCount();
else
seriesSpace = xAxisWidth / graphSeries->GetCount();
double tmpD = (seriesSpace - 60)* .9; //max width of any pie
radius = tmpD *1.3;
int centerYPie = yAxisHeight / 2;
pos = graphSeries->GetHeadPosition();
for(int x = 1; x <= graphSeries->GetCount(); x++)
{
tmpSeries = (CGraphSeries*)graphSeries->GetNext(pos);
totalSum = 0;
for(int s = 0; s < 10; s++)
totalSum += tmpSeries->GetData(s);
int pieLeft, pieRight;
if(graphSeries->GetCount() == 1)
{
pieLeft = ((xAxisWidth - legendWidth - 10) / 2) - radius - 25;
}
else
{
pieLeft = xApexPoint + 5 + (x * 50) + ((x - 1) * (2 * radius));
}
pieRight = pieLeft + ( 2*radius);
CRect pieRect (pieLeft-60,
centerYPie - radius,
pieRight-60,
centerYPie + radius);
int centerXPie = pieLeft + radius;
//plot series label
pDC->TextOut(centerXPie - ((tmpSeries->GetLabel().GetLength() * 8) / 2+55),
centerYPie + radius +12, tmpSeries->GetLabel());
lastXLocation = pieLeft;
lastYLocation = centerYPie;
dataSum = 0;
for(s = 0; s < 10; s++)
{
if(tmpSeries->GetData(s) > 0)
{
dataSum += tmpSeries->GetData(s);
percent = (dataSum * 100) / totalSum;
degrees = (360 * percent) / 100;
//degress / 90 will never exceed 4.
//this can tell us the quadrant of destination
deltaXY = (degrees * radius) / 90;
//deltaXY is change from start point of pie 0
//this value is total change. so if radius is 300
//and degrees is 270, delta is 300. The change
//would move both x and y 300 pixels. For x, 100
//to right is center, another 100 to right edge,
//100 back to center. For y, 100 to bottom, 100
//back to center, 100 to top. thus gives 270 degree
//rotation.
//determine destination quadrant...
//and set newXLocation and newYLocation values...
int quadrant = degrees / 90; //truncates decimal
switch(quadrant)
{
//in the computations below, the remarked line is
//the original computation. The line above it, for
//actual use, is the simplified line, and gives the
//exact same result
case 0 : newXLocation = pieLeft + deltaXY;
newYLocation = centerYPie + deltaXY;
break;
case 1 : newXLocation = pieLeft + deltaXY;
newYLocation = centerYPie + (2 * radius) - deltaXY;
// newYLocation = centerYPie + radius - (deltaXY - radius);
break;
case 2 : newXLocation = pieLeft + (4 * radius) - deltaXY;
// newXLocation = pieLeft + (2 * radius) - (deltaXY - (2 * radius));
newYLocation = centerYPie + (2 * radius) - deltaXY;
// newYLocation = centerYPie - (deltaXY - (2 * radius));
break;
case 3 : newXLocation = pieLeft + (4 * radius) - deltaXY;
// newXLocation = pieLeft + radius - (deltaXY - (3 * radius));
newYLocation = centerYPie - (4 * radius) + deltaXY;
// newYLocation = centerYPie - radius + (deltaXY - (3 * radius));
break;
case 4 : newXLocation = pieLeft;
newYLocation = centerYPie - 1;
break;
}
if(s == 0)
lastYLocation -= 1;
CPoint p1 (lastXLocation-60, lastYLocation);
CPoint p2 (newXLocation-60, newYLocation);
COLORREF barColor;
barColor = GetColor(s);
CBrush brush (barColor);
CBrush* pOldBrush;
pOldBrush = pDC->SelectObject(&brush);
pDC->Pie(pieRect, p1, p2);
pDC->SelectObject(pOldBrush);
lastXLocation = newXLocation;
lastYLocation = newYLocation;
}
}
}
}
}
void CGraph::SetLegend(int datagroup, CString label)
{
graphLegend.SetLegendText(datagroup, label);
graphHasLegend = TRUE;
}
void 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;
legendT = (maxHeight / 2) - (legendHeight / 2);
legendB = legendT + legendHeight;
legendR = maxWidth - 5;
legendL = legendR - ((graphLegend.GetLegendLength() * 12) + 50);
//allows 50 pixels for display of legend bar 45 + 5 space.
legendWidth = legendR - legendL;
pDC->Rectangle(legendL, legendT, legendR, legendB);
pDC->TextOut(legendL + (legendWidth / 2) - 24,
legendT + 3, "Legend");
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.
pDC->TextOut(legendL + 5, legendT + 24 + (i * 18), graphLegend.GetLegendText(i));
//draw bar
COLORREF barColor;
barColor = GetColor(i);
CBrush brush (barColor);
CBrush* pOldBrush;
pOldBrush = pDC->SelectObject(&brush);
barL = legendL + 5 + (graphLegend.GetLegendText(i).GetLength() * 8) + 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);
}
}
void CGraph::SetGraphTitle(CString title)
{
graphTitle = title;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -