【问题标题】:Using core plot for iPhone, drawing date on x axis使用 iPhone 的核心图,在 x 轴上绘制日期
【发布时间】:2011-03-01 05:10:38
【问题描述】:

我有一个包含NSDateNSNumber 值的字典数组。我想在 X 轴上绘制日期。 对于绘图,我需要提供 xRanges 以绘制一些十进制值。我不明白如何将 NSDate 值提供给 xRange(低和长)。

这个方法应该有什么:

-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index

我的意思是我的日期值将如何返回为NSNumber?我想我应该在那里使用一些间隔,但是确切的转换应该是什么? 谁能解释一下在 xAxis 上绘制日期的确切要求是什么?

我在视图的一半处绘制我的情节。

【问题讨论】:

  • 嘿 xmax 我在我的项目中做同样的事情。您是否找到任何解决方法?
  • 我遇到了您面临的问题。所以你会指导我在那种情况下你会做什么。
  • 注意,有一件事,在现代 iOS 中,Apple 推荐使用日期格式化程序的唯一方法是:stackoverflow.com/a/42370648/294884

标签: ios iphone objective-c nsdate core-plot


【解决方案1】:

给你,在 iOS 上运行的 DatePlot。不要忘记检查它是否正确。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    // If you make sure your dates are calculated at noon, you shouldn't have to 
    // worry about daylight savings. If you use midnight, you will have to adjust
    // for daylight savings time.
    NSDate *refDate = [NSDate dateWithTimeIntervalSinceReferenceDate:31556926 * 10];
    NSTimeInterval oneDay = 24 * 60 * 60;

    // Invert graph view to compensate for iOS coordinates
    CGAffineTransform verticalFlip = CGAffineTransformMakeScale(1,-1);
    self.view.transform = verticalFlip;

     // allocate the graph within the current view bounds
    graph = [[CPTXYGraph alloc] initWithFrame: self.view.bounds];

    // assign theme to graph
    CPTTheme *theme = [CPTTheme themeNamed:kCPTDarkGradientTheme];
    [graph applyTheme:theme];

    // Setting the graph as our hosting layer
    CPTGraphHostingView *hostingView = [[CPTGraphHostingView alloc] initWithFrame:self.view.bounds];

    [self.view addSubview:hostingView];

    hostingView.hostedGraph = graph;

    graph.paddingLeft = 20.0;
    graph.paddingTop = 20.0;
    graph.paddingRight = 20.0;
    graph.paddingBottom = 150.0;

    // setup a plot space for the plot to live in
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
    NSTimeInterval xLow = 0.0f;
    // sets the range of x values
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xLow)
                                                   length:CPTDecimalFromFloat(oneDay*5.0f)];
    // sets the range of y values
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) 
                                                   length:CPTDecimalFromFloat(5)];

    // plotting style is set to line plots
    CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
    lineStyle.lineColor = [CPTColor blackColor];
    lineStyle.lineWidth = 2.0f;

    // X-axis parameters setting
    CPTXYAxisSet *axisSet = (id)graph.axisSet;
    axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(oneDay);
    axisSet.xAxis.minorTicksPerInterval = 0;
    axisSet.xAxis.orthogonalCoordinateDecimal = CPTDecimalFromString(@"1"); //added for date, adjust x line
    axisSet.xAxis.majorTickLineStyle = lineStyle;
    axisSet.xAxis.minorTickLineStyle = lineStyle;
    axisSet.xAxis.axisLineStyle = lineStyle;
    axisSet.xAxis.minorTickLength = 5.0f;
    axisSet.xAxis.majorTickLength = 7.0f;
    axisSet.xAxis.labelOffset = 3.0f;

    // added for date
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    dateFormatter.dateStyle = kCFDateFormatterShortStyle;
    CPTTimeFormatter *timeFormatter = [[[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter] autorelease];
    timeFormatter.referenceDate = refDate;
    axisSet.xAxis.labelFormatter = timeFormatter;

    // Y-axis parameters setting    
    axisSet.yAxis.majorIntervalLength = CPTDecimalFromString(@"0.5");
    axisSet.yAxis.minorTicksPerInterval = 2;
    axisSet.yAxis.orthogonalCoordinateDecimal = CPTDecimalFromFloat(oneDay); // added for date, adjusts y line
    axisSet.yAxis.majorTickLineStyle = lineStyle;
    axisSet.yAxis.minorTickLineStyle = lineStyle;
    axisSet.yAxis.axisLineStyle = lineStyle;
    axisSet.yAxis.minorTickLength = 5.0f;
    axisSet.yAxis.majorTickLength = 7.0f;
    axisSet.yAxis.labelOffset = 3.0f;


    // This actually performs the plotting
    CPTScatterPlot *xSquaredPlot = [[[CPTScatterPlot alloc] init] autorelease];

    CPTMutableLineStyle *dataLineStyle = [CPTMutableLineStyle lineStyle];
    //xSquaredPlot.identifier = @"X Squared Plot";
    xSquaredPlot.identifier = @"Date Plot";

    dataLineStyle.lineWidth = 1.0f;
    dataLineStyle.lineColor = [CPTColor redColor];
    xSquaredPlot.dataLineStyle = dataLineStyle;
    xSquaredPlot.dataSource = self;

    CPTPlotSymbol *greenCirclePlotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
    greenCirclePlotSymbol.fill = [CPTFill fillWithColor:[CPTColor greenColor]];
    greenCirclePlotSymbol.size = CGSizeMake(2.0, 2.0);
    xSquaredPlot.plotSymbol = greenCirclePlotSymbol;  

    // add plot to graph
    [graph addPlot:xSquaredPlot];

    // Add some data
    NSMutableArray *newData = [NSMutableArray array];
    NSUInteger i;
    for ( i = 0; i < 5; i++ ) {
        NSTimeInterval x = oneDay*i;
        id y = [NSDecimalNumber numberWithFloat:1.2*rand()/(float)RAND_MAX + 1.2];
        [newData addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          [NSDecimalNumber numberWithFloat:x], [NSNumber numberWithInt:CPTScatterPlotFieldX], 
          y, [NSNumber numberWithInt:CPTScatterPlotFieldY], 
          nil]];
        NSLog(@"%@",newData);
    }
    plotData = [newData retain];

}

