Added dirty implementation of chart animation with both axes.

This commit is contained in:
23rd 2023-06-08 15:18:19 +03:00 committed by John Preston
parent f4fc8ec2c4
commit 629dd6f9de
4 changed files with 92 additions and 5 deletions

View File

@ -183,23 +183,58 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
auto p = QPainter(_footer.get()); auto p = QPainter(_footer.get());
if (_chartData) { 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( Statistic::PaintLinearChartView(
p, p,
_chartData, _chartData,
{}, {},
limits, limits,
limitsY,
1., 1.,
_footer->rect()); _footer->rect());
} }
}, _footer->lifetime()); }, _footer->lifetime());
_xPercentage.animation.init([=] { _xPercentage.animation.init([=](crl::time now) {
const auto progress = (crl::now() - _xPercentage.lastUserInteracted) const auto timeDiff = (now - _xPercentage.lastUserInteracted);
/ float64(400.); 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; _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.animation.stop();
_xPercentage.was = _xPercentage.now; _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( const auto startXIndex = _chartData.findStartIndex(
_xPercentage.now.min); _xPercentage.now.min);
@ -221,8 +256,46 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
_xPercentage.animation.start(); _xPercentage.animation.start();
// _xPercentage.was = base::take(_xPercentage.now); // _xPercentage.was = base::take(_xPercentage.now);
} }
_animValueXMin.start(xPercentageLimits.min);
_animValueXMax.start(xPercentageLimits.max);
_xPercentage.now = xPercentageLimits; _xPercentage.now = xPercentageLimits;
_xPercentage.lastUserInteracted = crl::now(); _xPercentage.lastUserInteracted = crl::now();
const auto &chartData = _chartData;
{
auto minY = std::numeric_limits<float64>::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(); // _xPercentage.animation.stop();
// const auto was = _xPercentageLimits; // const auto was = _xPercentageLimits;
// const auto now = xPercentageLimits; // const auto now = xPercentageLimits;
@ -301,7 +374,9 @@ void ChartWidget::paintEvent(QPaintEvent *e) {
p, p,
_chartData, _chartData,
_xPercentage.was, _xPercentage.was,
_xPercentage.now, { _animValueXMin.current(), _animValueXMax.current() },
{ _animValueYMin.current(), _animValueYMax.current() },
// _xPercentage.now,
_xPercentage.progress, _xPercentage.progress,
chartRect); chartRect);
} }

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_statistics.h" #include "data/data_statistics.h"
#include "statistics/chart_horizontal_lines_data.h" #include "statistics/chart_horizontal_lines_data.h"
#include "statistics/statistics_common.h" #include "statistics/statistics_common.h"
#include "ui/effects/animation_value.h"
#include "ui/effects/animations.h" #include "ui/effects/animations.h"
#include "ui/rp_widget.h" #include "ui/rp_widget.h"
@ -48,6 +49,12 @@ private:
crl::time lastUserInteracted = 0; crl::time lastUserInteracted = 0;
float64 progress = 0.; float64 progress = 0.;
} _xPercentage; } _xPercentage;
anim::value _animValueXMin;
anim::value _animValueXMax;
anim::value _animValueYMin;
anim::value _animValueYMax;
crl::time _yAnimStarted = 0;
float64 _minMaxUpdateStep = 0.; float64 _minMaxUpdateStep = 0.;

View File

@ -19,6 +19,7 @@ void PaintLinearChartView(
const Data::StatisticalChart &chartData, const Data::StatisticalChart &chartData,
const Limits &xPercentageLimitsWas, const Limits &xPercentageLimitsWas,
const Limits &xPercentageLimitsNow, const Limits &xPercentageLimitsNow,
const Limits &xPercentageLimitsNowY,
float64 progress, float64 progress,
const QRect &rect) { const QRect &rect) {
const auto offset = 0; const auto offset = 0;
@ -76,6 +77,9 @@ void PaintLinearChartView(
} }
} }
minY = xPercentageLimitsNowY.min;
maxY = xPercentageLimitsNowY.max;
for (auto i = localStart; i <= localEnd; i++) { for (auto i = localStart; i <= localEnd; i++) {
if (line.y[i] < 0) { if (line.y[i] < 0) {
continue; continue;

View File

@ -20,6 +20,7 @@ void PaintLinearChartView(
const Data::StatisticalChart &chartData, const Data::StatisticalChart &chartData,
const Limits &xPercentageLimitsWas, const Limits &xPercentageLimitsWas,
const Limits &xPercentageLimitsNow, const Limits &xPercentageLimitsNow,
const Limits &xPercentageLimitsNowY,
float64 progress, float64 progress,
const QRect &rect); const QRect &rect);