📄 graph.cpp
字号:
//--------------------------------------------------------------------------
//
// Filename: Graph.cpp
//
// Description:
//
//--------------------------------------------------------------------------
// $Archive: /WirelessUSB/WUSB Kits/CY3635 N-to-1 DVK/DocSrc/CD_Root/Software/Nto1/common/Graph/Graph.cpp $
// $Modtime: 10/06/04 6:19p $
// $Revision: 1 $
//--------------------------------------------------------------------------
//
// Copyright 2004, Cypress Semiconductor Corporation.
//
// This software is owned by Cypress Semiconductor Corporation (Cypress)
// and is protected by and subject to worldwide patent protection (United
// States and foreign), United States copyright laws and international
// treaty provisions. Cypress hereby grants to licensee a personal,
// non-exclusive, non-transferable license to copy, use, modify, create
// derivative works of, and compile the Cypress Source Code and derivative
// works for the sole purpose of creating custom software in support of
// licensee product to be used only in conjunction with a Cypress integrated
// circuit as specified in the applicable agreement. Any reproduction,
// modification, translation, compilation, or representation of this
// software except as specified above is prohibited without the express
// written permission of Cypress.
//
// Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// Cypress reserves the right to make changes without further notice to the
// materials described herein. Cypress does not assume any liability arising
// out of the application or use of any product or circuit described herein.
// Cypress does not authorize its products for use as critical components in
// life-support systems where a malfunction or failure may reasonably be
// expected to result in significant injury to the user. The inclusion of
// Cypress' product in a life-support systems application implies that the
// manufacturer assumes all risk of such use and in doing so indemnifies
// Cypress against all charges.
//
// Use may be limited by and subject to the applicable Cypress software
// license agreement.
//
//--------------------------------------------------------------------------
#include "stdafx.h"
#include "Graph.h"
#include "math.h"
#include ".\graph.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// This macro can be called at the beginning and ending of every
// method. It is identical to saying "ASSERT_VALID(); ASSERT_KINDOF();"
// but is written like this so that VALIDATE can be a macro. It is useful
// as an "early warning" that something has gone wrong with "this" object.
#ifndef VALIDATE
#ifdef _DEBUG
#define VALIDATE ::AfxAssertValidObject(this, __FILE__ , __LINE__ ); \
_ASSERTE(IsKindOf(GetRuntimeClass()));
#else
#define VALIDATE
#endif
#endif
#undef VERIFY
#define VERIFY(x) x
#ifdef _DEBUG
#undef ASSERT_VALID
#define ASSERT_VALID(x) x=x
#endif
/////////////////////////////////////////////////////////////////////////////
// CGraphSeries
// Constructor.
CGraphSeries::CGraphSeries(CString sLabel /* = "" */ )
: m_sLabel(sLabel)
{
}
// Destructor.
/* virtual */ CGraphSeries::~CGraphSeries()
{
while (!m_dwaValues.IsEmpty())
{
int* pValue;
if ((pValue = (int*)m_dwaValues.GetAt(0)) != NULL)
{
delete pValue;
}
m_dwaValues.RemoveAt(0);
}
}
//
void CGraphSeries::SetLabel(CString sLabel)
{
VALIDATE;
_ASSERTE(! sLabel.IsEmpty());
m_sLabel = sLabel;
}
//
void CGraphSeries::SetData(int nGroup, int nValue)
{
VALIDATE;
_ASSERTE(0 <= nGroup);
int* pValue = NULL;
if (m_dwaValues.GetUpperBound() >= nGroup)
{
pValue = (int*)m_dwaValues.GetAt(nGroup);
}
if (!pValue)
{
pValue = new int(0);
if(!pValue) return;
m_dwaValues.SetAtGrow(nGroup, (void*)pValue);
}
if (pValue)
*pValue = nValue;
}
//
CString CGraphSeries::GetLabel()
{
VALIDATE;
return m_sLabel;
}
//
int CGraphSeries::GetData(int nGroup)
{
VALIDATE;
_ASSERTE(0 <= nGroup);
_ASSERTE(m_dwaValues.GetSize() > nGroup);
int* pValue = (int*)m_dwaValues[nGroup];
if (pValue)
return *pValue;
return -1;
}
//
void CGraphSeries::DeleteData(int nGroup)
{
VALIDATE;
_ASSERTE(0 <= nGroup);
_ASSERTE(m_dwaValues.GetSize() > nGroup);
int* pValue = (int*)(int*)m_dwaValues.GetAt(nGroup);
if (pValue != NULL)
{
delete pValue;
}
m_dwaValues.RemoveAt(nGroup);
m_dwaValues.FreeExtra();
}
// Returns the largest data value in this series.
int CGraphSeries::GetMaxDataValue()
{
VALIDATE;
int nMax(-32768);
for (int nGroup = 0; nGroup < m_dwaValues.GetSize(); ++nGroup) {
int* pValue = (int*)m_dwaValues[nGroup];
if (pValue)
nMax = max(nMax, *pValue);
}
return nMax;
}
// Returns the number of data points that are not zero.
int CGraphSeries::GetNonZeroElementCount()
{
VALIDATE;
int nCount(0);
for (int nGroup = 0; nGroup < m_dwaValues.GetSize(); ++nGroup) {
int* pValue = (int*)m_dwaValues[nGroup];
if (pValue)
{
if (*pValue) {
++nCount;
}
}
}
return nCount;
}
// Returns the sum of the data points for this series.
int CGraphSeries::GetDataTotal()
{
VALIDATE;
int nTotal(0);
for (int nGroup = 0; nGroup < m_dwaValues.GetSize(); ++nGroup) {
int* pValue = (int*)m_dwaValues.GetAt(nGroup);
if (pValue)
nTotal += *pValue;
}
return nTotal;
}
/////////////////////////////////////////////////////////////////////////////
// CGraph
int CGraph::m_nXAxisScale;
//int CGraph::m_nXAxisStart;
CFileTime CGraph::m_nXAxisStartFT;
// Constructor.
CGraph::CGraph(GraphType eGraphType /* = CGraph::Pie */ )
: m_nXAxisWidth(0)
, m_nYAxisHeight(0)
, m_eGraphType(eGraphType)
{
m_ptOrigin.x = m_ptOrigin.y = 0;
m_rcGraph.SetRectEmpty();
m_rcLegend.SetRectEmpty();
m_rcTitle.SetRectEmpty();
m_nYAxisShift = 0;
m_nXAxisScale = 30; //default 30 Seconds
m_nXAxisStartFT = CFileTime::GetCurrentTime();
int nColorsDelta(240 / MAX_GROUPS_ALLOWED);
for (int nGroup = 0; nGroup < MAX_GROUPS_ALLOWED; ++nGroup) {
// adjust color manualy
COLORREF cr;
if(nGroup == 4)
cr = CGraph::HLStoRGB((nColorsDelta * nGroup + nColorsDelta/2), 120, 240);
else if(nGroup == 6)
cr = CGraph::HLStoRGB((nColorsDelta * nGroup - nColorsDelta/2), 120, 240);
else
cr = CGraph::HLStoRGB(nColorsDelta * nGroup, 120, 240);
m_dwaColors.SetAtGrow(nGroup, cr);
}
}
// Destructor.
/* virtual */ CGraph::~CGraph()
{
RemoveAllSeries();
RemoveAllLegend();
m_dwaColors.RemoveAll();
}
/////////////////////////////////////////////////////////////////////////////
// CGraph message handlers
//
BEGIN_MESSAGE_MAP(CGraph, CStatic)
END_MESSAGE_MAP()
CGraphSeries* CGraph::GetSeries(CString sLabel)
{
VALIDATE;
POSITION pos(m_olCGraphSeries.GetHeadPosition());
while (pos)
{
CGraphSeries* pSeries = (CGraphSeries*)m_olCGraphSeries.GetNext(pos);
ASSERT_VALID(pSeries);
if (sLabel.Compare(pSeries->GetLabel()) == 0)
{
return pSeries;
}
}
return NULL;
}
//
void CGraph::RemoveSeries(CGraphSeries* series)
{
VALIDATE;
POSITION pos(m_olCGraphSeries.GetHeadPosition());
while(pos != NULL)
{
CGraphSeries* pSeries = (CGraphSeries*)m_olCGraphSeries.GetAt(pos);
if(series == pSeries)
{
m_olCGraphSeries.RemoveAt(pos);
delete pSeries;
//TRACE1("Series is removed. %d\n", pos);
break;
}
m_olCGraphSeries.GetNext(pos);
}
}
//
void CGraph::RemoveAllSeries()
{
VALIDATE;
POSITION pos(m_olCGraphSeries.GetHeadPosition());
while (pos)
{
CGraphSeries* pSeries = (CGraphSeries*)m_olCGraphSeries.GetNext(pos);
ASSERT_VALID(pSeries);
delete pSeries;
}
m_olCGraphSeries.RemoveAll();
}
//
int CGraph::GetGroup(CString sLabel)
{
VALIDATE;
// First get max number of characters.
for (int nGroup = 0; nGroup < m_paLegend.GetSize(); ++nGroup)
{
if (((PGRAPHICLEGEND)(m_paLegend.GetAt(nGroup)))->sLabel == sLabel)
{
return nGroup;
}
}
return -1;
}
//
void CGraph::RemoveGroup(int group)
{
VALIDATE;
POSITION pos(m_olCGraphSeries.GetHeadPosition());
while (pos)
{
CGraphSeries* pSeries = (CGraphSeries*)m_olCGraphSeries.GetNext(pos);
ASSERT_VALID(pSeries);
if (pSeries->m_dwaValues.GetUpperBound() >= group)
pSeries->DeleteData(group);
}
PGRAPHICLEGEND DeleteLegend = (PGRAPHICLEGEND)(m_paLegend.GetAt(group));
m_dwaColors.Add(DeleteLegend->dwColor);
delete DeleteLegend;
m_paLegend.RemoveAt(group);
}
void CGraph::RemoveAllLegend()
{
for (int nGroup = 0; nGroup < m_paLegend.GetSize(); ++nGroup)
{
PGRAPHICLEGEND DeleteLegend = (PGRAPHICLEGEND)(m_paLegend.GetAt(nGroup));
m_dwaColors.Add(DeleteLegend->dwColor);
delete DeleteLegend;
}
m_paLegend.RemoveAll();
}
// Change the type of the graph; the caller should call Invalidate() on this
// window to make the effect of this change visible.
void CGraph::SetGraphType(GraphType e)
{
VALIDATE;
m_eGraphType = e;
}
// Calculate the current max legend label length in pixels.
int CGraph::GetMaxLegendLabelLength(CDC* pDc)
{
VALIDATE;
ASSERT_VALID(pDc);
CString sMax;
int nMaxChars(-1);
CSize siz(-1,-1);
// First get max number of characters.
for (int nGroup = 0; nGroup < m_paLegend.GetSize(); ++nGroup) {
int nLabelLength(((PGRAPHICLEGEND)(m_paLegend.GetAt(nGroup)))->sLabel.GetLength());
if (nMaxChars < nLabelLength) {
nMaxChars = nLabelLength;
sMax = ((PGRAPHICLEGEND)(m_paLegend.GetAt(nGroup)))->sLabel;
}
}
// Now calculate the pixels.
siz = pDc->GetTextExtent(sMax);
_ASSERTE(-1 < siz.cx);
return siz.cx;
}
//
int CGraph::GetSeriesSize()
{
VALIDATE;
return (int)m_olCGraphSeries.GetSize();
}
// Returns the largest number of data points in any series.
int CGraph::GetMaxSeriesSize()
{
VALIDATE;
int nMax(0);
POSITION pos(m_olCGraphSeries.GetHeadPosition());
while (pos) {
CGraphSeries* pSeries = (CGraphSeries*)m_olCGraphSeries.GetNext(pos);
ASSERT_VALID(pSeries);
nMax = max(nMax, (int)pSeries->m_dwaValues.GetSize());
}
return nMax;
}
// Returns the largest number of non-zero data points in any series.
int CGraph::GetMaxNonZeroSeriesSize()
{
VALIDATE;
int nMax(0);
POSITION pos(m_olCGraphSeries.GetHeadPosition());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -