charts_flutter: ^0.10.0

先看图片

在这里插入图片描述

要是需要柱状图支持左右滚动的可以看官方案例,若是想看中文解释的可以看这篇文章,因为有这篇文章所以我这边也只是展示部分配置文件代码。

解决问题:

1.支持左右滚动
behaviors: [
          new charts.SlidingViewport(),
          new charts.PanAndZoomBehavior(),
        ],
        //配置初始状态展示个数
domainAxis: new charts.NumericAxisSpec(
   viewport: new charts.NumericExtents(0, 6)
),

2.横坐标自定义代码

因为line 横坐标默认返回的数据是 num 类型的,我是将x轴的数据提前放到一个数组内,然后通过有序数组取出对应数据。

 domainAxis: new charts.NumericAxisSpec(
 			charts.BasicNumericTickFormatterSpec((val) {
              return "${val}点";
           })),
3.自定义tooltip

目前版本应该是不支持触碰某个节点,如下图显示对应数据。不过在issues上有大佬讨论出暂时的解决方案,有兴趣的可以去看看issues 。要是显示各点数据是个特别重要的功能,还是换个插件类似fl_chart,不过这个好像是不支持左右滚动的😂😂。在这里插入图片描述

完整代码

line模块我做了简单的分装还不够完善,上述的配置项位置在代码中都有体现,不过这边代码是为了本人自己寻找方便!!

import 'dart:math';

import 'package:charts_flutter/flutter.dart';
import 'package:flutter/material.dart';
import 'package:charts_flutter/src/text_element.dart' as textElement;
import 'package:charts_flutter/src/text_style.dart' as style;
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

class ChartFlutterLine extends StatefulWidget {
  final List<charts.Series> seriesList;
  final bool animate;
  List xAxisData; //x轴数据
  int viewportCount;
  ChartFlutterLine(
    this.seriesList, {
    this.animate,
    this.xAxisData,
    this.viewportCount = 6,
  });

  /// Creates a [LineChart] with sample data and no transition.
  factory ChartFlutterLine.withSampleData(chartData) {
    return new ChartFlutterLine(
      _createSampleData(chartData["seriesData"]),
      // Disable animations for image tests.
      animate: chartData["animate"] ?? false,
      xAxisData: chartData["xAxisData"],
      viewportCount: chartData["viewportCount"],
    );
  }

  /// Create one series with sample hard coded data.
  static List<charts.Series<LinearSales, int>> _createSampleData(
      Map<String, List<List>> seriesData) {
    List<Color> colors = [
      charts.MaterialPalette.blue.shadeDefault,
      charts.MaterialPalette.red.shadeDefault,
      charts.MaterialPalette.purple.shadeDefault,
      charts.MaterialPalette.cyan.shadeDefault,
      charts.MaterialPalette.yellow.shadeDefault,
      charts.MaterialPalette.deepOrange.shadeDefault,
      charts.MaterialPalette.lime.shadeDefault,
      charts.MaterialPalette.indigo.shadeDefault,
      charts.MaterialPalette.pink.shadeDefault,
      charts.MaterialPalette.teal.shadeDefault,
      charts.MaterialPalette.gray.shadeDefault,
    ];

    List<charts.Series<LinearSales, int>> data = [];

    List _keys = seriesData.keys.toList();
    int _len = seriesData.length;

    for (int i = 0; i < _len; i++) {
      int _xAxisindex = 0;
      List<LinearSales> itemData = [];
      seriesData[_keys[i]].forEach((item) {
        itemData.add(new LinearSales(index: _xAxisindex, sales: item[1]));
        _xAxisindex++;
      });
      // print("xAxis:${xAxis}");
      int _colorLen = colors.length;
      data.add(new charts.Series<LinearSales, int>(
        id: _keys[i],
        colorFn: (_, __) => colors[i % _colorLen],
        domainFn: (LinearSales sales, _) => sales.index,
        measureFn: (LinearSales sales, _) => sales.sales,
        data: itemData,
        // keyFn: (LinearSales row, _) => '${row.sales}%',
      ));
    }
    return data;
  }

  @override
  _ChartFlutterLineState createState() => _ChartFlutterLineState();
}

class _ChartFlutterLineState extends State<ChartFlutterLine> {
  Map _data = {}; //tootlip显示数据

  @override
  Widget build(BuildContext context) {
    return new charts.LineChart(widget.seriesList,
        domainAxis: new charts.NumericAxisSpec(
            viewport: new charts.NumericExtents(0, widget.viewportCount ?? 6),
            tickFormatterSpec: charts.BasicNumericTickFormatterSpec((val) {
              int _len = widget.xAxisData.length;
              // print("widget.xAxisData:${widget.xAxisData}");
              if (widget.xAxisData != null &&
                  _len > 0 &&
                  _len > val.round() &&
                  val.round() >= 0) {
                return "${widget.xAxisData[val.round()] ?? val}";
              }
              return "";
            })),
        defaultRenderer: new charts.LineRendererConfig(
          includeArea: true,
          // stacked: true,
        ),
        behaviors: [
          new charts.SlidingViewport(),
          new charts.PanAndZoomBehavior(),
          new charts.SeriesLegend(
              // horizontalFirst: false,
              // desiredMaxRows: 2,
              cellPadding: new EdgeInsets.only(right: 4.0, top: 1, bottom: 1),
              entryTextStyle: charts.TextStyleSpec(fontSize: 10),
              position: charts.BehaviorPosition.bottom),
          charts.LinePointHighlighter(
              symbolRenderer: CustomCircleSymbolRenderer(data: _data))
        ],
        selectionModels: [
          charts.SelectionModelConfig(
              type: charts.SelectionModelType.info,
              changedListener: (charts.SelectionModel model) {
                if (model.hasDatumSelection) {
                  int _len = widget.seriesList.length;
                  Map _seleted = {};
                  for (int i = 0; i < _len; i++) {
                    _seleted.addAll({
                      widget.seriesList[i].id: widget.seriesList[i]
                          .measureFn(model.selectedDatum[0].index)
                    });
                  }
                  _data.addAll({"seleted": _seleted});
                }
              })
        ],
        animate: widget.animate);
  }
}

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

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

class CustomCircleSymbolRenderer extends CircleSymbolRenderer {
  final data;
  CustomCircleSymbolRenderer({this.data});
  @override
  void paint(ChartCanvas canvas, Rectangle<num> bounds,
      {List<int> dashPattern,
      Color fillColor,
      FillPatternType fillPattern,
      Color strokeColor,
      double strokeWidthPx}) {
    super.paint(canvas, bounds,
        dashPattern: dashPattern,
        fillColor: fillColor,
        strokeColor: strokeColor,
        strokeWidthPx: strokeWidthPx);
    // print("bounds.left:${bounds.left}");
    // print("data:${data}");
    Map _seleted = data["seleted"];
    int _len = _seleted.length;
    List _valList = _seleted.values.toList();
    List _keysList = _seleted.keys.toList();
    canvas.drawRect(
        Rectangle(bounds.left < 250 ? 240 : 20, 0, 100, 18 * _len + 15),
        fill: Color(r: 0, g: 0, b: 0, a: 30));
    for (int i = 0; i < _len; i++) {
      var textStyle = style.TextStyle();
      textStyle.color = Color.black;
      textStyle.fontSize = 12;

      canvas.drawText(
          textElement.TextElement(
            _keysList[i] + " " + _valList[i].toString(),
            style: textStyle,
          ),
          bounds.left < 250 ? 245 : 25,
          i * 18 + 10);
    }
  }
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