mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps/regression] Fix regression
This commit is contained in:
@@ -32,7 +32,7 @@ App * App::Snapshot::unpack(Container * container) {
|
||||
}
|
||||
|
||||
void App::Snapshot::reset() {
|
||||
m_store.deleteAllPairsOfAllSeries();
|
||||
m_store.deleteAllPairs();
|
||||
m_store.setDefault();
|
||||
m_modelVersion = 0;
|
||||
m_rangeVersion = 0;
|
||||
|
||||
@@ -163,7 +163,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int
|
||||
}
|
||||
if (i == 1 && j > k_totalNumberOfDoubleBufferRows) {
|
||||
assert(j != 9);
|
||||
CalculPointer calculationMethods[k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows] = {&Store::numberOfPairs, &Store::covariance,
|
||||
CalculPointer calculationMethods[k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows] = {&Store::doubleCastedNumberOfPairsOfSeries, &Store::covariance,
|
||||
&Store::columnProductSum, nullptr, &Store::slope, &Store::yIntercept, &Store::correlationCoefficient, &Store::squaredCorrelationCoefficient};
|
||||
double calculation = (m_store->*calculationMethods[j-k_totalNumberOfDoubleBufferRows-1])();
|
||||
EvenOddBufferTextCell * myCell = (EvenOddBufferTextCell *)cell;
|
||||
|
||||
@@ -26,10 +26,15 @@ ViewController * GraphController::initialisationParameterController() {
|
||||
}
|
||||
|
||||
bool GraphController::isEmpty() const {
|
||||
if (m_store->numberOfPairs() < 2 || std::isinf(m_store->slope()) || std::isnan(m_store->slope())) {
|
||||
if (m_store->isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
for (int series = 0; series < FloatPairStore::k_numberOfSeries; series++) {
|
||||
if (!m_store->seriesIsEmpty(series) && !std::isinf(m_store->slope(series)) && (std::isnan(m_store->slope(series)))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
I18n::Message GraphController::emptyMessage() {
|
||||
|
||||
@@ -9,7 +9,8 @@ GraphView::GraphView(Store * store, CurveViewCursor * cursor, BannerView * banne
|
||||
CurveView(store, cursor, bannerView, cursorView),
|
||||
m_store(store),
|
||||
m_xLabels{},
|
||||
m_yLabels{}
|
||||
m_yLabels{},
|
||||
m_series(0) //TODO
|
||||
{
|
||||
}
|
||||
|
||||
@@ -20,17 +21,17 @@ void GraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
drawAxes(ctx, rect, Axis::Vertical);
|
||||
drawLabels(ctx, rect, Axis::Horizontal, true);
|
||||
drawLabels(ctx, rect, Axis::Vertical, true);
|
||||
float regressionParameters[2] = {(float)m_store->slope(), (float)m_store->yIntercept()};
|
||||
float regressionParameters[2] = {(float)m_store->slope(m_series), (float)m_store->yIntercept(m_series)};
|
||||
drawCurve(ctx, rect, [](float abscissa, void * model, void * context) {
|
||||
float * params = (float *)model;
|
||||
return params[0]*abscissa+params[1];
|
||||
},
|
||||
regressionParameters, nullptr, Palette::YellowDark);
|
||||
for (int index = 0; index < m_store->numberOfPairs(); index++) {
|
||||
drawDot(ctx, rect, m_store->get(0,index), m_store->get(1,index), Palette::Red);
|
||||
drawDot(ctx, rect, m_store->get(m_series, 0,index), m_store->get(m_series, 1,index), Palette::Red);
|
||||
}
|
||||
drawDot(ctx, rect, m_store->meanOfColumn(0), m_store->meanOfColumn(1), Palette::Palette::YellowDark, true);
|
||||
drawDot(ctx, rect, m_store->meanOfColumn(0), m_store->meanOfColumn(1), KDColorWhite);
|
||||
drawDot(ctx, rect, m_store->meanOfColumn(m_series, 0), m_store->meanOfColumn(m_series, 1), Palette::Palette::YellowDark, true);
|
||||
drawDot(ctx, rect, m_store->meanOfColumn(m_series, 0), m_store->meanOfColumn(m_series, 1), KDColorWhite);
|
||||
}
|
||||
|
||||
char * GraphView::label(Axis axis, int index) const {
|
||||
|
||||
@@ -17,6 +17,7 @@ private:
|
||||
Store * m_store;
|
||||
char m_xLabels[k_maxNumberOfXLabels][Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
|
||||
char m_yLabels[k_maxNumberOfYLabels][Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
|
||||
int m_series;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@ using namespace Shared;
|
||||
|
||||
namespace Regression {
|
||||
|
||||
static inline float max(float x, float y) { return (x>y ? x : y); }
|
||||
static inline float min(float x, float y) { return (x<y ? x : y); }
|
||||
|
||||
Store::Store() :
|
||||
InteractiveCurveViewRange(nullptr, this),
|
||||
FloatPairStore()
|
||||
@@ -16,7 +19,7 @@ Store::Store() :
|
||||
|
||||
/* Dots */
|
||||
|
||||
int Store::closestVerticalDot(int series, int direction, float x) {
|
||||
int Store::closestVerticalDot(int direction, float x) {
|
||||
float nextX = INFINITY;
|
||||
float nextY = INFINITY;
|
||||
int selectedDot = -1;
|
||||
@@ -25,82 +28,87 @@ int Store::closestVerticalDot(int series, int direction, float x) {
|
||||
* - the next dot is the closest one in abscissa to x
|
||||
* - the next dot is above the regression curve if direction == 1 and below
|
||||
* otherwise */
|
||||
for (int index = 0; index < m_numberOfPairs[series]; index++) {
|
||||
if ((m_xMin <= m_data[series][0][index] && m_data[series][0][index] <= m_xMax) &&
|
||||
(std::fabs(m_data[series][0][index] - x) < std::fabs(nextX - x)) &&
|
||||
((m_data[series][1][index] - yValueForXValue(m_data[series][0][index]) >= 0) == (direction > 0))) {
|
||||
// Handle edge case: if 2 dots have the same abscissa but different ordinates
|
||||
if (nextX != m_data[series][0][index] || ((nextY - m_data[series][1][index] >= 0) == (direction > 0))) {
|
||||
nextX = m_data[series][0][index];
|
||||
nextY = m_data[series][1][index];
|
||||
selectedDot = index;
|
||||
for (int series = 0; series < k_numberOfSeries; series ++) {
|
||||
if (!seriesIsEmpty(series)) {
|
||||
for (int index = 0; index < numberOfPairsOfSeries(series); index++) {
|
||||
if ((m_xMin <= m_data[series][0][index] && m_data[series][0][index] <= m_xMax) &&
|
||||
(std::fabs(m_data[series][0][index] - x) < std::fabs(nextX - x)) &&
|
||||
((m_data[series][1][index] - yValueForXValue(series, m_data[series][0][index]) >= 0) == (direction > 0))) {
|
||||
// Handle edge case: if 2 dots have the same abscissa but different ordinates
|
||||
if (nextX != m_data[series][0][index] || ((nextY - m_data[series][1][index] >= 0) == (direction > 0))) {
|
||||
nextX = m_data[series][0][index];
|
||||
nextY = m_data[series][1][index];
|
||||
selectedDot = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Compare with the mean dot
|
||||
double meanX = meanOfColumn(series, 0);
|
||||
double meanY = meanOfColumn(series, 1);
|
||||
if (m_xMin <= meanX && meanX <= m_xMax &&
|
||||
(std::fabs(meanX - x) < std::fabs(nextX - x)) &&
|
||||
((meanY - yValueForXValue(meanX) >= 0) == (direction > 0))) {
|
||||
if (nextX != meanX || ((nextY - meanY >= 0) == (direction > 0))) {
|
||||
selectedDot = m_numberOfPairs[series];
|
||||
// Compare with the mean dot
|
||||
double meanX = meanOfColumn(series, 0);
|
||||
double meanY = meanOfColumn(series, 1);
|
||||
if (m_xMin <= meanX && meanX <= m_xMax &&
|
||||
(std::fabs(meanX - x) < std::fabs(nextX - x)) &&
|
||||
((meanY - yValueForXValue(series, meanX) >= 0) == (direction > 0))) {
|
||||
if (nextX != meanX || ((nextY - meanY >= 0) == (direction > 0))) {
|
||||
selectedDot = numberOfPairsOfSeries(series);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return selectedDot;
|
||||
}
|
||||
|
||||
int Store::nextDot(int direction, int dot) {
|
||||
int Store::nextDot(int series, int direction, int dot) {
|
||||
float nextX = INFINITY;
|
||||
int selectedDot = -1;
|
||||
double meanX = meanOfColumn(series, 0);
|
||||
float x = meanX;
|
||||
if (dot >= 0 && dot < m_numberOfPairs[series]) {
|
||||
x = get(0, dot);
|
||||
if (dot >= 0 && dot < numberOfPairsOfSeries(series)) {
|
||||
x = get(series, 0, dot);
|
||||
}
|
||||
/* We have to scan the Store in opposite ways for the 2 directions to ensure to
|
||||
* select all dots (even with equal abscissa) */
|
||||
if (direction > 0) {
|
||||
for (int index = 0; index < m_numberOfPairs[series]; index++) {
|
||||
for (int index = 0; index < numberOfPairsOfSeries(series); index++) {
|
||||
/* The conditions to test are in this order:
|
||||
* - the next dot is the closest one in abscissa to x
|
||||
* - the next dot is not the same as the selected one
|
||||
* - the next dot is at the right of the selected one */
|
||||
if (std::fabs(m_date[series][0][index] - x) < std::fabs(nextX - x) &&
|
||||
if (std::fabs(m_data[series][0][index] - x) < std::fabs(nextX - x) &&
|
||||
(index != dot) &&
|
||||
(m_date[series][0][index] >= x)) {
|
||||
(m_data[series][0][index] >= x)) {
|
||||
// Handle edge case: 2 dots have same abscissa
|
||||
if (m_date[series][0][index] != x || (index > dot)) {
|
||||
nextX = m_date[series][0][index];
|
||||
if (m_data[series][0][index] != x || (index > dot)) {
|
||||
nextX = m_data[series][0][index];
|
||||
selectedDot = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Compare with the mean dot
|
||||
if (std::fabs(meanX - x) < std::fabs(nextX - x) &&
|
||||
(m_numberOfPairs[series] != dot) &&
|
||||
(numberOfPairsOfSeries(series) != dot) &&
|
||||
(meanX >= x)) {
|
||||
if (meanX != x || (x > dot)) {
|
||||
selectedDot = m_numberOfPairs[series];
|
||||
selectedDot = numberOfPairsOfSeries(series);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Compare with the mean dot
|
||||
if (std::fabs(meanX - x) < std::fabs(nextX - x) &&
|
||||
(m_numberOfPairs[series] != dot) &&
|
||||
(numberOfPairsOfSeries(series) != dot) &&
|
||||
(meanX <= x)) {
|
||||
if (meanX != x || (m_numberOfPairs[series] < dot)) {
|
||||
if (meanX != x || (numberOfPairsOfSeries(series) < dot)) {
|
||||
nextX = meanX;
|
||||
selectedDot = m_numberOfPairs[series];
|
||||
selectedDot = numberOfPairsOfSeries(series);
|
||||
}
|
||||
}
|
||||
for (int index = m_numberOfPairs[series]-1; index >= 0; index--) {
|
||||
if (std::fabs(m_date[series][0][index] - x) < std::fabs(nextX - x) &&
|
||||
for (int index = numberOfPairsOfSeries(series)-1; index >= 0; index--) {
|
||||
if (std::fabs(m_data[series][0][index] - x) < std::fabs(nextX - x) &&
|
||||
(index != dot) &&
|
||||
(m_date[series][0][index] <= x)) {
|
||||
(m_data[series][0][index] <= x)) {
|
||||
// Handle edge case: 2 dots have same abscissa
|
||||
if (m_date[series][0][index] != x || (index < dot)) {
|
||||
nextX = m_date[series][0][index];
|
||||
if (m_data[series][0][index] != x || (index < dot)) {
|
||||
nextX = m_data[series][0][index];
|
||||
selectedDot = index;
|
||||
}
|
||||
}
|
||||
@@ -111,115 +119,132 @@ int Store::nextDot(int direction, int dot) {
|
||||
|
||||
/* Window */
|
||||
|
||||
void Store::setDefault(int series) {
|
||||
float min = minValueOfColumn(series, 0);
|
||||
float max = maxValueOfColumn(series, 0);
|
||||
float range = max - min;
|
||||
setXMin(min - k_displayLeftMarginRatio*range);
|
||||
setXMax(max + k_displayRightMarginRatio*range);
|
||||
void Store::setDefault() {
|
||||
float minX = FLT_MAX;
|
||||
float maxX = -FLT_MAX;
|
||||
for (int series = 0; series < k_numberOfSeries; series ++) {
|
||||
if (!seriesIsEmpty(series)) {
|
||||
minX = min(minX, minValueOfColumn(series, 0));
|
||||
maxX = max(maxX, maxValueOfColumn(series, 0));
|
||||
}
|
||||
}
|
||||
float range = maxX - minX;
|
||||
setXMin(minX - k_displayLeftMarginRatio*range);
|
||||
setXMax(maxX + k_displayRightMarginRatio*range);
|
||||
setYAuto(true);
|
||||
}
|
||||
|
||||
bool Store::isEmpty() const {
|
||||
for (int i = 0; i < k_numberOfSeries; i ++) {
|
||||
if (!seriesIsEmpty(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Store::seriesIsEmpty(int series) const {
|
||||
return numberOfPairsOfSeries(series) < 2;
|
||||
}
|
||||
|
||||
/* Calculations */
|
||||
|
||||
float Store::maxValueOfColumn(int series, int i) {
|
||||
float max = -FLT_MAX;
|
||||
for (int k = 0; k < m_numberOfPairs[series]; k++) {
|
||||
if (m_data[series][i][k] > max) {
|
||||
max = m_data[series][i][k];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
double Store::doubleCastedNumberOfPairsOfSeries(int series) const {
|
||||
return FloatPairStore::numberOfPairsOfSeries(series);
|
||||
}
|
||||
|
||||
float Store::minValueOfColumn(int series, int i) {
|
||||
float min = FLT_MAX;
|
||||
for (int k = 0; k < m_numberOfPairs[series]; k++) {
|
||||
if (m_data[series][i][k] < min) {
|
||||
min = m_data[series][i][k];
|
||||
}
|
||||
float Store::maxValueOfColumn(int series, int i) const {
|
||||
float maxColumn = -FLT_MAX;
|
||||
for (int k = 0; k < numberOfPairsOfSeries(series); k++) {
|
||||
maxColumn = max(maxColumn, m_data[series][i][k]);
|
||||
}
|
||||
return min;
|
||||
return maxColumn;
|
||||
}
|
||||
|
||||
double Store::squaredValueSumOfColumn(int series, int i) {
|
||||
float Store::minValueOfColumn(int series, int i) const {
|
||||
float minColumn = FLT_MAX;
|
||||
for (int k = 0; k < numberOfPairsOfSeries(series); k++) {
|
||||
minColumn = min(minColumn, m_data[series][i][k]);
|
||||
}
|
||||
return minColumn;
|
||||
}
|
||||
|
||||
double Store::squaredValueSumOfColumn(int series, int i) const {
|
||||
double result = 0;
|
||||
for (int k = 0; k < m_numberOfPairs[series]; k++) {
|
||||
for (int k = 0; k < numberOfPairsOfSeries(series); k++) {
|
||||
result += m_data[series][i][k]*m_data[series][i][k];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double Store::columnProductSum(int series) {
|
||||
double Store::columnProductSum(int series) const {
|
||||
double result = 0;
|
||||
for (int k = 0; k < m_numberOfPairs[series]; k++) {
|
||||
result += m_date[series][0][k]*m_date[series][1][k];
|
||||
for (int k = 0; k < numberOfPairsOfSeries(series); k++) {
|
||||
result += m_data[series][0][k]*m_data[series][1][k];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double Store::meanOfColumn(int series, int i) {
|
||||
return m_numberOfPairs[series] == 0 ? 0 : sumOfColumn(series, i)/m_numberOfPairs[series];
|
||||
double Store::meanOfColumn(int series, int i) const {
|
||||
return numberOfPairsOfSeries(series) == 0 ? 0 : sumOfColumn(series, i)/numberOfPairsOfSeries(series);
|
||||
}
|
||||
|
||||
double Store::varianceOfColumn(int series, int i) {
|
||||
double Store::varianceOfColumn(int series, int i) const {
|
||||
double mean = meanOfColumn(series, i);
|
||||
return squaredValueSumOfColumn(series, i)/m_numberOfPairs[series] - mean*mean;
|
||||
return squaredValueSumOfColumn(series, i)/numberOfPairsOfSeries(series) - mean*mean;
|
||||
}
|
||||
|
||||
double Store::standardDeviationOfColumn(int series, int i) {
|
||||
double Store::standardDeviationOfColumn(int series, int i) const {
|
||||
return std::sqrt(varianceOfColumn(series, i));
|
||||
}
|
||||
|
||||
double Store::covariance(int series) {
|
||||
return columnProductSum(series)/m_numberOfPairs[series] - meanOfColumn(series, 0)*meanOfColumn(series, 1);
|
||||
double Store::covariance(int series) const {
|
||||
return columnProductSum(series)/numberOfPairsOfSeries(series) - meanOfColumn(series, 0)*meanOfColumn(series, 1);
|
||||
}
|
||||
|
||||
double Store::slope(int series) {
|
||||
double Store::slope(int series) const {
|
||||
return covariance(series)/varianceOfColumn(series, 0);
|
||||
}
|
||||
|
||||
double Store::yIntercept(int series) {
|
||||
double Store::yIntercept(int series) const {
|
||||
return meanOfColumn(series, 1) - slope(series)*meanOfColumn(series, 0);
|
||||
}
|
||||
|
||||
double Store::yValueForXValue(int series, double x) {
|
||||
double Store::yValueForXValue(int series, double x) const {
|
||||
return slope(series)*x+yIntercept(series);
|
||||
}
|
||||
|
||||
double Store::xValueForYValue(int series, double y) {
|
||||
double Store::xValueForYValue(int series, double y) const {
|
||||
return std::fabs(slope(series)) < DBL_EPSILON ? NAN : (y - yIntercept(series))/slope(series);
|
||||
}
|
||||
|
||||
double Store::correlationCoefficient(int series) {
|
||||
double Store::correlationCoefficient(int series) const {
|
||||
double sd0 = standardDeviationOfColumn(series, 0);
|
||||
double sd1 = standardDeviationOfColumn(series, 1);
|
||||
return (sd0 == 0.0 || sd1 == 0.0) ? 1.0 : covariance(series)/(sd0*sd1);
|
||||
}
|
||||
|
||||
double Store::squaredCorrelationCoefficient(int series) {
|
||||
double Store::squaredCorrelationCoefficient(int series) const {
|
||||
double cov = covariance(series);
|
||||
double v0 = varianceOfColumn(series, 0);
|
||||
double v1 = varianceOfColumn(series, 1);
|
||||
return (v0 == 0.0 || v1 == 0.0) ? 1.0 : cov*cov/(v0*v1);
|
||||
}
|
||||
|
||||
InteractiveCurveViewRangeDelegate::Range Store::computeYRange(int series, InteractiveCurveViewRange * interactiveCurveViewRange) {
|
||||
float min = FLT_MAX;
|
||||
float max = -FLT_MAX;
|
||||
for (int k = 0; k < m_numberOfPairs[series]; k++) {
|
||||
if (m_xMin <= m_date[series][0][k] && m_date[series][0][k] <= m_xMax) {
|
||||
if (m_date[series][1][k] < min) {
|
||||
min = m_date[series][1][k];
|
||||
}
|
||||
if (m_date[series][1][k] > max) {
|
||||
max = m_date[series][1][k];
|
||||
InteractiveCurveViewRangeDelegate::Range Store::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) {
|
||||
float minY = FLT_MAX;
|
||||
float maxY = -FLT_MAX;
|
||||
for (int series = 0; series < k_numberOfSeries; series++) {
|
||||
for (int k = 0; k < numberOfPairsOfSeries(series); k++) {
|
||||
if (m_xMin <= m_data[series][0][k] && m_data[series][0][k] <= m_xMax) {
|
||||
minY = min(minY, m_data[series][1][k]);
|
||||
maxY = max(maxY, m_data[series][1][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
InteractiveCurveViewRangeDelegate::Range range;
|
||||
range.min = min;
|
||||
range.max = max;
|
||||
range.min = minY;
|
||||
range.max = maxY;
|
||||
return range;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,43 +9,48 @@ namespace Regression {
|
||||
class Store : public Shared::InteractiveCurveViewRange, public Shared::FloatPairStore, public Shared::InteractiveCurveViewRangeDelegate {
|
||||
public:
|
||||
Store();
|
||||
|
||||
// Dots
|
||||
/* Return the closest dot to x above the regression curve if direction > 0,
|
||||
* below otherwise*/
|
||||
int closestVerticalDot(int series, int direction, float x);
|
||||
/* Return the closest dot to dot given on the right if direction > 0,
|
||||
* on the left otherwise*/
|
||||
/* Return the closest dot to abscissa x above the regression curve if
|
||||
* direction > 0, below otherwise */
|
||||
int closestVerticalDot(int direction, float x);
|
||||
/* Return the closest dot to given dot, on the right if direction > 0,
|
||||
* on the left otherwise */
|
||||
int nextDot(int series, int direction, int dot);
|
||||
|
||||
// Window
|
||||
void setDefault() override;
|
||||
|
||||
// Series
|
||||
bool isEmpty() const;
|
||||
bool seriesIsEmpty(int series) const;
|
||||
|
||||
// Calculation
|
||||
double numberOfPairs(int series) const { return m_numberOfPairs; }
|
||||
double squaredValueSumOfColumn(int series, int i);
|
||||
double columnProductSum(int series);
|
||||
double meanOfColumn(int series, int i);
|
||||
double varianceOfColumn(int series, int i);
|
||||
double standardDeviationOfColumn(int series, int i);
|
||||
double covariance(int series);
|
||||
double slope(int series);
|
||||
double yIntercept(int series);
|
||||
double yValueForXValue(int series, double x);
|
||||
double xValueForYValue(int series, double y);
|
||||
double correlationCoefficient(int series);
|
||||
double squaredCorrelationCoefficient(int series);
|
||||
double doubleCastedNumberOfPairsOfSeries(int series) const;
|
||||
double squaredValueSumOfColumn(int series, int i) const;
|
||||
double columnProductSum(int series) const;
|
||||
double meanOfColumn(int series, int i) const;
|
||||
double varianceOfColumn(int series, int i) const;
|
||||
double standardDeviationOfColumn(int series, int i) const;
|
||||
double covariance(int series) const;
|
||||
double slope(int series) const;
|
||||
double yIntercept(int series) const;
|
||||
double yValueForXValue(int series, double x) const;
|
||||
double xValueForYValue(int series, double y) const;
|
||||
double correlationCoefficient(int series) const;
|
||||
double squaredCorrelationCoefficient(int series) const;
|
||||
private:
|
||||
constexpr static float k_displayTopMarginRatio = 0.12f;
|
||||
constexpr static float k_displayRightMarginRatio = 0.05f;
|
||||
constexpr static float k_displayBottomMarginRatio = 0.5f;
|
||||
constexpr static float k_displayLeftMarginRatio = 0.05f;
|
||||
InteractiveCurveViewRangeDelegate::Range computeYRange(int series, InteractiveCurveViewRange * interactiveCurveViewRange) override;
|
||||
InteractiveCurveViewRangeDelegate::Range computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) override;
|
||||
float addMargin(float x, float range, bool isMin) override;
|
||||
float maxValueOfColumn(int series, int i);
|
||||
float minValueOfColumn(int series, int i);
|
||||
float maxValueOfColumn(int series, int i) const;
|
||||
float minValueOfColumn(int series, int i) const;
|
||||
};
|
||||
|
||||
typedef double (Store::*ArgCalculPointer)(int);
|
||||
typedef double (Store::*ArgCalculPointer)(int, int) const;
|
||||
typedef double (Store::*CalculPointer)();
|
||||
typedef void (Store::*RangeMethodPointer)();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user