/FlutterChart

一款flutter图表库(折线图、曲线图、柱状图、饼状图、多维图)

Primary LanguageDartOtherNOASSERTION

flutter_chart

所有功能示例

** 图表库集合:柱状图饼状图折线图多维图专注力曲线图记忆力游戏结果图线性指示器弧形指示器常用小组件 **

统一设置

BaseBean 作为统一对外暴漏参数定义,适用于所有基础坐标轴的参数设置(不涉及坐标轴的可以不设置,例如:饼状图,多维图)

//基本的xy轴设置属性参数
class BaseBean {
  //xy轴线条的高度宽度
  double xyLineWidth;
  //x轴的颜色
  Color xColor;
  //y轴的颜色
  Color yColor;
  //顶部的辅助线
  bool isShowBorderTop;
  //右侧的辅助线
  bool isShowBorderRight;
  //y轴左侧刻度显示,不传则没有
  List<DialStyleY> yDialValues;
  //y轴显示副刻度是在左侧还是在右侧,默认左侧
  bool isLeftYDialSub;
  //是否显示x轴文本,
  bool isShowX;
  //y轴最大值
  double yMax;
  //xy轴默认的边距,不包含周围的标注文字高度,只是xy轴的方框距离周围容器的间距
  EdgeInsets basePadding;
  //x轴辅助线
  bool isShowHintX;
  //y轴的辅助线
  bool isShowHintY;
  //辅助线颜色
  Color hintLineColor;
  //辅助线宽度
  double hintLineWidth;
  //辅助线是否为虚线
  bool isHintLineImaginary;
  //是否显示x轴刻度
  bool isShowXScale;
  //是否显示y轴刻度
  bool isShowYScale;
  //xy轴刻度的高度
  double rulerWidth;
  //x轴的单位。默认null,不绘制单位
  UnitXY? unitX;
  //y轴的单位。默认null,不绘制单位
  UnitXY? unitY;

  BaseBean({
    this.xyLineWidth = 2,
    this.xColor = defaultColor,
    this.yColor = defaultColor,
    this.isShowBorderTop = false,
    this.isShowBorderRight = false,
    this.yDialValues,
    this.isLeftYDialSub = true,
    this.isShowX = true,
    this.yMax = 100.0,
    this.basePadding = defaultBasePadding,
    this.isShowHintX = false,
    this.isShowHintY = false,
    this.hintLineColor = defaultColor,
    this.hintLineWidth = 1.0,
    this.isHintLineImaginary = false,
    this.isShowXScale = false,
    this.isShowYScale = false,
    this.rulerWidth = 4,
    this.unitX,
    this.unitY,
  });

xy设置的参数(xy的显示点位的两员大将)

y轴
//y轴
 class DialStyleY {
  //刻度标志内容(y轴仅适用于内容为数值类型的)
  String title;
  //y轴获取的值,只读
  double get titleValue {
    if (title == null || title.isEmpty) {
      return 0;
    } else {
      return double.parse(title);
    }
  }
  
  //刻度标志样式
  TextStyle titleStyle;
  //与最大数值的比率,用来计算绘制刻度的位置使用。
  double positionRetioy;
  //两个刻度之间的标注文案(y轴在该刻度下面绘制),不需要的话不设置
  String centerSubTitle;
  //标注文案样式,centerSubTitle有内容时有效
  TextStyle centerSubTextStyle;
  DialStyleY(
      {this.title,
       this.titleStyle,
       this.centerSubTitle,
       this.centerSubTextStyle,
       this.positionRetioy});
 }
x轴
//x轴
class DialStyleX {
  //刻度标志内容
  String title;
  //刻度标志样式
  TextStyle titleStyle;
  //与最大数值的比率,用来计算绘制刻度的位置使用。
  double positionRetioy;
  DialStyleX({this.title, this.titleStyle, this.positionRetioy});
}

单独使用方法(参数解析)

1.柱状图 柱状图 柱状图

///bar-circle
  Widget _buildChartBarCircle(context) {
    var chartBar = ChartBar(
    //x轴刻度显示,不传则没有,均匀分布x轴
      xDialValues: [
        ChartBarBeanX(
            title: '12-02',
            value: 100,
            titleStyle: TextStyle(color: Colors.white, fontSize: 10),
            gradualColor: [Colors.yellow, Colors.yellow]),
        ChartBarBeanX(
            title: '12-03',
            value: 70,
            titleStyle: TextStyle(color: Colors.red, fontSize: 10),
            gradualColor: [Colors.green, Colors.green])
      ],
      baseBean: BaseBean(
        yDialValues: [
          DialStyleY(
              title: '100',
              titleStyle: TextStyle(color: Colors.lightBlue, fontSize: 10),
              centerSubTitle: 'Calm',
              centerSubTextStyle: TextStyle(color: Colors.red, fontSize: 10),
              positionRetioy: 100 / 100),
          DialStyleY(
              title: '65',
              titleStyle: TextStyle(color: Colors.lightBlue, fontSize: 10),
              centerSubTitle: 'Aware',
              centerSubTextStyle: TextStyle(color: Colors.red, fontSize: 10),
              positionRetioy: 65 / 100),
          DialStyleY(
              title: '35',
              titleStyle: TextStyle(color: Colors.lightBlue, fontSize: 10),
              centerSubTitle: 'Focused',
              centerSubTextStyle: TextStyle(color: Colors.red, fontSize: 10),
              positionRetioy: 35 / 100)
        ],
        yMax: 100.0,
      ),
      size: Size(MediaQuery.of(context).size.width,
          MediaQuery.of(context).size.height / 5 * 1.8),
    //柱状图的宽度,如果小的话按照这个显示,如果过于宽,则按照平均宽度减去最小间距5得出的宽度
      rectWidth: 50.0,
      duration: Duration(seconds: 2),
      //柱体四周圆角,默认没有圆角
      borderRadius: BorderRadius.only(
          topLeft: Radius.circular(50), topRight: Radius.circular(50)),
    );
    return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
      semanticContainer: true,
      color: Colors.blue.withOpacity(0.4),
      child: chartBar,
      clipBehavior: Clip.antiAlias,
    );
  }

2.饼状图 饼状图

///pie
  Widget _buildChartPie(context) {
    var chartPie = ChartPie(
      chartBeans: [
        ChartPieBean(
            type: '话费',
            value: 180,
            color: Colors.blueGrey,
            assistTextStyle: TextStyle(fontSize: 12, color: Colors.blueGrey)),
        ChartPieBean(
            type: '零食',
            value: 10,
            color: Colors.deepPurple,
            assistTextStyle: TextStyle(fontSize: 12, color: Colors.deepPurple)),
        ChartPieBean(
            type: '衣服',
            value: 1,
            color: Colors.green,
            assistTextStyle: TextStyle(fontSize: 12, color: Colors.green))
      ],
      //辅助性文案显示的样式
      assistTextShowType: AssistTextShowType.OnlyName,
      //开始画圆的位置(枚举)
      arrowBegainLocation: ArrowBegainLocation.Right,
      backgroundColor: Colors.white,
      assistBGColor: Color(0xFFF6F6F6),
      //辅助性百分比显示的小数位数,(饼状图还是真实的比例)
      decimalDigits: 1,
      //各个占比之间的分割线宽度,默认为0即不显示分割
      divisionWidth: 2,
      size: Size(
          MediaQuery.of(context).size.width, MediaQuery.of(context).size.width),
          // 圆盘的半径,设置太长会按照可承受(除去basebean的basepadding的限制之后)最小的宽或者高的长度的一半
      globalR: MediaQuery.of(context).size.width / 3,
      //中心的圆半径
      centerR: 6,
      centerColor: Colors.white,
      centerWidget: Text(
        '测试中心widget',
        style: TextStyle(color: Colors.black, fontSize: 20),
      ),
    );
    return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
      color: Colors.orangeAccent.withOpacity(0.6),
      clipBehavior: Clip.antiAlias,
      borderOnForeground: true,
      child: chartPie,
    );
  }

3.折线图 折线图 折线图 双折线

class _ChartLineState extends State<ChartLinePage> {
  ChartBeanSystem _chartLineBeanSystem;

