Fixed smooth paint of stack linear chart on move of footer slider.
This commit is contained in:
		
							parent
							
								
									cee833f102
								
							
						
					
					
						commit
						d9a08bb6a6
					
				
					 2 changed files with 65 additions and 29 deletions
				
			
		| 
						 | 
					@ -46,6 +46,45 @@ inline float64 InterpolationRatio(float64 from, float64 to, float64 result) {
 | 
				
			||||||
	return (result - from) / (to - from);
 | 
						return (result - from) / (to - from);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]] Limits FindAdditionalZoomedOutXIndices(const PaintContext &c) {
 | 
				
			||||||
 | 
						constexpr auto kOffset = int(1);
 | 
				
			||||||
 | 
						auto &xPercentage = c.chartData.xPercentage;
 | 
				
			||||||
 | 
						auto leftResult = 0.;
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto i = std::max(int(c.xIndices.min) - kOffset, 0);
 | 
				
			||||||
 | 
							if (xPercentage[i] > c.xPercentageLimits.min) {
 | 
				
			||||||
 | 
								while (true) {
 | 
				
			||||||
 | 
									i--;
 | 
				
			||||||
 | 
									if (i < 0) {
 | 
				
			||||||
 | 
										leftResult = 0;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									} else if (!(xPercentage[i] > c.xPercentageLimits.min)) {
 | 
				
			||||||
 | 
										leftResult = i;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								leftResult = i;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							const auto lastIndex = float64(xPercentage.size() - 1);
 | 
				
			||||||
 | 
							auto i = std::min(lastIndex, float64(c.xIndices.max) + kOffset);
 | 
				
			||||||
 | 
							if (xPercentage[i] < c.xPercentageLimits.max) {
 | 
				
			||||||
 | 
								while (true) {
 | 
				
			||||||
 | 
									i++;
 | 
				
			||||||
 | 
									if (i > lastIndex) {
 | 
				
			||||||
 | 
										return { leftResult, lastIndex };
 | 
				
			||||||
 | 
									} else if (!(xPercentage[i] < c.xPercentageLimits.max)) {
 | 
				
			||||||
 | 
										return { leftResult, i };
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return { leftResult, i };
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
StackLinearChartView::StackLinearChartView() = default;
 | 
					StackLinearChartView::StackLinearChartView() = default;
 | 
				
			||||||
| 
						 | 
					@ -68,13 +107,10 @@ void StackLinearChartView::prepareZoom(
 | 
				
			||||||
		const PaintContext &c,
 | 
							const PaintContext &c,
 | 
				
			||||||
		TransitionStep step) {
 | 
							TransitionStep step) {
 | 
				
			||||||
	if (step == TransitionStep::ZoomedOut) {
 | 
						if (step == TransitionStep::ZoomedOut) {
 | 
				
			||||||
		constexpr auto kOffset = float64(2);
 | 
							_transition.zoomedOutXIndicesAdditional
 | 
				
			||||||
		_transition.zoomedOutXIndices = {
 | 
								= FindAdditionalZoomedOutXIndices(c);
 | 
				
			||||||
			float64(std::max(0., c.xIndices.min - kOffset)),
 | 
							_transition.zoomedOutXIndices = c.xIndices;
 | 
				
			||||||
			float64(std::min(
 | 
							_transition.zoomedOutXPercentage = c.xPercentageLimits;
 | 
				
			||||||
				float64(c.chartData.xPercentage.size() - 1),
 | 
					 | 
				
			||||||
				c.xIndices.max + kOffset)),
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	} else if (step == TransitionStep::PrepareToZoomIn) {
 | 
						} else if (step == TransitionStep::PrepareToZoomIn) {
 | 
				
			||||||
		const auto &[zoomedStart, zoomedEnd] =
 | 
							const auto &[zoomedStart, zoomedEnd] =
 | 
				
			||||||
			_transition.zoomedOutXIndices;
 | 
								_transition.zoomedOutXIndices;
 | 
				
			||||||
| 
						 | 
					@ -82,10 +118,7 @@ void StackLinearChartView::prepareZoom(
 | 
				
			||||||
			c.chartData.lines.size(),
 | 
								c.chartData.lines.size(),
 | 
				
			||||||
			Transition::TransitionLine());
 | 
								Transition::TransitionLine());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const auto xPercentageLimits = Limits{
 | 
							const auto xPercentageLimits = _transition.zoomedOutXPercentage;
 | 
				
			||||||
			c.chartData.xPercentage[_transition.zoomedOutXIndices.min],
 | 
					 | 
				
			||||||
			c.chartData.xPercentage[_transition.zoomedOutXIndices.max],
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (auto j = 0; j < 2; j++) {
 | 
							for (auto j = 0; j < 2; j++) {
 | 
				
			||||||
			const auto i = int((j == 1) ? zoomedEnd : zoomedStart);
 | 
								const auto i = int((j == 1) ? zoomedEnd : zoomedStart);
 | 
				
			||||||
| 
						 | 
					@ -230,7 +263,7 @@ void StackLinearChartView::paintChartOrZoomAnimation(
 | 
				
			||||||
	const auto hasTransitionAnimation = _transition.progress && !c.footer;
 | 
						const auto hasTransitionAnimation = _transition.progress && !c.footer;
 | 
				
			||||||
	const auto &[localStart, localEnd] = c.footer
 | 
						const auto &[localStart, localEnd] = c.footer
 | 
				
			||||||
		? Limits{ 0., float64(c.chartData.xPercentage.size() - 1) }
 | 
							? Limits{ 0., float64(c.chartData.xPercentage.size() - 1) }
 | 
				
			||||||
		: _transition.zoomedOutXIndices;
 | 
							: _transition.zoomedOutXIndicesAdditional;
 | 
				
			||||||
	_skipPoints = std::vector<bool>(c.chartData.lines.size(), false);
 | 
						_skipPoints = std::vector<bool>(c.chartData.lines.size(), false);
 | 
				
			||||||
	auto paths = std::vector<QPainterPath>(
 | 
						auto paths = std::vector<QPainterPath>(
 | 
				
			||||||
		c.chartData.lines.size(),
 | 
							c.chartData.lines.size(),
 | 
				
			||||||
| 
						 | 
					@ -246,7 +279,9 @@ void StackLinearChartView::paintChartOrZoomAnimation(
 | 
				
			||||||
			.map(p);
 | 
								.map(p);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const auto xPercentageLimits = Limits{
 | 
						const auto xPercentageLimits = !c.footer
 | 
				
			||||||
 | 
							? _transition.zoomedOutXPercentage
 | 
				
			||||||
 | 
							: Limits{
 | 
				
			||||||
			c.chartData.xPercentage[localStart],
 | 
								c.chartData.xPercentage[localStart],
 | 
				
			||||||
			c.chartData.xPercentage[localEnd],
 | 
								c.chartData.xPercentage[localEnd],
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
| 
						 | 
					@ -283,6 +318,10 @@ void StackLinearChartView::paintChartOrZoomAnimation(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto drawingLinesCount = int(0);
 | 
							auto drawingLinesCount = int(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const auto xPoint = c.rect.width()
 | 
				
			||||||
 | 
								* ((c.chartData.xPercentage[i] - xPercentageLimits.min)
 | 
				
			||||||
 | 
									/ (xPercentageLimits.max - xPercentageLimits.min));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (auto k = 0; k < c.chartData.lines.size(); k++) {
 | 
							for (auto k = 0; k < c.chartData.lines.size(); k++) {
 | 
				
			||||||
			const auto &line = c.chartData.lines[k];
 | 
								const auto &line = c.chartData.lines[k];
 | 
				
			||||||
			if (!isEnabled(line.id)) {
 | 
								if (!isEnabled(line.id)) {
 | 
				
			||||||
| 
						 | 
					@ -311,10 +350,6 @@ void StackLinearChartView::paintChartOrZoomAnimation(
 | 
				
			||||||
				? 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 = c.rect.width()
 | 
					 | 
				
			||||||
				* ((c.chartData.xPercentage[i] - xPercentageLimits.min)
 | 
					 | 
				
			||||||
					/ (xPercentageLimits.max - xPercentageLimits.min));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!yPercentage && isLastLine) {
 | 
								if (!yPercentage && isLastLine) {
 | 
				
			||||||
				hasEmptyPoint = true;
 | 
									hasEmptyPoint = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -803,10 +838,7 @@ void StackLinearChartView::paintSelectedXIndex(
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	const auto &[localStart, localEnd] = _transition.zoomedOutXIndices;
 | 
						const auto &[localStart, localEnd] = _transition.zoomedOutXIndices;
 | 
				
			||||||
	const auto xPercentageLimits = Limits{
 | 
						const auto xPercentageLimits = _transition.zoomedOutXPercentage;
 | 
				
			||||||
		c.chartData.xPercentage[localStart],
 | 
					 | 
				
			||||||
		c.chartData.xPercentage[localEnd],
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	p.setBrush(st::boxBg);
 | 
						p.setBrush(st::boxBg);
 | 
				
			||||||
	const auto r = st::statisticsDetailsDotRadius;
 | 
						const auto r = st::statisticsDetailsDotRadius;
 | 
				
			||||||
	const auto i = selectedXIndex;
 | 
						const auto i = selectedXIndex;
 | 
				
			||||||
| 
						 | 
					@ -858,9 +890,10 @@ int StackLinearChartView::findXIndexByPosition(
 | 
				
			||||||
		(x - rect.x()) / rect.width(),
 | 
							(x - rect.x()) / rect.width(),
 | 
				
			||||||
		0.,
 | 
							0.,
 | 
				
			||||||
		1.);
 | 
							1.);
 | 
				
			||||||
 | 
						const auto &[localStart, localEnd] = _transition.zoomedOutXIndices;
 | 
				
			||||||
	const auto rawXPercentage = anim::interpolateF(
 | 
						const auto rawXPercentage = anim::interpolateF(
 | 
				
			||||||
		xPercentageLimits.min,
 | 
							_transition.zoomedOutXPercentage.min,
 | 
				
			||||||
		xPercentageLimits.max,
 | 
							_transition.zoomedOutXPercentage.max,
 | 
				
			||||||
		pointerRatio);
 | 
							pointerRatio);
 | 
				
			||||||
	const auto it = ranges::lower_bound(
 | 
						const auto it = ranges::lower_bound(
 | 
				
			||||||
		chartData.xPercentage,
 | 
							chartData.xPercentage,
 | 
				
			||||||
| 
						 | 
					@ -868,9 +901,10 @@ int StackLinearChartView::findXIndexByPosition(
 | 
				
			||||||
	const auto left = rawXPercentage - (*(it - 1));
 | 
						const auto left = rawXPercentage - (*(it - 1));
 | 
				
			||||||
	const auto right = (*it) - rawXPercentage;
 | 
						const auto right = (*it) - rawXPercentage;
 | 
				
			||||||
	const auto nearestXPercentageIt = ((right) > (left)) ? (it - 1) : it;
 | 
						const auto nearestXPercentageIt = ((right) > (left)) ? (it - 1) : it;
 | 
				
			||||||
	return std::distance(
 | 
						return std::clamp(
 | 
				
			||||||
		begin(chartData.xPercentage),
 | 
							std::distance(begin(chartData.xPercentage), nearestXPercentageIt),
 | 
				
			||||||
		nearestXPercentageIt);
 | 
							long(localStart),
 | 
				
			||||||
 | 
							long(localEnd));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void StackLinearChartView::setEnabled(int id, bool enabled, crl::time now) {
 | 
					void StackLinearChartView::setEnabled(int id, bool enabled, crl::time now) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,6 +120,8 @@ private:
 | 
				
			||||||
		bool pendingPrepareToZoomIn = false;
 | 
							bool pendingPrepareToZoomIn = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Limits zoomedOutXIndices;
 | 
							Limits zoomedOutXIndices;
 | 
				
			||||||
 | 
							Limits zoomedOutXIndicesAdditional;
 | 
				
			||||||
 | 
							Limits zoomedOutXPercentage;
 | 
				
			||||||
		Limits zoomedInLimit;
 | 
							Limits zoomedInLimit;
 | 
				
			||||||
		Limits zoomedInLimitXIndices;
 | 
							Limits zoomedInLimitXIndices;
 | 
				
			||||||
		Limits zoomedInRange;
 | 
							Limits zoomedInRange;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue