Search code examples
core-plot

Implementation of Core Plot DatePlot example not rendering lines


I'm attempting to add the DatePlot example of core-plot to a UIVisualEffectView. I have the graph rendering but for some reason I'm not seeing the actual line of data. I'm wondering if someone can help me see what I'm doing wrong. Below is my code. I'm calling set_up_chart, then add_chart_data, if that helps. (I've also tried calling add_chart_data before set_up_chart but get the same result.)

def graph
  @graph ||= CPTXYGraph.alloc.initWithFrame(host_view.bounds)
end

def host_view
  chart_frame = CGRect.new(
    [0, 0],
    [vibrancy_view.frame.size.width, vibrancy_view.frame.size.height]
  )

  @host_view ||= CPTGraphHostingView.alloc.initWithFrame(chart_frame)
end

def set_up_chart
  # graph.applyTheme(CPTTheme.themeNamed(KCPTDarkGradientTheme))
  host_view.backgroundColor = UIColor.clearColor
  host_view.allowPinchScaling = false

  whiteTextStyle = CPTMutableTextStyle.alloc.init
  whiteTextStyle.color    = CPTColor.whiteColor
  whiteTextStyle.fontSize = 12.0

  whiteTickStyle = CPTLineStyle.alloc.init
  whiteTickStyle.lineColor = CPTColor.whiteColor
  whiteTickStyle.lineWidth = 0.5

  axisLineStyle = CPTMutableLineStyle.alloc.init
  axisLineStyle.lineColor = CPTColor.whiteColor
  axisLineStyle.lineWidth = 1.0
  axisLineStyle.lineCap   = KCGLineCapRound

  host_view.hostedGraph = graph

  graph.paddingLeft   = 5.0
  graph.paddingTop    = 5.0
  graph.paddingRight  = 5.0
  graph.paddingBottom = 5.0

  graph.plotAreaFrame.paddingLeft   = 32.0
  graph.plotAreaFrame.paddingTop    = 0.0
  graph.plotAreaFrame.paddingRight  = 0.0
  graph.plotAreaFrame.paddingBottom = 22.0

  # Plot space
  plotSpace = graph.defaultPlotSpace

  start_time = Time.now.to_i
  plotSpace.xRange = CPTPlotRange.plotRangeWithLocation(0.0, length: 1)

  y_range_length = ((event[:range_minimum]).abs + 1) + (event[:range_maximum] + 1)
  y_start = event[:range_minimum] - 1
  plotSpace.yRange = CPTPlotRange.plotRangeWithLocation(y_start, length: y_range_length)

  plotSpace.delegate = self

  axisSet = graph.axisSet

  # X axis
  x = axisSet.xAxis
  x.labelingPolicy        = CPTAxisLabelingPolicyAutomatic
  x.majorIntervalLength   = start_time
  # set where the x-axis aligns itself
  x.orthogonalPosition    = y_start

  x.minorTicksPerInterval = 0
  x.labelOffset           = 0.25
  x.labelTextStyle          = whiteTextStyle
  x.titleTextStyle          = whiteTextStyle
  x.axisLineStyle           = axisLineStyle
  x.majorTickLineStyle      = whiteTickStyle
  x.minorTickLineStyle      = whiteTickStyle
  x.axisConstraints         = CPTConstraints.constraintWithLowerOffset(0.0)
  # x.labelOffset = 16.0
  x.majorTickLength = 4.0
  x.minorTickLength = 2.0
  # x.tickDirection = CPTSignPositive
  x.preferredNumberOfMajorTicks = 4.0
  # x.majorGridLineStyle    = majorGridLineStyle
  # x.minorGridLineStyle    = minorGridLineStyle

  dateFormatter = NSDateFormatter.alloc.init
  dateFormatter.setDateFormat("h:mm")
  timeFormatter = CPTTimeFormatter.alloc.initWithDateFormatter(dateFormatter)
  timeFormatter.referenceDate = reference_date
  x.labelFormatter            = timeFormatter

  # Y axis
  y = axisSet.yAxis
  y.labelingPolicy        = CPTAxisLabelingPolicyAutomatic
  y.orthogonalPosition    = 0.0
  # y.majorGridLineStyle    = majorGridLineStyle
  # y.minorGridLineStyle    = minorGridLineStyle
  y.minorTicksPerInterval = 1
  y.labelOffset           = 0.25
  y.axisConstraints       = CPTConstraints.constraintWithLowerOffset(0.0)
  y.labelTextStyle          = whiteTextStyle
  y.titleTextStyle          = whiteTextStyle
  y.axisLineStyle           = axisLineStyle
  y.majorTickLineStyle      = whiteTickStyle

  # Remove minor ticks on y-axis
  y.minorTickLineStyle      = whiteTickStyle

  # Create the plot
  dataSourceLinePlot = CPTScatterPlot.alloc.init
  dataSourceLinePlot.identifier     = "Test"
  dataSourceLinePlot.cachePrecision = CPTPlotCachePrecisionDouble

  lineStyle = dataSourceLinePlot.dataLineStyle.mutableCopy
  lineStyle.lineWidth              = 3.0
  lineStyle.lineColor              = CPTColor.greenColor
  dataSourceLinePlot.dataLineStyle = lineStyle

  dataSourceLinePlot.dataSource = self
  dataSourceLinePlot.delegate = self

  graph.addPlot(dataSourceLinePlot)
end

def add_chart_data
  if self.chart_data.count == 0
    array = []

    100.times do |n|
      value = [-5,-1,0,1,5].sample
      time = (Time.now.to_i - 100) + (5 * n)
      data = {CPTScatterPlotFieldX => time, CPTScatterPlotFieldY => value}
      array << data

      self.chart_data = array
    end
  end

  graph.reloadData
end

def numberOfRecordsForPlot(plot)
  self.chart_data.count
end

def numberForPlot(plot, field: fieldEnum, recordIndex: index)
  if self.chart_data[index]
    if fieldEnum == CPTScatterPlotFieldX
      self.chart_data[index][fieldEnum]
    else
      self.chart_data[index][fieldEnum]
    end
  end
end

Solution

  • The xRange for the plot space is being initialized to [0, 1] while the data is initialized to values between time - 125 and time - 75. All of the data points are outside this xRange.

    Do you need to use the current time when computing the data points? If so, save it somewhere and use the same value when creating the data and configuring the plot space. If not, pick a constant starting point for the data and create the xRange to match.