mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 07:33:52 +02:00
Added initial display of footer while chart lines are filtering.
This commit is contained in:
parent
ee172d951d
commit
64bb818fe9
2 changed files with 66 additions and 67 deletions
|
@ -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() },
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue