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

📄 barchart.cpp

📁 a bar chart,a good refernce for the control
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*********************************************************************
 * BarChart.cpp
 * implementation of 
 *						CChartBar, 
 *						CChartData, 
 *						CChartPrinter,
 *						CChartGCalc,
 *						CGDIGrid,
 *
 * Auther: Hamed.M.
 * EMail : HamedMosavi @ gmail.com
 * 
 * CAUTION   Disclaimer:
 *			 This code is provided as is without any warranty of 
 *			 any kind. The author is not responsible for whatever 
 *			 problem or damages that may occur as aresault of using 
 *			 this code. Use this entirely at your own risk.
 *			 So don't try to find me if this code made your dog 
 *			 Sound like a frog, or burned your car, or even made your
 *			 girl/boy friend shout on you. I am not responsible ;)
 *			 
 *
 ********************************************************************/
/********************************************************************
 * History:
 *
 *			Released : 2007/01/11
 *
 *	BugFixes:
 *			2007/01/11
 *			unsigned long double converted to -> double
 *			Some scaling bugs fixed
 *			Tooltips added
 *
 *			2007/01/15
 *			Some function changed.
 *			Tooltip updated.
 *			Some comments added.
 *
 *			2007/01/20
 *			Tooltips now behave much like tooltips(!)
 *
 *			2007/01/24
 *			Database connectivity added.
 *
 *			2007/01/26
 *			Tooltip bug fixed (SetCapture added).
 ********************************************************************/

#include "stdafx.h"
#include "BarChart.h"

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

 ///////////////////////////////////////////////////////////////////////
 // CBarChart Class
 //
 //				Represents a chart control. The chart shows some bars
 //				Each bar has a value. Bars heights will be calculated
 //				Regarding other bars. The bars are able to show a percentage
 //				Instead of a value. The bar with maximum value has 100% and
 //				Percentage of other bars will be calculated in accordance to
 //				This maximum value.
 //
 ///////////////////////////////////////////////////////////////////////

CBarChart::CBarChart()
{
	m_rctClient = CRect(0, 0, 0, 0);

	SetBKColor(RGB(240, 240, 240));

	m_pBmpBars = NULL;
	m_pBmpOld = NULL;

	ShowLabel(TRUE);
	ShowGrid(TRUE);
	ShowBarText(1, TRUE);
	SetAutoScale(FALSE);
	ShowTooltip(TRUE);

	m_szTitle = "";
	m_szLastErr = "";
}

CBarChart::~CBarChart()
{
	if (m_brFrame.GetSafeHandle())
	{
		m_brFrame.DeleteObject();
	}

	if (m_pBmpOld)
	{
		m_dcMem.SelectObject(m_pBmpOld);
	}

	if (m_pBmpBars)
	{
		m_pBmpBars->DeleteObject();
		delete m_pBmpBars;
		m_pBmpBars = NULL;
	}

	if (m_dcMem.GetSafeHdc())
	{
		m_dcMem.DeleteDC();
	}
}


BEGIN_MESSAGE_MAP(CBarChart, CWnd)
	//{{AFX_MSG_MAP(CBarChart)
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	ON_WM_MOUSEMOVE()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CBarChart message handlers

// Creates the child control.
// Parameters:
//				rect		: Defines bounding rectangle of the control
//				pParentWnd	: A pointer to the window on which this control will be shown
//				nControlID	: Identifyer of the control
//				szChartTitle: Defines the title at the bottom of the control, can be a simple description of the chart.
BOOL CBarChart::Create(const RECT &rect, CWnd *pParentWnd, UINT nControlID, CString szChartTitle)
{
	if (GetSafeHwnd())
	{
		return FALSE;
	}

	m_rctClient = rect;

	m_szTitle = szChartTitle;

	BOOL bRes = CWnd::Create( NULL, NULL, WS_CHILD|WS_VISIBLE, rect, pParentWnd, nControlID );

	if (TRUE == bRes)
	{
		InitToolTips();
	}

	return bRes;
}

BOOL CBarChart::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

