From c332119e41de008b7038b7feece666dba1ba5283 Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Tue, 14 Aug 2018 16:25:04 -0500 Subject: [PATCH 01/18] Added Charts pod --- Podfile | 1 + Podfile.lock | 8 +++++++- WooCommerce/WooCommerce.xcodeproj/project.pbxproj | 10 ++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Podfile b/Podfile index 247f5df90e6..45e8cba67fe 100644 --- a/Podfile +++ b/Podfile @@ -30,6 +30,7 @@ target 'WooCommerce' do pod 'KeychainAccess', '~> 3.1' pod 'CocoaLumberjack/Swift', '~> 3.4' pod 'XLPagerTabStrip', '~> 8.0' + pod 'Charts', '~> 3.1' # Unit Tests # ========== diff --git a/Podfile.lock b/Podfile.lock index 09d5e896c98..b1c4b098d87 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -5,6 +5,9 @@ PODS: - CocoaLumberjack (~> 3.4.1) - Reachability (~> 3.1) - UIDeviceIdentifier (~> 0.4) + - Charts (3.1.1): + - Charts/Core (= 3.1.1) + - Charts/Core (3.1.1) - CocoaLumberjack (3.4.2): - CocoaLumberjack/Default (= 3.4.2) - CocoaLumberjack/Extensions (= 3.4.2) @@ -69,6 +72,7 @@ PODS: DEPENDENCIES: - Alamofire (~> 4.7) - Automattic-Tracks-iOS (from `https://github.com/Automattic/Automattic-Tracks-iOS.git`, tag `0.2.3`) + - Charts (~> 3.1) - CocoaLumberjack/Swift (~> 3.4) - Crashlytics (~> 3.10) - Gridicons (= 0.15) @@ -81,6 +85,7 @@ SPEC REPOS: https://github.com/cocoapods/specs.git: - 1PasswordExtension - Alamofire + - Charts - CocoaLumberjack - Crashlytics - Fabric @@ -116,6 +121,7 @@ SPEC CHECKSUMS: 1PasswordExtension: 0e95bdea64ec8ff2f4f693be5467a09fac42a83d Alamofire: e4fa87002c137ba2d8d634d2c51fabcda0d5c223 Automattic-Tracks-iOS: d8c6c6c1351b1905a73e45f431b15598d71963b5 + Charts: 90a4d61da0f6e06684c591e3bcab11940fe61736 CocoaLumberjack: db7cc9e464771f12054c22ff6947c5a58d43a0fd Crashlytics: 7f2e38d302d9da96475b3d64d86fb29e31a542b7 Fabric: a2917d3895e4c1569b9c3170de7320ea1b1e6661 @@ -137,6 +143,6 @@ SPEC CHECKSUMS: wpxmlrpc: bfc572f62ce7ee897f6f38b098d2ba08732ecef4 XLPagerTabStrip: c908b17cbf42fcd2598ee1adfc49bae25444d88a -PODFILE CHECKSUM: fad8937db279e4bf9807a4985a2418c4832c9b35 +PODFILE CHECKSUM: a2a2362208b6735d77e2c6358fbcdf29aead6bff COCOAPODS: 1.5.3 diff --git a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj index 59b04aaca42..a97c4afbf6f 100644 --- a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj +++ b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj @@ -1033,6 +1033,7 @@ "${BUILT_PRODUCTS_DIR}/1PasswordExtension/OnePasswordExtension.framework", "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", "${BUILT_PRODUCTS_DIR}/Automattic-Tracks-iOS/AutomatticTracks.framework", + "${BUILT_PRODUCTS_DIR}/Charts/Charts.framework", "${BUILT_PRODUCTS_DIR}/CocoaLumberjack.default-Swift/CocoaLumberjack.framework", "${BUILT_PRODUCTS_DIR}/FormatterKit/FormatterKit.framework", "${PODS_ROOT}/GoogleSignInRepacked/Frameworks/GoogleSignIn.framework", @@ -1057,6 +1058,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OnePasswordExtension.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AutomatticTracks.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Charts.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FormatterKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleSignIn.framework", @@ -1252,7 +1254,7 @@ CODE_SIGN_STYLE = Automatic; INFOPLIST_PREFIX_HEADER = InfoPlist.h; PRODUCT_NAME = "$(TARGET_NAME)"; - SECRETS_PATH = $HOME/.woo_app_credentials.json; + SECRETS_PATH = "$HOME/.woo_app_credentials.json"; VALID_ARCHS = "$(inherited)"; }; name = Debug; @@ -1263,7 +1265,7 @@ CODE_SIGN_STYLE = Automatic; INFOPLIST_PREFIX_HEADER = InfoPlist.h; PRODUCT_NAME = "$(TARGET_NAME)"; - SECRETS_PATH = $HOME/.woo_app_credentials.json; + SECRETS_PATH = "$HOME/.woo_app_credentials.json"; VALID_ARCHS = "$(inherited)"; }; name = Release; @@ -1401,7 +1403,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = "WooCommerce Development"; - SECRETS_PATH = $HOME/.woo_app_credentials.json; + SECRETS_PATH = "$HOME/.woo_app_credentials.json"; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; USER_HEADER_SEARCH_PATHS = ""; @@ -1427,7 +1429,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.automattic.woocommerce; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "WooCommerce App Store"; - SECRETS_PATH = $HOME/.woo_app_credentials.json; + SECRETS_PATH = "$HOME/.woo_app_credentials.json"; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; USER_HEADER_SEARCH_PATHS = ""; From d43e14d8ca754bf40b62b669ab7dda7dc54110d9 Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Tue, 14 Aug 2018 16:36:51 -0500 Subject: [PATCH 02/18] Added bar chart view to PeriodDataVC --- .../MyStore/PeriodDataViewController.swift | 19 ++++++++++++++++++- .../MyStore/PeriodDataViewController.xib | 4 ++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift index 20727a06934..058c7ad11c5 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift @@ -1,5 +1,6 @@ import UIKit import Yosemite +import Charts import XLPagerTabStrip import WordPressShared import CocoaLumberjack @@ -15,8 +16,8 @@ class PeriodDataViewController: UIViewController, IndicatorInfoProvider { @IBOutlet private weak var ordersData: UILabel! @IBOutlet private weak var revenueTitle: UILabel! @IBOutlet private weak var revenueData: UILabel! + @IBOutlet private weak var barChartView: BarChartView! @IBOutlet private weak var lastUpdated: UILabel! - @IBOutlet private weak var chartView: UIView! @IBOutlet private weak var borderView: UIView! private var lastUpdatedDate: Date? @@ -67,6 +68,7 @@ class PeriodDataViewController: UIViewController, IndicatorInfoProvider { override func viewDidLoad() { super.viewDidLoad() configureView() + configureBarChart() } override func viewDidAppear(_ animated: Bool) { @@ -109,6 +111,21 @@ private extension PeriodDataViewController { lastUpdated.font = UIFont.footnote lastUpdated.textColor = StyleManager.wooGreyMid } + + func configureBarChart() { + barChartView.chartDescription?.enabled = false + + barChartView.dragEnabled = true + barChartView.setScaleEnabled(true) + barChartView.pinchZoomEnabled = false + + // ChartYAxis *leftAxis = chartView.leftAxis; + + let xAxis = barChartView.xAxis + xAxis.labelPosition = .bottom + + barChartView.rightAxis.enabled = false + } } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.xib b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.xib index 4a599aa0925..ac0ed6a5c1e 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.xib +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.xib @@ -11,8 +11,8 @@ + - @@ -158,7 +158,7 @@ - + From 2b1963866e6f1081354f16c9bda86e744aa60590 Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Wed, 15 Aug 2018 12:30:21 -0500 Subject: [PATCH 03/18] Dashboard: Revenue value now uses totalSales instead of totalGrossSales --- WooCommerce/Classes/Model/OrderStats+Woo.swift | 9 +++++++++ .../Dashboard/MyStore/PeriodDataViewController.swift | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/WooCommerce/Classes/Model/OrderStats+Woo.swift b/WooCommerce/Classes/Model/OrderStats+Woo.swift index c12ed998fef..1ef49989881 100644 --- a/WooCommerce/Classes/Model/OrderStats+Woo.swift +++ b/WooCommerce/Classes/Model/OrderStats+Woo.swift @@ -18,4 +18,13 @@ extension OrderStats { return Locale(identifier: identifier).currencySymbol ?? currency } + + /// Returns the sum of total sales this stats period. This value is typically used in the dashboard for revenue reporting. + /// + /// *Note:* The value returned here is an aggrigation of all the `OrderStatsItem.totalSales` values and + /// _not_ `OrderStats.totalGrossSales` or `OrderStats.totalNetSales`. + /// + var totalSales: Double { + return items?.map({ $0.totalSales }).reduce(0.0, +) ?? 0.0 + } } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift index 058c7ad11c5..a1d3c01cde0 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift @@ -158,7 +158,7 @@ private extension PeriodDataViewController { if let orderStats = orderStats { totalOrdersText = Double(orderStats.totalOrders).friendlyString() let currencySymbol = orderStats.currencySymbol - let totalRevenue = orderStats.totalGrossSales.friendlyString() + let totalRevenue = orderStats.totalSales.friendlyString() totalRevenueText = "\(currencySymbol)\(totalRevenue)" } ordersData.text = totalOrdersText From 21a6c5e6938ee182d70967670f62beac204d6ebf Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Wed, 15 Aug 2018 14:45:33 -0500 Subject: [PATCH 04/18] Charting WIP --- .../Classes/Model/OrderStats+Woo.swift | 14 ++++ WooCommerce/Classes/Styles/Style.swift | 6 ++ .../MyStore/PeriodDataViewController.swift | 64 ++++++++++++++++--- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/WooCommerce/Classes/Model/OrderStats+Woo.swift b/WooCommerce/Classes/Model/OrderStats+Woo.swift index 1ef49989881..43733ef1a1e 100644 --- a/WooCommerce/Classes/Model/OrderStats+Woo.swift +++ b/WooCommerce/Classes/Model/OrderStats+Woo.swift @@ -27,4 +27,18 @@ extension OrderStats { var totalSales: Double { return items?.map({ $0.totalSales }).reduce(0.0, +) ?? 0.0 } + + /// Returns a dictionary containing all of the `OrderStatsItem` periods and their related total sales values. + /// + var totalSalesItems: [String: Double]? { + guard let items = items, !items.isEmpty else { + return nil + } + + var returnVal: [String: Double] = [:] + for item in items { + returnVal[item.period] = item.totalSales + } + return returnVal + } } diff --git a/WooCommerce/Classes/Styles/Style.swift b/WooCommerce/Classes/Styles/Style.swift index 06f652ce98a..98a09f48d4a 100644 --- a/WooCommerce/Classes/Styles/Style.swift +++ b/WooCommerce/Classes/Styles/Style.swift @@ -16,6 +16,7 @@ protocol Style { var buttonDisabledHighlightedColor: UIColor { get } var buttonDisabledTitleColor: UIColor { get } var cellSeparatorColor: UIColor { get } + var chartLabelFont: UIFont { get } var defaultTextColor: UIColor { get } var destructiveActionColor: UIColor { get } var navBarImage: UIImage { get } @@ -51,6 +52,7 @@ class DefaultStyle: Style { let actionButtonTitleFont = UIFont.font(forStyle: .headline, weight: .semibold) let alternativeLoginsTitleFont = UIFont.font(forStyle: .subheadline, weight: .semibold) let subheadlineFont = UIFont.font(forStyle: .subheadline, weight: .regular) + let chartLabelFont = UIFont.font(forStyle: .caption2, weight: .ultraLight) // Colors! // @@ -182,6 +184,10 @@ class StyleManager { return active.cellSeparatorColor } + static var chartLabelFont: UIFont { + return active.chartLabelFont + } + static var defaultTextColor: UIColor { return active.defaultTextColor } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift index a1d3c01cde0..b0b83395a56 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift @@ -2,7 +2,6 @@ import UIKit import Yosemite import Charts import XLPagerTabStrip -import WordPressShared import CocoaLumberjack @@ -26,6 +25,7 @@ class PeriodDataViewController: UIViewController, IndicatorInfoProvider { didSet { lastUpdatedDate = Date() reloadOrderFields() + reloadChart() reloadLastUpdatedField() } } @@ -48,6 +48,22 @@ class PeriodDataViewController: UIViewController, IndicatorInfoProvider { } } + private var chartData: BarChartData? { + guard let totalSalesItems = orderStats?.totalSalesItems, !totalSalesItems.isEmpty else { + return nil + } + + var dataEntries: [BarChartDataEntry] = [] + var barCount = 0 + for salesItem in totalSalesItems { + dataEntries.append(BarChartDataEntry(x: Double(barCount), y: salesItem.value)) + barCount += 1 + } + + let dataSet = BarChartDataSet(values: dataEntries, label: "Data") + return BarChartData(dataSet: dataSet) + } + // MARK: - Initialization /// Designated Initializer @@ -82,6 +98,9 @@ class PeriodDataViewController: UIViewController, IndicatorInfoProvider { // extension PeriodDataViewController { func clearAllFields() { + if barChartView != nil { + barChartView.clear() + } orderStats = nil siteStats = nil reloadAllFields() @@ -114,17 +133,35 @@ private extension PeriodDataViewController { func configureBarChart() { barChartView.chartDescription?.enabled = false - - barChartView.dragEnabled = true - barChartView.setScaleEnabled(true) + barChartView.dragEnabled = false + barChartView.setScaleEnabled(false) barChartView.pinchZoomEnabled = false - - // ChartYAxis *leftAxis = chartView.leftAxis; + barChartView.rightAxis.enabled = false + barChartView.legend.enabled = false + barChartView.fitBars = true + barChartView.isUserInteractionEnabled = false + barChartView.noDataText = NSLocalizedString("No data available", comment: "Text displayed when no data is available for revenue chart.") + barChartView.noDataFont = StyleManager.chartLabelFont + barChartView.noDataTextColor = StyleManager.wooSecondary let xAxis = barChartView.xAxis xAxis.labelPosition = .bottom - - barChartView.rightAxis.enabled = false + xAxis.labelFont = StyleManager.chartLabelFont + xAxis.labelTextColor = StyleManager.wooSecondary + xAxis.axisLineColor = StyleManager.wooSecondary + xAxis.gridColor = StyleManager.wooGreyBorder + xAxis.drawLabelsEnabled = true + xAxis.drawGridLinesEnabled = false + xAxis.drawAxisLineEnabled = true + + let yAxis = barChartView.leftAxis + yAxis.labelFont = StyleManager.chartLabelFont + yAxis.labelTextColor = StyleManager.wooSecondary + yAxis.axisLineColor = StyleManager.wooSecondary + yAxis.gridColor = StyleManager.wooGreyBorder + yAxis.drawLabelsEnabled = true + yAxis.drawGridLinesEnabled = true + yAxis.drawAxisLineEnabled = true } } @@ -145,6 +182,7 @@ private extension PeriodDataViewController { func reloadAllFields() { reloadOrderFields() reloadSiteFields() + reloadChart() reloadLastUpdatedField() } @@ -177,6 +215,15 @@ private extension PeriodDataViewController { visitorsData.text = visitorsText } + func reloadChart() { + guard barChartView != nil else { + return + } + barChartView.data = chartData + barChartView.notifyDataSetChanged() + barChartView.animate(yAxisDuration: Constants.chartAnimationDuration) + } + func reloadLastUpdatedField() { if lastUpdated != nil { lastUpdated.text = summaryDateUpdated } } @@ -188,5 +235,6 @@ private extension PeriodDataViewController { private extension PeriodDataViewController { enum Constants { static let placeholderText = "-" + static let chartAnimationDuration = 0.75 } } From cf297aa96c9f9c1469ca463c6a080bf00ea8ec4d Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Wed, 15 Aug 2018 15:16:39 -0500 Subject: [PATCH 05/18] Removed zero bars in chart --- .../Dashboard/MyStore/PeriodDataViewController.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift index b0b83395a56..9ed423bed5d 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift @@ -56,7 +56,11 @@ class PeriodDataViewController: UIViewController, IndicatorInfoProvider { var dataEntries: [BarChartDataEntry] = [] var barCount = 0 for salesItem in totalSalesItems { - dataEntries.append(BarChartDataEntry(x: Double(barCount), y: salesItem.value)) + if salesItem.value > 0.0 { + // By only including the values that are greater than zero (but still incrementing barCount), + // we will create nice "gaps" in the chart instead of a bunch of zero value bars. + dataEntries.append(BarChartDataEntry(x: Double(barCount), y: salesItem.value)) + } barCount += 1 } @@ -138,7 +142,6 @@ private extension PeriodDataViewController { barChartView.pinchZoomEnabled = false barChartView.rightAxis.enabled = false barChartView.legend.enabled = false - barChartView.fitBars = true barChartView.isUserInteractionEnabled = false barChartView.noDataText = NSLocalizedString("No data available", comment: "Text displayed when no data is available for revenue chart.") barChartView.noDataFont = StyleManager.chartLabelFont @@ -220,6 +223,7 @@ private extension PeriodDataViewController { return } barChartView.data = chartData + barChartView.fitBars = true barChartView.notifyDataSetChanged() barChartView.animate(yAxisDuration: Constants.chartAnimationDuration) } From 17eca4e09d2467ca56ab9f1220c9c423a58618cd Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Wed, 15 Aug 2018 16:18:17 -0500 Subject: [PATCH 06/18] Dashboard: chart tweaks --- WooCommerce/Classes/Model/OrderStats+Woo.swift | 14 -------------- .../MyStore/PeriodDataViewController.swift | 17 ++++++++++------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/WooCommerce/Classes/Model/OrderStats+Woo.swift b/WooCommerce/Classes/Model/OrderStats+Woo.swift index 43733ef1a1e..1ef49989881 100644 --- a/WooCommerce/Classes/Model/OrderStats+Woo.swift +++ b/WooCommerce/Classes/Model/OrderStats+Woo.swift @@ -27,18 +27,4 @@ extension OrderStats { var totalSales: Double { return items?.map({ $0.totalSales }).reduce(0.0, +) ?? 0.0 } - - /// Returns a dictionary containing all of the `OrderStatsItem` periods and their related total sales values. - /// - var totalSalesItems: [String: Double]? { - guard let items = items, !items.isEmpty else { - return nil - } - - var returnVal: [String: Double] = [:] - for item in items { - returnVal[item.period] = item.totalSales - } - return returnVal - } } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift index 9ed423bed5d..4bd7e5e91de 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift @@ -49,17 +49,18 @@ class PeriodDataViewController: UIViewController, IndicatorInfoProvider { } private var chartData: BarChartData? { - guard let totalSalesItems = orderStats?.totalSalesItems, !totalSalesItems.isEmpty else { + guard let statItems = orderStats?.items, !statItems.isEmpty else { return nil } var dataEntries: [BarChartDataEntry] = [] var barCount = 0 - for salesItem in totalSalesItems { - if salesItem.value > 0.0 { + + statItems.forEach { (item) in + if item.totalSales > 0.0 { // By only including the values that are greater than zero (but still incrementing barCount), // we will create nice "gaps" in the chart instead of a bunch of zero value bars. - dataEntries.append(BarChartDataEntry(x: Double(barCount), y: salesItem.value)) + dataEntries.append(BarChartDataEntry(x: Double(barCount), y: item.totalSales)) } barCount += 1 } @@ -142,6 +143,7 @@ private extension PeriodDataViewController { barChartView.pinchZoomEnabled = false barChartView.rightAxis.enabled = false barChartView.legend.enabled = false + barChartView.drawValueAboveBarEnabled = true barChartView.isUserInteractionEnabled = false barChartView.noDataText = NSLocalizedString("No data available", comment: "Text displayed when no data is available for revenue chart.") barChartView.noDataFont = StyleManager.chartLabelFont @@ -151,20 +153,21 @@ private extension PeriodDataViewController { xAxis.labelPosition = .bottom xAxis.labelFont = StyleManager.chartLabelFont xAxis.labelTextColor = StyleManager.wooSecondary - xAxis.axisLineColor = StyleManager.wooSecondary + xAxis.axisLineColor = StyleManager.wooGreyBorder xAxis.gridColor = StyleManager.wooGreyBorder - xAxis.drawLabelsEnabled = true + xAxis.drawLabelsEnabled = false xAxis.drawGridLinesEnabled = false xAxis.drawAxisLineEnabled = true let yAxis = barChartView.leftAxis yAxis.labelFont = StyleManager.chartLabelFont yAxis.labelTextColor = StyleManager.wooSecondary - yAxis.axisLineColor = StyleManager.wooSecondary + yAxis.axisLineColor = StyleManager.wooGreyBorder yAxis.gridColor = StyleManager.wooGreyBorder yAxis.drawLabelsEnabled = true yAxis.drawGridLinesEnabled = true yAxis.drawAxisLineEnabled = true + yAxis.drawZeroLineEnabled = false } } From 24accac2cd39f4cffc363fa5d4a7871031675e09 Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Wed, 15 Aug 2018 16:49:09 -0500 Subject: [PATCH 07/18] WIP chart labels --- .../MyStore/PeriodDataViewController.swift | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift index 4bd7e5e91de..98f238d1642 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift @@ -155,19 +155,25 @@ private extension PeriodDataViewController { xAxis.labelTextColor = StyleManager.wooSecondary xAxis.axisLineColor = StyleManager.wooGreyBorder xAxis.gridColor = StyleManager.wooGreyBorder - xAxis.drawLabelsEnabled = false + xAxis.drawLabelsEnabled = true xAxis.drawGridLinesEnabled = false - xAxis.drawAxisLineEnabled = true + xAxis.drawAxisLineEnabled = false + xAxis.granularity = 1.0 + xAxis.granularityEnabled = true + xAxis.setLabelCount(2, force: true) + xAxis.valueFormatter = self let yAxis = barChartView.leftAxis yAxis.labelFont = StyleManager.chartLabelFont yAxis.labelTextColor = StyleManager.wooSecondary yAxis.axisLineColor = StyleManager.wooGreyBorder yAxis.gridColor = StyleManager.wooGreyBorder + yAxis.zeroLineColor = StyleManager.wooGreyBorder yAxis.drawLabelsEnabled = true yAxis.drawGridLinesEnabled = true - yAxis.drawAxisLineEnabled = true - yAxis.drawZeroLineEnabled = false + yAxis.drawAxisLineEnabled = false + yAxis.drawZeroLineEnabled = true + yAxis.axisMinimum = 0 } } @@ -237,6 +243,20 @@ private extension PeriodDataViewController { } +// MARK: - IAxisValueFormatter Conformance +// +extension PeriodDataViewController: IAxisValueFormatter { + func stringForValue(_ value: Double, axis: AxisBase?) -> String { + guard let item = orderStats?.items?[Int(value)] else { + return "" + } + + //TODO: This is not right! + return String(item.period) + } +} + + // MARK: - Constants! // private extension PeriodDataViewController { From 2076ee3d9d812fc772ce67c46cd5ccaea18cbae5 Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Sat, 18 Aug 2018 18:46:31 -0500 Subject: [PATCH 08/18] Cleaned up YAxis on charts --- .../MyStore/PeriodDataViewController.swift | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift index 98f238d1642..f1cedde7eaf 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift @@ -169,6 +169,7 @@ private extension PeriodDataViewController { yAxis.axisLineColor = StyleManager.wooGreyBorder yAxis.gridColor = StyleManager.wooGreyBorder yAxis.zeroLineColor = StyleManager.wooGreyBorder + yAxis.valueFormatter = self yAxis.drawLabelsEnabled = true yAxis.drawGridLinesEnabled = true yAxis.drawAxisLineEnabled = false @@ -247,12 +248,20 @@ private extension PeriodDataViewController { // extension PeriodDataViewController: IAxisValueFormatter { func stringForValue(_ value: Double, axis: AxisBase?) -> String { - guard let item = orderStats?.items?[Int(value)] else { + guard let axis = axis, let orderStats = orderStats else { return "" } - //TODO: This is not right! - return String(item.period) + if axis is XAxis { + if let item = orderStats.items?[Int(value)] { + //TODO: This is not right! + return String(item.period) + } else { + return "" + } + } else { + return orderStats.currencySymbol + value.friendlyString() + } } } From a0fbc0f2448fcd2f2a63f7e99b624b58c8e0c8ff Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Sat, 18 Aug 2018 19:17:36 -0500 Subject: [PATCH 09/18] WIP date formatting for charting --- .../Classes/Extensions/Date+Helpers.swift | 46 +++++++++++++++++++ .../MyStore/PeriodDataViewController.swift | 26 +++++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/WooCommerce/Classes/Extensions/Date+Helpers.swift b/WooCommerce/Classes/Extensions/Date+Helpers.swift index 0b61e0add09..32ee52094f7 100644 --- a/WooCommerce/Classes/Extensions/Date+Helpers.swift +++ b/WooCommerce/Classes/Extensions/Date+Helpers.swift @@ -18,4 +18,50 @@ extension DateFormatter { return formatter }() } + + /// Chart Formatters + /// + struct Charts { + + /// Date formatter used for creating the date displayed on a chart axis for **day** granularity. + /// + public static let chartsDayFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.timeZone = TimeZone(identifier: "GMT") + formatter.dateFormat = "MMM dd" + return formatter + }() + + /// Date formatter used for creating the date displayed on a chart axis for **week** granularity. + /// + public static let chartsWeekFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.timeZone = TimeZone(identifier: "GMT") + formatter.dateFormat = "MMM yyyy" + return formatter + }() + + /// Date formatter used for creating the date displayed on a chart axis for **month** granularity. + /// + public static let chartsMonthFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.timeZone = TimeZone(identifier: "GMT") + formatter.dateFormat = "MMM yyyy" + return formatter + }() + + /// Date formatter used for creating the date displayed on a chart axis for **year** granularity. + /// + public static let chartsYearFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.timeZone = TimeZone(identifier: "GMT") + formatter.dateFormat = "yyyy" + return formatter + }() + } + } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift index f1cedde7eaf..7c56bcf3788 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.swift @@ -254,13 +254,33 @@ extension PeriodDataViewController: IAxisValueFormatter { if axis is XAxis { if let item = orderStats.items?[Int(value)] { - //TODO: This is not right! - return String(item.period) + // FIXME: This logic could prolly be pushed into a model extension + var dateString = "" + switch orderStats.granularity { + case .day: + if let periodDate = DateFormatter.Stats.statsDayFormatter.date(from: item.period) { + dateString = DateFormatter.Charts.chartsDayFormatter.string(from: periodDate) + } + case .week: + if let periodDate = DateFormatter.Stats.statsWeekFormatter.date(from: item.period) { + dateString = DateFormatter.Charts.chartsWeekFormatter.string(from: periodDate) + } + case .month: + if let periodDate = DateFormatter.Stats.statsMonthFormatter.date(from: item.period) { + dateString = DateFormatter.Charts.chartsMonthFormatter.string(from: periodDate) + } + case .year: + if let periodDate = DateFormatter.Stats.statsYearFormatter.date(from: item.period) { + dateString = DateFormatter.Charts.chartsYearFormatter.string(from: periodDate) + } + } + + return dateString } else { return "" } } else { - return orderStats.currencySymbol + value.friendlyString() + return value.friendlyString() } } } From a31062d90d268b493df02f78d67e05e482a853a2 Mon Sep 17 00:00:00 2001 From: Matt Bumgardner Date: Sat, 18 Aug 2018 19:35:55 -0500 Subject: [PATCH 10/18] Added side padding to chart --- .../MyStore/PeriodDataViewController.xib | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.xib b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.xib index ac0ed6a5c1e..2671ee98a09 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.xib +++ b/WooCommerce/Classes/ViewRelated/Dashboard/MyStore/PeriodDataViewController.xib @@ -158,13 +158,32 @@ - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + +