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

📄 graph.cpp

📁 一个简单的学生学籍管理工具。vc编写。 有喜欢的可以批评指正^_^
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Graph.cpp : implementation file
//

#include "stdafx.h"
//#include "testdraw.h"
#include "GraphSeries.h"
#include "GraphLegend.h"
#include "math.h"
#include "Graph.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGraph

CGraph::CGraph()
{
	graphSeries = new CObList();
	tickRange = 100;
	seriesSize = 0;

	graphHasLegend = FALSE;
	legendWidth = 0;

	graphType = 0;

	dataColor[1] = RGB(0,255,0);  //green
	dataColor[0] = RGB(0,0,255);  //blue
	dataColor[2] = RGB(255,0,0);  //red
	dataColor[3] = RGB(255,255,0);  //yellow
	dataColor[4] = RGB(255,153,51);  //orange
	dataColor[5] = RGB(255,51,153);  //hot pink
	dataColor[6] = RGB(153,0,204);  //purple
	dataColor[7] = RGB(0,255,255);  //cyan
	dataColor[8] = RGB(0,0,0);  //black
	dataColor[9] = RGB(255,255,255);  //white

	xAxisAlign = 0;  //horizontal
	xAxisLabelLength = 0;
}

CGraph::CGraph(int type)
{
	graphSeries = new CObList();
	tickRange = 100;
	seriesSize = 0;

	graphHasLegend = FALSE;
	legendWidth = 0;

	graphType = type;

	dataColor[0] = RGB(0,255,0);  //green
	dataColor[1] = RGB(0,0,255);  //blue
	dataColor[2] = RGB(255,0,0);  //red
	dataColor[3] = RGB(255,255,0);  //yellow
	dataColor[4] = RGB(255,153,51);  //orange
	dataColor[5] = RGB(255,51,153);  //hot pink
	dataColor[6] = RGB(153,0,204);  //purple
	dataColor[7] = RGB(0,255,255);  //cyan
	dataColor[8] = RGB(0,0,0);  //black
	dataColor[9] = RGB(255,255,255);  //white

	xAxisAlign = 0;  //horizontal
	xAxisLabelLength = 0;
}

CGraph::~CGraph()
{
}


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::SetTickSpace(int yDist)
{
	tickSpace = yDist;
}

void CGraph::SetTickRange(int maxTick)
{
	tickRange = maxTick;
}

void CGraph::SetGraphType(int gType)
{
	graphType = gType;
}

void CGraph::SetXAxisAlignment(int alignValue)
{
	xAxisAlign = alignValue;
}

int CGraph::GetXAxisAlignment()
{
	return xAxisAlign;
}

