Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
// PWSChart.cpp : implementation file
//
#include "stdafx.h"
#include "PWSChart.h"
#include <pwsdata.hxx>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// CPWSChart
CPWSChart::CPWSChart(): m_pData( NULL ), m_period( PWS_CHART_HOURLY ), m_dataType( PWS_CHART_SESSIONS ) { }
CPWSChart::~CPWSChart() { }
BEGIN_MESSAGE_MAP(CPWSChart, CStatic) //{{AFX_MSG_MAP(CPWSChart)
ON_WM_PAINT() //}}AFX_MSG_MAP
END_MESSAGE_MAP()
//------------------------------------------------------------------
void CPWSChart::DrawChart() { CDC* dc = GetDC(); DrawChart( dc ); ReleaseDC( dc ); }
//------------------------------------------------------------------
void CPWSChart::OnPaint() { CPaintDC dc(this); // device context for painting
// draw the chart
DrawChart( &dc ); }
#define NUM_ROWS 4
//------------------------------------------------------------------
DWORD CPWSChart::GetDataValue( DWORD i ) { PPWS_DATA pData = (PPWS_DATA)m_pData; // get the right thing
switch( m_period ) { case PWS_CHART_HOURLY: switch( m_dataType ) { case PWS_CHART_SESSIONS: return pData->rgbHourData[i].nTotalSessions; case PWS_CHART_HITS: return pData->rgbHourData[i].nHits; case PWS_CHART_KB: return pData->rgbHourData[i].nBytesSent; case PWS_CHART_HITS_PER_USER: if ( !pData->rgbHourData[i].nTotalSessions ) return 0; else return pData->rgbHourData[i].nHits / pData->rgbHourData[i].nTotalSessions; case PWS_CHART_KB_PER_USER: if ( !pData->rgbHourData[i].nTotalSessions ) return 0; else return pData->rgbHourData[i].nBytesSent / pData->rgbHourData[i].nTotalSessions; default: return 0; }; break; case PWS_CHART_DAILY: switch( m_dataType ) { case PWS_CHART_SESSIONS: return pData->rgbDayData[i].nTotalSessions; case PWS_CHART_HITS: return pData->rgbDayData[i].nHits; case PWS_CHART_KB: return pData->rgbDayData[i].nBytesSent; case PWS_CHART_HITS_PER_USER: if ( !pData->rgbHourData[i].nTotalSessions ) return 0; else return pData->rgbDayData[i].nHits / pData->rgbDayData[i].nTotalSessions; case PWS_CHART_KB_PER_USER: if ( !pData->rgbHourData[i].nTotalSessions ) return 0; else return pData->rgbDayData[i].nBytesSent / pData->rgbDayData[i].nTotalSessions; default: return 0; }; break; default: return 0; }; return 0; }
//------------------------------------------------------------------
void CPWSChart::DrawChart( CDC* dc ) { CRect rectWindow, rectChart; CDC* dcDraw = dc; DWORD value;
int cpColWidth; int cpRowHeight; int xErr, xLeftover; CRect rect, rectInterior;
int nNumColumns, i;
if ( !m_pData ) { return; }
// cache the current time
GetLocalTime( &m_timeCurrent );
// prepare basic stuff
GetClientRect( &rectWindow ); rectWindow.bottom--; rectWindow.right--;
rectChart = rectWindow; rectChart.DeflateRect( 1, 0 ); rectChart.top += 1;
//============= CALCULATIONS
// now we calculate scale factors and the like
// first, the period-based stuff
switch( m_period ) { case PWS_CHART_HOURLY: nNumColumns = 24; break; case PWS_CHART_DAILY: nNumColumns = 7; break; default: return; };
// generic stuff
int cpWindowWidth = rectChart.right - rectChart.left + 1; cpColWidth = cpWindowWidth / nNumColumns; xLeftover = cpWindowWidth % nNumColumns; cpRowHeight = (rectChart.bottom - rectChart.top) / NUM_ROWS;
// figure out the maximum value of the data
m_max = 0; for ( i = 0; i < nNumColumns; i++ ) { DWORD data = GetDataValue(i); if ( data > m_max ) m_max = data; };
// create a floating point scaling factor for the y value;
float yFactor; if ( m_max ) yFactor = (float)(rectChart.bottom - rectChart.top ) / m_max;
//============= DRAWING!
// start by blanking out the background of the chart
dcDraw->FillSolidRect( &rectWindow, GetSysColor(COLOR_APPWORKSPACE) );
// prepare the data rect
rect.left = rectChart.left; rect.right = rect.left + cpColWidth; rect.bottom = rectChart.bottom; xErr = 0;
// the bars
if ( m_max ) { for ( i = 0; i < nNumColumns; i++ ) { // only draw something if there is a value there
value = GetDataValue(i); if ( !value ) { goto increment; }
// build the rectangle to fill
rect.top = (int)((float)rectWindow.bottom - 1.0 - ((float)GetDataValue(i) * yFactor));
// draw the data bar
dcDraw->Draw3dRect( rect, GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW) ); // fill in the data bar
rectInterior = rect; rectInterior.DeflateRect( 1, 1 ); dcDraw->FillSolidRect( rectInterior, GetSysColor(COLOR_3DFACE) );
// increment stuff
increment: rect.left = rect.right; // account for the error factor
xErr += xLeftover; if ( xErr > nNumColumns ) { rect.right++; xErr -= nNumColumns; } rect.right += cpColWidth; } } }
|