Replaced static function for linear chart paint with dedicated class.
This commit is contained in:
parent
f473a1a804
commit
1209bd35c5
|
@ -950,7 +950,7 @@ void ChartWidget::setupChartArea() {
|
||||||
// !_animationController.isFPSSlow()
|
// !_animationController.isFPSSlow()
|
||||||
// || !_animationController.animating());
|
// || !_animationController.animating());
|
||||||
PainterHighQualityEnabler hp(p);
|
PainterHighQualityEnabler hp(p);
|
||||||
Statistic::PaintLinearChartView(
|
_linearChartPainter.main->paint(
|
||||||
p,
|
p,
|
||||||
_chartData,
|
_chartData,
|
||||||
_animationController.currentXIndices(),
|
_animationController.currentXIndices(),
|
||||||
|
@ -1076,7 +1076,7 @@ void ChartWidget::setupFooter() {
|
||||||
// || !_animationController.animating());
|
// || !_animationController.animating());
|
||||||
PainterHighQualityEnabler hp(p);
|
PainterHighQualityEnabler hp(p);
|
||||||
_animatedChartLines.setCacheFooter(true);
|
_animatedChartLines.setCacheFooter(true);
|
||||||
Statistic::PaintLinearChartView(
|
_linearChartPainter.footer->paint(
|
||||||
p,
|
p,
|
||||||
_chartData,
|
_chartData,
|
||||||
{ 0., float64(_chartData.x.size() - 1) },
|
{ 0., float64(_chartData.x.size() - 1) },
|
||||||
|
@ -1254,6 +1254,9 @@ void ChartWidget::setupFilterButtons() {
|
||||||
void ChartWidget::setChartData(Data::StatisticalChart chartData) {
|
void ChartWidget::setChartData(Data::StatisticalChart chartData) {
|
||||||
_chartData = std::move(chartData);
|
_chartData = std::move(chartData);
|
||||||
|
|
||||||
|
_linearChartPainter.main = std::make_unique<LinearChartPainter>();
|
||||||
|
_linearChartPainter.footer = std::make_unique<LinearChartPainter>();
|
||||||
|
|
||||||
setupDetails();
|
setupDetails();
|
||||||
setupFilterButtons();
|
setupFilterButtons();
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace Statistic {
|
||||||
class RpMouseWidget;
|
class RpMouseWidget;
|
||||||
class PointDetailsWidget;
|
class PointDetailsWidget;
|
||||||
class ChartLinesFilterWidget;
|
class ChartLinesFilterWidget;
|
||||||
|
class LinearChartPainter;
|
||||||
|
|
||||||
class ChartWidget : public Ui::RpWidget {
|
class ChartWidget : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
|
@ -132,6 +133,10 @@ private:
|
||||||
Data::StatisticalChart _chartData;
|
Data::StatisticalChart _chartData;
|
||||||
|
|
||||||
ChartLineViewContext _animatedChartLines;
|
ChartLineViewContext _animatedChartLines;
|
||||||
|
struct {
|
||||||
|
std::unique_ptr<LinearChartPainter> main;
|
||||||
|
std::unique_ptr<LinearChartPainter> footer;
|
||||||
|
} _linearChartPainter;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
base::unique_qptr<PointDetailsWidget> widget;
|
base::unique_qptr<PointDetailsWidget> widget;
|
||||||
|
|
|
@ -16,6 +16,43 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_statistics.h"
|
#include "styles/style_statistics.h"
|
||||||
|
|
||||||
namespace Statistic {
|
namespace Statistic {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void PaintChartLine(
|
||||||
|
QPainter &p,
|
||||||
|
int lineIndex,
|
||||||
|
const Data::StatisticalChart &chartData,
|
||||||
|
const Limits &xIndices,
|
||||||
|
const Limits &xPercentageLimits,
|
||||||
|
const Limits &heightLimits,
|
||||||
|
const QSize &size) {
|
||||||
|
const auto &line = chartData.lines[lineIndex];
|
||||||
|
|
||||||
|
auto chartPoints = QPolygonF();
|
||||||
|
|
||||||
|
const auto localStart = std::max(0, int(xIndices.min));
|
||||||
|
const auto localEnd = std::min(
|
||||||
|
int(chartData.xPercentage.size() - 1),
|
||||||
|
int(xIndices.max));
|
||||||
|
|
||||||
|
for (auto i = localStart; i <= localEnd; i++) {
|
||||||
|
if (line.y[i] < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto xPoint = size.width()
|
||||||
|
* ((chartData.xPercentage[i] - xPercentageLimits.min)
|
||||||
|
/ (xPercentageLimits.max - xPercentageLimits.min));
|
||||||
|
const auto yPercentage = (line.y[i] - heightLimits.min)
|
||||||
|
/ float64(heightLimits.max - heightLimits.min);
|
||||||
|
const auto yPoint = (1. - yPercentage) * size.height();
|
||||||
|
chartPoints << QPointF(xPoint, yPoint);
|
||||||
|
}
|
||||||
|
p.setPen(QPen(line.color, st::statisticsChartLineWidth));
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
p.drawPolyline(chartPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void PaintLinearChartView(
|
void PaintLinearChartView(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
|
@ -117,4 +154,78 @@ void PaintLinearChartView(
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinearChartPainter::LinearChartPainter() = default;
|
||||||
|
|
||||||
|
void LinearChartPainter::paint(
|
||||||
|
QPainter &p,
|
||||||
|
const Data::StatisticalChart &chartData,
|
||||||
|
const Limits &xIndices,
|
||||||
|
const Limits &xPercentageLimits,
|
||||||
|
const Limits &heightLimits,
|
||||||
|
const QRect &rect,
|
||||||
|
ChartLineViewContext &lineViewContext,
|
||||||
|
DetailsPaintContext &detailsPaintContext) {
|
||||||
|
|
||||||
|
const auto cacheToken = LinearChartPainter::CacheToken(
|
||||||
|
xIndices,
|
||||||
|
xPercentageLimits,
|
||||||
|
heightLimits,
|
||||||
|
rect.size());
|
||||||
|
|
||||||
|
for (auto i = 0; i < chartData.lines.size(); i++) {
|
||||||
|
const auto &line = chartData.lines[i];
|
||||||
|
p.setOpacity(lineViewContext.alpha(line.id));
|
||||||
|
if (!p.opacity()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (p.opacity() < 1.) {
|
||||||
|
// p.setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
////
|
||||||
|
auto &cache = _caches[line.id];
|
||||||
|
|
||||||
|
const auto isSameToken = (cache.lastToken == cacheToken);
|
||||||
|
if (isSameToken && cache.hq) {
|
||||||
|
p.drawImage(rect.topLeft(), cache.image);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto ratio = style::DevicePixelRatio();
|
||||||
|
cache.hq = isSameToken;
|
||||||
|
auto image = QImage();
|
||||||
|
image = QImage(
|
||||||
|
rect.size() * style::DevicePixelRatio() * (isSameToken ? 1. : ratio),
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
image.setDevicePixelRatio(style::DevicePixelRatio());
|
||||||
|
image.fill(Qt::transparent);
|
||||||
|
// image.fill(Qt::darkRed);
|
||||||
|
{
|
||||||
|
auto imagePainter = QPainter(&image);
|
||||||
|
imagePainter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
if (isSameToken) {
|
||||||
|
// PainterHighQualityEnabler hp(imagePainter);
|
||||||
|
} else {
|
||||||
|
imagePainter.scale(ratio, ratio);
|
||||||
|
}
|
||||||
|
////
|
||||||
|
|
||||||
|
PaintChartLine(
|
||||||
|
imagePainter,
|
||||||
|
i,
|
||||||
|
chartData,
|
||||||
|
xIndices,
|
||||||
|
xPercentageLimits,
|
||||||
|
heightLimits,
|
||||||
|
rect.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSameToken) {
|
||||||
|
image = image.scaled(rect.size() * style::DevicePixelRatio(), Qt::IgnoreAspectRatio, Qt::FastTransformation);
|
||||||
|
}
|
||||||
|
p.drawImage(rect.topLeft(), image);
|
||||||
|
cache.lastToken = cacheToken;
|
||||||
|
cache.image = std::move(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Statistic
|
} // namespace Statistic
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <statistics/statistics_common.h>
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
struct StatisticalChart;
|
struct StatisticalChart;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
@ -17,6 +19,64 @@ struct Limits;
|
||||||
struct DetailsPaintContext;
|
struct DetailsPaintContext;
|
||||||
struct ChartLineViewContext;
|
struct ChartLineViewContext;
|
||||||
|
|
||||||
|
class LinearChartPainter {
|
||||||
|
public:
|
||||||
|
LinearChartPainter();
|
||||||
|
|
||||||
|
void paint(
|
||||||
|
QPainter &p,
|
||||||
|
const Data::StatisticalChart &chartData,
|
||||||
|
const Limits &xIndices,
|
||||||
|
const Limits &xPercentageLimits,
|
||||||
|
const Limits &heightLimits,
|
||||||
|
const QRect &rect,
|
||||||
|
ChartLineViewContext &lineViewContext,
|
||||||
|
DetailsPaintContext &detailsPaintContext);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct CacheToken final {
|
||||||
|
explicit CacheToken() = default;
|
||||||
|
explicit CacheToken(
|
||||||
|
Limits xIndices,
|
||||||
|
Limits xPercentageLimits,
|
||||||
|
Limits heightLimits,
|
||||||
|
QSize rectSize)
|
||||||
|
: xIndices(std::move(xIndices))
|
||||||
|
, xPercentageLimits(std::move(xPercentageLimits))
|
||||||
|
, heightLimits(std::move(heightLimits))
|
||||||
|
, rectSize(std::move(rectSize)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const CacheToken &other) const {
|
||||||
|
return (rectSize == other.rectSize)
|
||||||
|
&& (xIndices.min == other.xIndices.min)
|
||||||
|
&& (xIndices.max == other.xIndices.max)
|
||||||
|
&& (xPercentageLimits.min == other.xPercentageLimits.min)
|
||||||
|
&& (xPercentageLimits.max == other.xPercentageLimits.max)
|
||||||
|
&& (heightLimits.min == other.heightLimits.min)
|
||||||
|
&& (heightLimits.max == other.heightLimits.max);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const CacheToken &other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
Limits xIndices;
|
||||||
|
Limits xPercentageLimits;
|
||||||
|
Limits heightLimits;
|
||||||
|
QSize rectSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Cache final {
|
||||||
|
QImage image;
|
||||||
|
CacheToken lastToken;
|
||||||
|
bool hq = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
base::flat_map<int, Cache> _caches;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
void PaintLinearChartView(
|
void PaintLinearChartView(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const Data::StatisticalChart &chartData,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user