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

📄 smartgraph.cpp

📁 A source code for gragh
💻 CPP
字号:
// SmartGraph.cpp : Implementation of SmartGraph
#include "stdafx.h"
#include "SmartGraph.h"
#include ".\smartgraph.h"


// SmartGraph

STDMETHODIMP SmartGraph::get_Title(BSTR* pVal)
{
	*pVal = _com_util::ConvertStringToBSTR((char*)m_strTitle);
	return S_OK;
}

STDMETHODIMP SmartGraph::put_Title(BSTR newVal)
{
	m_strTitle = _com_util::ConvertBSTRToString(newVal);
	UpdateGraph();
	return S_OK;
}


STDMETHODIMP SmartGraph::get_xLable(BSTR* pVal)
{
	*pVal = _com_util::ConvertStringToBSTR((char*)m_strxLable);
	return S_OK;
}

STDMETHODIMP SmartGraph::put_xLable(BSTR newVal)
{
	m_strxLable = _com_util::ConvertBSTRToString(newVal);
	UpdateGraph();
	return S_OK;
}

STDMETHODIMP SmartGraph::get_yLable(BSTR* pVal)
{
	*pVal = _com_util::ConvertStringToBSTR((char*)m_stryLable);
	return S_OK;
}

STDMETHODIMP SmartGraph::put_yLable(BSTR newVal)
{
	m_stryLable = _com_util::ConvertBSTRToString(newVal);
	UpdateGraph();
	return S_OK;
}


STDMETHODIMP SmartGraph::get_Columns(LONG* pVal)
{
	*pVal = m_nCol;
	return S_OK;
}

STDMETHODIMP SmartGraph::put_Columns(LONG newVal)
{
	m_nCol = newVal;
	UpdateGraph();
	return S_OK;
}


STDMETHODIMP SmartGraph::get_Rows(LONG* pVal)
{
	*pVal = m_nRow;
	return S_OK;
}

STDMETHODIMP SmartGraph::put_Rows(LONG newVal)
{
	m_nRow = newVal;
	UpdateGraph();
	return S_OK;
}

STDMETHODIMP SmartGraph::get_MarginBottom(LONG* pVal)
{
	*pVal = m_nBMargin;
	return S_OK;
}

STDMETHODIMP SmartGraph::put_MarginBottom(LONG newVal)
{
	m_nBMargin = newVal;
	UpdateGraph();
	return S_OK;
}

STDMETHODIMP SmartGraph::get_MarginLeft(LONG* pVal)
{
	*pVal = m_nLMargin;
	return S_OK;
}

STDMETHODIMP SmartGraph::put_MarginLeft(LONG newVal)
{
	m_nLMargin = newVal;
	UpdateGraph();
	return S_OK;
}

STDMETHODIMP SmartGraph::get_MarginTop(LONG* pVal)
{
	*pVal = m_nTMargin;
	return S_OK;
}

STDMETHODIMP SmartGraph::put_MarginTop(LONG newVal)
{
	m_nTMargin = newVal;
	UpdateGraph();
	return S_OK;
}

STDMETHODIMP SmartGraph::get_MarginRight(LONG* pVal)
{
	*pVal = m_nRMargin;
	return S_OK;
}

STDMETHODIMP SmartGraph::put_MarginRight(LONG newVal)
{
	m_nRMargin = newVal;
	UpdateGraph();
	return S_OK;
}

void SmartGraph::CreateFonts(void)
{
	m_FontX = CreateFont( 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
		ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial" );

	m_FontY = CreateFont( 12, 0, 900, 0, FW_NORMAL, FALSE, FALSE, 0,
		ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN,"Arial" );
}


STDMETHODIMP SmartGraph::SetData(DOUBLE* xData, DOUBLE* yData, LONG NumOfPoints, VARIANT_BOOL bResample)
{
	m_bResample = bResample;
	SetData(xData,yData,NumOfPoints);
	return S_OK;
}

///<ISmartGraph::SetData2 Implementation/>
STDMETHODIMP SmartGraph::SetData2(DOUBLE* xData, DOUBLE* yData, LONG NumOfPoints, DOUBLE xMin, DOUBLE xMax, DOUBLE yMin, DOUBLE yMax, VARIANT_BOOL bResample)
{
	m_bResample = bResample;
	SetData(xData, yData, NumOfPoints, xMin, xMax, yMin, yMax);
	return S_OK;
}


///<SmartGraph::SetData a general function used by ISmartGraph::SetData and ISmartGraph::SetData2 methods>

void SmartGraph::SetData(double* xData, double* yData, long NumOfPoints,
						 double xMin, double xMax, double yMin, double yMax)
{
	SAFE_DELETE(m_pxData);
	SAFE_DELETE(m_pyData);
	///<ZoomParam>
	//Set zoom parameters to show all samples
	if(!m_lstZoom.IsEmpty())
		m_lstZoom.RemoveAll();	
	ZoomParam zp;
	zp.nFrom = 0;
	zp.nTo = NumOfPoints;
	zp.nLen = NumOfPoints;
	m_lstZoom.AddTail(zp);
	///</ZoomParam>

	m_pxData = new double[NumOfPoints];
	m_pyData = new double[NumOfPoints];
	m_nDataLength = NumOfPoints;

	if(xData == NULL)
	{
		for(int i = 0; i < NumOfPoints; i++)
			m_pxData[i] = i;
	}
	else
		memcpy(m_pxData, xData, NumOfPoints*sizeof(double));

	if(yData == NULL)
	{
		for(int i = 0; i < NumOfPoints; i++)
			m_pyData[i] = i;
	}
	else
		memcpy(m_pyData, yData, NumOfPoints*sizeof(double));

	double nLen = 20*(m_rcPlot.right - m_rcPlot.left);
	//m_dFactor = nLen/(double)NumOfPoints;
	int nFactor = NumOfPoints / nLen;

	if(m_bResample && (nFactor > 1))

	{
		double * xTmp = new double [nLen];
		double * yTmp = new double [nLen];
		for (int i = 0; i < nLen; i++)
		{
			xTmp[i] = m_pxData[nFactor*i];
			yTmp[i] = m_pyData[nFactor*i];
		}
		if((xMax < xMin) || (yMax < yMin))
			m_cDataSet->SetData(xTmp, yTmp, nLen);
		else
			m_cDataSet->SetData(xTmp, yTmp, nLen,xMin,xMax,yMin,yMax);
		delete [] xTmp;
		delete [] yTmp;
	}
	else
	{
		if((xMax < xMin) || (yMax < yMin))
			m_cDataSet->SetData(m_pxData, m_pyData, NumOfPoints);
		else
			m_cDataSet->SetData(m_pxData, m_pyData, NumOfPoints,xMin,xMax,yMin,yMax);
	}
	return;
}

void SmartGraph::UpdateGraph(HDC dc)
{
	if(m_bDirty)
	{	
		DeleteDC(m_dcMem);
		DeleteObject(m_bmTemp);
		m_dcMem = CreateCompatibleDC(dc);
		m_bmTemp = CreateCompatibleBitmap(dc, m_rcClient.right - m_rcClient.left, m_rcClient.bottom - m_rcClient.top); 
		m_bmOld = (HBITMAP)SelectObject( m_dcMem, m_bmTemp );
		SetWindowOrgEx(m_dcMem,m_rcClient.left, m_rcClient.top,0);

		SetBkMode(m_dcMem, TRANSPARENT);
		FillRect(m_dcMem, &m_rcClient, m_brMarginColor);
		FillRect(m_dcMem, &m_rcPlot, m_brBackColor);
		if(m_bGrid)
			DrawGrids(m_dcMem);

		static bool first = true;
		if(first && m_clrForeColor == 0)
		{
			m_clrForeColor = RGB(0,255,0);
			first = false;
		}
		HPEN oldPen = (HPEN)SelectObject(m_dcMem,m_penGraph);
		m_cDataSet->Draw(m_dcMem,m_rcPlot,m_nPlotType);
		SelectObject(m_dcMem,oldPen);
		DrawLabes(m_dcMem,m_rcClient);
		m_bDirty = false;
	}
	BitBlt(dc,m_rcClient.left,m_rcClient.top, m_rcClient.right - m_rcClient.left, m_rcClient.bottom - m_rcClient.top,
		m_dcMem,m_rcClient.left,m_rcClient.top,SRCCOPY);
	/*SetBkMode(dc, TRANSPARENT);
	FillRect(dc, &m_rcClient, m_brMarginColor);
	FillRect(dc, &m_rcPlot, m_brBackColor);
	if(m_bGrid)
	DrawGrids(dc);
	static bool first = true;
	if(first && m_clrForeColor == 0)
	{
	m_clrForeColor = RGB(0,255,0);
	}
	first = false;
	HPEN pen = CreatePen(PS_SOLID,1,m_clrForeColor);
	HPEN oldPen = (HPEN)SelectObject(dc,pen);
	m_cDataSet->Draw(dc,m_rcPlot,m_nPlotType);
	DrawLabes(dc,m_rcClient);
	SelectObject(dc,oldPen);*/
}

int SmartGraph::DrawGrids(HDC dc)
{
	int x = m_rcPlot.left;
	if(m_penGrids)
		DeleteObject(m_penGrids);
	m_penGrids = CreatePen(PS_DOT,1,RGB(128,128,128));
	HPEN oldPen = (HPEN)SelectObject(dc,m_penGrids);
	for(int i = 0; i < m_nRow; i++)
	{
		x += (m_rcPlot.right-m_rcPlot.left)/m_nRow;
		MoveToEx(dc,x,m_rcPlot.bottom,0);
		LineTo(dc,x,m_rcPlot.top);
	}
	int y = m_rcPlot.bottom;
	for(int i = 0; i < m_nCol; i++)
	{
		y -= (m_rcPlot.bottom-m_rcPlot.top)/m_nCol;
		MoveToEx(dc,m_rcPlot.left,y,0);
		LineTo(dc,m_rcPlot.right,y);
	}

	SelectObject(dc,oldPen);
	return 0;
}

int SmartGraph::DrawLabes(HDC dc, RECT rc)
{
	SetBkMode(dc,TRANSPARENT);
	SelectObject(dc,m_FontY);
	TextOut(dc, rc.left + m_nLMargin/2 - 15, (rc.top+rc.bottom)/2, m_stryLable, lstrlen(m_stryLable));
	SetTextAlign(dc, TA_CENTER|TA_BASELINE);
	LPCTSTR pszCaption =  m_strTitle;//_T("Smart Graph");
	SelectObject(dc,m_FontX);
	TextOut(dc, (rc.left + rc.right) / 2, rc.top+m_nTMargin/2, pszCaption, lstrlen(pszCaption));
	TextOut(dc, (rc.left + rc.right) / 2, rc.bottom-m_nBMargin/2 + 10, m_strxLable, lstrlen(m_strxLable));

	char str[64];
	double range  = m_cDataSet->m_xDataSet.Max-m_cDataSet->m_xDataSet.Min;
	int scale = 0;
	while(range > 100)
	{
		scale++;
		range /= 10;
	}
	while((range < 1) && (range != 0))
	{
		scale--;
		range *= 10;
	}
	if(scale)
	{
		sprintf(str,"*1e%d",scale);//x Axes Scale
		TextOut(dc, m_rcPlot.right - 40, m_rcPlot.bottom + 15, str, strlen(str));
	}

	double start = 0;
	if(scale > 0)
		start = m_cDataSet->m_xDataSet.Min/(pow(10,scale));
	else
		start = m_cDataSet->m_xDataSet.Min*(pow(10,scale));

	int W = m_rcPlot.right - m_rcPlot.left; 
	for(int i = 0; i <= m_nCol; i++)
	{
		sprintf(str,"%-4.2f",start);
		start += range/(double)m_nCol;
		TextOut(dc, m_rcPlot.left + i*W/m_nCol, m_rcPlot.bottom + 10, str, strlen(str));
	}
	////////////////////////////////////////////////////////////////////////////////////////////
	scale = 0;
	range  = m_cDataSet->m_yDataSet.Max-m_cDataSet->m_yDataSet.Min;
	while(range > 100)
	{
		scale++;
		range /= 10;
	}
	while((range < 1) && (range != 0))
	{
		scale--;
		range *= 10;
	}
	if(scale)
	{
		sprintf(str,"*1e%d",scale);//y Axes Scale
		TextOut(dc, m_rcPlot.left + 20, m_rcPlot.top - 10, str, strlen(str));
	}

	if(scale > 0)
		start = m_cDataSet->m_yDataSet.Min/(pow(10,scale));
	else
		start = m_cDataSet->m_yDataSet.Min*(pow(10,scale));

	int H = m_rcPlot.bottom - m_rcPlot.top; 
	for(int i = 0; i <= m_nRow; i++)
	{
		sprintf(str,"%-4.2f",start);
		start += range/(double)m_nRow;
		TextOut(dc, m_rcPlot.left - 10, m_rcPlot.bottom - i*H/m_nRow, str, strlen(str));
	}
	SetTextColor(dc,RGB(0,255,255));
	SetTextAlign(dc,TA_LEFT);
	DrawText(dc,m_strLegend,lstrlen(m_strLegend),&m_rcLegend, DT_NOCLIP);
	return 0;
}

STDMETHODIMP SmartGraph::ShowGrid(VARIANT_BOOL bShow)
{
	m_bGrid = bShow;
	m_bDirty = true;
	/*m_nReason = GRID_CHANGED;*/
	return S_OK;
}

STDMETHODIMP SmartGraph::UpdateGraph(void)
{
	m_bDirty = true;
	/*m_nReason = DATA_CHANGED;*/
	if(m_hWndParent)
		::RedrawWindow(m_hWndParent, &m_rcClient,0,RDW_INVALIDATE | RDW_UPDATENOW/* | RDW_ERASE*/);
	return S_OK;
}

//0--> Normal , 1-->Dot , 2-->Bar
STDMETHODIMP SmartGraph::SetPlotType(LONG nType)
{
	ATLASSERT((nType > -1) && (nType < 3));
	m_nPlotType = nType;
	UpdateGraph();
	return S_OK;
}


LRESULT SmartGraph::OnLButtonDown(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
	POINT pt;
	pt.x = GET_X_LPARAM(lParam); 
	pt.y = GET_Y_LPARAM(lParam); 
	LButtonDown(pt.x, pt.y, wParam);
	return 0;
}

LRESULT SmartGraph::OnMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
	POINT pt;
	pt.x = GET_X_LPARAM(lParam); 
	pt.y = GET_Y_LPARAM(lParam); 
	MouseMove(pt.x, pt.y, wParam);
	return 0;
}

