19.1.flutter-柱状图

1

import 'dart:math';

import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

///柱状图-不可滑动-单数据
class ChartTestPage extends StatelessWidget {
  const ChartTestPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("chart_flutter")),
      body: Column(children: [Container(height: 240, child: _simpleBar())]),
    );
  }

  Widget _simpleBar() {
    var random = Random();

    var data = [
      OrdinalSales('2011', random.nextInt(100)),
      OrdinalSales('2012', random.nextInt(100)),
      OrdinalSales('2013', random.nextInt(100)),
      OrdinalSales('2014', random.nextInt(100)),
      OrdinalSales('2015', random.nextInt(100)),
      OrdinalSales('2016', random.nextInt(100)),
    ];

    var seriesList = [
      charts.Series<OrdinalSales, String>(
        id: 'Sales',
        colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault, //柱体颜色
        domainFn: (OrdinalSales sales, _) => sales.year,
        measureFn: (OrdinalSales sales, _) => sales.sales,
        labelAccessorFn: (OrdinalSales sales, _) => "${sales.sales}", //柱体最上边数字
        data: data, //数据
      )
    ];

    return charts.BarChart(
      seriesList,
      animate: true,
      barRendererDecorator: new charts.BarLabelDecorator<String>(), //显示柱体最上边数字
      vertical: true, //true:垂直展示,false:水平展示
    );
  }
}

class OrdinalSales {
  final String year;
  final int sales;

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

2

import 'dart:math';

import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

///柱状图-单数据-可滑动
class ChartTestPage1 extends StatelessWidget {
  const ChartTestPage1({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("chart_flutter")),
      body: Column(children: [Container(height: 240, child: _simpleBar())]),
    );
  }

  Widget _simpleBar() {
    var random = Random();

    var data = [
      OrdinalSales('2011', random.nextInt(100)),
      OrdinalSales('2012', random.nextInt(100)),
      OrdinalSales('2013', random.nextInt(100)),
      OrdinalSales('2014', random.nextInt(100)),
      OrdinalSales('2015', random.nextInt(100)),
      OrdinalSales('2016', random.nextInt(100)),
    ];

    var seriesList = [
      charts.Series<OrdinalSales, String>(
        id: 'Sales',
        colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault, //柱体颜色
        domainFn: (OrdinalSales sales, _) => sales.year,
        measureFn: (OrdinalSales sales, _) => sales.sales,
        labelAccessorFn: (OrdinalSales sales, _) => "${sales.sales}", //柱体最上边数字
        data: data,
      )
    ];

    ///左右滑动
    return charts.BarChart(
      seriesList,
      animate: true, // 动画
      behaviors: [
        charts.SlidingViewport(), //滑动窗口
        charts.PanAndZoomBehavior(), //平移和缩放行为
      ],
      barRendererDecorator: new charts.BarLabelDecorator<String>(), //显示柱体最上边数字
      domainAxis: new charts.OrdinalAxisSpec(viewport: new charts.OrdinalViewport('2011', 4)), //从2011,界面显示4个,其他隐
      vertical: true, //true:垂直展示,false:水平展示藏
    );
  }
}

class OrdinalSales {
  final String year;
  final int sales;

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

3

import 'dart:math';

import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

///左右滑动-柱状图-多数据
class ChartTestPage2 extends StatelessWidget {
  const ChartTestPage2({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("chart_flutter")),
      body: Column(children: [Container(height: 250, child: _simpleBar())]),
    );
  }

  Widget _simpleBar() {
    var random = Random();

    var data1 = [
      OrdinalSales('2011', random.nextInt(100)),
      OrdinalSales('2012', random.nextInt(100)),
      OrdinalSales('2013', random.nextInt(100)),
      OrdinalSales('2014', random.nextInt(100)),
      OrdinalSales('2015', random.nextInt(100)),
      OrdinalSales('2016', random.nextInt(100)),
      OrdinalSales('2017', random.nextInt(100)),
      OrdinalSales('2018', random.nextInt(100)),
    ];

    var data2 = [
      OrdinalSales('2011', random.nextInt(100)),
      OrdinalSales('2012', random.nextInt(100)),
      OrdinalSales('2013', random.nextInt(100)),
      OrdinalSales('2014', random.nextInt(100)),
      OrdinalSales('2015', random.nextInt(100)),
      OrdinalSales('2016', random.nextInt(100)),
      OrdinalSales('2017', random.nextInt(100)),
      OrdinalSales('2018', random.nextInt(100)),
    ];

    var data3 = [
      OrdinalSales('2011', random.nextInt(100)),
      OrdinalSales('2012', random.nextInt(100)),
      OrdinalSales('2013', random.nextInt(100)),
      OrdinalSales('2014', random.nextInt(100)),
      OrdinalSales('2015', random.nextInt(100)),
      OrdinalSales('2016', random.nextInt(100)),
      OrdinalSales('2017', random.nextInt(100)),
      OrdinalSales('2018', random.nextInt(100)),
    ];

    var seriesList = [
      charts.Series<OrdinalSales, String>(
        id: 'Sales1',
        colorFn: (_, __) => charts.ColorUtil.fromDartColor(Color(0xFFE41E31)),
        domainFn: (OrdinalSales sales, _) => sales.year,
        measureFn: (OrdinalSales sales, _) => sales.sales,
        labelAccessorFn: (OrdinalSales sales, _) => "${sales.sales}", //柱体最上边数字
        data: data1,
      ),
      charts.Series<OrdinalSales, String>(
        id: 'Sales2',
        colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, //柱体颜色
        domainFn: (OrdinalSales sales, _) => sales.year,
        measureFn: (OrdinalSales sales, _) => sales.sales,
        labelAccessorFn: (OrdinalSales sales, _) => "${sales.sales}",
        data: data2,
      ),
      charts.Series<OrdinalSales, String>(
        id: 'Sales3',
        colorFn: (_, __) => charts.MaterialPalette.yellow.shadeDefault,
        domainFn: (OrdinalSales sales, _) => sales.year,
        measureFn: (OrdinalSales sales, _) => sales.sales,
        labelAccessorFn: (OrdinalSales sales, _) => "${sales.sales}", //柱体最上边数字
        data: data3,
      ),
    ];

    ///左右滑动
    return charts.BarChart(
      seriesList, //数据
      animate: true, //动画
      behaviors: [
        charts.SlidingViewport(), //滑动窗口
        charts.PanAndZoomBehavior(), //平移和缩放行为
        //显示说明时的字体大小和颜色
        new charts.SeriesLegend(
          entryTextStyle: charts.TextStyleSpec(
            fontSize: 12,
            color: charts.Color.black,
          ),
        ),
      ],
      barGroupingType: charts.BarGroupingType.stacked, //多个数据时的展示方式 // stacked:上下多组 //grouped左右多组
      barRendererDecorator: new charts.BarLabelDecorator<String>(), //显示柱头文本
      domainAxis: new charts.OrdinalAxisSpec(viewport: new charts.OrdinalViewport('2011', 4)), //从2011,显示四个,其他隐藏
      vertical: true, //true:垂直展示,false:水平展示
    );
  }
}

class OrdinalSales {
  final String year;
  final int sales;

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

4

import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';
import 'package:imes_base_plugins/common/logs.dart';

import 'chart_histogram_model.dart';

///柱状图
class ChartHistogramWidget extends StatefulWidget {
  final String title; //从哪来的
  final List<String> names; //说明
  final Map<String, Color> nameColorMap; //说明-颜色 对照表
  final List<List<OrdinalSales>> data; //数据
  final bool vertical; //true:垂直展示,false:水平展示
  final bool animate; //true:开启动画,false:关闭动画
  final bool sliding; //true:开启滑动,false:关闭滑动
  final bool barGroupingType; //true:左右多组展示,false:上下多组展示
  final bool barRendererDecorator; //true:显示柱头文本,隐藏柱头文本
  final String xStart; //从 xStart 显示
  final int xCount; //显示 xCount 个
  final int maxBarWidthPx; //每个柱子的最大宽度

  const ChartHistogramWidget({
    Key key,
    @required this.title,
    @required this.names,
    @required this.nameColorMap,
    @required this.data,
    this.vertical = true,
    this.animate = true,
    this.sliding = true,
    this.barGroupingType = true,
    this.barRendererDecorator = true,
    this.xStart,
    this.xCount,
    this.maxBarWidthPx = 36,
  }) : super(key: key);

  @override
  State<ChartHistogramWidget> createState() => _ChartHistogramWidgetState();
}

class _ChartHistogramWidgetState extends State<ChartHistogramWidget> {
  //数据
  List<charts.Series<OrdinalSales, String>> _seriesList = [];

  ///initState
  @override
  void initState() {
    super.initState();
    logs("进入: ${widget.title}-图表");
    _seriesList = _getSeriesList(widget.data ?? []);
  }

  ///dispose
  @override
  void dispose() {
    logs("结束: ${widget.title}-图表");
    super.dispose();
  }

  ///build
  @override
  Widget build(BuildContext context) {
    logs("柱状图--说明: ${widget.names}");
    logs("名字颜色对照: ${widget.nameColorMap}");
    logs("数据: $_seriesList");
    return charts.BarChart(
      _seriesList, //数据
      animate: widget.animate, //动画
      //行为
      behaviors: widget.sliding
          ? [
              charts.SlidingViewport(), //滑动窗口
              charts.PanAndZoomBehavior(), //平移和缩放行为
              //显示说明时的字体大小和颜色
              // new charts.SeriesLegend(
              //   entryTextStyle: charts.TextStyleSpec(fontSize: 12, color: charts.Color.black),
              // ),
            ]
          : [],
      //多数据展示方式 stacked:上下多组 grouped左右多组
      barGroupingType: widget.barGroupingType ? charts.BarGroupingType.grouped : charts.BarGroupingType.stacked,
      //显示柱头文本
      barRendererDecorator: widget.barRendererDecorator ? charts.BarLabelDecorator<String>() : null,
      //从 xStart 显示,显示 xCount 个
      domainAxis: charts.OrdinalAxisSpec(
        viewport: charts.OrdinalViewport(widget.xStart ?? widget.data[0][0].x, widget.xCount ?? widget.data[0].length),
      ),
      //true:垂直展示,false:水平展示
      vertical: widget.vertical,
      //渲染器-设置外形
      defaultRenderer: charts.BarRendererConfig<String>(
        //多数据展示方式 stacked:上下多组 grouped左右多组
        groupingType: widget.barGroupingType ? charts.BarGroupingType.grouped : charts.BarGroupingType.stacked,
        //每个柱子的最大宽度
        maxBarWidthPx: widget.maxBarWidthPx,
        //
        barRendererDecorator: charts.BarLabelDecorator<String>(),
      ),
    );
  }

  //数据...

  ///获取 seriesList
  _getSeriesList(List<List<OrdinalSales>> data) {
    //空
    List<charts.Series<OrdinalSales, String>> newList = [];
    //遍历
    for (int i = 0; i < data.length; i++) {
      //创建series
      var series = charts.Series<OrdinalSales, String>(
        id: widget.names[i],
        colorFn: (_, __) => charts.ColorUtil.fromDartColor(widget.nameColorMap[widget.names[i]]), // 每个柱体的颜色
        domainFn: (OrdinalSales sales, _) => sales.x, //x轴
        measureFn: (OrdinalSales sales, _) => sales.y, //y轴
        labelAccessorFn: (OrdinalSales sales, _) => "${sales.y}", //显示柱头文本
        data: data[i], //数据
      );
      //添加
      newList.add(series);
    }
    return newList;
  }
}


///数据模型
class OrdinalSales {
  final String x;
  final int y;

  OrdinalSales(this.x, this.y);
}

参考:
https://www.jianshu.com/p/75f112d54028

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352