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

📄 chartaxis.cpp

📁 BCB CHART控件 在Wince5.0下的移植
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 *
 *	ChartAxis.cpp
 *
 *	Written by C閐ric Moonen (cedric_moonen@hotmail.com)
 *
 *
 *
 *	This code may be used for any non-commercial and commercial purposes in a compiled form.
 *	The code may be redistributed as long as it remains unmodified and providing that the 
 *	author name and this disclaimer remain intact. The sources can be modified WITH the author 
 *	consent only.
 *	
 *	This code is provided without any garanties. I cannot be held responsible for the damage or
 *	the loss of time it causes. Use it at your own risks
 *
 *	An e-mail to notify me that you are using this code is appreciated also.
 *
 *	
 *	History:
 *		- 16/05/2006: Bug fix in ScreenToValue function
 *		- 18/05/2006: Added support for panning
 *		- 11/08/2006: Changes done for the automatic axis (Un/RegisterSeries, ...)
 *		- 12/08/2006: Tick increment can be set manually also 
 *
 */

#include "stdafx.h"
#include "ChartAxis.h"
#include "ChartAxisLabel.h"
#include "ChartGrid.h"
#include "ChartCtrl.h"

#include "Math.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CChartAxis::CChartAxis(CChartCtrl* pParent,bool bHoriz):CChartObject(pParent)
{
	m_bIsHorizontal = bHoriz;
	m_bIsInverted = false;
	m_bIsAutomatic = false;
	m_bIsLogarithmic = false;

	m_bIsSecondary = false;

	m_MaxValue = m_UnzoomMax = 10;
	m_MinValue = m_UnzoomMin = 0;

	m_bAutoTicks = true;
	m_TickIncrement = 1;
	m_FirstTickVal = 0;
	m_DecCount = 0;

	m_StartPos = m_EndPos = 0;

	m_nFontSize = 80;
	m_strFontName = _T("Microsoft Sans Serif");

	m_pAxisGrid = new CChartGrid(pParent,this,bHoriz);
	m_pAxisLabel = new CChartAxisLabel(pParent,bHoriz);
}

CChartAxis::~CChartAxis()
{
	if (m_pAxisGrid)
	{
		delete m_pAxisGrid;
		m_pAxisGrid = NULL;
	}
	if (m_pAxisLabel)
	{
		delete m_pAxisLabel;
		m_pAxisLabel = NULL;
	}
}	


