I am using the Charts framework (danielgindi/Charts). My line chart is showing duplicated labels on x-axis, if is there is only one value available on my labels array(xAxisLabels in this case). See image below.
how can I ensure that the labels won't be duplicated? So if there is only one entry available on the labels array then it should display only one label on the left most side. other labels would be blank, which will be gradually filled upon availability on the labels array.
Here is the code that I have tried so far. Thank you very much for your help.
#property (nonatomic) LineChartView* chartView;
#property (strong, nonatomic) NSArray<NSString *> *xAxisLabels;
- (void)configureChartViewIfNeeded {
self.chartView.drawGridBackgroundEnabled = NO;
self.chartView.legend.enabled = NO;
self.chartView.minOffset = 28;
self.chartView.xAxis.enabled = YES;
self.chartView.xAxis.labelPosition = XAxisLabelPositionBottom;
self.chartView.xAxis.labelTextColor = [UIColor colorWithWhite:1 alpha:0.79];
self.chartView.xAxis.gridColor = [UIColor colorWithWhite:1 alpha:0.79];
self.chartView.xAxis.drawAxisLineEnabled = NO;
self.chartView.xAxis.drawGridLinesEnabled = NO;
self.chartView.leftAxis.labelTextColor = [UIColor colorWithWhite:1 alpha:0.79];
self.chartView.leftAxis.gridColor = [UIColor colorWithWhite:1 alpha:0.3];
self.chartView.leftAxis.gridLineWidth = 1.0f;
self.chartView.leftAxis.drawZeroLineEnabled = NO;
self.chartView.leftAxis.drawAxisLineEnabled = NO;
[self.chartView.leftAxis setLabelCount:leftAxisLabelCount force:NO];
self.chartView.leftAxis.drawTopYLabelEntryEnabled = YES;
self.chartView.leftAxis.axisMinimum = 0;
JVNImpactMetricsFormatter *numberFormatter = [[JVNImpactMetricsFormatter alloc] init]; //My custom formatter
[numberFormatter setUsesGroupingSeparator:YES];
[numberFormatter setGroupingSeparator:#","];
[numberFormatter setGroupingSize:3];
numberFormatter.maximumFractionDigits = 1;
self.chartView.xAxis.valueFormatter = numberFormatter; //Will present integer values
self.chartView.rightAxis.enabled = NO;
self.chartView.dragEnabled = NO;
self.chartView.scaleXEnabled = self.chartView.scaleYEnabled = NO;
self.chartView.drawBordersEnabled = NO;
self.chartView.doubleTapToZoomEnabled = NO;
self.chartView.delegate = self;
self.chartView.descriptionText = #"";
[self.chartView animateWithXAxisDuration:0.3 yAxisDuration:0.3];
}
#pragma mark - IChartAxisValueFormatter
- (NSString * _Nonnull)stringForValue:(double)value axis:(ChartAxisBase * _Nullable)axis {
return self.xAxisLabels[[#(value) intValue]];
}
Try using :
self.chartView.xAxis.granularityEnabled = true
Related
I have a application, that can display charts with data using iOS Charts library v.2.3. Now I must enable the option to track touching points of data on the chart. I do some research and I know, that I must use the chartValueSelected method in class, that implements . I also declare chartView.delegate to self and connect outlet in view on the storyboard. But when I tested it, I always get a signal from the chartValueNothingSelected method, with none from chartValueSelected. It is something, that I should put in my code, that enables tracking touch on points in my application?
Edit: code
#interface ChartViewController () <ChartViewDelegate>
#end
#implementation ChartViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.chartView.delegate = self;
_chartView.dragEnabled = YES;
[_chartView setScaleEnabled:YES];
_chartView.pinchZoomEnabled = YES;
_chartView.drawGridBackgroundEnabled = NO;
// some random data generator
// x-axis limit line
ChartLimitLine *llXAxis = [[ChartLimitLine alloc] initWithLimit:10.0 label:#"Index 10"];
llXAxis.lineWidth = 4.0;
llXAxis.lineDashLengths = #[#(10.f), #(10.f), #(0.f)];
llXAxis.labelPosition = ChartLimitLabelPositionRightBottom;
llXAxis.valueFont = [UIFont systemFontOfSize:10.f];
//[_chartView.xAxis addLimitLine:llXAxis];
_chartView.xAxis.gridLineDashLengths = #[#10.0, #10.0];
_chartView.xAxis.gridLineDashPhase = 0.f;
ChartLimitLine *ll1 = [[ChartLimitLine alloc] initWithLimit:150.0 label:#"Upper Limit"];
ll1.lineWidth = 4.0;
ll1.lineDashLengths = #[#5.f, #5.f];
ll1.labelPosition = ChartLimitLabelPositionRightTop;
ll1.valueFont = [UIFont systemFontOfSize:10.0];
ChartLimitLine *ll2 = [[ChartLimitLine alloc] initWithLimit:-30.0 label:#"Lower Limit"];
ll2.lineWidth = 4.0;
ll2.lineDashLengths = #[#5.f, #5.f];
ll2.labelPosition = ChartLimitLabelPositionRightBottom;
ll2.valueFont = [UIFont systemFontOfSize:10.0];
ChartYAxis *leftAxis = _chartView.leftAxis;
[leftAxis removeAllLimitLines];
[leftAxis addLimitLine:ll1];
[leftAxis addLimitLine:ll2];
leftAxis.gridLineDashLengths = #[#5.f, #5.f];
leftAxis.drawZeroLineEnabled = NO;
leftAxis.drawLimitLinesBehindDataEnabled = YES;
_chartView.rightAxis.enabled = NO;
//[_chartView.viewPortHandler setMaximumScaleY: 2.f];
//[_chartView.viewPortHandler setMaximumScaleX: 2.f];
//_chartView.marker = marker;
_chartView.legend.form = ChartLegendFormLine;
[_chartView animateWithXAxisDuration:2.5];
NSMutableArray *xVals = [[NSMutableArray alloc] init];
for (int i = 0; i < 100; i++)
{
[xVals addObject:[#(i) stringValue]];
}
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < 100; i++)
{
double mult = (1000 + 1);
double val = (double) (arc4random_uniform(mult)) + 3;
[yVals addObject:[[ChartDataEntry alloc] initWithValue:val xIndex:i]];
}
LineChartDataSet *set1 = nil;
if (_chartView.data.dataSetCount > 0)
{
set1 = (LineChartDataSet *)_chartView.data.dataSets[0];
set1.yVals = yVals;
_chartView.data.xValsObjc = xVals;
[_chartView.data notifyDataChanged];
[_chartView notifyDataSetChanged];
}
else
{
set1 = [[LineChartDataSet alloc] initWithYVals:yVals label:#"DataSet 1"];
set1.lineDashLengths = #[#5.f, #2.5f];
set1.highlightLineDashLengths = #[#5.f, #2.5f];
[set1 setColor:UIColor.blackColor];
[set1 setCircleColor:UIColor.blackColor];
set1.lineWidth = 1.0;
set1.circleRadius = 3.0;
set1.drawCircleHoleEnabled = NO;
set1.valueFont = [UIFont systemFontOfSize:9.f];
//set1.fillAlpha = 65/255.0;
//set1.fillColor = UIColor.blackColor;
NSArray *gradientColors = #[
(id)[ChartColorTemplates colorFromString:#"#00ff0000"].CGColor,
(id)[ChartColorTemplates colorFromString:#"#ffff0000"].CGColor
];
CGGradientRef gradient = CGGradientCreateWithColors(nil, (CFArrayRef)gradientColors, nil);
set1.fillAlpha = 1.f;
set1.fill = [ChartFill fillWithLinearGradient:gradient angle:90.f];
set1.drawFilledEnabled = YES;
CGGradientRelease(gradient);
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
LineChartData *data = [[LineChartData alloc] initWithXVals:xVals dataSets:dataSets];
_chartView.data = data;
}
}
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(#"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(#"chartValueNothingSelected");
}
#end
and from .h file
#import <UIKit/UIKit.h>
#import Charts;
#interface ChartViewController : UIViewController
#property(nonatomic, strong) IBOutlet LineChartView* chartView;
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *chartViewHeightConstraint;
#end
For everyone, who will occurr similar problem to mine. I resolve my problem, cleaning everything, that can be left of old version 2.3 of Charts using CocoaPods tools and later add reference to new 3.0 version. For me, it enabled option to show actually clicked point.
I had an iPhone application in which i have to calculate the values for x axis and y axis with some intervals as xaxis array and Yaxis array
I had fixed values.
Then i need to draw 3 line graph with their on x values and Y
values.then i need to plot scatter points on that graph itself with
different (x,y) coordinates.
I am using IOs charts library.But when giving different x values to
the line graph the X axis values are also changing, I am trying in
this way
` chartview.descriptionText = #"";
chartview.noDataTextDescription = #"You need to provide data for the chart.";
chartview.drawGridBackgroundEnabled = NO;
chartview.drawBarShadowEnabled = NO;
chartview.highlightFullBarEnabled = NO;
chartview.rightAxis.enabled=NO;
chartview.drawOrder = #[#(CombinedChartDrawOrderLine),
#(CombinedChartDrawOrderScatter),
];
ChartLegend *l = chartview.legend;
l.enabled = false;
//chartview.xAxisRenderer
ChartYAxis *leftAxis = chartview.leftAxis;
leftAxis.axisLineWidth=2.0f;
leftAxis.axisLineColor =[UIColor whiteColor];
leftAxis.drawGridLinesEnabled = YES;
leftAxis.gridColor=[UIColor whiteColor];
leftAxis.gridLineDashLengths = #[#5.f, #5.f];
NSLog(#"%#",yaxispoints);
NSLog(#"%f",[[yaxispoints firstObject] floatValue]);
NSLog(#"%f",[[yaxispoints lastObject] floatValue]);
leftAxis.axisMinimum = [[yaxispoints firstObject] floatValue]; // this replaces startAtZero = YES
leftAxis.axisMaximum = [[yaxispoints lastObject] floatValue];
leftAxis.labelCount = [yaxispoints count];
leftAxis.spaceTop = 40.0;
leftAxis.labelTextColor=[UIColor whiteColor];
ChartXAxis *xAxis = chartview.xAxis;
[xAxis setDrawAxisLineEnabled:YES];
xAxis.axisLineWidth=2.0f;
xAxis.granularityEnabled=YES;
xAxis.axisLineColor =[UIColor whiteColor];
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.axisMinimum = [[months firstObject] floatValue]; // this replaces startAtZero = YES
xAxis.axisMaximum = [[months lastObject] floatValue];
xAxis.labelCount = [months count];
xAxis.forceLabelsEnabled=YES;
xAxis.drawGridLinesEnabled = YES;
xAxis.gridColor=[UIColor whiteColor];
xAxis.gridLineDashLengths = #[#5.f, #5.f];
xAxis.valueFormatter = self;
xAxis.labelTextColor=[UIColor whiteColor];
[self updateChartData];
[chartview animateWithXAxisDuration:1.5 yAxisDuration:1.5];`
- (void)updateChartData
{
[self setChartData];
}
- (void)setChartData
{
CombinedChartData *data = [[CombinedChartData alloc] init];
data.lineData = [self generateLineData];
data.scatterData = [self generateScatterData];
chartview.xAxis.axisMaximum = data.xMax + 5.0;
chartview.data = data;
}
- (LineChartData *)generateLineData
{
LineChartData *d = [[LineChartData alloc] init];
NSMutableArray *entries = [[NSMutableArray alloc] init];
NSArray *scxaxis = #[#"55.987", #"75.976", #"85.976"
];
NSArray *scyaxis = #[#"85.987", #"25.976", #"95.976"
];
for (int index = 0; index < [scxaxis count]; index++)
{
[entries addObject:[[ChartDataEntry alloc] initWithX:[[scxaxis objectAtIndex:index] doubleValue] y:[[scyaxis objectAtIndex:index] doubleValue]]];
}
LineChartDataSet *set = [[LineChartDataSet alloc] initWithValues:entries label:#"Line DataSet"];
[set setColor:[UIColor greenColor]];
set.lineWidth = 3.0;
// [set setCircleColor:[UIColor redColor]];
//set.circleRadius = 0.0;
// set.circleHoleRadius = 0.0;
set .drawCirclesEnabled=NO;
set.fillColor = [UIColor clearColor];
set.mode = LineChartModeLinear;
set.drawValuesEnabled = NO;
set.valueFont = [UIFont systemFontOfSize:14.f];
set.valueTextColor = [UIColor whiteColor];
set.axisDependency = AxisDependencyLeft;
[d addDataSet:set];
return d;
}
I am trying like this,But when giving different x values to each data set in line graph the x axis is completely going wrong according to it. i want the x axis to be fetched from different array and x,y points of line graph to be from different array, Can anybody help me on achieving this ?
Maybe the problem is
chartview.xAxis.axisMaximum = data.xMax + 5.0;
Cause you are using CombinedChartData,if the you should call calcMinMax() at first.
And accord to your code ,the x axis should be in [0,90.976].What your graph shows?
I've used the ios-charts project on github and used the HorizontalCharts example. It works good in the example but when I try to set the horizontal bar value, the bar just gets too long. Example visible here:
My code is this:
-(void)setupChart{
myQuota = [[DataManager shared] myQuota];
[self setupBarLineChartView:_chartView];
_chartView.delegate = self;
_chartView.drawBarShadowEnabled = NO;
_chartView.drawValueAboveBarEnabled = YES;
_chartView.maxVisibleValueCount = 60;
ChartXAxis *xAxis = _chartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.labelFont = [UIFont systemFontOfSize:10.f];
xAxis.drawAxisLineEnabled = YES;
xAxis.drawGridLinesEnabled = YES;
xAxis.gridLineWidth = .3;
ChartYAxis *leftAxis = _chartView.leftAxis;
leftAxis.labelFont = [UIFont systemFontOfSize:10.f];
leftAxis.drawAxisLineEnabled = YES;
leftAxis.drawGridLinesEnabled = YES;
leftAxis.drawLabelsEnabled = NO;
leftAxis.gridLineWidth = .3;
leftAxis.axisMinValue = 0.0;
ChartYAxis *rightAxis = _chartView.rightAxis;
rightAxis.enabled = YES;
rightAxis.labelFont = [UIFont systemFontOfSize:10.f];
rightAxis.drawAxisLineEnabled = YES;
rightAxis.drawGridLinesEnabled = NO;
rightAxis.axisMinValue = 0.0;
rightAxis.yOffset = 1.0;
rightAxis.axisMaxValue = [myQuota.quota doubleValue]; // here is 10
_chartView.doubleTapToZoomEnabled = NO;
_chartView.highlightPerTapEnabled = NO;
_chartView.legend.enabled = NO;
[_chartView animateWithYAxisDuration:2.5];
[self updateChartData];
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
if(myQuota != nil && myQuota.quota != nil)
{
[self setDataCount:(1) range: [myQuota.quota doubleValue]];
}
}
- (void)setDataCount:(int)count range:(double)range
{
NSMutableArray *xVals = [[NSMutableArray alloc] init];
[xVals addObject:myQuota.rowName];
NSMutableArray *yVals = [[NSMutableArray alloc] init];
double val = [myQuota.quotaReached doubleValue]; // here is 2
[yVals addObject:[[BarChartDataEntry alloc] initWithValue:val xIndex:0]];
BarChartDataSet *set1 = nil;
if (_chartView.data.dataSetCount > 0)
{
set1 = (BarChartDataSet *)_chartView.data.dataSets[0];
set1.yVals = yVals;
_chartView.data.xValsObjc = xVals;
[_chartView notifyDataSetChanged];
}
else
{
set1 = [[BarChartDataSet alloc] initWithYVals:yVals label:#""];
set1.barSpace = 0.35;
set1.colors = [NSArray arrayWithObjects:[UIColor greenColor], nil];
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]];
_chartView.data = data;
}
}
Why is the bar so long?
Okay, since nobody offered an answer I tried a HACK. I've added an invisible bar/row for which I set the value to the maximum of the bar chart. This way the axis shows the maximum even though the bar is invisible.
I welcome anybody who knows a better way but until then I'll do it like this:
- (void)setDataCount:(int)count range:(double)range{
MY_MAX_VALUE = 10; // put HERE your MAX value for the axis
NSMutableArray *xVals = [[NSMutableArray alloc] init];
[xVals addObject:myQuota.rowName];
NSMutableArray *yVals = [[NSMutableArray alloc] init];
double val = [myQuota.quotaReached doubleValue]; // here is 2
[yVals addObject:[[BarChartDataEntry alloc] initWithValue:val xIndex:0]];
[yVals addObject:[[BarChartDataEntry alloc] initWithValue: MY_MAX_VALUE xIndex:1]];
}
I have a view controller that's just a full screen ios-chart view nested in a nav controller. This was working in October and I've looked through my git repo and nothing has changed about this file. However I did pull in the latest version from the repo and I achieved the same results.
So first I have a setup function that sets up chart:
if (vertical)
{
self.barChart = [[BarChartView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
else
{
self.barChart = [[HorizontalBarChartView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
self.barChart.backgroundColor = [UIColor clearColor];
self.barChart.delegate = self;
self.barChart.descriptionText = #"";
self.barChart.noDataTextDescription = #"";
self.barChart.drawBarShadowEnabled = NO;
self.barChart.drawValueAboveBarEnabled = YES;
self.barChart.rightAxis.drawLabelsEnabled = NO;
self.barChart.rightAxis.drawGridLinesEnabled = NO;
self.barChart.maxVisibleValueCount = 60;
self.barChart.pinchZoomEnabled = NO;
self.barChart.drawGridBackgroundEnabled = NO;
self.barChart.backgroundColor = [UIColor whiteColor];
ChartXAxis *xAxis = self.barChart.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.labelFont = [UIFont systemFontOfSize:10.f];
xAxis.drawGridLinesEnabled = NO;
xAxis.spaceBetweenLabels = 0;
ChartYAxis *leftAxis = self.barChart.leftAxis;
leftAxis.labelFont = [UIFont systemFontOfSize:10.f];
leftAxis.labelCount = 3;
leftAxis.drawGridLinesEnabled = YES;
leftAxis.valueFormatter = [[NSNumberFormatter alloc] init];
leftAxis.valueFormatter.maximumFractionDigits = 0;
leftAxis.valueFormatter.positivePrefix = #"$";
leftAxis.valueFormatter.negativePrefix = #"-$";
leftAxis.labelPosition = YAxisLabelPositionOutsideChart;
leftAxis.spaceTop = 0.25;
[self.barChart.legend setEnabled:false];
[self refresh]; //refreshes data for charting
Refresh on self grabs the JSON off my website and forms it into an array of dictionaries and then calls this:
NSMutableArray *xAxis = [[NSMutableArray alloc] init];
NSMutableArray *yAxis = [[NSMutableArray alloc] init];
for (int x = 0; x < data.count; x++) {
[xAxis addObject:data[x][#"title"]];
[yAxis addObject:[[BarChartDataEntry alloc] initWithValue:floor([data[x][#"value"] doubleValue]) xIndex:x]];
}
BarChartDataSet *set1 = [[BarChartDataSet alloc] initWithYVals:yAxis label:self.barTitle];
set1.barSpace = 0.35;
set1.colors = #[[[UIColor alloc] initWithRed:0.007843137255 green:0.2117647059 blue:0.4470588235 alpha:1]];
set1.valueFormatter = [[NSNumberFormatter alloc] init];
set1.valueFormatter.positivePrefix = #"$";
set1.valueFormatter.negativePrefix = #"-$";
[set1.valueFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
set1.valueFormatter.maximumFractionDigits = 0;
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
BarChartData *barData = [[BarChartData alloc] initWithXVals:xAxis dataSets:dataSets];
[barData setValueFont:[UIFont fontWithName:#"HelveticaNeue-Light" size:10.f]];
self.barChart.data = barData;
The dataset is correct and gets all 24 values and appears to setup the xAxis and yAxis correctly but after all this, my chart just displays "No chart data available"
I've searched around and didn't find many articles on this but one suggestion was use dispatch_after to run setNeedsDisplay on the bar chart:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.barChart setNeedsDisplay];
});
I've tried that code with 30 seconds as my timer to be absolutely sure the chart library finished doing what it needs to with that data and still the chart shows no data.
Any and all help would be appreciated. Thanks in advance!
I have an implementation of CorePlot in my project and though I have no relevant errors or warnings in Xcode, have been unsuccessful in getting the plot to show up in the graph. The axis and chart show up fine, but no bars in the graph.
Any help or advice would be appreciated!
Header File
#import <UIKit/UIKit.h>
#import "PresentedViewControllerDelegate.h"
#import <CorePlot/ios/CorePlot.h>
#interface DeviceDetailModal : UIViewController <PresentedViewControllerDelegate, UIWebViewDelegate, UITableViewDataSource, UITableViewDelegate, CPTPlotDataSource,CPTBarPlotDelegate>{
CPTGraph *graph;
}
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (nonatomic, weak) id <PresentedViewControllerDelegate> delegate;
#property (strong,nonatomic) NSArray *dataSet;
#property (nonatomic, strong) CPTBarPlot *aaplPlot;
#property (nonatomic, strong) CPTPlotSpaceAnnotation *priceAnnotation;
#end
Main File
#import <Foundation/Foundation.h>
#import "DeviceDetailModal.h"
#import "DetailCell.h"
#import <CorePlot/ios/CorePlot.h>
#import "Constants.h"
#implementation DeviceDetailModal
NSString * const CPDTickerSymbolAAPL = #"AAPL";
CGFloat const CPDBarWidth = 0.25f;
CGFloat const CPDBarInitialX = 0.25f;
#synthesize aaplPlot = aaplPlot_;
-(void)viewDidLoad{
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor colorWithRed:0.03 green:0.06 blue:0.10 alpha:1.0]];
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:#"Close" style:UIBarButtonItemStylePlain target:self action:#selector(closeView)];
self.navigationItem.leftBarButtonItem = closeButton;
[[UIBarButtonItem appearance] setTintColor:[UIColor lightGrayColor]];
[[UINavigationBar appearance] setBarTintColor:[UIColor blackColor]];
self.tableView.layer.cornerRadius = 10.0;
self.tableView.layer.borderWidth = 0.7;
self.tableView.layer.borderColor = [UIColor whiteColor].CGColor;
self.tableView.opaque = NO;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.backgroundView = nil;
self.dataSet = [[NSArray alloc] init];
self.dataSet = [NSArray arrayWithObjects:
[NSDecimalNumber numberWithFloat:571.70],
[NSDecimalNumber numberWithFloat:560.28],
[NSDecimalNumber numberWithFloat:610.00],
[NSDecimalNumber numberWithFloat:607.70],
[NSDecimalNumber numberWithFloat:603.00],
nil];
[self configureGraph];
[graph reloadData];
}
-(void)configureGraph {
CGRect hostingRect = CGRectMake(20, 350, 335, 310);
CPTGraphHostingView *hostingView = [[CPTGraphHostingView alloc] initWithFrame:hostingRect];
[self.view addSubview:hostingView];
[hostingView setBackgroundColor:[UIColor colorWithRed:0.03 green:0.06 blue:0.10 alpha:1.0]];
hostingView.layer.cornerRadius = 10.0;
hostingView.layer.borderWidth = 0.7;
hostingView.layer.borderColor = [UIColor whiteColor].CGColor;
graph = [[CPTXYGraph alloc] initWithFrame:hostingView.bounds];
hostingView.hostedGraph = graph;
[[graph defaultPlotSpace] setAllowsUserInteraction:TRUE];
// 1 - Create the graph
graph.plotAreaFrame.masksToBorder = NO;
// 2 - Configure the graph
//[graph applyTheme:[CPTTheme themeNamed:kCPTPlainBlackTheme]];
graph.paddingBottom = 30.0f;
graph.paddingLeft = 30.0f;
graph.paddingTop = -1.0f;
graph.paddingRight = -5.0f;
// 3 - Set up styles
CPTMutableTextStyle *titleStyle = [CPTMutableTextStyle textStyle];
titleStyle.color = [CPTColor whiteColor];
titleStyle.fontName = #"Helvetica-Bold";
titleStyle.fontSize = 16.0f;
// 4 - Set up title
NSString *title = #"Portfolio Prices: April 23 - 27, 2012";
graph.title = title;
graph.titleTextStyle = titleStyle;
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
graph.titleDisplacement = CGPointMake(0.0f, -16.0f);
// 5 - Set up plot space
CGFloat xMin = 0.0f;
CGFloat xMax = 7;
CGFloat yMin = 0.0f;
CGFloat yMax = 800.0f; // should determine dynamically based on max price
NSNumber *xAxisStart = [NSNumber numberWithFloat:xMin];
NSNumber *xAxisLength = [NSNumber numberWithDouble:xMax];
NSNumber *yAxisStart = [NSNumber numberWithFloat:yMin];
NSNumber *yAxisLength = [NSNumber numberWithDouble:yMax];
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:xAxisStart length:xAxisLength];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:yAxisStart length:yAxisLength];
// 1 - Set up the three plots
self.aaplPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor redColor] horizontalBars:NO];
self.aaplPlot.identifier = CPDTickerSymbolAAPL;
// 2 - Set up line style
CPTMutableLineStyle *barLineStyle = [[CPTMutableLineStyle alloc] init];
barLineStyle.lineColor = [CPTColor lightGrayColor];
barLineStyle.lineWidth = 0.5;
// 3 - Add plots to graph
graph = hostingView.hostedGraph;
CGFloat barX = CPDBarInitialX;
NSArray *plots = [NSArray arrayWithObjects:self.aaplPlot, nil];
for (CPTBarPlot *plot in plots) {
plot.dataSource = self;
plot.delegate = self;
plot.barWidth = [NSNumber numberWithFloat:CPDBarWidth];
plot.barOffset = [NSNumber numberWithFloat:barX];
plot.lineStyle = barLineStyle;
[graph addPlot:plot toPlotSpace:graph.defaultPlotSpace];
barX += CPDBarWidth;
}
// 1 - Configure styles
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor whiteColor];
axisTitleStyle.fontName = #"Helvetica-Bold";
axisTitleStyle.fontSize = 12.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:1];
// 2 - Get the graph's axis set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) hostingView.hostedGraph.axisSet;
// 3 - Configure the x-axis
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
axisSet.xAxis.title = #"Days of Week (Mon - Fri)";
axisSet.xAxis.titleTextStyle = axisTitleStyle;
axisSet.xAxis.titleOffset = 10.0f;
axisSet.xAxis.axisLineStyle = axisLineStyle;
// 4 - Configure the y-axis
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
axisSet.yAxis.title = #"Price";
axisSet.yAxis.titleTextStyle = axisTitleStyle;
axisSet.yAxis.titleOffset = 5.0f;
axisSet.yAxis.axisLineStyle = axisLineStyle;
}
#pragma mark - CPTPlotDataSource methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
return [self.dataSet count];
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSLog(#"DATA: %#",[self.dataSet objectAtIndex:index]);
return [self.dataSet objectAtIndex:index];
}
#pragma mark - CPTBarPlotDelegate methods
-(void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)index {
// 1 - Is the plot hidden?
if (plot.isHidden == YES) {
return;
}
// 2 - Create style, if necessary
static CPTMutableTextStyle *style = nil;
if (!style) {
style = [CPTMutableTextStyle textStyle];
style.color= [CPTColor yellowColor];
style.fontSize = 16.0f;
style.fontName = #"Helvetica-Bold";
}
// 3 - Create annotation, if necessary
NSNumber *price = [self numberForPlot:plot field:CPTBarPlotFieldBarTip recordIndex:index];
if (!self.priceAnnotation) {
NSNumber *x = [NSNumber numberWithInt:0];
NSNumber *y = [NSNumber numberWithInt:0];
NSArray *anchorPoint = [NSArray arrayWithObjects:x, y, nil];
self.priceAnnotation = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:plot.plotSpace anchorPlotPoint:anchorPoint];
}
// 4 - Create number formatter, if needed
static NSNumberFormatter *formatter = nil;
if (!formatter) {
formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:2];
}
// 5 - Create text layer for annotation
NSString *priceValue = [formatter stringFromNumber:price];
CPTTextLayer *textLayer = [[CPTTextLayer alloc] initWithText:priceValue style:style];
self.priceAnnotation.contentLayer = textLayer;
// 6 - Get plot index based on identifier
NSInteger plotIndex = 0;
if ([plot.identifier isEqual:CPDTickerSymbolAAPL] == YES) {
plotIndex = 0;
}
// 7 - Get the anchor point for annotation
CGFloat x = index + CPDBarInitialX + (plotIndex * CPDBarWidth);
NSNumber *anchorX = [NSNumber numberWithFloat:x];
CGFloat y = [price floatValue] + 40.0f;
NSNumber *anchorY = [NSNumber numberWithFloat:y];
self.priceAnnotation.anchorPlotPoint = [NSArray arrayWithObjects:anchorX, anchorY, nil];
// 8 - Add the annotation
[plot.graph.plotAreaFrame.plotArea addAnnotation:self.priceAnnotation];
}
#end
Plot ranges are given as a starting location and length. In your case, make the starting location the min value and the length max - min. Right now it's ok since the min is zero, but the length will be wrong if you ever change the min values.
The -numberForPlot:field:recordIndex: datasource method must check the field parameter and return the correct value for the field. Return the index parameter value for the CPTBarPlotFieldBarLocation field. Return the value from the dataSet array for the CPTBarPlotFieldBarTip field.