I am getting data that have epochtime,need to show this epochtime on axis with fixed interval time.I am able to do this thing,but while displaying I need to show only Date not the epochtime.
Code Snippet
long long xLow = [[[plotData firstObject] objectForKey:#"Time"] longLongValue];
long long xHigh = [[[plotData lastObject] objectForKey:#"Time"] longLongValue];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(xLow)
length:CPTDecimalFromDouble(xHigh-xLow)];
// Set axis styles
CPTXYAxis *leftY = [(CPTXYAxisSet *)graph.axisSet yAxis];
CPTXYAxis *x = [(CPTXYAxisSet *)graph.axisSet xAxis];
x.preferredNumberOfMajorTicks = 6;
long long intervalSize = (xHigh - xLow)/6;
x.majorIntervalLength = CPTDecimalFromLongLong(intervalSize);
x.majorTickLength = 2.0;
x.minorTickLength = 1.0;
You need a labelFormatter for the axis labels. You can use CPTTimeFormatter or CPTCalendarFormatter or make your own custom formatter. There is sample code for both built-in formatter classes in the Core Plot example apps.
Related
I'm experiencing some problems with CorePlot. I try to plot multiple scatterPlots into one graph. Which works as expected but when I start scrolling or zooming the graph the whole app increases it's memory usage up to 900MB an crashes. I think I have to do some object releasing but I don't know how. Basically I plot each line with a different plot identifier and put the according data into the datasource.
Here is what I got: (In this example code I just reduced the axe ranges with static values for testing purposes.)
- (void)setupGraph {
// Create graph from theme
self.graph = [[CPTXYGraph alloc] initWithFrame:self.scatterPlotView.bounds];
self.graph.plotAreaFrame.masksToBorder = NO;
self.scatterPlotView.hostedGraph = self.graph;
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainBlackTheme];
[self.graph applyTheme:theme];
self.graph.paddingLeft = 0.0;
self.graph.paddingTop = 0.0;
self.graph.paddingRight = 0.0;
self.graph.paddingBottom = 0.0;
// Setup plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.delegate = self;
plotSpace.globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(30)];
plotSpace.globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(10)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
CPTXYAxis *y = axisSet.yAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
}
This method loads my data and draws the scatterplots
- (void)loadSignals {
//Data loading logic goes here nothing special just one array for each plot
for (Signal *sig in [signals allValues]) {
[self constructScatterPlot:sig.name];
}
}];
This is where the drawing happens:
- (void)constructScatterPlot:(NSString *)identifier {
CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];
CPTMutableLineStyle *lineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy];
CPTScatterPlot *boundLinePlot = [[CPTScatterPlot alloc] init];
boundLinePlot.identifier = identifier;
lineStyle = [boundLinePlot.dataLineStyle mutableCopy];
lineStyle.miterLimit = 1.0;
lineStyle.lineWidth = 1.0;
lineStyle.lineColor = [CPTColor redColor];
boundLinePlot.dataLineStyle = lineStyle;
boundLinePlot.dataSource = self;
boundLinePlot.cachePrecision = CPTPlotCachePrecisionDouble;
boundLinePlot.interpolation = CPTScatterPlotInterpolationStepped;
[self.graph addPlot:boundLinePlot];
}
...and this is where the datasource gets it's values:
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSString *plotIdent = (NSString *) plot.identifier;
if (![plotIdent isEqualToString:self.currentIdent]) {
self.countPlot++;
self.currentIdent = plotIdent;
}
Signal *newSig = [self.signals objectForKey:plotIdent];
Value * newValue = [newSig valueAtTime:index];
NSNumber *number = [NSNumber numberWithInteger:[newValue.value integerValue]];
if ( fieldEnum == CPTScatterPlotFieldY ) {
return number;
}
if ( fieldEnum == CPTScatterPlotFieldX ) {
return [NSNumber numberWithInteger:index];
}
return nil;
}
So first of all I'd like to know if this is the correct way of drawing multiple plots (up to 40 in my case) into one graph? If so, what could I do to optimize my plot performance?
The output should look like this:
I found this use
"try setting collapsesLayers to YES on the hosting view"
Application get stuck when drawing nearly 40 Scatter Plots using Core Plot in IPad
Each plot is a CALayer that covers the entire plot area of the graph, so with 40 of them you may be using up most of the available video memory. If they all use the same line style, you can plot all of the lines on the same plot and save some memory that way. Insert an extra data point between the line segments and return nil or #(NAN) from the datasource to break the line.
I am trying to make a bar graph with core plot. I cannot get the y-axis to scale properly or the tick-marks in the correct places. My biggest issue is that if I set:
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDEcimalFromFloat(0) length:CPTDecimalFromFloat(max_value);
And max_value is anything higher then 10 it takes an unreasonable amount of time for the graph to load. For example I need max_value to be around 1000 to show the tops of all the values but when I set it to 1000 it takes over 15 seconds to load the screen. But if I leave it set to 10 my bar graphs take up the entire screen and you cannot see the top.
This is the rest of the part of the code dealing with this. Any advice would be appreciated.
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0)
length:CPTDecimalFromFloat(1000)];
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:_liftOffPlot,_sideLeanPlot,_forwardLeanPlot,_crossLegsPlot,nil]];
graph.plotAreaFrame.borderLineStyle = nil;
axisSet.yAxis.title = #"times completed";
axisSet.yAxis.titleTextStyle = axisTitleStyle;
axisSet.yAxis.titleOffset = -25.0f;
axisSet.yAxis.axisLineStyle = nil;
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
axisSet.yAxis.preferredNumberOfMajorTicks = 10;
axisSet.yAxis.minorTicksPerInterval = 1;
axisSet.yAxis.minorTickLocations = nil;
axisSet.yAxis.majorTickLocations = nil;
axisSet.yAxis.title = #"times completed";
axisSet.yAxis.titleTextStyle = axisTitleStyle;
axisSet.yAxis.titleOffset = -25.0f;
axisSet.yAxis.axisLineStyle = nil;
axisSet.yAxis.majorIntervalLength = CPTDecimalFromString(#"100");
axisSet.yAxis.orthogonalCoordinateDecimal = CPTDecimalFromString(#"0");
axisSet.yAxis.visibleRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(1000)];
axisSet.yAxis.gridLinesRange = axisSet.yAxis.visibleRange;
As I seem to be finding with most things xcode, it is all about where you put your code. If I have CPTPlotRange:PlotRangeWithLocation:Length before I do my set up it is really slow and buggy. If instead I add it to the end of my code after setting the other values for the axises suddenly there is only a very minor delay. I actually got this code originally from a tutorial and modified it to fit what I needed but I guess the tutorial didn't have the same delay because the length of the data was much lower.
So all I did to fix this problem was put the following code after my axis set up instead of before;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0)
length:CPTDecimalFromFloat(1000)];
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:_liftOffPlot,_sideLeanPlot,_forwardLeanPlot,_crossLegsPlot,nil]];
graph.plotAreaFrame.borderLineStyle = nil;
I want to draw only 10 Majors Ticks on my Y axis. For that I'm using the methode preferredNumberOfMajorTicks = 10.
but as seen on the screenshot, it doesn't really work ...
Here is my configuration for the y axis :
CPTXYAxis *y = axisSet.yAxis;
y.labelingPolicy = CPTAxisLabelingPolicyFixedInterval;
//y.majorIntervalLength = CPTDecimalFromDouble(2);
y.preferredNumberOfMajorTicks = 10;
y.minorTicksPerInterval = 5;
y.tickDirection = CPTSignNone;
y.majorTickLineStyle = majorLineStyle;
y.minorTickLineStyle = minorLineStyle;
y.axisLineStyle = majorLineStyle;
y.majorTickLength = 7.0;
y.minorTickLength = 5.0;
y.labelTextStyle = whiteTextStyle;
y.minorTickLabelTextStyle = minorTickBlackTextStyle;
y.titleTextStyle = whiteTextStyle;
y.axisConstraints = [CPTConstraints constraintWithLowerOffset:40.0];
Something should over right the methode preferredNumberOfMajorTicks = 10 but I cannot see what ...
The preferredNumberOfMajorTicks property does not apply to the fixed interval labeling policy. See the Core Plot docs for details. You have two options here:
Keep the fixed interval labeling policy and change the majorIntervalLength to a value that will give the desired number of ticks.
Change the labeling policy to CPTAxisLabelingPolicyAutomatic or CPTAxisLabelingPolicyEqualDivisions.
I think i found a bug similar to issue 104
I have a bar graph. My axis is fixed with constraint and i use padding left on my plot area and custom label for my X axis.
It is import to show the last bars so my xRange starts on the end with the code below
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat([[posicoes lastObject] floatValue]) length:CPTDecimalFromFloat(tipoEscalaGrafico*60*13)];
Everything works perfectly except from the label.
On the print bellow you can see the problem
http://3.bp.blogspot.com/-BLWrnrZ1MZY/T8aMqEc3PzI/AAAAAAAAAG8/sXhIgvuuj_0/s1600/Captura+de+Tela+2012-05-30+às+18.05.01.png
The label doesn't respect the padding.
If i scroll the graph then it respect the padding as the screen bellow
http://1.bp.blogspot.com/-uvFem8xERAo/T8aMmaLRl2I/AAAAAAAAAG0/DZx_UwCcmbA/s1600/Captura+de+Tela+2012-05-30+às+18.05.01+(2).png
I have a class that inherits from CPTXYGraph and i did the method below to add custom labl=els
-(void)setarLabelsEixoX:(NSArray *)labels naPosicao:(NSArray *)posicaoLabels;{
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[labels count]];
for ( NSNumber *tickLocation in posicaoLabels ) {
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText:[labels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
newLabel.tickLocation = [tickLocation decimalValue];
newLabel.offset = x.labelOffset;
newLabel.alignment = CPTAlignmentCenter;
[customLabels addObject:newLabel];
}
axisSet.xAxis.majorTickLocations = (NSSet*)posicaoLabels;
x.axisLabels = [NSSet setWithArray:customLabels];
}
I did a little testing with the latest Core Plot code. I don't see an issue. Did you verify that the tick location of the errant label was actually outside the plot range? What version of Core Plot are you using?
I am using Core Plot alpha release 0.2 and generating a plot with custom labels. The labels are appearing in the correct location but I have no tick marks. I have tried every combination of these settings:
x.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:#"5"] decimalValue];
x.minorTicksPerInterval = 0;
x.majorTickLineStyle = lineStyle;
x.minorTickLineStyle = lineStyle;
x.axisLineStyle = lineStyle;
x.minorTickLength = 5.0f;
x.majorTickLength = 7.0f;
x.tickDirection=CPSignNegative;
I've also added padding to the bottom of the graph using:
graph.plotAreaFrame.paddingBottom=10.0;
which has the effect of moving the X axis 'up' but no tick marks are visible. This seems like it should be pretty simple, generate a tick mark at the location of the custom label. But I don't see any way to do it.
Ideas?
**** Here's the code I'm using to generate the labels and tick marks, with no luck *
for (int i = 0; i < [xAxisLabels count]; i++) {
NSDictionary * labelDict = [xAxisLabels objectAtIndex:i];
NSString *label=[labelDict valueForKey:#"element"];
NSNumber *offset=[labelDict valueForKey:#"x"];
float location=[offset floatValue]*multiplier;
CPAxisLabel *newLabel = [[CPAxisLabel alloc] initWithText: label textStyle:labelStyle];
newLabel.tickLocation = CPDecimalFromFloat(location);
newLabel.offset = x.labelOffset + x.majorTickLength;
[customTicks addObject:[NSDecimalNumber decimalNumberWithDecimal:CPDecimalFromFloat(location)]];
[customLabels addObject:newLabel];
[newLabel release];
}
x.axisLabels = [NSSet setWithArray:customLabels];
[x setMinorTickLocations:[NSSet setWithArray:customTicks]];
[x setMajorTickLocations:[NSSet setWithArray:customTicks]];
[customTicks release];
With CPAxisLabelingPolicyNone you need to provide the tick locations (minorTickLocations and majorTickLocations), too.