From 7442e8fbcab2630db08e16366d960553b56930f1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Mal=C3=BD?= Date: Tue, 3 Mar 2015 01:36:38 +0100 Subject: [PATCH] Adjust the logic of ruler drawing to prevent the ticks to be too densely or too sparsely placed. --- signalcontroller.cpp | 20 +++++++++++++++++++- signalcontroller.h | 7 ++++--- signaldrawer.cpp | 26 +++++++++++--------------- signaldrawer.h | 4 +++- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/signalcontroller.cpp b/signalcontroller.cpp index f04c0e8..caeb12e 100644 --- a/signalcontroller.cpp +++ b/signalcontroller.cpp @@ -167,12 +167,18 @@ std::vector SignalController::getPeaksDrawData(const double fromX, return peaks; } -RulerDrawData SignalController::getRulerDrawData(const double from, const double to, Axis axis) +RulerDrawData SignalController::getRulerDrawData(const double from, const double to, Axis axis, const int pixelLength, const int minPixelStep, const int maxPixelStep) { double diffAbs, diffRel; double fromAbs, toAbs; double step, relStep; double firstTickAbs, firstTickRel; + double pixelStep; + double numSteps; + + /* Don't bother doing anything for an invisible chart */ + if (pixelLength < 1) + return RulerDrawData(); diffRel = to - from; @@ -192,6 +198,18 @@ RulerDrawData SignalController::getRulerDrawData(const double from, const double /* Calculate step */ diffAbs = toAbs - fromAbs; step = 1 / pow(10, floor(log10(1 / (diffAbs))) + 1); // Magic - you want to love it but you better not touch! + numSteps = diffAbs / step; + pixelStep = pixelLength / numSteps + 1; + Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, __QFUNC__ + QString("pixelStep %1, step %2, pixelLength %3, numSteps %4").arg(pixelStep).arg(step).arg(pixelLength).arg(numSteps)); + if (pixelStep < minPixelStep) { + const double upscaleFactor = ceil(minPixelStep / pixelStep); + step *= upscaleFactor; + Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, __QFUNC__ + QString("Corrected step %1, upscaleFactor %2").arg(step).arg(upscaleFactor)); + } else if (pixelStep > maxPixelStep) { + const double downscaleFactor = ceil(pixelStep / maxPixelStep); + step /= downscaleFactor; + Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, __QFUNC__ + QString("Corrected step %1, downscaleFactor %2").arg(step).arg(downscaleFactor)); + } relStep = (diffRel * step) / (diffAbs); //Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, __QFUNC__ + QString(" rD %1 aD %2").arg(diffRel).arg(diffAbs)); //Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, __QFUNC__ + QString(" fA %1 tA %2 fR %3 tR %4").arg(fromAbs).arg(toAbs).arg(from).arg(to)); diff --git a/signalcontroller.h b/signalcontroller.h index ea8bf6d..d8105c3 100644 --- a/signalcontroller.h +++ b/signalcontroller.h @@ -85,14 +85,15 @@ struct PeakDrawData { }; struct RulerDrawData { - RulerDrawData() : firstTickAbs(0), firstTickRel(0), step(0), relStep(0) {} - RulerDrawData(const double fta, const double ftr, const double s, const double rs) : firstTickAbs(fta), firstTickRel(ftr), step(s), relStep(rs) + RulerDrawData() : firstTickAbs(0), firstTickRel(0), step(0), relStep(0), valid(false) {} + RulerDrawData(const double fta, const double ftr, const double s, const double rs) : firstTickAbs(fta), firstTickRel(ftr), step(s), relStep(rs), valid(true) {} const double firstTickAbs; const double firstTickRel; const double step; const double relStep; + const bool valid; }; class SignalController : public QObject, public JSONSerializable @@ -109,7 +110,7 @@ public: Signal::TimeValuePair getXYValues(const double x); std::shared_ptr getGraphDrawData(const double fromX, const double toX); std::vector getPeaksDrawData(const double fromX, const double fromY, const double toX, const double toY); - RulerDrawData getRulerDrawData(const double from, const double to, SignalController::Axis axis); + RulerDrawData getRulerDrawData(const double from, const double to, SignalController::Axis axis, const int pixelLength, const int minPixelStep, const int maxPixelStep); GUIViewport guiViewport() const { return m_guiViewport; } double fromXAbs() const { return m_signal->timeAt(0); } double toXAbs() const { return m_signal->timeAt(m_signal->count()-1); } diff --git a/signaldrawer.cpp b/signaldrawer.cpp index b42cbf5..b0262c9 100644 --- a/signaldrawer.cpp +++ b/signaldrawer.cpp @@ -29,6 +29,8 @@ const QString SignalDrawer::ME_SENDER_STR("SignalDrawer"); const int SignalDrawer::AXIS_LABEL_BORDER_OFFSET(2); const int SignalDrawer::AXIS_LABEL_SCALE_OFFSET(3); +const int SignalDrawer::MAXIMAL_AXIS_BIGTICK_STEP(75); +const int SignalDrawer::MINIMAL_AXIS_BIGTICK_STEP(25); const int SignalDrawer::SCALE_MARGIN_TIME(16); const int SignalDrawer::SCALE_MARGIN_VALUE(12); @@ -237,10 +239,9 @@ void SignalDrawer::drawLeadingSubticks(const RulerDrawData& rd, std::function= relMin) { - drawFunc(subRel, subAbs, (ctr++ == 5) ? TickType::TICK : TickType::SUBTICK); + drawFunc(subRel, subAbs, TickType::SUBTICK); subRel -= subRelStep; subAbs -= subAbsStep; } @@ -254,11 +255,8 @@ void SignalDrawer::drawScaleBySubticks(const RulerDrawData& rd, std::functiongetRulerDrawData(m_relXMin, m_relXMax, SignalController::Axis::TIME); + RulerDrawData rd = m_controller->getRulerDrawData(m_relXMin, m_relXMax, SignalController::Axis::TIME, m_gWidth, MINIMAL_AXIS_BIGTICK_STEP, MAXIMAL_AXIS_BIGTICK_STEP); + if (!rd.valid) + return; /* Draw text first - we need to know how wide is the largest numeric cue */ drawScaleByTicks(rd, textDrawFunc, m_relXMax, false); @@ -306,7 +306,9 @@ void SignalDrawer::drawValueScale(QPainter* const p) textDrawFunc = std::bind(&SignalDrawer::renderValueScaleText, this, p, std::ref(maxCueWidth), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); tickDrawFunc = std::bind(&SignalDrawer::renderValueScaleTick, this, p, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - RulerDrawData rd = m_controller->getRulerDrawData(m_relYMin, m_relYMax, SignalController::Axis::VALUE); + RulerDrawData rd = m_controller->getRulerDrawData(m_relYMin, m_relYMax, SignalController::Axis::VALUE, m_gHeight, MINIMAL_AXIS_BIGTICK_STEP, MAXIMAL_AXIS_BIGTICK_STEP); + if (!rd.valid) + return; /* Draw text first - we need to know how wide is the largest numeric cue */ drawScaleByTicks(rd, textDrawFunc, m_relYMax, false); @@ -378,9 +380,6 @@ void SignalDrawer::renderTimeScaleTick(QPainter* const p, const double rel, cons case TickType::BIGTICK: p->drawLine(xPix, m_gHeight + 2, xPix, m_gHeight + 8); break; - case TickType::TICK: - p->drawLine(xPix, m_gHeight + 2, xPix, m_gHeight + 6); - break; case TickType::SUBTICK: p->drawLine(xPix, m_gHeight + 2, xPix , m_gHeight + 4); break; @@ -396,9 +395,6 @@ void SignalDrawer::renderValueScaleTick(QPainter* const p, const double rel, con case TickType::BIGTICK: p->drawLine(m_leftGraphOffset - 8, yPix, m_leftGraphOffset - 1, yPix); break; - case TickType::TICK: - p->drawLine(m_leftGraphOffset - 6, yPix, m_leftGraphOffset - 1, yPix); - break; case TickType::SUBTICK: p->drawLine(m_leftGraphOffset - 4, yPix, m_leftGraphOffset - 1, yPix); break; @@ -696,7 +692,7 @@ void SignalDrawer::setNewRelativeConstraints(const double fromX, const double fr double SignalDrawer::subStep(const double step) { - return step / 10; + return step / 5; } SignalDrawer::~SignalDrawer() diff --git a/signaldrawer.h b/signaldrawer.h index d72edad..31ef120 100644 --- a/signaldrawer.h +++ b/signaldrawer.h @@ -68,7 +68,7 @@ public: bool setDimensions(const int width, const int height); protected: - enum class TickType { BIGTICK, TICK, SUBTICK }; + enum class TickType { BIGTICK, SUBTICK }; std::shared_ptr m_controller; QLocale m_locale; @@ -103,6 +103,8 @@ protected: static const int AXIS_LABEL_BORDER_OFFSET; static const int AXIS_LABEL_SCALE_OFFSET; + static const int MAXIMAL_AXIS_BIGTICK_STEP; + static const int MINIMAL_AXIS_BIGTICK_STEP; static const int SCALE_MARGIN_TIME; static const int SCALE_MARGIN_VALUE; -- 2.43.5