void CGraph::DrawGraph(CDC* pDC)
{
	pDC->SetTextColor(RGB(0,0,255));

	CString tickLabel;
	CWnd* graphWnd = pDC->GetWindow();
	CRect graphRect;
	graphWnd->GetClientRect(&graphRect);

	maxHeight = graphRect.Height() - 20;  //for frame window and status bar
	maxWidth = graphRect.Width() - 5;  //for frame window
	//We will leave 5 pixels blank on all sides of the graph.  So
	//top-left side of graph is at 5,5 and the bottom-right side of
	//graph is at ((maxHeight - 5), (maxWidth - 5))
	//these settings are altered by axis labels and legends.

	//draw graph title
	CFont titleFont;
	titleFont.CreateFont(22, 0, 0, 0, 600, FALSE, FALSE, 0,
		ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
	CFont* pOldFont = (CFont*) pDC->SelectObject(&titleFont);
if(graphType == 2)
{
	pDC->TextOut(16,20,graphTitle);
}else{
	pDC->TextOut((maxWidth / 2) - ((graphTitle.GetLength() * 16) / 2),
		20, graphTitle);}
	pDC->SelectObject(pOldFont);

	if(graphType == 2)  //pie
	{

		//since pie has not axis lines, set to full size minus 5 on each side
		//these are needed for legend to plot itself
		xAxisWidth = maxWidth - 10;
		yAxisHeight = maxHeight - 20;  //10 buffer and 20 for title
		xApexPoint = 5;
		yApexPoint = maxHeight - 5;
	}
	else
	{
		//X-axis will be raised by 20 pixels for tick-labels
		//Y-axis will be shifted by (max(tick-label size) * 10) + label * 10
		
		tickLabel.Format("%d", tickRange);

		//determine axis specifications 
			//tick label offset is 4 (for the tick) + 6 (total 10) from axis line
		xApexPoint = 5 + (tickLabel.GetLength() * 8) + 10 + 30/*(axisYLabel.GetLength() * 8)*/ + 5; //allowing 8 pixels per char in tick label
			//y apex based on 5 + 15 (x label) + 4 (for the tick) + 4 (text below tick) + 12 (tick label) + 10
		if(!xAxisAlign)  //horizontal
			yApexPoint = (maxHeight - 5) - 45;		//apex points are the cross section of axis lines
		else
			yApexPoint = (maxHeight - 5) - (xAxisLabelLength * 12) - 10;
		yAxisHeight = yApexPoint - 40;
		xAxisWidth = (maxWidth - 5) - xApexPoint;
	}

	//draw legend
	if(graphHasLegend)
		DrawLegend(pDC);

	if(graphType != 2)  //pie
	{
		//draw axis lines
		DrawAxis(pDC);
	}

	//draw series data and labels
	DrawSeries(pDC);

}

void CGraph::DrawAxis(CDC* pDC)
{
	pDC->SetTextColor(RGB(0,0,255));

	//draw y axis
	pDC->MoveTo(xApexPoint, yApexPoint);  
	pDC->LineTo(xApexPoint, yApexPoint - yAxisHeight);

	//draw x axis
	pDC->MoveTo(xApexPoint, yApexPoint);  
	if(graphHasLegend)
		pDC->LineTo(xApexPoint + (xAxisWidth - legendWidth - 10), yApexPoint);
	else
		pDC->LineTo(xApexPoint + xAxisWidth, yApexPoint);

	//draw labels
	CFont sideFont;
	sideFont.CreateFont(16, 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->TextOut(10, (maxHeight / 2) - 6, axisYLabel);
	pDC->SelectObject(pOldFont);

	pDC->TextOut(xApexPoint + (xAxisWidth / 2) - (axisXLabel.GetLength() * 19), maxHeight - 5 - 6, axisXLabel);

	//to allow scalability (height may be less than tickRange)
	double tickScale = 0.00;
	if(tickRange > yAxisHeight)
		tickScale = ((yAxisHeight * 1.00) / (tickRange * 1.00)) * tickSpace;
	else tickScale = tickSpace*2;

	//draw y axis ticks
	for(int y = 1; y <= tickRange / tickSpace; y++)  //no tick at 0
	{
		int tickYLocation = yApexPoint - (y * tickScale);

		pDC->MoveTo(xApexPoint - 4, tickYLocation);
		pDC->LineTo(xApexPoint + 4, tickYLocation);

		//draw tick label
		CString tickLabel;
		tickLabel.Format("%d", y * tickSpace);

		pDC->TextOut(xApexPoint - 10 - (tickLabel.GetLength() * 8), tickYLocation - 6, tickLabel);

	}

	//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);

		int seriesSpace;
		int tickXLocation;
		if(graphHasLegend)
			seriesSpace= (xAxisWidth - legendWidth - 10) / graphSeries->GetCount();
		else
			seriesSpace= xAxisWidth / graphSeries->GetCount();
		tickXLocation = xApexPoint + ((x * seriesSpace) - (seriesSpace / 2));

		pDC->MoveTo(tickXLocation,yApexPoint - 4);
		pDC->LineTo(tickXLocation,yApexPoint + 4);

		//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(16, 0, (xAxisAlign * 10), 0, 700, FALSE, FALSE, 0,
				ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
				DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial");
			pOldFont = (CFont*) pDC->SelectObject(&sideFont2);
			if(xAxisAlign < 180)
				pDC->TextOut(tickXLocation - 8, yApexPoint + 8 + (xAxisLabelLength * 8), tickLabel);
			else
				pDC->TextOut(tickXLocation + 8, yApexPoint + 8, tickLabel);

			pDC->SelectObject(pOldFont);
		}
	}


}

void CGraph::AddSeries(CGraphSeries* dataSet)
{
	int numData = 0;
	for(int i = 0; i < 10; i++)
	{
		if(dataSet->GetData(i) > 0)
			numData++;
		if(dataSet->GetLabel().GetLength() > xAxisLabelLength)
			xAxisLabelLength = dataSet->GetLabel().GetLength();
	}
	if(numData > seriesSize)
		seriesSize = numData;

	graphSeries->AddTail(dataSet);
}

void CGraph::SetXAxisLabel(CString label)
{
	axisXLabel = label;
}
void CGraph::SetYAxisLabel(CString label)
{
	axisYLabel = label;
}

void CGraph::SetColor(int group, COLORREF groupColor)
{
	dataColor[group] = groupColor;
}

COLORREF CGraph::GetColor(int group)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -