I am using charts library (Charts)
I am developing the application allows me to show number of guests in restaurant realtime and compare data between different days.
For example look at this picture
The dashed line means data for the compared to date. I would like to create BarChart like this but library only allows me to show 4 grouped bars. I want to show dashed bars above colored with small offset. Help me out please
My code is:
for (int i = 0; i < days.count; i++) {
BarChartDataEntry *guysEntry = [[BarChartDataEntry alloc] initWithX:i y:[guys[i] integerValue]];
[guysChartDataArray addObject:guysEntry];
BarChartDataEntry *girlsEntry = [[BarChartDataEntry alloc] initWithX:i y:[girls[i] integerValue]];
[girlsChartDataArray addObject:girlsEntry];
BarChartDataEntry *guysCompareToEntry = [[BarChartDataEntry alloc] initWithX:i y:[guysCompareTo[i] integerValue]];
[guysCompareToChartDataArray addObject:guysCompareToEntry];
BarChartDataEntry *girlsCompareToEntry = [[BarChartDataEntry alloc] initWithX:i y:[girlsCompareTo[i] integerValue]];
[girlsCompareToChartDataArray addObject:girlsCompareToEntry];
}
BarChartDataSet *guysChartDataSet = [[BarChartDataSet alloc] initWithValues:guysChartDataArray label:#"Guys"];
guysChartDataSet.colors = #[[UIColor maleColor]];
guysChartDataSet.valueTextColor = [UIColor clearColor];
BarChartDataSet *girlsChartDataSet = [[BarChartDataSet alloc] initWithValues:girlsChartDataArray label:#"Girls"];
girlsChartDataSet.colors = #[[UIColor femaleColor]];
girlsChartDataSet.valueTextColor = [UIColor clearColor];
LineChartXAxisFormatter *barGraphXFormatter = [[LineChartXAxisFormatter alloc] init];
barGraphXFormatter.xLabels = [days mutableCopy];
self.barChartView.xAxis.valueFormatter = barGraphXFormatter;
self.barChartView.xAxis.centerAxisLabelsEnabled = YES;
self.combinedChartView.xAxis.valueFormatter = barGraphXFormatter;
self.combinedChartView.xAxis.centerAxisLabelsEnabled = YES;
float groupSpace = 0.06f;
float barSpace = 0.02f;
float barWidth = 0.45f;
BarChartDataSet *guysCompareToChartDataSet = [[BarChartDataSet alloc] initWithValues:guysCompareToChartDataArray label:#"Guys (Compare)"];
guysCompareToChartDataSet.colors = #[[UIColor clearColor]];
guysCompareToChartDataSet.barBorderWidth = 1.f;
guysCompareToChartDataSet.barBorderColor = [UIColor grayColor];
guysCompareToChartDataSet.isDashedBorder = YES;
guysCompareToChartDataSet.axisDependency = AxisDependencyLeft;
guysCompareToChartDataSet.valueTextColor = [UIColor clearColor];
BarChartDataSet *girlsCompareToChartDataSet = [[BarChartDataSet alloc] initWithValues:girlsCompareToChartDataArray label:#"Girls (Compare)"];
girlsCompareToChartDataSet.colors = #[[UIColor clearColor]];
girlsCompareToChartDataSet.barBorderWidth = 1.f;
girlsCompareToChartDataSet.barBorderColor = [UIColor grayColor];
girlsCompareToChartDataSet.isDashedBorder = YES;
girlsCompareToChartDataSet.axisDependency = AxisDependencyLeft;
girlsCompareToChartDataSet.valueTextColor = [UIColor clearColor];
NSArray *dataSets = #[guysChartDataSet, girlsChartDataSet, guysCompareToChartDataSet, girlsCompareToChartDataSet];
BarChartData *barChartData = [[BarChartData alloc] initWithDataSets:dataSets];
barChartData.barWidth = barWidth;
CGFloat initialValue = 0;
CGFloat groupCount = days.count;
self.barChartView.xAxis.axisMinimum = initialValue;
self.barChartView.xAxis.axisMaximum = initialValue + [barChartData groupWidthWithGroupSpace:groupSpace barSpace: barSpace] * groupCount;
[barChartData groupBarsFromX:0 groupSpace:groupSpace barSpace:barSpace];
self.barChartView.data = barChartData;
I want to make something like:
Now that you've changed your question, this requires a different solution.
As I mentioned in the comments before, you need to manually calculate each bar's position. Then, don't use the grouping feature, because you've already grouped them how you want.
// Determine bar sizing and spacing parameters.
int barsPerGroup = 2;
double targetGroupWidth = 1;
double barSpacing = 0.2;
double groupSpacing = 0.3;
double barWidth = (targetGroupWidth - groupSpacing - barSpacing * barsPerGroup) / barsPerGroup;
double compareBarOffset = barWidth / 3;
for (int i = 0; i < entryCount; i++) {
// Determine X position for each bar
// NOTE: This is the most important step!
double groupStartPosition = targetGroupWidth * i;
double group1X = groupStartPosition + barWidth / 2;
double group1CompareX = group1X + compareBarOffset;
double group2X = group1X + barWidth + barSpacing;
double group2CompareX = group2X + compareBarOffset;
// Create data entries positioned at values calculated by previous step
NSNumber *group1Value = group1[i];
NSNumber *group1CompareValue = group1Compare[i];
NSNumber *group2Value = group2[i];
NSNumber *group2CompareValue = group2Compare[i];
BarChartDataEntry *group1DataEntry = [[BarChartDataEntry alloc] initWithX:group1X
y:[group1Value doubleValue]];
BarChartDataEntry *group1CompareDataEntry = [[BarChartDataEntry alloc] initWithX:group1CompareX
y:[group1CompareValue doubleValue]];
BarChartDataEntry *group2DataEntry = [[BarChartDataEntry alloc] initWithX:group2X
y:[group2Value doubleValue]];
BarChartDataEntry *group2CompareEntry = [[BarChartDataEntry alloc] initWithX:group2CompareX
y:[group2CompareValue doubleValue]];
// ...
}
// Create Data Sets, set styles, etc.
// ...
// Do NOT use this method because bars are already grouped.
//[barChartView groupBarsFromX:0 groupSpace:groupSpacing barSpace:barSpacing];
RESULT:
Note: I can't find the property isDashedBorder, so I don't know what version of the library you're using. Instead, I just set clear bars with a solid gray border.
With Charts, it looks you can:
Stack data into the same bar.
Group bars so that they overlap.
It also looks like you can't:
Give each data entry in the stacked bar a separate border color. (If you supply a border color, it will apply to the entire bar.)
Note about documentation
Do remember that Charts is modeled after MPAndroidChart and follows its API very closely.
Therefore, if you need help, refer to their documentation. The Java syntax is a bit foreign to me, but with the help of Xcode's autocomplete, I was able to find everything I needed.
Code:
Please take note of three specific parts:
How to create stacked data entries.
Inability to set separate borders per item in stacked bar.
How to overlap bars by providing a negative bar spacing.
I'm by no means an expert in this library, but simply reading the documentation, I was able to put this together.
// MARK: Data Entries
for (int i = 0; i < days.count; i++) {
NSNumber *guyValue = guys[i];
NSNumber *girlValue = girls[i];
// NOTE 1: To get "stacked" bars, use the initializer `initWithX:yValues:`
BarChartDataEntry *guyGirlDataEntry = [[BarChartDataEntry alloc] initWithX:i
yValues:#[guyValue, girlValue]];
NSNumber *guyCompareToValue = guysCompareTo[i];
NSNumber *girlCompareToValue = girlsCompareTo[i];
BarChartDataEntry *guyGirlCompareToEntry = [[BarChartDataEntry alloc] initWithX:i
yValues:#[guyCompareToValue, girlCompareToValue]];
[guyGirlChartDataArray addObject:guyGirlDataEntry];
[guyGirlCompareToChartDataArray addObject:guyGirlCompareToEntry];
}
// MARK: Data Sets
BarChartDataSet *guysGirlsChartDataSet = [[BarChartDataSet alloc] initWithValues:guyGirlChartDataArray label:nil];
BarChartDataSet *guysGirlsCompareToChartDataSet = [[BarChartDataSet alloc] initWithValues:guyGirlCompareToChartDataArray label:nil];
BarChartData *data = [[BarChartData alloc] initWithDataSets:#[guysGirlsCompareToChartDataSet, guysGirlsChartDataSet]];
// MARK: Styling
guysGirlsChartDataSet.stackLabels = #[#"Guys", #"Girls"];
guysGirlsChartDataSet.colors = #[[UIColor maleColor],
[UIColor femaleColor]];
// NOTE 2: Unfortunately, you can only set one border color to the bar.
// It seems, you won't be able to use separate dashed borders in the same bar, like you want.
// For demonstration purposes, I've simply made the comparison colors 50% transparent.
guysGirlsCompareToChartDataSet.stackLabels = #[#"Guys (Compare)", #"Girls (Compare)"];
guysGirlsCompareToChartDataSet.colors = #[[[UIColor maleColor] colorWithAlphaComponent:0.5],
[[UIColor femaleColor] colorWithAlphaComponent:0.5]];
// Sets the x axis label interval, so it doesn't show labels like "0.9"
barChartView.xAxis.granularity = 1;
// Centers the x axis label over the bar group, rather than on the grid line.
barChartView.xAxis.centerAxisLabelsEnabled = YES;
// MARK: Displaying Chart Data
barChartView.data = data;
// Grouping
// I still can't seem to set this properly.
// Even though I tell it to fit the bars exactly and don't show below 0 on the x axis,
// the chart still shows below zero and the right-most bar gets cut off.
// If this isn't a bug, then perhaps you can find the answer to this elsewhere.
barChartView.fitBars = YES;
[barChartView setVisibleXRangeMinimum:0];
// Calculate bar grouping parameters.
NSInteger barCountPerGroup = data.dataSetCount;
double barWidth = 0.4;
// NOTE 3: Negative bar spacing will make the bars overlap.
double barSpace = -0.3;
// According to documentation, total group width (bars and spacing) must add up to 1
double groupSpace = 1 - (barWidth + barSpace) * barCountPerGroup;
// Set the grouping parameters.
data.barWidth = barWidth;
[barChartView groupBarsFromX:0 groupSpace:groupSpace barSpace:barSpace];
// Refresh the chart (if necessary)
[barChartView notifyDataSetChanged];
Output:
The styling isn't very good, but the bars are grouped and overlap like you want.
I trust you can find help with the styling elsewhere.
Related
I have an issue with the BalloonMarker I used for my graph as it won't display the marker for all the chart elements, but only for one of them.
I used the BalloonMarker from the ChartsDemo project for a bar chart. The marker gets displayed, but only for one of the bars from the charts. I don't know if it is a coincidence or not, but it gets displayed for the bar from the middle.
I can't see what I am missing here. Is there any mistake or any other setting I can add in order to make the marker display properly?
This is the code I used to create the BallonMarker for the chart:
BalloonMarker *balloonMarker = [[BalloonMarker alloc]
initWithColor: [UIColor colorWithWhite:180/255. alpha:0.9]
font: [UIFont systemFontOfSize:10.0]
textColor: UIColor.whiteColor
insets: UIEdgeInsetsMake(8.0, 8.0, 20.0, 8.0)];
balloonMarker.chartView = barChartOrdersView;
balloonMarker.minimumSize = CGSizeMake(40.f, 20.f);
I added the marker to the chart using this code:
barChartOrdersView.drawMarkers = YES;
barChartOrdersView.marker = balloonMarker;
The properties for the bar chart are:
barChartOrdersView.gridBackgroundColor = [UIColor whiteColor];
barChartOrdersView.backgroundColor = [UIColor whiteColor];
barChartOrdersView.drawBarShadowEnabled = NO;
barChartOrdersView.drawValueAboveBarEnabled = YES;
barChartOrdersView.chartDescription.enabled = NO;
barChartOrdersView.dragEnabled = NO;
[barChartOrdersView setScaleEnabled:NO];
barChartOrdersView.pinchZoomEnabled = NO;
barChartOrdersView.rightAxis.enabled = NO;
barChartOrdersView.leftAxis.drawGridLinesEnabled = YES;
barChartOrdersView.leftAxis.drawLabelsEnabled = YES;
barChartOrdersView.leftAxis.labelFont = [UIFont systemFontOfSize:10.f];
barChartOrdersView.leftAxis.labelPosition = YAxisLabelPositionOutsideChart;
barChartOrdersView.leftAxis.spaceTop = 0.15;
barChartOrdersView.leftAxis.axisMinimum = 0.0;
barChartOrdersView.xAxis.labelPosition = XAxisLabelPositionBottom;
barChartOrdersView.xAxis.drawGridLinesEnabled = NO;
barChartOrdersView.xAxis.axisMinimum = 0.0;
barChartOrdersView.xAxis.granularity = 1.0;
barChartOrdersView.xAxis.labelFont = [UIFont systemFontOfSize:10.f];
barChartOrdersView.xAxis.drawGridLinesEnabled = NO;
barChartOrdersView.xAxis.granularity = 1.0;
barChartOrdersView.xAxis.labelCount = 7;
barChartOrdersView.xAxis.valueFormatter = [DayAxisValueFormatter new];
barChartOrdersView.legend.enabled = YES;
barChartOrdersView.legend.horizontalAlignment = ChartLegendHorizontalAlignmentLeft;
barChartOrdersView.legend.verticalAlignment = ChartLegendVerticalAlignmentBottom;
barChartOrdersView.legend.orientation = ChartLegendOrientationHorizontal;
barChartOrdersView.legend.drawInside = NO;
barChartOrdersView.legend.form = ChartLegendFormSquare;
barChartOrdersView.legend.formSize = 9.0;
barChartOrdersView.legend.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:11.f];
barChartOrdersView.legend.xEntrySpace = 4.0;
Make sure the entries you passed in is sorted by ascending order of x value.
Unordered entries could result in unexpected behavior such as dataset flashing or marker not tappable as you mentioned.
https://www.dropbox.com/s/8fqez61k9jhnoa4/Screen%20Shot%202017-06-01%20at%201.04.25%20PM.png?dl=0
(void)createBurnoutChart {
//Create the chart (if needed)
if (burnoutChart == nil) {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
burnoutChart = [[ShinobiChart alloc] initWithFrame:CGRectMake(0, 270, 768,725)]; // iPad
else
burnoutChart = [[ShinobiChart alloc] initWithFrame:CGRectMake(0, 165, 320,290)]; // iPhone
// Set a different theme on the chart
SChartMidnightTheme *midnight = [[SChartMidnightTheme alloc] init];
[burnoutChart setTheme:midnight];
//As the chart is a UIView, set its resizing mask to allow it to automatically resize when screen orientation changes.
burnoutChart.autoresizingMask = ~UIViewAutoresizingNone;
// Initialise the data source we will use for the chart
burnoutDatasource = [[LineChartDataSource alloc] initWithFileName:LineChartSource_Burnout seriesCount:1];
// Give the chart the data source
burnoutChart.datasource = burnoutDatasource;
// Create a date time axis to use as the x axis.
SChartDateTimeAxis *xAxis = [[SChartDateTimeAxis alloc] init];
// Enable panning and zooming on the x-axis.
xAxis.enableGesturePanning = YES;
xAxis.enableGestureZooming = YES;
xAxis.enableMomentumPanning = YES;
xAxis.enableMomentumZooming = YES;
xAxis.axisPositionValue = [NSNumber numberWithInt: 0];
// And allow them to scroll past the default range
xAxis.allowPanningOutOfMaxRange = YES;
xAxis.allowPanningOutOfDefaultRange = YES;
// Make the frequency of tick marks be one day
SChartDateFrequency *freq = [[SChartDateFrequency alloc] initWithDay:1];
xAxis.majorTickFrequency = freq;
burnoutChart.xAxis = xAxis;
//Create a number axis to use as the y axis.
//TODO:Checkback
NSNumber *lowRange = [[NSNumber alloc] initWithInteger:0];
NSNumber *highRange = [[NSNumber alloc] initWithInteger:100];
SChartNumberRange *yRange = [[SChartNumberRange alloc] initWithMinimum:lowRange andMaximum:highRange];
SChartNumberAxis *yAxis = [[SChartNumberAxis alloc] initWithRange:yRange ];
//Enable panning and zooming on Y
yAxis.enableGesturePanning = YES;
yAxis.enableGestureZooming = YES;
yAxis.enableMomentumPanning = YES;
yAxis.enableMomentumZooming = YES;
// yAxis.axisPositionValue = [NSNumber numberWithInt: 0];
// And allow them to scroll past the default range
yAxis.allowPanningOutOfMaxRange = NO;
yAxis.allowPanningOutOfDefaultRange = NO;
burnoutChart.yAxis.defaultRange;
burnoutChart.yAxis = yAxis;
//Set the chart title
burnoutChart.title = #"";
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
burnoutChart.titleLabel.font = [UIFont fontWithName:#"TrebuchetMS" size:27.0f];
} else {
burnoutChart.titleLabel.font = [UIFont fontWithName:#"TrebuchetMS" size:17.0f];
}
burnoutChart.titleLabel.textColor = [UIColor whiteColor];
// If you have a trial version, you need to enter your licence key here:
// chart.licenseKey = #"";
// Add the chart to the view controller
[self.viewBurnoutChart addSubview:burnoutChart];
}
// Make sure we get the latest data
NSInteger lastScore = [burnoutDatasource reReadData];
[self vasBurnoutImage:lastScore];
[self vasBurnoutScore:lastScore];
[burnoutChart reloadData];
[burnoutChart redrawChartAndGL:YES];
//***** Important for resetting visible portion..if I ever get it towork
//[burnoutChart.xAxis resetZoomLevel];
}
The chart displays well but when it comes to the yAxis it stops exactly at the 100 limit range. I want to show more intervals so that it doesn't look like it was cut off.
There are two ways you can achieve this:
If you want to manually set the range for the axis (as you do currently), then simply increase the range e.g. to 103. The tick labels should not be affected.
If you're happy to let the chart determine the range then you can use the rangePaddingHigh property to adjust how much padding is added to the calculated range.
I hope that helps!
I'm fairly new to CorePlot library. In one of our app we're drawing chart's bar graphs using CorePlot.
We also display data labels for each of the Bar graph in the chart.
I'm using labelOffset to set its position within the bar graph (i.e. labelOffset= -10.0)
However, when one of the bar graph in the chart is too small to house the data label within the bar, then I'm setting labelOffset = 10.0, so that it can appear above the bar as default.
But, I'm seeing this weird behaviour with the CPTPlot, wherein its drawing the data label twice on the bar graph. Here is a screenshot:
Here is a code snipet:
-(CPTTextLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{
plot.labelFormatter = nil;
plot. labelTextStyle = nil;
if (self.showValuesAsPlotLabels)
{
if (self.showValuesAsPlotLabels)
{
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setGeneratesDecimalNumbers:NO];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setMaximumFractionDigits:2];
[numberFormatter setMinimumFractionDigits:2];
CGFloat yValue = [self.chartData[index][1] floatValue];
//return [NSString stringWithFormat:#"%f", yValue];
NSString *labelStr = [numberFormatter stringFromNumber:#(yValue)];
/* Check to see how tall is bar chart so that we can accordingly position data label */
CGFloat yBaseOffsetValue = self.yAxisIntervalLength;
CGFloat compareValue = (yBaseOffsetValue * self.divisor);
UIColor *dataLabelColor;
float dataLabelOffset = -10.0f;
if (yValue > compareValue) {
dataLabelColor = [UIColor whiteColor];
plot.labelOffset = dataLabelOffset;
} else {
dataLabelColor = [UIColor blackColor];
plot.labelOffset = (0.0f - dataLabelOffset);
}
return [[CPTTextLayer alloc] initWithText:labelStr style:[CPTTextStyle textStyleWithAttributes:#{NSForegroundColorAttributeName: dataLabelColor}]];
}
if (self.plotLabels == nil || self.plotLabels.count < index)
{
return nil;
}
NSString *identifier = (self.plotLabels)[index];
CPTTextLayer *label = [[CPTTextLayer alloc] initWithText:identifier];
return label;
}
what am I missing or doing wrong here?
Thanks in adavance.
EDIT
After Eric's suggestion, I've tried using plot.identifier to check for plot specific yValues and then return labelOffset and textStyle of dataLabel accordingly. However, I see the following behaviour on the bar plot now:
I'm thinking that, dataLabelForPlot:recordIndex: is sort of using the same instance of CPTTextLayer? Is there a way that I can have separate instances of CPTTextLayer for each different CPTBarPlot?
Thanks
Im trying to draw a donut pie chart on ios with core-plot, with one chart inside of another. Each slice has the same width, but the slices are color coded. I'm trying to place a colored dot in the center of each slice, but I can't figure out how to get the position of the dots correct.
I've managed to get them roughly centered using the labelOffset property of the pie chart.(currently im using a label offset of -35, determined by trial and error). But I can't mange to get them exactly centered, and in the innermost graph they can end up far enough off that they are in the wrong slice.
I have tried setting the rectAnchor property of the text layer, and the padding, but neither one seems to have any effect.
Code for creating the plots:
CGFloat startAngle = [self degreesToRadians:90 + ((360 / [self.dangerRoseData numberOfSectors]) /2.0)];
NSInteger levels = [self.dangerRoseData numberOfLevels];
for(int i = 0; i < levels; i++){
CGFloat radiusD = (i + 1.0)/ levels;
CGFloat radius = MIN(radiusD * (graphHostingView.frame.size.height - 2 * graph.paddingLeft) / 2.8,
radiusD * (graphHostingView.frame.size.width - 2 * graph.paddingTop) / 2.8);
CPTPieChart *lastPie = [plots lastObject];
CGFloat innerRadius;
if(lastPie != nil)
innerRadius = lastPie.pieRadius;
else
innerRadius = 0;
CPTPieChart *piePlot = [[CPTPieChart alloc] init];
piePlot.backgroundColor = [UIColor clearColor].CGColor;
piePlot.dataSource = self;
piePlot.delegate = self;
piePlot.pieRadius = radius;
piePlot.pieInnerRadius = innerRadius;
piePlot.identifier = [self.dangerRoseData nameForLevel:i];
piePlot.borderLineStyle = lineStyle;
piePlot.startAngle = startAngle;
piePlot.sliceDirection = CPTPieDirectionClockwise;
piePlot.labelOffset = -35;//brute force trial and error
piePlot.labelRotationRelativeToRadius = NO;//new property after 1.0
[graph addPlot:piePlot];
[plots addObject:piePlot];
}
and for the labels:
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index{
....
CPTMutableTextStyle *textStyle = [[CPTMutableTextStyle alloc] init];
textStyle.color = color;
textStyle.fontSize = 36;
CPTTextLayer *label = [[CPTTextLayer alloc] initWithText:#"•" style:textStyle];
return label;
}
I Tried updating to the newest version of core-plot, which adds a new property to CPTPiePlot labelRotationRelativeToRadius which seems like it ought to be the answer to this problem, but it's not. With the new version im not able to get the dots positioned anywhere close to the correct spot.
Am I missing something with positioning the labels?
Am I using totally the wrong approach to putting the dots in the slices?
Well, I decided to give a try using images instead of text labels, and the positioning works just fine, it doesn't seem to be at all erratic like text labels.
In order to be able to fit the dots in the inner most pie I also had to change the sizes, so instead of taking up equal amounts of the total radius, the inner pie takes twice the space of the rest.
Code for generating the plots:
NSInteger levels = [self.dangerRoseData numberOfLevels];
for(int i = 0; i < levels; i++){
CPTPieChart *lastPie = [plots lastObject];
CGFloat innerRadius;
if(lastPie != nil)
innerRadius = lastPie.pieRadius;
else
innerRadius = 0;
CGFloat ringThickness;
ringThickness = ( (graphHostingView.frame.size.width - 2 * graph.paddingTop) / ((levels + 1) * 2) ) * .85;
if(i == 0)//make the inner circle twice the thickness of the rings
ringThickness += ringThickness;
CGFloat radius = innerRadius + ringThickness;
int labelOffset = -14;
if(i == 0)
labelOffset = -15;
CPTPieChart *piePlot = [[CPTPieChart alloc] init];
piePlot.backgroundColor = [UIColor clearColor].CGColor;
piePlot.dataSource = self;
piePlot.delegate = self;
piePlot.pieRadius = radius;
piePlot.pieInnerRadius = innerRadius;
piePlot.identifier = [self.dangerRoseData nameForLevel:i];
piePlot.borderLineStyle = lineStyle;
piePlot.startAngle = startAngle;
piePlot.sliceDirection = CPTPieDirectionClockwise;
piePlot.labelOffset = labelOffset;
[graph addPlot:piePlot];
[plots addObject:piePlot];
}
and for the labels:
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{
...
CPTImageLayer *layer = [[CPTImageLayer alloc] initWithImage:[UIImage imageNamed:filename]];
layer.anchorPoint = CGPointMake(0.5, 0.5);
return layer;
}
Note that the CPTImageLayer is an addition to the standard core-plot to reduce the complexity of using image
I'm having some trouble with the axis labels. It seems my custom labels aren't visible outside of the plot area. Looking at the Design Overview for core plot, the axis labels should be outside of the plot area. Any ideas on how I can make them visible outside the plot area?
The code/image below shows how the labels only show within the plot area. If I change the label offset to a positive number, the labels do not show at all. I'm using Core Plot 0.9 with iOS 5.
Thanks in advance!
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
graph = [[theme newGraph] retain];;
CPTGraphHostingView *hostingView = (CPTGraphHostingView *)self.view;
hostingView.hostedGraph = graph;
graph.paddingLeft = 40.0;
graph.paddingTop = 40.0;
graph.paddingRight = 40.0;
graph.paddingBottom = 40.0;
graph.masksToBorder = NO;
// ... setup axis
axisSet.yAxis.majorIntervalLength = CPTDecimalFromInt(0);
axisSet.yAxis.minorTicksPerInterval = 0;
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
// if this number is negative, the labels show,
// if it is positive, that is outside the plot area, the labels are hidden.
axisSet.yAxis.labelOffset = -20;
// ... setup labels
NSMutableArray *labels = [NSMutableArray array];
for (int i = 0; i < reportData.rowCount; ++i) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"Test Row %i", i] textStyle:labelStyle];
label.tickLocation = CPTDecimalFromInt(i);
label.offset = axisSet.yAxis.labelOffset;
label.alignment = CPTAlignmentLeft;
[labels addObject:label];
[label release];
}
axisSet.yAxis.axisLabels = [NSSet setWithArray:labels];
Set some padding on the plot area frame in addition to or instead of the graph itself.
graph.plotAreaFrame.paddingTop = 20.0;
graph.plotAreaFrame.paddingBottom = 50.0;
graph.plotAreaFrame.paddingLeft = 50.0;
graph.plotAreaFrame.paddingRight = 50.0;
This code is from the axis demo in the Plot Gallery example app.
I was having exactly the same problem and tried every solution I could find online for this with no success.
Finally I got it to work by turning off the border masking, like this:
graph.plotAreaFrame.masksToBorder = NO;