int CChartAxis::ClipMargin(CRect ControlRect,CRect& MarginRect,CDC* pDC) const
{
	if (!m_bIsVisible)
		return 0;

	int Size = 0;	

	CSize LabelSize = m_pAxisLabel->GetSize(pDC);
	CFont* pOldFont;
	CFont NewFont;
	NewFont.CreatePointFont(m_nFontSize,m_strFontName.c_str(),pDC);
	pOldFont = pDC->SelectObject(&NewFont);

	CString Buffer;
	Buffer.Format(_T("%.*f"),m_DecCount,m_MaxValue);
	if (m_bIsHorizontal)
	{
		Size += 4 + 1;		//Space above and under the text

		CSize TextSize = pDC->GetTextExtent(Buffer);
		Size += TextSize.cy;
		Size +=LabelSize.cy;

		if (!m_bIsSecondary)
		{
			ControlRect.bottom -= Size;
			ControlRect.right -= TextSize.cx/2+3;

			if (ControlRect.bottom < MarginRect.bottom)
				MarginRect.bottom = ControlRect.bottom;
			if (ControlRect.right < MarginRect.right)
				MarginRect.right = ControlRect.right;
		}
		else
		{
			ControlRect.top += Size;
			ControlRect.right -= TextSize.cx/2+3;

			if (ControlRect.top > MarginRect.top)
				MarginRect.top = ControlRect.top;
			if (ControlRect.right < MarginRect.right)
				MarginRect.right = ControlRect.right;
		}
	}
	else
	{
		Size += 7 + 1;		//Space before and after the text + Tick

		CString szBuff;

        if (!m_bIsLogarithmic)
        {
  
    		int MaxChars = abs( (int)log10(fabs(m_MaxValue) )) + 1;
    		int MinChars = abs( (int)log10(fabs(m_MinValue) )) + 1;
    		if (m_MinValue<0)
    			MinChars++;
    		if (m_MaxValue<0)
    			MaxChars++;
    		if (MaxChars>MinChars)
				szBuff.Format(_T("%.*f"),m_DecCount,m_MaxValue);
    		else
				szBuff.Format(_T("%.*f"),m_DecCount,m_MinValue);
       }
       else
       {
		   CString BuffMax;
		   CString BuffMin;

           int MaxDecCount = (int)log10(m_MaxValue);
           if (MaxDecCount < 0)
               MaxDecCount = -MaxDecCount;
           else
               MaxDecCount = 0;

           BuffMax.Format(BuffMax,_T("%.2f"),MaxDecCount,m_MaxValue);

           int MinDecCount = (int)log10(m_MinValue);
           if (MinDecCount < 0)
                MinDecCount = -MinDecCount;
           else
               MinDecCount = 0;

           BuffMin.Format(BuffMin,_T("%.2f"),MaxDecCount,m_MinValue);

           if (wcslen(BuffMin) > wcslen(BuffMax) )
		   {
			   szBuff = BuffMin;
		   }
           else
		   {
			   szBuff = BuffMax;
		   }
		}

		CSize TextSize = pDC->GetTextExtent(szBuff);
		Size += TextSize.cx;
		Size += LabelSize.cx + 2;

		if (!m_bIsSecondary)
		{
			ControlRect.left += Size;
			ControlRect.top += TextSize.cy/2+3;

			if (ControlRect.top > MarginRect.top)
				MarginRect.top = ControlRect.top;
			if (ControlRect.left > MarginRect.left)
				MarginRect.left = ControlRect.left;
		}
		else
		{
			ControlRect.right -= Size;
			ControlRect.top += TextSize.cy/2+3;

			if (ControlRect.top > MarginRect.top)
				MarginRect.top = ControlRect.top;
			if (ControlRect.right < MarginRect.right)
				MarginRect.right = ControlRect.right;
		}
	}

	pDC->SelectObject(pOldFont);
	return Size;
}

void CChartAxis::SetAutomatic(bool bNewValue)  
{ 
	m_bIsAutomatic = bNewValue; 
	if (m_bIsAutomatic)
		m_MinValue = m_MaxValue = 0;

	RefreshAutoAxis();
}

void CChartAxis::SetTickIncrement(bool bAuto, double Increment)
{
	m_bAutoTicks = bAuto;
	if (!m_bAutoTicks)
		m_TickIncrement = Increment;
	else
		CalculateTicksIncrement();

	CalculateFirstTick();
	m_pParent->RefreshCtrl();
}

void CChartAxis::SetAxisSize(CRect ControlRect,CRect MarginRect)
{
	if (m_bIsHorizontal)
	{
		m_StartPos = MarginRect.left;	
		m_EndPos = MarginRect.right;

		if (!m_bIsSecondary)
		{
			CRect AxisSize = ControlRect;
			AxisSize.top = MarginRect.bottom;
			SetRect(AxisSize);	
		}
		else
		{
			CRect AxisSize = ControlRect;
			AxisSize.bottom = MarginRect.top;
			SetRect(AxisSize);	
		}
	}
	else
	{
		m_StartPos = MarginRect.bottom;
		m_EndPos = MarginRect.top;

		if (!m_bIsSecondary)
		{
			CRect AxisSize = ControlRect;
			AxisSize.right = MarginRect.left;
			SetRect(AxisSize);
		}
		else
		{
			CRect AxisSize = ControlRect;
			AxisSize.left = MarginRect.right;
			SetRect(AxisSize);
		}
	}
}