LRESULT SmartGraph::OnLButtonUp(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
	POINT pt;
	pt.x = GET_X_LPARAM(lParam); 
	pt.y = GET_Y_LPARAM(lParam); 
	LButtonUp(pt.x, pt.y, wParam);
	return 0;
}
//The rect in which plot area is located.
STDMETHODIMP SmartGraph::GetPlotRect(LONG* left, LONG* top, LONG* right, LONG* bottom)
{
	*left = m_rcPlot.left;
	*top = m_rcPlot.top;
	*right = m_rcPlot.right;
	*bottom = m_rcPlot.bottom;
	return S_OK;
}
//The rect in which all graph components(plot area and lables) are located.
STDMETHODIMP SmartGraph::GetClientRect(LONG* left, LONG* top, LONG* right, LONG* bottom)
{
	RECT rc;
	*left	= m_rcPlot.left	- m_nLMargin;
	*top	= m_rcPlot.top	- m_nTMargin;
	*bottom	= m_rcPlot.bottom	+ m_nBMargin;
	*right	=	m_rcPlot.right	+ m_nRMargin;
	return S_OK;
}

//Zoom in with respect to previous zoom parameters
STDMETHODIMP SmartGraph::ZoomIn(LONG FromSample, LONG ToSample)
{
	if( (FromSample < 0) || ( (ToSample-FromSample) > m_lstZoom.GetTail().nLen) )
		return S_FALSE;

	//Zoom with respect to previous zoom
	ZoomParam zp;
	zp.nFrom = FromSample + m_lstZoom.GetTail().nFrom;
	zp.nTo = ToSample + m_lstZoom.GetTail().nFrom;
	zp.nLen = ToSample - FromSample;
	m_lstZoom.AddTail(zp);
	Zoom();
	return S_OK;
}

