Cached both main and footer charts in single linear chart view.

This commit is contained in:
23rd 2023-07-27 01:49:53 +03:00 committed by John Preston
parent 2055cc70d1
commit 25c97a3ee8
4 changed files with 36 additions and 37 deletions

View file

@ -822,7 +822,7 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
, _animationController([=] { , _animationController([=] {
_chartArea->update(); _chartArea->update();
if (_animationController.footerAnimating() if (_animationController.footerAnimating()
|| !_linearChartView.main->isFinished()) { || !_linearChartView->isFinished()) {
_footer->update(); _footer->update();
} }
}) { }) {
@ -900,7 +900,7 @@ void ChartWidget::setupChartArea() {
now, now,
_horizontalLines, _horizontalLines,
_bottomLine.dates, _bottomLine.dates,
_linearChartView.main); _linearChartView);
const auto chartRect = chartAreaRect(); const auto chartRect = chartAreaRect();
@ -934,7 +934,7 @@ void ChartWidget::setupChartArea() {
for (const auto &line : _chartData.lines) { for (const auto &line : _chartData.lines) {
_details.widget->setLineAlpha( _details.widget->setLineAlpha(
line.id, line.id,
_linearChartView.main->alpha(line.id)); _linearChartView->alpha(line.id));
} }
} }
} }
@ -949,15 +949,15 @@ void ChartWidget::setupChartArea() {
// QPainter::Antialiasing, // QPainter::Antialiasing,
// !_animationController.isFPSSlow() // !_animationController.isFPSSlow()
// || !_animationController.animating()); // || !_animationController.animating());
PainterHighQualityEnabler hp(p); _linearChartView->paint(
_linearChartView.main->paint(
p, p,
_chartData, _chartData,
_animationController.currentXIndices(), _animationController.currentXIndices(),
_animationController.currentXLimits(), _animationController.currentXLimits(),
_animationController.currentHeightLimits(), _animationController.currentHeightLimits(),
chartRect, chartRect,
detailsPaintContext); detailsPaintContext,
false);
} }
for (auto &horizontalLine : _horizontalLines) { for (auto &horizontalLine : _horizontalLines) {
@ -1074,14 +1074,15 @@ void ChartWidget::setupFooter() {
// !_animationController.isFPSSlow() // !_animationController.isFPSSlow()
// || !_animationController.animating()); // || !_animationController.animating());
PainterHighQualityEnabler hp(p); PainterHighQualityEnabler hp(p);
_linearChartView.footer->paint( _linearChartView->paint(
p, p,
_chartData, _chartData,
{ 0., float64(_chartData.x.size() - 1) }, { 0., float64(_chartData.x.size() - 1) },
fullXLimits, fullXLimits,
_animationController.currentFooterHeightLimits(), _animationController.currentFooterHeightLimits(),
r, r,
detailsPaintContext); detailsPaintContext,
true);
} }
}); });
@ -1097,7 +1098,7 @@ void ChartWidget::setupFooter() {
_animationController.setXPercentageLimits( _animationController.setXPercentageLimits(
_chartData, _chartData,
xPercentageLimits, xPercentageLimits,
_linearChartView.main, _linearChartView,
now); now);
updateChartFullWidth(_chartArea->width()); updateChartFullWidth(_chartArea->width());
updateBottomDates(); updateBottomDates();
@ -1215,12 +1216,12 @@ void ChartWidget::setupFilterButtons() {
_filterButtons->buttonEnabledChanges( _filterButtons->buttonEnabledChanges(
) | rpl::start_with_next([=](const ChartLinesFilterWidget::Entry &e) { ) | rpl::start_with_next([=](const ChartLinesFilterWidget::Entry &e) {
const auto now = crl::now(); const auto now = crl::now();
_linearChartView.main->setEnabled(e.id, e.enabled, now); _linearChartView->setEnabled(e.id, e.enabled, now);
_animationController.setXPercentageLimits( _animationController.setXPercentageLimits(
_chartData, _chartData,
_animationController.currentXLimits(), _animationController.currentXLimits(),
_linearChartView.main, _linearChartView,
now); now);
}, _filterButtons->lifetime()); }, _filterButtons->lifetime());
} }
@ -1228,8 +1229,7 @@ void ChartWidget::setupFilterButtons() {
void ChartWidget::setChartData(Data::StatisticalChart chartData) { void ChartWidget::setChartData(Data::StatisticalChart chartData) {
_chartData = std::move(chartData); _chartData = std::move(chartData);
_linearChartView.main = std::make_unique<LinearChartView>(); _linearChartView = std::make_unique<LinearChartView>();
_linearChartView.footer = std::make_unique<LinearChartView>();
setupDetails(); setupDetails();
setupFilterButtons(); setupFilterButtons();
@ -1237,7 +1237,7 @@ void ChartWidget::setChartData(Data::StatisticalChart chartData) {
_animationController.setXPercentageLimits( _animationController.setXPercentageLimits(
_chartData, _chartData,
{ _chartData.xPercentage.front(), _chartData.xPercentage.back() }, { _chartData.xPercentage.front(), _chartData.xPercentage.back() },
_linearChartView.main, _linearChartView,
0); 0);
updateChartFullWidth(_chartArea->width()); updateChartFullWidth(_chartArea->width());
updateBottomDates(); updateBottomDates();

View file

@ -131,10 +131,7 @@ private:
base::unique_qptr<ChartLinesFilterWidget> _filterButtons; base::unique_qptr<ChartLinesFilterWidget> _filterButtons;
Data::StatisticalChart _chartData; Data::StatisticalChart _chartData;
struct { std::unique_ptr<LinearChartView> _linearChartView;
std::unique_ptr<LinearChartView> main;
std::unique_ptr<LinearChartView> footer;
} _linearChartView;
struct { struct {
base::unique_qptr<PointDetailsWidget> widget; base::unique_qptr<PointDetailsWidget> widget;

View file

@ -64,7 +64,8 @@ void LinearChartView::paint(
const Limits &xPercentageLimits, const Limits &xPercentageLimits,
const Limits &heightLimits, const Limits &heightLimits,
const QRect &rect, const QRect &rect,
DetailsPaintContext &detailsPaintContext) { DetailsPaintContext &detailsPaintContext,
bool footer) {
const auto cacheToken = LinearChartView::CacheToken( const auto cacheToken = LinearChartView::CacheToken(
xIndices, xIndices,
@ -72,42 +73,38 @@ void LinearChartView::paint(
heightLimits, heightLimits,
rect.size()); rect.size());
const auto imageSize = rect.size() * style::DevicePixelRatio();
const auto cacheScale = 1. / style::DevicePixelRatio();
auto &caches = (footer ? _footerCaches : _mainCaches);
for (auto i = 0; i < chartData.lines.size(); i++) { for (auto i = 0; i < chartData.lines.size(); i++) {
const auto &line = chartData.lines[i]; const auto &line = chartData.lines[i];
p.setOpacity(alpha(line.id)); p.setOpacity(alpha(line.id));
if (!p.opacity()) { if (!p.opacity()) {
continue; continue;
} }
if (p.opacity() < 1.) {
// p.setRenderHint(QPainter::Antialiasing, false);
}
//// auto &cache = caches[line.id];
auto &cache = _caches[line.id];
const auto isSameToken = (cache.lastToken == cacheToken); const auto isSameToken = (cache.lastToken == cacheToken);
if (isSameToken && cache.hq) { if ((isSameToken && cache.hq)
|| (p.opacity() < 1. && !isEnabled(line.id))) {
p.drawImage(rect.topLeft(), cache.image); p.drawImage(rect.topLeft(), cache.image);
continue; continue;
} }
const auto ratio = style::DevicePixelRatio();
cache.hq = isSameToken; cache.hq = isSameToken;
auto image = QImage(); auto image = QImage();
image = QImage( image = QImage(
rect.size() * style::DevicePixelRatio() * (isSameToken ? 1. : ratio), imageSize * (isSameToken ? 1. : cacheScale),
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
image.setDevicePixelRatio(style::DevicePixelRatio()); image.setDevicePixelRatio(style::DevicePixelRatio());
image.fill(Qt::transparent); image.fill(Qt::transparent);
// image.fill(Qt::darkRed);
{ {
auto imagePainter = QPainter(&image); auto imagePainter = QPainter(&image);
imagePainter.setRenderHint(QPainter::Antialiasing, true); auto hq = PainterHighQualityEnabler(imagePainter);
if (isSameToken) { if (!isSameToken) {
// PainterHighQualityEnabler hp(imagePainter); imagePainter.scale(cacheScale, cacheScale);
} else {
imagePainter.scale(ratio, ratio);
} }
////
PaintChartLine( PaintChartLine(
imagePainter, imagePainter,
@ -120,7 +117,10 @@ void LinearChartView::paint(
} }
if (!isSameToken) { if (!isSameToken) {
image = image.scaled(rect.size() * style::DevicePixelRatio(), Qt::IgnoreAspectRatio, Qt::FastTransformation); image = image.scaled(
imageSize,
Qt::IgnoreAspectRatio,
Qt::FastTransformation);
} }
p.drawImage(rect.topLeft(), image); p.drawImage(rect.topLeft(), image);
cache.lastToken = cacheToken; cache.lastToken = cacheToken;

View file

@ -29,7 +29,8 @@ public:
const Limits &xPercentageLimits, const Limits &xPercentageLimits,
const Limits &heightLimits, const Limits &heightLimits,
const QRect &rect, const QRect &rect,
DetailsPaintContext &detailsPaintContext); DetailsPaintContext &detailsPaintContext,
bool footer);
void setEnabled(int id, bool enabled, crl::time now); void setEnabled(int id, bool enabled, crl::time now);
[[nodiscard]] bool isEnabled(int id) const; [[nodiscard]] bool isEnabled(int id) const;
@ -78,7 +79,8 @@ private:
bool hq = false; bool hq = false;
}; };
base::flat_map<int, Cache> _caches; base::flat_map<int, Cache> _mainCaches;
base::flat_map<int, Cache> _footerCaches;
struct Entry final { struct Entry final {
bool enabled = false; bool enabled = false;