Context analysis: Co-Occurrence
This commit is contained in:
88
main/Requests/Analytics/VCCoOccurrence.swift
Normal file
88
main/Requests/Analytics/VCCoOccurrence.swift
Normal file
@@ -0,0 +1,88 @@
|
||||
import UIKit
|
||||
|
||||
class VCCoOccurrence: UIViewController, UITableViewDataSource {
|
||||
var fqdn: String!
|
||||
private var dataSource: [ContextAnalysisResult] = []
|
||||
|
||||
@IBOutlet private var tableView: UITableView!
|
||||
@IBOutlet private var timeSegment: UISegmentedControl!
|
||||
private let availableTimes = [0, 5, 15, 30]
|
||||
private var selectedTime = -1 {
|
||||
didSet { logTimeDelta = log(CGFloat(max(2, selectedTime+1))) }
|
||||
}
|
||||
private var logTimeDelta: CGFloat = 1
|
||||
private var logMaxCount: CGFloat = 1
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
selectedTime = Pref.ContextAnalyis.CoOccurrenceTime ?? 5 // calls `didSet` and `logTimeDelta`
|
||||
timeSegment.removeAllSegments() // clear IB values
|
||||
for (i, time) in availableTimes.enumerated() {
|
||||
timeSegment.insertSegment(withTitle: TimeFormat(.abbreviated).from(seconds: time), at: i, animated: false)
|
||||
if time == selectedTime {
|
||||
timeSegment.selectedSegmentIndex = i
|
||||
}
|
||||
}
|
||||
reloadDataSource()
|
||||
}
|
||||
|
||||
func reloadDataSource() {
|
||||
dataSource = [("Loading …", 0, 0, 0)]
|
||||
logMaxCount = 1
|
||||
tableView.reloadData()
|
||||
let domain = fqdn!
|
||||
let time = Timestamp(selectedTime)
|
||||
DispatchQueue.global().async { [weak self] in
|
||||
guard let db = AppDB, let times = db.dnsLogsUniqTs(domain), times.count > 0 else {
|
||||
return // should never happen, or what did you tap then?
|
||||
}
|
||||
guard let result = db.contextAnalysis(coOccurrence: times, plusMinus: time, exclude: domain) else {
|
||||
return
|
||||
}
|
||||
self?.dataSource = result
|
||||
self?.logMaxCount = log(CGFloat(result.reduce(0) { max($0, $1.count) }))
|
||||
DispatchQueue.main.sync { [weak self] in
|
||||
self?.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func didChangeTime(_ sender: UISegmentedControl) {
|
||||
selectedTime = availableTimes[sender.selectedSegmentIndex]
|
||||
Pref.ContextAnalyis.CoOccurrenceTime = selectedTime
|
||||
reloadDataSource()
|
||||
}
|
||||
|
||||
@IBAction func didClose(_ sender: UIBarButtonItem) {
|
||||
dismiss(animated: true)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Table View Data Source
|
||||
|
||||
func tableView(_ _: UITableView, numberOfRowsInSection _: Int) -> Int {
|
||||
dataSource.count
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "CoOccurrenceCell") as! CoOccurrenceCell
|
||||
let src = dataSource[indexPath.row]
|
||||
cell.title.text = src.domain
|
||||
cell.rank.text = "\(indexPath.row + 1)."
|
||||
cell.count.text = "\(src.count)"
|
||||
cell.avgdiff.text = String(format: "%.2fs", src.avg)
|
||||
|
||||
cell.countMeter.percent = (log(CGFloat(src.count)) / logMaxCount)
|
||||
cell.avgdiffMeter.percent = 1 - (log(CGFloat(src.avg + 1)) / logTimeDelta)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
class CoOccurrenceCell: UITableViewCell {
|
||||
@IBOutlet var title: UILabel!
|
||||
@IBOutlet var rank: TagLabel!
|
||||
@IBOutlet var count: TagLabel!
|
||||
@IBOutlet var avgdiff: TagLabel!
|
||||
@IBOutlet var countMeter: MeterBar!
|
||||
@IBOutlet var avgdiffMeter: MeterBar!
|
||||
}
|
||||
Reference in New Issue
Block a user