IOS —— 折线图 Echart随笔
前阵子在寻觅折线图第三方工具的时候,找了许久都没太满意。(要么太简单,要么兼容不了)
在几经波折下找到了百度的Echarts,在学习的过程中也踩了几波坑。这里分享下自己学习的代码以及相应的备注
1.折线图
- (void)viewDidLoad { [super viewDidLoad]; //折线图 // [self createLineCharts]; self.view.backgroundColor = [UIColor whiteColor]; [self createScrollView]; [self showLineDemo]; //发送参数,通过参数获取并读取图表 [self.xgEchartView loadEcharts]; } - (void)createScrollView { //Echart 本质为webView,加载调用JS方法显示数据。如果需要数据之间不拥挤并且将具有滑动效果 //则需要将webView添加到scrollView上 _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, SCREEN_WIDTH, 300)]; [self.view addSubview:self.scrollView]; //更变实际内容页 self.scrollView.contentSize = CGSizeMake(SCREEN_WIDTH * 2, 0); //取消竖直滑动 self.scrollView.showsHorizontalScrollIndicator = NO; } - (void)showLineDemo { /* 图表选项 */ PYOption *option = [[PYOption alloc] init]; //是否启用拖拽重计算特性,默认关闭 option.calculable = NO; //折线颜色 option.color = @[@"#20BCFC",@"#ff6347"]; //图标背景色 option.backgroundColor = [[PYColor alloc] initWithColor:[UIColor whiteColor]]; //提示框 PYTooltip *tooltip = [[PYTooltip alloc] init]; //触发类型,默认数据触发 tooltip.trigger = @"axis"; //竖线宽度 tooltip.axisPointer.lineStyle.width = @1; //提示框,文字样式设置 tooltip.textStyle = [[PYTextStyle alloc] init]; tooltip.textStyle.fontSize = @12; //提示框 显示自定义 // tooltip.formatter = @""; //添加到图标选择中 option.tooltip = tooltip; /* 图例 */ PYLegend *legend = [[PYLegend alloc] init]; //设置数据 第一条线、第二条线 legend.data = @[@"挂牌价",@"成交价"]; //添加到图标选择中 option.legend = legend; /* 直角坐标系内绘图网格 */ PYGrid *grid = [[PYGrid alloc] init]; /* x:网格图左上角顶点距坐标系背景左侧的距离 y:网格图左上角顶点距坐标系背景上侧的距离 x2:网格图右下角顶点距坐标系背景右侧的距离 y2:网格图右下角距坐标系背景下侧的距离 */ grid.x = @(45); grid.y = @(20); grid.x2 = @(20); grid.y2 = @(30); grid.borderWidth = @(0); //添加到图标选择中 option.grid = grid; /* x轴设置 */ PYAxis *xAxis = [[PYAxis alloc] init]; //横轴默认为类目型(就是坐标系自己设置,坐标系中仅有这些指定类目坐标) xAxis.type = @"category"; //起始和结束俩端空白 xAxis.boundaryGap = @(YES); //分隔线 xAxis.splitArea.show = NO; //坐标轴线 xAxis.axisLine.show = NO; //X轴坐标数据 xAxis.data = @[@"一月",@"二月",@"三月",@"四月",@"五月",@"六月",@"七月",@"八月",@"九月",@"十月",@"十一月",@"十二月" ]; //坐标轴小标记 xAxis.axisTick = [[PYAxisTick alloc] init]; xAxis.axisTick.show = YES; //添加到图标选择中 option.xAxis = [[NSMutableArray alloc] initWithObjects:xAxis, nil ]; /* Y轴设置 */ PYAxis *yAxis = [[PYAxis alloc] init]; yAxis.axisLine.show = NO; //纵轴默认为数值型(就是坐标系统自动生成,坐标轴内包含数值区间内容全部坐标) ,改为@"category "会有问题 yAxis.type = @"value"; //y轴分隔段数,默认不修改为5 yAxis.splitNumber = @4; //分割线类型 // yAxis.splitLine.lineStyle.type = @"dashed"; //'solid' | 'dotted' | 'dashed' 虚线类型 //单位设置,最大值、最小值 // yAxis.axisLabel.formatter = @"{value} k "; // yAxis.max = @"9000"; // yAxis.min = @"5000"; //添加到图标选择中 option.yAxis = [[NSMutableArray alloc] initWithObjects:yAxis, nil]; /* 定义坐标点数组 */ NSMutableArray *seriesArr = [NSMutableArray array]; /* 第一条折线设置 */ PYCartesianSeries *series1 = [[PYCartesianSeries alloc] init]; series1.name = @"挂牌价"; //类型为折线 series1.type = @"line"; //曲线平滑 series1.smooth = YES; //坐标点大小 series1.symbolSize = @(1.5); //坐标点样式,设置连线的宽度 series1.itemStyle = [[PYItemStyle alloc] init]; series1.itemStyle.normal = [[PYItemStyleProp alloc] init]; series1.itemStyle.normal.lineStyle = [[PYLineStyle alloc] init]; series1.itemStyle.normal.lineStyle.width = @(1.5); //添加坐标点 y轴数据 (如果某一点无数据,可以传@"-",断开连线 如: @[@"1000",@"-", @"7571"]) series1.data = @[@"7566",@"7980",@"7651",@"7777",@"7528",@"7328",@"7890",@"7999",@"7265",@"7123",@"7663",@"7813"]; [seriesArr addObject:series1]; /* 第二条折线设置 */ PYCartesianSeries *series2 = [[PYCartesianSeries alloc] init]; series2.name = @"成交价"; series2.type = @"line"; series2.smooth = YES; series2.symbolSize = @(1.5); series2.itemStyle = [[PYItemStyle alloc] init]; series2.itemStyle.normal = [[PYItemStyleProp alloc] init]; series2.itemStyle.normal.lineStyle = [[PYLineStyle alloc] init]; series2.itemStyle.normal.lineStyle.width = @(1.5); series2.data = @[@"7466",@"7780",@"7751",@"7377",@"7428",@"7628",@"7590",@"7799",@"7565",@"7423",@"7263",@"7113"]; [seriesArr addObject:series2]; [option setSeries:seriesArr]; /* 初始化图标 */ self.xgEchartView = [[PYZoomEchartsView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH * 2, 300)]; //添加到scrollView上 [self.scrollView addSubview:self.xgEchartView]; //设置图标数据 [self.xgEchartView setOption:option]; }
2.柱型图
无独有偶,柱形图和折线图的实现方法差不多,仅是在数据类型 Type中 将 类型'Line' -> 'Bar'
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor whiteColor]; [self createScrollView]; //标准柱状图 [self showBarDemo]; [self.xgBarChartView loadEcharts]; } - (void)createScrollView { _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, SCREEN_WIDTH, 300)]; // _scrollView.contentSize = CGSizeMake(SCREEN_WIDTH *2, 0); //禁止上下滑动 _scrollView.showsHorizontalScrollIndicator = NO; [self.view addSubview:self.scrollView]; } - (void)showBarDemo { /* 图表 */ PYOption *option = [[PYOption alloc] init]; // option.calculable = YES; /** 如果颜色代码输入错误,则柱形图不显示 **/ option.color = @[@"#20BCFC",@"#ff6347"]; // option.backgroundColor = [[PYColor alloc] initWithColor:[UIColor redColor]]; /* 图表标题 */ PYTitle *title = [[PYTitle alloc] init]; title.text = @"某地区资源分布"; title.subtext = @"纯属虚构"; option.title = title; PYTooltip *tooltip = [[PYTooltip alloc] init]; //柱形图采用item触发 tooltip.trigger = PYTooltipTriggerAxis; //竖线宽度 tooltip.axisPointer.lineStyle.width = @1; //提示框,文字样式设置 tooltip.textStyle = [[PYTextStyle alloc] init]; tooltip.textStyle.fontSize = @12; option.tooltip = tooltip; /* 图例 */ PYLegend *legend = [[PYLegend alloc] init]; //设置柱状图表示数据 legend.data = @[@"降雨量",@"蒸发量"]; option.legend = legend; /* 直角坐标系内绘图网格 */ PYGrid *grid = [[PYGrid alloc] init]; grid.x = @(50); grid.y = @(60); grid.x2 = @(50); grid.y2 = @(60); //添加到图标选择中 option.grid = grid; /* x轴设置 */ PYAxis *xAxis = [[PYAxis alloc] init]; xAxis.type = PYAxisTypeCategory; xAxis.boundaryGap = @(YES); xAxis.position = @"bottom"; xAxis.scale = YES; //轴标记点 xAxis.splitArea.show = NO; //轴线 xAxis.axisLine.show = NO; //文本标签 xAxis.axisLabel.interval = @"auto"; //坐标轴小标记 xAxis.axisTick = [[PYAxisTick alloc] init]; xAxis.axisTick.show = YES; NSMutableArray *data = [NSMutableArray arrayWithObjects:@"周一",@"周二",@"周三",@"周四",@"周五",@"周六",@"周日", nil]; xAxis.data = data; option.xAxis = [[NSMutableArray alloc] initWithObjects:xAxis, nil]; /* y轴设置 */ PYAxis *yAxis = [[PYAxis alloc] init]; //轴线 yAxis.axisLine.show = YES; yAxis.type = PYAxisTypeValue; yAxis.splitNumber = @7; //顶部线条类型 yAxis.splitLine.lineStyle.type = @"dashed"; yAxis.axisLabel.formatter = @"{value}ml"; //最大值最小值 //yAxis.max = @250; //yAxis.min = @0; option.yAxis = [[NSMutableArray alloc] initWithObjects:yAxis, nil]; NSMutableArray *seriesArr = [NSMutableArray array]; PYCartesianSeries *series1 = [[PYCartesianSeries alloc] init]; /* 设置柱状图1类型 */ series1.type = @"bar"; //所代表数据 series1.name = @"降雨量"; //柱间间距 默认30% //series1.barGap = @"30%"; //类目间柱形距离,默认为类目间距的20% //series1.barCategoryGap = @"20%"; //柱条最低高度,防止item过小影响交互 //series1.barMinHeight = 0; //柱条宽度 不设置时自适应 //series1.barWidth = @100; //柱条最大宽度 不设置时自适应 //series1.barMaxWidth = @200; //series1.stack = @"group1"; //设置柱状图样式 //series1.itemStyle = [[PYItemStyle alloc] init]; //series1.itemStyle.normal = [[PYItemStyleProp alloc] init]; //柱状图边框颜色 //series1.itemStyle.normal.barBorderColor = [UIColor blueColor]; /*柱状图边框圆角,单位px。默认为0,支持传入数组指定圆角半径 例如[5,5,0,0] 分别 顺时针 对应左上 右上 右下 左下 */ //series1.itemStyle.normal.barBorderRadius = @[@5,@5,@0,@0]; //柱状图边框线宽度 //series1.itemStyle.normal.barBorderWidth = @100; //定义坐标点数据 series1.data = @[@126.2,@80.2,@96.0,@64.6,@81.3,@100.8,@140.4]; [seriesArr addObject:series1]; /* 设置柱状图2类型 */ PYCartesianSeries *series2 = [[PYCartesianSeries alloc] init]; series2.type = @"bar"; series2.name = @"蒸发量"; series2.data = @[@140.4,@120.4,@80.1,@64.8,@178.9,@99.9,@177.9]; [seriesArr addObject:series2]; [option setSeries:seriesArr]; /* 初始化图标 */ self.xgBarChartView = [[PYZoomEchartsView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH , 300)]; //添加到scrollView上 [self.scrollView addSubview:self.xgBarChartView]; //设置图标数据 [self.xgBarChartView setOption:option]; }
3.饼图
饼图在效果实现上与页面的不同,这可能是因为编译环境的差异。
这是饼图的基本实现代码,此处有坑。背景窗口 PYEchartsView 与 折线图的背景窗口 PYZoomEchartsView是不一样的。
如果运用了后者折线图本身是不会显示出来的,即使你其他属性设置正确(被坑惨了)
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor whiteColor]; [self createScrollView]; [self showCircleDemo]; [self.xgPieEchartsView loadEcharts]; } - (void)createScrollView { _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, SCREEN_WIDTH , 300)]; [self.view addSubview:self.scrollView]; // self.scrollView.contentSize = CGSizeMake(SCREEN_WIDTH *2, 0); self.scrollView.showsHorizontalScrollIndicator = NO; } - (void)showCircleDemo { /* 创建图表 */ PYOption *option = [[PYOption alloc] init]; //拖拽重计算,设置no可以提高加载速度 option.calculable = NO; // option.backgroundColor = [[PYColor alloc] initWithColor:[UIColor redColor]]; // option.color = @[@"#20BCFC",@"#ff6347"]; // PYTitle *title = [[PYTitle alloc] init]; // title.text = @"访问数据"; // title.subtext = @"都是假的"; // option.title = title; PYTooltip *tooltip = [[PYTooltip alloc] init]; tooltip.trigger = PYTooltipTriggerItem; tooltip.formatter = @"{a} <br/>{b}:{c}({d}%)"; option.tooltip = tooltip; PYLegend *legend = [[PYLegend alloc] init]; //提示栏 布局方式 'horizontal' 横| 'vertical' 竖 legend.orient = PYOrientVertical; //对齐位置 legend.x = PYPositionLeft; // legend.y = PYPositionCenter; legend.data = @[@"直接访问",@"邮件营销",@"联盟广告",@"视屏广告",@"搜索引擎"]; option.legend = legend; //toolbox 用于切换数据视图,暂且不写 NSMutableArray *dataArr = [NSMutableArray array]; PYPieSeries *series1 = [[PYPieSeries alloc] init]; series1.name = @"访问来源"; series1.type = PYSeriesTypePie; //传单个数据为圆半径,传数组数据1为内半径,数据2为外半径 series1.radius = @[@"50%",@"70%"]; //圆心坐标 // series1.center = @[@"50%",@"50%"]; series1.itemStyle = [[PYItemStyle alloc] init]; //圈外数据 normal // series1.itemStyle.normal = [[PYItemStyleProp alloc] init]; //圈外数据信息label series1.itemStyle.normal.label.show = YES; //圈外数据圆柱图连线 series1.itemStyle.normal.labelLine.show = YES; //圈内文字 // series1.itemStyle.emphasis = [[PYItemStyleProp alloc] init]; // series1.itemStyle.emphasis.label.show = YES; // series1.itemStyle.emphasis.labelLine.show = NO; // series1.itemStyle.emphasis.label.position = @"center"; // series1.itemStyle.emphasis.label.textStyle.fontSize = @(45); // series1.itemStyle.emphasis.label.textStyle.fontWeight = @"bold"; // series1.selectedMode = @"single"; series1.data = @[@{@"value":@(335),@"name":@"直接访问"}, @{@"value":@(310),@"name":@"邮件营销"}, @{@"value":@(234),@"name":@"联盟广告"}, @{@"value":@(135),@"name":@"视屏广告"}, @{@"value":@(1548),@"name":@"搜索引擎"}]; [dataArr addObject:series1]; [option setSeries:dataArr]; /* 初始化图标 */ self.xgPieEchartsView = [[PYEchartsView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH , 300)]; //添加到scrollView上 [self.scrollView addSubview:self.xgPieEchartsView]; //设置图标数据 [self.xgPieEchartsView setOption:option]; }
4.散点图
散点图因为数据问题,明天抽空改一改在铺上来
5.雷达图
雷达图同饼图,背景是PYEchartsView。
剩余属性相同的就不一一赘述了
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor whiteColor]; [self createScrollView]; [self showRadar]; [self.xgEchartsView loadEcharts]; } - (void)createScrollView { _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,100, SCREEN_WIDTH, 300)]; [self.view addSubview:self.scrollView]; _scrollView.contentSize = CGSizeMake(SCREEN_WIDTH * 2, 0); self.scrollView.showsHorizontalScrollIndicator = NO; } - (void)showRadar { PYOption *option = [[PYOption alloc] init]; PYTitle *title = [[PYTitle alloc] init]; title.text = @"预算 vs 开销 (Budget vs spending)"; title.subtext = @"纯属虚构"; option.title = title; PYTooltip *tooltip = [[PYTooltip alloc] init]; tooltip.trigger = @"axis"; option.tooltip = tooltip; PYLegend *legend = [[PYLegend alloc] init]; legend.orient = @"vertical"; legend.x = @"right"; legend.y = @"bottom"; legend.data = @[@"预算分配 (Allocated)",@"实际开销 (Actual Spending)"]; option.legend = legend; // PYGrid *grid = [[PYGrid alloc] init]; // grid.x = @(20); // grid.y = @(40); // grid.x2 = @(20); // grid.y2 = @(40); // // option.grid = grid; //极坐标 PYPolar *polar = [[PYPolar alloc] init]; //indicator 雷达指示坐标 NSMutableArray *polarArr= [[NSMutableArray alloc] initWithObjects:@{@"text":@"销售 (sales)",@"max":@(6000)}, @{@"text":@"管理 (Administartion)",@"max":@(16000)}, @{@"text":@"信息技术 (Information Techology)",@"max":@(30000)}, @{@"text":@"客服 (Customer Support)",@"max":@(38000)}, @{@"text":@"研发 (Development)",@"max":@(52000)}, @{@"text":@"市场 (Marketing)",@"max":@(25000)} , nil]; polar.indicator = polarArr; option.polar = [NSMutableArray arrayWithObject:polar]; NSMutableArray *dataArr = [NSMutableArray array]; PYRadarSeries *series = [[PYRadarSeries alloc] init]; series.name = @"预算 vs 开销 (Budget vs spending)"; series.type = @"radar"; //填充样式areStyle series.itemStyle = [[PYItemStyle alloc] init]; // series.itemStyle.normal = [[PYItemStyleProp alloc] init]; series.itemStyle.normal.areaStyle = [[PYAreaStyle alloc] init]; series.itemStyle.normal.areaStyle.type = PYAreaStyleTypeDefault; series.data = @[@{@"value":@[@(4300),@(10000),@(28000),@(35000),@(50000),@(19000)], @"name":@"预算分配 (Allocated)"}, @{@"value":@[@(5000),@(14000),@(28000),@(31000),@(42000),@(21000)], @"name":@"实际开销 (Actual Spending)"},]; [dataArr addObject:series]; option.series = dataArr; _xgEchartsView = [[PYEchartsView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH * 2, 300)]; [self.scrollView addSubview:self.xgEchartsView]; [self.xgEchartsView setOption:option]; }
结语:百度的Echart实质只是一个webView,用于提交参数加载其自身的html5代码实现图表。
所以第一次读取图标会明显的卡顿,并且需要网络才能完成运算这也是一个不足的地方
但是胜在功能足够强大,类型足够多。以上提供的代码只是实现了冰山的一角。但是也是最基础的模块
可以在这基础模块上慢慢添加各种装饰,就以此笔记存放此处
不足的地方还是有很多的。请多多指教。天色已晚就先行歇息了