OC調用Charts繪制圖表--LineChart

之前一直都說要寫關于繪制折線和柱狀圖的相關文章,之前在忙新的項目,這幾天不忙,也是之前那篇文章有小伙伴問我折線與柱狀圖繪制的相關問題,說一些自己研究Charts的經驗,僅代表個人觀點,如有錯誤,請多指正,下面進入正題。
首先看一下目前折線圖的效果


多系列折線圖.png

這個效果是經歷了將近一個月的時間,為了有這樣的效果,我翻遍了簡書的文章,問了很多人,技術群,這個效果是在產品經理每周叨叨叨逼出來的,不要問我為什么這么說,真的是每天都追著我改改改,優化優化優化,所以現在就有了這樣的效果,下面是代碼,代碼里面該標注釋的地方都有注釋,不要問我有github鏈接么,所有代碼都在這里,試試就知道了,講真,我不騙人,畢竟試試又不會懷孕~~??

聲明一下繪制的LineChartView只有左Y軸,沒有右Y軸,右Y軸設置也很簡單,請參考左Y軸,但是一般只要左Y軸就好了。
首先是初始化,喜歡用懶加載初始化,因為頁面有好幾個圖表,第一時間不一定用得到折線圖,初始化只有一句話,是不是很爽,別想太多,因為好幾個模塊用到的東西都一樣,就放在一個工具類里面了,MBSChartTool這個工具類,有文章,全是代碼以及注釋。。。這個工具類只是為了偷懶,最后控制器還有遵守一個代理

@interface ViewController ()<ChartViewDelegate>
@property (nonatomic, strong) LineChartView *lineChartView;
@end

#pragma mark - getter and setter
- (LineChartView *)lineChartView
{
    if (_lineChartView == nil) {
        
        _lineChartView = [MBSChartTool lineChartViewForLeftWithDelegate:self];

    }
    return _lineChartView;
}
- (NSArray *)colorArray
{
    if (_colorArray == nil) { //橘黃色  藍色 淡綠色 淺紫色 淺紅色
        _colorArray = @[ RGB(242, 152, 80), RGB(92, 178, 240), RGB(158, 202, 97), RGB(219, 95, 153), RGB(233, 84, 83)];
    }
    return _colorArray;
}
- (NSArray *)xTitles
{
    if (_xTitles == nil) {
        
        _xTitles = @[@"第1周", @"第2周", @"第3周", @"第4周", @"第5周"];
    }
    return _xTitles;
}
添加LinechartView 與 設置LinechartData
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.view addSubview:self.lineChartView];
    [self.lineChartView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(self.view).insets(UIEdgeInsetsMake(10, 20, 10, 10));
    }];
    [self setData];
}
- (void)setData
{
    NSArray *array = @[@"5553.8", @"5959.3", @"1961.7", @"<null>", @"<null>"];
    NSArray *array1 = @[@"998.5", @"1014.5", @"249", @"<null>", @"<null>"];
    NSMutableArray *valueArray = [NSMutableArray array];
    [valueArray addObject:array];
    [valueArray addObject:array1];

    NSMutableArray *dataSets = [NSMutableArray array];
    double leftAxisMin = 0;
    double leftAxisMax = 0;
    for (int i = 0; i < valueArray.count; i++) {
        
        NSArray *values = valueArray[i];
        NSMutableArray *yVals = [NSMutableArray array];
        NSString *legendName = [NSString stringWithFormat:@"第%d個圖例", i];
        for (int i = 0; i < values.count; i++)
        {
            NSString *valStr = [NSString stringWithFormat:@"%@", values[i]];
            double val = [valStr doubleValue];
            leftAxisMax = MAX(val, leftAxisMax);
            leftAxisMin = MIN(val, leftAxisMax);
            ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:i y:val];
            [yVals addObject:entry];
        }
        
        LineChartDataSet *dataSet = [[LineChartDataSet alloc] initWithValues:yVals label:legendName];
        dataSet.lineWidth = 3.0f;//折線寬度
        dataSet.drawValuesEnabled = YES;//是否在拐點處顯示數據
        dataSet.valueColors = @[self.colorArray[i]];//折線拐點處顯示數據的顏色
        [dataSet setColor:self.colorArray[i]];//折線顏色
        dataSet.drawSteppedEnabled = NO;//是否開啟繪制階梯樣式的折線圖
        dataSet.drawCirclesEnabled = NO;//是否繪制拐點
        dataSet.circleRadius = 3.0f;//拐點半徑
        dataSet.axisDependency = AxisDependencyLeft;
        dataSet.drawCircleHoleEnabled = YES;//是否繪制中間的空心
        dataSet.circleHoleRadius = 1.0f;//空心的半徑
        dataSet.circleHoleColor = self.colorArray[i];//空心的顏色
        dataSet.highlightEnabled = YES;//選中拐點,是否開啟高亮效果(顯示十字線)
        dataSet.highlightColor = [UIColor clearColor];
        dataSet.valueFont = [UIFont systemFontOfSize:12];
        [dataSets addObject:dataSet];
    }
    
    double leftDiff = leftAxisMax - leftAxisMin;
    if (leftAxisMax == 0 && leftAxisMin == 0) {
        leftAxisMax = 100.0;
        leftAxisMin = -10.0;
    } else {
        leftAxisMax = (leftAxisMax + leftDiff * 0.2);
        leftAxisMin = (leftAxisMin - leftDiff * 0.1);
    }
    self.lineChartView.leftAxis.axisMaximum = leftAxisMax;
    self.lineChartView.leftAxis.axisMinimum = leftAxisMin;
    LineChartData *data = [[LineChartData alloc] initWithDataSets:dataSets];
    self.lineChartView.data = nil;
    self.lineChartView.xAxis.axisMinimum = -0.8;
    self.lineChartView.xAxis.axisMaximum = 5.1;
    self.lineChartView.data = data;
    [self.lineChartView animateWithXAxisDuration:0.3f];
}
x軸數據源方法
lineChartView.xAxis.valueFormatter = target; 
這句話如果設置了,就必須實現x軸的數據源方法
- (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis
{
    return self.xTitles[(int)value % self.monthTitles.count];
}
xTitles就是你需要在x軸展現的標題數組,賦值就這么寫就好,別問為什么,英語好的點進去看看就知道了,四級過了英語就不看了。

這樣就會有出現下面的多系列折線圖


不完美的多系列折線圖.png

你看見x軸的標題多了一個,強迫癥受不了,產品經理看見也難受,所以要改正這個,其實這樣的圖表還是好的,看一下最初不知道設置零起點與x軸時的折線圖。


看著受不了的折線圖.png

這樣的折線圖,看著更加讓人難受,這就是最初不知道方法不知道如何解決時的折線圖,但是我那時候想到一個曲線救國的方法,就是在xtitles最前面添加倆個空的字符串,在賦值的時候把i變成了i+2,這樣雖然不是很完美,但是基本解決零起點問題,也不至于讓產品天天盯著你改改改,后來自己決定這樣不是問題,就去看demo,找到了新的解決辦法,當初步解決的時候,高興的我那感覺真的無法形容,就是可以在產品問你改好了么時候,你可以得意看著他,說一句哥改好了。說正事,方法如下:

曲線救國方法(可以忽略):   
ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:i + 2 y:val];
正確方法:
self.lineChartView.xAxis.axisMinimum = -0.8;    
self.lineChartView.xAxis.axisMaximum = 5.1;