void CChartAxis::Draw(CDC *pDC)
{
	if (!m_bIsVisible)
		return;

	CPen SolidPen(PS_SOLID,0,m_ObjectColor);
	CPen* pOldPen;

	CFont NewFont;
	CFont* pOldFont;

	if (pDC->GetSafeHdc() == NULL)
		return;

	CSize LabelSize = m_pAxisLabel->GetSize(pDC);
	int HalfAxisPos = (int)fabs((m_EndPos + m_StartPos)/2.0);
	int XPos = 0;
	int YPos = 0;
	if (m_bIsHorizontal)
	{
		if (!m_bIsSecondary)
		{
			YPos = m_ObjectRect.top  + LabelSize.cy + 2;
			XPos = HalfAxisPos - LabelSize.cx/2;
		}
		else
		{
			YPos = m_ObjectRect.top  + 2;
			XPos = HalfAxisPos - LabelSize.cx/2;
		}
	}
	else
	{
		if (!m_bIsSecondary)
		{
			YPos = HalfAxisPos + LabelSize.cy/2;
			XPos = m_ObjectRect.left + 0;
		}
		else
		{
			YPos = HalfAxisPos + LabelSize.cy/2;
			XPos = m_ObjectRect.right - LabelSize.cx - 2;
		}
	}
	m_pAxisLabel->SetPosition(XPos,YPos,pDC);
	m_pAxisLabel->Draw(pDC);

	NewFont.CreatePointFont(m_nFontSize,m_strFontName.c_str(),pDC) ;
	pOldPen = pDC->SelectObject(&SolidPen);
	pOldFont = pDC->SelectObject(&NewFont);

	CalculateTicksIncrement();

	CString szBuff;
	int TickCount = 0;
	int FirstTickPos = ValueToScreen(m_FirstTickVal);
    double TickValue = m_FirstTickVal;
	if (m_bIsHorizontal)
	{
		if (!m_bIsSecondary)
		{
			pDC->MoveTo(m_StartPos,m_ObjectRect.top+1);
			pDC->LineTo(m_EndPos,m_ObjectRect.top+1);
		}
		else
		{
			pDC->MoveTo(m_StartPos,m_ObjectRect.bottom-1);
			pDC->LineTo(m_EndPos,m_ObjectRect.bottom-1);
		}

		if (m_MinValue == m_MaxValue)
		{
			int HorizPos = m_StartPos + (int)fabs((m_EndPos-m_StartPos)/2.0);
			if (!m_bIsSecondary)
			{
				pDC->MoveTo(HorizPos,m_ObjectRect.top+1);
				pDC->LineTo(HorizPos,m_ObjectRect.top+4);
			}
			else
			{
				pDC->MoveTo(HorizPos,m_ObjectRect.bottom-1);
				pDC->LineTo(HorizPos,m_ObjectRect.bottom-4);
			}

            if (!m_bIsLogarithmic)
			{
				szBuff.Format(_T("%.*f"),m_DecCount,m_MinValue);
			}
            else
            {
                int LogDecCount = (int)log10(m_MinValue);

				szBuff.Format(_T("%.*f"),LogDecCount,m_MinValue);
            }

			CSize TextSize;
			TextSize = pDC->GetTextExtent(szBuff);

			if (!m_bIsSecondary)
				pDC->ExtTextOut(HorizPos-TextSize.cx/2,m_ObjectRect.top+5,ETO_CLIPPED|ETO_OPAQUE,NULL,szBuff,NULL);
			else
				pDC->ExtTextOut(HorizPos-TextSize.cx/2,m_ObjectRect.bottom-5,ETO_CLIPPED|ETO_OPAQUE,NULL,szBuff,NULL);
		}
		else while ( (TickValue<=m_MaxValue) || (TickValue-m_MaxValue < 0.0000001) )
		{
			int HorizPos = ValueToScreen(TickValue);
			if (m_bIsInverted)
			   FirstTickPos = HorizPos;

			if (!m_bIsSecondary)
			{
				pDC->MoveTo(HorizPos,m_ObjectRect.top+1);
				pDC->LineTo(HorizPos,m_ObjectRect.top+4);
			}
			else
			{
				pDC->MoveTo(HorizPos,m_ObjectRect.bottom-1);
				pDC->LineTo(HorizPos,m_ObjectRect.bottom-4);
			}

            if (!m_bIsLogarithmic)
			{
				szBuff.Format(_T("%.*f"),m_DecCount,TickValue);
			}
            else
            {
                int LogDecCount = (int)log10(TickValue);
                if (LogDecCount<0)
                    LogDecCount = -(LogDecCount)-1;
                else
                    LogDecCount = 0;

				szBuff.Format(_T("%.*f"),LogDecCount,TickValue);
            }

⌨️ 快捷键说明

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