Flutter中的資料視覺化charts家族

洋小洋同學發表於2019-12-27

本文系列

  • 洋小洋週五分享
  • Flutter技術

由於在實際開發的過程中,過多的業務模組都是資料視覺化,圖表很多,一個模組過久的時間花費我個人覺得不太好,那目前就我來看,在Flutter家族中暫時還沒有Web端像Echars這樣的輔助,那本篇章就和大家分享一下線圖,也叫line charts ,這其中又會分為折線圖、曲線圖又或者雙重曲線。那接下來就當聽故事一樣....

003.png

故事開頭

其實在圖表的眾多外掛之中呢,就像下圖所示,

001.png

開發一個外掛一個包有個很完善的文件對於開發者來說是十分友好的,不過google倉庫下有個圖表庫,是關於Flutter相關的,雖然還未有很完善的文件,但我個人覺得,它還是最值得入手的

故事過程

當我們有個需求是讓用圖表處理資料的話,如果UI是相對來說比較簡約的,那官方維護的外掛是再適合不過,然而我看也有一段時間沒有更新,最新的版本依舊

  • 版本 V0.8.1

首先我們的瞭解這幾個

其實在這個圖表庫中實現效果有兩種方式

方式一

通過官方的示例,在呼叫的時候

return Container(height: height, child: SimpleLineChart.withSampleData());
複製程式碼

通過點方法的形式,這也是示例中的使用方式,舉個例子,以線圖為例

/// Example of a simple line chart.
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

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

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

  /// Creates a [LineChart] with sample data and no transition.
  factory SimpleLineChart.withSampleData() {
    return new SimpleLineChart(
      _createSampleData(),
      // Disable animations for image tests.
      animate: false,
    );
  }
  _onSelectionChanged(charts.SelectionModel model) {
    final selectedDatum = model.selectedDatum;
    print(selectedDatum.first.datum.year);
    print(selectedDatum.first.datum.sales);
    print(selectedDatum.first.series.displayName);
  }

  @override
  Widget build(BuildContext context) {
    return new charts.LineChart(
      seriesList,
      animate: animate,
      defaultRenderer: charts.LineRendererConfig(
        // 折線圖繪製的配置
        includeArea: true,
        includePoints: true,
        includeLine: true,
        stacked: false,
      ),
      domainAxis: charts.NumericAxisSpec(
        // // 主軸的配置
        // tickFormatterSpec: DomainFormatterSpec(
        //     widget.dateRange), // tick 值的格式化,這裡把 num 轉換成 String
        renderSpec: charts.SmallTickRendererSpec(
          // 主軸繪製的配置
          tickLengthPx: 0, // 刻度標識突出的長度
          labelOffsetFromAxisPx: 12, // 刻度文字距離軸線的位移
          labelStyle: charts.TextStyleSpec(
              // 刻度文字的樣式
              // color: ChartUtil.getChartColor(HColors.lightGrey),
              // fontSize: HFontSizes.smaller.toInt(),
              ),
          axisLineStyle: charts.LineStyleSpec(
              // 軸線的樣式
              // color: ChartUtil.getChartColor(ChartUtil.lightBlue),
              ),
        ),
        tickProviderSpec: charts.BasicNumericTickProviderSpec(
          // 軸線刻度配置
          dataIsInWholeNumbers: false,
          // desiredTickCount: widget.data.length, // 期望顯示幾個刻度
        ),
      ),
      primaryMeasureAxis: charts.NumericAxisSpec(
        // 交叉軸的配置,引數參考主軸配置
        showAxisLine: false, // 顯示軸線
        // tickFormatterSpec: MeasureFormatterSpec(),
        tickProviderSpec: charts.BasicNumericTickProviderSpec(
          dataIsInWholeNumbers: false,
          desiredTickCount: 4,
        ),
        renderSpec: charts.GridlineRendererSpec(
          // 交叉軸刻度水平線
          tickLengthPx: 0,
          labelOffsetFromAxisPx: 12,
          labelStyle: charts.TextStyleSpec(
              // color: ChartUtil.getChartColor(HColors.lightGrey),
              // fontSize: HFontSizes.smaller.toInt(),
              ),
          lineStyle: charts.LineStyleSpec(
              // color: ChartUtil.getChartColor(ChartUtil.lightBlue),
              ),
          axisLineStyle: charts.LineStyleSpec(
              // color: ChartUtil.getChartColor(ChartUtil.lightBlue),
              ),
        ),
      ),
      selectionModels: [
        // 設定點選選中事件
        charts.SelectionModelConfig(
          type: charts.SelectionModelType.info,
          changedListener: _onSelectionChanged,
        )
      ],
      behaviors: [
        charts.InitialSelection(selectedDataConfig: [
          // 設定預設選中
          charts.SeriesDatumConfig<num>('LineChart', 2)
        ]),
      ],
    );
  }

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

    return [
      new charts.Series<LinearSales, int>(
        id: 'Sales',
        colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
        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);
}

複製程式碼

以上的程式碼包含自定義的部分,完整我會同步到倉庫傳送門

方式二

這種方式就是直接傳入不同圖表需要的配置項就可


 Container(
            width: double.infinity,
            height: 200.0,
            child: charts.BarChart(
              //通過下面獲取資料傳入
              ChartFlutterBean.createSampleData(),
              //配置項,以及設定觸發的函式
              selectionModels: [
                charts.SelectionModelConfig(
                  type: charts.SelectionModelType.info,
                  changedListener: _onSelectionChanged,
                )
              ],
            ),
複製程式碼

其中比較核心的部分便是,點選事件,也就是說不管是條形圖也好,這裡推薦看下我的另一篇文章,也有分享到圖表相關的,d點選事件就是在selectionModels 這裡放著,但是我們又不能像平常寫點選事件那樣

006.png

我們點選去看一下原始碼charts.SelectionModelConfig




import 'package:meta/meta.dart' show immutable;

import 'package:charts_common/common.dart' as common;

@immutable
class SelectionModelConfig<D> {
  final common.SelectionModelType type;

  /// Listens for change in selection.
  final common.SelectionModelListener<D> changedListener;

  /// Listens anytime update selection is called.
  final common.SelectionModelListener<D> updatedListener;

  SelectionModelConfig(
      {this.type = common.SelectionModelType.info,
      this.changedListener,
      this.updatedListener});
}

複製程式碼

我們可以看到是有兩個事件的,那這時候我們也事件就可以取到值了

 _onSelectionChanged(charts.SelectionModel model) {
    final selectedDatum = model.selectedDatum;
    print(selectedDatum.first.datum.year);
    print(selectedDatum.first.datum.sales);
    print(selectedDatum.first.series.displayName);
  }

複製程式碼

故事結尾

特別感謝你能讀到這兒,今天特別開心的一事兒,

004.png

特別感謝


Although the article is here, your fate has just begun

相關文章