From 086c8a0f94c897368e8101b60844676c58a134fa Mon Sep 17 00:00:00 2001 From: Kilian Hofmann Date: Tue, 20 Jun 2017 21:14:17 +0200 Subject: [PATCH] Frequncy Window and loading implemented --- Docsis Toolkit.xcodeproj/project.pbxproj | 8 + Graphic Analysis 2/CollectionViewMonth.swift | 3 +- Graphic Analysis 2/FlippedView.swift | 24 ++ Graphic Analysis 2/FrequencyGraph.swift | 263 +++++++++++++++++++ Graphic Analysis 2/GraphWindow.swift | 44 +++- Graphic Analysis 2/GraphWindow.xib | 26 ++ Graphic Analysis 2/Info.plist | 2 +- Graphic Analysis 2/buildnum.ver | 2 +- 8 files changed, 367 insertions(+), 5 deletions(-) create mode 100644 Graphic Analysis 2/FlippedView.swift create mode 100644 Graphic Analysis 2/FrequencyGraph.swift diff --git a/Docsis Toolkit.xcodeproj/project.pbxproj b/Docsis Toolkit.xcodeproj/project.pbxproj index 883479b..9b7ca38 100644 --- a/Docsis Toolkit.xcodeproj/project.pbxproj +++ b/Docsis Toolkit.xcodeproj/project.pbxproj @@ -41,6 +41,8 @@ E26246451EF5E64900EAA4A6 /* PDFDraw.xib in Resources */ = {isa = PBXBuildFile; fileRef = E26246431EF5E64900EAA4A6 /* PDFDraw.xib */; }; E26246471EF6684B00EAA4A6 /* PDFItemViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E26246461EF6684B00EAA4A6 /* PDFItemViewController.xib */; }; E26246491EF6688400EAA4A6 /* PDFItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E26246481EF6688400EAA4A6 /* PDFItemViewController.swift */; }; + E27A9DB51EF995C1000BC7A3 /* FrequencyGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DB41EF995C1000BC7A3 /* FrequencyGraph.swift */; }; + E27A9DB91EF99C20000BC7A3 /* FlippedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DB81EF99C20000BC7A3 /* FlippedView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -103,6 +105,8 @@ E26246431EF5E64900EAA4A6 /* PDFDraw.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PDFDraw.xib; sourceTree = ""; }; E26246461EF6684B00EAA4A6 /* PDFItemViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PDFItemViewController.xib; sourceTree = ""; }; E26246481EF6688400EAA4A6 /* PDFItemViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PDFItemViewController.swift; sourceTree = ""; }; + E27A9DB41EF995C1000BC7A3 /* FrequencyGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrequencyGraph.swift; sourceTree = ""; }; + E27A9DB81EF99C20000BC7A3 /* FlippedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlippedView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -347,6 +351,8 @@ E2268DFA1EF712D300C97726 /* Graph View */ = { isa = PBXGroup; children = ( + E27A9DB81EF99C20000BC7A3 /* FlippedView.swift */, + E27A9DB41EF995C1000BC7A3 /* FrequencyGraph.swift */, E2218D511EF32AC6004298F6 /* GraphDetailsController.swift */, E262463C1EF55BCE00EAA4A6 /* GraphWindow.swift */, ); @@ -571,6 +577,8 @@ E262463E1EF55BCE00EAA4A6 /* GraphWindow.swift in Sources */, E26246491EF6688400EAA4A6 /* PDFItemViewController.swift in Sources */, E2218D641EF45F37004298F6 /* LossDistributionPie.swift in Sources */, + E27A9DB51EF995C1000BC7A3 /* FrequencyGraph.swift in Sources */, + E27A9DB91EF99C20000BC7A3 /* FlippedView.swift in Sources */, E2218D571EF335E6004298F6 /* CollectionViewItemYear.swift in Sources */, E2218D521EF32AC6004298F6 /* GraphDetailsController.swift in Sources */, E2218D5D1EF3DD6F004298F6 /* CollectionViewItemMonth.swift in Sources */, diff --git a/Graphic Analysis 2/CollectionViewMonth.swift b/Graphic Analysis 2/CollectionViewMonth.swift index 5ea4cbb..168c504 100644 --- a/Graphic Analysis 2/CollectionViewMonth.swift +++ b/Graphic Analysis 2/CollectionViewMonth.swift @@ -87,8 +87,7 @@ extension CollectionViewMonth: NSCollectionViewDataSource { /* guard var logA = String(data: log.regularFileContents!, encoding: .utf8)?.components(separatedBy: "\n") else { return } */ - guard var logA = FileOperations.load(log: log.regularFileContents! as NSData) else { return } - logA.removeLast() + guard let logA = FileOperations.load(log: log.regularFileContents! as NSData) else { return } item2.distribution = logA OperationQueue.main.addOperation { item2.loss.stringValue = "\(logA.count)" diff --git a/Graphic Analysis 2/FlippedView.swift b/Graphic Analysis 2/FlippedView.swift new file mode 100644 index 0000000..45436f7 --- /dev/null +++ b/Graphic Analysis 2/FlippedView.swift @@ -0,0 +1,24 @@ +// +// FlippedView.swift +// Logger2 +// +// Created by Kilian Hofmann on 03.08.16. +// Copyright © 2016 Kilian Hofmann. All rights reserved. +// + +import Cocoa + +class FlippedView: NSView { + + override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) + + // Drawing code here. + } + + override var isFlipped: Bool { + get { + return true + } + } +} diff --git a/Graphic Analysis 2/FrequencyGraph.swift b/Graphic Analysis 2/FrequencyGraph.swift new file mode 100644 index 0000000..d9ee05d --- /dev/null +++ b/Graphic Analysis 2/FrequencyGraph.swift @@ -0,0 +1,263 @@ +// +// GraphView.swift +// Docsis Toolkit +// +// Created by Kilian Hofmann on 20.06.17. +// Copyright © 2017 Kilian Hofmann. All rights reserved. +// + +import Cocoa + +class FrequencyGraph: NSView { + let opQueue: OperationQueue = OperationQueue() + // Constants + static let graphSizeWithSeparator: Int = 109 + static let graphSize: Int = 108 + static let maxGraphSize: Int = 17300 + let zeroOffset: Double = 37 + // Path related + var path: NSBezierPath = NSBezierPath.init() + var threshold: NSBezierPath = NSBezierPath.init() + var upstream: Bool = false + var lastTime: Int = 0 + var lastTimeThreshold: Int = 0 + var timePaths: [NSBezierPath] = [] + var lossPaths: [NSBezierPath] = [] + var offset: Int = 0 + // Popover + let popover: NSPopover = NSPopover() + // Data + var data: [String] = [] + var dataLoss: [String] = [] + var frequency: Double = 0.0 + // Cursor + var cursor: NSBezierPath = NSBezierPath.init() + // Superview + var content: FlippedView! + + init(upstream: Bool, frame: CGRect, superview: FlippedView) { + super.init(frame: frame) + self.upstream = upstream + + let tracking: NSTrackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .mouseMoved, .activeInActiveApp, .inVisibleRect], owner: self, userInfo: nil) + self.addTrackingArea(tracking) + + popover.contentViewController = GraphDetailsController() + + self.content = superview + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + override func draw(_ dirtyRect: NSRect) { + + NSColor.white.setFill() + NSRectFill(dirtyRect) + + threshold.lineWidth = 0.5 + + if upstream { + NSColor.red.set() + threshold.stroke() + } else { + NSColor.blue.set() + threshold.stroke() + } + + NSColor.black.set() + path.lineWidth = 1 + path.stroke() + + NSColor(red: 0, green: 0, blue: 0, alpha: 0.3).set() + cursor.lineWidth = 2 + cursor.stroke() + + for index in 0..= 0 { + + (popover.contentViewController! as! GraphDetailsController).freq_str = "\(roundToPlaces(1, input: frequency)) MHz" + + (popover.contentViewController! as! GraphDetailsController).time_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[0])" + (popover.contentViewController! as! GraphDetailsController).power_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[1]) dBmV" + + if upstream { + (popover.contentViewController! as! GraphDetailsController).snr_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[2]) dBmV" + (popover.contentViewController! as! GraphDetailsController).ranging_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[3])" + } else { + (popover.contentViewController! as! GraphDetailsController).snr_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[2]) dB" + } + + popover.show(relativeTo: NSMakeRect(CGFloat(x), 0, 2, CGFloat(FrequencyGraph.graphSize)), of: self, preferredEdge: .minY) + } + } + + override func scrollWheel(with event: NSEvent) { + super.scrollWheel(with: event) + cursor.removeAllPoints() + popover.performClose(self) + + setNeedsDisplay(self.bounds) + } + + // MARK: - Helper + + func roundToPlaces(_ places:Int, input: Double) -> Double { + let divisor = pow(10.0, Double(places)) + return round(input * divisor) / divisor + } +} diff --git a/Graphic Analysis 2/GraphWindow.swift b/Graphic Analysis 2/GraphWindow.swift index a4ab5c6..3463105 100644 --- a/Graphic Analysis 2/GraphWindow.swift +++ b/Graphic Analysis 2/GraphWindow.swift @@ -10,7 +10,8 @@ import Cocoa class GraphWindow: NSWindowController { - var collectionViewItem: CollectionViewItemMonth? + var collectionViewItem: CollectionViewItemMonth! + @IBOutlet var scrollView: NSScrollView! override var windowNibName: String! { return "GraphWindow" @@ -28,6 +29,47 @@ class GraphWindow: NSWindowController { override func windowDidLoad() { super.windowDidLoad() // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. + + var upstreamFiles: [FileWrapper] = [] + var downstreamFiles: [FileWrapper] = [] + guard collectionViewItem.dayFW != nil else { return } + for file in (collectionViewItem.dayFW?.fileWrappers)! { + if file.key.contains("Upstream") { + upstreamFiles.append(file.value) + } else if file.key.contains("Downstream") { + downstreamFiles.append(file.value) + } + } + + let content: FlippedView = FlippedView(frame: NSMakeRect(0, 0, CGFloat(FrequencyGraph.maxGraphSize), CGFloat(((upstreamFiles.count + downstreamFiles.count) * FrequencyGraph.graphSizeWithSeparator)-1))) + + scrollView.documentView = content + + var numGraphs: Int = 0 + for item in upstreamFiles { + let graph: FrequencyGraph = FrequencyGraph(upstream: true, frame: NSMakeRect(0, CGFloat(numGraphs * FrequencyGraph.graphSizeWithSeparator), CGFloat(FrequencyGraph.maxGraphSize), CGFloat(FrequencyGraph.graphSize)), superview: content) + graph.dataLoss = collectionViewItem.distribution + graph.data = FileOperations.loadUpstream(log: item.regularFileContents! as NSData)! + let keyString: String = item.filename!.components(separatedBy: " ")[1] + graph.frequency = Double(keyString.substring(to: keyString.index(keyString.endIndex, offsetBy: -4)))! / 1000000 + let opQueue: OperationQueue = OperationQueue() + opQueue.addOperation { + graph.initView() + } + numGraphs += 1 + } + for item in downstreamFiles { + let graph: FrequencyGraph = FrequencyGraph(upstream: false, frame: NSMakeRect(0, CGFloat(numGraphs * FrequencyGraph.graphSizeWithSeparator), CGFloat(FrequencyGraph.maxGraphSize), CGFloat(FrequencyGraph.graphSize)), superview: content) + graph.dataLoss = collectionViewItem.distribution + graph.data = FileOperations.loadDownstream(log: item.regularFileContents! as NSData)! + let keyString: String = item.filename!.components(separatedBy: " ")[1] + graph.frequency = Double(keyString.substring(to: keyString.index(keyString.endIndex, offsetBy: -4)))! / 1000000 + let opQueue: OperationQueue = OperationQueue() + opQueue.addOperation { + graph.initView() + } + numGraphs += 1 + } } } diff --git a/Graphic Analysis 2/GraphWindow.xib b/Graphic Analysis 2/GraphWindow.xib index a01107b..c5668ed 100644 --- a/Graphic Analysis 2/GraphWindow.xib +++ b/Graphic Analysis 2/GraphWindow.xib @@ -8,6 +8,7 @@ + @@ -21,6 +22,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Graphic Analysis 2/Info.plist b/Graphic Analysis 2/Info.plist index 849eb1b..230bfcc 100644 --- a/Graphic Analysis 2/Info.plist +++ b/Graphic Analysis 2/Info.plist @@ -44,7 +44,7 @@ CFBundleShortVersionString 2.1 CFBundleVersion - 424 + 454 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/Graphic Analysis 2/buildnum.ver b/Graphic Analysis 2/buildnum.ver index b610306..994cac0 100644 --- a/Graphic Analysis 2/buildnum.ver +++ b/Graphic Analysis 2/buildnum.ver @@ -1,2 +1,2 @@ version 2.1 -build 424 +build 454