STDMETHODIMP SmartGraph::ZoomInByPercent(DOUBLE FromPercent, DOUBLE ToPercent)
{
	// TODO: Add your implementation code here
	int From = FromPercent * m_lstZoom.GetTail().nLen / 100;
	int To = ToPercent * m_lstZoom.GetTail().nLen / 100;
	ZoomIn(From, To);
	return S_OK;
}

STDMETHODIMP SmartGraph::ZoomOut(void)
{
	if(m_lstZoom.GetCount() < 2)
		return S_FALSE;

	m_lstZoom.RemoveTail();
	Zoom();
	return S_OK;
}

STDMETHODIMP SmartGraph::Reset(void)
{
	while (m_lstZoom.GetCount() > 1) 
	{
		m_lstZoom.RemoveTail();
	}
	Zoom();
	return S_OK;
}

int SmartGraph::Zoom(void)
{	
	int start = m_lstZoom.GetTail().nFrom;
	int end = m_lstZoom.GetTail().nTo;
	int len = m_lstZoom.GetTail().nLen;

	int nLen = 20*(m_rcPlot.right - m_rcPlot.left);
	int nFactor = len / nLen;

	if(m_bResample && (nFactor > 1))
	{
		double * xTmp = new double [nLen];
		double * yTmp = new double [nLen];
		for (int i = 0; i < nLen; i++)
		{
			xTmp[i] = m_pxData[start + nFactor*i];
			yTmp[i] = m_pyData[start + nFactor*i];
		}
		m_cDataSet->SetData(xTmp, yTmp, nLen);
		delete [] xTmp;
		delete [] yTmp;
	}
	else
	{
		m_cDataSet->SetData(m_pxData + start, m_pyData + start, len);
	}
	if(m_hWndParent)
		::RedrawWindow(m_hWndParent, &m_rcPlot,0,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);

	return 0;
}

STDMETHODIMP SmartGraph::GetDisplayedRange(LONGLONG* nStartSample, LONGLONG* nEndSample)
{	
	*nStartSample = m_lstZoom.GetTail().nFrom;
	*nEndSample = m_lstZoom.GetTail().nTo;
	return S_OK;
}

STDMETHODIMP SmartGraph::SetLegendText(BSTR strText, LONG top, LONG left, LONG bottom, LONG right)
{
	m_strLegend = _com_util::ConvertBSTRToString(strText);
	m_rcLegend.top		= top	+ m_rcPlot.top;
	m_rcLegend.left		= left	+ m_rcPlot.left;
	m_rcLegend.right	= right	+ m_rcPlot.left;
	m_rcLegend.bottom	= bottom+ m_rcPlot.top;
	return S_OK;
}

STDMETHODIMP SmartGraph::SetParentWnd(OLE_HANDLE hWnd)
{
	m_hWndParent = (HWND)hWnd;
	return S_OK;
}

⌨️ 快捷键说明

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