mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Various improvements
This commit is contained in:
parent
b7c18980f6
commit
24d7deb3e8
43 changed files with 2076 additions and 1055 deletions
|
|
@ -60,6 +60,18 @@ enum BaseConstants {
|
|||
return numberFormatter
|
||||
}()
|
||||
|
||||
static let tonNumberFormatter: NumberFormatter = {
|
||||
let numberFormatter = TonNumberFormatter()
|
||||
numberFormatter.allowsFloats = true
|
||||
numberFormatter.numberStyle = .decimal
|
||||
numberFormatter.usesGroupingSeparator = true
|
||||
numberFormatter.groupingSeparator = " "
|
||||
numberFormatter.minimumIntegerDigits = 1
|
||||
numberFormatter.minimumFractionDigits = 0
|
||||
numberFormatter.maximumFractionDigits = 2
|
||||
return numberFormatter
|
||||
}()
|
||||
|
||||
static let detailsNumberFormatter: NumberFormatter = {
|
||||
let detailsNumberFormatter = NumberFormatter()
|
||||
detailsNumberFormatter.allowsFloats = false
|
||||
|
|
|
|||
|
|
@ -280,6 +280,9 @@ class GeneralChartComponentController: ChartThemeContainer {
|
|||
}
|
||||
}
|
||||
|
||||
var verticalLimitsNumberFormatter: NumberFormatter = BaseConstants.chartNumberFormatter
|
||||
var detailsNumberFormatter: NumberFormatter = BaseConstants.detailsNumberFormatter
|
||||
|
||||
func verticalLimitsLabels(verticalRange: ClosedRange<CGFloat>) -> (ClosedRange<CGFloat>, [LinesChartLabel]) {
|
||||
let ditance = verticalRange.distance
|
||||
let chartHeight = chartFrame().height
|
||||
|
|
@ -313,7 +316,7 @@ class GeneralChartComponentController: ChartThemeContainer {
|
|||
var verticalValue = (verticalRange.lowerBound / base).rounded(.down) * base
|
||||
let lowerBound = verticalValue
|
||||
|
||||
let numberFormatter = BaseConstants.chartNumberFormatter
|
||||
let numberFormatter = self.verticalLimitsNumberFormatter
|
||||
numberFormatter.maximumFractionDigits = maximumNumberOfDecimals
|
||||
while verticalValue < verticalRange.upperBound {
|
||||
let text: String = numberFormatter.string(from: NSNumber(value: Double(verticalValue))) ?? ""
|
||||
|
|
@ -331,7 +334,7 @@ class GeneralChartComponentController: ChartThemeContainer {
|
|||
let (index, component) = arg
|
||||
return ChartDetailsViewModel.Value(prefix: nil,
|
||||
title: component.name,
|
||||
value: BaseConstants.detailsNumberFormatter.string(from: NSNumber(value: component.values[pointIndex])) ?? "",
|
||||
value: self.detailsNumberFormatter.string(from: NSNumber(value: component.values[pointIndex])) ?? "",
|
||||
color: component.color,
|
||||
visible: chartVisibility[index])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
let mainBarsRenderer: BarChartRenderer
|
||||
let horizontalScalesRenderer: HorizontalScalesRenderer
|
||||
let verticalScalesRenderer: VerticalScalesRenderer
|
||||
let secondaryScalesRenderer: VerticalScalesRenderer?
|
||||
|
||||
let lineBulletsRenderer = LineBulletsRenderer()
|
||||
let verticalLineRenderer = VerticalLinesRenderer()
|
||||
|
|
@ -32,11 +33,13 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
mainBarsRenderer: BarChartRenderer,
|
||||
horizontalScalesRenderer: HorizontalScalesRenderer,
|
||||
verticalScalesRenderer: VerticalScalesRenderer,
|
||||
secondaryScalesRenderer: VerticalScalesRenderer? = nil,
|
||||
previewBarsChartRenderer: BarChartRenderer,
|
||||
step: Bool = false) {
|
||||
self.mainBarsRenderer = mainBarsRenderer
|
||||
self.horizontalScalesRenderer = horizontalScalesRenderer
|
||||
self.verticalScalesRenderer = verticalScalesRenderer
|
||||
self.secondaryScalesRenderer = secondaryScalesRenderer
|
||||
self.previewBarsChartRenderer = previewBarsChartRenderer
|
||||
self.step = step
|
||||
|
||||
|
|
@ -122,6 +125,7 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
mainBarsRenderer.setVisible(visible, animated: animated)
|
||||
horizontalScalesRenderer.setVisible(visible, animated: animated)
|
||||
verticalScalesRenderer.setVisible(visible, animated: animated)
|
||||
secondaryScalesRenderer?.setVisible(visible, animated: animated)
|
||||
previewBarsChartRenderer.setVisible(visible, animated: animated)
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +133,7 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
mainBarsRenderer.setup(horizontalRange: horizontalRange, animated: animated)
|
||||
horizontalScalesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
|
||||
verticalScalesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
|
||||
secondaryScalesRenderer?.setup(horizontalRange: horizontalRange, animated: animated)
|
||||
|
||||
verticalLineRenderer.setup(horizontalRange: horizontalRange, animated: animated)
|
||||
lineBulletsRenderer.setup(horizontalRange: horizontalRange, animated: animated)
|
||||
|
|
@ -144,20 +149,49 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
components: visibleComponents)
|
||||
}
|
||||
|
||||
var conversionRate: Double = 1.0
|
||||
func verticalLimitsLabels(verticalRange: ClosedRange<CGFloat>, secondary: Bool) -> (ClosedRange<CGFloat>, [LinesChartLabel]) {
|
||||
var (range, labels) = super.verticalLimitsLabels(verticalRange: verticalRange)
|
||||
if secondary {
|
||||
var updatedLabels: [LinesChartLabel] = []
|
||||
for label in labels {
|
||||
let convertedValue = (Double(label.text) ?? 0.0) * self.conversionRate
|
||||
let text: String
|
||||
if convertedValue > 1.0 {
|
||||
text = String(format: "%0.1f", convertedValue)
|
||||
} else {
|
||||
text = String(format: "%0.3f", convertedValue)
|
||||
}
|
||||
updatedLabels.append(LinesChartLabel(value: label.value, text: "≈$\(text)"))
|
||||
}
|
||||
labels = updatedLabels
|
||||
}
|
||||
return (range, labels)
|
||||
}
|
||||
|
||||
func updateChartVerticalRanges(horizontalRange: ClosedRange<CGFloat>, animated: Bool) {
|
||||
if let range = BarChartRenderer.BarsData.verticalRange(bars: visibleBars,
|
||||
separate: self.step,
|
||||
calculatingRange: horizontalRange,
|
||||
addBounds: true) {
|
||||
let (range, labels) = verticalLimitsLabels(verticalRange: range)
|
||||
let (range, labels) = verticalLimitsLabels(verticalRange: range, secondary: false)
|
||||
if verticalScalesRenderer.verticalRange.end != range {
|
||||
verticalScalesRenderer.setup(verticalLimitsLabels: labels, animated: animated)
|
||||
}
|
||||
verticalScalesRenderer.setVisible(true, animated: animated)
|
||||
|
||||
if let secondaryScalesRenderer = self.secondaryScalesRenderer {
|
||||
let (range, labels) = verticalLimitsLabels(verticalRange: range, secondary: true)
|
||||
if secondaryScalesRenderer.verticalRange.end != range {
|
||||
secondaryScalesRenderer.setup(verticalLimitsLabels: labels, animated: animated)
|
||||
}
|
||||
secondaryScalesRenderer.setVisible(true, animated: animated)
|
||||
}
|
||||
|
||||
setupMainChart(verticalRange: range, animated: animated)
|
||||
} else {
|
||||
verticalScalesRenderer.setVisible(false, animated: animated)
|
||||
secondaryScalesRenderer?.setVisible(false, animated: animated)
|
||||
}
|
||||
|
||||
if let range = BarChartRenderer.BarsData.verticalRange(bars: visibleBars, separate: self.step) {
|
||||
|
|
@ -169,6 +203,7 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
mainBarsRenderer.setup(verticalRange: verticalRange, animated: animated)
|
||||
horizontalScalesRenderer.setup(verticalRange: verticalRange, animated: animated)
|
||||
verticalScalesRenderer.setup(verticalRange: verticalRange, animated: animated)
|
||||
secondaryScalesRenderer?.setup(verticalRange: verticalRange, animated: animated)
|
||||
lineBulletsRenderer.setup(verticalRange: verticalRange, animated: animated)
|
||||
}
|
||||
|
||||
|
|
@ -232,6 +267,9 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
verticalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = theme.barChartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = theme.barChartStrongLinesColor
|
||||
secondaryScalesRenderer?.labelsColor = theme.chartLabelsColor
|
||||
secondaryScalesRenderer?.axisXColor = .clear
|
||||
secondaryScalesRenderer?.horizontalLinesColor = .clear
|
||||
mainBarsRenderer.update(backgroundColor: theme.chartBackgroundColor, animated: false)
|
||||
previewBarsChartRenderer.update(backgroundColor: theme.chartBackgroundColor, animated: false)
|
||||
verticalLineRenderer.linesColor = theme.chartStrongLinesColor
|
||||
|
|
|
|||
|
|
@ -23,14 +23,26 @@ public class StackedBarsChartController: BaseChartController {
|
|||
}
|
||||
}
|
||||
|
||||
override public init(chartsCollection: ChartsCollection) {
|
||||
public init(chartsCollection: ChartsCollection, isCrypto: Bool = false, rate: Double = 1.0) {
|
||||
let horizontalScalesRenderer = HorizontalScalesRenderer()
|
||||
let verticalScalesRenderer = VerticalScalesRenderer()
|
||||
var secondaryScalesRenderer: VerticalScalesRenderer?
|
||||
if isCrypto {
|
||||
verticalScalesRenderer.isCrypto = true
|
||||
secondaryScalesRenderer = VerticalScalesRenderer()
|
||||
secondaryScalesRenderer?.isRightAligned = true
|
||||
}
|
||||
barsController = BarsComponentController(isZoomed: false,
|
||||
mainBarsRenderer: BarChartRenderer(),
|
||||
horizontalScalesRenderer: horizontalScalesRenderer,
|
||||
verticalScalesRenderer: verticalScalesRenderer,
|
||||
secondaryScalesRenderer: secondaryScalesRenderer,
|
||||
previewBarsChartRenderer: BarChartRenderer())
|
||||
if isCrypto {
|
||||
barsController.conversionRate = rate
|
||||
barsController.verticalLimitsNumberFormatter = BaseConstants.tonNumberFormatter
|
||||
barsController.detailsNumberFormatter = BaseConstants.tonNumberFormatter
|
||||
}
|
||||
zoomedBarsController = BarsComponentController(isZoomed: true,
|
||||
mainBarsRenderer: BarChartRenderer(),
|
||||
horizontalScalesRenderer: horizontalScalesRenderer,
|
||||
|
|
@ -67,12 +79,16 @@ public class StackedBarsChartController: BaseChartController {
|
|||
}
|
||||
|
||||
public override var mainChartRenderers: [ChartViewRenderer] {
|
||||
return [barsController.mainBarsRenderer,
|
||||
var renderers = [barsController.mainBarsRenderer,
|
||||
zoomedBarsController.mainBarsRenderer,
|
||||
barsController.horizontalScalesRenderer,
|
||||
barsController.verticalScalesRenderer,
|
||||
// performanceRenderer
|
||||
]
|
||||
if let secondary = barsController.secondaryScalesRenderer {
|
||||
renderers.append(secondary)
|
||||
}
|
||||
return renderers
|
||||
}
|
||||
|
||||
public override var navigationRenderers: [ChartViewRenderer] {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class VerticalScalesRenderer: BaseChartRenderer {
|
|||
var axisXWidth: CGFloat = GView.oneDevicePixel
|
||||
|
||||
var isRightAligned: Bool = false
|
||||
var isCrypto: Bool = false
|
||||
|
||||
var horizontalLinesColor: GColor = .black {
|
||||
didSet {
|
||||
|
|
@ -120,6 +121,45 @@ class VerticalScalesRenderer: BaseChartRenderer {
|
|||
context.strokeLineSegments(between: lineSegments)
|
||||
}
|
||||
|
||||
func drawTonSymbol(context: CGContext, color: UIColor, at point: CGPoint) {
|
||||
let width: CGFloat = 8.0
|
||||
let height: CGFloat = 7.5
|
||||
let cornerRadius: CGFloat = 0.5
|
||||
|
||||
let topPoint = CGPoint(x: point.x + width / 2, y: point.y)
|
||||
let bottomPoint = CGPoint(x: point.x + width / 2, y: point.y + height)
|
||||
let leftTopPoint = CGPoint(x: point.x, y: point.y)
|
||||
let rightTopPoint = CGPoint(x: point.x + width, y: point.y)
|
||||
|
||||
context.saveGState()
|
||||
|
||||
context.beginPath()
|
||||
context.move(to: CGPoint(x: leftTopPoint.x + cornerRadius, y: leftTopPoint.y))
|
||||
|
||||
context.addArc(tangent1End: leftTopPoint, tangent2End: bottomPoint, radius: cornerRadius)
|
||||
context.addLine(to: CGPoint(x: bottomPoint.x, y: bottomPoint.y - cornerRadius + GView.oneDevicePixel))
|
||||
|
||||
context.move(to: CGPoint(x: rightTopPoint.x - cornerRadius, y: rightTopPoint.y))
|
||||
context.addArc(tangent1End: rightTopPoint, tangent2End: bottomPoint, radius: cornerRadius)
|
||||
context.addLine(to: CGPoint(x: bottomPoint.x, y: bottomPoint.y - cornerRadius + GView.oneDevicePixel))
|
||||
|
||||
context.move(to: CGPoint(x: leftTopPoint.x + cornerRadius, y: leftTopPoint.y))
|
||||
context.addLine(to: CGPoint(x: rightTopPoint.x - cornerRadius, y: rightTopPoint.y))
|
||||
|
||||
context.move(to: topPoint)
|
||||
context.addLine(to: CGPoint(x: bottomPoint.x, y: bottomPoint.y - 1.0))
|
||||
|
||||
context.setLineWidth(1.0)
|
||||
context.setLineCap(.round)
|
||||
context.setFillColor(UIColor.clear.cgColor)
|
||||
context.setStrokeColor(color.withAlphaComponent(1.0).cgColor)
|
||||
|
||||
context.setAlpha(color.alphaValue)
|
||||
context.strokePath()
|
||||
|
||||
context.restoreGState()
|
||||
}
|
||||
|
||||
func drawVerticalLabels(_ labels: [LinesChartLabel], attributes: [NSAttributedString.Key: Any]) {
|
||||
if isRightAligned {
|
||||
for label in labels {
|
||||
|
|
@ -133,7 +173,14 @@ class VerticalScalesRenderer: BaseChartRenderer {
|
|||
let y = transform(toChartCoordinateVertical: label.value, chartFrame: chartFrame) - labelsFont.pointSize - labelsAxisOffset
|
||||
let attributedString = NSAttributedString(string: label.text, attributes: attributes)
|
||||
let textNode = LabelNode.layoutText(attributedString, bounds.size)
|
||||
textNode.1.draw(CGRect(origin: CGPoint(x:chartFrame.minX, y: y), size: textNode.0.size), in: context, backingScaleFactor: deviceScale)
|
||||
|
||||
var xOffset = 0.0
|
||||
if self.isCrypto {
|
||||
xOffset += 11.0
|
||||
drawTonSymbol(context: context, color: attributes[.foregroundColor] as? UIColor ?? .black, at: CGPoint(x: chartFrame.minX, y: y + 4.0))
|
||||
}
|
||||
|
||||
textNode.1.draw(CGRect(origin: CGPoint(x: chartFrame.minX + xOffset, y: y), size: textNode.0.size), in: context, backingScaleFactor: deviceScale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,3 +35,28 @@ class ScalesNumberFormatter: NumberFormatter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TonNumberFormatter: NumberFormatter {
|
||||
override func string(from number: NSNumber) -> String? {
|
||||
var balanceText = "\(number.intValue)"
|
||||
let decimalSeparator = self.decimalSeparator ?? "."
|
||||
while balanceText.count < 10 {
|
||||
balanceText.insert("0", at: balanceText.startIndex)
|
||||
}
|
||||
balanceText.insert(contentsOf: decimalSeparator, at: balanceText.index(balanceText.endIndex, offsetBy: -9))
|
||||
while true {
|
||||
if balanceText.hasSuffix("0") {
|
||||
if balanceText.hasSuffix("\(decimalSeparator)0") {
|
||||
balanceText.removeLast()
|
||||
balanceText.removeLast()
|
||||
break
|
||||
} else {
|
||||
balanceText.removeLast()
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return balanceText
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue