From 4754b6144a5aa2b42ea2f2ffeb055115b416ece7 Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Tue, 19 Dec 2023 23:05:33 +0100 Subject: [PATCH] feat: added reverse order to the network chart (#1721) --- Kit/Widgets/NetworkChart.swift | 16 ++++++ Kit/extensions.swift | 4 ++ Kit/plugins/Charts.swift | 89 ++++++++++++++++++++-------------- Modules/Net/popup.swift | 15 ++++++ 4 files changed, 87 insertions(+), 37 deletions(-) diff --git a/Kit/Widgets/NetworkChart.swift b/Kit/Widgets/NetworkChart.swift index 4a2f7ac2..53527bdb 100644 --- a/Kit/Widgets/NetworkChart.swift +++ b/Kit/Widgets/NetworkChart.swift @@ -20,6 +20,7 @@ public class NetworkChart: WidgetWrapper { private var uploadColor: Color = .secondRed private var scaleState: Scale = .linear private var commonScaleState: Bool = true + private var reverseOrderState: Bool = false private var chart: NetworkChartView = NetworkChartView( frame: NSRect(x: 0, y: 0, width: 30, height: Constants.Widget.height - (2*Constants.Widget.margin.y)), @@ -84,6 +85,7 @@ public class NetworkChart: WidgetWrapper { self.uploadColor = Color.fromString(Store.shared.string(key: "\(self.title)_\(self.type.rawValue)_uploadColor", defaultValue: self.uploadColor.key)) self.scaleState = Scale.fromString(Store.shared.string(key: "\(self.title)_\(self.type.rawValue)_scale", defaultValue: self.scaleState.key)) self.commonScaleState = Store.shared.bool(key: "\(self.title)_\(self.type.rawValue)_commonScale", defaultValue: self.commonScaleState) + self.reverseOrderState = Store.shared.bool(key: "\(self.title)_\(self.type.rawValue)_reverseOrder", defaultValue: self.reverseOrderState) if let downloadColor = self.downloadColor.additional as? NSColor, let uploadColor = self.uploadColor.additional as? NSColor { @@ -91,6 +93,7 @@ public class NetworkChart: WidgetWrapper { } self.chart.setScale(self.scaleState, self.commonScaleState) self.chart.reinit(self.historyCount) + self.chart.setReverseOrder(self.reverseOrderState) } if preview { @@ -247,6 +250,12 @@ public class NetworkChart: WidgetWrapper { state: self.commonScaleState )) + view.addArrangedSubview(toggleSettingRow( + title: localizedString("Reverse order"), + action: #selector(toggleReverseOrder), + state: self.reverseOrderState + )) + return view } @@ -332,4 +341,11 @@ public class NetworkChart: WidgetWrapper { Store.shared.set(key: "\(self.title)_\(self.type.rawValue)_commonScale", value: self.commonScaleState) self.display() } + + @objc private func toggleReverseOrder(_ sender: NSControl) { + self.reverseOrderState = controlState(sender) + self.chart.setReverseOrder(self.reverseOrderState) + Store.shared.set(key: "\(self.title)_\(self.type.rawValue)_reverseOrder", value: self.reverseOrderState) + self.display() + } } diff --git a/Kit/extensions.swift b/Kit/extensions.swift index 01033580..78a13dcd 100644 --- a/Kit/extensions.swift +++ b/Kit/extensions.swift @@ -14,6 +14,10 @@ import Cocoa extension String: LocalizedError { public var errorDescription: String? { return self } + public var digits: String { + return components(separatedBy: CharacterSet.decimalDigits.inverted).joined() + } + public func widthOfString(usingFont font: NSFont) -> CGFloat { let fontAttributes = [NSAttributedString.Key.font: font] let size = self.size(withAttributes: fontAttributes) diff --git a/Kit/plugins/Charts.swift b/Kit/plugins/Charts.swift index 496ff612..8c1d029a 100644 --- a/Kit/plugins/Charts.swift +++ b/Kit/plugins/Charts.swift @@ -290,19 +290,20 @@ public class LineChartView: NSView { public class NetworkChartView: NSView { public var id: String = UUID().uuidString public var base: DataSizeBase = .byte - public var inColor: NSColor - public var outColor: NSColor + public var topColor: NSColor + public var bottomColor: NSColor public var points: [(Double, Double)] private var minMax: Bool = false private var scale: Scale = .none private var commonScale: Bool = true + private var reverseOrder: Bool = false public init(frame: NSRect, num: Int, minMax: Bool = true, outColor: NSColor = .systemRed, inColor: NSColor = .systemBlue) { self.minMax = minMax self.points = Array(repeating: (0, 0), count: num) - self.outColor = outColor - self.inColor = inColor + self.topColor = inColor + self.bottomColor = outColor super.init(frame: frame) } @@ -317,20 +318,20 @@ public class NetworkChartView: NSView { context.setShouldAntialias(true) let points = self.points - var uploadMax: Double = points.map{ $0.0 }.max() ?? 0 - var downloadMax: Double = points.map{ $0.1 }.max() ?? 0 - if uploadMax == 0 { - uploadMax = 1 + var topMax: Double = (self.reverseOrder ? points.map{ $0.1 }.max() : points.map{ $0.0 }.max()) ?? 0 + var bottomMax: Double = (self.reverseOrder ? points.map{ $0.0 }.max() : points.map{ $0.1 }.max()) ?? 0 + if topMax == 0 { + topMax = 1 } - if downloadMax == 0 { - downloadMax = 1 + if bottomMax == 0 { + bottomMax = 1 } if !self.commonScale { - if downloadMax > uploadMax { - uploadMax = downloadMax + if bottomMax > topMax { + topMax = bottomMax } else { - downloadMax = uploadMax + bottomMax = topMax } } @@ -341,29 +342,35 @@ public class NetworkChartView: NSView { let columnXPoint = { (point: Int) -> CGFloat in return (CGFloat(point) * xRatio) + (self.frame.origin.x - lineWidth) } - let uploadYPoint = { (point: Int) -> CGFloat in - return scaleValue(scale: self.scale, value: points[point].0, maxValue: uploadMax, maxHeight: self.frame.height/2) + (self.frame.height/2 + self.frame.origin.y) + + let topYPoint = { (point: Int) -> CGFloat in + let value = self.reverseOrder ? points[point].1 : points[point].0 + return scaleValue(scale: self.scale, value: value, maxValue: topMax, maxHeight: self.frame.height/2) + (self.frame.height/2 + self.frame.origin.y) } - let downloadYPoint = { (point: Int) -> CGFloat in - return (self.frame.height/2 + self.frame.origin.y) - scaleValue(scale: self.scale, value: points[point].1, maxValue: downloadMax, maxHeight: self.frame.height/2) + let bottomYPoint = { (point: Int) -> CGFloat in + let value = self.reverseOrder ? points[point].0 : points[point].1 + return (self.frame.height/2 + self.frame.origin.y) - scaleValue(scale: self.scale, value: value, maxValue: bottomMax, maxHeight: self.frame.height/2) } let uploadlinePath = NSBezierPath() - uploadlinePath.move(to: CGPoint(x: columnXPoint(0), y: uploadYPoint(0))) + uploadlinePath.move(to: CGPoint(x: columnXPoint(0), y: topYPoint(0))) let downloadlinePath = NSBezierPath() - downloadlinePath.move(to: CGPoint(x: columnXPoint(0), y: downloadYPoint(0))) + downloadlinePath.move(to: CGPoint(x: columnXPoint(0), y: bottomYPoint(0))) for i in 1..