diff --git a/Telegram/SourceFiles/statistics/chart_widget.cpp b/Telegram/SourceFiles/statistics/chart_widget.cpp index 9f6dcb5fe..a7cea3beb 100644 --- a/Telegram/SourceFiles/statistics/chart_widget.cpp +++ b/Telegram/SourceFiles/statistics/chart_widget.cpp @@ -1183,26 +1183,17 @@ void ChartWidget::setupDetails() { case QEvent::MouseButtonPress: case QEvent::MouseMove: { const auto chartRect = chartAreaRect(); - const auto pointerRatio = std::clamp( - state.point.x() / float64(chartRect.width()), - 0., - 1.); const auto currentXLimits = _animationController.finalXLimits(); - const auto rawXPercentage = anim::interpolateF( - currentXLimits.min, - currentXLimits.max, - pointerRatio); - const auto nearestXPercentageIt = ranges::lower_bound( - _chartData.xPercentage, - rawXPercentage); - const auto nearestXIndex = std::distance( - begin(_chartData.xPercentage), - nearestXPercentageIt); + const auto nearestXIndex = _chartView->findXIndexByPosition( + _chartData, + currentXLimits, + chartRect, + state.point.x()); const auto currentX = 0 + chartRect.width() * InterpolationRatio( currentXLimits.min, currentXLimits.max, - *nearestXPercentageIt); + _chartData.xPercentage[nearestXIndex]); const auto xLeft = currentX - _details.widget->width(); const auto x = (xLeft >= 0) diff --git a/Telegram/SourceFiles/statistics/view/abstract_chart_view.h b/Telegram/SourceFiles/statistics/view/abstract_chart_view.h index 67cbda885..1dd0d3ab1 100644 --- a/Telegram/SourceFiles/statistics/view/abstract_chart_view.h +++ b/Telegram/SourceFiles/statistics/view/abstract_chart_view.h @@ -37,6 +37,12 @@ public: int selectedXIndex, float64 progress) = 0; + [[nodiscard]] virtual int findXIndexByPosition( + const Data::StatisticalChart &chartData, + const Limits &xPercentageLimits, + const QRect &rect, + float64 x) = 0; + virtual void setEnabled(int id, bool enabled, crl::time now) = 0; [[nodiscard]] virtual bool isEnabled(int id) const = 0; [[nodiscard]] virtual bool isFinished() const = 0; diff --git a/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp b/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp index 9936f9219..fdad065c1 100644 --- a/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp +++ b/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp @@ -189,6 +189,35 @@ void LinearChartView::paintSelectedXIndex( _selectedPoints.lastXLimits = xPercentageLimits; } +int LinearChartView::findXIndexByPosition( + const Data::StatisticalChart &chartData, + const Limits &xPercentageLimits, + const QRect &rect, + float64 x) { + if (x < rect.x()) { + return 0; + } else if (x > (rect.x() + rect.width())) { + return chartData.xPercentage.size() - 1; + } + const auto pointerRatio = std::clamp( + (x - rect.x()) / rect.width(), + 0., + 1.); + const auto rawXPercentage = anim::interpolateF( + xPercentageLimits.min, + xPercentageLimits.max, + pointerRatio); + const auto it = ranges::lower_bound( + chartData.xPercentage, + rawXPercentage); + const auto left = rawXPercentage - (*(it - 1)); + const auto right = (*it) - rawXPercentage; + const auto nearestXPercentageIt = ((right) > (left)) ? (it - 1) : it; + return std::distance( + begin(chartData.xPercentage), + nearestXPercentageIt); +} + void LinearChartView::setEnabled(int id, bool enabled, crl::time now) { const auto it = _entries.find(id); if (it == end(_entries)) { diff --git a/Telegram/SourceFiles/statistics/view/linear_chart_view.h b/Telegram/SourceFiles/statistics/view/linear_chart_view.h index 74b69d653..0a4c40800 100644 --- a/Telegram/SourceFiles/statistics/view/linear_chart_view.h +++ b/Telegram/SourceFiles/statistics/view/linear_chart_view.h @@ -41,6 +41,12 @@ public: int selectedXIndex, float64 progress) override; + int findXIndexByPosition( + const Data::StatisticalChart &chartData, + const Limits &xPercentageLimits, + const QRect &rect, + float64 x) override; + void setEnabled(int id, bool enabled, crl::time now) override; [[nodiscard]] bool isEnabled(int id) const override; [[nodiscard]] bool isFinished() const override; diff --git a/Telegram/SourceFiles/statistics/view/stack_chart_view.cpp b/Telegram/SourceFiles/statistics/view/stack_chart_view.cpp index 65200bfbf..979b5aee1 100644 --- a/Telegram/SourceFiles/statistics/view/stack_chart_view.cpp +++ b/Telegram/SourceFiles/statistics/view/stack_chart_view.cpp @@ -98,6 +98,14 @@ void StackChartView::paintSelectedXIndex( float64 progress) { } +int StackChartView::findXIndexByPosition( + const Data::StatisticalChart &chartData, + const Limits &xPercentageLimits, + const QRect &rect, + float64 xPos) { + return 0; +} + void StackChartView::setEnabled(int id, bool enabled, crl::time now) { } diff --git a/Telegram/SourceFiles/statistics/view/stack_chart_view.h b/Telegram/SourceFiles/statistics/view/stack_chart_view.h index 95eb55876..dc0e84d46 100644 --- a/Telegram/SourceFiles/statistics/view/stack_chart_view.h +++ b/Telegram/SourceFiles/statistics/view/stack_chart_view.h @@ -42,6 +42,12 @@ public: int selectedXIndex, float64 progress) override; + int findXIndexByPosition( + const Data::StatisticalChart &chartData, + const Limits &xPercentageLimits, + const QRect &rect, + float64 x) override; + void setEnabled(int id, bool enabled, crl::time now) override; [[nodiscard]] bool isEnabled(int id) const override; [[nodiscard]] bool isFinished() const override;