Hi All
Can someone help me with this problem I have encountered
Can I plot a bargraph in coreplote with unequal bar width meaning Say my X-axis interval is 1 unit and I have set the bar graph width as same 1 unit. But there are certain points where x-axis value changes at 0.5units and i want the bar width to be equal to the width where change has occurred. And the data is dynamically changing. Is there any other solution that I can use and still looks like a bar graph. The only reason for using bar is I need to fill the plot space.
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)barChart.defaultPlotSpace;
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromInt(0)
length:CPDecimalFromInt(rangeY)];
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-0.5f)
length:CPDecimalFromFloat(rangeX)];
CPXYAxisSet *axisSet = (CPXYAxisSet *)barChart.axisSet;
CPXYAxis *x = axisSet.xAxis;
x.axisLineStyle = nil;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
x.majorIntervalLength = CPDecimalFromString(#"1");
x.orthogonalCoordinateDecimal = CPDecimalFromString(#"0");
x.title = [[[tempCol colName] componentsSeparatedByString:#"*#"] objectAtIndex:0];
x.titleLocation = CPDecimalFromFloat((rangeX-1)/2);
x.titleOffset = 25.0f;
// Define some custom labels for the data elements
x.labelRotation = 0;
x.labelingPolicy = CPAxisLabelingPolicyNone;
NSMutableArray *customTickLocations = [[NSMutableArray alloc] init];
NSMutableArray *xAxisLabels = [[NSMutableArray alloc] init];
for (int i = 0; i < [tempGraph.d2pArray count]; i++) {
tempD2P = [tempGraph.d2pArray objectAtIndex:i];
[customTickLocations addObject:[NSNumber numberWithInt:i]];
[xAxisLabels addObject:[tempD2P d2pName]];
}
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[xAxisLabels count]];
for (NSNumber *tickLocation in customTickLocations) {
CPAxisLabel *newLabel = [[CPAxisLabel alloc]
initWithText:[xAxisLabels objectAtIndex:labelLocation++]
textStyle:x.labelTextStyle];
newLabel.tickLocation = [tickLocation decimalValue];
newLabel.offset = 0;
newLabel.rotation = 0;
newLabel.alignment = CPAlignmentCenter;
[customLabels addObject:newLabel];
[newLabel release];
newLabel = nil;
}
[xAxisLabels release];
xAxisLabels = nil;
[customTickLocations release];
customTickLocations = nil;
x.axisLabels = [NSSet setWithArray:customLabels];
CPXYAxis *y = axisSet.yAxis;
CPLineStyle *majorGridLineStyle = [CPLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [CPColor colorWithCGColor:[[UIColor grayColor] CGColor]];
y.axisLineStyle = nil;
y.majorTickLineStyle = nil;
y.majorGridLineStyle = majorGridLineStyle;
y.minorTickLineStyle = nil;
y.majorIntervalLength = CPDecimalFromInt(rangeY/8);
y.orthogonalCoordinateDecimal = CPDecimalFromString(#"-0.5");
y.title = [[[tempCol colName] componentsSeparatedByString:#"*#"] objectAtIndex:1];
y.titleOffset = 30 + 5*log10(mult);
y.titleLocation = CPDecimalFromInt(rangeY/2);
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:0];
y.labelFormatter = formatter;
[formatter release];
formatter = nil;
char firstChar = 'F';
CPBarPlot *barPlot;
// First bar plot
for (int i = 0; i < noOfBarCharts; i++) {
static CPTextStyle *whiteText = nil;
if ( !whiteText ) {
whiteText = [[CPTextStyle alloc] init];
whiteText.color = [CPColor whiteColor];
whiteText.fontSize = 14;
}
barPlot = [CPBarPlot tubularBarPlotWithColor:[CPColor colorWithComponentRed:[[[rgbArray objectAtIndex:0] objectAtIndex:i] floatValue]/255.0
green:[[[rgbArray objectAtIndex:1] objectAtIndex:i] floatValue]/255.0
blue:[[[rgbArray objectAtIndex:2] objectAtIndex:i] floatValue]/255.0
alpha:1.0]
horizontalBars:NO];
barPlot.baseValue = CPDecimalFromString(#"0");
barPlot.dataSource = self;
barPlot.barOffset = ([tempGraph.graType rangeOfString:#"GROUPED"].location != NSNotFound)?(i+0.5)-(noOfBarCharts/2):0;
barPlot.labelOffset = 0;
barPlot.barWidth = 20;
barPlot.identifier = [NSString stringWithFormat:#"%d%c", [tempGraph.graID intValue], (firstChar - noOfBarCharts +1 + i)];
barPlot.delegate = self;
[barChart addPlot:barPlot
toPlotSpace:plotSpace];
I figured it out myself instead of using a bar chart i used a scatter plot with step graph That did the trick :
Plot.interpolation = CPTScatterPlotInterpolationStepped;
and filled the plot with:
Plot.areaFill = [CPTFill fillWithColor:[CPTColor blueColor]];
Plot.areaBaseValue = CPTDecimalFromInteger(0);
If you're not putting a border line on the bars, you could make the bar width half the distance between bars and double-up the wide ones.
Related
Currently i'm using iosChart in my project. I have used the bar chart in shown below in image:
The problem is It is not showing(2nd and 4th) entire x - axis lable. when I zoom then showing. Is there any way to show this lable?
Here is my code:
chartView.delegate = self;
chartView.descriptionText = #"";
chartView.noDataTextDescription = GGLocalizeString(#"deshboard.ui.chart.empty");
chartView.drawBarShadowEnabled = NO;
chartView.drawValueAboveBarEnabled = YES;
chartView.maxVisibleValueCount = 60;
chartView.pinchZoomEnabled = NO;
chartView.drawGridBackgroundEnabled = NO;
ChartXAxis *xAxis = chartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.labelFont = [UIFont systemFontOfSize:10.f];
xAxis.drawGridLinesEnabled = NO;
xAxis.spaceBetweenLabels = 2.0;
ChartYAxis *leftAxis = chartView.leftAxis;
leftAxis.labelFont = [UIFont systemFontOfSize:10.f];
leftAxis.labelCount = 8;
leftAxis.valueFormatter = [[NSNumberFormatter alloc] init];
leftAxis.valueFormatter.maximumFractionDigits = 1;
leftAxis.valueFormatter.negativeSuffix = #"";
leftAxis.valueFormatter.positiveSuffix = #"";
leftAxis.labelPosition = YAxisLabelPositionOutsideChart;
leftAxis.spaceTop = 0.15;
ChartYAxis *rightAxis = chartView.rightAxis;
rightAxis.drawGridLinesEnabled = NO;
rightAxis.labelFont = [UIFont systemFontOfSize:10.f];
rightAxis.labelCount = 8;
rightAxis.valueFormatter = leftAxis.valueFormatter;
rightAxis.spaceTop = 0.15;
chartView.legend.position = ChartLegendPositionBelowChartLeft;
chartView.legend.form = ChartLegendFormSquare;
chartView.legend.formSize = 9.0;
chartView.legend.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:11.f];
chartView.legend.xEntrySpace = 4.0;
if (self.chartData.arrayCityData.count == 0) {
return cell;
}
//X - VALUE
NSMutableArray *xVals = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.chartData.arrayCityData count]; i++)
{
DealData *dealData = [self.chartData.arrayCityData objectAtIndex:i];
[xVals addObject: [NSString stringWithFormat:#"%#(%.2f%%)",dealData.name,[dealData.totalClick floatValue]*100/[self totalCityClicks]]];
}
//Y - VALUE
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.chartData.arrayCityData count]; i++)
{
DealData *dealData = [self.chartData.arrayCityData objectAtIndex:i];
[yVals addObject:[[BarChartDataEntry alloc] initWithValue:[dealData.totalClick doubleValue] xIndex:i]];
}
BarChartDataSet *set1 = [[BarChartDataSet alloc] initWithYVals:yVals label:GGLocalizeString(#"deshboard.ui.cell.lblTitle6.cities")];
set1.barSpace = 0.35;
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:dataSets];
[data setValueFont:[UIFont fontWithName:#"HelveticaNeue-Light" size:10.f]];
//remove decimal
NSNumberFormatter *vf = [[NSNumberFormatter alloc] init];
vf.generatesDecimalNumbers = NO;
data.valueFormatter = vf;
chartView.data = data;
chartView.legend.position = ChartLegendPositionBelowChartLeft;
chartView.legend.form = ChartLegendFormSquare;
chartView.legend.formSize = 9.0;
chartView.legend.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:11.f];
chartView.legend.xEntrySpace = 4.0;
if (self.chartData.arrayCityData.count == 0) {
return cell;
}
//X - VALUE
NSMutableArray *xVals = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.chartData.arrayCityData count]; i++)
{
DealData *dealData = [self.chartData.arrayCityData objectAtIndex:i];
[xVals addObject: [NSString stringWithFormat:#"%#(%.2f%%)",dealData.name,[dealData.totalClick floatValue]*100/[self totalCityClicks]]];
}
//Y - VALUE
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.chartData.arrayCityData count]; i++)
{
DealData *dealData = [self.chartData.arrayCityData objectAtIndex:i];
[yVals addObject:[[BarChartDataEntry alloc] initWithValue:[dealData.totalClick doubleValue] xIndex:i]];
}
BarChartDataSet *set1 = [[BarChartDataSet alloc] initWithYVals:yVals label:GGLocalizeString(#"deshboard.ui.cell.lblTitle6.cities")];
set1.barSpace = 0.35;
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:dataSets];
[data setValueFont:[UIFont fontWithName:#"HelveticaNeue-Light" size:10.f]];
//remove decimal
NSNumberFormatter *vf = [[NSNumberFormatter alloc] init];
vf.generatesDecimalNumbers = NO;
data.valueFormatter = vf;
chartView.data = data;
well, by default, ios-charts will calculate a modulus for x axis to decide the interval to draw the x axis labels. that's your case. because every label is longer than the bar, so to avoid the label overlap, we have to do it.
If you don't want so, just call xAxis.setLabelsToSkip(0)
If Label is overlap with each other then just add below code and see i think it's work.
[xAxis setLabelsToSkip:0];
[xAxis setWordWrapEnabled:YES];
The axis lines and tick marks for my graph don't appear when I set hostingView.collapsesLayers = NO. When I set hostingView.collapsesLayers = YES, they do appear. Any idea what might be causing this situation?
I've tried changing up the chart layer order, but no order (that I've tried) seems to make the axis lines appear. The issue also doesn't seem to be related to the background color of the hosting view or fill color of the graph, which I've tried setting to be clear for both.
The axis labels are appearing and in the correct locations.
EDIT: Grid lines and annotations are also all appearing. Everything is appearing as it should except the axis lines and tick marks.
EDIT2: Graph setup code, called in viewDidAppear
//create graph and hosting view
_graph = [[CPTXYGraph alloc] initWithFrame:_graphHostingView.frame];
_graphHostingView.hostedGraph = _graph;
_graphHostingView.collapsesLayers = NO;
//format graph
CGFloat graphPadding = 0.0f;
_graph.paddingBottom = graphPadding;
_graph.paddingLeft = graphPadding;
_graph.paddingRight = graphPadding;
_graph.paddingTop = graphPadding;
_graph.fill = [CPTFill fillWithColor:[CPTColor whiteColor]];
CGFloat plotPadding = 20.0f;
_graph.plotAreaFrame.paddingBottom = plotPadding;
_graph.plotAreaFrame.paddingLeft = plotPadding;
_graph.plotAreaFrame.paddingRight = plotPadding;
_graph.plotAreaFrame.paddingTop = plotPadding;
//configure plot spaces
_rightAxisPlotSpace = [[CPTXYPlotSpace alloc] init];
[_graph addPlotSpace:_rightAxisPlotSpace];
//init axes
_xAxis = [[CPTXYAxis alloc] init];
_xAxis.coordinate = CPTCoordinateX;
_xAxis.plotSpace = _graph.defaultPlotSpace;
_yAxisLeft = [[CPTXYAxis alloc] init];
_yAxisLeft.coordinate = CPTCoordinateY;
_yAxisLeft.plotSpace = _graph.defaultPlotSpace;
_yAxisRight = [[CPTXYAxis alloc] init];
_yAxisRight.coordinate = CPTCoordinateY;
_yAxisRight.plotSpace = _rightAxisPlotSpace;
_xAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0f];
_yAxisLeft.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0f];
_yAxisRight.axisConstraints = [CPTConstraints constraintWithUpperOffset:0.0f];
_xAxis.tickDirection = CPTSignNegative;
_yAxisLeft.tickDirection = CPTSignNegative;
_yAxisRight.tickDirection = CPTSignPositive;
CPTAxisSet* axisSet = [[CPTAxisSet alloc] init];
axisSet.axes = [NSArray arrayWithObjects:_xAxis, _yAxisLeft, _yAxisRight, nil];
_graph.axisSet = axisSet;
//format axes
CPTMutableLineStyle* axisStyle = [CPTMutableLineStyle lineStyle];
axisStyle.lineWidth = 0.75f;
axisStyle.lineColor = [CPTColor colorWithCGColor:DARK_GRAY.CGColor];
CPTMutableLineStyle* axisTickStyle = [CPTMutableLineStyle lineStyle];
axisTickStyle.lineWidth = 0.5f;
axisTickStyle.lineColor = axisStyle.lineColor;
CPTMutableLineStyle* gridStyle = [CPTMutableLineStyle lineStyle];
gridStyle.lineWidth = 0.25f;
gridStyle.lineColor = [CPTColor colorWithCGColor:LIGHT_GRAY.CGColor];
CPTMutableTextStyle* labelTextStyle = [CPTMutableTextStyle textStyle];
labelTextStyle.fontName = FONT_REGULAR;
labelTextStyle.fontSize = 8.0f;
labelTextStyle.color = [CPTColor colorWithCGColor:DARK_GRAY.CGColor];
CPTMutableTextStyle* leftAxisTitleStyle = [CPTMutableTextStyle textStyle];
leftAxisTitleStyle.fontName = FONT_HEAVY;
leftAxisTitleStyle.fontSize = 10.0f;
leftAxisTitleStyle.color = [CPTColor colorWithCGColor:BLUE.CGColor];
CPTMutableTextStyle* rightAxisTitleStyle = [CPTMutableTextStyle textStyle];
rightAxisTitleStyle.fontName = FONT_HEAVY;
rightAxisTitleStyle.fontSize = 10.0f;
rightAxisTitleStyle.color = [CPTColor colorWithCGColor:YELLOW.CGColor];
CPTTimeFormatter* calendarFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:_dateFormatter];
_xAxis.majorGridLineStyle = gridStyle;
_xAxis.labelFormatter = calendarFormatter;
NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setMinimumFractionDigits:0];
[numberFormatter setMaximumFractionDigits:2];
_yAxisLeft.majorGridLineStyle = gridStyle;
_yAxisLeft.minorGridLineStyle = gridStyle;
_yAxisLeft.titleTextStyle = leftAxisTitleStyle;
_yAxisLeft.titleOffset = 20.0f;
_yAxisLeft.labelFormatter = numberFormatter;
_yAxisRight.majorGridLineStyle = nil;
_yAxisRight.minorGridLineStyle = nil;
_yAxisRight.titleTextStyle = rightAxisTitleStyle;
_yAxisRight.titleOffset = 20.0f;
_yAxisRight.titleRotation = 3.0f*M_PI/2.0f;
_yAxisRight.labelFormatter = numberFormatter;
for(CPTXYAxis* axis in _graph.axisSet.axes)
{
axis.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
axis.preferredNumberOfMajorTicks = 7;
axis.minorTicksPerInterval = 0;
axis.majorTickLineStyle = axisTickStyle;
axis.minorTickLineStyle = axisTickStyle;
axis.axisLineStyle = axisStyle;
axis.labelTextStyle = labelTextStyle;
axis.majorTickLength = 3.0f;
axis.minorTickLength = 1.5f;
axis.labelOffset = 0.0f;
}
//set chart layer order
NSArray* chartLayers = [NSArray arrayWithObjects:[NSNumber numberWithInteger:CPTGraphLayerTypeAxisLines],
[NSNumber numberWithInteger:CPTGraphLayerTypeAxisLabels],
[NSNumber numberWithInteger:CPTGraphLayerTypePlots],
[NSNumber numberWithInteger:CPTGraphLayerTypeMajorGridLines],
[NSNumber numberWithInteger:CPTGraphLayerTypeMinorGridLines],
[NSNumber numberWithInteger:CPTGraphLayerTypeAxisTitles], nil];
_graph.topDownLayerOrder = chartLayers;
Instead of replacing the default axis set, just set your new axes array to it:
_graph.axisSet.axes = #[_xAxis, _yAxisLeft, _yAxisRight];
You are replacing a CPTXYAxisSet with a CPTAxisSet that doesn't know how to lay out and draw the x-y axes.
I'm new to mac app development. I'm drawing a bar graph using core plot frame work.
What actually i want to is, when i select a month i want to draw graph for last 6 months.when i select '12/2012' I'm able to draw the graph correctly for last 6 months. But when i select '02/2013' the graph is showing only January and February and not the previous months.
- (int)maxVal:(NSMutableArray *)arr {
NSDictionary *dict = [arr objectAtIndex:0];
NSString* dictValue = [dict objectForKey:#"X_VAL"];
int mxm = [dictValue intValue];
for (int i=0; i<[arr count]; i++) {
if ([[[arr objectAtIndex:i] objectForKey:#"X_VAL"] intValue] > mxm) {
mxm = [[[arr objectAtIndex:i] objectForKey:#"X_VAL"] intValue];
}
}
return mxm;
}
- (int)minVal:(NSMutableArray *)arr {
int mn = [[[arr objectAtIndex:0] objectForKey:#"X_VAL"] intValue];
for (int i=0; i<[arr count]; i++) {
if ([[[arr objectAtIndex:i] objectForKey:#"X_VAL"] intValue] < mn) {
mn = [[[arr objectAtIndex:i] objectForKey:#"X_VAL"] intValue];
}
}
return mn;
}
- (void)drawGraph {
if ([graphMutableArray count] > 0) {
NSRect viewRect = [aGraphView bounds];
double xAxisStart = 0, yAxisStart = 0, xAxisLength = [graphMutableArray count], yAxisLength = [[graphMutableArray valueForKeyPath:#"#max.Y_VAL"] doubleValue], tenthPartOfYAxis = (yAxisLength + (yAxisLength / 10));
NSLog(#"Y Axis Length = %f", yAxisLength);
for (int k = 0; k < xAxisLength; k++) {
NSDictionary *dict1 = [graphMutableArray objectAtIndex:k];
NSDictionary *dict2 = [dict1 objectForKey:#"X_VAL"];
NSDictionary *dict3 = [dict1 valueForKey:#"Y_VAL"];
NSLog(#"dict 2 = %# and dict 3 = %#", dict2, dict3);
}
graph = [[CPTXYGraph alloc] initWithFrame:viewRect];
[graph applyTheme:[CPTTheme themeNamed:kCPTSlateTheme]];//kCPTDarkGradientTheme]];//kCPTStocksTheme]];
aGraphView.hostedGraph = graph;
graph.plotAreaFrame.masksToBorder = NO;
graph.paddingLeft = 90.0;
graph.paddingTop = 20.0;
graph.paddingRight = 20.0;
graph.paddingBottom = 70.0;
// Add plot space for horizontal bar charts
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(xAxisStart)
length:CPTDecimalFromDouble(xAxisLength + 1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(yAxisStart)
length:CPTDecimalFromDouble(tenthPartOfYAxis)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
NSString *cptDecimalstr = [NSString stringWithFormat:#"%f", xAxisLength /[x.axisLabels count]];
x.majorIntervalLength = CPTDecimalFromString(cptDecimalstr);
x.minorTicksPerInterval = 1;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
x.axisLineStyle = nil;
x.titleLocation = CPTDecimalFromFloat(1.0f);
x.titleOffset = 55.0f;
// Define some custom labels for the data elements
x.labelRotation = M_PI/4;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
NSLog(#"Max = %d and Min = %d", [self maxVal:graphMutableArray], [self minVal:graphMutableArray]);
NSMutableArray *tempCustomTickLocations = [NSMutableArray arrayWithObjects:[NSNumber numberWithFloat:0.5],[NSNumber numberWithFloat:1.7],[NSNumber numberWithFloat:3.0],[NSNumber numberWithFloat:4.1],[NSNumber numberWithFloat:5.3],[NSNumber numberWithFloat:6.5],[NSNumber numberWithFloat:6.9],[NSNumber numberWithFloat:7.1],[NSNumber numberWithFloat:7.5],[NSNumber numberWithFloat:8.1],[NSNumber numberWithFloat:8.5],[NSNumber numberWithFloat:8.9],nil];
NSMutableArray *tempMonthsArr = [NSMutableArray arrayWithObjects:#"",#"January", #"February", #"March", #"April", #"May", #"June", #"July", #"August", #"September", #"October", #"November", #"December", nil];
NSMutableArray *tempMonthsMutArr
= [[[NSMutableArray alloc] initWithCapacity:[graphMutableArray count]] autorelease], *tempMutCustomTickLocations
= [[[NSMutableArray alloc] initWithCapacity:[graphMutableArray count]] autorelease];
int k = 0;
for (int l = [self minVal:graphMutableArray]; l <=[self maxVal:graphMutableArray]; l++) {
NSString *tempMonth = [tempMonthsArr objectAtIndex:l];
[tempMonthsMutArr addObject:tempMonth];
[tempMutCustomTickLocations addObject:[tempCustomTickLocations objectAtIndex:k]];
k = k + 1;
NSLog(#"tempMutCustomTickLocations= %#",tempMutCustomTickLocations);
}
if ([self minVal:graphMutableArray] == [self maxVal:graphMutableArray]) {
NSString *tempMonth = [tempMonthsArr objectAtIndex:[self minVal:graphMutableArray]];
[tempMonthsMutArr addObject:tempMonth];
[tempMutCustomTickLocations addObject:[tempCustomTickLocations objectAtIndex:0]];
}
NSMutableArray *customTickLocations = [NSMutableArray arrayWithArray:tempMutCustomTickLocations];
NSArray *xAxisLabels = [NSArray arrayWithArray:tempMonthsMutArr];
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[graphMutableArray count]];
for (NSNumber *tickLocation in customTickLocations) {
//NSLog(#"tickLocation==%d",tickLocation.intValue);
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText: [xAxisLabels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
newLabel.tickLocation = [tickLocation decimalValue];//[tickLocation decimalValue];
newLabel.offset = x.labelOffset + x.majorTickLength;
// NSLog(#"[tickLocation floatValue] = %f", [tickLocation floatValue]);
newLabel.offset = x.labelOffset + x.majorTickLength;
//NSLog(#"x.labelOffset = %f, x.majorTickLength = %f and newLabel.offset = %f", x.labelOffset, x.majorTickLength, newLabel.offset);
newLabel.rotation = M_PI/4;
//NSLog(#"-=-=-=--=-=-=- %f",x.labelOffset);
//NSLog(#"%f", x.majorTickLength );
[customLabels addObject:newLabel];
//NSLog(#"%#",customLabels);
[newLabel release];
}
x.axisLabels = [NSSet setWithArray:customLabels];
NSLog(#"%#",x.axisLabels);
CPTXYAxis *y = axisSet.yAxis;
y.axisLineStyle = nil;
y.majorTickLineStyle = nil;
y.minorTickLineStyle = nil;
NSString *cptDecimalStr = [NSString stringWithFormat:#"%f", yAxisLength / 10];
y.majorIntervalLength = CPTDecimalFromString(cptDecimalStr);
//y.constantCoordinateValue = CPTDecimalFromString(#"0");
// y.title = #"Y Axis";
y.titleOffset = 45.0f;
y.titleLocation = CPTDecimalFromFloat(150.0f);
//CPTPieChart
CPTBarPlot *plot = [[CPTBarPlot alloc] initWithFrame:CGRectZero];
plot.plotRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0)
length:CPTDecimalFromDouble(xAxisLength)];
plot.barOffset = [[NSDecimalNumber decimalNumberWithString:#"0.50"]
decimalValue]; //CPTDecimalFromDouble(0.50f);
plot.fill = [CPTFill fillWithColor:[CPTColor lightGrayColor]];
plot.dataSource = self;
[graph addPlot:plot ];//toPlotSpace:plotSpace];
}
else {
aGraphView.hostedGraph = nil;
[[NSAlert alertWithMessageText:#"No Data Found" defaultButton:#"Ok" alternateButton:nil otherButton:nil informativeTextWithFormat:#""] runModal];
}
}
Can Anyone Help me to solve the problem!!!
You need to update the xRange of the plot space. This will move the axis labels to the correct position and draw data points in the new range. You'll also need to add the new data points to the plot.
I have been playing with Core Plot and trying to create a dynamic date x-axis. From the date plot example I have managed to create a static date axis, but would like to create a two-minute window at any time and update the xRange values. I am not sure on how to pass dates as the xRange min and length values and display time on the x-axis.
I have looked at examples, but I haven't been able to utilize NSTimeInterval (if this is how to do it...).
Below is the picture (if it helps)
Below is my attempt so far; can someone please advise me on how to achieve this?
- (void)loadView {
// Alloc & Init Main View and since the display resolution is 1024x768 take 20 off for labels later
UIView *tmpView = [ [ UIView alloc ] initWithFrame:CGRectMake(0, 0, 1024.0,768.0) ];
[ tmpView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight ];
[ tmpView setBackgroundColor:[ UIColor redColor ] ];
// Alloc Graph View
graphView = [ [ CPGraphHostingView alloc ] initWithFrame:CGRectMake(0, 0, 1024.0,768.0) ];
[ tmpView addSubview:[ graphView autorelease ] ];
// Set MainView
[ self setView:[ tmpView autorelease ] ];
}
-(void)viewDidLoad{
[super viewDidLoad];
NSDate *refDate = [NSDate date];
// NSTimeInterval oneDay = 24 * 60 * 60;
NSTimeInterval oneHour = 60 * 60;
NSTimeInterval fivemin= 5 * 60;
// Create graph from theme
graph = [(CPXYGraph *) [CPXYGraph alloc] initWithFrame:self.view.bounds];
CPTheme *theme = [CPTheme themeNamed:kCPDarkGradientTheme];
[graph applyTheme:theme];
graphView.hostedGraph = graph;
//padding
graph.paddingLeft = 20.0;
graph.paddingTop = 20.0;
graph.paddingRight = 20.0;
graph.paddingBottom = 20.0;
graph.plotAreaFrame.paddingTop=10.0;
graph.plotAreaFrame.paddingLeft=50.0;
graph.plotAreaFrame.paddingRight=35.0;
graph.plotAreaFrame.paddingBottom=50.0;
// Setup scatter plot space
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
NSTimeInterval xLow = 0.0f;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(xLow) length:CPDecimalFromFloat(oneHour)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0f) length:CPDecimalFromFloat(100.0f)];
//Line Styles
CPLineStyle *lineStyle = [CPLineStyle lineStyle];
lineStyle.lineColor = [CPColor redColor];
lineStyle.lineWidth = 2.0f;
CPLineStyle *majorGridLineStyle = [CPLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [[CPColor colorWithGenericGray:0.2] colorWithAlphaComponent:0.75];
CPLineStyle *minorGridLineStyle = [CPLineStyle lineStyle];
minorGridLineStyle.lineWidth = 0.25;
minorGridLineStyle.lineColor = [[CPColor whiteColor] colorWithAlphaComponent:0.1];
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
// X-Axes formatting
CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromFloat(oneHour);
x.orthogonalCoordinateDecimal = CPDecimalFromString(#"0");
x.minorTicksPerInterval = 0;
x.labelOffset=0;
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateStyle = kCFDateFormatterShortStyle;
CPTimeFormatter *timeFormatter = [[[CPTimeFormatter alloc] initWithDateFormatter:dateFormatter] autorelease];
timeFormatter.referenceDate = refDate;
x.labelFormatter = timeFormatter;
x.majorGridLineStyle = majorGridLineStyle;
x.minorGridLineStyle = minorGridLineStyle;
x.title=#"Time Axis";
//Y-Axes formatting
CPXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = [ [ NSDecimalNumber decimalNumberWithString:#"10.0" ] decimalValue ];
y.orthogonalCoordinateDecimal = CPDecimalFromString(#"0");
y.minorTicksPerInterval = 5;
y.labelOffset = 0.0;
y.majorGridLineStyle = majorGridLineStyle;
y.minorGridLineStyle = minorGridLineStyle;
y.preferredNumberOfMajorTicks = 10;
y.minorTickLineStyle = nil;
y.labelTextStyle = nil;
y.visibleRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0f) length:CPDecimalFromFloat(100.0f)];
CPConstraints yConstraints = {CPConstraintFixed, CPConstraintFixed};
y.isFloatingAxis=YES;
y.constraints=yConstraints;
// Create a plot that uses the data source method
CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
dataSourceLinePlot.identifier = #"Date Plot";
dataSourceLinePlot.dataLineStyle = lineStyle;
dataSourceLinePlot.dataSource = self;
[graph addPlot:dataSourceLinePlot];
mydata = [[NSMutableArray alloc]initWithObjects:
[NSDecimalNumber numberWithInt:0],
nil ];
//a timer to re-load the graph every 2 seconds and re-draw x-axis
Timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(testingTimer:) userInfo:nil repeats:YES];
}
-(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot
{
return mydata.count;
}
-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
switch ( fieldEnum ) {
case CPScatterPlotFieldX:
return (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:index];
case CPScatterPlotFieldY:
return [mydata objectAtIndex:index];
}
return nil;
}
-(void) testingTimer: (NSTimer *) Timer{
//generating random number and add to mydata array
testdata=arc4random() % 100;
[mydata addObject:[NSNumber numberWithInt:testdata]];
[graph reloadData];
count++;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(count) length:CPDecimalFromFloat(5*30.0f)];
}
the location for the xRange is where you want the plot to start, for example if you had 5 minutes(assuming 1 entry per second) of data loaded for the plot and you wanted to start at minute 3 your location would be 3*60. your length would always be 2*60 if you only want to show 2 minutes of data.
you probably want to change x.majorIntervalLength as well, that value controls how often a major tick is placed along the x axis. your major tick usually has a label associated with it, so you'd want to lower that value to something more appropriate for only 2 minutes of data
I'm using core plot in an application and from past one week I am trying to show labels on x-axis and y-axis. But haven't succeed yet. I'm posting my code here with screen shot. If someone knows any solution to fix the problem let me know urgently.
Code -
-(void)viewDidLoad {
[super viewDidLoad];
// Initialize all graph dependent data.
//self.dataForPlot = [[NSMutableArray alloc] initWithCapacity:0];
minYValues = [[NSMutableArray alloc] initWithCapacity:0];
maxYValues = [[NSMutableArray alloc] initWithCapacity:0];
[self createGraph];
[self customizeGraph];
}
- (void) createGraph{
// Create graph
graph = [[CPXYGraph alloc] initWithFrame:CGRectZero];
CPGraphHostingView *hostingView = (CPGraphHostingView *)self.view;
hostingView.collapsesLayers = YES;
hostingView.hostedGraph = graph;
hostingView.frame = self.view.frame;
//Create a blue plot area
CPScatterPlot *boundLinePlot = [[[CPScatterPlot alloc] init] autorelease];
boundLinePlot.dataLineStyle.miterLimit = 1.0f;
boundLinePlot.dataLineStyle.lineWidth = 1.0f;
UIColor* color = [UIColor orangeColor];
boundLinePlot.dataLineStyle.lineColor = [CPColor colorWithCGColor:[color CGColor]];
boundLinePlot.dataSource = self;
[graph addPlot:boundLinePlot];
}
- (void) customizeGraph{
if(graph)
{
graph.paddingLeft = 20.0;
graph.paddingTop = 20.0;
graph.paddingRight = 20.0;
graph.paddingBottom = 20.0;
CPScatterPlot *goalWeightPlot = [[[CPScatterPlot alloc] init] autorelease];
goalWeightPlot.identifier = kGoalWeightPlot;
//boundLinePlot.dataLineStyle.miterLimit = 5.0f;
goalWeightPlot.dataLineStyle.lineWidth = 1.0f;
goalWeightPlot.dataLineStyle.lineColor = [CPColor redColor];
goalWeightPlot.dataLineStyle.dashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:5.0],[NSNumber numberWithFloat:2.0],nil];
goalWeightPlot.dataSource = self;
[graph addPlot:goalWeightPlot];
// Create a blue plot area
CPScatterPlot *boundLinePlot = [[[CPScatterPlot alloc] init] autorelease];
boundLinePlot.identifier = kActualWeightPlot;
//boundLinePlot.dataLineStyle.miterLimit = 5.0f;
boundLinePlot.dataLineStyle.lineWidth = 1.0f;
boundLinePlot.dataLineStyle.lineColor = [CPColor orangeColor];
boundLinePlot.dataSource = self;
// Add plot symbols
CPLineStyle *symbolLineStyle = [CPLineStyle lineStyle];
symbolLineStyle.lineColor = [CPColor orangeColor];
CPPlotSymbol *plotSymbol = [CPPlotSymbol ellipsePlotSymbol];
plotSymbol.fill = [CPFill fillWithColor:[CPColor orangeColor]];
plotSymbol.lineStyle = symbolLineStyle;
plotSymbol.size = CGSizeMake(5.0, 5.0);
boundLinePlot.plotSymbol = plotSymbol;
[graph addPlot:boundLinePlot];
}
}
- (void) resetData{
dataForPlot = nil;
}
- (void) setGraphData:(NSArray*)graphData andRefrenceValue:(float)goalValue{
self.refereceValue = goalValue;
[self setGraphData:graphData];
}
- (void) setGraphData:(NSArray*)graphData{
//Check if we have any single weight entry in the array
if(graphData && [graphData count] > 0) {
[self prepareGraphData:graphData];
[self setRangeForGraph];
[graph reloadData];
}
}
- (NSArray *)sortedWeightEntriesByWeightDate:(NSArray *)unsortedArray {
NSMutableArray *tempArray = [NSMutableArray array];
for(int i=0;i<[unsortedArray count];i++) {
NSDateFormatter *df = [[NSDateFormatter alloc]init];
WeightEntry *entry = [unsortedArray objectAtIndex:i];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [df dateFromString:entry.weightDate];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
if(date) {
[dict setObject:entry forKey:#"entity"];
[dict setObject:date forKey:#"date"];
[tempArray addObject:dict];
}
[df release];
}
NSInteger counter = [tempArray count];
NSDate *compareDate;
NSInteger index;
for(int i = 0 ; i < counter; i++) {
index = i;
compareDate = [[tempArray objectAtIndex:i] valueForKey:#"date"];
NSDate *compareDateSecond;
for(int j = i+1 ; j < counter; j++)
{
compareDateSecond=[[tempArray objectAtIndex:j] valueForKey:#"date"];
NSComparisonResult result = [compareDate compare:compareDateSecond];
if(result == NSOrderedDescending)
{
compareDate = compareDateSecond;
index=j;
}
}
if(i!=index)
[tempArray exchangeObjectAtIndex:i withObjectAtIndex:index];
}
NSMutableArray *sortedArray = [NSMutableArray arrayWithCapacity:0];
NSInteger counterIndex = [tempArray count];
for(int i = 0; i < counterIndex ; i++) {
[sortedArray addObject:[[tempArray objectAtIndex:i] valueForKey:#"entity"]];
}
return [NSArray arrayWithArray:sortedArray];
}
- (void) prepareGraphData:(NSArray*)data{
data = [self sortedWeightEntriesByWeightDate:data];
NSNumber* minYValue = nil;
NSNumber* maxYValue = nil;
NSMutableArray *contentArray = [NSMutableArray arrayWithCapacity:[data count]];
NSUInteger i;
for ( i = 0; i < [data count]; i++ ) {
WeightEntry* weightEntry = [data objectAtIndex:i];
if(i == 0){
maxYValue = [NSNumber numberWithFloat:weightEntry.weight];
minYValue = [NSNumber numberWithFloat:weightEntry.weight];
}
//id x = [NSNumber numberWithFloat:weightEntry.weight];
//id y = [NSNumber numberWithFloat:1.2*rand()/(float)RAND_MAX + 1.2];
id x = [NSNumber numberWithFloat:i];
id y = [NSNumber numberWithFloat:weightEntry.weight];
if([y floatValue] > [maxYValue floatValue])
maxYValue = y;
if([y floatValue] < [minYValue floatValue])
minYValue = y;
//[contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, #"x", y, #"y",[NSNumber numberWithFloat:goalWeight],#"goalY",nil]];
[contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, #"x", y, #"y",nil]];
}
self.dataForPlot = [NSArray arrayWithArray:contentArray];
[minYValues addObject:minYValue];
[maxYValues addObject:maxYValue];
lblHighValue.text = [NSString stringWithFormat:#"High = %0.2f", [maxYValue floatValue]];
lblLowValue.text = [NSString stringWithFormat:#"Low = %0.2f", [minYValue floatValue]];
lblRefrenceValue.text = [NSString stringWithFormat:#"Goal = %0.2f", self.refereceValue];
}
// Update the Plot Space Range to cover all graphs
- (void) setRangeForGraph{
NSNumber* minimumYValue;
NSNumber* maxmumYValue;
if([minYValues count] > 0 && [maxYValues count] > 0){
minimumYValue = [minYValues objectAtIndex:0];
maxmumYValue = [maxYValues objectAtIndex:0];
// Calculate minimum y value among all graphs.
for (int i = 0 ; i < [minYValues count] ; i++) {
if([[minYValues objectAtIndex:i] floatValue] < [minimumYValue floatValue])
minimumYValue = [minYValues objectAtIndex:i];
}
// Calculate maximum y value among all graphs.
for (int i = 0 ; i < [maxYValues count] ; i++) {
if([[maxYValues objectAtIndex:i] floatValue] > [maxmumYValue floatValue])
maxmumYValue = [maxYValues objectAtIndex:i];
}
NSDecimalNumber *high = [NSDecimalNumber decimalNumberWithDecimal:[maxmumYValue decimalValue]];
high = [high decimalNumberByAdding:[NSDecimalNumber decimalNumberWithString:#"30"]];
// Modify the y range for plot space to cover all values.
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:[high decimalValue]];
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:CPDecimalFromInt([self.dataForPlot count])];
CPPlotAreaFrame *area = (CPPlotAreaFrame *)graph.plotAreaFrame;
area.paddingLeft = 20;
area.paddingBottom = 10;
CPXYAxisSet *axisSet = (CPXYAxisSet*)graph.axisSet;
//axis.paddingLeft = 20.0;
axisSet.xAxis.paddingBottom = 50.0;
CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromInteger([self.dataForPlot count]);
CPXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPDecimalFromFloat([high floatValue]);
axisSet.xAxis.orthogonalCoordinateDecimal = CPDecimalFromFloat([minimumYValue floatValue]);
//axisSet.xAxis.labelOffset = 0.0;
CPLineStyle *lineStyle = [CPLineStyle lineStyle];
lineStyle.lineColor = [CPColor colorWithCGColor:((UIColor*)kProtienColor).CGColor];
lineStyle.lineWidth = 1.0f;
// style the graph with white text and lines
CPTextStyle *whiteText = [CPTextStyle textStyle];
whiteText.color = [CPColor redColor];
//CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromString(#"1");
x.axisLineStyle = lineStyle;
//x.majorGridLineStyle=lineStyle;
//x.minorTicksPerInterval = 0;
//x.minorTickLineStyle = lineStyle;
x.title = #"Weight";
x.titleOffset = 3.0f;
x.titleLocation = CPDecimalFromFloat(3.0f);
x.titleTextStyle = whiteText;
x.labelTextStyle = whiteText;
//y.majorIntervalLength = CPDecimalFromString(#"150");
//y.minorTicksPerInterval = 10;
y.axisLineStyle = lineStyle;
y.title = #"Date";
y.titleTextStyle = whiteText;
y.titleOffset = 0;
y.minorTickLineStyle = lineStyle;
//y.titleLocation = CPDecimalFromFloat(graph.frame.origin.y+10);
//y.majorGridLineStyle=lineStyle;
//y.labelTextStyle=whiteText;
}
}
- (NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot {
int nofOfRecords = 0;
#try {
nofOfRecords = [self.dataForPlot count];
}
#catch (NSException * e) {
NSLog(#"Exception while calculating graph index : %#", [e description]);
}
#finally {
//NSLog(#"Number of Records : %d For Graph Index : %d", nofOfRecords, graphIndex);
return nofOfRecords;
}
}
- (NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSNumber *num = 0;
//int plotIndex = [(NSString *)plot.identifier intValue];
if([self.dataForPlot count] > 0){
if(![((NSString*)[plot identifier]) isEqualToString:kGoalWeightPlot]){
num = [[dataForPlot objectAtIndex:index] valueForKey:(fieldEnum == CPScatterPlotFieldX ? #"x" : #"y")];
}else {
if(fieldEnum == CPScatterPlotFieldX)
num = [[dataForPlot objectAtIndex:index] valueForKey:#"x"];
else {
num = [NSNumber numberWithFloat:self.refereceValue];
}
}
}
return num;
}
Screenshot -
I want to show custom labels on x-axis and default labels on y-axis.
EDIT:
I've tried adding sample class of barChart+XIB from CPTest-iPhoneApp. The bar chart appears but axis label's don't. Here is the screenshot form CPTest-iPhone app and mine.
CPXYAxis *yy = axisSet.yAxis;
yy.axisLineStyle.lineColor=[CPColor whiteColor];
yy.majorTickLineStyle = nil;
yy.minorTickLineStyle = nil;
yy.title = #"Y Axis";
yy.titleLocation = CPDecimalFromFloat(100.0f);
yy.titleOffset = 245.0f;
// Define some custom labels for the data elements
yy.labelingPolicy = CPAxisLabelingPolicyNone;
NSArray *customTickLocations1 = [NSArray arrayWithObjects:[NSDecimalNumber numberWithInt:0], [NSDecimalNumber numberWithInt:10],[NSDecimalNumber numberWithInt:20], [NSDecimalNumber numberWithInt:30], nil];
NSArray *yAxisLabels = [NSArray arrayWithObjects:#"a",#"b", #"c",nil];
NSUInteger labelLocation1 = 0;
NSMutableArray *customLabels1 = [NSMutableArray arrayWithCapacity:[yAxisLabels count]];
for (NSNumber *tickLocation1 in customTickLocations1)
{
CPAxisLabel *newLabel1 = [[CPAxisLabel alloc]
initWithText: [yAxisLabels objectAtIndex:labelLocation1++]
textStyle:yy.labelTextStyle];
newLabel1.tickLocation = [tickLocation1 decimalValue];
newLabel1.offset = yy.labelOffset + yy.majorTickLength;
[customLabels1 addObject:newLabel1];
[newLabel1 release];
}
yy.axisLabels = [NSSet setWithArray:customLabels1];
I have resolved my problem. All I have to do is start adding core-plot from beginning. I removed core-plot from my project again add voila! it's working