  @override
  void initState() {
    _chartLineBeanSystem = ChartBeanSystem(
      //x轴的字体样式
      xTitleStyle: TextStyle(color: Colors.grey, fontSize: 12),
      //是否显示x轴的文字,用来处理多个线条绘制的时候,同一x轴坐标不需要绘制多次,则只需要将多条线中一个标记绘制即可
      isDrawX: true,
      lineWidth: 2,
      //线条点的特殊处理,如果内容不为空,则在点上面会绘制,这个是圆点半径参数
      pointRadius: 0,
        //标记是否为曲线
      isCurve: false,
        //点集合
      chartBeans: [
        ChartLineBean(x: '12-01', y: 30),
        ChartLineBean(x: '12-02', y: 88),
        ChartLineBean(x: '12-03', y: 20),
        ChartLineBean(x: '12-04', y: 67),
        ChartLineBean(x: '12-05', y: 10),
        ChartLineBean(x: '12-06', y: 40),
        ChartLineBean(x: '12-07', y: 10),
      ],
      //Line渐变色,从曲线到x轴从上到下的闭合颜色集
      shaderColors: [
        Colors.blue.withOpacity(0.3),
        Colors.blue.withOpacity(0.1)
      ],
      //曲线或折线的颜色
      lineColor: Colors.red,
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(ChartLinePage.title),
      ),
      body: _buildChartLine(context),
    );
  }

  ///line
  Widget _buildChartLine(context) {
    var chartLine = ChartLine(
      chartBeanSystems: [_chartLineBeanSystem],
      size: Size(MediaQuery.of(context).size.width,
          MediaQuery.of(context).size.height / 5 * 1.6),
      baseBean: BaseBean(
        xColor: Colors.black,
        yColor: Colors.white,
        yDialValues: [
          DialStyleY(
            title: '0',
            titleStyle: TextStyle(fontSize: 10.0, color: Colors.black),
            positionRetioy: 0 / 100.0,
          ),
          DialStyleY(
            title: '35',
            titleStyle: TextStyle(fontSize: 10.0, color: Colors.black),
            positionRetioy: 35 / 100.0,
          ),
          DialStyleY(
            title: '65',
            titleStyle: TextStyle(fontSize: 10.0, color: Colors.black),
            positionRetioy: 65 / 100.0,
          ),
          DialStyleY(
            title: '100',
            titleStyle: TextStyle(fontSize: 10.0, color: Colors.black),
            positionRetioy: 100 / 100.0,
          )
        ],
        yMax: 100,
        isShowHintX: true,
        isHintLineImaginary: true,
      ),
    );
    return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
      semanticContainer: true,
      color: Colors.yellow.withOpacity(0.4),
      child: chartLine,
      clipBehavior: Clip.antiAlias,
    );
  }
}

4.多维图 多维图 多维图 多维图

Widget _buildWidget(BuildContext context) {
    var chartLine = ChartDimensionality(
    //维度划分的重要参数
      dimensionalityDivisions: [
        ChartBeanDimensionality(
          tip: '选择性专注力',
          tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
        ),
        ChartBeanDimensionality(
          tip: '持续性专注力',
          tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
        ),
        ChartBeanDimensionality(
          tip: '转换性专注力',
          tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
        ),
        ChartBeanDimensionality(
          tip: '分配性专注力',
          tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
        ),
        ChartBeanDimensionality(
          tip: '视觉性专注力',
          tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
        ),
        ChartBeanDimensionality(
          tip: '玩儿呢',
          tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
        )
      ],
     //维度填充数据的重要内容
      dimensionalityTags: [
        DimensionalityBean(
          tagColor: Color(0xFFB1E3AD).withOpacity(0.6),
          tagTitleStyle: TextStyle(color: Color(0xFF666666), fontSize: 16.0),
          tagTitle: '初次评测',
          tagContents: [0.2, 0.4, 0.8, 1.0, 0.1, 0.5],
        ),
        DimensionalityBean(
          tagColor: Color(0xFFF88282).withOpacity(0.6),
          tagTitleStyle: TextStyle(color: Color(0xFF666666), fontSize: 16.0),
          tagTitle: '本次评测',
          tagContents: [0.8, 0.9, 0.8, 1.0, 0.7, 0.9],
        )
      ],
      size: Size(MediaQuery.of(context).size.width,
          MediaQuery.of(context).size.height / 5 * 1.6),
     //背景网是否为虚线
      isDotted: false,
      //线宽
      lineWidth: 2,
      centerR: 150,
      backgroundColor: Colors.white,
      //线条颜色
      lineColor: Colors.blueAccent,
      //阶层:维度图从中心到最外层有几圈
      dimensionalityNumber: 4,
    );
    return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
      semanticContainer: true,
      color: Colors.green.withOpacity(0.5),
      child: chartLine,
      clipBehavior: Clip.antiAlias,
    );
  }

5.专注力曲线图 专注力曲线图 专注力曲线gif

