mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
ScatterDraw: Improvements and bug fixes
git-svn-id: svn://ultimatepp.org/upp/trunk@7672 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
55d8b70bb1
commit
55038caed5
5 changed files with 327 additions and 226 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@ esES("Polinomio")
|
|||
euES("Polinomio")
|
||||
frFR("Polyn\303\264me")
|
||||
|
||||
T_("Sinusoidal")
|
||||
caES("")
|
||||
esES("")
|
||||
euES("")
|
||||
frFR("")
|
||||
|
||||
T_("Fourier")
|
||||
caES("")
|
||||
esES("")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue