Reputation: 343
I would like to create line chart together with stacked bar for flutter. Anyone knows which library can I use? Could not find it in charts_flutter.
Thanks.
Upvotes: 0
Views: 3841
Reputation: 327
I took the code from OrdinalComboBarLineChart and replaced it with charts.BarGroupingType.stacked
as suggested by speedlight.
I my case I did not need to specify a secondary axis.
/// Example of an ordinal combo chart with two series rendered as stacked bars, and a
/// third rendered as a line.
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.stacked),
// 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);
}
Then I created a flutter app and put the OrdinalComboBarLineChart.withSampleData()
as the child of an expanded widget. It worked perfectly.
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class HomePage extends StatefulWidget {
static const String id ='/StackedBarLineExample';
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String myMessageText = '';
@override
Widget build(BuildContext context) {
//print ('logged in screen built');
return MaterialApp(
home: DefaultTabController(
length: 1,
initialIndex: int.parse(myLastSelectedPhase),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
bottom: TabBar(
indicatorColor: Colors.white,
tabs: [
Tab(
icon: Icon(FontAwesomeIcons.chartBar)
),
],
),
title: Text('My Graph examples'),
),
body:
TabBarView(
children: [
Padding(
padding: EdgeInsets.all(8.0),
child: Container(
child: Center(
child: Column(
children: <Widget>[
Text(
'Stacked bar with line', style: TextStyle(
fontSize: 24.0, fontWeight: FontWeight.bold),),
Expanded(
child: OrdinalComboBarLineChart.withSampleData())
],
),
),
),
),
]
),
),
),
);
}
}
This is the result!
Upvotes: 1
Reputation: 343
By using Ordinal Bar Line Combo Chart, I am able to achieve what I need.
https://google.github.io/charts/flutter/example/combo_charts/ordinal_bar_line.html
Next, change the grouping type to "charts.BarGroupingType.groupedStacked", groupedStacked option with change the bar chart to stacked bar.
Bar chart and line chart has 2 vertical axis, by default, there is only primary axis from the bar chart. You will need to specify secondary axis or else the chart display for stackedbar and line chart will be out.
declare -> static const secondaryMeasureAxisId = 'secondaryMeasureAxisId';
and add "..setAttribute(charts.measureAxisIdKey, 'secondaryMeasureAxisId')," to your linechart.
Lastly, if you have many data, more than 30 like mine. The text under horizontal axis (domain axis) will be overlapping. I cannot find any shortcuts to reduce it. The method I used so far is to declare a new domain axis.
Under build:
final staticTicks = <charts.TickSpec<String>>[];
if(xxx){
staticTicks.add(xxx);
}
domainAxis: new charts.OrdinalAxisSpec(
tickProviderSpec:
new charts.StaticOrdinalTickProviderSpec(staticTicks)),
Upvotes: 0
Reputation: 837
This seems to be the highest rated package for flutter that can handle both graph types. Be careful with questions like this on Stack Overflow though because it is considered a question of opinion.
flutter_charts: https://pub.dev/packages/flutter_charts
Upvotes: 0