⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graph.cpp

📁 一个简单的学生学籍管理工具。vc编写。 有喜欢的可以批评指正^_^
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	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 + -