#pragma mark - Plot Data Source Methods

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    return plotData.count;
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    NSDecimalNumber *num = [[plotData objectAtIndex:index] objectForKey:[NSNumber numberWithInt:fieldEnum]];
    return num;
}

【讨论】:

  • 嘿,这对我帮助很大。我只是想不通,如何实际决定哪个值写在哪个 NSTimeInterval 的 x 轴上?
  • 嗨,@zambono,符号 'plotData' 的类型是什么?我想知道它的定义。
  • 使用 CorePlot 1.1,您不再需要反转 y 轴。如果你去掉“verticalFlip”行,上面的代码就可以工作。
  • 同样重要的是在 x 值中使用 NSNumber,而不是 NSDate。
  • 使用 oneDay 等于 24*60*60 会不会在跨越夏令时时出现问题?
【解决方案2】:

查看示例文件夹中的 DatePlot 程序。它展示了如何将轴标签格式化为日期。

【讨论】:

  • 事实上我正在遵循这个例子。但是使用该技巧绘制图形但图形不可见。因为它不在范围内或提供值有问题。实际上,我的数据包含过去 3 到 6 个月的日期。在将 NSdate 转换为等效的 NSDecimalNumber 时,我没有得到我应该提供的确切参考日期。我对 plotSpace.xRange 感到困惑。我应该提供什么。?我的意思是如何从我的数据源计算为 xRange 提供的日期范围..?
  • 还有一件事是,我无法在 xAxis 上正确显示日期,例如 coreplot 中的股票图。如果我必须在核心图 StockPlot 示例上绘制 xAxis,那么它会是什么......?
  • 参考日期可以是任何你想要的。它定义了轴的零点。坐标轴范围的起始位置是坐标轴上的第一个日期与参考日期之间的差异,以秒为单位。范围长度是以秒为单位的范围长度(一天有86400秒)。
  • 感谢您的建议。我按照您提到的方式进行了操作,并且正在以应有的方式绘制图形。但是我遇到的问题是我想在 xAxis 上显示日期标签。并且当前未显示。我将 maskToBorder 属性设置为 NO。你能告诉我哪里可能是问题..?我也为 xAxis 提供了 CPdateFormatter ..
  • 将 dateplot 从 osx 转换为 ios 给我带来了错误的访问错误,但仅在将数据提供给图表时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多