ScatterDraw: Improvements and bug fixes

git-svn-id: svn://ultimatepp.org/upp/trunk@7672 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
koldo 2014-09-12 20:59:20 +00:00
parent 55d8b70bb1
commit 55038caed5
5 changed files with 327 additions and 226 deletions

View file

@ -7,8 +7,8 @@ class DataSource {
public:
typedef double (DataSource::*Getdatafun)(int64 id);
DataSource() : isParam(false), isExplicit(false) {}
virtual ~DataSource() {}
DataSource() : isParam(false), isExplicit(false), key(111111) {}
virtual ~DataSource() {key = 0;}
virtual double y(int64 id) {return xn(0, id);}
virtual double x(int64 id) {return xn(1, id);}
virtual double xn(int n, int64 id) {NEVER(); return Null;}
@ -20,6 +20,7 @@ public:
virtual int64 GetCount() {NEVER(); return Null;}
bool IsParam() {return isParam;}
bool IsExplicit() {return isExplicit;}
bool IsDeleted() {return key != 111111;}
virtual double MinY() {return Min(&DataSource::y);}
virtual double MinX() {return Min(&DataSource::x);}
@ -36,6 +37,9 @@ protected:
virtual double Min(Getdatafun getdata);
virtual double Max(Getdatafun getdata);
virtual double Avg(Getdatafun getdata);
private:
int key;
};
class CArray : public DataSource {
@ -62,9 +66,12 @@ private:
public:
VectorY(Vector<Y> &yData, double x0, double deltaX) : yData(&yData), x0(x0), deltaX(deltaX) {}
virtual inline double y(int64 id) {return (*yData)[id];}
virtual inline double y(int64 id) {return (*yData)[ptrdiff_t(id)];}
virtual inline double x(int64 id) {return id*deltaX + x0;}
virtual inline int64 GetCount() {return yData->GetCount();}
virtual double MinX() {return x0;}
virtual double MaxX() {return x0 + (yData->GetCount() - 1)*deltaX;}
virtual double AvgX() {return x0 + ((yData->GetCount() - 1)*deltaX)/2.;}
};
template <class Y>
@ -75,9 +82,12 @@ private:
public:
ArrayY(Upp::Array<Y> &yData, double x0, double deltaX) : yData(&yData), x0(x0), deltaX(deltaX) {}
virtual inline double y(int64 id) {return (*yData)[id];}
virtual inline double y(int64 id) {return (*yData)[ptrdiff_t(id)];}
virtual inline double x(int64 id) {return id*deltaX + x0;}
virtual inline int64 GetCount() {return yData->GetCount();}
virtual double MinX() {return x0;}
virtual double MaxX() {return x0 + yData->GetCount()*deltaX;}
virtual double AvgX() {return (x0 + yData->GetCount()*deltaX)/2.;}
};
template <class Y>
@ -138,7 +148,7 @@ public:
VectorDouble(const Vector<double> &yData, Vector<double> &xData) : xData(&xData), yData(&yData) {}
virtual inline double y(int64 id) {return (*yData)[int(id)];}
virtual inline double x(int64 id) {return (*xData)[int(id)];}
virtual inline int64 GetCount() {return xData->GetCount();}
virtual inline int64 GetCount() {return min(xData->GetCount(), yData->GetCount());}
};
class ArrayDouble : public DataSource {
@ -149,7 +159,7 @@ public:
ArrayDouble(const Upp::Array<double> &yData, Upp::Array<double> &xData) : xData(&xData), yData(&yData) {}
virtual inline double y(int64 id) {return (*yData)[int(id)];}
virtual inline double x(int64 id) {return (*xData)[int(id)];}
virtual inline int64 GetCount() {return xData->GetCount();}
virtual inline int64 GetCount() {return min(xData->GetCount(), yData->GetCount());}
};
class VectorPointf : public DataSource {

View file

@ -61,13 +61,26 @@ public:
class PolynomialEquation : public ExplicitEquation {
public:
PolynomialEquation() {}
PolynomialEquation(const Array<double>& c) {SetCoeff(c);}
PolynomialEquation() {}
PolynomialEquation(const Array<double>& c) {SetCoeff(c);}
double f(double x);
virtual String GetName() {return t_("Polynomial");}
virtual String GetFullName() {return t_("Polynomial") + String(" n = ") + FormatInt(degree);}
virtual String GetName() {return t_("Polynomial");}
virtual String GetFullName() {return t_("Polynomial") + String(" n = ") + FormatInt(degree);}
virtual String GetEquation();
void SetDegree(int num) {degree = num; SetNumCoeff(num + 1);}
void SetDegree(int num) {degree = num; SetNumCoeff(num + 1);}
};
class SinEquation : public ExplicitEquation {
public:
SinEquation() {coeff.Clear(); coeff << 0. << 0.1 << 0.1 << 0.1;}
SinEquation(double offset, double A, double w, double phi) {coeff.Clear(); coeff << offset << A << w << phi;}
double f(double x) {return coeff[0] + coeff[1]*sin(coeff[2]*x + coeff[3]);}
virtual String GetName() {return t_("Sinusoidal");}
virtual String GetEquation() {return FormatDoubleFix(coeff[0], numDigits) + " + " +
FormatDoubleFix(coeff[1], numDigits) + "*sin(" +
FormatDoubleFix(coeff[2], numDigits) + "*t + " +
FormatDoubleFix(coeff[3], numDigits) + ")";}
void SetDegree(int num) {NEVER();}
};
class FourierEquation : public ExplicitEquation {
@ -81,6 +94,30 @@ public:
void SetDegree(int num) {degree = num; SetNumCoeff(2*num + 2);}
};
class ExponentialEquation : public ExplicitEquation {
public:
ExponentialEquation() {SetCoeff(1, 0);}
ExponentialEquation(double c0, double c1) {SetCoeff(c0, c1);}
double f(double x) {return coeff[0]*exp(-x) + coeff[1];}
virtual String GetName() {return t_("Exponential");}
virtual String GetEquation() {return FormatDoubleFix(fabs(coeff[0]), numDigits) + "*e^-x " +
(coeff[1] >= 0 ? "+" : "-") + " " + FormatDoubleFix(coeff[1], numDigits);}
void SetDegree(int num) {NEVER();}
};
class Rational1Equation : public ExplicitEquation {
public:
Rational1Equation() {SetCoeff(1, 0, 0);}
Rational1Equation(double c0, double c1, double c2) {SetCoeff(c0, c1, c2);}
double f(double x) {return coeff[0]/(x + coeff[1]) + coeff[2];}
virtual String GetName() {return t_("Rational_1");}
virtual String GetEquation() {return FormatDoubleFix(fabs(coeff[0]), numDigits) + "/(x " + (coeff[1] >= 0 ? "+" : "-") + " " +
FormatDoubleFix(fabs(coeff[1]), numDigits) + ") " + (coeff[2] >= 0 ? "+" : "-") + " " +
FormatDoubleFix(fabs(coeff[2]), numDigits);}
void SetDegree(int num) {NEVER();}
};
END_UPP_NAMESPACE
#endif

View file

@ -343,73 +343,84 @@ void ScatterDraw::FitToData(bool vertical) {
linkedCtrls[i]->DoFitToData(vertical);
}
}
void ScatterDraw::DoFitToData(bool vertical) {
double minx, maxx, miny, miny2, maxy, maxy2;
minx = miny = miny2 = -DOUBLE_NULL;
maxx = maxy = maxy2 = DOUBLE_NULL;
for (int j = 0; j < series.GetCount(); j++) {
if (series[j].opacity == 0 || series[j].PointsData()->IsExplicit())
continue;
minx = min(minx, series[j].PointsData()->MinX());
maxx = max(maxx, series[j].PointsData()->MaxX());
}
if (vertical) {
try {
for (int j = 0; j < series.GetCount(); j++) {
if (series[j].opacity == 0 || series[j].PointsData()->IsExplicit())
continue;
for (int64 i = 0; i < series[j].PointsData()->GetCount(); i++) {
if (series[j].primaryY) {
if (series[j].PointsData()->y(i) < miny)
miny = series[j].PointsData()->y(i);
if (series[j].PointsData()->y(i) > maxy)
maxy = series[j].PointsData()->y(i);
} else {
if (series[j].PointsData()->y(i) < miny2)
miny2 = series[j].PointsData()->y(i);
if (series[j].PointsData()->y(i) > maxy2)
maxy2 = series[j].PointsData()->y(i);
minx = min(minx, series[j].PointsData()->MinX());
maxx = max(maxx, series[j].PointsData()->MaxX());
}
if (vertical) {
for (int j = 0; j < series.GetCount(); j++) {
if (series[j].opacity == 0 || series[j].PointsData()->IsExplicit())
continue;
for (int64 i = 0; i < series[j].PointsData()->GetCount(); i++) {
double py = series[j].PointsData()->y(i);
if (IsNull(py))
continue;
if (series[j].primaryY) {
if (py < miny)
miny = py;
if (py > maxy)
maxy = py;
} else {
if (py < miny2)
miny2 = py;
if (py > maxy2)
maxy2 = py;
}
}
}
}
}
if (minx != -DOUBLE_NULL) {
double deltaX = xMin - minx;
xMin -= deltaX;
xMinUnit += deltaX;
AdjustMinUnitX();
if (maxx == minx) {
if (maxx == 0) {
xRange = 2;
xMin = -1;
}
}
if (minx != -DOUBLE_NULL) {
if (maxx == minx) {
if (maxx == 0) {
xRange = 2;
xMin = -1;
} else
xRange = 2*maxx;
} else
xRange = 2*maxx;
} else
xRange = maxx - minx;
xRange = maxx - minx;
double deltaX = xMin - minx;
xMin -= deltaX;
xMinUnit += deltaX;
xMajorUnit = xRange/10;
AdjustMinUnitX();
}
if (vertical) {
if (miny != -DOUBLE_NULL) {
if (maxy == miny)
yRange2 = maxy > 0 ? 2*maxy : 1;
else
yRange = maxy - miny;
double deltaY = yMin - miny;
yMin -= deltaY;
yMinUnit += deltaY;
yMajorUnit = yRange/10;
AdjustMinUnitY();
}
if (miny2 != -DOUBLE_NULL) {
if (maxy2 == miny2)
yRange2 = maxy2 > 0 ? 2*maxy2 : 1;
else
yRange2 = maxy2 - miny2;
double deltaY2 = yMin2 - miny2;
yMin2 -= deltaY2;
yMinUnit2 += deltaY2;
yMajorUnit2 = yRange2/10;
AdjustMinUnitY2();
}
}
} catch (ValueTypeError err) {
ASSERT_(true, err);
return;
}
if (vertical) {
if (miny != -DOUBLE_NULL) {
double deltaY = yMin - miny;
yMin -= deltaY;
yMinUnit += deltaY;
AdjustMinUnitY();
if (maxy == miny)
yRange2 = maxy > 0 ? 2*maxy : 1;
else
yRange = maxy - miny;
}
if (miny2 != -DOUBLE_NULL) {
double deltaY2 = yMin2 - miny2;
yMin2 -= deltaY2;
yMinUnit2 += deltaY2;
AdjustMinUnitY2();
if (maxy2 == miny2)
yRange2 = maxy2 > 0 ? 2*maxy2 : 1;
else
yRange2 = maxy2 - miny2;
}
}
WhenSetRange();
WhenSetXYMin();
Refresh();
@ -453,9 +464,9 @@ String ScatterDraw::VariableFormat(double range, double d) {
else if (0.1 <= range && range < 1) return FormatDouble(d, 3);
else if (1 <= range && range < 10) return FormatDouble(d, 2);
else if (10 <= range && range < 100) return FormatDouble(d, 1);
else if (100 <= range && range < 100000) {
if (d < 1 && d > -1) return "0"; // Never -0
else return FormatDouble(d, 0);
else if (100 <= range && range < 10000000) {
/*if (d < 1 && d > -1) return "0"; // Never -0
else*/ return FormatDouble(d, 0);
} else return FormatDoubleExp(d, 2);
}
@ -571,52 +582,53 @@ ScatterDraw &ScatterDraw::_AddSeries(DataSource *data) {
return *this;
}
void ScatterDraw::InsertSeries(int index, double *yData, int numData, double x0, double deltaX) {
InsertSeries<CArray>(index, yData, numData, x0, deltaX);
ScatterDraw &ScatterDraw::InsertSeries(int index, double *yData, int numData, double x0, double deltaX) {
return InsertSeries<CArray>(index, yData, numData, x0, deltaX);
}
void ScatterDraw::InsertSeries(int index, double *xData, double *yData, int numData) {
InsertSeries<CArray>(index, xData, yData, numData);
ScatterDraw &ScatterDraw::InsertSeries(int index, double *xData, double *yData, int numData) {
return InsertSeries<CArray>(index, xData, yData, numData);
}
void ScatterDraw::InsertSeries(int index, Vector<double> &xData, Vector<double> &yData) {
InsertSeries<VectorDouble>(index, xData, yData);
ScatterDraw &ScatterDraw::InsertSeries(int index, Vector<double> &xData, Vector<double> &yData) {
return InsertSeries<VectorDouble>(index, xData, yData);
}
void ScatterDraw::InsertSeries(int index, Array<double> &xData, Array<double> &yData) {
InsertSeries<ArrayDouble>(index, xData, yData);
ScatterDraw &ScatterDraw::InsertSeries(int index, Array<double> &xData, Array<double> &yData) {
return InsertSeries<ArrayDouble>(index, xData, yData);
}
void ScatterDraw::InsertSeries(int index, Vector<Pointf> &points) {
InsertSeries<VectorPointf>(index, points);
ScatterDraw &ScatterDraw::InsertSeries(int index, Vector<Pointf> &points) {
return InsertSeries<VectorPointf>(index, points);
}
void ScatterDraw::InsertSeries(int index, Array<Pointf> &points) {
InsertSeries<ArrayPointf>(index, points);
ScatterDraw &ScatterDraw::InsertSeries(int index, Array<Pointf> &points) {
return InsertSeries<ArrayPointf>(index, points);
}
void ScatterDraw::InsertSeries(int index, double (*function)(double)) {
InsertSeries<FuncSource>(index, function);
ScatterDraw &ScatterDraw::InsertSeries(int index, double (*function)(double)) {
return InsertSeries<FuncSource>(index, function);
}
void ScatterDraw::InsertSeries(int index, Pointf (*function)(double), int np, double from, double to) {
InsertSeries<FuncSourcePara>(index, function, np, from, to);
ScatterDraw &ScatterDraw::InsertSeries(int index, Pointf (*function)(double), int np, double from, double to) {
return InsertSeries<FuncSourcePara>(index, function, np, from, to);
}
void ScatterDraw::InsertSeries(int index, PlotExplicFunc &function) {
InsertSeries<PlotExplicFuncSource>(index, function);
ScatterDraw &ScatterDraw::InsertSeries(int index, PlotExplicFunc &function) {
return InsertSeries<PlotExplicFuncSource>(index, function);
}
void ScatterDraw::InsertSeries(int index, PlotParamFunc function, int np, double from, double to) {
InsertSeries<PlotParamFuncSource>(index, function, np, from, to);
ScatterDraw &ScatterDraw::InsertSeries(int index, PlotParamFunc function, int np, double from, double to) {
return InsertSeries<PlotParamFuncSource>(index, function, np, from, to);
}
void ScatterDraw::_InsertSeries(int index, DataSource *data) {
ScatterDraw &ScatterDraw::_InsertSeries(int index, DataSource *data) {
ASSERT(IsValid(index));
ScatterSeries &s = series.Insert(index);
s.Init(index);
s.SetDataSource(data);
Refresh();
return *this;
}
int64 ScatterDraw::GetCount(int index) {
@ -631,20 +643,35 @@ int64 ScatterDraw::GetCount(int index) {
void ScatterDraw::GetValues(int index, int64 idata, double &x, double &y) {
ASSERT(IsValid(index) && !IsNull(GetCount(index)));
ASSERT(idata >= 0 && idata < series[index].PointsData()->GetCount());
x = series[index].PointsData()->x(idata);
y = series[index].PointsData()->y(idata);
try {
x = series[index].PointsData()->x(idata);
y = series[index].PointsData()->y(idata);
} catch(ValueTypeError error) {
ASSERT_(true, error);
x = y = Null;
}
}
double ScatterDraw::GetValueX(int index, int64 idata) {
ASSERT(IsValid(index) && !IsNull(GetCount(index)));
ASSERT(idata >= 0 && idata < series[index].PointsData()->GetCount());
return series[index].PointsData()->x(idata);
try {
return series[index].PointsData()->x(idata);
} catch(ValueTypeError error) {
ASSERT_(true, error);
return Null;
}
}
double ScatterDraw::GetValueY(int index, int64 idata) {
ASSERT(IsValid(index) && !IsNull(GetCount(index)));
ASSERT(idata >= 0 && idata < series[index].PointsData()->GetCount());
return series[index].PointsData()->y(idata);
try {
return series[index].PointsData()->y(idata);
} catch(ValueTypeError error) {
ASSERT_(true, error);
return Null;
}
}
ScatterDraw &ScatterDraw::PlotStyle(SeriesPlot *data) {
@ -1098,7 +1125,7 @@ void ScatterDraw::DoZoom(double scale, bool mouseX, bool mouseY) {
return;
}
double oldYMin = yMin;
yMin += yRange*(1-scale)/2.;
yMin += yRange*(1 - scale)/2.;
yMinUnit = oldYMin + yMinUnit - yMin;
AdjustMinUnitY();
double oldYMin2 = yMin2;
@ -1576,7 +1603,7 @@ void FillPolylineOpa(Painter& w, const Vector<Point> &p, int scale, double opaci
}
void debug_h() {
; // Do nothing. Just to set a breakpoint in templated functions
; // It does nothing. Just to set a breakpoint in templated functions
}
INITBLOCK{

View file

@ -72,7 +72,7 @@ protected:
public:
ScatterSeries() {pD = 0;}
void SetDataSource(DataSource *pointsData, bool ownsData = true) {pD = pointsData; owns = ownsData;}
inline DataSource *PointsData() {return pD;}
inline DataSource *PointsData() {ASSERT_(!pD->IsDeleted(), "DataSource in ScatterCtrl/Draw has been deleted.\nIt has been probably declared in a function."); return pD;}
~ScatterSeries() {if(pD && owns) delete pD;}
private:
DataSource *pD;
@ -139,13 +139,13 @@ public:
ScatterDraw& ShowLegend(bool show = true) {showLegend = show; return *this;}
bool GetShowLegend() {return showLegend;}
ScatterDraw& SetLegendPos(const Point &pos) {legendPos = pos; showLegend = true; return *this;}
ScatterDraw& SetLegendPosX(int x) {legendPos.x = x; showLegend = true; return *this;}
ScatterDraw& SetLegendPosY(int y) {legendPos.y = y; showLegend = true; return *this;}
ScatterDraw& SetLegendPos(const Point &pos) {legendPos = pos; return *this;}
ScatterDraw& SetLegendPosX(int x) {legendPos.x = x; return *this;}
ScatterDraw& SetLegendPosY(int y) {legendPos.y = y; return *this;}
Point& GetLegendPos() {return legendPos;}
ScatterDraw& SetLegendNumCols(int num) {legendNumCols = num; showLegend = true; return *this;}
ScatterDraw& SetLegendNumCols(int num) {legendNumCols = num; return *this;}
int GetLegendNumCols() {return legendNumCols;}
ScatterDraw& SetLegendRowSpacing(int num) {legendRowSpacing = num; showLegend = true; return *this;}
ScatterDraw& SetLegendRowSpacing(int num) {legendRowSpacing = num;return *this;}
int GetLegendRowSpacing() {return legendRowSpacing;}
enum LEGEND_POS {
LEGEND_TOP,
@ -156,8 +156,8 @@ public:
};
ScatterDraw& SetLegendAnchor(int anchor) {legendAnchor = anchor; return *this;}
int GetLegendAnchor() {return legendAnchor;}
ScatterDraw& SetLegendFillColor(const Color &color) {legendFillColor = color; return *this;}
ScatterDraw& SetLegendBorderColor(const Color &color) {legendBorderColor = color; return *this;}
ScatterDraw& SetLegendFillColor(const Color &color) {legendFillColor = color; return *this;}
ScatterDraw& SetLegendBorderColor(const Color &color) {legendBorderColor = color; return *this;}
Color& GetLegendFillColor() {return legendFillColor;}
Color& GetLegendBorderColor() {return legendBorderColor;}
@ -196,7 +196,7 @@ public:
ScatterDraw &SetPolar(bool polar = true) {isPolar = polar; return *this;};
ScatterDraw &AddSeries(double *yData, int numData, double x0 = 0, double deltaX = 1)
ScatterDraw &AddSeries(double *yData, int numData, double x0, double deltaX)
{return AddSeries<CArray>(yData, numData, x0, deltaX);}
ScatterDraw &AddSeries(double *xData, double *yData, int numData)
{return AddSeries<CArray>(yData, xData, numData);}
@ -239,55 +239,55 @@ public:
{return _AddSeries(new C(arg1, arg2, arg3, arg4, arg5, arg6));}
template <class Y>
ScatterDraw &AddSeries(Vector<Y> &yData) {return _AddSeries(new VectorY<Y>(yData));}
ScatterDraw &AddSeries(Vector<Y> &yData, double x0, double deltaX) {return _AddSeries(new VectorY<Y>(yData, x0, deltaX));}
template <class Y>
ScatterDraw &AddSeries(Upp::Array<Y> &yData) {return _AddSeries(new ArrayY<Y>(yData));}
ScatterDraw &AddSeries(Upp::Array<Y> &yData, double x0, double deltaX) {return _AddSeries(new ArrayY<Y>(yData, x0, deltaX));}
template <class X, class Y>
ScatterDraw &AddSeries(VectorMap<X, Y> &data) {return _AddSeries(new VectorMapXY<X, Y>(data));}
template <class X, class Y>
ScatterDraw &AddSeries(ArrayMap<X, Y> &data) {return _AddSeries(new ArrayMapXY<X, Y>(data));}
void InsertSeries(int index, double *yData, int numData, double x0 = 0, double deltaX = 1);
void InsertSeries(int index, double *xData, double *yData, int numData);
void InsertSeries(int index, Vector<double> &xData, Vector<double> &yData);
void InsertSeries(int index, Upp::Array<double> &xData, Upp::Array<double> &yData);
void InsertSeries(int index, Vector<Pointf> &points);
void InsertSeries(int index, Upp::Array<Pointf> &points);
void InsertSeries(int index, double (*function)(double));
void InsertSeries(int index, Pointf (*function)(double), int np, double from = 0, double to = 1);
void InsertSeries(int index, PlotExplicFunc &function);
void InsertSeries(int index, PlotParamFunc function, int np, double from = 0, double to = 1);
void _InsertSeries(int index, DataSource *data);
ScatterDraw &InsertSeries(int index, double *yData, int numData, double x0 = 0, double deltaX = 1);
ScatterDraw &InsertSeries(int index, double *xData, double *yData, int numData);
ScatterDraw &InsertSeries(int index, Vector<double> &xData, Vector<double> &yData);
ScatterDraw &InsertSeries(int index, Upp::Array<double> &xData, Upp::Array<double> &yData);
ScatterDraw &InsertSeries(int index, Vector<Pointf> &points);
ScatterDraw &InsertSeries(int index, Upp::Array<Pointf> &points);
ScatterDraw &InsertSeries(int index, double (*function)(double));
ScatterDraw &InsertSeries(int index, Pointf (*function)(double), int np, double from = 0, double to = 1);
ScatterDraw &InsertSeries(int index, PlotExplicFunc &function);
ScatterDraw &InsertSeries(int index, PlotParamFunc function, int np, double from = 0, double to = 1);
ScatterDraw &_InsertSeries(int index, DataSource *data);
template <class C>
void InsertSeries(int index) {_InsertSeries(index, new C());}
ScatterDraw &InsertSeries(int index) {return _InsertSeries(index, new C());}
template <class C, class T1>
void InsertSeries(int index, T1 &arg1)
{_InsertSeries(index, new C(arg1));}
ScatterDraw &InsertSeries(int index, T1 &arg1)
{return _InsertSeries(index, new C(arg1));}
template <class C, class T1, class T2>
void InsertSeries(int index, T1 &arg1, T2 &arg2)
{_InsertSeries(index, new C(arg1, arg2));}
ScatterDraw &InsertSeries(int index, T1 &arg1, T2 &arg2)
{return _InsertSeries(index, new C(arg1, arg2));}
template <class C, class T1, class T2, class T3>
void InsertSeries(int index, T1 &arg1, T2 &arg2, T3 &arg3)
{_InsertSeries(index, new C(arg1, arg2, arg3));}
ScatterDraw &InsertSeries(int index, T1 &arg1, T2 &arg2, T3 &arg3)
{return _InsertSeries(index, new C(arg1, arg2, arg3));}
template <class C, class T1, class T2, class T3, class T4>
void InsertSeries(int index, T1 &arg1, T2 &arg2, T3 &arg3, T4 &arg4)
{_InsertSeries(index, new C(arg1, arg2, arg3, arg4));}
ScatterDraw &InsertSeries(int index, T1 &arg1, T2 &arg2, T3 &arg3, T4 &arg4)
{return _InsertSeries(index, new C(arg1, arg2, arg3, arg4));}
template <class C, class T1, class T2, class T3, class T4, class T5>
void InsertSeries(int index, T1 &arg1, T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5)
{_InsertSeries(index, new C(arg1, arg2, arg3, arg4, arg5));}
ScatterDraw &InsertSeries(int index, T1 &arg1, T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5)
{return _InsertSeries(index, new C(arg1, arg2, arg3, arg4, arg5));}
template <class C, class T1, class T2, class T3, class T4, class T5, class T6>
void InsertSeries(int index, T1 &arg1, T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5, T6 &arg6)
{_InsertSeries(index, new C(arg1, arg2, arg3, arg4, arg5, arg6));}
ScatterDraw &InsertSeries(int index, T1 &arg1, T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5, T6 &arg6)
{return _InsertSeries(index, new C(arg1, arg2, arg3, arg4, arg5, arg6));}
template <class Y>
void InsertSeries(int index, Vector<Y> &yData) {_InsertSeries(index, new VectorY<Y>(yData));}
ScatterDraw &InsertSeries(int index, Vector<Y> &yData, double x0, double deltaX) {return _InsertSeries(index, new VectorY<Y>(yData, x0, deltaX));}
template <class Y>
void InsertSeries(int index, Upp::Array<Y> &yData) {_InsertSeries(index, new ArrayY<Y>(yData));}
ScatterDraw &InsertSeries(int index, Upp::Array<Y> &yData, double x0, double deltaX) {return _InsertSeries(index, new ArrayY<Y>(yData, x0, deltaX));}
template <class X, class Y>
void InsertSeries(int index, VectorMap<X, Y> &data){_InsertSeries(index, new VectorMapXY<X, Y>(data));}
ScatterDraw &InsertSeries(int index, VectorMap<X, Y> &data) {return _InsertSeries(index, new VectorMapXY<X, Y>(data));}
template <class X, class Y>
void InsertSeries(int index, ArrayMap<X, Y> &data) {_InsertSeries(index, new ArrayMapXY<X, Y>(data));}
ScatterDraw &InsertSeries(int index, ArrayMap<X, Y> &data) {return _InsertSeries(index, new ArrayMapXY<X, Y>(data));}
int64 GetCount(int index);
void GetValues(int index, int64 idata, double &x, double &y);
@ -589,7 +589,7 @@ bool ScatterDraw::PlotTexts(T& w, const Size &size, int scale)
Size ly = GetTextSize(yLabel, fontLabel);
Size ly2 = GetTextSize(yLabel2, italicLabel);
DrawText(w, (plotW - lx.cx)/2., plotH + scale*(vPlotBottom - 2) - lx.cy, 0, xLabel, fontLabel, labelsColor);
DrawText(w, scale*(2 - hPlotLeft), (plotH + ly.cx)/2., 900, yLabel, fontLabel, labelsColor);
DrawText(w, scale*(2 - hPlotLeft), (plotH + ly.cx)/2., 900, yLabel, fontLabel, labelsColor);
DrawText(w, scale*(size.cx - 2) - ly2.cy - hPlotLeft, (plotH + ly2.cx)/2., 900, yLabel2, italicLabel, labelsColor);
drawXReticle &= (xRange != 0 && xMajorUnit != 0);
@ -731,100 +731,121 @@ void ScatterDraw::Plot(T& w, const Size &size, int scale)
}
if (!series.IsEmpty()) {
for (int j = 0; j < series.GetCount(); j++) {
if (series[j].opacity == 0 || (!series[j].seriesPlot && !series[j].markPlot) ||
(!series[j].PointsData()->IsExplicit() && series[j].PointsData()->GetCount() == 0))
continue;
Vector<Point> points;
if (series[j].PointsData()->IsParam()) {
double xmin = 0;
double xmax = double(series[j].PointsData()->GetCount());
for (double x = xmin; x <= xmax; x++) {
double xx = series[j].PointsData()->x(x);
double yy = series[j].PointsData()->y(x);
int ix = fround(plotW*(xx - xMin)/xRange);
int iy;
if (series[j].primaryY)
iy = fround(plotH*(yy - yMin)/yRange);
else
iy = fround(plotH*(yy - yMin2)/yRange2);
points << Point(ix, plotH - iy);
}
} else if (series[j].PointsData()->IsExplicit()) {
double xmin = xMin - 1;
double xmax = xMin + xRange + 1;
double dx = double(xmax - xmin)/plotW;
for (double xx = xmin; xx < xmax; xx += dx) {
double yy = series[j].PointsData()->f(xx);
int ix = fround(plotW*(xx - xMin)/xRange);
int iy;
if (series[j].primaryY)
iy = fround(plotH*(yy - yMin)/yRange);
else
iy = fround(plotH*(yy - yMin2)/yRange2);
points << Point(ix, plotH - iy);
}
} else {
int64 imin, imax;
if (series[j].sequential) {
imin = imax = Null;
for (int64 i = 1; i < series[j].PointsData()->GetCount() - 1; ++i) {
if (IsNull(imin)) {
if (series[j].PointsData()->x(i) >= xMin)
imin = i - 1;
} else if (IsNull(imax)) {
if (series[j].PointsData()->x(i) >= xMin + xRange)
imax = i + 1;
}
try {
for (int j = 0; j < series.GetCount(); j++) {
if (series[j].opacity == 0 || (!series[j].seriesPlot && !series[j].markPlot) ||
(!series[j].PointsData()->IsExplicit() && series[j].PointsData()->GetCount() == 0))
continue;
Vector<Point> points;
if (series[j].PointsData()->IsParam()) {
double xmin = 0;
double xmax = double(series[j].PointsData()->GetCount());
for (double x = xmin; x <= xmax; x++) {
double xx = series[j].PointsData()->x(x);
double yy = series[j].PointsData()->y(x);
if (IsNull(xx) || IsNull(yy))
continue;
int ix = fround(plotW*(xx - xMin)/xRange);
int iy;
if (series[j].primaryY)
iy = fround(plotH*(yy - yMin)/yRange);
else
iy = fround(plotH*(yy - yMin2)/yRange2);
points << Point(ix, plotH - iy);
}
} else if (series[j].PointsData()->IsExplicit()) {
double xmin = xMin - 1;
double xmax = xMin + xRange + 1;
double dx = double(xmax - xmin)/plotW;
for (double xx = xmin; xx < xmax; xx += dx) {
double yy = series[j].PointsData()->f(xx);
if (IsNull(yy))
continue;
int ix = fround(plotW*(xx - xMin)/xRange);
int iy;
if (series[j].primaryY)
iy = fround(plotH*(yy - yMin)/yRange);
else
iy = fround(plotH*(yy - yMin2)/yRange2);
points << Point(ix, plotH - iy);
}
if (IsNull(imin))
imin = 0;
if (IsNull(imax))
imax = series[j].PointsData()->GetCount() - 1;
} else {
imin = 0;
imax = series[j].PointsData()->GetCount();
}
double dxpix;
if (fastViewX)
dxpix = (series[j].PointsData()->x(imax) - series[j].PointsData()->x(imin))/plotW;
int npix = 1;
for (int64 i = imin; i < imax; ) {
double xx, yy;
if (fastViewX) {
yy = series[j].PointsData()->y(i);
int64 ii;
double maxv = dxpix*npix;
for (ii = 1; series[j].PointsData()->x(i + ii) < maxv && i + ii < imax; ++ii)
yy += series[j].PointsData()->y(i + ii);
yy /= double(ii);
xx = series[j].PointsData()->x(i);
i += ii;
npix++;
int64 imin, imax;
if (series[j].sequential) {
imin = imax = Null;
for (int64 i = 1; i < series[j].PointsData()->GetCount() - 1; ++i) {
double xx = series[j].PointsData()->x(i);
if (IsNull(xx))
continue;
if (IsNull(imin)) {
if (xx >= xMin)
imin = i - 1;
} else if (IsNull(imax)) {
if (xx >= xMin + xRange)
imax = i + 1;
}
}
if (IsNull(imin))
imin = 0;
if (IsNull(imax))
imax = series[j].PointsData()->GetCount() - 1;
} else {
xx = series[j].PointsData()->x(i);
yy = series[j].PointsData()->y(i);
++i;
imin = 0;
imax = series[j].PointsData()->GetCount();
}
int ix = fround(plotW*(xx - xMin)/xRange);
int iy;
if (series[j].primaryY)
iy = fround(plotH*(yy - yMin)/yRange);
else
iy = fround(plotH*(yy - yMin2)/yRange2);
points << Point(ix, plotH - iy);
double dxpix;
if (fastViewX)
dxpix = (series[j].PointsData()->x(imax) - series[j].PointsData()->x(imin))/plotW;
int npix = 1;
for (int64 i = imin; i < imax; ) {
double xx, yy;
if (fastViewX) {
yy = series[j].PointsData()->y(i);
if (IsNull(yy))
continue;
int64 ii;
double maxv = dxpix*npix;
for (ii = 1; series[j].PointsData()->x(i + ii) < maxv && i + ii < imax; ++ii) {
double dd = series[j].PointsData()->y(i + ii);
if (IsNull(dd))
continue;
yy += dd;
}
yy /= double(ii);
xx = series[j].PointsData()->x(i);
if (IsNull(xx))
continue;
i += ii;
npix++;
} else {
xx = series[j].PointsData()->x(i);
yy = series[j].PointsData()->y(i);
++i;
if (IsNull(xx) || IsNull(yy))
continue;
}
int ix = fround(plotW*(xx - xMin)/xRange);
int iy;
if (series[j].primaryY)
iy = fround(plotH*(yy - yMin)/yRange);
else
iy = fround(plotH*(yy - yMin2)/yRange2);
points << Point(ix, plotH - iy);
}
}
if (!points.IsEmpty() && series[j].seriesPlot)
series[j].seriesPlot->Paint(w, points, scale, series[j].opacity,
fround(series[j].thickness), series[j].color,
series[j].dash, plotAreaColor, series[j].fillColor, plotW/xRange, plotH/yRange,
int(plotH*(1 + yMin/yRange)));
if (series[j].markWidth >= 1 && series[j].markPlot) {
for (int i = 0; i < points.GetCount(); i++)
series[j].markPlot->Paint(w, scale, points[i], series[j].markWidth, series[j].markColor);
}
}
if (!points.IsEmpty() && series[j].seriesPlot)
series[j].seriesPlot->Paint(w, points, scale, series[j].opacity,
fround(series[j].thickness), series[j].color,
series[j].dash, plotAreaColor, series[j].fillColor, plotW/xRange, plotH/yRange,
int(plotH*(1 + yMin/yRange)));
if (series[j].markWidth >= 1 && series[j].markPlot) {
for (int i = 0; i < points.GetCount(); i++)
series[j].markPlot->Paint(w, scale, points[i], series[j].markWidth, series[j].markColor);
}
} catch(ValueTypeError error) {
ASSERT_(true, error);
}
}
ClipEnd(w);

View file

@ -24,6 +24,12 @@ esES("Polinomio")
euES("Polinomio")
frFR("Polyn\303\264me")
T_("Sinusoidal")
caES("")
esES("")
euES("")
frFR("")
T_("Fourier")
caES("")
esES("")