📄 chartaxis.cpp
字号:
/*
*
* 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 + -