Flutter —— 二:如何绘制图表charts_flutter

        最近做了个项目需要有折线图和饼图 因为能查找到的资料很少 实现的过程比较艰难 所以记录下来。做的时候用到了 fl_chart 和 charts_flutter 两个库,今天先讲charts_flutter 。

charts_flutter的文档里面有丰富的示例图和示例代码。可以选择自己想要的样式的示例代码进行查看。

这次做的是饼图,就截一张饼图的示例图,每个点进去都有完整的示例代码。
饼图示例图

接下来开始动手:

1.添加依赖

        打开项目下的pubspec.yaml文件,在 dependencies 下添加 charts_flutter: ^0.9.0 (添加完别忘了flutter pub get,最新版请在charts_flutter上查看)

2.示例代码(初识)

先拿到上图中第一个的示例代码,放到自己的项目中跑起来看看效果。

/// Simple pie chart example.
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

class SimplePieChart extends StatelessWidget {
  final List<charts.Series> seriesList;
  final bool animate;

  SimplePieChart(this.seriesList, {this.animate});

  /// Creates a [PieChart] with sample data and no transition.
  factory SimplePieChart.withSampleData() {
    return new SimplePieChart(
      _createSampleData(),
      // Disable animations for image tests.
      animate: false,
    );
  }

  @override
  Widget build(BuildContext context) {
    return new charts.PieChart(seriesList, animate: animate);
  }

  /// Create one series with sample hard coded data.
  static List<charts.Series<LinearSales, int>> _createSampleData() {
    final data = [
      new LinearSales(0, 100),
      new LinearSales(1, 75),
      new LinearSales(2, 25),
      new LinearSales(3, 5),
    ];

    return [
      new charts.Series<LinearSales, int>(
        id: 'Sales',
        domainFn: (LinearSales sales, _) => sales.year,
        measureFn: (LinearSales sales, _) => sales.sales,
        data: data,
      )
    ];
  }
}

/// Sample linear data type.
class LinearSales {
  final int year;
  final int sales;

  LinearSales(this.year, this.sales);
}

跑起来后,就跟示例图一样。
在这里插入图片描述

3.示例代码分析(认知)

  @override
  Widget build(BuildContext context) {
    return new charts.PieChart(seriesList, animate: animate);
  }

        首先,创建饼图的方式为 new charts.PieChart();,然后在括号里传入所需的参数。在AndroidStudio中按住ctrl,并将光标移到PieCHart上可以看到具体的参数信息。示例代码中,传入了seriesListanimate
        1.seriesList: 既然是饼图,那就需要数据,根据不同数据的大小,来显示不同的占比。
这里的数据类型为List<charts.Series<LinearSales, int>>,很明显这是库定义的类型,我们只要学会怎么去生成这种数据,就能放入饼图中使用。
        首先是创建一个数据模型,可以根据自己的需求进行定义。示例代码中定义的LinearSales 有两个属性,分别为yearsales,顾名思义应该是不同年份的销量进行对比。

class LinearSales {
  final int year;
  final int sales;

  LinearSales(this.year, this.sales);
}

创建完后,就可以生成数据了,下面是示例代码中的数据。

 static List<charts.Series<LinearSales, int>> _createSampleData() {
   final data = [
     new LinearSales(0, 100),
     new LinearSales(1, 75),
     new LinearSales(2, 25),
     new LinearSales(3, 5),
   ];

   return [
     new charts.Series<LinearSales, int>(
       // 1.id:这里要求填入一个id,既然人家要求了那就设置一个以免出现问题吧。
       id: 'Sales',
       // 2.domianFn:这个属性相当于折线图或柱状图的横坐标
       domainFn: (LinearSales sales, _) => sales.year,
       // 3.measureFn:这个属性相当于折线图或柱状图的纵坐标,也就是比较的数值
       measureFn: (LinearSales sales, _) => sales.sales,
       // 4.data:这个就是要传入的自己的数据
       data: data,
     )
   ];
 }

简单的说下return里的内容: 遍历data中的数据,先拿出第一个LinearSales(0, 100),然后domainFn中的sales即为LinearSales(0, 100),此时的sales.year就是0measureFn中也一样,此时的sales.sales就是100。之后以此类推拿出第二个第三个数据。

        2.animate: bool类型。是true的时候,会有一个动画效果(生成时的动画)。效果如下:

在这里插入图片描述

4.扩展(关键)

        很明显,我们平时项目要求的样式,和这个示例图有着不小的出入,我们该如何去根据自己的需求来进行修改。
        在charts.PieChart中,有个属性叫defaultRenderer,根据名字可以认为这是一个默认渲染,当没有重写的时候,默认的就是上面示例图的样式,而我们可以根据自己的需求通过new charts.ArcRendererConfig()的方式重写这个属性。

  @override
  Widget build(BuildContext context) {
    return new charts.PieChart(
      seriesList, 
      defaultRenderer: new charts.ArcRendererConfig(
        arcWidth: int,
        arcRendererDecorators: []... // 这里有挺多属性的 由于我项目中只用到了上面2个属性 所以没有深究其他的 有兴趣的可以自己看源码
     )
    );
  }

1.arcWidth: 下图是arcWidth设置为40的样式,arcWidth的值即为圆环的宽度,值越小,宽度越小
在这里插入图片描述
2.arcRendererDecorators: 之前的图里都没有文字,看起来不直观,不知道哪部分是什么。通过这个属性,可以把内容显示出来。
        先介绍一下部分属性,分别为labelPositionshowLeaderLinesleaderLineStyleSpecinsideLabelStyleSpecoutsideLabelStyleSpec。剩余的可以看源码了解

        labelPosition: 可以控制文字在饼图内部还是外部,设置成inside时在里面,outside时在外面,也可以设置成auto,默认内部,当文字显示不下时会自动放在外面。当文字在内部的时候,跟LeaderLine有关的内容就不生效,因为指引线是跟外面的文字所连接的。
        showLeaderLines: 该属性用来控制文字在外面时显不显示指引线,默认是true即显示。
        其他三个Spec结尾的属性: Spec结尾的均为设置样式,根据名字可以知道分别是内部文字样式,外部文字样式和指引线样式,可以根据下面代码查看编写方式,并不难。不过需要注意其中的Color类需要用该库中的Color类。需要通过charts.ColorUtil.fromDartColor(Colors.orange)的方式在()传入颜色值来设置颜色。

arcRendererDecorators: [
 new charts.ArcLabelDecorator(
      labelPosition: charts.ArcLabelPosition.outside,
      showLeaderLines: true,
      insideLabelStyleSpec: charts.TextStyleSpec(
	    color: charts.ColorUtil.fromDartColor(Colors.orange),
	    fontSize: 14),
      outsideLabelStyleSpec: charts.TextStyleSpec(
        color: charts.ColorUtil.fromDartColor(Colors.orange),
        fontSize: 14),
      leaderLineStyleSpec: charts.ArcLabelLeaderLineStyleSpec(
        color: charts.ColorUtil.fromDartColor(Colors.orange),
        length: 15.0,
        thickness: 1.0
      ),
    )
]

上面代码的效果如下:
在这里插入图片描述
        现在为止,可以发现一个问题,刚才的样式设置,都是统一的,一设置,所有文字的颜色都会变。假如我们需要对不同的文字设置不同的颜色,同时将饼图中各部分的颜色设置成和文字相同,那么就需要在数据中设置。即示例代码中的seriesList。因为涉及到颜色值,所以我们修改一下数据模型和数据。

首先是数据模型,这里将year改成String只是为了说明该类型不局限于int

class LinearSales {
  String year;
  int sales;
  Color colorVal;

  LinearSales(this.year, this.sales,this.colorVal);
}

下面是数据
        colorFn: 在这里传入sales.colorVal就可以改变饼图各部分的颜色了。
        outsideLabelStyleAccessorFn: 这里是外部文字样式,也可以传入sales.colorVal来设置颜色
        labelAccessorFn: 这个是显示的文字,通过自己的拼接显示出相应格式的文字。下面代码中的'${sales.year}: ${sales.sales}'对应的第一个数据就是 2017:95

  List<charts.Series<LinearSales, String>> _createSampleData() {
    final data = [
      new LinearSales('2017', 95, Colors.red),
      new LinearSales('2018', 75, Colors.grey),
      new LinearSales('2019', 25, Colors.green),
      new LinearSales('2020', 5, Colors.blue),
    ];

    return [
      new charts.Series<LinearSales, String>(
        id: 'Sales',
        data: data,
        domainFn: (LinearSales sales, _) => sales.year,
        measureFn: (LinearSales sales, _) => sales.sales,
        colorFn: (LinearSales sales, _) =>   charts.ColorUtil.fromDartColor(sales.colorVal),
        labelAccessorFn: (LinearSales sales, _) => '${sales.year}:${sales.sales}',
        outsideLabelStyleAccessorFn: (LinearSales sales, _) =>
         charts.TextStyleSpec(
            fontSize: 12,
            color: charts.ColorUtil.fromDartColor(sales.colorVal),
          )
      )
    ];
  }

下面是相应的界面:
在这里插入图片描述
问题: 指引线暂时没看到如何单独设置颜色,不知道有没有看漏什么。第一次花心思写博客,如果哪里有问题或者有什么意见和建议都可以提。
demo已上传

评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starcrius

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值