2016-07-16 66 views
0

缺省的CareKit實現創建一個只有兩個參數的圖表進行比較和對比。是否可以使用圖表中的所有參數來使用戶能夠同時比較和對比不同參數的進度。在CareKit中創建具有多個參數的圖表

我用下面的代碼目前但這拋出試圖增加更多的參數時異常錯誤:

import CareKit 

class BuildInsightsOperation: NSOperation { 

    // MARK: Properties 

    var medicationEvents: DailyEvents? 

    var backPainEvents: DailyEvents? 

    private(set) var insights = [OCKInsightItem.emptyInsightsMessage()] 

    // MARK: NSOperation 

    override func main() { 
     // Do nothing if the operation has been cancelled. 
     guard !cancelled else { return } 

     // Create an array of insights. 
     var newInsights = [OCKInsightItem]() 

     if let insight = createMedicationAdherenceInsight() { 
      newInsights.append(insight) 
     } 

     if let insight = createBackPainInsight() { 
      newInsights.append(insight) 
     } 

     // Store any new insights thate were created. 
     if !newInsights.isEmpty { 
      insights = newInsights 
     } 
    } 

    // MARK: Convenience 

    func createMedicationAdherenceInsight() -> OCKInsightItem? { 
     // Make sure there are events to parse. 
     guard let medicationEvents = medicationEvents else { return nil } 

     // Determine the start date for the previous week. 
     let calendar = NSCalendar.currentCalendar() 
     let now = NSDate() 

     let components = NSDateComponents() 
     components.day = -7 
     let startDate = calendar.weekDatesForDate(calendar.dateByAddingComponents(components, toDate: now, options: [])!).start 

     var totalEventCount = 0 
     var completedEventCount = 0 

     for offset in 0..<7 { 
      components.day = offset 
      let dayDate = calendar.dateByAddingComponents(components, toDate: startDate, options: [])! 
      let dayComponents = NSDateComponents(date: dayDate, calendar: calendar) 
      let eventsForDay = medicationEvents[dayComponents] 

      totalEventCount += eventsForDay.count 

      for event in eventsForDay { 
       if event.state == .Completed { 
        completedEventCount += 1 
       } 
      } 
     } 

     guard totalEventCount > 0 else { return nil } 

     // Calculate the percentage of completed events. 
     let medicationAdherence = Float(completedEventCount)/Float(totalEventCount) 

     // Create an `OCKMessageItem` describing medical adherence. 
     let percentageFormatter = NSNumberFormatter() 
     percentageFormatter.numberStyle = .PercentStyle 
     let formattedAdherence = percentageFormatter.stringFromNumber(medicationAdherence)! 

     let insight = OCKMessageItem(title: "Adherence", text: "Your routine adherence was \(formattedAdherence) last week.", tintColor: Colors.Pink.color, messageType: .Tip) 

     return insight 
    } 

    func createBackPainInsight() -> OCKInsightItem? { 
     // Make sure there are events to parse. 
     guard let medicationEvents = medicationEvents, backPainEvents = backPainEvents else { return nil } 

     // Determine the date to start pain/medication comparisons from. 
     let calendar = NSCalendar.currentCalendar() 
     let components = NSDateComponents() 
     components.day = -7 

     let startDate = calendar.dateByAddingComponents(components, toDate: NSDate(), options: [])! 

     // Create formatters for the data. 
     let dayOfWeekFormatter = NSDateFormatter() 
     dayOfWeekFormatter.dateFormat = "E" 

     let shortDateFormatter = NSDateFormatter() 
     shortDateFormatter.dateFormat = NSDateFormatter.dateFormatFromTemplate("Md", options: 0, locale: shortDateFormatter.locale) 

     let percentageFormatter = NSNumberFormatter() 
     percentageFormatter.numberStyle = .PercentStyle 

     /* 
      Loop through 7 days, collecting medication adherance and pain scores 
      for each. 
     */ 
     var medicationValues = [Float]() 
     var medicationLabels = [String]() 
     var painValues = [Int]() 
     var painLabels = [String]() 
     var axisTitles = [String]() 
     var axisSubtitles = [String]() 

     for offset in 0..<7 { 
      // Determine the day to components. 
      components.day = offset 
      let dayDate = calendar.dateByAddingComponents(components, toDate: startDate, options: [])! 
      let dayComponents = NSDateComponents(date: dayDate, calendar: calendar) 

      // Store the pain result for the current day. 
      if let result = backPainEvents[dayComponents].first?.result, score = Int(result.valueString) where score > 0 { 
       painValues.append(score) 
       painLabels.append(result.valueString) 
      } 
      else { 
       painValues.append(0) 
       painLabels.append(NSLocalizedString("N/A", comment: "")) 
      } 

      // Store the medication adherance value for the current day. 
      let medicationEventsForDay = medicationEvents[dayComponents] 
      if let adherence = percentageEventsCompleted(medicationEventsForDay) where adherence > 0.0 { 
       // Scale the adherance to the same 0-10 scale as pain values. 
       let scaledAdeherence = adherence * 10.0 

       medicationValues.append(scaledAdeherence) 
       medicationLabels.append(percentageFormatter.stringFromNumber(adherence)!) 
      } 
      else { 
       medicationValues.append(0.0) 
       medicationLabels.append(NSLocalizedString("N/A", comment: "")) 
      } 

      axisTitles.append(dayOfWeekFormatter.stringFromDate(dayDate)) 
      axisSubtitles.append(shortDateFormatter.stringFromDate(dayDate)) 
     } 

     // Create a `OCKBarSeries` for each set of data. 
     let painBarSeries = OCKBarSeries(title: "Feel", values: painValues, valueLabels: painLabels, tintColor: Colors.Blue.color) 
     let medicationBarSeries = OCKBarSeries(title: "Adherence", values: medicationValues, valueLabels: medicationLabels, tintColor: Colors.LightBlue.color) 

     /* 
      Add the series to a chart, specifing the scale to use for the chart 
      rather than having CareKit scale the bars to fit. 
     */ 
     let chart = OCKBarChart(title: "Mood", 
           text: nil, 
           tintColor: Colors.Blue.color, 
           axisTitles: axisTitles, 
           axisSubtitles: axisSubtitles, 
           dataSeries: [painBarSeries, medicationBarSeries], 
           minimumScaleRangeValue: 0, 
           maximumScaleRangeValue: 10) 

     return chart 
    } 

    /** 
     For a given array of `OCKCarePlanEvent`s, returns the percentage that are 
     marked as completed. 
    */ 
    private func percentageEventsCompleted(events: [OCKCarePlanEvent]) -> Float? { 
     guard !events.isEmpty else { return nil } 

     let completedCount = events.filter({ event in 
      event.state == .Completed 
     }).count 

     return Float(completedCount)/Float(events.count) 
    } 
} 

/** 
An extension to `SequenceType` whose elements are `OCKCarePlanEvent`s. The 
extension adds a method to return the first element that matches the day 
specified by the supplied `NSDateComponents`. 
*/ 
extension SequenceType where Generator.Element: OCKCarePlanEvent { 

    func eventForDay(dayComponents: NSDateComponents) -> Generator.Element? { 
     for event in self where 
       event.date.year == dayComponents.year && 
       event.date.month == dayComponents.month && 
       event.date.day == dayComponents.day { 
      return event 
     } 

     return nil 
    } 
} 

回答

0

看起來它可以創建多個圖表,然後堆疊起來在彼此創造全參數比較

let chart = OCKBarChart(title: "Mood", 
          text: nil, 
          tintColor: Colors.Blue.color, 
          axisTitles: axisTitles, 
          axisSubtitles: axisSubtitles, 
          dataSeries: [painBarSeries, medicationBarSeries], 
          minimumScaleRangeValue: 0, 
          maximumScaleRangeValue: 10) 

    return chart 
相關問題