diff --git a/submodules/GraphCore/Sources/Charts/Controllers/GeneralChartComponentController.swift b/submodules/GraphCore/Sources/Charts/Controllers/GeneralChartComponentController.swift index dc036421ed..b908e547f8 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/GeneralChartComponentController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/GeneralChartComponentController.swift @@ -269,16 +269,20 @@ class GeneralChartComponentController: ChartThemeContainer { var numberOfOffsetsPerItem = ditance / approximateNumberOfChartValues var multiplier: CGFloat = 1.0 - while numberOfOffsetsPerItem > 10 { - numberOfOffsetsPerItem /= 10 - multiplier *= 10 + if numberOfOffsetsPerItem > 0 { + while numberOfOffsetsPerItem > 10 { + numberOfOffsetsPerItem /= 10 + multiplier *= 10 + } } var dividor: CGFloat = 1.0 var maximumNumberOfDecimals = 2 - while numberOfOffsetsPerItem < 1 { - numberOfOffsetsPerItem *= 10 - dividor *= 10 - maximumNumberOfDecimals += 1 + if numberOfOffsetsPerItem > 0 { + while numberOfOffsetsPerItem < 1 { + numberOfOffsetsPerItem *= 10 + dividor *= 10 + maximumNumberOfDecimals += 1 + } } var base: CGFloat = BaseConstants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Lines/BaseLinesChartController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Lines/BaseLinesChartController.swift index 39960ba4fe..39f9a4f31d 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Lines/BaseLinesChartController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Lines/BaseLinesChartController.swift @@ -107,6 +107,8 @@ public class BaseLinesChartController: BaseChartController { color: component.color, visible: actualChartVisibility[index]) } + let total = actualChartsCollection.chartValues.enumerated().map { $0.element.values[pointIndex] }.reduce(0, +) + let dateString: String if isZoomed { dateString = BaseConstants.timeDateFormatter.string(from: closestDate) @@ -114,7 +116,7 @@ public class BaseLinesChartController: BaseChartController { dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate) } let viewModel = ChartDetailsViewModel(title: dateString, - showArrow: self.isZoomable && !self.isZoomed, + showArrow: total > 0 && self.isZoomable && !self.isZoomed, showPrefixes: false, values: values, totalValue: nil, @@ -194,16 +196,20 @@ public class BaseLinesChartController: BaseChartController { var numberOfOffsetsPerItem = distance / approximateNumberOfChartValues var multiplier: CGFloat = 1.0 - while numberOfOffsetsPerItem > 10 { - numberOfOffsetsPerItem /= 10 - multiplier *= 10 + if numberOfOffsetsPerItem > 0 { + while numberOfOffsetsPerItem > 10 { + numberOfOffsetsPerItem /= 10 + multiplier *= 10 + } } var dividor: CGFloat = 1.0 var maximumNumberOfDecimals = 2 - while numberOfOffsetsPerItem < 1 { - numberOfOffsetsPerItem *= 10 - dividor *= 10 - maximumNumberOfDecimals += 1 + if numberOfOffsetsPerItem > 0 { + while numberOfOffsetsPerItem < 1 { + numberOfOffsetsPerItem *= 10 + dividor *= 10 + maximumNumberOfDecimals += 1 + } } var base: CGFloat = BaseConstants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift index 8ea3dbe647..e3de9d1f45 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift @@ -61,7 +61,7 @@ public class GeneralLinesChartController: BaseLinesChartController { self.prevoiusHorizontalStrideInterval = -1 self.totalVerticalRange = LinesChartRenderer.LineData.verticalRange(lines: chartLines) ?? Constants.defaultRange self.totalHorizontalRange = LinesChartRenderer.LineData.horizontalRange(lines: chartLines) ?? Constants.defaultRange - self.lineBulletsRenderer.bullets = self.chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, + self.lineBulletsRenderer.bullets = self.chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, offset: .zero, color: $0.color)} let chartRange: ClosedRange @@ -133,7 +133,7 @@ public class GeneralLinesChartController: BaseLinesChartController { super.chartInteractionDidBegin(point: point) self.lineBulletsRenderer.bullets = chartLines.compactMap { chart in - return LineBulletsRenderer.Bullet(coordinate: chart.points[minIndex], color: chart.color) + return LineBulletsRenderer.Bullet(coordinate: chart.points[minIndex], offset: .zero, color: chart.color) } self.lineBulletsRenderer.isEnabled = true diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift index fbb482720e..145662acb1 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift @@ -77,7 +77,7 @@ public class TwoAxisLinesChartController: BaseLinesChartController { controller.verticalScalesRenderer.labelsColor = chart.color controller.totalVerticalRange = LinesChartRenderer.LineData.verticalRange(lines: chartLines) ?? Constants.defaultRange self.totalHorizontalRange = LinesChartRenderer.LineData.horizontalRange(lines: chartLines) ?? Constants.defaultRange - controller.lineBulletsRenderer.bullets = chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, + controller.lineBulletsRenderer.bullets = chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, offset: .zero, color: $0.color) } controller.previewLinesRenderer.setup(horizontalRange: self.totalHorizontalRange, animated: animated) controller.previewLinesRenderer.setup(verticalRange: controller.totalVerticalRange, animated: animated) @@ -161,7 +161,7 @@ public class TwoAxisLinesChartController: BaseLinesChartController { for graphController in graphControllers { graphController.lineBulletsRenderer.bullets = graphController.chartLines.map { chart in - LineBulletsRenderer.Bullet(coordinate: chart.points[minIndex], color: chart.color) + LineBulletsRenderer.Bullet(coordinate: chart.points[minIndex], offset: .zero, color: chart.color) } graphController.lineBulletsRenderer.isEnabled = true } @@ -246,16 +246,20 @@ public class TwoAxisLinesChartController: BaseLinesChartController { var numberOfOffsetsPerItem = verticalRange.distance / approximateNumberOfChartValues var multiplier: CGFloat = 1.0 - while numberOfOffsetsPerItem > 10 { - numberOfOffsetsPerItem /= 10 - multiplier *= 10 + if numberOfOffsetsPerItem > 0 { + while numberOfOffsetsPerItem > 10 { + numberOfOffsetsPerItem /= 10 + multiplier *= 10 + } } var dividor: CGFloat = 1.0 var maximumNumberOfDecimals = 2 - while numberOfOffsetsPerItem < 1 { - numberOfOffsetsPerItem *= 10 - dividor *= 10 - maximumNumberOfDecimals += 1 + if numberOfOffsetsPerItem > 0 { + while numberOfOffsetsPerItem < 1 { + numberOfOffsetsPerItem *= 10 + dividor *= 10 + maximumNumberOfDecimals += 1 + } } let generalBase = Constants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift index 09ec881be9..4c0c6e7e3e 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift @@ -62,7 +62,7 @@ class LinesComponentController: GeneralChartComponentController { let (chartLines, totalHorizontalRange, totalVerticalRange) = LinesChartRenderer.LineData.initialComponents(chartsCollection: chartsCollection) self.chartLines = chartLines - self.lineBulletsRenderer.bullets = self.chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, + self.lineBulletsRenderer.bullets = self.chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, offset: .zero, color: $0.color)} super.initialize(chartsCollection: chartsCollection, @@ -190,7 +190,7 @@ class LinesComponentController: GeneralChartComponentController { lineBulletsRenderer.isEnabled = true lineBulletsRenderer.setVisible(true, animated: animted) lineBulletsRenderer.bullets = chartLines.compactMap { chart in - return LineBulletsRenderer.Bullet(coordinate: chart.points[dataIndex], color: chart.color) + return LineBulletsRenderer.Bullet(coordinate: chart.points[dataIndex], offset: .zero, color: chart.color) } } diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/TwoAxisStepBarsChartController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/TwoAxisStepBarsChartController.swift index 5729bda287..301911f640 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/TwoAxisStepBarsChartController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/TwoAxisStepBarsChartController.swift @@ -72,7 +72,7 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController { for i in 0 ..< chartBars.locations.count { let location = chartBars.locations[i] let value = component.values[i] - bullets.append(LineBulletsRenderer.Bullet(coordinate: CGPoint(x: location, y: value), color: component.color)) + bullets.append(LineBulletsRenderer.Bullet(coordinate: CGPoint(x: location, y: value), offset: .zero, color: component.color)) } } @@ -155,12 +155,17 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController { let chartInteractionWasBegin = isChartInteractionBegun super.chartInteractionDidBegin(point: point) + var barOffset: CGFloat = 0.0 for graphController in graphControllers { var bullets: [LineBulletsRenderer.Bullet] = [] if let component = graphController.chartBars.components.first { let location = graphController.chartBars.locations[minIndex] let value = component.values[minIndex] - bullets.append(LineBulletsRenderer.Bullet(coordinate: CGPoint(x: location, y: value), color: component.color)) + + let offset = -(graphController.mainBarsRenderer.transform(toChartCoordinateHorizontal: horizontalRange.lowerBound + graphController.barsWidth, chartFrame: chartFrame) - chartFrame.minX) / 2.0 + barOffset = offset + + bullets.append(LineBulletsRenderer.Bullet(coordinate: CGPoint(x: location, y: value), offset: CGPoint(x: offset, y: 0.0), color: component.color)) } graphController.lineBulletsRenderer.bullets = bullets graphController.lineBulletsRenderer.isEnabled = true @@ -172,6 +177,7 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController { self.setDetailsChartVisibleClosure?(true, true) self.setDetailsViewPositionClosure?(detailsViewPosition) self.verticalLineRenderer.values = [chartValue] + self.verticalLineRenderer.offset = barOffset } public override var currentChartHorizontalRangeFraction: ClosedRange { @@ -244,18 +250,22 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController { var numberOfOffsetsPerItem = verticalRange.distance / approximateNumberOfChartValues var multiplier: CGFloat = 1.0 - while numberOfOffsetsPerItem > 10 { - numberOfOffsetsPerItem /= 10 - multiplier *= 10 + if numberOfOffsetsPerItem > 0 { + while numberOfOffsetsPerItem > 10 { + numberOfOffsetsPerItem /= 10 + multiplier *= 10 + } } var dividor: CGFloat = 1.0 var maximumNumberOfDecimals = 2 - while numberOfOffsetsPerItem < 1 { - numberOfOffsetsPerItem *= 10 - dividor *= 10 - maximumNumberOfDecimals += 1 + if numberOfOffsetsPerItem > 0 { + while numberOfOffsetsPerItem < 1 { + numberOfOffsetsPerItem *= 10 + dividor *= 10 + maximumNumberOfDecimals += 1 + } } - + let generalBase = Constants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor let base = generalBase * multiplier / dividor diff --git a/submodules/GraphCore/Sources/Charts/Renderes/LineBulletsRenerer.swift b/submodules/GraphCore/Sources/Charts/Renderes/LineBulletsRenerer.swift index abbf2e58d2..8e42ef7e8b 100644 --- a/submodules/GraphCore/Sources/Charts/Renderes/LineBulletsRenerer.swift +++ b/submodules/GraphCore/Sources/Charts/Renderes/LineBulletsRenerer.swift @@ -16,6 +16,7 @@ import UIKit class LineBulletsRenderer: BaseChartRenderer { struct Bullet { var coordinate: CGPoint + var offset: CGPoint var color: GColor } @@ -56,8 +57,8 @@ class LineBulletsRenderer: BaseChartRenderer { let alpha = alphaAnimators[index].current if alpha == 0 { continue } - let centerX = transform(toChartCoordinateHorizontal: bullet.coordinate.x, chartFrame: chartFrame) - let centerY = transform(toChartCoordinateVertical: bullet.coordinate.y, chartFrame: chartFrame) + let centerX = transform(toChartCoordinateHorizontal: bullet.coordinate.x, chartFrame: chartFrame) + bullet.offset.x + let centerY = transform(toChartCoordinateVertical: bullet.coordinate.y, chartFrame: chartFrame) + bullet.offset.y context.setFillColor(innerColorAnimator.current.color.withAlphaComponent(alpha).cgColor) context.setStrokeColor(bullet.color.withAlphaComponent(alpha).cgColor) context.setLineWidth(linesWidth) diff --git a/submodules/GraphCore/Sources/Charts/Renderes/VerticalLinesRenderer.swift b/submodules/GraphCore/Sources/Charts/Renderes/VerticalLinesRenderer.swift index 4fc169d44e..f1c1a08cfa 100644 --- a/submodules/GraphCore/Sources/Charts/Renderes/VerticalLinesRenderer.swift +++ b/submodules/GraphCore/Sources/Charts/Renderes/VerticalLinesRenderer.swift @@ -20,6 +20,7 @@ class VerticalLinesRenderer: BaseChartRenderer { setNeedsDisplay() } } + var offset: CGFloat = 0.0 private var alphaAnimators: [AnimationController] = [] var linesColor: GColor = .black @@ -39,7 +40,7 @@ class VerticalLinesRenderer: BaseChartRenderer { if alpha == 0 { continue } context.setStrokeColor(linesColor.withAlphaComponent(linesColor.alphaValue * alpha).cgColor) - let pointX = transform(toChartCoordinateHorizontal: value, chartFrame: chartFrame) + let pointX = transform(toChartCoordinateHorizontal: value, chartFrame: chartFrame) + offset context.strokeLineSegments(between: [CGPoint(x: pointX, y: chartFrame.minY), CGPoint(x: pointX, y: chartFrame.maxY)]) } diff --git a/submodules/GraphCore/Sources/Charts/Renderes/VerticalScalesRenderer.swift b/submodules/GraphCore/Sources/Charts/Renderes/VerticalScalesRenderer.swift index 857d91531e..e846e95ad2 100644 --- a/submodules/GraphCore/Sources/Charts/Renderes/VerticalScalesRenderer.swift +++ b/submodules/GraphCore/Sources/Charts/Renderes/VerticalScalesRenderer.swift @@ -100,11 +100,10 @@ class VerticalScalesRenderer: BaseChartRenderer { if generalAlpha == 0 { return } let labelColorAlpha = labelsColor.alphaValue + let spacing: CGFloat = 1.0 + context.clip(to: CGRect(origin: CGPoint(x: 0.0, y: chartFrame.minY - spacing), size: CGSize(width: chartFrame.width + chartFrame.origin.x * 2.0, height: chartFrame.height + spacing * 2.0))) + func drawLines(_ labels: [LinesChartLabel], alpha: CGFloat) { - var labels = labels - if labels.count > 1 { - labels.removeFirst() - } var lineSegments: [CGPoint] = [] let x0 = chartFrame.minX let x1 = chartFrame.maxX @@ -113,8 +112,10 @@ class VerticalScalesRenderer: BaseChartRenderer { for lineInfo in labels { let y = transform(toChartCoordinateVertical: lineInfo.value, chartFrame: chartFrame).roundedUpToPixelGrid() - lineSegments.append(CGPoint(x: x0, y: y)) - lineSegments.append(CGPoint(x: x1, y: y)) + if y < chartFrame.maxY - 2.0 { + lineSegments.append(CGPoint(x: x0, y: y)) + lineSegments.append(CGPoint(x: x1, y: y)) + } } context.strokeLineSegments(between: lineSegments) } @@ -164,5 +165,7 @@ class VerticalScalesRenderer: BaseChartRenderer { attributes: [.foregroundColor: labelsColor.withAlphaComponent(animatedLabesAndLines.alphaAnimator.current * labelColorAlpha * generalAlpha), .font: labelsFont]) } + + context.resetClip() } } diff --git a/submodules/GraphCore/Sources/Helpers/AnimationController.swift b/submodules/GraphCore/Sources/Helpers/AnimationController.swift index 7a45825ef0..3b5b25a5f2 100644 --- a/submodules/GraphCore/Sources/Helpers/AnimationController.swift +++ b/submodules/GraphCore/Sources/Helpers/AnimationController.swift @@ -28,7 +28,6 @@ enum TimeFunction { return time / duration case .easeIn: return (pow(2, 10 * (time / duration - 1)) - 0.0009765625) * 1.0009775171065499 - case .easeOut: return (-pow(2, -10 * time / duration)) + 1 * 1.0009775171065499 } diff --git a/submodules/GraphCore/Sources/Helpers/TimeInterval+Utils.swift b/submodules/GraphCore/Sources/Helpers/TimeInterval+Utils.swift index c8e27b0463..2daddaef56 100644 --- a/submodules/GraphCore/Sources/Helpers/TimeInterval+Utils.swift +++ b/submodules/GraphCore/Sources/Helpers/TimeInterval+Utils.swift @@ -18,7 +18,7 @@ public extension TimeInterval { static let hour: TimeInterval = 60 * 60 static let day: TimeInterval = 60 * 60 * 24 static let osXDuration: TimeInterval = 0.25 - static let expandAnimationDuration: TimeInterval = 0.4 + static let expandAnimationDuration: TimeInterval = 0.25 static var animationDurationMultipler: Double = 1.0 static var defaultDuration: TimeInterval { diff --git a/submodules/GraphUI/Sources/ChartDetailsView.swift b/submodules/GraphUI/Sources/ChartDetailsView.swift index c07dbd9f13..8ce6276359 100644 --- a/submodules/GraphUI/Sources/ChartDetailsView.swift +++ b/submodules/GraphUI/Sources/ChartDetailsView.swift @@ -57,8 +57,8 @@ class ChartDetailsView: UIControl { self.viewModel = viewModel titleLabel.setText(viewModel.title, animated: false) - titleLabel.setVisible(!viewModel.title.isEmpty, animated: animated) - arrowView.setVisible(viewModel.showArrow, animated: animated) + titleLabel.setVisible(!viewModel.title.isEmpty, animated: false) + arrowView.setVisible(viewModel.showArrow, animated: false) arrowButton.isUserInteractionEnabled = viewModel.showArrow let width: CGFloat = margin * 2 + (viewModel.showPrefixes ? (prefixLabelWidth + margin) : 0) + textLabelWidth + valueLabelWidth