diff --git a/uppsrc/ScatterDraw/DataSource.h b/uppsrc/ScatterDraw/DataSource.h index cdf90699a..3a983c040 100644 --- a/uppsrc/ScatterDraw/DataSource.h +++ b/uppsrc/ScatterDraw/DataSource.h @@ -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 &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 @@ -75,9 +82,12 @@ private: public: ArrayY(Upp::Array &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 @@ -138,7 +148,7 @@ public: VectorDouble(const Vector &yData, Vector &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 &yData, Upp::Array &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 { diff --git a/uppsrc/ScatterDraw/Equation.h b/uppsrc/ScatterDraw/Equation.h index 1c40eb903..a0f4daba4 100644 --- a/uppsrc/ScatterDraw/Equation.h +++ b/uppsrc/ScatterDraw/Equation.h @@ -61,13 +61,26 @@ public: class PolynomialEquation : public ExplicitEquation { public: - PolynomialEquation() {} - PolynomialEquation(const Array& c) {SetCoeff(c);} + PolynomialEquation() {} + PolynomialEquation(const Array& 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 diff --git a/uppsrc/ScatterDraw/ScatterDraw.cpp b/uppsrc/ScatterDraw/ScatterDraw.cpp index 8284d9494..4cc6229bc 100644 --- a/uppsrc/ScatterDraw/ScatterDraw.cpp +++ b/uppsrc/ScatterDraw/ScatterDraw.cpp @@ -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(index, yData, numData, x0, deltaX); +ScatterDraw &ScatterDraw::InsertSeries(int index, double *yData, int numData, double x0, double deltaX) { + return InsertSeries(index, yData, numData, x0, deltaX); } -void ScatterDraw::InsertSeries(int index, double *xData, double *yData, int numData) { - InsertSeries(index, xData, yData, numData); +ScatterDraw &ScatterDraw::InsertSeries(int index, double *xData, double *yData, int numData) { + return InsertSeries(index, xData, yData, numData); } -void ScatterDraw::InsertSeries(int index, Vector &xData, Vector &yData) { - InsertSeries(index, xData, yData); +ScatterDraw &ScatterDraw::InsertSeries(int index, Vector &xData, Vector &yData) { + return InsertSeries(index, xData, yData); } -void ScatterDraw::InsertSeries(int index, Array &xData, Array &yData) { - InsertSeries(index, xData, yData); +ScatterDraw &ScatterDraw::InsertSeries(int index, Array &xData, Array &yData) { + return InsertSeries(index, xData, yData); } -void ScatterDraw::InsertSeries(int index, Vector &points) { - InsertSeries(index, points); +ScatterDraw &ScatterDraw::InsertSeries(int index, Vector &points) { + return InsertSeries(index, points); } -void ScatterDraw::InsertSeries(int index, Array &points) { - InsertSeries(index, points); +ScatterDraw &ScatterDraw::InsertSeries(int index, Array &points) { + return InsertSeries(index, points); } -void ScatterDraw::InsertSeries(int index, double (*function)(double)) { - InsertSeries(index, function); +ScatterDraw &ScatterDraw::InsertSeries(int index, double (*function)(double)) { + return InsertSeries(index, function); } -void ScatterDraw::InsertSeries(int index, Pointf (*function)(double), int np, double from, double to) { - InsertSeries(index, function, np, from, to); +ScatterDraw &ScatterDraw::InsertSeries(int index, Pointf (*function)(double), int np, double from, double to) { + return InsertSeries(index, function, np, from, to); } -void ScatterDraw::InsertSeries(int index, PlotExplicFunc &function) { - InsertSeries(index, function); +ScatterDraw &ScatterDraw::InsertSeries(int index, PlotExplicFunc &function) { + return InsertSeries(index, function); } -void ScatterDraw::InsertSeries(int index, PlotParamFunc function, int np, double from, double to) { - InsertSeries(index, function, np, from, to); +ScatterDraw &ScatterDraw::InsertSeries(int index, PlotParamFunc function, int np, double from, double to) { + return InsertSeries(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 &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{ diff --git a/uppsrc/ScatterDraw/ScatterDraw.h b/uppsrc/ScatterDraw/ScatterDraw.h index c503fe498..debb61ea2 100644 --- a/uppsrc/ScatterDraw/ScatterDraw.h +++ b/uppsrc/ScatterDraw/ScatterDraw.h @@ -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(yData, numData, x0, deltaX);} ScatterDraw &AddSeries(double *xData, double *yData, int numData) {return AddSeries(yData, xData, numData);} @@ -239,55 +239,55 @@ public: {return _AddSeries(new C(arg1, arg2, arg3, arg4, arg5, arg6));} template - ScatterDraw &AddSeries(Vector &yData) {return _AddSeries(new VectorY(yData));} + ScatterDraw &AddSeries(Vector &yData, double x0, double deltaX) {return _AddSeries(new VectorY(yData, x0, deltaX));} template - ScatterDraw &AddSeries(Upp::Array &yData) {return _AddSeries(new ArrayY(yData));} + ScatterDraw &AddSeries(Upp::Array &yData, double x0, double deltaX) {return _AddSeries(new ArrayY(yData, x0, deltaX));} template ScatterDraw &AddSeries(VectorMap &data) {return _AddSeries(new VectorMapXY(data));} template ScatterDraw &AddSeries(ArrayMap &data) {return _AddSeries(new ArrayMapXY(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 &xData, Vector &yData); - void InsertSeries(int index, Upp::Array &xData, Upp::Array &yData); - void InsertSeries(int index, Vector &points); - void InsertSeries(int index, Upp::Array &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 &xData, Vector &yData); + ScatterDraw &InsertSeries(int index, Upp::Array &xData, Upp::Array &yData); + ScatterDraw &InsertSeries(int index, Vector &points); + ScatterDraw &InsertSeries(int index, Upp::Array &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 - void InsertSeries(int index) {_InsertSeries(index, new C());} + ScatterDraw &InsertSeries(int index) {return _InsertSeries(index, new C());} template - void InsertSeries(int index, T1 &arg1) - {_InsertSeries(index, new C(arg1));} + ScatterDraw &InsertSeries(int index, T1 &arg1) + {return _InsertSeries(index, new C(arg1));} template - 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 - 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 - 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 - 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 - 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 - void InsertSeries(int index, Vector &yData) {_InsertSeries(index, new VectorY(yData));} + ScatterDraw &InsertSeries(int index, Vector &yData, double x0, double deltaX) {return _InsertSeries(index, new VectorY(yData, x0, deltaX));} template - void InsertSeries(int index, Upp::Array &yData) {_InsertSeries(index, new ArrayY(yData));} + ScatterDraw &InsertSeries(int index, Upp::Array &yData, double x0, double deltaX) {return _InsertSeries(index, new ArrayY(yData, x0, deltaX));} template - void InsertSeries(int index, VectorMap &data){_InsertSeries(index, new VectorMapXY(data));} + ScatterDraw &InsertSeries(int index, VectorMap &data) {return _InsertSeries(index, new VectorMapXY(data));} template - void InsertSeries(int index, ArrayMap &data) {_InsertSeries(index, new ArrayMapXY(data));} + ScatterDraw &InsertSeries(int index, ArrayMap &data) {return _InsertSeries(index, new ArrayMapXY(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 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 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); diff --git a/uppsrc/ScatterDraw/ScatterDraw.t b/uppsrc/ScatterDraw/ScatterDraw.t index 28e35a606..1f6614802 100644 --- a/uppsrc/ScatterDraw/ScatterDraw.t +++ b/uppsrc/ScatterDraw/ScatterDraw.t @@ -24,6 +24,12 @@ esES("Polinomio") euES("Polinomio") frFR("Polyn\303\264me") +T_("Sinusoidal") +caES("") +esES("") +euES("") +frFR("") + T_("Fourier") caES("") esES("")