void CBarChart::OnPaint() 
{
	CPaintDC dc(this);

	GetClientRect(&m_rctClient);
	
	if (m_dcMem.GetSafeHdc())
	{
		if (m_bAutoScale)
		{
			dc.StretchBlt(0, 0, m_rctClient.Width(), m_rctClient.Height(), 
				&m_dcMem, 0, 0, m_rctMemPic.Width(), m_rctMemPic.Height(), SRCCOPY);
		}
		else
		{
			dc.BitBlt(0, 0, m_rctClient.Width(), m_rctClient.Height(), 
				&m_dcMem, 0, 0, SRCCOPY);
		}
	}
	else
	{
		RedrawChart(&dc);
	}
}
// Prints the content of the child control (WYSIWYG)
// Parameters:
//				bCompatible : 
//								Default is set to FALSE
//								Set this TRUE if you have any difficaulty printing your chart.
//								It's defined since some printers might not be able to print DDB
//								Bitmaps, setting this to TRUE force the function to use DIB instead.
void CBarChart::Print(BOOL bCompatible)
{
	CClientDC dc(this);
	m_printer.Print(&dc, &m_dcMem, m_pBmpBars, 
		(CString)AfxGetAppName() + (CString)" - " + (CString)m_szTitle, 
		m_rctMemPic, m_bAutoScale, bCompatible);
}

void CBarChart::RedrawChart(CDC* pDC)
{
	if (!m_dcMem.GetSafeHdc())
	{
		m_dcMem.CreateCompatibleDC(pDC);
	}

	// Deselect and destroy old bitmap, and create a new one
	ResetBitmap(pDC);

	Refresh();
}

void CBarChart::ResetBitmap(CDC* pDC)
{
	// Deselect and destroy old bitmap
	if (m_pBmpOld)
	{
		m_dcMem.SelectObject(m_pBmpOld);
	}

	if (m_pBmpBars)
	{
		m_pBmpBars->DeleteObject();
		delete m_pBmpBars;
		m_pBmpBars = NULL;
	}

	// Re create bitmap
	m_rctMemPic.top = 0;
	m_rctMemPic.left = 0;
	
	m_rctMemPic.bottom = m_bars.GetBarHeight();
	m_rctMemPic.right = m_bars.GetBarWidth();

	if (m_rctMemPic.Width()<m_rctClient.Width())
	{
		m_rctMemPic.right = m_rctClient.Width();
	}

	if (m_rctMemPic.Height()<m_rctClient.Height())
	{
		m_rctMemPic.bottom = m_rctClient.Height();
	}

	m_pBmpBars = new CBitmap;

	m_pBmpBars->CreateCompatibleBitmap(pDC, m_rctMemPic.right, m_rctMemPic.bottom);
	m_pBmpOld = (CBitmap*)m_dcMem.SelectObject(m_pBmpBars);
}

// Sets/Resets the scale capability
// Parameters:
//				bAutoScale : 
//							If set to TRUE force the chart to scale itself to the parent 
//							Window, regardless of it's initial bounding rectangle.
//							If set to FALSE returns the size of the chart to the original
//							Bounding rectangle.
//							Note that chart saves it's initial state of creation.
void CBarChart::SetAutoScale(BOOL bAutoScale)
{
	m_bAutoScale = bAutoScale;
}

// Sets the color of the background rectangle of the chart
// Parameters:
//				colorBK : 
//							The color in COLORREF format(eg.RGB(250,250,250))
void CBarChart::SetBKColor(COLORREF colorBK)
{
	// Reset background color
	m_colorBK = colorBK;

	// Reset frame brush
	if (m_brFrame.GetSafeHandle())
	{
		m_brFrame.DeleteObject();
	}
	m_brFrame.CreateSolidBrush(DifColor(colorBK, CHART_BORDER_DARKNESS));

	// Reset grid
	m_grid.SetColor(DifColor(colorBK, 50));

	// Redraw window, if it is created
	if (GetSafeHwnd())
	{
		Invalidate();
	}
}