因為x標題數組較少,所有就這么寫了,標準的方法:
self.lineChartView.xAxis.axisMinimum = data.xMin - 0.8;            
self.lineChartView.xAxis.axisMaximum = data.xMax + 0.8;

采用標準方法修復x軸最小值與最大值問題效果如之前不完美的折線圖


不完美的多系列折線圖.png

這樣雖然距離左右軸美觀了,但是有重復問題,我目前也沒有找到直接解決問題的辦法,但是可以采用方法折線圖的方法間接解決此問題,放大折線圖之后不讓進行縮放與拖動,如果你夠耐心的話,可以繼續調試ineChartView.xAxis.axisMaximum和lineChartView.xAxis.axisMinimum這倆個屬性,達到一個理想的狀態,方法折線圖方法如下:

[_lineChartView zoomWithScaleX:1.03 scaleY:1 x:0 y:0];

放大的方法有了,又會遇到新的問題,方法的比例是多少,這個好解決,折線圖有個代理方法,添加代理方法,手動進行縮放,打印里面的放大比例,然后把這個值填進去就是你需要的,不要問我為什么這么機智,逼出來的

#pragma mark - ChartView Delegate
- (void)chartScaled:(ChartViewBase *)chartView scaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY
{
    NSLog(@"%2f %2f", scaleX, scaleY);
}

還有一些其他的屬性和方法,想到那個寫那個

//縮放重置  
 [_lineChartView zoomOut];
// 可以設置dataset依賴左Y軸還是右Y軸,有的時候左右y軸的大小值不一樣,可以進行這么設置
dataSet.axisDependency = AxisDependencyLeft;
//   多系列折線圖數據初始化  
 LineChartData *data = [[LineChartData alloc] initWithDataSets:dataSets];
//   單系列折線圖數據初始化
 LineChartData *data = [[LineChartData alloc] initWithDataSet:dataSet];

經歷了半個月的煎熬,對于折線圖x軸標題重復的問題得到了完美的解決,只需要一個屬性,上面的話沒有刪除,全當自己靈活變通的思路了,也做為一個對自己的警醒,明明是一個屬性的設置,卻因為抵觸情緒不知道嘗試,下面說正事

 lineChartView.xAxis.granularity = 1.0;

看下這個屬性的charts的解釋

/**
  The minimum interval between axis values.
  This can be used to avoid label duplicating when zooming in.
  <em>default</em>: 1.0
*/
@property (nonatomic) double granularity;

百度翻譯加自己的理解一下大概意思就是:
x軸標題中間最小的間隔。這樣可以避免在縮放時label文字重復。

然后在設置x軸大小的時候就可以使用通用的方法:

self.lineChartView.xAxis.axisMinimum = data.xMin - 0.8;      self.lineChartView.xAxis.axisMaximum = data.xMax + 0.8;

這樣x軸標題重復的問題就完美解決了,也不用跟產品和測試撕逼了。
折線圖暫時想的問題和解決辦法就這么多,如有不對的地方還請多指教
最后demo地址,歡迎大家下載,最好給個star??

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,430評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,134評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,653評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,136評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,372評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,888評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,738評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,179評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,610評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,916評論 2 372

推薦閱讀更多精彩內容