www.gusucode.com > VC++曲线绘制源码——人体生命曲线-源码程序 > VC++曲线绘制源码——人体生命曲线-源码程序/code/BioGraphCtrl.cpp
#include "stdafx.h" #include "math.h" #include "BioGraphCtrl.h" // Download by http://www.NewXing.com BioGraphCtrl::BioGraphCtrl() { m_bornDate = CTime(1980, 1, 1, 0, 0, 0 ); m_curDate = CTime::GetCurrentTime (); m_startDate = CTime (m_curDate.GetYear(), m_curDate.GetMonth(), 1, 0, 0, 0); m_endDate = CTime (m_curDate.GetYear(), m_curDate.GetMonth()+1, 1, 0, 0, 0); m_topColor = RGB (255, 255, 255); m_bottomColor = RGB (255, 255, 0); m_focusColor = RGB(255,0,0); m_focusDate = CTime (m_curDate.GetYear(), m_curDate.GetMonth(), 5, 0, 0, 0); } BioGraphCtrl::~BioGraphCtrl() { } void BioGraphCtrl::SetBornDate (CTime bornDate) { m_bornDate = bornDate; Invalidate (); } CTime BioGraphCtrl::GetBornDate () { return m_bornDate; } void BioGraphCtrl::SetCurDate (CTime curDate) { m_curDate = curDate; } CTime BioGraphCtrl::GetCurDate () { return m_curDate; } void BioGraphCtrl::SetStartDate (CTime startDate) { m_startDate = startDate; Invalidate (); } CTime BioGraphCtrl::GetStartDate () { return m_startDate; } void BioGraphCtrl::SetEndDate (CTime endDate) { if (endDate == NULL) { int month = m_startDate.GetMonth(); int year = m_startDate.GetYear(); if (month == 12) { month = 1; year ++; } else month++; m_endDate = CTime(year, month, m_startDate.GetDay(), 0, 0, 0); } else m_endDate = endDate; } CTime BioGraphCtrl::GetEndDate () { return m_endDate; } void BioGraphCtrl::SetFocusDate (CTime focusDate) { m_focusDate = focusDate; } CTime BioGraphCtrl::GetFocusDate () { return m_focusDate; } void BioGraphCtrl::SetTopColor(COLORREF topColor) { m_topColor = topColor; } COLORREF BioGraphCtrl::GetTopColor() { return m_topColor; } void BioGraphCtrl::SetBottomColor(COLORREF bottomColor) { m_bottomColor = bottomColor; } COLORREF BioGraphCtrl::GetBottomColor() { return m_bottomColor; } void BioGraphCtrl::SetFocusColor(COLORREF focusColor) { m_focusColor = focusColor; } COLORREF BioGraphCtrl::GetFocusColor() { return m_focusColor; } void BioGraphCtrl::GotoNextMonth() { int month = m_endDate.GetMonth(); int year = m_endDate.GetYear(); if (month == 12) { month = 1; year ++; } else month++; m_startDate = m_endDate; m_endDate = CTime(year, month, 1, 0, 0, 0); m_focusDate = CTime(m_startDate.GetYear(), m_startDate.GetMonth(), m_focusDate.GetDay(), 0, 0, 0); Invalidate (); GetParent ()->SendMessage (WM_BIO_SELECTCHANGING, GetDlgCtrlID (), NULL ); } void BioGraphCtrl::GotoPrevMonth() { int month = m_startDate.GetMonth(); int year = m_startDate.GetYear(); if (month == 1) { month = 12; year --; } else month--; m_endDate = m_startDate; m_startDate = CTime(year, month, 1, 0, 0, 0); m_focusDate = CTime(m_startDate.GetYear(), m_startDate.GetMonth(), m_focusDate.GetDay(), 0, 0, 0); Invalidate (); GetParent ()->SendMessage (WM_BIO_SELECTCHANGING, GetDlgCtrlID (), NULL ); } void BioGraphCtrl::GotoCurrentMonth() { CTime currentTime = CTime::GetCurrentTime(); m_startDate = CTime(currentTime.GetYear(), currentTime.GetMonth(), 1, 0, 0, 0); int month = m_startDate.GetMonth(); int year = m_startDate.GetYear(); if (month == 12) { month = 1; year ++; } else month++; m_endDate = CTime(year, month, 1, 0, 0, 0); m_focusDate = CTime(m_startDate.GetYear(), m_startDate.GetMonth(), m_focusDate.GetDay(), 0, 0, 0); Invalidate (); GetParent ()->SendMessage (WM_BIO_SELECTCHANGING, GetDlgCtrlID (), NULL ); } //渐变颜色背景 void BioGraphCtrl::DrawBackground (CDC* pDC) { byte r1 = GetRValue (m_topColor); byte g1 = GetGValue (m_topColor); byte b1 = GetBValue (m_topColor); byte r2 = GetRValue (m_bottomColor); byte g2 = GetGValue (m_bottomColor); byte b2 = GetBValue (m_bottomColor); CRect rect; GetClientRect(rect); float rStep = float (r2-r1) / rect.Height (); float gStep = float (g2-g1) / rect.Height (); float bStep = float (b2-b1) / rect.Height (); float r = r1; float g = g1; float b = b1; for (float y = 0; y < rect.Height(); y ++) { CPen pen (PS_SOLID, 1, RGB (r, g, b)); CPen* oldPen = pDC->SelectObject (&pen); pDC->MoveTo (0, int(y)); pDC->LineTo (rect.right, int(y)); pDC->SelectObject (oldPen); r += rStep; g += gStep; b += bStep; } } //画网格 void BioGraphCtrl::DrawGrid (CDC* pDC) { CFont font; font.CreateFont (14, 4, 0, 0, FW_EXTRALIGHT, 0, 0, 0, ANSI_CHARSET, OUT_STROKE_PRECIS, CLIP_STROKE_PRECIS, DRAFT_QUALITY, VARIABLE_PITCH | FF_SWISS,_T("Arial")); CFont* oldFont = pDC->SelectObject(&font); CRect rect; GetClientRect(rect); rect.bottom -= 20; //画横线 CPen pen1 (PS_SOLID, 1, RGB (0, 0, 180)); CPen* oldPen = pDC->SelectObject(&pen1); float yStep = float (rect.Height()-1) / 10; for (float y = 0 ; y < rect.Height(); y += yStep) { pDC->MoveTo (rect.left, int(y)); pDC->LineTo (rect.right, int(y)); } //画竖线 CPen pen2 (PS_SOLID, 1, RGB(150, 150, 0)); pDC->SelectObject(&pen2); int days = min (max ( int((m_endDate-m_startDate).GetDays ()), 7), 100); float xStep = float (rect.Width()-1) / days; for (float x = 0; x < rect.Width(); x += xStep) { pDC->MoveTo (int(x), rect.top); pDC->LineTo (int(x), rect.bottom); } //加粗中线 CPen pen3 (PS_SOLID, 2, RGB(50, 0, 250)); pDC->SelectObject(&pen3); pDC->MoveTo (rect.left, rect.Height() / 2); pDC->LineTo (rect.right, rect.Height() / 2); DrawGuage(pDC); pDC->SelectObject (oldPen); pDC->SelectObject (oldFont); } //画生命曲线 void BioGraphCtrl::DrawLifeCurve (CDC* pDC) { //体力曲线 DrawLifeCurve(pDC, 23, 1, 1, RGB(0,255,0)); //情绪曲线 DrawLifeCurve(pDC, 28, 1, 1, RGB(0,0,255)); //智力曲线 DrawLifeCurve(pDC, 33, 1, 1, RGB(255,0,0)); } //画曲线 void BioGraphCtrl::DrawLifeCurve (CDC* pDC, int cycle, float range, int width, COLORREF color) { const float Pi = 3.1415926353f; CPen pen (PS_SOLID, width, color); CPen* oldPen = pDC->SelectObject(&pen); CRect rect; GetClientRect(rect); rect.bottom -= 20; int offsDay = CalcDays() % cycle; int days = min (max ( int((m_endDate-m_startDate).GetDays ()), 7), 100); float xStep = float (rect.Width()-1) / days; for (float x = 0; x <= rect.right; x ++) { float y = rect.Height() / 2 - rect.Height() / 2 * range * float (sin((x + offsDay*xStep) * 2 * Pi / (cycle*xStep))); if (x == 0) pDC->MoveTo (int (x), int (y)); else pDC->LineTo (int (x), int (y)); } pDC->SelectObject (oldPen); } void BioGraphCtrl::DrawLabel (CDC* pDC) { } //画焦点 void BioGraphCtrl:: DrawFocus (CDC* pDC) { CRect rect; GetClientRect(rect); int days = min (max ( int((m_endDate-m_startDate).GetDays ()), 7), 100); float xStep = float (rect.Width()-1) / days; int offsDays = int ((m_focusDate - m_startDate).GetDays ()); int x = int(xStep * offsDays); CPen pen (PS_SOLID, 3, m_focusColor); CPen* oldPen = pDC->SelectObject(&pen); pDC->MoveTo (x, rect.top); pDC->LineTo (x, rect.bottom - 20); pDC->LineTo (int(x + xStep), rect.bottom - 20); pDC->LineTo (int(x + xStep), rect.top); pDC->LineTo (x, rect.top); pDC->SelectObject (oldPen); } void BioGraphCtrl::DrawGuage (CDC* pDC) { CRect rect; GetClientRect(rect); int days = min (max ( int((m_endDate-m_startDate).GetDays ()), 7), 100); float xStep = float (rect.Width()-1) / days; int fontHeight = max (6, min (int(xStep), 32)); CFont font; font.CreateFont (fontHeight, 0, 0, 0, FW_EXTRALIGHT, 0, 0, 0, ANSI_CHARSET, OUT_STROKE_PRECIS, CLIP_STROKE_PRECIS, DRAFT_QUALITY, VARIABLE_PITCH | FF_SWISS,_T("Arial")); pDC->SelectObject(&font); pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(20,20,0)); CTime curDate = m_startDate.GetTime(); CTimeSpan day( 1, 0, 0, 0); for (float x = 0; x < rect.Width(); x += xStep) { CString str = curDate.Format("%d"); pDC->TextOut(int(x + xStep / 5), rect.bottom - 20, str); curDate = curDate + day; } } int BioGraphCtrl::CalcDays () { return int ((m_startDate - m_bornDate).GetDays ()); } float BioGraphCtrl::Eval (CTime testDate, int cycle) { const float Pi = 3.1415926353f; int offsDay = (int ((testDate - m_bornDate).GetDays ())) % cycle; return float ((sin(float(offsDay) * 2 * Pi / cycle)) + 1) * 50; } CString BioGraphCtrl::EvalString(CTime testDate) { CString str =""; str.Format("%s\r\n体力 %.f\r\n情绪 %.f\r\n智力 %.f\r\n", testDate.Format("%Y - %m - %d"), Eval(testDate, 23), Eval(testDate, 28), Eval(testDate, 33)); return str; } BEGIN_MESSAGE_MAP(BioGraphCtrl, CWnd) ON_WM_LBUTTONDOWN() ON_WM_PAINT() ON_WM_MOUSEMOVE() END_MESSAGE_MAP() void BioGraphCtrl::OnLButtonDown(UINT nFlags, CPoint point) { GetParent ()->SendMessage (WM_BIO_SELECTCHANGED, GetDlgCtrlID (), NULL ); CWnd::OnLButtonDown(nFlags, point); } void BioGraphCtrl::OnPaint() { CPaintDC dc(this); CDC* pDC = &dc; DrawBackground (pDC); DrawGrid (pDC); DrawLifeCurve (pDC); DrawFocus (pDC); DrawLabel (pDC); } void BioGraphCtrl::OnMouseMove(UINT nFlags, CPoint point) { static CTime oldFocusDate = m_focusDate; CRect rect; GetClientRect(rect); int days = min (max ( int((m_endDate-m_startDate).GetDays ()), 7), 100); float xStep = float (rect.Width()-1) / days; CTimeSpan day( int (point.x / xStep), 0, 0, 0); m_focusDate = m_startDate.GetTime(); m_focusDate += day; if (m_focusDate != oldFocusDate ) { GetParent ()->SendMessage (WM_BIO_SELECTCHANGING, GetDlgCtrlID (), NULL ); Invalidate (); } oldFocusDate = m_focusDate; CWnd::OnMouseMove(nFlags, point); }