// Adds a bar to the chart
// Parameters:
//				udValue : Value of the bar
//				szLabel : Label of the bar, will be shown under the bar
//				color	: Color of the bar. This color will be used to create a gradient.
//				bRepaint: If set to TRUE, forces the chart to show changes on the screen
//						  Default is set to false. It is recommended to set it to true just
//						  For last Add bar of the chart, so the chart won't be forced to
//						  Show changes every time a single bar is added.
void CBarChart::AddBar(double udValue, CString szLabel, COLORREF color, BOOL bRepaint)
{
	m_bars.AddBar(udValue, szLabel, color);

	if (bRepaint)
	{
		CClientDC dc(this);
		RedrawChart(&dc);

		Invalidate();
	}
}

// Shows/Hides the labels under the chart control
// Parameters:
//				bShow :	 Set to TRUE to show labels
//				bRedraw: If set to TRUE, forces the chart to show changes on the screen
//						  Default is set to false.
void CBarChart::ShowLabel(BOOL bShow, BOOL bRedraw)
{
	m_bars.ShowLabel(bShow);

	if(bRedraw)
	{
		Refresh();
	}
}

// Shows/Hides the grid behind the chart control
// Parameters:
//				bShow :	 Set to TRUE to show labels
//				bRedraw: If set to TRUE, forces the chart to show changes on the screen
//						  Default is set to false.
void CBarChart::ShowGrid(BOOL bShow, BOOL bRedraw)
{
	m_bShowGrid = bShow;
	if(bRedraw)
	{
		Refresh();
	}
}

// Shows/Hides the values at the top of the bars of the chart control
// Parameters:
//				nType :  This parameter can be 0 or 1. 0 indicates the chart should
//						 Display percentage of it's value as the top text which is also
//						 The default behavior. Set it to 1 to force the chart to show
//						 The exact VALUE instead of the percentage.
//				bShow :	 Set to TRUE to show labels or FALSE to hide them
//				bRedraw: If set to TRUE, forces the chart to show changes on the screen
//						  Default is set to false.
void CBarChart::ShowBarText(int nType, BOOL bShow, BOOL bRedraw)
{
	m_bars.ShowBarText(nType, bShow);
	if(bRedraw)
	{
		Refresh();
	}
}

// Activates/Deactivates tooltips for bars
// Parameters:
//				bShow :	 Set to TRUE to Activate tooltips
void CBarChart::ShowTooltip(BOOL bShow)
{
	m_bShowTip = bShow;
}
// Draw bar chart
void CBarChart::DrawBars(CDC* pDC, CRect& rcBound)
{
	m_bars.SetBkColor(m_colorBK);
	m_bars.Draw(&m_dcMem, rcBound);
}

