概要
棒グラフと折れ線グラフをオーバーラップしたグラフが必要とのことで
Flutterでグラフ描画を調べてみたところ
chart_flutter
を使えばいいらしいので調査
これこれ、このグラフが欲しいんよ!
というわけで、サンプルコードがあったので、早速試してみました。
サンプルコード
Example
/// Example of an ordinal combo chart with two series rendered as bars, and a
/// third rendered as a line.
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class OrdinalComboBarLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
OrdinalComboBarLineChart(this.seriesList, {this.animate});
factory OrdinalComboBarLineChart.withSampleData() {
return new OrdinalComboBarLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
@override
Widget build(BuildContext context) {
return new charts.OrdinalComboChart(seriesList,
animate: animate,
// Configure the default renderer as a bar renderer.
defaultRenderer: new charts.BarRendererConfig(
groupingType: charts.BarGroupingType.grouped),
// Custom renderer configuration for the line series. This will be used for
// any series that does not define a rendererIdKey.
customSeriesRenderers: [
new charts.LineRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customLine')
]);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 200),
new OrdinalSales('2017', 150),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Mobile ',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData)
// Configure our custom line renderer for this series.
..setAttribute(charts.rendererIdKey, 'customLine'),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}
動かしてみる
サクッとビルドエラー
なんか対象になってるDartsの仕様が古いっぽいですね...
というわけで、修正してみましたよ
修正結果
CorrectedExample
/// Example of an ordinal combo chart with two series rendered as bars, and a
/// third rendered as a line.
// ignore_for_file: use_key_in_widget_constructors
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class OrdinalComboBarLineChart extends StatelessWidget {
final List<charts.Series<dynamic, String>> seriesList;
final bool animate;
const OrdinalComboBarLineChart(this.seriesList, {this.animate = false});
factory OrdinalComboBarLineChart.withSampleData() {
return OrdinalComboBarLineChart(
_createSampleData(),
animate: false,
);
}
@override
Widget build(BuildContext context) {
return charts.OrdinalComboChart(seriesList,
animate: animate,
// Configure the default renderer as a bar renderer.
defaultRenderer: charts.BarRendererConfig(
groupingType: charts.BarGroupingType.grouped),
// Custom renderer configuration for the line series. This will be used for
// any series that does not define a rendererIdKey.
customSeriesRenderers: [
charts.LineRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customLine')
]);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
OrdinalSales('2014', 5),
OrdinalSales('2015', 25),
OrdinalSales('2016', 100),
OrdinalSales('2017', 75),
];
final tableSalesData = [
OrdinalSales('2014', 5),
OrdinalSales('2015', 25),
OrdinalSales('2016', 100),
OrdinalSales('2017', 75),
];
final mobileSalesData = [
OrdinalSales('2014', 10),
OrdinalSales('2015', 50),
OrdinalSales('2016', 200),
OrdinalSales('2017', 150),
];
return [
charts.Series<OrdinalSales, String>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData),
charts.Series<OrdinalSales, String>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData),
charts.Series<OrdinalSales, String>(
id: 'Mobile ',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData)
// Configure our custom line renderer for this series.
..setAttribute(charts.rendererIdKey, 'customLine'),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}
ちなみに main はこんな感じで。(抜粋)
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: OrdinalComboBarLineChart.withSampleData(),
);
}
}
今度こそ動かしてみる
Webでも問題なく動きました。
解説
やったこと
- OrdinalComboBarLineChart クラスのコンストラクタに animate の Default値の設定を追加。
- seriesList のテンプレートを明示的に記述
- // ignore_for_file: use_key_in_widget_constructors を追加 ←もっと良い方法ありそう
- インスタンス生成時の new の削除
感想
公式のサンプルが動かないとかやめて欲しいわ〜〜
q(〃・`з・´〃)p モ─ッ!!