之前寫了一期Charts框架的集成以及折線圖的簡單實現,需要的看這里傳送門
那么最近又需要繪圖, 所以來更新下最新的使用。
Charts框架最新版本是v3.4.0, 從v3.0版本開始, 有了一些重大更改,摘錄了一部分在下面:
x索引已失效。引誘:x值。現在,每個條目都有一個x和一個y。
餅圖/雷達圖不再具有X索引的概念
統一的XAxis / YAxis功能和經驗。
軸的統一格式器接口。
用于y值的新格式化程序,不再從NSNumberFormatter繼承,以具有dataSet和視口信息以做出更好的格式化決策。
所有數據集構造函數都已更改-它們不再采用x索引數組。
所有條目構造函數均已更改-它們采用X和Y。
其實對我們影響更大的部分是一些類方法需要替換,比如:用[[LineChartDataSet alloc]initWithEntries:yVals label:nil];
替換[[LineChartDataSet alloc]initWithValues:yVals label:nil];
所以下面重新梳理一下折線圖的繪制,注解會更詳細:
- 創建LineChartView
- (LineChartView *)lineChartView
{
if (!_lineChartView)
{
_lineChartView = [[LineChartView alloc] init];
_lineChartView.backgroundColor = [UIColor clearColor];
_lineChartView.delegate = self;
// 設置間隙
[_lineChartView setExtraOffsetsWithLeft:0 top:20 right:0 bottom:10];
// 關于圖表的描述
_lineChartView.noDataText = @"暫無數據";
_lineChartView.chartDescription.enabled = YES;
// 關閉圖例顯示
_lineChartView.legend.enabled = NO;
// x/y軸是否支持拖拽
_lineChartView.scaleYEnabled = YES;
_lineChartView.scaleXEnabled = YES;
// 是否支持雙擊縮放
_lineChartView.doubleTapToZoomEnabled = NO;
// 啟用拖拽
_lineChartView.dragEnabled = NO;
// 展現動畫
[_lineChartView animateWithYAxisDuration:0.75f];
// Y軸設置
ChartYAxis *leftAxis = _lineChartView.leftAxis;
leftAxis.enabled = YES;
leftAxis.axisLineColor = [UIColor clearColor]; // Y軸顏色
leftAxis.labelFont = SystemFontSize(10);
leftAxis.labelTextColor = UIColorFromHEXA(0xFFFFFF, 0.6);
leftAxis.gridColor = UIColorFromHEXA(0xffffff, 0.6); // 網格線顏色
leftAxis.granularityEnabled = NO; // 是否開啟j抗鋸齒,默認打開
leftAxis.drawZeroLineEnabled = YES; // 繪制零線
leftAxis.zeroLineColor = [UIColor blueColor];
[leftAxis setXOffset:15.0f];
leftAxis.labelCount = 6; // 強制固定label個數
leftAxis.forceLabelsEnabled = YES;
_lineChartView.rightAxis.enabled = NO; // 不繪制右邊軸
// X軸設置
ChartXAxis *xAxis = _lineChartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom; // 設置x軸數據在底部
xAxis.axisLineColor = [UIColor clearColor];
xAxis.labelFont = SystemFontSize(10);
xAxis.labelTextColor = UIColorFromHEXA(0xFFFFFF, 0.6);
xAxis.gridColor = [UIColor clearColor];
xAxis.avoidFirstLastClippingEnabled = YES;
[xAxis setYOffset:15.0f];
xAxis.labelCount = 6; // 強制固定label個數
xAxis.forceLabelsEnabled = YES;
xAxis.valueFormatter = [[LWOtherDataXAxisFormatter alloc] init];
}
return _lineChartView;
}
- 顯示數據處理
- (void)setLineChartWithXData:(NSArray *)xData yData:(NSArray *)yData
{
if (xData.count > 0)
{
//對應Y軸上面需要顯示的數據
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < yData.count; i++) {
ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:[xData[i] doubleValue] y:[yData[i] doubleValue]];
[yVals addObject:entry];
}
LineChartDataSet *set1 = [[LineChartDataSet alloc]initWithEntries:yVals label:nil];
// 折線寬度
set1.lineWidth = 3.0f;
// 折線顏色
[set1 setColor:UIColorFromHEXA(0xFFD14F, 1.0)];
// 折線模式
set1.mode = LineChartModeCubicBezier;
// 是否填充顏色
set1.drawFilledEnabled = YES;
// 是否繪制拐點
set1.drawCirclesEnabled = NO;
// 是否在拐點處顯示數據
set1.drawValuesEnabled = NO;
// 拐點圓設置
set1.circleRadius = 7.0f; // 半徑
set1.circleColors = @[WhiteColor]; // 圓圈顏色
set1.circleHoleColor = UIColorFromHEXA(0xFFD14F, 1.0); // 圓圈孔中間顏色
set1.circleHoleRadius = 2.5f; // 圓圈孔半徑
LineChartData *data = [[LineChartData alloc]initWithDataSet:set1];
_lineChartView.data = data;
}
}
基本這些已經夠我們繪制一個好看,平滑且有背景遮罩的折線圖了。
但是我根據需求處理的時候發現了一個問題, 服務器返回的數據, x軸的時間點是“8:30”這種格式, 在進行doubleValue轉變后,X軸的值就變成了“8.00”,導致8:00 和 8:30 都顯示為8.00
所以這里就需要我們引入協議IChartAxisValueFormatter
:
聲明一個NSObject
類,讓其遵循IChartAxisValueFormatter
協議,重寫-(NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis
方法,然后設置X軸的valueFormatter,即xAxis.valueFormatter
。
#import <Foundation/Foundation.h>
#import <Charts/Charts-Swift.h>
NS_ASSUME_NONNULL_BEGIN
@interface LWOtherDataXAxisFormatter : NSObject<IChartAxisValueFormatter>
@end
NS_ASSUME_NONNULL_END
#import "LWOtherDataXAxisFormatter.h"
@implementation LWOtherDataXAxisFormatter
- (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis{
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:value];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"HH:mm"];
NSString *strDate = [dateFormatter stringFromDate:date];
return strDate;
}
@end
這里重寫stringForValue
方法時, 根據自己需求,自行處理即可。
使用:
ChartXAxis *xAxis = _lineChartView.xAxis;
xAxis.valueFormatter = [[LWOtherDataXAxisFormatter alloc] init];
這樣就ok了。
關于指示器maskView,是完全可以自定義的,ChartMarkerView添加一個子視圖即可:
ChartMarkerView * makerView = [[ChartMarkerView alloc]init];
MaskView *masker = [[MaskView alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
[makerView addSubview:masker];
視圖是否支持顯示指示器:chartView.drawMarkers = YES;
最后寫一下ChartViewDelegate,常用的代理也就是第一個:
- (void)chartValueSelected:(ChartViewBase *)chartView entry:(ChartDataEntry *)entry highlight:(ChartHighlight *)highlight
{
NSLog(@"數值被選中,可更新指示器顯示, maskView可以自定義");
}
- (void)chartValueNothingSelected:(ChartViewBase *)chartView{
NSLog(@"空白區域被選中");
}
- (void)chartScaled:(ChartViewBase *)chartView scaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY{
NSLog(@"視圖被縮放");
}
- (void)chartTranslated:(ChartViewBase *)chartView dX:(CGFloat)dX dY:(CGFloat)dY{
NSLog(@"視圖被移動");
}
以上, End。
對你有幫助的話,記得點個??哦~