An amazing project that generates micro reports from tournament results
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pa-tournament-stats/TournamentStats/utils/ColumnRepresentable.swift

186 lines
4.8 KiB

//
// CSVUtils.swift
// TournamentStats
//
// Created by Laurent Morvillier on 03/06/2019.
// Copyright © 2019 Stax River. All rights reserved.
//
import Foundation
import Charts
extension UIColor {
static var paGreen: UIColor {
return UIColor(red: 0/255, green: 255/255, blue: 196/255, alpha: 1)
}
static var paColor1: UIColor {
return UIColor(red: 125/255, green: 155/255, blue: 255/255, alpha: 1)
}
static var paColor2: UIColor {
return UIColor(red: 255/255, green: 125/255, blue: 196/255, alpha: 1)
}
static let paColor3: UIColor = UIColor(red: 255/255, green: 155/255, blue: 50/255, alpha: 1)
}
struct ColumnDescriptor {
var header: String
var number: Bool = false
var widthWeight: CGFloat = 1.0
}
protocol ColumnRepresentable {
static func columnDescriptors() -> [ColumnDescriptor]
func cellValues() -> [String]
var chartDataEntry: ChartDataEntry { get }
var pieChartDataEntry: PieChartDataEntry { get }
}
extension ColumnRepresentable {
var chartDataEntry: ChartDataEntry {
return ChartDataEntry(x: 0, y: 0)
}
var pieChartDataEntry: PieChartDataEntry {
return PieChartDataEntry(value: 0.0)
}
}
class PercentageFormatter : IValueFormatter {
var numberFormatter: NumberFormatter = NumberFormatter()
init() {
self.numberFormatter.maximumFractionDigits = 0
}
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
if let formatted = self.numberFormatter.string(from: NSNumber(value: value)) {
return formatted + "%"
} else {
return ""
}
}
}
extension Array where Element : ColumnRepresentable {
var pieChartData: PieChartData {
var dataEntries: [ChartDataEntry] = []
self.forEach { representable in
dataEntries.append(representable.pieChartDataEntry)
}
let dataSet = PieChartDataSet(entries: dataEntries, label: "")
dataSet.entryLabelFont = Fonts.pieChartEntries
dataSet.valueFont = Fonts.pieChartEntries
dataSet.colors = [UIColor.paGreen, UIColor.paColor1, UIColor.paColor2, UIColor.paColor3]
dataSet.valueFormatter = PercentageFormatter()
return PieChartData(dataSet: dataSet)
}
var chartData: ChartData {
var dataEntries: [ChartDataEntry] = []
self.forEach { representable in
dataEntries.append(representable.chartDataEntry)
}
let dataSet = ChartDataSet(entries: dataEntries)
return ChartData(dataSet: dataSet)
}
}
//extension Array where Element : Aggregeable {
//
// func aggregate(param: String) -> [Element] {
// return []
// }
//
//}
protocol Aggregeable {
static func aggregate(table: [Self], param: String) -> [Self]
}
protocol HTMLRepresentable : ColumnRepresentable {
static func htmlHeaders() -> String
func html() -> String
}
extension HTMLRepresentable {
static func htmlHeaders() -> String {
let all = self.columnDescriptors().map { $0.header }.joined(separator: "</td><td>")
return "<tr class=\"table-header\"><td>\(all)</td></tr>"
}
func html() -> String {
let all = self.cellValues().joined(separator: "</td><td>")
return "<tr><td>\(all)</td></tr>"
}
}
extension Array where Element : HTMLRepresentable {
func writeHTML(fileName: String, limit: Int? = 10) {
var html = "<table class=\"wp-block-table alignwide\">\n"
html.append("<thead>")
html.append(Element.htmlHeaders())
html.append("</thead>\n<tbody>")
let max = limit ?? Int.max
for (index, rep) in self.enumerated() {
html.append("\n")
html.append(rep.html())
if index + 1 >= max {
break
}
}
html.append("\n</tbody></table>")
do {
try FileWriter.writeToDocumentDirectory(content: html, fileName: fileName)
} catch {
print(error)
}
}
}
extension Array where Element : CSVRepresentable {
func writeCSV(file: String, limit: Int? = 10) {
var string = Element.csvHeaders()
let max = limit ?? Int.max
for (index, rep) in self.enumerated() {
string.append("/n")
string.append(rep.csv())
if index >= max {
break
}
}
do {
try FileWriter.writeToDocumentDirectory(content: string, fileName: file)
} catch {
print(error)
}
}
}
public protocol CSVRepresentable {
static func csvHeaders() -> String
func csv() -> String
}