class _FNDoubleLinePageState extends State<FNDoubleLinePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(FNDoubleLinePage.title),
      ),
      body: ChangeNotifierProvider(
        create: (_) => ChartFocusDoubleLineProvider(),
        child: Consumer<ChartFocusDoubleLineProvider>(
            builder: (context, provider, child) {
          return Card(
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
            margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
            semanticContainer: true,
            color: Colors.white,
            child: ChartLineFocus(
              size: Size(MediaQuery.of(context).size.width,
                  MediaQuery.of(context).size.height / 5 * 1.6),
                  //专注力曲线的数组,数组中的每一个元素都是一条线,支持多条曲线绘制
              focusChartBeans: provider.focusChartBeanMains,
              //这里的参数不再赘述,基础设置已介绍完备
              baseBean: BaseBean(
                isShowHintX: true,
                isShowHintY: false,
                hintLineColor: Colors.blue,
                isHintLineImaginary: false,
                isLeftYDialSub: false,
                yMax: 100.0,
                yDialValues: provider.yArr,
              ),
              xMax: 60,
              xDialValues: provider.xArr,
            ),
            clipBehavior: Clip.antiAlias,
          );
        }),
      ),
    );
  }
}

//专注力曲线的每一条线的模型内容
class FocusChartBeanMain {
  //数据显示点集合
  List<ChartBeanFocus> chartBeans;
  //曲线或折线的颜色
  Color lineColor = Colors.lightBlueAccent;
  //曲线或折线的线宽
  double lineWidth = 4;
  //是否是曲线
  bool isCurve = true;
  //是否需要触摸(针对静态图),触摸之后的显示参数在ChartLineFocus里面有设置,目前仅支持一条触摸线显示,多条线的话只显示第一条支持触摸的线的触摸
  bool touchEnable = false;
  //是否显示占位点(每一个值的位置以空心点的形式展示,占位点的颜色目前按照y轴辅助文案的颜色显示)
  bool showSite = false;
  //内部的渐变颜色。不设置的话默认按照解释文案的分层显示,如果设置,即为整体颜色渐变显示
  List<Color> gradualColors;
  //beans的时间轴如果断开,true: 是继续上一个有数值的值绘制,还是 false:断开。按照多条绘制,默认true
  bool isLinkBreak = true;
  //结束回调
  VoidCallback canvasEnd;

  FocusChartBeanMain(
      {this.chartBeans,
      this.lineColor,
      this.lineWidth,
      this.isCurve = true,
      this.touchEnable = false,
      this.showSite = false,
      this.gradualColors,
      this.isLinkBreak,
      this.canvasEnd});
}

6.记忆力图表游戏结果

  ResultMemory(
    contentWidth: 500,
    extraJson: pic_extraJson,
    // isShow: true,
    backgroundColor: Colors.orange,
  )

7.线性指示器 线性指示器

LinearPercentIndicator(
                width: 140.0,
                lineHeight: 14.0,
                percentModel: PercentModel(
                  percent: 0.7,
                  fillColor: Colors.green,
                ),
                centerSet: CenterSet(
                    center: Text(
                  '70.0%',
                  style: TextStyle(fontSize: 12.0),
                )),
                strokeCap: StrokeCap.square,
                backgroundGradient: ColorGradientModel(color: Colors.orange),
                progressGradient: ColorGradientModel(
                  linearGradient: LinearGradient(
                    colors: [Colors.red, Colors.blue],
                  ),
                ),
              )

8.弧形指示器 弧形指示器 弧形指示器

CircularPercentIndicator(
                size: 100.0,
                percentModel: PercentModel(
                  percent: 0.5,
                ),
                animationSet: AnimationSet(
                  animationDuration: 2000,
                ),
                progressModel: LineModel(
                  width: 10.0,
                  color: Colors.red,
                ),
                backgroundModel: LineModel(
                  color: Colors.orange,
                ),
                arcType: ArcType.HALF,
                center: Text(
                  '40 hours',
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0),
                ),
                strokeCap: StrokeCap.butt,
              ),

9.常用小组件 常用小组件

// 方形选中和非选中“对勾”
CustomCheckbox(
              strokeWidth: 3,
              strokeColor: Colors.orange,
              normalBorderColor: Colors.cyan,
              fillColor: Colors.red,
              radius: 3,
              value: _checked,
              onChanged: _onChange,
            ),
//圆形选中和非选中“对勾”
DoneWidget(
            outline: true,
            value: _checked,
            color: Colors.orange,
            normalBorderColor: Colors.cyan,
            onChanged: _onChange,
          ),