Added initial display of footer while chart lines are filtering.

This commit is contained in:
23rd 2023-07-14 20:13:42 +03:00 committed by John Preston
parent ee172d951d
commit 64bb818fe9
2 changed files with 66 additions and 67 deletions

View file

@ -33,43 +33,6 @@ inline float64 InterpolationRatio(float64 from, float64 to, float64 result) {
return (result - from) / (to - from); return (result - from) / (to - from);
}; };
[[nodiscard]] int FindMaxValue(
Data::StatisticalChart &chartData,
int startXIndex,
int endXIndex) {
auto maxValue = 0;
for (auto &l : chartData.lines) {
const auto lineMax = l.segmentTree.rMaxQ(startXIndex, endXIndex);
maxValue = std::max(lineMax, maxValue);
}
return maxValue;
}
[[nodiscard]] int FindMinValue(
Data::StatisticalChart &chartData,
int startXIndex,
int endXIndex) {
auto minValue = std::numeric_limits<int>::max();
for (auto &l : chartData.lines) {
const auto lineMin = l.segmentTree.rMinQ(startXIndex, endXIndex);
minValue = std::min(lineMin, minValue);
}
return minValue;
}
[[nodiscard]] Limits FindHeightLimitsBetweenXLimits(
Data::StatisticalChart &chartData,
const Limits &xPercentageLimits) {
const auto startXIndex = chartData.findStartIndex(xPercentageLimits.min);
const auto endXIndex = chartData.findEndIndex(
startXIndex,
xPercentageLimits.max);
return Limits{
float64(FindMinValue(chartData, startXIndex, endXIndex)),
float64(FindMaxValue(chartData, startXIndex, endXIndex)),
};
}
void PaintHorizontalLines( void PaintHorizontalLines(
QPainter &p, QPainter &p,
const ChartHorizontalLinesData &horizontalLine, const ChartHorizontalLinesData &horizontalLine,
@ -236,9 +199,6 @@ public:
[[nodiscard]] rpl::producer<Limits> xPercentageLimitsChange() const; [[nodiscard]] rpl::producer<Limits> xPercentageLimitsChange() const;
[[nodiscard]] rpl::producer<> userInteractionFinished() const; [[nodiscard]] rpl::producer<> userInteractionFinished() const;
void setFullHeightLimits(Limits limits);
[[nodiscard]] const Limits &fullHeightLimits() const;
void setPaintChartCallback(PaintCallback paintChartCallback); void setPaintChartCallback(PaintCallback paintChartCallback);
protected: protected:
@ -248,8 +208,6 @@ private:
rpl::event_stream<Limits> _xPercentageLimitsChange; rpl::event_stream<Limits> _xPercentageLimitsChange;
rpl::event_stream<> _userInteractionFinished; rpl::event_stream<> _userInteractionFinished;
Limits _fullHeightLimits;
void prepareCache(int height); void prepareCache(int height);
void moveSide(bool left, float64 x); void moveSide(bool left, float64 x);
@ -513,14 +471,6 @@ rpl::producer<> ChartWidget::Footer::userInteractionFinished() const {
return _userInteractionFinished.events(); return _userInteractionFinished.events();
} }
void ChartWidget::Footer::setFullHeightLimits(Limits limits) {
_fullHeightLimits = std::move(limits);
}
const Limits &ChartWidget::Footer::fullHeightLimits() const {
return _fullHeightLimits;
}
ChartWidget::ChartAnimationController::ChartAnimationController( ChartWidget::ChartAnimationController::ChartAnimationController(
Fn<void()> &&updateCallback) Fn<void()> &&updateCallback)
: _animation(std::move(updateCallback)) { : _animation(std::move(updateCallback)) {
@ -548,14 +498,12 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits(
_animationValueXMax.to()); _animationValueXMax.to());
_currentXIndices = { float64(startXIndex), float64(endXIndex) }; _currentXIndices = { float64(startXIndex), float64(endXIndex) };
_finalHeightLimits = Limits{
float64(FindMinValue(chartData, startXIndex, endXIndex)),
float64(FindMaxValue(chartData, startXIndex, endXIndex)),
};
{ {
auto minValue = std::numeric_limits<int>::max(); auto minValue = std::numeric_limits<int>::max();
auto maxValue = 0; auto maxValue = 0;
auto minValueFull = std::numeric_limits<int>::max();
auto maxValueFull = 0;
for (auto &l : chartData.lines) { for (auto &l : chartData.lines) {
if (!chartLinesViewContext.isEnabled(l.id)) { if (!chartLinesViewContext.isEnabled(l.id)) {
continue; continue;
@ -564,8 +512,23 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits(
const auto lineMin = l.segmentTree.rMinQ(startXIndex, endXIndex); const auto lineMin = l.segmentTree.rMinQ(startXIndex, endXIndex);
maxValue = std::max(lineMax, maxValue); maxValue = std::max(lineMax, maxValue);
minValue = std::min(lineMin, minValue); minValue = std::min(lineMin, minValue);
maxValueFull = std::max(l.maxValue, maxValueFull);
minValueFull = std::min(l.minValue, minValueFull);
} }
_finalHeightLimits = { float64(minValue), float64(maxValue) }; _finalHeightLimits = { float64(minValue), float64(maxValue) };
if (!chartLinesViewContext.isFinished()) {
_animationValueFooterHeightMin = anim::value(
_animationValueFooterHeightMin.current(),
minValueFull);
_animationValueFooterHeightMax = anim::value(
_animationValueFooterHeightMax.current(),
maxValueFull);
} else if (!_animationValueFooterHeightMax.to()) {
// Will be finished in setChartData.
_animationValueFooterHeightMin = anim::value(0, minValueFull);
_animationValueFooterHeightMax = anim::value(0, maxValueFull);
}
} }
_animationValueHeightMin = anim::value( _animationValueHeightMin = anim::value(
@ -612,6 +575,8 @@ void ChartWidget::ChartAnimationController::finish() {
_animationValueXMax.finish(); _animationValueXMax.finish();
_animationValueHeightMin.finish(); _animationValueHeightMin.finish();
_animationValueHeightMax.finish(); _animationValueHeightMax.finish();
_animationValueFooterHeightMin.finish();
_animationValueFooterHeightMax.finish();
_animValueYAlpha.finish(); _animValueYAlpha.finish();
_benchmark = {}; _benchmark = {};
} }
@ -721,6 +686,12 @@ void ChartWidget::ChartAnimationController::tick(
_animationValueHeightMin.update(_dtCurrent.min, anim::easeInCubic); _animationValueHeightMin.update(_dtCurrent.min, anim::easeInCubic);
_animationValueHeightMax.update(_dtCurrent.max, anim::easeInCubic); _animationValueHeightMax.update(_dtCurrent.max, anim::easeInCubic);
_animValueYAlpha.update(dtAlpha, anim::easeInCubic); _animValueYAlpha.update(dtAlpha, anim::easeInCubic);
_animationValueFooterHeightMin.update(
_dtCurrent.min,
anim::easeInCubic);
_animationValueFooterHeightMax.update(
_dtCurrent.max,
anim::easeInCubic);
for (auto &horizontalLine : horizontalLines) { for (auto &horizontalLine : horizontalLines) {
horizontalLine.computeRelative( horizontalLine.computeRelative(
@ -787,6 +758,14 @@ Limits ChartWidget::ChartAnimationController::currentHeightLimits() const {
}; };
} }
auto ChartWidget::ChartAnimationController::currentFooterHeightLimits() const
-> Limits {
return {
_animationValueFooterHeightMin.current(),
_animationValueFooterHeightMax.current(),
};
}
Limits ChartWidget::ChartAnimationController::finalHeightLimits() const { Limits ChartWidget::ChartAnimationController::finalHeightLimits() const {
return _finalHeightLimits; return _finalHeightLimits;
} }
@ -809,6 +788,13 @@ bool ChartWidget::ChartAnimationController::animating() const {
return _animation.animating(); return _animation.animating();
} }
bool ChartWidget::ChartAnimationController::footerAnimating() const {
return (_animationValueFooterHeightMin.current()
!= _animationValueFooterHeightMin.to())
|| (_animationValueFooterHeightMax.current()
!= _animationValueFooterHeightMax.to());
}
bool ChartWidget::ChartAnimationController::isFPSSlow() const { bool ChartWidget::ChartAnimationController::isFPSSlow() const {
return _benchmark.lastFPSSlow; return _benchmark.lastFPSSlow;
} }
@ -822,7 +808,13 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
: Ui::RpWidget(parent) : Ui::RpWidget(parent)
, _chartArea(base::make_unique_q<RpMouseWidget>(this)) , _chartArea(base::make_unique_q<RpMouseWidget>(this))
, _footer(std::make_unique<Footer>(this)) , _footer(std::make_unique<Footer>(this))
, _animationController([=] { _chartArea->update(); }) { , _animationController([=] {
_chartArea->update();
if (_animationController.footerAnimating()
|| !_animatedChartLines.isFinished()) {
_footer->update();
}
}) {
sizeValue( sizeValue(
) | rpl::start_with_next([=](const QSize &s) { ) | rpl::start_with_next([=](const QSize &s) {
const auto filtersHeight = _filterButtons const auto filtersHeight = _filterButtons
@ -1054,12 +1046,16 @@ void ChartWidget::setupFooter() {
if (_chartData) { if (_chartData) {
auto detailsPaintContext = DetailsPaintContext{ .xIndex = -1 }; auto detailsPaintContext = DetailsPaintContext{ .xIndex = -1 };
p.fillRect(r, st::boxBg); p.fillRect(r, st::boxBg);
p.setRenderHint(
QPainter::Antialiasing,
!_animationController.isFPSSlow()
|| !_animationController.animating());
Statistic::PaintLinearChartView( Statistic::PaintLinearChartView(
p, p,
_chartData, _chartData,
{ 0., float64(_chartData.x.size() - 1) }, { 0., float64(_chartData.x.size() - 1) },
fullXLimits, fullXLimits,
_footer->fullHeightLimits(), _animationController.currentFooterHeightLimits(),
r, r,
_animatedChartLines, _animatedChartLines,
detailsPaintContext); detailsPaintContext);
@ -1104,15 +1100,17 @@ void ChartWidget::setupDetails() {
_chartArea->update(); _chartArea->update();
return; return;
} }
const auto maxAbsoluteValue = [&] {
auto maxValue = 0;
for (const auto &l : _chartData.lines) {
maxValue = std::max(l.maxValue, maxValue);
}
return maxValue;
}();
_details.widget = base::make_unique_q<PointDetailsWidget>( _details.widget = base::make_unique_q<PointDetailsWidget>(
this, this,
_chartData, _chartData,
FindHeightLimitsBetweenXLimits( maxAbsoluteValue);
_chartData,
{
_chartData.xPercentage.front(),
_chartData.xPercentage.back(),
}).max);
_details.widget->shownValue( _details.widget->shownValue(
) | rpl::start_with_next([=](bool shown) { ) | rpl::start_with_next([=](bool shown) {
@ -1218,10 +1216,6 @@ void ChartWidget::setChartData(Data::StatisticalChart chartData) {
setupDetails(); setupDetails();
setupFilterButtons(); setupFilterButtons();
_footer->setFullHeightLimits(FindHeightLimitsBetweenXLimits(
_chartData,
{ _chartData.xPercentage.front(), _chartData.xPercentage.back() }));
_animationController.setXPercentageLimits( _animationController.setXPercentageLimits(
_chartData, _chartData,
{ _chartData.xPercentage.front(), _chartData.xPercentage.back() }, { _chartData.xPercentage.front(), _chartData.xPercentage.back() },

View file

@ -65,11 +65,13 @@ private:
[[nodiscard]] Limits currentXIndices() const; [[nodiscard]] Limits currentXIndices() const;
[[nodiscard]] Limits finalXLimits() const; [[nodiscard]] Limits finalXLimits() const;
[[nodiscard]] Limits currentHeightLimits() const; [[nodiscard]] Limits currentHeightLimits() const;
[[nodiscard]] Limits currentFooterHeightLimits() const;
[[nodiscard]] Limits finalHeightLimits() const; [[nodiscard]] Limits finalHeightLimits() const;
[[nodiscard]] float64 detailsProgress( [[nodiscard]] float64 detailsProgress(
crl::time now, crl::time now,
const Limits &appearedOnXLimits) const; const Limits &appearedOnXLimits) const;
[[nodiscard]] bool animating() const; [[nodiscard]] bool animating() const;
[[nodiscard]] bool footerAnimating() const;
[[nodiscard]] bool isFPSSlow() const; [[nodiscard]] bool isFPSSlow() const;
[[nodiscard]] rpl::producer<> heightAnimationStarts() const; [[nodiscard]] rpl::producer<> heightAnimationStarts() const;
@ -87,6 +89,9 @@ private:
anim::value _animationValueHeightMin; anim::value _animationValueHeightMin;
anim::value _animationValueHeightMax; anim::value _animationValueHeightMax;
anim::value _animationValueFooterHeightMin;
anim::value _animationValueFooterHeightMax;
anim::value _animValueYAlpha; anim::value _animValueYAlpha;
anim::value _animValueBottomLineAlpha; anim::value _animValueBottomLineAlpha;