void CBarChart::DrawTitle(CDC* pDC)
{
	//pDC->SetBkMode(TRANSPARENT);
	pDC->SetBkColor(m_colorBK);

	CRect rcTitle = CRect(m_rctMemPic.left ,
				m_rctMemPic.bottom-CHART_TITLE_HEIGHT, 
				m_rctMemPic.right, m_rctMemPic.bottom);

	pDC->FillSolidRect(rcTitle, m_colorBK);

	// UNDONE : DEFAULT DEVICE CONTEXT FONT IS SELECTED, SHOUD CHANGE TO A CUSTOM DEFINED FONT
	pDC->SetTextColor(RGB(200, 200, 200));
	pDC->DrawText(m_szTitle,
		CRect(rcTitle.left+2 ,rcTitle.top+2, rcTitle.right, rcTitle.bottom)
		, DT_CENTER | DT_SINGLELINE | DT_VCENTER);

	pDC->SetTextColor(RGB(0,0,0));
	
	pDC->DrawText(m_szTitle,rcTitle, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
}

// Sets the text(Title/Label) of the chart control. This is the text that will be diplayed
// At the bottom of the chart.
// Parameters:
//				szNewTitle : A title string
void CBarChart::SetTitle(CString szNewTitle)
{
	m_szTitle = szNewTitle;
}

// Forces chart to be redrawn. Redrawing does not affect the chart's bars or etc.
// It just makes the chart to redraw all it's content items.
void CBarChart::Refresh()
{
	if (!GetSafeHwnd())
	{
		return;
	}

	// Draw background
	if (m_dcMem.GetSafeHdc())
	{
		m_dcMem.FillSolidRect(&m_rctMemPic, m_colorBK);
	}
	else
	{
		return;
	}

	// Draw gridlines
	if (m_bShowGrid)
	{
		m_rctMemPic.bottom -= (CHART_TITLE_HEIGHT + 
			(m_bars.IsLabelVisible() * BAR_TXT_LABEL_HEIGHT) + 3);
		
		m_grid.Draw(&m_dcMem, m_rctMemPic);
		m_rctMemPic.bottom += (CHART_TITLE_HEIGHT + 
			(m_bars.IsLabelVisible() * BAR_TXT_LABEL_HEIGHT) + 3);
	}

	// Draw bar chart
	DrawBars(&m_dcMem, m_rctMemPic);

	// Draw the chart title
	DrawTitle(&m_dcMem);

	// Draw a frame around the window
	m_dcMem.FrameRect(&m_rctMemPic, &m_brFrame);

	Invalidate();
}

// Removes all bars from the chart. The background  remains unchanges
void CBarChart::RemoveAll()
{
	m_bars.RemoveAll();
	Refresh();
}

// Removes a bar with the zero index identified. Removing a bar does not force the other bars to
// Re calculate height or percentage. There is, however, workaround this as a new feature.
// Parameters:
//				nIndex: Zero based index of the bar to remove.
void CBarChart::RemoveAt(int nIndex)
{
	m_bars.RemoveAt(nIndex);
	Refresh();
}

// Removes all bars, and forces the chart to be redrawn.
void CBarChart::Reset()
{
	m_bars.RemoveAll();
	m_rctMemPic = CRect(0, 0, 0, 0);

	CClientDC dc(this);
	RedrawChart(&dc);
}


void CBarChart::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);

//	m_rctClient.bottom = cy - m_rctClient.top;
//	m_rctClient.right = cx - m_rctClient.left;
}

void CBarChart::OnMouseMove(UINT nFlags, CPoint point) 
{
	CWnd::OnMouseMove(nFlags, point);

	if ( (m_bAutoScale && PtInRect(m_rctClient, point)) ||
		 (!m_bAutoScale&& PtInRect(m_rctMemPic, point)) )
	{
		if (this!=GetCapture())
		{
			SetCapture();
		}

		m_bars.DisplayToolTip(point, m_rctClient, m_rctMemPic, m_bAutoScale, m_szTip);
		if (!m_szTip.IsEmpty())
		{
			m_toolTip.Pop();
		}
		else
		{
			m_toolTip.Hide();
		}
	}
	else
	{
		m_toolTip.Hide();

		if (this == GetCapture())
		{
			if (!ReleaseCapture())
			{
				// Retry
				ReleaseCapture();
			};
		}
	}
}

void CBarChart::InitToolTips()
{
	m_toolTip.Create(this, &m_bShowTip, &m_szTip, 4000);
}

// Does nothing at the moment
// {
//		//Empty body
// }
void CBarChart::RedrawAll()
{
	// UNDONE : FORCE CHART TO RE CALCULATE ALL BAR HEIGHTS AND %
}
// WARNING : ODBC ONLY
// This function tryes to read chart data from a Table
BOOL CBarChart::ReadFromDatabase(CString szDSN, CString szTable, CString szFilter,
					  CString szLabelFieldName, CString szValueFieldName,
					  COLORREF colorBars,
					  CString szUsername, CString szPass)
{
	CChartDatabase cDB;
	if (!cDB.OpenTable(szDSN, szTable, szLabelFieldName, szValueFieldName,
		szFilter, szUsername, szPass))
	{
		m_szLastErr = cDB.GetLastErrorMessage();
		return FALSE;
	};

	CString szLabel;
	double dVal;

	while (!cDB.IsEOF())
	{
		cDB.GetRow(szLabel, dVal);
		if (colorBars == RGB(0, 0, 0))
		{
			AddBar(dVal, szLabel, RGB(rand()%255, rand()%255, rand()%255));
		}
		else
		{
			AddBar(dVal, szLabel, colorBars);
		}

⌨️ 快捷键说明

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