📄 hmxchart.cpp
字号:
dc.Polygon( pPoint, 3 );
break;
case HMX_DATASET_MARKER_BOX:
ds.GetData( f, nSample);
nTemp = ( nSample - m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
pPoint[ 0 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f) - ds.GetSize()*2;
pPoint[ 0 ].y = m_rectData.bottom - (int)nTemp - ds.GetSize()*2;
pPoint[ 1 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f) + ds.GetSize()*2;
pPoint[ 1 ].y = m_rectData.bottom - (int)nTemp - ds.GetSize()*2;
pPoint[ 2 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f) + ds.GetSize()*2;
pPoint[ 2 ].y = m_rectData.bottom - (int)nTemp + ds.GetSize()*2;
pPoint[ 3 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f) - ds.GetSize()*2;
pPoint[ 3 ].y = m_rectData.bottom - (int)nTemp + ds.GetSize()*2;
dc.Polygon( pPoint, 4 );
break;
case HMX_DATASET_MARKER_SPH:
ds.GetData( f, nSample);
nTemp = ( nSample - m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
pPoint[ 0 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f) - ds.GetSize()*2;
pPoint[ 0 ].y = m_rectData.bottom - (int)nTemp - ds.GetSize()*2;
pPoint[ 1 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f) + ds.GetSize()*2;
pPoint[ 1 ].y = m_rectData.bottom - (int)nTemp + ds.GetSize()*2;
dc.Ellipse( pPoint[0].x, pPoint[0].y, pPoint[1].x, pPoint[1].y );
break;
case HMX_DATASET_MARKER_DIA:
ds.GetData( f, nSample);
nTemp = ( nSample - m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
pPoint[ 0 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f);
pPoint[ 0 ].y = m_rectData.bottom - (int)nTemp - ds.GetSize()*2;
pPoint[ 1 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f) + ds.GetSize()*2;
pPoint[ 1 ].y = m_rectData.bottom - (int)nTemp;
pPoint[ 2 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f);
pPoint[ 2 ].y = m_rectData.bottom - (int)nTemp + ds.GetSize()*2;
pPoint[ 3 ].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f) - ds.GetSize()*2;
pPoint[ 3 ].y = m_rectData.bottom - (int)nTemp;
dc.Polygon( pPoint, 4 );
break;
}
}
delete []pPoint;
}
}
dc.SelectObject( pPenOld );
dc.SelectObject( pBrushOld );
}
if( ds.GetStyle() == HMX_DATASET_STYLE_VBAR ) {
// let's rock
CPen pen( PS_SOLID, 1, ds.GetColor() ), *pPenOld;
CBrush brush( ds.GetColor() ), *pBrushOld;
pPenOld = dc.SelectObject( &pen );
pBrushOld = dc.SelectObject( &brush );
CRect rectTemp;
// nTemp will contains a parametrized data
for( f=0; f<ds.GetDatasetSize(); f++ ) {
ds.GetData( f, nSample);
if( nSample == HMX_DATASET_VALUE_INVALID )
continue;
nTemp = ( nSample - m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
if( nSample > 0.0 ) {
// bar is positive
nZeroLine = m_nYMin > 0 ? m_nYMin : 0;
nTemp1 = ( nZeroLine -m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
rectTemp.top = m_rectData.bottom - (int)(nTemp);
rectTemp.bottom = m_rectData.bottom - (int)(nTemp1);
rectTemp.left = m_rectData.left + (int)(nBarWidth/2.0) - (int)(nBarWidth*(ds.GetSize()/2.0)/10.0) + (int)(nBarWidth*f);
rectTemp.right = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*(ds.GetSize()/2.0)/10.0) + (int)(nBarWidth*f);
// show at least 1 line bar
rectTemp.right += (rectTemp.right == rectTemp.left ) ? 1 : 0 ;
} else {
// bar is negative
nZeroLine = m_nYMax < 0 ? m_nYMax : 0;
nTemp1 = ( nZeroLine -m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
rectTemp.top = m_rectData.bottom - (int)(nTemp1);
rectTemp.bottom = m_rectData.bottom - (int)(nTemp);
rectTemp.left = m_rectData.left + (int)(nBarWidth/2.0) - (int)(nBarWidth*(ds.GetSize()/2.0)/10.0) + (int)(nBarWidth*f);
rectTemp.right = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*(ds.GetSize()/2.0)/10.0) + (int)(nBarWidth*f);
// show at least 1 line bar
rectTemp.right += (rectTemp.right == rectTemp.left ) ? 1 : 0 ;
}
dc.Rectangle( rectTemp );
}
dc.SelectObject( pPenOld );
dc.SelectObject( pBrushOld );
}
if( ds.GetStyle() == HMX_DATASET_STYLE_AREA ) {
int g;
// let's rock
CPen pen( PS_SOLID, 1, ds.GetColor() ), *pPenOld;
CBrush brush( ds.GetColor() ), *pBrushOld;
pPenOld = dc.SelectObject( &pen );
pBrushOld = dc.SelectObject( &brush );
// let's cale real dataset size (excluding invalid data)
int nPoints = 0;
for( g=0; g<ds.GetDatasetSize(); g++ ) {
ds.GetData( g, nSample );
if( nSample != HMX_DATASET_VALUE_INVALID )
nPoints++;
}
// add two points, for firs and last point
nPoints += 2;
// create a dynamic array
POINT* pPoint = new POINT[ nPoints ];
// the first
f=0;
do {
ds.GetData( f, nSample);
f++;
} while( nSample == HMX_DATASET_VALUE_INVALID );
pPoint[0].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*(f-1.0));
nZeroLine = m_nYMin > 0 ? m_nYMin : 0;
nZeroLine = m_nYMax < 0 ? m_nYMax : nZeroLine;
nTemp = ( nZeroLine -m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
pPoint[0].y = m_rectData.bottom - (int)nTemp;
g = 1;
for( f=0; f<ds.GetDatasetSize(); f++ ) {
ds.GetData( f, nSample);
if( nSample == HMX_DATASET_VALUE_INVALID )
continue;
// nTemp will contains a parametrized data
nTemp = ( nSample - m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
pPoint[g].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*f);
pPoint[g].y = m_rectData.bottom - (int) nTemp;
g++;
}
// the last
// pPoint[nPoints-1].x = m_rectData.left + (int)(nBarWidth/2.0) + (int)(nBarWidth*(g-2));
pPoint[nPoints-1].x = pPoint[g-1].x;
nZeroLine = m_nYMin > 0 ? m_nYMin : 0;
nZeroLine = m_nYMax < 0 ? m_nYMax : nZeroLine;
nTemp = ( nZeroLine - m_nYMin) * m_rectData.Height()/(m_nYMax-m_nYMin);
pPoint[nPoints-1].y = m_rectData.bottom - (int) nTemp;
dc.Polygon( pPoint, nPoints );
dc.SelectObject( pPenOld );
dc.SelectObject( pBrushOld );
delete []pPoint;
}
return true;
}
//
// CalcDatas
// calculate all useful variables starting from the control size
//
// arguments
//
// none
//
// return
//
// true if ok, else false
//
bool CHMXChart::CalcDatas()
{
double nTemp1, nTemp2;
int f=0, nTemp3;
GetClientRect( m_rectArea );
m_rectUsable.top = m_rectArea.top + m_rectArea.Height()/HMX_AREA_MARGINS;
m_rectUsable.bottom = m_rectArea.bottom - m_rectArea.Height()/HMX_AREA_MARGINS;
m_rectUsable.left = m_rectArea.left + m_rectArea.Width() /HMX_AREA_MARGINS;
m_rectUsable.right = m_rectArea.right - m_rectArea.Width() /HMX_AREA_MARGINS;
// let's calc everything
if( !m_strTitle.IsEmpty() ) {
m_rectTitle.top = m_rectUsable.top;
m_rectTitle.left = m_rectUsable.left;
m_rectTitle.bottom = m_rectUsable.bottom/HMX_AREA_TITLE;
m_rectTitle.right = m_rectUsable.right;
m_rectGraph.top = m_rectTitle.bottom;
m_rectGraph.left = m_rectUsable.left;
m_rectGraph.bottom = m_rectUsable.bottom;
m_rectGraph.right = m_rectUsable.right;
} else {
m_rectGraph = m_rectUsable;
}
m_rectYAxis.top = m_rectGraph.top;
m_rectYAxis.left = m_rectGraph.left;
m_rectYAxis.bottom = m_rectGraph.top + m_rectGraph.Height()*(100-HMX_AREA_XAXIS)/100;
m_rectYAxis.right = m_rectGraph.left + m_rectGraph.Width()*(HMX_AREA_YAXIS)/100;
m_rectXAxis.top = m_rectGraph.top + m_rectGraph.Height()*(100-HMX_AREA_XAXIS)/100;
m_rectXAxis.left = m_rectGraph.left + m_rectGraph.Width()*(HMX_AREA_YAXIS)/100;
m_rectXAxis.bottom = m_rectGraph.bottom;
m_rectXAxis.right = m_rectGraph.right;
m_rectData.top = m_rectGraph.top;
m_rectData.bottom = m_rectXAxis.top;
m_rectData.left = m_rectYAxis.right;
m_rectData.right = m_rectGraph.right;
// reset
m_nXMax = 0;
for( f=0; f<HMX_MAX_DATASET; f++ ) {
nTemp3 = m_dataset[f].GetDatasetSize();
m_nXMax = max( m_nXMax, nTemp3 );
}
// Hey man, there's nothing to draw
if( m_nXMax == 0 )
return false;
// search min & max in first non-empty dataset
f = 0;
while( !m_dataset[f].GetMinMax( m_nYMin, m_nYMax ) )
f++;
// let's search
for( ; f<HMX_MAX_DATASET; f++ ) {
if( m_dataset[f].GetMinMax( nTemp1, nTemp2 ) ) {
m_nYMin = min( m_nYMin ,nTemp1 );
m_nYMax = max( m_nYMax, nTemp2 );
}
}
// now I modify m_nYMin & m_nXMax to improve readability
m_nYMin -= (m_nYMax - m_nYMin)*0.0;
m_nYMax += (m_nYMax - m_nYMin)*0.0;
// whid this 'strange' function I can set m_nYmin & m_nYMax so that
// they are multiply of m_nRoundY
if( m_nRoundY > 0.0 ) {
m_nYMin = (((int)m_nYMin-(int)m_nRoundY)/(int)m_nRoundY)*m_nRoundY;
m_nYMax = (((int)m_nYMax+(int)m_nRoundY)/(int)m_nRoundY)*m_nRoundY;
}
// now nYMin & nYMax contain absolute min and absolute max
// and these data can be used to calc the graphic's Y scale factor
// nXMax contains the maximum number of elements, useful to
// calculate the X scale factor
return true;
}
//
// Redraw
// redraw everything
//
// arguments
//
// none
//
// return
//
// true if ok, else false
//
bool CHMXChart::Redraw()
{
Invalidate(true);
GetParent()->SendMessage( WM_PAINT, 0, 0 );
return true;
}
//
// SetData
// Add new data to the dataset
//
// arguments
//
// nDatasetIndex = the dataset index
// nData = the value
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetData(int nDatasetIndex, double nData)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
return m_dataset[nDatasetIndex].SetData(nData);
}
//
// SetData
// Modify a data into the dataset
//
// arguments
//
// nDatasetIndex = dataset index
// nIndex = index
// nData = value
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetData(int nDatasetIndex, int nIndex, double nData)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
return m_dataset[nDatasetIndex].SetData(nIndex, nData);
}
//
// GetData
// get data from the dataset
//
// arguments
//
// nDatasetIndex = dataset index
// nIndex = index
// nData = value
//
// return
//
// true if ok, else false
//
bool CHMXChart::GetData(int nDatasetIndex, int nIndex, double& nData)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
return m_dataset[nDatasetIndex].GetData(nIndex,nData);
}
//
// SetDatasetStyle
//
// arguments
//
// nDatasetIndex = dataset index
// nStyle = style
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetDatasetStyle(int nDatasetIndex, int nStyle)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
return m_dataset[nDatasetIndex].SetStyle( nStyle );
}
//
// GetDatasetStyle
//
// arguments
//
// nDatasetIndex = dataset index
// nStyle = style
//
// return
//
// true if ok, else false
//
bool CHMXChart::GetDatasetStyle(int nDatasetIndex, int& nStyle)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
nStyle = m_dataset[nDatasetIndex].GetStyle();
return true;
}
//
// SetDatasetMarker
//
// arguments
//
// nDatasetIndex = dataset index
// nMarker = marker
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetDatasetMarker(int nDatasetIndex, int nMarker)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
return m_dataset[nDatasetIndex].SetMarker( nMarker );
}
//
// GetDatasetMarker
//
// arguments
//
// nDatasetIndex = dataset index
// nMarker = marker
//
// return
//
// true if ok, else false
//
bool CHMXChart::GetDatasetMarker(int nDatasetIndex, int& nMarker)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
nMarker = m_dataset[nDatasetIndex].GetMarker();
return true;
}
//
// SetDatasetPenSize
//
// arguments
//
// nDatasetIndex = dataset index
// nSize = pen size in pixel or bar size (range 1-10)
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetDatasetPenSize(int nDatasetIndex, int nSize)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
return m_dataset[nDatasetIndex].SetSize( nSize );
}
//
// GetDatasetPenSize
//
// arguments
//
// nDatasetIndex = dataset index
// nSize = size
//
// return
//
// true if ok, else false
//
bool CHMXChart::GetDatasetPenSize(int nDatasetIndex, int& nSize)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
nSize = m_dataset[nDatasetIndex].GetSize();
return true;
}
//
// SetDatasetPenColor
//
// arguments
//
// nDatasetIndex = dataset index
// clr = color
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetDatasetPenColor(int nDatasetIndex, COLORREF clr)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
return m_dataset[nDatasetIndex].SetColor( clr );
}
//
// GetDatasetPenColor
//
// arguments
//
// nDatasetIndex = dataset index
// clr = color
//
// return
//
// true if ok, else false
//
bool CHMXChart::GetDatasetPenColor(int nDatasetIndex, COLORREF& clr)
{
if( nDatasetIndex < 0 || nDatasetIndex >= HMX_MAX_DATASET )
return false;
clr = m_dataset[nDatasetIndex].GetColor();
return true;
}
//
// SetBkGnd
//
// arguments
//
// clr = color
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetBkGnd(COLORREF clr)
{
m_clrBkGnd = clr;
Redraw();
return true;
}
//
// SetBkGnd
//
// arguments
//
// none
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetBkGnd()
{
CColorDialog dlg( GetBkGnd() );
if( dlg.DoModal() == IDOK )
return SetBkGnd( dlg.GetColor() );
else
return false;
}
//
// GetBkGnd
//
// arguments
//
// none
//
// return
//
// background color
//
COLORREF CHMXChart::GetBkGnd()
{
return m_clrBkGnd;
}
//
// SetTitle
//
// arguments
//
// sTitle = title
//
// return
//
// true if ok, else false
//
bool CHMXChart::SetTitle(CString strTitle)
{
m_strTitle = strTitle;
Redraw();
return true;
}
//
// GetTitle
//
// arguments
//
// none
//
// return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -