I'm using a custom image symbol, as described in Showing images on Scattering Graph as plot symbols in Core plot iOS. Also refer to Positioning label on CPTBarPlot (Core-Plot) regarding positioning of the data label in a CPTPlot.
However, I'm not seeing the behavior from CPTScatterPlot.labelOffset that I need. Positive values increase the distance between the image bottom and the point, while negative values increase the distance between the image top and the point. I need to center the image on the point. See screenshots:
positive labelOffset values:
negative labelOffset values:
My solution is hacky and requires me to modify the image frame in my CustomImageForScatterPlot's drawInContext method. Any ideas on how to make labelOffset work how I want?
That behavior is correct for data labels. You want to use a plot symbol.
-(CPTPlotSymbol *)symbolForScatterPlot:(CPTScatterPlot *)plot
recordIndex:(NSUInteger)index
{
CPTPlotSymbol *symbol = nil;
if ( /* use symbol for this index? */ ) {
symbol = [CPTPlotSymbol ellipsePlotSymbol];
symbol.fill = [CPTFill fillWithImage:/* symbol image */];
symbol.size = CGSizeMake(width, height);
}
return symbol;
}
If you want every point to have a symbol, set the plotSymbol property instead of implementing this datasource method.
Related
I have made a bubble chart using a coreplot scatterplot by adjusting the size of each symbol in the data source method
-(CPTPlotSymbol *)symbolForScatterPlot:(CPTScatterPlot *)plot recordIndex:(NSUInteger)idx {
Event *thisEvent;
CGSize size;
CPTPlotSymbol *symbol;
symbol = [CPTPlotSymbol ellipsePlotSymbol];
CPTMutableLineStyle *lineStyle = [symbol.lineStyle mutableCopy];
if (idx < self.events.count) {
thisEvent = [self.events objectAtIndex:idx];
size.width = [thisEvent scaledValue];
size.height = size.width;
}
}
How can I create a legend showing the values for each of several symbol sizes? I've been looking at CPTLegendEntry in the class reference, but haven't been able to work it out yet. If anyone out there can help (Eric?), i'd appreciate it.
You can use a legend delegate to customize drawing the swatches. Implement the - legend:shouldDrawSwatchAtIndex:forPlot:inRect:inContext: delegate method and draw your custom swatch into the given context. Return NO to tell the legend that it doesn't need to draw the default swatch, too.
If you need more control, you can create your own. Subclass CPTBorderedLayer, override -renderAsVectorInContext: to do the drawing, and attach the custom layer to the graph as an annotation.
I have two CPTScatterPlots and I would like to find their intersection and draw a custom circle with fill there. Of course I could calculate it manually, but maybe core plot has this already.
see attached.
Is this possible with Core Plot?
UPDATE based on Eric's sugestion:
/* Add the plot symbol for the intersection */
CPTMutableLineStyle *symbolLineStyle = [CPTMutableLineStyle lineStyle];
symbolLineStyle.lineWidth = 2.;
symbolLineStyle.lineColor = [[CPTColor colorWithComponentRed:91./255. green:173./255. blue:221./255. alpha:1.] colorWithAlphaComponent:1];
CPTPlotSymbol *plotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
plotSymbol.fill = [CPTFill fillWithColor:[[CPTColor colorWithComponentRed:241./255. green:241./255. blue:241. /255. alpha:1.] colorWithAlphaComponent:1.]];
plotSymbol.lineStyle = symbolLineStyle;
plotSymbol.size = CGSizeMake(_CIRCLE_RADIUS, _CIRCLE_RADIUS);
dataSourceIntersectionPlot.plotSymbol = plotSymbol;
Core Plot can't find the intersection point for you, but it can mark it. If you know the lines will cross at one of the data points, just add a plot symbol to one of the plots. Implement the -symbolForScatterPlot:recordIndex: datasource method and return a symbol at the correct index.
If the lines might cross between data points, create a third plot that is used only for highlighting the crossing point. It only needs one data point with a plot symbol—the intersection point.
In my code images used instead of data labels using CPTPlotSpaceAnnotaions to display in center in the each bars of the bar plot. The images placed at the center and working fine, but if the image is enlarged it is stretched outside of the bar. I need it to cut off upto the bar width.
Image is drawn using,
CPTBorderedLayer *borderedLayerObject =[[CPTBorderedLayer alloc] initWithFrame:CGRectMake(0, 0, 52, 52)];
borderedLayerObject.fill = [CPTFill fillWithImage:cptimage];
NSArray *anchorPoint = [NSArray arrayWithObjects:xPosition, yPosition, nil];
CPTPlotSpaceAnnotation *imageAnnotation = [[CPTPlotSpaceAnnotation alloc]initWithPlotSpace:graph.defaultPlotSpace anchorPlotPoint:anchorPoint];
imageAnnotation.contentLayer = borderedLayerObject;
[graph.plotAreaFrame addAnnotation:imageAnnotation];
return imageAnnotation;
and this borderedLayerObject is set as the contentLayer of CPTPlotSpaceAnnotation, and CPTPlotSpaceAnnotation object is returned...
the image i draw take the frame size of borderedLayerObject and its placed over the bar in the barplot, so i'm unable to understand how to crop the image i've drawn...
CPTPlotSpaceAnnotation is used becoz i need to display the image at the center of the bar plot, using anchorpoint i've given the x and y position that where the images must be displayed in the bar of barplot. Please help me to get the solution...
It's easy to determine the width of the bars. If barWidthsAreInViewCoordinates is YES, the width is given by the barWidth property. Otherwise, you have to use the plot space to convert data coordinates to pixels. Pick two points that are barWidth units apart along the axis that is perpendicular to the bars (e.g., the x-axis for vertical bars), convert them both to view coordinates with the plot space, and find the width from the converted points.
In Core Plot for iOS, is there a way to add some sort of padding to a plot area, as opposed to a plot area frame? When using plot symbols, the symbols can be truncated if they fall on an axis line or boundary of the frame. Admittedly, I understand why this is the case when plotting a non-zero sized circle as a data symbol, but I'm curious if there's a way to add some padding to prevent this.
Or maybe there's a way to do with the axis ranges, but if so I haven't figured out the magic combination other than creating axis ranges that are "magically" large enough to account for the size of these symbols.
In the attached screenshot, the x-axis represents a week. Any data point for the first day will be truncated because it's getting drawn right on the y-axis. Ideally, I'd like this data point drawn just "a bit inside". (Which really means I want the x-axis range to increase by just enough to take this in to account.)
Likewise for the y-axis. A value of '0' plots right on the x-axis.
I don't really want the axis to show a range wider than required (i.e. I don't want the y-axis to go -1, for example.)
Thank you.
Here's some sample code from the "Control Chart" demo in the Plot Gallery example app:
// Adjust visible ranges so plot symbols along the edges are not clipped
CPTMutablePlotRange *xRange = [[plotSpace.xRange mutableCopy] autorelease];
CPTMutablePlotRange *yRange = [[plotSpace.yRange mutableCopy] autorelease];
x.orthogonalCoordinateDecimal = yRange.location;
y.orthogonalCoordinateDecimal = xRange.location;
x.visibleRange = xRange;
y.visibleRange = yRange;
x.gridLinesRange = yRange;
y.gridLinesRange = xRange;
[xRange expandRangeByFactor:CPTDecimalFromDouble(1.05)];
[yRange expandRangeByFactor:CPTDecimalFromDouble(1.05)];
plotSpace.xRange = xRange;
plotSpace.yRange = yRange;
You can adjust the expansion factor as needed based on the size of the graph and plot symbols.
Only this solved for me, values aligned properly from both sides(leading and trialing)
[xRange expandRangeByFactor:[NSNumber numberWithDouble:1.2]];
I am trying to change default position of labels in Bar chart with Core-Plot.
I am using this method:
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)idx;
And I return:
return textLayer = [[CPTTextLayer alloc] initWithText:#"2222" style:textStyle];
I get this result:
But I want to appear as follows:
Any idea? I tried to find answer on documentation, but I has been impossible.
Use a negative labelOffset for the bar plot. The default is +10 which puts the labels 10 pixels above the bars. This property is inherited from CPTPlot so it works for all plot types, although the default value and behavior varies somewhat.