Core-plot - построение очень маленьких чисел на точечной диаграмме - PullRequest
2 голосов
/ 03 апреля 2012

На точечной диаграмме мои данные по x-координате - это просто длинные числа, представляющие время в секундах с начала эпохи, тогда как данные по y-координате выглядят следующим образом: 0.675088, 0.670629, 0.669599. То, что я хочу показать в виде основных тиков на оси у, выглядит примерно так: 0,64, 0,65, 0,66, 0,67, но в настоящее время на графике показано: 0,5, 0,7, 1,0, 1,2.

Прежде всего, я не знаю, почему я получаю неправильный интервал между тиками, как упомянуто выше (от 0,5 до 0,7 = 0,2, от 0,7 до 1,0 = 0,3?), Но я предполагаю, потому что я экспериментировал с политикой маркировки и установили для него CPTAxisLabelingPolicyEqualDivisions - может кто-нибудь объяснить, что означают все эти политики маркировки?

Реальный вопрос в том, какое значение я должен использовать для majorIntervalLength на оси Y, учитывая, что я строю очень маленькие числа? На данный момент у меня есть 0,01, но, поскольку я корректирую это значение на порядок -n, это на самом деле не имеет никакого значения для моего графика.

Это фрагмент моего кода, основанный на Plot_Gallery_iOS DatePlot.m

-(void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme
{
CGRect bounds = layerHostingView.bounds;

NSDate *refDate = [NSDate dateWithTimeIntervalSince1970:0];
NSTimeInterval oneDay = 24 * 60 * 60;

CPTGraph *graph = [[[CPTXYGraph alloc] initWithFrame:bounds] autorelease];
[self addGraph:graph toHostingView:layerHostingView];
[self applyTheme:theme toGraph:graph withDefault:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];

[self setTitleDefaultsForGraph:graph withBounds:bounds];
[self setPaddingDefaultsForGraph:graph withBounds:bounds];

CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;

NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
NSTimeInterval threeMonthsago = now - (90*oneDay);

plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(threeMonthsago) length:CPTDecimalFromFloat(now - threeMonthsago)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.6f) length:CPTDecimalFromFloat(0.7f)];

NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateStyle = kCFDateFormatterShortStyle;
CPTTimeFormatter *timeFormatter = [[[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter] autorelease];
timeFormatter.referenceDate = refDate;

// Axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x          = axisSet.xAxis;
x.majorIntervalLength         = CPTDecimalFromFloat(oneDay*30);
x.orthogonalCoordinateDecimal = CPTDecimalFromFloat(0.6f);
x.minorTicksPerInterval       = 7;
x.labelFormatter            = timeFormatter;
x.labelRotation             = M_PI / 4;
x.preferredNumberOfMajorTicks = 5;

CPTXYAxis *y = axisSet.yAxis;
y.majorIntervalLength         = CPTDecimalFromDouble(0.001);
y.labelingPolicy = CPTAxisLabelingPolicyEqualDivisions;
y.preferredNumberOfMajorTicks = 5;
y.minorTicksPerInterval       = 10;
y.orthogonalCoordinateDecimal = CPTDecimalFromFloat(now);
//    y.visibleRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.6f) length:CPTDecimalFromFloat(0.1f)];
CPTScatterPlot *dataSourceLinePlot = [[[CPTScatterPlot alloc] init] autorelease];
dataSourceLinePlot.identifier = @"Date Plot";

// [plotSpace scaleToFitPlots:[NSArray arrayWithObjects:dataSourceLinePlot, nil]];

CPTMutableLineStyle *lineStyle = [[dataSourceLinePlot.dataLineStyle mutableCopy] autorelease];
lineStyle.lineWidth              = .5f;
lineStyle.lineColor              = [CPTColor greenColor];
dataSourceLinePlot.dataLineStyle = lineStyle;

// Auto scale the plot space to fit the plot data
// Extend the ranges by 30% for neatness
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:dataSourceLinePlot, nil]];
CPTMutablePlotRange *xRange = [[plotSpace.xRange mutableCopy] autorelease];
CPTMutablePlotRange *yRange = [[plotSpace.yRange mutableCopy] autorelease];
[xRange expandRangeByFactor:CPTDecimalFromDouble(1.3)];
[yRange expandRangeByFactor:CPTDecimalFromDouble(1.3)];
plotSpace.xRange = xRange;
plotSpace.yRange = yRange;

dataSourceLinePlot.dataSource = self;
[graph addPlot:dataSourceLinePlot];
 }

UPDATE:

Решил проблему, установив пользовательские основные тики, выполнив это:

y.labelingPolicy = CPTAxisLabelingPolicyLocationsProvided;

NSSet *majorTickLoc = [NSSet setWithObjects:[NSDecimalNumber numberWithFloat:0.64f], [NSDecimalNumber numberWithFloat:0.65f], [NSDecimalNumber numberWithFloat:0.66f], [NSDecimalNumber numberWithFloat:0.67f],[NSDecimalNumber numberWithFloat:0.68f],nil];
y.majorTickLocations = majorTickLoc;

Но число все равно оказалось округленным, т. Е. Имеющим только одну дробную цифру 0,6, 0,7, 0,7 и т. Д., И оказалось, что это просто маркировка. Настройка числового форматера на этикетке работает:

NSNumberFormatter *yFormatter = [[NSNumberFormatter alloc] init];
[yFormatter setMinimumFractionDigits:4];
[yFormatter setMaximumFractionDigits:4];
[yFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
y.labelFormatter = yFormatter;

Ответы [ 2 ]

0 голосов
/ 04 апреля 2012

Установите labelFormatter для оси Y.

NSNumberFormatter *newFormatter = [[[NSNumberFormatter alloc] init] autorelease];
newFormatter.minimumIntegerDigits = 1;
newFormatter.maximumFractionDigits = 2;
newFormatter.minimumFractionDigits = 2;
y.labelFormatter = newFormatter;
0 голосов
/ 03 апреля 2012

Попробуйте следующий код:

y.majorIntervalLength = CPTDecimalFromString(@"0.1")
...