diff --git a/apps/curve_view.cpp b/apps/curve_view.cpp index 52a39186b..13bc89d1f 100644 --- a/apps/curve_view.cpp +++ b/apps/curve_view.cpp @@ -188,11 +188,11 @@ void CurveView::drawCurve(void * curve, KDColor color, KDContext * ctx, KDRect r } } -void CurveView::drawHistogram(void * curve, KDColor color, KDContext * ctx, KDRect rect, bool colorUnderCurve, KDColor highlightColor, float colorLowerBound, float colorUpperBound) const { +void CurveView::drawDiscreteHistogram(KDColor color, KDContext * ctx, KDRect rect, bool colorUnderCurve, KDColor highlightColor, float colorLowerBound, float colorUpperBound) const { int rectMin = ceilf(pixelToFloat(Axis::Horizontal, rect.left())); int rectMax = pixelToFloat(Axis::Horizontal, rect.right()); for (int x = rectMin; x < rectMax; x += 1) { - float y = evaluateCurveAtAbscissa(curve, x); + float y = evaluateCurveAtAbscissa(nullptr, x); if (!isnan(y)) { float pxf = floatToPixel(Axis::Horizontal, x); float pyf = floatToPixel(Axis::Vertical, y); @@ -209,6 +209,33 @@ void CurveView::drawHistogram(void * curve, KDColor color, KDContext * ctx, KDRe } } +void CurveView::drawHistogram(float binWidth, KDColor color, KDContext * ctx, KDRect rect, KDColor highlightColor, float coloredBin) const { + KDCoordinate pixelBinWidth = floatToPixel(Axis::Horizontal, binWidth) - floatToPixel(Axis::Horizontal, 0.0f); + float min = m_curveViewWindow->xMin(); + float rectMin = pixelToFloat(Axis::Horizontal, rect.left()); + int rectMinBinNumber = (rectMin - min)/binWidth; + float rectMinLowerBound = min + rectMinBinNumber*binWidth; + float rectMax = pixelToFloat(Axis::Horizontal, rect.right()); + int rectMaxBinNumber = (rectMax - min)/binWidth; + float rectMaxUpperBound = min + (rectMaxBinNumber+1)*binWidth; + for (float x = rectMinLowerBound; x < rectMaxUpperBound; x += binWidth) { + float y = evaluateCurveAtAbscissa(nullptr, x); + if (!isnan(y)) { + float pxf = floatToPixel(Axis::Horizontal, x); + float pyf = floatToPixel(Axis::Vertical, y); + KDRect binRect(pxf, roundf(pyf), pixelBinWidth+1 , floatToPixel(Axis::Vertical, 0.0f) - roundf(pyf)); + if (floatToPixel(Axis::Vertical, 0.0f) < roundf(pyf)) { + binRect = KDRect(pxf, floatToPixel(Axis::Vertical, 0.0f), pixelBinWidth+1, roundf(pyf) - floatToPixel(Axis::Vertical, 0.0f)); + } + KDColor binColor = color; + if (x <= coloredBin && coloredBin < x+binWidth) { + binColor = highlightColor; + } + ctx->fillRect(binRect, binColor); + } + } +} + void CurveView::stampAtLocation(float pxf, float pyf, KDColor color, KDContext * ctx, KDRect rect) const { // We avoid drawing when no part of the stamp is visible if (pyf < -stampSize || pyf > pixelLength(Axis::Vertical)+stampSize) { diff --git a/apps/curve_view.h b/apps/curve_view.h index ee37fe522..10472539a 100644 --- a/apps/curve_view.h +++ b/apps/curve_view.h @@ -32,7 +32,8 @@ protected: float coordinate, KDColor color, KDCoordinate thickness = 1) const; void drawAxes(Axis axis, KDContext * ctx, KDRect rect) const; void drawCurve(void * curve, KDColor color, KDContext * ctx, KDRect rect, bool colorUnderCurve = false, float colorLowerBound = 0.0f, float colorUpperBound = 0.0f, bool continuously = false) const; - void drawHistogram(void * curve, KDColor color, KDContext * ctx, KDRect rect, bool colorHighlightBin = false, KDColor highlightColor = KDColorBlack, float colorLowerBound = 0.0f, float colorUpperBound = 0.0f) const; + void drawDiscreteHistogram(KDColor color, KDContext * ctx, KDRect rect, bool colorHighlightBin = false, KDColor highlightColor = KDColorBlack, float colorLowerBound = 0.0f, float colorUpperBound = 0.0f) const; + void drawHistogram(float binWidth, KDColor color, KDContext * ctx, KDRect rect, KDColor highlightColor, float coloredBin) const; void computeLabels(Axis axis); void drawLabels(Axis axis, bool shiftOrigin, KDContext * ctx, KDRect rect) const; private: diff --git a/apps/probability/law_curve_view.cpp b/apps/probability/law_curve_view.cpp index 7e8752d3a..27c0ba79b 100644 --- a/apps/probability/law_curve_view.cpp +++ b/apps/probability/law_curve_view.cpp @@ -42,7 +42,7 @@ void LawCurveView::drawRect(KDContext * ctx, KDRect rect) const { if (m_law->isContinuous()) { drawCurve(m_law, KDColorRed, ctx, rect, true, lowerBound, upperBound, true); } else { - drawHistogram(m_law, KDColorBlue, ctx, rect, true, KDColorRed, lowerBound, upperBound); + drawDiscreteHistogram(KDColorBlue, ctx, rect, true, KDColorRed, lowerBound, upperBound); } } diff --git a/apps/statistics/histogram_view.cpp b/apps/statistics/histogram_view.cpp index fcf84417a..72cd35eb1 100644 --- a/apps/statistics/histogram_view.cpp +++ b/apps/statistics/histogram_view.cpp @@ -19,7 +19,7 @@ void HistogramView::drawRect(KDContext * ctx, KDRect rect) const { drawAxes(Axis::Horizontal, ctx, rect); drawAxes(Axis::Vertical, ctx, rect); drawLabels(Axis::Horizontal, true, ctx, rect); - drawHistogram(nullptr, KDColorBlack, ctx, rect); + drawHistogram(m_data->binWidth(), KDColorBlack, ctx, rect, KDColorRed, 3.0f); } char * HistogramView::label(Axis axis, int index) const {