** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ezplot.cpp,v 1.21 2000/12/23 18:12:35 kevin Exp $
+** $Id: ezplot.cpp,v 1.25 2000/12/27 20:09:19 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
static const int DEF_CURVE_CLR = C_RED;
-EZPlotCurve::EZPlotCurve (const double* xData, const double* yData, int n, int color, int linestyle, int symbol, int symfreq, const std::string& legend)
-: x(NULL), y(NULL), m_sLegend (legend)
+EZPlotCurve::EZPlotCurve (const double* xData, const double* yData, int n)
+: x(NULL), y(NULL)
{
x = new double [n];
y = new double [n];
memcpy (y, yData, copyCount);
m_iPointCount = n;
- m_iColor = color;
- m_iLineStyle = linestyle;
- m_iSymbol = symbol;
- m_iSymbolFreq = symfreq;
}
EZPlotCurve::~EZPlotCurve ()
if (num < 1)
return;
- EZPlotCurve* pCurve = new EZPlotCurve (x, y, num, o_color, o_linestyle, o_symbol, o_symfreq, c_legend);
+ EZPlotCurve* pCurve = new EZPlotCurve (x, y, num);
m_vecCurves.push_back (pCurve);
}
EZPlot::EZPlot (SGP& sgp)
: rSGP (sgp)
{
- initPlotSettings();
+ initKeywords();\r
+ m_pol.addSkipWord ("please");\r
+ m_pol.addSkipWord ("use");\r
+ m_pol.addSkipWord ("are");\r
+ m_pol.addSkipWord ("and");\r
+ m_pol.addSkipWord ("is");\r
+ m_pol.addSkipWord ("the");\r
+ m_pol.addSkipWord ("equals");\r
+ m_pol.addSkipChar ('=');\r
+ \r
+ m_pol.usefile (POL::P_USE_STR,"");\r
+ m_pol.set_inputline ("!eoc ,");\r
+ m_pol.reader ();\r
+ m_pol.closefile ();\r
+\r
+ initPlotSettings();
}
void
{
charheight = rSGP.getCharHeight();
charwidth = rSGP.getCharWidth();
-
+\r
+ m_iCurrentCurve = -1;\r
+
c_xlabel = "";
c_ylabel = "";
c_title = "";
- c_legend = "";
o_xporigin = 0.0;
o_yporigin = 0.0;
s_textsize = FALSE;
clr_axis = C_BLACK; // set fixed colors
- clr_title = C_CYAN;
- clr_label = C_CYAN;
- clr_legend = C_RED;
+ clr_title = C_RED;
+ clr_label = C_BLUE;
+ clr_legend = C_CYAN;
clr_number = C_GREEN;
clr_grid = C_LTGRAY;
}
-
+void\r
+EZPlot::setColor (unsigned int iCurve, int iColor)\r
+{\r
+ if (m_veciColor.size() <= iCurve) {\r
+ m_veciColor.resize ((m_iCurrentCurve + 1) * 2);\r
+ m_vecbColorSet.resize ((m_iCurrentCurve + 1) * 2);\r
+ }\r
+ m_veciColor [iCurve] = iColor;\r
+ m_vecbColorSet [iCurve] = true;\r
+}\r
+\r
+void\r
+EZPlot::setSymbol (unsigned int iCurve, int iSymbol)\r
+{\r
+ if (m_veciSymbol.size() <= iCurve) {\r
+ m_veciSymbol.resize ((m_iCurrentCurve + 1) * 2);\r
+ m_vecbSymbolSet.resize ((m_iCurrentCurve + 1) * 2);\r
+ }\r
+ m_veciSymbol [iCurve] = iSymbol;\r
+ m_vecbSymbolSet [iCurve] = true;\r
+}\r
+\r
+void\r
+EZPlot::setSymbolFreq (unsigned int iCurve, int iSymbolFreq)\r
+{\r
+ if (m_veciSymbolFreq.size() <= iCurve) {\r
+ m_veciSymbolFreq.resize ((m_iCurrentCurve + 1) * 2);\r
+ m_vecbSymbolFreqSet.resize ((m_iCurrentCurve + 1) * 2);\r
+ }\r
+ m_veciSymbolFreq [iCurve] = iSymbolFreq;\r
+ m_vecbSymbolFreqSet [iCurve] = true;\r
+}\r
+\r
+void\r
+EZPlot::setLinestyle (unsigned int iCurve, int iLinestyle)\r
+{\r
+ if (m_veciLinestyle.size() <= iCurve) {\r
+ m_veciLinestyle.resize ((m_iCurrentCurve + 1) * 2);\r
+ m_vecbLinestyleSet.resize ((m_iCurrentCurve + 1) * 2);\r
+ }\r
+ m_veciLinestyle [iCurve] = iLinestyle;\r
+ m_vecbLinestyleSet [iCurve] = true;\r
+}\r
+\r
+void\r
+EZPlot::setLegend (unsigned int iCurve, const std::string& strLegend)\r
+{\r
+ if (m_vecsLegend.size() <= iCurve) {\r
+ m_vecsLegend.resize ((m_iCurrentCurve + 1) * 2);\r
+ m_vecbLegendSet.resize ((m_iCurrentCurve + 1) * 2);\r
+ }\r
+ m_vecsLegend [iCurve] = strLegend;\r
+ m_vecbLegendSet [iCurve] = true;\r
+}\r
+\r
+void\r
+EZPlot::setLegend (unsigned int iCurve, const char* const pszLegend)\r
+{\r
+ if (m_vecsLegend.size() <= iCurve) {\r
+ m_vecsLegend.resize ((m_iCurrentCurve + 1) * 2);\r
+ m_vecbLegendSet.resize ((m_iCurrentCurve + 1) * 2);\r
+ }\r
+ m_vecsLegend [iCurve] = pszLegend;\r
+ m_vecbLegendSet [iCurve] = true;\r
+}\r
+\r
+int\r
+EZPlot::getColor (unsigned int iCurve) const\r
+{\r
+ if (m_veciColor.size() > iCurve && m_vecbColorSet[iCurve])\r
+ return m_veciColor[iCurve];\r
+ else\r
+ return o_color;\r
+}\r
+ \r
+int\r
+EZPlot::getSymbol (unsigned int iCurve) const\r
+{\r
+ if (m_veciSymbol.size() > iCurve && m_vecbSymbolSet[iCurve])\r
+ return m_veciSymbol[iCurve];\r
+ else\r
+ return o_symbol;\r
+}\r
+ \r
+int\r
+EZPlot::getSymbolFreq (unsigned int iCurve) const\r
+{\r
+ if (m_veciSymbolFreq.size() > iCurve && m_vecbSymbolFreqSet[iCurve])\r
+ return m_veciSymbolFreq[iCurve];\r
+ else\r
+ return o_symfreq;\r
+}\r
+ \r
+int\r
+EZPlot::getLinestyle (unsigned int iCurve) const\r
+{\r
+ if (m_veciLinestyle.size() > iCurve && m_vecbLinestyleSet[iCurve])\r
+ return m_veciLinestyle[iCurve];\r
+ else\r
+ return o_linestyle;\r
+}\r
+ \r
+const std::string*\r
+EZPlot::getLegend (unsigned int iCurve) const\r
+{\r
+ if (m_vecsLegend.size() > iCurve && m_vecbLegendSet[iCurve])\r
+ return &m_vecsLegend[iCurve];\r
+ else\r
+ return NULL;\r
+}\r
+ \r
+\r
/* NAME
* plot Plots all curves collected by addCurves ()
*
void
EZPlot::plot ()
{\r
-#if 0\r
- wxFont* myFont = new wxFont (12, wxMODERN, wxNORMAL, wxNORMAL);\r
- rSGP.getDriver().idWX()->SetFont (*myFont);\r
-#endif
if (m_vecCurves.size() <= 0)
return;
rSGP.setWindow (0., 0., 1., 1.);
- if (s_textsize == TRUE) {
- charheight = v_textsize;
- charwidth = rSGP.getCharWidth();
- } else {
- charheight = rSGP.getCharHeight();
- charwidth = rSGP.getCharWidth();
- }
-
- const EZPlotCurve& firstCurve = *m_vecCurves[0];
+ if (s_textsize == TRUE)
+ rSGP.setTextPointSize (v_textsize);\r
+ charheight = rSGP.getCharHeight();
+ charwidth = rSGP.getCharWidth();
+
+ const EZPlotCurve& firstCurve = *m_vecCurves[0];\r
double xmin = firstCurve.x[0]; // extent of curves in world coord
double xmax = xmin;
double ymin = firstCurve.y[0];
- double ymax = ymin;
-
- for (EZPlotCurveConstIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) {
- const EZPlotCurve& curve = **iterCurve;
+ double ymax = ymin; \r
+ unsigned int iCurve;
+ for (iCurve = 0; iCurve < m_vecCurves.size(); iCurve++) {
+ const EZPlotCurve* const pCurve = m_vecCurves [iCurve];
- for (int ip = 0; ip < curve.m_iPointCount; ip++) {
- if (curve.x[ip] > xmax)
- xmax = curve.x[ip];
- else if (curve.x[ip] < xmin)
- xmin = curve.x[ip];
- if (curve.y[ip] > ymax)
- ymax = curve.y[ip];
- else if (curve.y[ip] < ymin)
- ymin = curve.y[ip];
+ for (int ip = 0; ip < pCurve->m_iPointCount; ip++) {
+ if (pCurve->x[ip] > xmax)
+ xmax = pCurve->x[ip];
+ else if (pCurve->x[ip] < xmin)
+ xmin = pCurve->x[ip];
+ if (pCurve->y[ip] > ymax)
+ ymax = pCurve->y[ip];
+ else if (pCurve->y[ip] < ymin)
+ ymin = pCurve->y[ip];
}
}
ya_max = yp_max;
// adjust frame for title
+ title_row = ya_max;;\r
if (c_title.length() > 0)
- ya_max -= 2 * charheight;
- title_row = ya_max + 2 * charheight;
-
+ ya_max -= 2 * charheight;\r
+
// calculate legend box boundaries
int max_leg = 0; // longest legend in characters
- int num_leg = 0; // number of legend titles
- for (EZPlotCurveConstIterator iterCurve2 = m_vecCurves.begin(); iterCurve2 != m_vecCurves.end(); iterCurve2++) {
- const EZPlotCurve& curve = **iterCurve2;
- int nLegend = curve.m_sLegend.length();
- if (nLegend > 0) {
- ++num_leg;
- if (nLegend > max_leg)\r
- nLegend = max_leg;
+ int num_leg = 0; // number of legend titles \r
+ for (iCurve = 0; iCurve < m_vecCurves.size(); iCurve++) {
+ const std::string* pstrLegend = getLegend (iCurve);\r
+ if (pstrLegend && pstrLegend->length() > 0) {\r
+ int nLegend = pstrLegend->length();
+ if (nLegend > 0) {
+ ++num_leg;
+ if (nLegend > max_leg)\r
+ nLegend = max_leg;\r
+ }
}
}
rSGP.setColor (clr_legend);
rSGP.drawRect (xl_min, yl_min, xl_max, yl_max);
- int iLegend = 0; // current legend position
- for (EZPlotCurveIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) {
- const EZPlotCurve& curve = **iterCurve;
-
- if (curve.m_sLegend.length() == 0)
+ int iLegend = 0; // current legend position \r
+ for (iCurve = 0; iCurve < m_vecCurves.size(); iCurve++) {
+ const std::string* pstrLegend = getLegend (iCurve);
+ if (! pstrLegend || pstrLegend->length() == 0)
continue;
double xmin = xl_min + 1.0 * charwidth;
double xmax = xl_max - 1.0 * charwidth;
double y = yl_max - (2.0 + iLegend * 3) * charheight;
- rSGP.moveAbs (xmin, y + 0.5 * charheight);
- rSGP.drawText (curve.m_sLegend);
- rSGP.setColor (curve.m_iColor);
- if (curve.m_iLineStyle != SGP::LS_NOLINE) {
- rSGP.setLineStyle (curve.m_iLineStyle);
+ rSGP.moveAbs (xmin, y + 0.5 * charheight);\r
+ rSGP.drawText (pstrLegend->c_str());
+ rSGP.setColor (getColor (iCurve));\r
+ int iLS = getLinestyle (iCurve);
+ if (iLS != SGP::LS_NOLINE) {
+ rSGP.setLineStyle (iLS);
rSGP.moveAbs (xmin, y);
rSGP.lineAbs (xmax, y);
- }
- if (curve.m_iSymbol > 0) {
+ }\r
+ int iSymbol = getSymbol (iCurve);
+ if (iSymbol > 0) {
double xinc = (xmax - xmin) / (5 - 1);
rSGP.setLineStyle (SGP::LS_SOLID);
for (int j = 0; j < 5; j++) {
rSGP.moveAbs (xmin + j * xinc, y);
- symbol(curve.m_iSymbol, 0.5 * charwidth, 0.5 * charheight);
+ symbol(iSymbol, 0.5 * charwidth, 0.5 * charheight);
}
}
++iLegend; // move to next legend position
// X-Label
if (c_xlabel.length() > 0)
- ya_min += 3.0 * charheight;
+ ya_min += 1.5 * charheight;
xlbl_row = xp_min; // put x-label on bottom of plot frame
// Y-Label
- if (c_ylabel.length() > 0)
- xa_min += 3.0 * charwidth; // reverse rSGP.setTextSize because writing text sideways
- ylbl_col = xp_min + 2 * charwidth;
+ if (c_ylabel.length() > 0) {\r
+ rSGP.setTextAngle (HALFPI);\r
+ rSGP.setTextSize (1.5 * charheight);\r
+ double xExtent, yExtent;\r
+ rSGP.getTextExtent (c_ylabel.c_str(), &xExtent, &yExtent);\r
+ rSGP.setTextSize (charheight);\r
+ xa_min += xExtent;\r
+ rSGP.setTextAngle (0.0);\r
+ }
+ ylbl_col = xp_min;
/*------------------------------*/
/* adjust frame for tick labels */
if (o_xaxis == NOAXIS || o_xtlabel == FALSE)
xtl_ofs = 0.0;
else if (o_xticks == BELOW)
- xtl_ofs = -1.5 * charheight; // kr
+ xtl_ofs = -0.5 * charheight;
else if (o_xticks == ABOVE)
- xtl_ofs = 1.5 * charheight;
+ xtl_ofs = 0.5 * charheight;
if (o_yaxis == NOAXIS || o_ytlabel == FALSE)
ytl_ofs = 0.0;
else if (o_yticks == LEFT)
- ytl_ofs = -(1 + y_fldwid) * charwidth;
+ ytl_ofs = -(2 + y_fldwid) * charwidth;
else if (o_yticks == RIGHT)
ytl_ofs = 1.5 * charwidth;
+ xa_max -= 0.7 * x_fldwid * charwidth; // make room for last x tick label\r
+\r
xt_min = xa_min;
yt_min = ya_min;
xt_max = xa_max;
// see if need to shrink axis extents and/or tick extents
if (xtl_ofs != 0.0 && s_ycross == FALSE) {
if (o_xticks == BELOW) {
- ya_min += 2.5 * charheight;
+ ya_min += 1.5 * charheight;
yt_min = ya_min;
} else if (o_xticks == ABOVE) {
ya_min += 0.0;
- yt_min = ya_min + 2.5 * charheight;
+ yt_min = ya_min + 1.5 * charheight;
}
} else // noaxis, no t-labels, or user set cross
yt_min = ya_min;
if (ytl_ofs != 0.0 && s_xcross == FALSE) {
if (o_yticks == LEFT) {
- xa_min += (1 + y_fldwid) * charwidth;
+ xa_min += (2 + y_fldwid) * charwidth;
xt_min = xa_min;
} else if (o_yticks == RIGHT) {
xa_min += 0.0;
}
} else
xt_min = xa_min;
-
+
// decrease size of graph, if necessary, to accommadate space
// between axis boundary and boundary of ticks
double x_added_ticks = 0; // number of tick spaces added to axis
\r
double clipRect[4];\r
clipRect[0] = xgn_min; clipRect[1] = ygn_min; clipRect[2] = xgn_max; clipRect[3] = ygn_max;\r
-
- for (EZPlotCurveIterator iterCurve3 = m_vecCurves.begin(); iterCurve3 != m_vecCurves.end(); iterCurve3++) {
- const EZPlotCurve& curve = **iterCurve3;
-
- rSGP.setColor (curve.m_iColor);
+\r
+ for (iCurve = 0; iCurve < m_vecCurves.size(); iCurve++) {
+ const EZPlotCurve* const pCurve = m_vecCurves [iCurve];
\r
- bool bOutside = false;
- if (curve.m_iLineStyle != SGP::LS_NOLINE) {
- rSGP.setLineStyle (curve.m_iLineStyle);
- double x1 = convertWorldToNDC_X (curve.x[0]);
- double y1 = convertWorldToNDC_Y (curve.y[0]);\r
- for (int i = 1; i < curve.m_iPointCount; i++) {
- double x2 = convertWorldToNDC_X (curve.x[i]);
- double y2 = convertWorldToNDC_Y (curve.y[i]);\r
+ rSGP.setColor (getColor (iCurve));\r
+ int iSym = getSymbol (iCurve);\r
+ int iLS = getLinestyle (iCurve);\r
+\r
+ if (iLS != SGP::LS_NOLINE) {
+ rSGP.setLineStyle (iLS);
+ double x1 = convertWorldToNDC_X (pCurve->x[0]);
+ double y1 = convertWorldToNDC_Y (pCurve->y[0]);\r
+ for (int i = 1; i < pCurve->m_iPointCount; i++) {
+ double x2 = convertWorldToNDC_X (pCurve->x[i]);
+ double y2 = convertWorldToNDC_Y (pCurve->y[i]);\r
double x2Clip = x2;\r
double y2Clip = y2;\r
if (clip_rect (x1, y1, x2Clip, y2Clip, clipRect)) {\r
y1 = y2;\r
}
}
- if (curve.m_iSymbol > 0) {
+ if (iSym > 0) {\r
+ int iSymFreq = getSymbolFreq (iCurve);
rSGP.setLineStyle (SGP::LS_SOLID);
- double x = convertWorldToNDC_X (curve.x[0]);
- double y = convertWorldToNDC_Y (curve.y[0]);
+ double x = convertWorldToNDC_X (pCurve->x[0]);
+ double y = convertWorldToNDC_Y (pCurve->y[0]);
rSGP.moveAbs (x, y);
- symbol (curve.m_iSymbol, symwidth, symheight);
- for (int i = 1; i < curve.m_iPointCount; i++)
- if (i % curve.m_iSymbolFreq == 0 || i == curve.m_iPointCount - 1) {
- x = convertWorldToNDC_X (curve.x[i]);
- y = convertWorldToNDC_Y (curve.y[i]);\r
+ symbol (iSym, symwidth, symheight);
+ for (int i = 1; i < pCurve->m_iPointCount; i++)
+ if (i % iSymFreq == 0 || i == pCurve->m_iPointCount - 1) {
+ x = convertWorldToNDC_X (pCurve->x[i]);
+ y = convertWorldToNDC_Y (pCurve->y[i]);\r
if (y >= ygn_min && y <= ygn_max) {
rSGP.moveAbs (x, y);
- symbol (curve.m_iSymbol, symwidth, symheight);\r
+ symbol (iSym, symwidth, symheight);\r
}
}
}
rSGP.setTextColor (1, -1);
if (o_xticks == ABOVE)
- xticklen = charheight;
+ xticklen = 0.5 * charheight;
else if (o_xticks == BELOW)
- xticklen = -charheight;
+ xticklen = -0.5 * charheight;
if (o_yticks == RIGHT)
yticklen = charwidth;
rSGP.lineAbs (xt_min + xn_tickinc * i, ya_min);
}
}
- rSGP.moveAbs (xa_min + (xa_max-xa_min)/2 - c_xlabel.length()*charwidth * 1.5, xlbl_row + charheight * 1.5);
rSGP.setTextSize (charheight * 1.5);
- rSGP.setTextColor (clr_label, -1);
+ rSGP.setTextColor (clr_label, -1);\r
+ double wText, hText;\r
+ rSGP.getTextExtent (c_xlabel.c_str(), &wText, &hText);
+ rSGP.moveAbs (xa_min + (xa_max-xa_min)/2 - wText / 2, xlbl_row + charheight * 1.5);\r
rSGP.drawText (c_xlabel);
rSGP.setTextSize (charheight);
minorinc = xn_tickinc / (o_xminortick + 1);
rSGP.moveAbs (xa_max, y);
rSGP.lineAbs (xa_min, y);
}
- }
- rSGP.moveAbs (ylbl_col, ya_min + (ya_max-ya_min)/2 - c_ylabel.length()*charheight*1.5);\r
- rSGP.getDriver().idWX()->SetFont(*wxSWISS_FONT);
+ }\r
rSGP.setTextAngle (HALFPI);
rSGP.setTextSize (1.5 * charheight);
- rSGP.setTextColor (clr_label, -1);
+ rSGP.setTextColor (clr_label, -1);\r
+ double xExtent, yExtent;\r
+ rSGP.getTextExtent (c_ylabel.c_str(), &xExtent, &yExtent);\r
+ rSGP.moveAbs (ylbl_col, ya_min + (ya_max-ya_min)/2 - yExtent / 2);\r
+ rSGP.drawText (c_ylabel);\r
rSGP.setTextAngle (0.0);
rSGP.setTextSize (charheight);
minorinc = yn_tickinc / (o_yminortick + 1);
axis_near = TRUE;
}
if (o_ytlabel == TRUE && axis_near == FALSE) {
- snprintf (str, sizeof(str), y_numfmt, ygw_min + yw_tickinc * i);
- rSGP.moveAbs (yaxispos + ytl_ofs, y + 0.5 * charheight);
+ snprintf (str, sizeof(str), y_numfmt, ygw_min + yw_tickinc * i);\r
+ rSGP.moveAbs (yaxispos + ytl_ofs, y + 0.5 * charheight);\r
rSGP.setTextColor (clr_number, -1);\r
rSGP.drawText (str);
}