|
I get the same error
Graham W Griffiths
|
|
|
|
|
1. Download source into separate directory, compile and copy the resulting lib directory (containing XGraph10.lib, etc) to your XGraphTest directory.
2. You should then be able to compile XGraphTest.exe successfully
Program should then run.
Good luck.
Graham
======
Graham W Griffiths
|
|
|
|
|
Error executing f:\winnt\system32\cmd.exe.
|
|
|
|
|
The problem is in the project settings.
You have to set the right path in the linker pre-stage setting:
"copy ..\lib\xgraph10.dll .\release"
|
|
|
|
|
Very nice job! I'd like to use it, but it does not compile on VC7! Here's a log of the errors issued. Any hint for removing them?
XGRAPH.cpp
d:\Vcpp\Test\XGraph\XGRAPH.cpp(426) : error C2440: 'static_cast' : cannot convert from 'BOOL (__thiscall CXGraph::* )(CDCEx *)' to 'BOOL (__thiscall CWnd::* )(CDC *)'
None of the functions with this name in scope match the target type
LabelDlg.cpp
d:\Vcpp\Test\XGraph\LabelDlg.cpp(55) : error C2440: 'static_cast' : cannot convert from 'void (__thiscall CLabelDlg::* )(void)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
None of the functions with this name in scope match the target type
CurveDlg.cpp
d:\Vcpp\Test\XGraph\CurveDlg.cpp(76) : error C2440: 'static_cast' : cannot convert from 'UINT (__thiscall CCurveDlg::* )(UINT,LONG)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
None of the functions with this name in scope match the target type
ColourPopup.cpp
d:\Vcpp\Test\XGraph\ColourPopup.cpp(228) : error C2440: 'static_cast' : cannot convert from 'void (__thiscall CColourPopup::* )(BOOL,HTASK)' to 'void (__thiscall CWnd::* )(BOOL,DWORD)'
None of the functions with this name in scope match the target type
ChartDlg.cpp
d:\Vcpp\Test\XGraph\ChartDlg.cpp(66) : error C2440: 'static_cast' : cannot convert from 'UINT (__thiscall CChartDlg::* )(UINT,LONG)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
None of the functions with this name in scope match the target type
AxisDlg.cpp
d:\Vcpp\Test\XGraph\AxisDlg.cpp(95) : error C2440: 'static_cast' : cannot convert from 'UINT (__thiscall CAxisDlg::* )(UINT,LONG)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
None of the functions with this name in scope match the target type
d:\Vcpp\Test\XGraph\AxisDlg.cpp(103) : error C2440: 'static_cast' : cannot convert from 'void (__thiscall CAxisDlg::* )(void)' to 'void (__thiscall CCmdTarget::* )(NMHDR *,LRESULT *)'
None of the functions with this name in scope match the target type
d:\Vcpp\Test\XGraph\AxisDlg.cpp(104) : error C2440: 'static_cast' : cannot convert from 'void (__thiscall CAxisDlg::* )(void)' to 'void (__thiscall CCmdTarget::* )(NMHDR *,LRESULT *)'
None of the functions with this name in scope match the target type
d:\Vcpp\Test\XGraph\AxisDlg.cpp(105) : error C2440: 'static_cast' : cannot convert from 'void (__thiscall CAxisDlg::* )(void)' to 'void (__thiscall CCmdTarget::* )(NMHDR *,LRESULT *)'
None of the functions with this name in scope match the target type
d:\Vcpp\Test\XGraph\AxisDlg.cpp(106) : error C2440: 'static_cast' : cannot convert from 'void (__thiscall CAxisDlg::* )(void)' to 'void (__thiscall CCmdTarget::* )(NMHDR *,LRESULT *)'
None of the functions with this name in scope match the target type
d:\vcpp\test\xgraph\xgraphaxis.cpp(117) : error C4716: 'CXGraphAxis::operator=' : must return a value
d:\vcpp\test\xgraph\xgraphdataserie.cpp(86) : error C4716: 'CXGraphDataSerie::operator=' : must return a value
d:\vcpp\test\xgraph\xgraphobjectbase.cpp(51) : error C4716: 'CXGraphObject::operator=' : must return a value
|
|
|
|
|
I've found some issues with the time axis.
This is how I fixed it:
(file: XGraphAxis.cpp)
void CXGraphAxis::FitTimeScale(double *fStepWidth, int nBestCount, double fStart, double fEnd)
{
COleDateTime cStart, cEnd;
COleDateTimeSpan cSpan;
double fStep;
double fSpan;
cStart = fStart;
cEnd = fEnd;
cSpan = cEnd - cStart;
fSpan = cSpan.GetTotalSeconds ();
if(nBestCount > 0) // <------------ avoid divide by zero!
{
fStep = fSpan / (double)nBestCount;
}
else
{
fStep = 0;
}
for (int i = 1; TimeStepTable[i] != -1; i++)
{
if (fStep > TimeStepTable[i-1] && fStep <= TimeStepTable[i])
{
fStep = TimeStepTable[i];
break;
}
}
*fStepWidth = fStep;
*fStepWidth /= 24.0 * 3600;
}
//--------------------------------------------------------------------------------
void CXGraphAxis::AdaptTimeAxis(double * pfStart, double * pfEnd, double fStep)
{
double fDummy;
unsigned long iDummy;
int iModulo = 0;
COleDateTimeSpan cSpan;
COleDateTime cOffset,
cStart,
cEnd;
double lSeconds;
cOffset.SetDateTime (1970, 1, 1, 0, 0, 0);
fStep *= 24 * 3600;
cStart = *pfStart;
cSpan = cStart - cOffset;
lSeconds = cSpan.GetTotalSeconds ();
if(fStep > 0.0)
{
iModulo = ((long) lSeconds - (long) fStep) % (long)fStep;
}
if (iModulo == 0)
{
;//*pfStart = *pfStart - fStep / 24.0 / 3600.0;
}
else
{
iDummy = (unsigned long) lSeconds / (unsigned long) fStep;
fDummy = (double) ((iDummy) * (unsigned long)fStep);
*pfStart = (DATE)(COleDateTime(fDummy / 24.0 / 3600.0)) + cOffset ;
}
cEnd = *pfEnd;
cSpan = cEnd - cOffset;
lSeconds = cSpan.GetTotalSeconds ();
if(fStep > 0.0) // <------------ avoid divide by zero!
{
iModulo = ((long) lSeconds - (long) fStep) % (long)fStep;
}
else
{
iModulo = 0;
}
if (iModulo == 0)
{
;//*pfEnd = *pfEnd + fStep / 24.0 / 3600.0;
}
else
{
iDummy = (unsigned long) lSeconds / (unsigned long) fStep;
fDummy = (double) ((iDummy) * (unsigned long)fStep);
*pfEnd = (DATE)(COleDateTime(fDummy / 24.0 / 3600.0)) + cOffset ;
}
}
//-------------------------------------------------------------------------------------
void CXGraphAxis::Draw(CDCEx* pDC)
{
m_fRange = m_fCurMax - m_fCurMin;
if (m_bAutoScale)
AutoScale(pDC);
if (m_AxisKind == yAxis)
{
m_fSpareRange = (2*m_nArcSize);
m_fMarkerSpareSize = DrawCurveMarkers(pDC);
if (pDC->m_bMono)
pDC->SetBkColor(RGB(255,255,255));
else
pDC->SetBkColor(m_pGraph->m_crGraphColor);
pDC->SetBkMode(OPAQUE);
int nChartTop = m_clChart.top + m_fMarkerSpareSize;
int nTop = m_pGraph->m_clInnerRect.top + m_fSpareRange + m_fMarkerSpareSize;
int nBottom = m_pGraph->m_clInnerRect.bottom;
//m_nRange = nBottom - nTop;
if (m_cLabel != "")
{
CSize titleSize;
{
CFontSelector fs(&m_TitleFont, pDC, false);
titleSize = GetTitleSize(pDC);
m_fSpareRange += titleSize.cy;
}
CFontSelector fs(&m_TitleFont, pDC);
if (m_Placement == apLeft)
{
CRect clTitle(m_nLeft - titleSize.cx - m_nTickSize, nChartTop, m_nLeft - m_nTickSize, nChartTop + titleSize.cy);
pDC->DrawText(m_cLabel, clTitle, DT_RIGHT);
}
else
{
CRect clTitle(m_nLeft + m_nTickSize, nChartTop, m_nLeft + titleSize.cx + m_nTickSize, nChartTop + titleSize.cy);
pDC->DrawText(m_cLabel, clTitle, DT_LEFT);
}
}
m_nRange = m_nTop - nChartTop - m_fSpareRange; // <------------ calc m_nRange BEFORE drawing the scale divisions!
double fSteps = (m_fCurMax - m_fCurMin) / m_fStep;
double fStep = ((double)m_nRange / fSteps);
double fnY = m_nTop;
CString cTxt;
CSize csText;
for (double fY = m_fCurMin; fY <= m_fCurMax; fY += m_fStep, fnY -= fStep)
{
{
CFontSelector fs(&m_Font, pDC, false);
if (m_bDateTime)
cTxt = COleDateTime(fY).Format(m_cDisplayFmt);
else
cTxt.Format(m_cDisplayFmt, fY);
csText = GetTextExtentEx (pDC, cTxt);
}
CFontSelector fs(&m_Font, pDC);
if (m_Placement == apLeft)
{
CRect crText(m_nLeft - csText.cx - m_nTickSize, fnY - csText.cy / 2, m_nLeft - m_nTickSize, fnY + csText.cy / 2);
pDC->DrawText(cTxt, crText, DT_RIGHT);
CPenSelector ps(m_crGridColor, 1, pDC, m_nGridStyle);
pDC->MoveTo(m_nLeft - m_nTickSize, fnY);
// Spare last gridline to prevent axis to be overdrawn
if (!m_bShowGrid || (int)fnY == m_nTop)
pDC->LineTo(m_nLeft, fnY);
else
pDC->LineTo(m_pGraph->m_clInnerRect.right, fnY);
}
if (m_Placement == apRight)
{
CRect crText(m_nLeft + m_nTickSize, fnY - csText.cy / 2, m_nLeft + csText.cx + m_nTickSize, fnY + csText.cy / 2);
pDC->DrawText(cTxt, crText, DT_LEFT);
CPenSelector ps(m_crGridColor, 1, pDC, m_nGridStyle);
pDC->MoveTo(m_nLeft + m_nTickSize, fnY);
// Spare last gridline to prevent axis to be overdrawn
if (!m_bShowGrid || (int)fnY == m_nTop)
pDC->LineTo(m_nLeft, fnY);
else
pDC->LineTo(m_pGraph->m_clInnerRect.left, fnY);
}
}
CPenSelector ps(m_crColor, 1, pDC);
pDC->MoveTo (m_nLeft, m_nTop);
pDC->LineTo (m_nLeft, nChartTop);
DrawArc(pDC, CPoint(m_nLeft, nChartTop), up, m_nArcSize);
m_clRect.SetRect(m_nLeft - 5, nChartTop, m_nLeft + 5, m_nTop);
}
else
{
m_fSpareRange = (4*m_nArcSize);
m_fMarkerSpareSize = DrawCurveMarkers(pDC);
pDC->SetBkColor(m_pGraph->m_crGraphColor);
pDC->SetBkMode(OPAQUE);
int nChartRight = m_pGraph->m_clInnerRect.right - m_fMarkerSpareSize; //m_clChart.right - m_fMarkerSpareSize;
int nLeft = m_pGraph->m_clInnerRect.left;
int nRight = m_pGraph->m_clInnerRect.right - m_fSpareRange - m_fMarkerSpareSize;
if (m_cLabel != "")
{
CSize titleSize;
{
CFontSelector fs(&m_TitleFont, pDC, false);
titleSize = GetTitleSize(pDC);
m_fSpareRange += titleSize.cx;
}
CFontSelector fs(&m_TitleFont, pDC);
CRect clTitle(nChartRight - titleSize.cx, m_nTop + m_nTickSize, nChartRight, m_nTop + m_nTickSize + titleSize.cy);
pDC->DrawText(m_cLabel, clTitle, DT_LEFT);
}
m_nRange = nChartRight - m_nLeft - m_fSpareRange; // <------------ calc m_nRange BEFORE drawing the scale divisions!
double fSteps = ((m_fCurMax - m_fCurMin) / m_fStep);
double fStep = ((double)m_nRange / fSteps);
double fnX = m_nLeft;
CString cTxt;
CSize csText;
for (double fX = m_fCurMin; fX <= m_fCurMax; fX += m_fStep, fnX += fStep)
{
if (m_bDateTime)
cTxt = COleDateTime(fX).Format(m_cDisplayFmt);
else
cTxt.Format(m_cDisplayFmt, fX);
{
CFontSelector fs(&m_Font, pDC, false);
csText = GetTextExtentEx (pDC, cTxt);
}
CFontSelector fs(&m_Font, pDC);
CRect crText(fnX - csText.cx / 2, m_nTop + m_nTickSize, fnX + csText.cx / 2, m_nTop + csText.cy + m_nTickSize);
pDC->DrawText(cTxt, crText, DT_CENTER);
CPenSelector ps(m_crGridColor, 1, pDC, m_nGridStyle);
pDC->MoveTo(fnX, m_nTop + m_nTickSize);
// Spare last gridline to prevent axis to be overdrawn
if (!m_bShowGrid || (int)fnX == m_nLeft)
pDC->LineTo(fnX, m_nTop);
else
pDC->LineTo(fnX, m_clChart.top);
}
CPenSelector ps(m_crColor, 1, pDC);
pDC->MoveTo (m_nLeft, m_nTop);
pDC->LineTo (nChartRight, m_nTop);
DrawArc(pDC, CPoint(nChartRight, m_nTop), right, m_nArcSize);
m_clRect.SetRect(m_nLeft, m_nTop - 5, nChartRight, m_nTop + 5);
}
if (m_bSelected)
pDC->DrawFocusRect (m_clRect);
DrawColorRanges(pDC);
}
Otherwise - thxs for this control - great work!
|
|
|
|
|
See:
PRB: Clipping Doesn't Work Correctly in Print Preview (Q128334)
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q128334
MS says it affects only VC 4.0 and prior versions.
However, this "behaviour" exists also in 6.0.
Few lines must be inserted to have correct clipping.
Adios
|
|
|
|
|
I already tried to use this solution but it sill doesn't work either.
|
|
|
|
|
first I like to say that I love it.
I'm using it for research on high energy astrophysics, and the multi graph/multi axis is great for me.
I've seen that if I try to use a range of say, 1E50 to +1E53 it does'nt work
I didn't have time to fix it. also the auto scale for numbers smaller than 0.1 doesn't work.
for now I've bypassed it, but when I'll fix it I'll post it here.
|
|
|
|
|
In my opinion, some values have truncated.
That is, fDummy = (double)((int)fEnd).
Of course, fDummy and fEnd are double variables.
This must be fDummy = (double((INT64)fEnd) to correct it.
Here is some fix;
---------------------------------------------------------
typedef INT64 myint64;
void CXGraphAxis::AdaptAxis(double* fStart, double* fEnd, double fStep)
{
myint64 iDummy;
myint64 iModulo;
double fDivisor;
double fDummy;
fDivisor = 1.0;
while ((myint64)fStep == 0)
{
fStep *= 10.0;
fDivisor *= 10.0;
}
*fStart *= fDivisor;
*fEnd *= fDivisor;
iModulo = ((myint64) *fStart - (myint64) fStep) % (myint64)fStep;
if (iModulo == 0)
{
if (((double) ((myint64) *fStart) == *fStart) &&
(((myint64) *fStart % (myint64)fStep) == 0))
fDummy = (double)((myint64)*fStart);
else
fDummy = (double)((myint64) *fStart - (myint64) fStep);
}
else
{
iDummy = (myint64) *fStart / (myint64) fStep;
if (*fStart < 0)
fDummy = (double) ((iDummy-1) * (myint64)fStep);
else
fDummy = (double) ((iDummy) * (myint64)fStep);
}
*fStart = fDummy / fDivisor;
iModulo = ((myint64) *fEnd + (myint64) fStep) % (myint64)fStep;
if (iModulo == 0)
{
if (((double) ((myint64) *fEnd) == *fEnd) &&
(((int) *fEnd % (myint64)fStep) == 0))
fDummy = (double)((myint64)*fEnd);
else
fDummy = (double)((myint64) *fEnd + (myint64) fStep);
}
else
{
iDummy = (myint64) *fEnd / (myint64) fStep;
if (*fEnd < 0)
fDummy = (double) ((iDummy-1) * (myint64)fStep);
else
fDummy = (double) ((iDummy+1) * (myint64)fStep);
}
*fEnd = fDummy / fDivisor;
}
|
|
|
|
|
Using INT64 in AdaptAxis won't work either since casting large doubles to INT64 still produces 0 values (INT64 -> 9.223E +/- 18 whereas double -> 1.7E +/- 308).
For now i provide the following fix to overcome this problem, i'll introduce it in the next version.
// bypass fmod problem (results unexpected due to binary representation)
double saveFmod(double x, double y)
{
double fRes = 0.0;
while ((fRes+y) <= fabs(x))
fRes += y;
if (x < 0.0)
return x + fRes;
else
return x - fRes;
}
void CXGraphAxis::AdaptAxis(double* fStart, double* fEnd, double fStep)
{
double fRemainder;
fRemainder = saveFmod(*fStart-fStep, fStep);
if (fRemainder != 0.0)
*fStart -= fRemainder + fStep;
fRemainder = saveFmod(*fEnd+fStep, fStep);
if (fRemainder != 0.0)
*fEnd -= fRemainder - fStep;
}
|
|
|
|
|
Nice work.
While playing with it I found a bug in the CXGraph::DrawCursorLegend method. It crashes in cursor mode, if the x-axis is in a datetime mode. A bad format string is passed to CString::Format.
Here is the fix:
void CXGraph::DrawCursorLegend (CDCEx* pDC)
{
int i;
double fVal;
CString cLabel = "", cFmt, cItem;
m_CursorLabel.m_bVisible = true;
for (i = 0; i < m_XAxis.size(); i++)
{
//CHANGED: bugfix, correct handling of X axis in time mode
fVal = m_XAxis[i].GetValueForPos (m_CurrentPoint.x);
if(m_XAxis[i].m_bDateTime)
{
cFmt = "X[%02d] : " + COleDateTime(fVal).Format(m_XAxis[i].m_cDisplayFmt) + " %s";
cItem.Format(cFmt, i+1, m_XAxis[i].m_cLabel);
cLabel += (" " + cItem + "\r\n");
}
else
{
cFmt = "X[%02d] : " + m_XAxis[i].m_cDisplayFmt + " %s";
cItem.Format(cFmt, i+1, fVal, m_XAxis[i].m_cLabel);
cLabel += (" " + cItem + "\r\n");
}
//ENDCHANGES
}
for (i = 0; i < m_YAxis.size(); i++)
{
fVal = m_YAxis[i].GetValueForPos (m_CurrentPoint.y);
cFmt = "Y[%02d] : " + m_YAxis[i].m_cDisplayFmt + " %s";
cItem.Format(cFmt, i+1, fVal, m_YAxis[i].m_cLabel);
cLabel += (" " + cItem + "\r\n");
}
if (m_nSnappedCurve != -1)
{
//CHANGED: bugfix, correct handling of X axis in time mode
CString cXFmt = m_XAxis[m_Data[m_nSnappedCurve].m_nXAxis].m_cDisplayFmt;
CString cYFmt = m_YAxis[m_Data[m_nSnappedCurve].m_nYAxis].m_cDisplayFmt;
if(m_XAxis[m_Data[m_nSnappedCurve].m_nXAxis].m_bDateTime)
{
cFmt = "%s[%02d] : " + COleDateTime(m_fSnappedXVal).Format(cXFmt) + ", " + cYFmt;
cItem.Format(cFmt, m_Data[m_nSnappedCurve].m_cLabel, m_nSnappedCurve + 1, m_fSnappedYVal);
cLabel += (" " + cItem + "\r\n");
}
else
{
cFmt = "%s[%02d] : " + cXFmt + ", " + cYFmt;
cItem.Format(cFmt, m_Data[m_nSnappedCurve].m_cLabel, m_nSnappedCurve + 1, m_fSnappedXVal, m_fSnappedYVal);
cLabel += (" " + cItem + "\r\n");
}
//ENDCHANGES
}
m_CursorLabel.m_cText = cLabel;
m_CursorLabel.Draw (pDC);
}
Sonork 100.15206;PavelK
|
|
|
|
|
Thanks for that. I've posted a new version.
|
|
|
|
|
Did you try root ? (root.cern.ch)
Jonathan de Halleux, Belgium.
|
|
|
|
|
Well done,
it needs a bit of work still,
Regardz
Colin J Davies
Sonork ID 100.9197:Colin
Testing Current Sig
<marquee><marquee behavior="alternate" scrollamount="12">< >
|
|
|
|
|
Indeed, feel free to advance this one
Regards
Gunnar
|
|
|
|
|