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.柱型图

无独有偶,柱形图和折线图的实现方法差不多,仅是数据类型将 '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代码实现图表。

所以第一次读取图标会明显的卡顿,并且需要网络才能完成运算这也是一个不足的地方

但是胜在功能足够强大,类型足够多。以上提供的代码只是实现了冰山的一角。但是也是最基础的模块

可以在这基础模块上慢慢添加各种装饰,就以此笔记存放此处

不足的地方还是有很多的。请多多指教。天色已晚就先行歇息了

猜你喜欢

转载自www.cnblogs.com/UUUUgua/p/10106320.html