diff --git a/Telegram/SourceFiles/statistics/chart_widget.cpp b/Telegram/SourceFiles/statistics/chart_widget.cpp index 440a334c9..631e1450b 100644 --- a/Telegram/SourceFiles/statistics/chart_widget.cpp +++ b/Telegram/SourceFiles/statistics/chart_widget.cpp @@ -183,23 +183,58 @@ ChartWidget::ChartWidget(not_null parent) auto p = QPainter(_footer.get()); if (_chartData) { + const auto startXIndex2 = 0; + const auto endXIndex2 = int(_chartData.xPercentage.size() - 1); + const auto limitsY = Limits{ + float64(FindMinValue(_chartData, startXIndex2, endXIndex2)), + float64(FindMaxValue(_chartData, startXIndex2, endXIndex2)), + }; Statistic::PaintLinearChartView( p, _chartData, {}, limits, + limitsY, 1., _footer->rect()); } }, _footer->lifetime()); - _xPercentage.animation.init([=] { - const auto progress = (crl::now() - _xPercentage.lastUserInteracted) - / float64(400.); + _xPercentage.animation.init([=](crl::time now) { + const auto timeDiff = (now - _xPercentage.lastUserInteracted); + const auto dt = (now - _xPercentage.animation.started()) + / float64(200); + + if (!_yAnimStarted && timeDiff >= 400) { + _yAnimStarted = _xPercentage.lastUserInteracted; + } + const auto dt2 = (now - _yAnimStarted - 400) + / float64(2000); + + const auto progress = timeDiff / float64(2000.); _xPercentage.progress = progress; - if (progress > 1.) { + if ((_animValueXMin.to() == _animValueXMin.current()) + && (_animValueXMax.to() == _animValueXMax.current()) + && (_animValueYMin.to() == _animValueYMin.current()) + && (_animValueYMax.to() == _animValueYMax.current())) { + // if (progress > 1.) { _xPercentage.animation.stop(); _xPercentage.was = _xPercentage.now; + + _animValueXMin.finish(); + _animValueXMax.finish(); + _animValueYMin.finish(); + _animValueYMax.finish(); + + _yAnimStarted = 0; + } else { + _animValueXMin.update(std::min(dt, 1.), anim::linear); + _animValueXMax.update(std::min(dt, 1.), anim::linear); + + if (_yAnimStarted) { + _animValueYMin.update(std::min(dt2, 1.), anim::sineInOut); + _animValueYMax.update(std::min(dt2, 1.), anim::sineInOut); + } } const auto startXIndex = _chartData.findStartIndex( _xPercentage.now.min); @@ -221,8 +256,46 @@ ChartWidget::ChartWidget(not_null parent) _xPercentage.animation.start(); // _xPercentage.was = base::take(_xPercentage.now); } + _animValueXMin.start(xPercentageLimits.min); + _animValueXMax.start(xPercentageLimits.max); _xPercentage.now = xPercentageLimits; _xPercentage.lastUserInteracted = crl::now(); + + const auto &chartData = _chartData; + { + auto minY = std::numeric_limits::max(); + auto maxY = 0.; + auto minYIndex = 0; + auto maxYIndex = 0; + const auto tempXPercentage = Limits{ + .min = *ranges::lower_bound( + chartData.xPercentage, + xPercentageLimits.min), + .max = *ranges::lower_bound( + chartData.xPercentage, + xPercentageLimits.max), + }; + for (auto i = 0; i < chartData.xPercentage.size(); i++) { + if (chartData.xPercentage[i] == tempXPercentage.min) { + minYIndex = i; + } + if (chartData.xPercentage[i] == tempXPercentage.max) { + maxYIndex = i; + } + } + for (const auto &line : chartData.lines) { + for (auto i = minYIndex; i < maxYIndex; i++) { + if (line.y[i] > maxY) { + maxY = line.y[i]; + } + if (line.y[i] < minY) { + minY = line.y[i]; + } + } + } + _animValueYMin.start(minY); + _animValueYMax.start(maxY); + } // _xPercentage.animation.stop(); // const auto was = _xPercentageLimits; // const auto now = xPercentageLimits; @@ -301,7 +374,9 @@ void ChartWidget::paintEvent(QPaintEvent *e) { p, _chartData, _xPercentage.was, - _xPercentage.now, + { _animValueXMin.current(), _animValueXMax.current() }, + { _animValueYMin.current(), _animValueYMax.current() }, + // _xPercentage.now, _xPercentage.progress, chartRect); } diff --git a/Telegram/SourceFiles/statistics/chart_widget.h b/Telegram/SourceFiles/statistics/chart_widget.h index 7c1cc261a..7adba3af3 100644 --- a/Telegram/SourceFiles/statistics/chart_widget.h +++ b/Telegram/SourceFiles/statistics/chart_widget.h @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_statistics.h" #include "statistics/chart_horizontal_lines_data.h" #include "statistics/statistics_common.h" +#include "ui/effects/animation_value.h" #include "ui/effects/animations.h" #include "ui/rp_widget.h" @@ -48,6 +49,12 @@ private: crl::time lastUserInteracted = 0; float64 progress = 0.; } _xPercentage; + anim::value _animValueXMin; + anim::value _animValueXMax; + anim::value _animValueYMin; + anim::value _animValueYMax; + + crl::time _yAnimStarted = 0; float64 _minMaxUpdateStep = 0.; diff --git a/Telegram/SourceFiles/statistics/linear_chart_view.cpp b/Telegram/SourceFiles/statistics/linear_chart_view.cpp index 2aa9e008a..46c8faec8 100644 --- a/Telegram/SourceFiles/statistics/linear_chart_view.cpp +++ b/Telegram/SourceFiles/statistics/linear_chart_view.cpp @@ -19,6 +19,7 @@ void PaintLinearChartView( const Data::StatisticalChart &chartData, const Limits &xPercentageLimitsWas, const Limits &xPercentageLimitsNow, + const Limits &xPercentageLimitsNowY, float64 progress, const QRect &rect) { const auto offset = 0; @@ -76,6 +77,9 @@ void PaintLinearChartView( } } + minY = xPercentageLimitsNowY.min; + maxY = xPercentageLimitsNowY.max; + for (auto i = localStart; i <= localEnd; i++) { if (line.y[i] < 0) { continue; diff --git a/Telegram/SourceFiles/statistics/linear_chart_view.h b/Telegram/SourceFiles/statistics/linear_chart_view.h index 0b943d4f0..07e6a4828 100644 --- a/Telegram/SourceFiles/statistics/linear_chart_view.h +++ b/Telegram/SourceFiles/statistics/linear_chart_view.h @@ -20,6 +20,7 @@ void PaintLinearChartView( const Data::StatisticalChart &chartData, const Limits &xPercentageLimitsWas, const Limits &xPercentageLimitsNow, + const Limits &xPercentageLimitsNowY, float64 progress, const QRect &rect);