mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 23:24:01 +02:00
Moved out context for chart paint to separated structure.
This commit is contained in:
parent
e4e85e5a39
commit
a9b0464726
8 changed files with 192 additions and 320 deletions
|
@ -923,22 +923,24 @@ void ChartWidget::setupChartArea() {
|
||||||
|
|
||||||
p.fillRect(r, st::boxBg);
|
p.fillRect(r, st::boxBg);
|
||||||
|
|
||||||
|
if (!_chartData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_horizontalLinesView.paintHorizontalLines(p, chartRect);
|
_horizontalLinesView.paintHorizontalLines(p, chartRect);
|
||||||
|
|
||||||
if (_chartData) {
|
const auto context = PaintContext{
|
||||||
// p.setRenderHint(
|
_chartData,
|
||||||
// QPainter::Antialiasing,
|
_animationController.currentXIndices(),
|
||||||
// !_animationController.isFPSSlow()
|
_animationController.currentXLimits(),
|
||||||
// || !_animationController.animating());
|
_animationController.currentHeightLimits(),
|
||||||
|
chartRect,
|
||||||
|
false,
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
PainterHighQualityEnabler hp(p);
|
PainterHighQualityEnabler hp(p);
|
||||||
_chartView->paint(
|
_chartView->paint(p, context);
|
||||||
p,
|
|
||||||
_chartData,
|
|
||||||
_animationController.currentXIndices(),
|
|
||||||
_animationController.currentXLimits(),
|
|
||||||
_animationController.currentHeightLimits(),
|
|
||||||
chartRect,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_horizontalLinesView.paintCaptionsToHorizontalLines(p, chartRect);
|
_horizontalLinesView.paintCaptionsToHorizontalLines(p, chartRect);
|
||||||
|
@ -960,10 +962,7 @@ void ChartWidget::setupChartArea() {
|
||||||
}
|
}
|
||||||
_chartView->paintSelectedXIndex(
|
_chartView->paintSelectedXIndex(
|
||||||
p,
|
p,
|
||||||
_chartData,
|
context,
|
||||||
_animationController.currentXLimits(),
|
|
||||||
_animationController.currentHeightLimits(),
|
|
||||||
chartRect,
|
|
||||||
_details.widget->xIndex(),
|
_details.widget->xIndex(),
|
||||||
detailsAlpha);
|
detailsAlpha);
|
||||||
}
|
}
|
||||||
|
@ -1069,19 +1068,18 @@ void ChartWidget::setupFooter() {
|
||||||
const QRect &r) {
|
const QRect &r) {
|
||||||
if (_chartData) {
|
if (_chartData) {
|
||||||
p.fillRect(r, st::boxBg);
|
p.fillRect(r, st::boxBg);
|
||||||
// p.setRenderHint(
|
|
||||||
// QPainter::Antialiasing,
|
auto hp = PainterHighQualityEnabler(p);
|
||||||
// !_animationController.isFPSSlow()
|
|
||||||
// || !_animationController.animating());
|
|
||||||
PainterHighQualityEnabler hp(p);
|
|
||||||
_chartView->paint(
|
_chartView->paint(
|
||||||
p,
|
p,
|
||||||
_chartData,
|
PaintContext{
|
||||||
{ 0., float64(_chartData.x.size() - 1) },
|
_chartData,
|
||||||
fullXLimits,
|
{ 0., float64(_chartData.x.size() - 1) },
|
||||||
_animationController.currentFooterHeightLimits(),
|
fullXLimits,
|
||||||
r,
|
_animationController.currentFooterHeightLimits(),
|
||||||
true);
|
r,
|
||||||
|
true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,25 +15,24 @@ namespace Statistic {
|
||||||
|
|
||||||
struct Limits;
|
struct Limits;
|
||||||
|
|
||||||
|
struct PaintContext final {
|
||||||
|
const Data::StatisticalChart &chartData;
|
||||||
|
const Limits &xIndices;
|
||||||
|
const Limits &xPercentageLimits;
|
||||||
|
const Limits &heightLimits;
|
||||||
|
const QRect ▭
|
||||||
|
bool footer = false;
|
||||||
|
};
|
||||||
|
|
||||||
class AbstractChartView {
|
class AbstractChartView {
|
||||||
public:
|
public:
|
||||||
virtual ~AbstractChartView() = default;
|
virtual ~AbstractChartView() = default;
|
||||||
|
|
||||||
virtual void paint(
|
virtual void paint(QPainter &p, const PaintContext &c) = 0;
|
||||||
QPainter &p,
|
|
||||||
const Data::StatisticalChart &chartData,
|
|
||||||
const Limits &xIndices,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) = 0;
|
|
||||||
|
|
||||||
virtual void paintSelectedXIndex(
|
virtual void paintSelectedXIndex(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c,
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
int selectedXIndex,
|
int selectedXIndex,
|
||||||
float64 progress) = 0;
|
float64 progress) = 0;
|
||||||
|
|
||||||
|
|
|
@ -26,20 +26,16 @@ float64 Ratio(const LinearChartView::CachedLineRatios &ratios, int id) {
|
||||||
void PaintChartLine(
|
void PaintChartLine(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
int lineIndex,
|
int lineIndex,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c,
|
||||||
const Limits &xIndices,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QSize &size,
|
|
||||||
const LinearChartView::CachedLineRatios &ratios) {
|
const LinearChartView::CachedLineRatios &ratios) {
|
||||||
const auto &line = chartData.lines[lineIndex];
|
const auto &line = c.chartData.lines[lineIndex];
|
||||||
|
|
||||||
auto chartPoints = QPolygonF();
|
auto chartPoints = QPolygonF();
|
||||||
|
|
||||||
const auto localStart = std::max(0, int(xIndices.min));
|
const auto localStart = std::max(0, int(c.xIndices.min));
|
||||||
const auto localEnd = std::min(
|
const auto localEnd = std::min(
|
||||||
int(chartData.xPercentage.size() - 1),
|
int(c.chartData.xPercentage.size() - 1),
|
||||||
int(xIndices.max));
|
int(c.xIndices.max));
|
||||||
|
|
||||||
const auto ratio = Ratio(ratios, line.id);
|
const auto ratio = Ratio(ratios, line.id);
|
||||||
|
|
||||||
|
@ -47,12 +43,12 @@ void PaintChartLine(
|
||||||
if (line.y[i] < 0) {
|
if (line.y[i] < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto xPoint = size.width()
|
const auto xPoint = c.rect.width()
|
||||||
* ((chartData.xPercentage[i] - xPercentageLimits.min)
|
* ((c.chartData.xPercentage[i] - c.xPercentageLimits.min)
|
||||||
/ (xPercentageLimits.max - xPercentageLimits.min));
|
/ (c.xPercentageLimits.max - c.xPercentageLimits.min));
|
||||||
const auto yPercentage = (line.y[i] * ratio - heightLimits.min)
|
const auto yPercentage = (line.y[i] * ratio - c.heightLimits.min)
|
||||||
/ float64(heightLimits.max - heightLimits.min);
|
/ float64(c.heightLimits.max - c.heightLimits.min);
|
||||||
const auto yPoint = (1. - yPercentage) * size.height();
|
const auto yPoint = (1. - yPercentage) * c.rect.height();
|
||||||
chartPoints << QPointF(xPoint, yPoint);
|
chartPoints << QPointF(xPoint, yPoint);
|
||||||
}
|
}
|
||||||
p.setPen(QPen(line.color, st::statisticsChartLineWidth));
|
p.setPen(QPen(line.color, st::statisticsChartLineWidth));
|
||||||
|
@ -68,27 +64,19 @@ LinearChartView::LinearChartView(bool isDouble)
|
||||||
|
|
||||||
LinearChartView::~LinearChartView() = default;
|
LinearChartView::~LinearChartView() = default;
|
||||||
|
|
||||||
void LinearChartView::paint(
|
void LinearChartView::paint(QPainter &p, const PaintContext &c) {
|
||||||
QPainter &p,
|
|
||||||
const Data::StatisticalChart &chartData,
|
|
||||||
const Limits &xIndices,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) {
|
|
||||||
|
|
||||||
const auto cacheToken = LinearChartView::CacheToken(
|
const auto cacheToken = LinearChartView::CacheToken(
|
||||||
xIndices,
|
c.xIndices,
|
||||||
xPercentageLimits,
|
c.xPercentageLimits,
|
||||||
heightLimits,
|
c.heightLimits,
|
||||||
rect.size());
|
c.rect.size());
|
||||||
|
|
||||||
const auto imageSize = rect.size() * style::DevicePixelRatio();
|
const auto imageSize = c.rect.size() * style::DevicePixelRatio();
|
||||||
const auto cacheScale = 1. / style::DevicePixelRatio();
|
const auto cacheScale = 1. / style::DevicePixelRatio();
|
||||||
auto &caches = (footer ? _footerCaches : _mainCaches);
|
auto &caches = (c.footer ? _footerCaches : _mainCaches);
|
||||||
|
|
||||||
for (auto i = 0; i < chartData.lines.size(); i++) {
|
for (auto i = 0; i < c.chartData.lines.size(); i++) {
|
||||||
const auto &line = chartData.lines[i];
|
const auto &line = c.chartData.lines[i];
|
||||||
p.setOpacity(alpha(line.id));
|
p.setOpacity(alpha(line.id));
|
||||||
if (!p.opacity()) {
|
if (!p.opacity()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -99,7 +87,7 @@ void LinearChartView::paint(
|
||||||
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.opacity() < 1. && !isEnabled(line.id))) {
|
||||||
p.drawImage(rect.topLeft(), cache.image);
|
p.drawImage(c.rect.topLeft(), cache.image);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cache.hq = isSameToken;
|
cache.hq = isSameToken;
|
||||||
|
@ -116,15 +104,7 @@ void LinearChartView::paint(
|
||||||
imagePainter.scale(cacheScale, cacheScale);
|
imagePainter.scale(cacheScale, cacheScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
PaintChartLine(
|
PaintChartLine(imagePainter, i, c, _cachedLineRatios);
|
||||||
imagePainter,
|
|
||||||
i,
|
|
||||||
chartData,
|
|
||||||
xIndices,
|
|
||||||
xPercentageLimits,
|
|
||||||
heightLimits,
|
|
||||||
rect.size(),
|
|
||||||
_cachedLineRatios);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSameToken) {
|
if (!isSameToken) {
|
||||||
|
@ -133,7 +113,7 @@ void LinearChartView::paint(
|
||||||
Qt::IgnoreAspectRatio,
|
Qt::IgnoreAspectRatio,
|
||||||
Qt::FastTransformation);
|
Qt::FastTransformation);
|
||||||
}
|
}
|
||||||
p.drawImage(rect.topLeft(), image);
|
p.drawImage(c.rect.topLeft(), image);
|
||||||
cache.lastToken = cacheToken;
|
cache.lastToken = cacheToken;
|
||||||
cache.image = std::move(image);
|
cache.image = std::move(image);
|
||||||
}
|
}
|
||||||
|
@ -141,10 +121,7 @@ void LinearChartView::paint(
|
||||||
|
|
||||||
void LinearChartView::paintSelectedXIndex(
|
void LinearChartView::paintSelectedXIndex(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c,
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
int selectedXIndex,
|
int selectedXIndex,
|
||||||
float64 progress) {
|
float64 progress) {
|
||||||
if (selectedXIndex < 0) {
|
if (selectedXIndex < 0) {
|
||||||
|
@ -156,36 +133,36 @@ void LinearChartView::paintSelectedXIndex(
|
||||||
const auto r = st::statisticsDetailsDotRadius;
|
const auto r = st::statisticsDetailsDotRadius;
|
||||||
const auto i = selectedXIndex;
|
const auto i = selectedXIndex;
|
||||||
const auto isSameToken = (_selectedPoints.lastXIndex == selectedXIndex)
|
const auto isSameToken = (_selectedPoints.lastXIndex == selectedXIndex)
|
||||||
&& (_selectedPoints.lastHeightLimits.min == heightLimits.min)
|
&& (_selectedPoints.lastHeightLimits.min == c.heightLimits.min)
|
||||||
&& (_selectedPoints.lastHeightLimits.max == heightLimits.max)
|
&& (_selectedPoints.lastHeightLimits.max == c.heightLimits.max)
|
||||||
&& (_selectedPoints.lastXLimits.min == xPercentageLimits.min)
|
&& (_selectedPoints.lastXLimits.min == c.xPercentageLimits.min)
|
||||||
&& (_selectedPoints.lastXLimits.max == xPercentageLimits.max);
|
&& (_selectedPoints.lastXLimits.max == c.xPercentageLimits.max);
|
||||||
auto linePainted = false;
|
auto linePainted = false;
|
||||||
for (const auto &line : chartData.lines) {
|
for (const auto &line : c.chartData.lines) {
|
||||||
const auto lineAlpha = alpha(line.id);
|
const auto lineAlpha = alpha(line.id);
|
||||||
const auto useCache = isSameToken
|
const auto useCache = isSameToken
|
||||||
|| (lineAlpha < 1. && !isEnabled(line.id));
|
|| (lineAlpha < 1. && !isEnabled(line.id));
|
||||||
if (!useCache) {
|
if (!useCache) {
|
||||||
// Calculate.
|
// Calculate.
|
||||||
const auto r = Ratio(_cachedLineRatios, line.id);
|
const auto r = Ratio(_cachedLineRatios, line.id);
|
||||||
const auto xPoint = rect.width()
|
const auto xPoint = c.rect.width()
|
||||||
* ((chartData.xPercentage[i] - xPercentageLimits.min)
|
* ((c.chartData.xPercentage[i] - c.xPercentageLimits.min)
|
||||||
/ (xPercentageLimits.max - xPercentageLimits.min));
|
/ (c.xPercentageLimits.max - c.xPercentageLimits.min));
|
||||||
const auto yPercentage = (line.y[i] * r - heightLimits.min)
|
const auto yPercentage = (line.y[i] * r - c.heightLimits.min)
|
||||||
/ float64(heightLimits.max - heightLimits.min);
|
/ float64(c.heightLimits.max - c.heightLimits.min);
|
||||||
const auto yPoint = (1. - yPercentage) * rect.height();
|
const auto yPoint = (1. - yPercentage) * c.rect.height();
|
||||||
_selectedPoints.points[line.id] = QPointF(xPoint, yPoint)
|
_selectedPoints.points[line.id] = QPointF(xPoint, yPoint)
|
||||||
+ rect.topLeft();
|
+ c.rect.topLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!linePainted) {
|
if (!linePainted) {
|
||||||
const auto lineRect = QRectF(
|
const auto lineRect = QRectF(
|
||||||
rect.x()
|
c.rect.x()
|
||||||
+ begin(_selectedPoints.points)->second.x()
|
+ begin(_selectedPoints.points)->second.x()
|
||||||
- (st::lineWidth / 2.),
|
- (st::lineWidth / 2.),
|
||||||
rect.y(),
|
c.rect.y(),
|
||||||
st::lineWidth,
|
st::lineWidth,
|
||||||
rect.height());
|
c.rect.height());
|
||||||
p.fillRect(lineRect, st::windowSubTextFg);
|
p.fillRect(lineRect, st::windowSubTextFg);
|
||||||
linePainted = true;
|
linePainted = true;
|
||||||
}
|
}
|
||||||
|
@ -196,8 +173,8 @@ void LinearChartView::paintSelectedXIndex(
|
||||||
p.drawEllipse(_selectedPoints.points[line.id], r, r);
|
p.drawEllipse(_selectedPoints.points[line.id], r, r);
|
||||||
}
|
}
|
||||||
_selectedPoints.lastXIndex = selectedXIndex;
|
_selectedPoints.lastXIndex = selectedXIndex;
|
||||||
_selectedPoints.lastHeightLimits = heightLimits;
|
_selectedPoints.lastHeightLimits = c.heightLimits;
|
||||||
_selectedPoints.lastXLimits = xPercentageLimits;
|
_selectedPoints.lastXLimits = c.xPercentageLimits;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LinearChartView::findXIndexByPosition(
|
int LinearChartView::findXIndexByPosition(
|
||||||
|
|
|
@ -25,21 +25,11 @@ public:
|
||||||
LinearChartView(bool isDouble);
|
LinearChartView(bool isDouble);
|
||||||
~LinearChartView() override final;
|
~LinearChartView() override final;
|
||||||
|
|
||||||
void paint(
|
void paint(QPainter &p, const PaintContext &c) override;
|
||||||
QPainter &p,
|
|
||||||
const Data::StatisticalChart &chartData,
|
|
||||||
const Limits &xIndices,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) override;
|
|
||||||
|
|
||||||
void paintSelectedXIndex(
|
void paintSelectedXIndex(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c,
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
int selectedXIndex,
|
int selectedXIndex,
|
||||||
float64 progress) override;
|
float64 progress) override;
|
||||||
|
|
||||||
|
|
|
@ -23,76 +23,60 @@ StackChartView::StackChartView() = default;
|
||||||
|
|
||||||
StackChartView::~StackChartView() = default;
|
StackChartView::~StackChartView() = default;
|
||||||
|
|
||||||
void StackChartView::paint(
|
void StackChartView::paint(QPainter &p, const PaintContext &c) {
|
||||||
QPainter &p,
|
|
||||||
const Data::StatisticalChart &chartData,
|
|
||||||
const Limits &xIndices,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) {
|
|
||||||
constexpr auto kOffset = float64(2);
|
constexpr auto kOffset = float64(2);
|
||||||
_lastPaintedXIndices = {
|
_lastPaintedXIndices = {
|
||||||
float64(std::max(0., xIndices.min - kOffset)),
|
float64(std::max(0., c.xIndices.min - kOffset)),
|
||||||
float64(std::min(
|
float64(std::min(
|
||||||
float64(chartData.xPercentage.size() - 1),
|
float64(c.chartData.xPercentage.size() - 1),
|
||||||
xIndices.max + kOffset)),
|
c.xIndices.max + kOffset)),
|
||||||
};
|
};
|
||||||
|
|
||||||
StackChartView::paint(
|
StackChartView::paintChartAndSelected(p, c);
|
||||||
p,
|
|
||||||
chartData,
|
|
||||||
xPercentageLimits,
|
|
||||||
heightLimits,
|
|
||||||
rect,
|
|
||||||
footer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StackChartView::paint(
|
void StackChartView::paintChartAndSelected(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c) {
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) {
|
|
||||||
const auto &[localStart, localEnd] = _lastPaintedXIndices;
|
const auto &[localStart, localEnd] = _lastPaintedXIndices;
|
||||||
const auto &[leftStart, w] = ComputeLeftStartAndStep(
|
const auto &[leftStart, w] = ComputeLeftStartAndStep(
|
||||||
chartData,
|
c.chartData,
|
||||||
xPercentageLimits,
|
c.xPercentageLimits,
|
||||||
rect,
|
c.rect,
|
||||||
localStart);
|
localStart);
|
||||||
|
|
||||||
const auto opacity = p.opacity();
|
const auto opacity = p.opacity();
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
|
||||||
auto bottoms = std::vector<float64>(localEnd - localStart + 1, -rect.y());
|
auto bottoms = std::vector<float64>(
|
||||||
|
localEnd - localStart + 1,
|
||||||
|
-c.rect.y());
|
||||||
auto selectedBottoms = std::vector<float64>();
|
auto selectedBottoms = std::vector<float64>();
|
||||||
const auto hasSelectedXIndex = !footer && (_lastSelectedXIndex >= 0);
|
const auto hasSelectedXIndex = !c.footer && (_lastSelectedXIndex >= 0);
|
||||||
if (hasSelectedXIndex) {
|
if (hasSelectedXIndex) {
|
||||||
selectedBottoms = std::vector<float64>(chartData.lines.size(), 0);
|
selectedBottoms = std::vector<float64>(c.chartData.lines.size(), 0);
|
||||||
constexpr auto kSelectedAlpha = 0.5;
|
constexpr auto kSelectedAlpha = 0.5;
|
||||||
p.setOpacity(
|
p.setOpacity(
|
||||||
anim::interpolateF(1.0, kSelectedAlpha, _lastSelectedXProgress));
|
anim::interpolateF(1.0, kSelectedAlpha, _lastSelectedXProgress));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = 0; i < chartData.lines.size(); i++) {
|
for (auto i = 0; i < c.chartData.lines.size(); i++) {
|
||||||
const auto &line = chartData.lines[i];
|
const auto &line = c.chartData.lines[i];
|
||||||
auto path = QPainterPath();
|
auto path = QPainterPath();
|
||||||
for (auto x = localStart; x <= localEnd; x++) {
|
for (auto x = localStart; x <= localEnd; x++) {
|
||||||
if (line.y[x] <= 0) {
|
if (line.y[x] <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto xPoint = rect.width()
|
const auto yPercentage = (line.y[x] - c.heightLimits.min)
|
||||||
* ((chartData.xPercentage[x] - xPercentageLimits.min)
|
/ float64(c.heightLimits.max - c.heightLimits.min);
|
||||||
/ (xPercentageLimits.max - xPercentageLimits.min));
|
const auto yPoint = yPercentage
|
||||||
const auto yPercentage = (line.y[x] - heightLimits.min)
|
* c.rect.height()
|
||||||
/ float64(heightLimits.max - heightLimits.min);
|
* alpha(line.id);
|
||||||
const auto yPoint = yPercentage * rect.height() * alpha(line.id);
|
|
||||||
|
|
||||||
const auto bottomIndex = x - localStart;
|
const auto bottomIndex = x - localStart;
|
||||||
const auto column = QRectF(
|
const auto column = QRectF(
|
||||||
leftStart + (x - localStart) * w,
|
leftStart + (x - localStart) * w,
|
||||||
rect.height() - bottoms[bottomIndex] - yPoint,
|
c.rect.height() - bottoms[bottomIndex] - yPoint,
|
||||||
w,
|
w,
|
||||||
yPoint);
|
yPoint);
|
||||||
if (hasSelectedXIndex && (x == _lastSelectedXIndex)) {
|
if (hasSelectedXIndex && (x == _lastSelectedXIndex)) {
|
||||||
|
@ -110,10 +94,10 @@ void StackChartView::paint(
|
||||||
if (selectedBottoms[i] <= 0) {
|
if (selectedBottoms[i] <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto &line = chartData.lines[i];
|
const auto &line = c.chartData.lines[i];
|
||||||
const auto yPercentage = (line.y[_lastSelectedXIndex] - heightLimits.min)
|
const auto yPercentage = (line.y[_lastSelectedXIndex] - c.heightLimits.min)
|
||||||
/ float64(heightLimits.max - heightLimits.min);
|
/ float64(c.heightLimits.max - c.heightLimits.min);
|
||||||
const auto yPoint = yPercentage * rect.height() * alpha(line.id);
|
const auto yPoint = yPercentage * c.rect.height() * alpha(line.id);
|
||||||
|
|
||||||
const auto column = QRectF(
|
const auto column = QRectF(
|
||||||
leftStart + (_lastSelectedXIndex - localStart) * w,
|
leftStart + (_lastSelectedXIndex - localStart) * w,
|
||||||
|
@ -126,22 +110,13 @@ void StackChartView::paint(
|
||||||
|
|
||||||
void StackChartView::paintSelectedXIndex(
|
void StackChartView::paintSelectedXIndex(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c,
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
int selectedXIndex,
|
int selectedXIndex,
|
||||||
float64 progress) {
|
float64 progress) {
|
||||||
_lastSelectedXIndex = selectedXIndex;
|
_lastSelectedXIndex = selectedXIndex;
|
||||||
_lastSelectedXProgress = progress;
|
_lastSelectedXProgress = progress;
|
||||||
[[maybe_unused]] const auto o = ScopedPainterOpacity(p, progress);
|
[[maybe_unused]] const auto o = ScopedPainterOpacity(p, progress);
|
||||||
StackChartView::paint(
|
StackChartView::paintChartAndSelected(p, c);
|
||||||
p,
|
|
||||||
chartData,
|
|
||||||
xPercentageLimits,
|
|
||||||
heightLimits,
|
|
||||||
rect,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int StackChartView::findXIndexByPosition(
|
int StackChartView::findXIndexByPosition(
|
||||||
|
|
|
@ -25,21 +25,11 @@ public:
|
||||||
StackChartView();
|
StackChartView();
|
||||||
~StackChartView() override final;
|
~StackChartView() override final;
|
||||||
|
|
||||||
void paint(
|
void paint(QPainter &p, const PaintContext &c) override;
|
||||||
QPainter &p,
|
|
||||||
const Data::StatisticalChart &chartData,
|
|
||||||
const Limits &xIndices,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) override;
|
|
||||||
|
|
||||||
void paintSelectedXIndex(
|
void paintSelectedXIndex(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c,
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
int selectedXIndex,
|
int selectedXIndex,
|
||||||
float64 progress) override;
|
float64 progress) override;
|
||||||
|
|
||||||
|
@ -62,13 +52,7 @@ public:
|
||||||
void update(float64 dt) override;
|
void update(float64 dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paint(
|
void paintChartAndSelected(QPainter &p, const PaintContext &c);
|
||||||
QPainter &p,
|
|
||||||
const Data::StatisticalChart &chartData,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer);
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Limits full;
|
Limits full;
|
||||||
|
|
|
@ -48,28 +48,21 @@ StackLinearChartView::StackLinearChartView() = default;
|
||||||
|
|
||||||
StackLinearChartView::~StackLinearChartView() = default;
|
StackLinearChartView::~StackLinearChartView() = default;
|
||||||
|
|
||||||
void StackLinearChartView::paint(
|
void StackLinearChartView::paint(QPainter &p, const PaintContext &c) {
|
||||||
QPainter &p,
|
|
||||||
const Data::StatisticalChart &chartData,
|
|
||||||
const Limits &xIndices,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) {
|
|
||||||
constexpr auto kOffset = float64(2);
|
constexpr auto kOffset = float64(2);
|
||||||
const auto wasXIndices = _lastPaintedXIndices;
|
const auto wasXIndices = _lastPaintedXIndices;
|
||||||
_lastPaintedXIndices = {
|
_lastPaintedXIndices = {
|
||||||
float64(std::max(0., xIndices.min - kOffset)),
|
float64(std::max(0., c.xIndices.min - kOffset)),
|
||||||
float64(std::min(
|
float64(std::min(
|
||||||
float64(chartData.xPercentage.size() - 1),
|
float64(c.chartData.xPercentage.size() - 1),
|
||||||
xIndices.max + kOffset)),
|
c.xIndices.max + kOffset)),
|
||||||
};
|
};
|
||||||
if ((wasXIndices.min != _lastPaintedXIndices.min)
|
if ((wasXIndices.min != _lastPaintedXIndices.min)
|
||||||
|| (wasXIndices.max != _lastPaintedXIndices.max)) {
|
|| (wasXIndices.max != _lastPaintedXIndices.max)) {
|
||||||
|
|
||||||
const auto &[localStart, localEnd] = _lastPaintedXIndices;
|
const auto &[localStart, localEnd] = _lastPaintedXIndices;
|
||||||
_cachedTransition.lines = std::vector<Transition::TransitionLine>(
|
_cachedTransition.lines = std::vector<Transition::TransitionLine>(
|
||||||
chartData.lines.size(),
|
c.chartData.lines.size(),
|
||||||
Transition::TransitionLine());
|
Transition::TransitionLine());
|
||||||
|
|
||||||
for (auto j = 0; j < 2; j++) {
|
for (auto j = 0; j < 2; j++) {
|
||||||
|
@ -77,7 +70,7 @@ void StackLinearChartView::paint(
|
||||||
auto stackOffset = 0;
|
auto stackOffset = 0;
|
||||||
auto sum = 0.;
|
auto sum = 0.;
|
||||||
auto drawingLinesCount = 0;
|
auto drawingLinesCount = 0;
|
||||||
for (const auto &line : chartData.lines) {
|
for (const auto &line : c.chartData.lines) {
|
||||||
if (!isEnabled(line.id)) {
|
if (!isEnabled(line.id)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -87,11 +80,11 @@ void StackLinearChartView::paint(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto k = 0; k < chartData.lines.size(); k++) {
|
for (auto k = 0; k < c.chartData.lines.size(); k++) {
|
||||||
auto &linePoint = (j
|
auto &linePoint = (j
|
||||||
? _cachedTransition.lines[k].end
|
? _cachedTransition.lines[k].end
|
||||||
: _cachedTransition.lines[k].start);
|
: _cachedTransition.lines[k].start);
|
||||||
const auto &line = chartData.lines[k];
|
const auto &line = c.chartData.lines[k];
|
||||||
if (!isEnabled(line.id)) {
|
if (!isEnabled(line.id)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -99,22 +92,22 @@ void StackLinearChartView::paint(
|
||||||
? (line.y[i] ? alpha(line.id) : 0)
|
? (line.y[i] ? alpha(line.id) : 0)
|
||||||
: (sum ? (line.y[i] * alpha(line.id) / sum) : 0);
|
: (sum ? (line.y[i] * alpha(line.id) / sum) : 0);
|
||||||
|
|
||||||
const auto xPoint = rect.width()
|
const auto xPoint = c.rect.width()
|
||||||
* ((chartData.xPercentage[i] - xPercentageLimits.min)
|
* ((c.chartData.xPercentage[i] - c.xPercentageLimits.min)
|
||||||
/ (xPercentageLimits.max - xPercentageLimits.min));
|
/ (c.xPercentageLimits.max - c.xPercentageLimits.min));
|
||||||
const auto height = yPercentage * rect.height();
|
const auto height = yPercentage * c.rect.height();
|
||||||
const auto yPoint = rect::bottom(rect) - height - stackOffset;
|
const auto yPoint = rect::bottom(c.rect) - height - stackOffset;
|
||||||
linePoint = { xPoint, yPoint };
|
linePoint = { xPoint, yPoint };
|
||||||
stackOffset += height;
|
stackOffset += height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sums = std::vector<float64>();
|
auto sums = std::vector<float64>();
|
||||||
sums.reserve(chartData.lines.size());
|
sums.reserve(c.chartData.lines.size());
|
||||||
auto totalSum = 0;
|
auto totalSum = 0;
|
||||||
for (const auto &line : chartData.lines) {
|
for (const auto &line : c.chartData.lines) {
|
||||||
auto sum = 0;
|
auto sum = 0;
|
||||||
for (auto i = xIndices.min; i <= xIndices.max; i++) {
|
for (auto i = c.xIndices.min; i <= c.xIndices.max; i++) {
|
||||||
sum += line.y[i];
|
sum += line.y[i];
|
||||||
}
|
}
|
||||||
sum *= alpha(line.id);
|
sum *= alpha(line.id);
|
||||||
|
@ -129,43 +122,26 @@ void StackLinearChartView::paint(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackLinearChartView::paint(
|
StackLinearChartView::paintChartOrZoomAnimation(p, c);
|
||||||
p,
|
|
||||||
chartData,
|
|
||||||
xPercentageLimits,
|
|
||||||
heightLimits,
|
|
||||||
rect,
|
|
||||||
footer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StackLinearChartView::paint(
|
void StackLinearChartView::paintChartOrZoomAnimation(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c) {
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) {
|
|
||||||
const auto context = PaintContext{
|
|
||||||
chartData,
|
|
||||||
xPercentageLimits,
|
|
||||||
heightLimits,
|
|
||||||
rect,
|
|
||||||
footer
|
|
||||||
};
|
|
||||||
if (_transitionProgress == 1.) {
|
if (_transitionProgress == 1.) {
|
||||||
if (footer) {
|
if (c.footer) {
|
||||||
return paintZoomedFooter(p, context);
|
return paintZoomedFooter(p, c);
|
||||||
} else {
|
} else {
|
||||||
return paintZoomed(p, context);
|
return paintZoomed(p, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto &[localStart, localEnd] = _lastPaintedXIndices;
|
const auto &[localStart, localEnd] = _lastPaintedXIndices;
|
||||||
_skipPoints = std::vector<bool>(chartData.lines.size(), false);
|
_skipPoints = std::vector<bool>(c.chartData.lines.size(), false);
|
||||||
auto paths = std::vector<QPainterPath>(
|
auto paths = std::vector<QPainterPath>(
|
||||||
chartData.lines.size(),
|
c.chartData.lines.size(),
|
||||||
QPainterPath());
|
QPainterPath());
|
||||||
|
|
||||||
const auto center = QPointF(rect.center());
|
const auto center = QPointF(c.rect.center());
|
||||||
|
|
||||||
const auto rotate = [&](float64 ang, const QPointF &p) {
|
const auto rotate = [&](float64 ang, const QPointF &p) {
|
||||||
return QTransform()
|
return QTransform()
|
||||||
|
@ -175,7 +151,7 @@ void StackLinearChartView::paint(
|
||||||
.map(p);
|
.map(p);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto hasTransitionAnimation = _transitionProgress && !footer;
|
const auto hasTransitionAnimation = _transitionProgress && !c.footer;
|
||||||
|
|
||||||
auto straightLineProgress = 0.;
|
auto straightLineProgress = 0.;
|
||||||
auto hasEmptyPoint = false;
|
auto hasEmptyPoint = false;
|
||||||
|
@ -188,13 +164,13 @@ void StackLinearChartView::paint(
|
||||||
0.,
|
0.,
|
||||||
1.);
|
1.);
|
||||||
auto rectPath = QPainterPath();
|
auto rectPath = QPainterPath();
|
||||||
rectPath.addRect(rect);
|
rectPath.addRect(c.rect);
|
||||||
const auto r = anim::interpolateF(
|
const auto r = anim::interpolateF(
|
||||||
1.,
|
1.,
|
||||||
kCircleSizeRatio,
|
kCircleSizeRatio,
|
||||||
_transitionProgress);
|
_transitionProgress);
|
||||||
const auto per = anim::interpolateF(0., 100., _transitionProgress);
|
const auto per = anim::interpolateF(0., 100., _transitionProgress);
|
||||||
const auto side = (rect.width() / 2.) * r;
|
const auto side = (c.rect.width() / 2.) * r;
|
||||||
const auto rectF = QRectF(
|
const auto rectF = QRectF(
|
||||||
center - QPointF(side, side),
|
center - QPointF(side, side),
|
||||||
center + QPointF(side, side));
|
center + QPointF(side, side));
|
||||||
|
@ -209,8 +185,8 @@ void StackLinearChartView::paint(
|
||||||
|
|
||||||
auto drawingLinesCount = int(0);
|
auto drawingLinesCount = int(0);
|
||||||
|
|
||||||
for (auto k = 0; k < chartData.lines.size(); k++) {
|
for (auto k = 0; k < c.chartData.lines.size(); k++) {
|
||||||
const auto &line = chartData.lines[k];
|
const auto &line = c.chartData.lines[k];
|
||||||
if (!isEnabled(line.id)) {
|
if (!isEnabled(line.id)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -221,8 +197,8 @@ void StackLinearChartView::paint(
|
||||||
lastEnabled = k;
|
lastEnabled = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto k = 0; k < chartData.lines.size(); k++) {
|
for (auto k = 0; k < c.chartData.lines.size(); k++) {
|
||||||
const auto &line = chartData.lines[k];
|
const auto &line = c.chartData.lines[k];
|
||||||
const auto isLastLine = (k == lastEnabled);
|
const auto isLastLine = (k == lastEnabled);
|
||||||
const auto &transitionLine = _cachedTransition.lines[k];
|
const auto &transitionLine = _cachedTransition.lines[k];
|
||||||
if (!isEnabled(line.id)) {
|
if (!isEnabled(line.id)) {
|
||||||
|
@ -237,20 +213,20 @@ void StackLinearChartView::paint(
|
||||||
? float64(y[i] ? lineAlpha : 0.)
|
? float64(y[i] ? lineAlpha : 0.)
|
||||||
: float64(sum ? (y[i] * lineAlpha / sum) : 0.);
|
: float64(sum ? (y[i] * lineAlpha / sum) : 0.);
|
||||||
|
|
||||||
const auto xPoint = rect.width()
|
const auto xPoint = c.rect.width()
|
||||||
* ((chartData.xPercentage[i] - xPercentageLimits.min)
|
* ((c.chartData.xPercentage[i] - c.xPercentageLimits.min)
|
||||||
/ (xPercentageLimits.max - xPercentageLimits.min));
|
/ (c.xPercentageLimits.max - c.xPercentageLimits.min));
|
||||||
|
|
||||||
if (!yPercentage && isLastLine) {
|
if (!yPercentage && isLastLine) {
|
||||||
hasEmptyPoint = true;
|
hasEmptyPoint = true;
|
||||||
}
|
}
|
||||||
const auto height = yPercentage * rect.height();
|
const auto height = yPercentage * c.rect.height();
|
||||||
const auto yPoint = rect::bottom(rect) - height - stackOffset;
|
const auto yPoint = rect::bottom(c.rect) - height - stackOffset;
|
||||||
// startFromY[k] = yPoint;
|
// startFromY[k] = yPoint;
|
||||||
|
|
||||||
auto angle = 0.;
|
auto angle = 0.;
|
||||||
auto resultPoint = QPointF(xPoint, yPoint);
|
auto resultPoint = QPointF(xPoint, yPoint);
|
||||||
auto pointZero = QPointF(xPoint, rect.y() + rect.height());
|
auto pointZero = QPointF(xPoint, c.rect.y() + c.rect.height());
|
||||||
// if (i == localEnd) {
|
// if (i == localEnd) {
|
||||||
// endXPoint = xPoint;
|
// endXPoint = xPoint;
|
||||||
// } else if (i == localStart) {
|
// } else if (i == localStart) {
|
||||||
|
@ -289,11 +265,11 @@ void StackLinearChartView::paint(
|
||||||
std::max(pointZero.x(), center.x()),
|
std::max(pointZero.x(), center.x()),
|
||||||
rotate(resultAngle, pointZero).y());
|
rotate(resultAngle, pointZero).y());
|
||||||
} else {
|
} else {
|
||||||
const auto &xLimits = xPercentageLimits;
|
const auto &xLimits = c.xPercentageLimits;
|
||||||
const auto isNextXPointAfterCenter = false
|
const auto isNextXPointAfterCenter = false
|
||||||
|| center.x() < (rect.width() * ((i == localEnd)
|
|| center.x() < (c.rect.width() * ((i == localEnd)
|
||||||
? 1.
|
? 1.
|
||||||
: ((chartData.xPercentage[i + 1] - xLimits.min)
|
: ((c.chartData.xPercentage[i + 1] - xLimits.min)
|
||||||
/ (xLimits.max - xLimits.min))));
|
/ (xLimits.max - xLimits.min))));
|
||||||
if (isNextXPointAfterCenter) {
|
if (isNextXPointAfterCenter) {
|
||||||
pointZero = resultPoint = QPointF()
|
pointZero = resultPoint = QPointF()
|
||||||
|
@ -309,7 +285,7 @@ void StackLinearChartView::paint(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == localStart) {
|
if (i == localStart) {
|
||||||
const auto bottomLeft = QPointF(rect.x(), rect::bottom(rect));
|
const auto bottomLeft = QPointF(c.rect.x(), rect::bottom(c.rect));
|
||||||
const auto local = (hasTransitionAnimation && !isLastLine)
|
const auto local = (hasTransitionAnimation && !isLastLine)
|
||||||
? rotate(
|
? rotate(
|
||||||
_transitionProgress * angle
|
_transitionProgress * angle
|
||||||
|
@ -361,10 +337,10 @@ void StackLinearChartView::paint(
|
||||||
|| (local.y() > center.y()
|
|| (local.y() > center.y()
|
||||||
&& resultPoint.y() > center.y()));
|
&& resultPoint.y() > center.y()));
|
||||||
const auto endQuarter = (!ending)
|
const auto endQuarter = (!ending)
|
||||||
? QuarterForPoint(rect, resultPoint)
|
? QuarterForPoint(c.rect, resultPoint)
|
||||||
: kRightTop;
|
: kRightTop;
|
||||||
const auto startQuarter = (!ending)
|
const auto startQuarter = (!ending)
|
||||||
? QuarterForPoint(rect, local)
|
? QuarterForPoint(c.rect, local)
|
||||||
: (transitionLine.angle == -180.)
|
: (transitionLine.angle == -180.)
|
||||||
? kRightTop
|
? kRightTop
|
||||||
: kLeftTop;
|
: kLeftTop;
|
||||||
|
@ -372,14 +348,14 @@ void StackLinearChartView::paint(
|
||||||
for (auto q = endQuarter; q <= startQuarter; q++) {
|
for (auto q = endQuarter; q <= startQuarter; q++) {
|
||||||
chartPath.lineTo(
|
chartPath.lineTo(
|
||||||
(q == kLeftTop || q == kLeftBottom)
|
(q == kLeftTop || q == kLeftBottom)
|
||||||
? rect.x()
|
? c.rect.x()
|
||||||
: rect::right(rect),
|
: rect::right(c.rect),
|
||||||
(q == kLeftTop || q == kRightTop)
|
(q == kLeftTop || q == kRightTop)
|
||||||
? rect.y()
|
? c.rect.y()
|
||||||
: rect::right(rect));
|
: rect::right(c.rect));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
chartPath.lineTo(rect::right(rect), rect::bottom(rect));
|
chartPath.lineTo(rect::right(c.rect), rect::bottom(c.rect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,23 +365,23 @@ void StackLinearChartView::paint(
|
||||||
|
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
|
||||||
p.fillRect(rect, st::boxBg);
|
p.fillRect(c.rect, st::boxBg);
|
||||||
if (!ovalPath.isEmpty()) {
|
if (!ovalPath.isEmpty()) {
|
||||||
p.setClipPath(ovalPath);
|
p.setClipPath(ovalPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto opacity = footer ? (1. - _transitionProgress) : 1.;
|
const auto opacity = c.footer ? (1. - _transitionProgress) : 1.;
|
||||||
for (auto k = int(chartData.lines.size() - 1); k >= 0; k--) {
|
for (auto k = int(c.chartData.lines.size() - 1); k >= 0; k--) {
|
||||||
if (paths[k].isEmpty()) {
|
if (paths[k].isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto &line = chartData.lines[k];
|
const auto &line = c.chartData.lines[k];
|
||||||
p.setOpacity(alpha(line.id) * opacity);
|
p.setOpacity(alpha(line.id) * opacity);
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.fillPath(paths[k], line.color);
|
p.fillPath(paths[k], line.color);
|
||||||
}
|
}
|
||||||
p.setOpacity(opacity);
|
p.setOpacity(opacity);
|
||||||
if (!footer) {
|
if (!c.footer) {
|
||||||
constexpr auto kAlphaTextPart = 0.6;
|
constexpr auto kAlphaTextPart = 0.6;
|
||||||
const auto progress = std::clamp(
|
const auto progress = std::clamp(
|
||||||
(_transitionProgress - kAlphaTextPart) / (1. - kAlphaTextPart),
|
(_transitionProgress - kAlphaTextPart) / (1. - kAlphaTextPart),
|
||||||
|
@ -413,14 +389,14 @@ void StackLinearChartView::paint(
|
||||||
1.);
|
1.);
|
||||||
if (progress > 0) {
|
if (progress > 0) {
|
||||||
auto o = ScopedPainterOpacity(p, progress);
|
auto o = ScopedPainterOpacity(p, progress);
|
||||||
paintPieText(p, context);
|
paintPieText(p, c);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
paintZoomedFooter(p, context);
|
paintZoomedFooter(p, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix ugly outline.
|
// Fix ugly outline.
|
||||||
if (!footer || !_transitionProgress) {
|
if (!c.footer || !_transitionProgress) {
|
||||||
p.setBrush(Qt::transparent);
|
p.setBrush(Qt::transparent);
|
||||||
p.setPen(st::boxBg);
|
p.setPen(st::boxBg);
|
||||||
p.drawPath(ovalPath);
|
p.drawPath(ovalPath);
|
||||||
|
@ -672,10 +648,7 @@ bool StackLinearChartView::skipSelectedTranslation() const {
|
||||||
|
|
||||||
void StackLinearChartView::paintSelectedXIndex(
|
void StackLinearChartView::paintSelectedXIndex(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c,
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
int selectedXIndex,
|
int selectedXIndex,
|
||||||
float64 progress) {
|
float64 progress) {
|
||||||
if (selectedXIndex < 0) {
|
if (selectedXIndex < 0) {
|
||||||
|
@ -685,39 +658,39 @@ void StackLinearChartView::paintSelectedXIndex(
|
||||||
const auto r = st::statisticsDetailsDotRadius;
|
const auto r = st::statisticsDetailsDotRadius;
|
||||||
const auto i = selectedXIndex;
|
const auto i = selectedXIndex;
|
||||||
const auto isSameToken = (_selectedPoints.lastXIndex == selectedXIndex)
|
const auto isSameToken = (_selectedPoints.lastXIndex == selectedXIndex)
|
||||||
&& (_selectedPoints.lastHeightLimits.min == heightLimits.min)
|
&& (_selectedPoints.lastHeightLimits.min == c.heightLimits.min)
|
||||||
&& (_selectedPoints.lastHeightLimits.max == heightLimits.max)
|
&& (_selectedPoints.lastHeightLimits.max == c.heightLimits.max)
|
||||||
&& (_selectedPoints.lastXLimits.min == xPercentageLimits.min)
|
&& (_selectedPoints.lastXLimits.min == c.xPercentageLimits.min)
|
||||||
&& (_selectedPoints.lastXLimits.max == xPercentageLimits.max);
|
&& (_selectedPoints.lastXLimits.max == c.xPercentageLimits.max);
|
||||||
for (const auto &line : chartData.lines) {
|
for (const auto &line : c.chartData.lines) {
|
||||||
const auto lineAlpha = alpha(line.id);
|
const auto lineAlpha = alpha(line.id);
|
||||||
const auto useCache = isSameToken
|
const auto useCache = isSameToken
|
||||||
|| (lineAlpha < 1. && !isEnabled(line.id));
|
|| (lineAlpha < 1. && !isEnabled(line.id));
|
||||||
if (!useCache) {
|
if (!useCache) {
|
||||||
// Calculate.
|
// Calculate.
|
||||||
const auto xPoint = rect.width()
|
const auto xPoint = c.rect.width()
|
||||||
* ((chartData.xPercentage[i] - xPercentageLimits.min)
|
* ((c.chartData.xPercentage[i] - c.xPercentageLimits.min)
|
||||||
/ (xPercentageLimits.max - xPercentageLimits.min));
|
/ (c.xPercentageLimits.max - c.xPercentageLimits.min));
|
||||||
const auto yPercentage = (line.y[i] - heightLimits.min)
|
const auto yPercentage = (line.y[i] - c.heightLimits.min)
|
||||||
/ float64(heightLimits.max - heightLimits.min);
|
/ float64(c.heightLimits.max - c.heightLimits.min);
|
||||||
_selectedPoints.points[line.id] = QPointF(xPoint, 0)
|
_selectedPoints.points[line.id] = QPointF(xPoint, 0)
|
||||||
+ rect.topLeft();
|
+ c.rect.topLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto lineRect = QRectF(
|
const auto lineRect = QRectF(
|
||||||
rect.x()
|
c.rect.x()
|
||||||
+ begin(_selectedPoints.points)->second.x()
|
+ begin(_selectedPoints.points)->second.x()
|
||||||
- (st::lineWidth / 2.),
|
- (st::lineWidth / 2.),
|
||||||
rect.y(),
|
c.rect.y(),
|
||||||
st::lineWidth,
|
st::lineWidth,
|
||||||
rect.height());
|
c.rect.height());
|
||||||
p.fillRect(lineRect, st::windowSubTextFg);
|
p.fillRect(lineRect, st::windowSubTextFg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_selectedPoints.lastXIndex = selectedXIndex;
|
_selectedPoints.lastXIndex = selectedXIndex;
|
||||||
_selectedPoints.lastHeightLimits = heightLimits;
|
_selectedPoints.lastHeightLimits = c.heightLimits;
|
||||||
_selectedPoints.lastXLimits = xPercentageLimits;
|
_selectedPoints.lastXLimits = c.xPercentageLimits;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StackLinearChartView::findXIndexByPosition(
|
int StackLinearChartView::findXIndexByPosition(
|
||||||
|
|
|
@ -26,21 +26,11 @@ public:
|
||||||
StackLinearChartView();
|
StackLinearChartView();
|
||||||
~StackLinearChartView() override final;
|
~StackLinearChartView() override final;
|
||||||
|
|
||||||
void paint(
|
void paint(QPainter &p, const PaintContext &c) override;
|
||||||
QPainter &p,
|
|
||||||
const Data::StatisticalChart &chartData,
|
|
||||||
const Limits &xIndices,
|
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer) override;
|
|
||||||
|
|
||||||
void paintSelectedXIndex(
|
void paintSelectedXIndex(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const PaintContext &c,
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
int selectedXIndex,
|
int selectedXIndex,
|
||||||
float64 progress) override;
|
float64 progress) override;
|
||||||
|
|
||||||
|
@ -69,25 +59,11 @@ public:
|
||||||
const QPoint &p);
|
const QPoint &p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PaintContext final {
|
void paintChartOrZoomAnimation(QPainter &p, const PaintContext &c);
|
||||||
const Data::StatisticalChart &chartData;
|
|
||||||
const Limits &xPercentageLimits;
|
|
||||||
const Limits &heightLimits;
|
|
||||||
const QRect ▭
|
|
||||||
bool footer = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
void paint(
|
void paintZoomed(QPainter &p, const PaintContext &c);
|
||||||
QPainter &p,
|
void paintZoomedFooter(QPainter &p, const PaintContext &c);
|
||||||
const Data::StatisticalChart &chartData,
|
void paintPieText(QPainter &p, const PaintContext &c);
|
||||||
const Limits &xPercentageLimits,
|
|
||||||
const Limits &heightLimits,
|
|
||||||
const QRect &rect,
|
|
||||||
bool footer);
|
|
||||||
|
|
||||||
void paintZoomed(QPainter &p, const PaintContext &context);
|
|
||||||
void paintZoomedFooter(QPainter &p, const PaintContext &context);
|
|
||||||
void paintPieText(QPainter &p, const PaintContext &context);
|
|
||||||
|
|
||||||
[[nodiscard]] bool skipSelectedTranslation() const;
|
[[nodiscard]] bool skipSelectedTranslation() const;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue