Table of Contents
- Examples with code
- ex10RandomData_lineChart
- ex10RandomData_verticalBarChart
- ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart
- ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart
- ex31SomeNegativeValues_lineChart
- ex31SomeNegativeValues_verticalBarChart
- ex32AllPositiveYsYAxisStartsAbove0_lineChart
- ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart
- ex33AllNegativeYsYAxisEndsBelow0_lineChart
- ex34OptionsDefiningUserTextStyleOnLabels_lineChart
- ex35AnimalsBySeasonNoLabelsShown_lineChart
- ex35AnimalsBySeasonNoLabelsShown_verticalBarChart
- ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart
- ex50StocksWithNegativesWithUserColors_verticalBarChart
- ex52AnimalsBySeasonLogarithmicScale_lineChart
- ex52AnimalsBySeasonLogarithmicScale_verticalBarChart
- ex60LabelsIteration1_verticalBarChart
- ex60LabelsIteration2_verticalBarChart
- ex60LabelsIteration3_verticalBarChart
- ex60LabelsIteration4_verticalBarChart
- ex900ErrorFixUserDataAllZero_lineChart
- Latest release changes
- Installation
- Running the examples included in flutter_charts
- Illustration of the "iterative auto layout" feature
- Known packages, libraries and apps that use this flutter_charts package
- Todos
- Internal notes for exporting this document
Examples with code
This section contains sample charts from flutter_charts, with code that generated the charts. The code for each chart is in a method
Widget chartToRun() {
// .. code which generates the sample chart
}
To quickly test the code, you can paste the method chartToRun()
into the sample main app provided in github.com/mzimmerm/flutter_charts/blob/master/example/lib/main_run_doc_example.dart.
ex10RandomData_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows a demo-type data generated randomly in a range.
chartData = RandomChartData.generated(chartOptions: chartOptions);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex10RandomData_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows a demo-type data generated randomly in a range.
chartData = RandomChartData.generated(chartOptions: chartOptions);
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows an explicit use of the DefaultIterativeLabelLayoutStrategy.
// The xContainerLabelLayoutStrategy, if set to null or not set at all,
// defaults to DefaultIterativeLabelLayoutStrategy
// Clients can also create their own LayoutStrategy.
xContainerLabelLayoutStrategy = DefaultIterativeLabelLayoutStrategy(
options: chartOptions,
);
chartData = ChartData(
dataRows: const [
[10.0, 20.0, 5.0, 30.0, 5.0, 20.0],
[30.0, 60.0, 16.0, 100.0, 12.0, 120.0],
[25.0, 40.0, 20.0, 80.0, 12.0, 90.0],
[12.0, 30.0, 18.0, 40.0, 10.0, 30.0],
],
xUserLabels: const ['Wolf', 'Deer', 'Owl', 'Mouse', 'Hawk', 'Vole'],
dataRowsLegends: const [
'Spring',
'Summer',
'Fall',
'Winter',
],
chartOptions: chartOptions,
);
// chartData.dataRowsDefaultColors(); // if not set, called in constructor
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows an explicit use of the DefaultIterativeLabelLayoutStrategy.
// The xContainerLabelLayoutStrategy, if set to null or not set at all,
// defaults to DefaultIterativeLabelLayoutStrategy
// Clients can also create their own LayoutStrategy.
xContainerLabelLayoutStrategy = DefaultIterativeLabelLayoutStrategy(
options: chartOptions,
);
chartData = ChartData(
dataRows: const [
[10.0, 20.0, 5.0, 30.0, 5.0, 20.0],
[30.0, 60.0, 16.0, 100.0, 12.0, 120.0],
[25.0, 40.0, 20.0, 80.0, 12.0, 90.0],
[12.0, 30.0, 18.0, 40.0, 10.0, 30.0],
],
xUserLabels: const ['Wolf', 'Deer', 'Owl', 'Mouse', 'Hawk', 'Vole'],
dataRowsLegends: const [
'Spring',
'Summer',
'Fall',
'Winter',
],
chartOptions: chartOptions,
);
// chartData.dataRowsDefaultColors(); // if not set, called in constructor
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex31SomeNegativeValues_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows a mix of positive and negative data values.
chartData = ChartData(
dataRows: const [
[2000.0, 1800.0, 2200.0, 2300.0, 1700.0, 1800.0],
[1100.0, 1000.0, 1200.0, 800.0, 700.0, 800.0],
[0.0, 100.0, -200.0, 150.0, -100.0, -150.0],
[-800.0, -400.0, -300.0, -400.0, -200.0, -250.0],
],
xUserLabels: const ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
dataRowsLegends: const [
'Big Corp',
'Medium Corp',
'Print Shop',
'Bar',
],
chartOptions: chartOptions,
);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex31SomeNegativeValues_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows a mix of positive and negative data values.
chartData = ChartData(
dataRows: const [
[2000.0, 1800.0, 2200.0, 2300.0, 1700.0, 1800.0],
[1100.0, 1000.0, 1200.0, 800.0, 700.0, 800.0],
[0.0, 100.0, -200.0, 150.0, -100.0, -150.0],
[-800.0, -400.0, -300.0, -400.0, -200.0, -250.0],
],
xUserLabels: const ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
dataRowsLegends: const [
'Big Corp',
'Medium Corp',
'Print Shop',
'Bar',
],
chartOptions: chartOptions,
);
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex32AllPositiveYsYAxisStartsAbove0_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows how to create ChartOptions instance
// which will request to start Y axis at data minimum.
// Even though startYAxisAtDataMinRequested is set to true, this will not be granted on bar chart,
// as it does not make sense there.
chartOptions = const ChartOptions(
dataContainerOptions: DataContainerOptions(
startYAxisAtDataMinRequested: true,
),
);
chartData = ChartData(
dataRows: const [
[20.0, 25.0, 30.0, 35.0, 40.0, 20.0],
[35.0, 40.0, 20.0, 25.0, 30.0, 20.0],
],
xUserLabels: const ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
dataRowsLegends: const [
'Off zero 1',
'Off zero 2',
],
chartOptions: chartOptions,
);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows how to create ChartOptions instance
// which will request to start Y axis at data minimum.
// Even though startYAxisAtDataMinRequested is set to true, this will not be granted on bar chart,
// as it does not make sense there.
chartOptions = const ChartOptions(
dataContainerOptions: DataContainerOptions(
startYAxisAtDataMinRequested: true,
),
);
chartData = ChartData(
dataRows: const [
[20.0, 25.0, 30.0, 35.0, 40.0, 20.0],
[35.0, 40.0, 20.0, 25.0, 30.0, 20.0],
],
xUserLabels: const ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
dataRowsLegends: const [
'Off zero 1',
'Off zero 2',
],
chartOptions: chartOptions,
);
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex33AllNegativeYsYAxisEndsBelow0_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows how to create ChartOptions instance
// which will request to end Y axis at maximum data (as all data negative).
// Even though startYAxisAtDataMinRequested is set to true, this will not be granted on bar chart,
// as it does not make sense there.
chartOptions = const ChartOptions(
dataContainerOptions: DataContainerOptions(
startYAxisAtDataMinRequested: true,
),
);
chartData = ChartData(
dataRows: const [
[-20.0, -25.0, -30.0, -35.0, -40.0, -20.0],
[-35.0, -40.0, -20.0, -25.0, -30.0, -20.0],
],
xUserLabels: const ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
dataRowsLegends: const [
'Off zero 1',
'Off zero 2',
],
chartOptions: chartOptions,
);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex34OptionsDefiningUserTextStyleOnLabels_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example shows how to use user-defined font in the chart labels.
// In fact, same approach can be used more generally, to set any property
// in user-defined TextStyle (font, font color, etc - any property available on TextStyle) on labels.
// To achieve setting custom fonts and/or any member of TextStyle,
// client can declare their own extension of 'LabelCommonOptions', and override the `labelTextStyle` getter.
// A sample declaration of the class MyLabelCommonOptions, is given here as a comment.
// ```dart
// /// An example user-defined extension of [LabelCommonOptions] overrides the [LabelCommonOptions.labelTextStyle]
// /// which is the source for user-specific font on labels.
// class MyLabelCommonOptions extends LabelCommonOptions {
// const MyLabelCommonOptions(
// ) : super ();
//
// /// Override [labelTextStyle] with a new font, color, etc.
// @override
// get labelTextStyle => GoogleFonts.comforter(
// textStyle: const TextStyle(
// color: ui.Color(0xFF757575),
// fontSize: 14.0,
// fontWeight: FontWeight.w400, // Regular
// ),
// );
//
// /* This alternative works in an app as well, but not in the integration test. All style set in options defaults.
// get labelTextStyle =>
// const ChartOptions().labelCommonOptions.labelTextStyle.copyWith(
// fontFamily: GoogleFonts.comforter().fontFamily,
// );
// */
// }
// ```
// Given such extended class, declare ChartOptions as follows:
chartOptions = const ChartOptions(
labelCommonOptions: MyLabelCommonOptions(),
);
// Then proceed as usual
chartData = ChartData(
dataRows: const [
[20.0, 25.0, 30.0, 35.0, 40.0, 20.0],
[35.0, 40.0, 20.0, 25.0, 30.0, 20.0],
],
xUserLabels: const ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
dataRowsLegends: const [
'Font Test Series1',
'Font Test Series2',
],
chartOptions: chartOptions,
);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex35AnimalsBySeasonNoLabelsShown_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Set chart options to show no labels
chartOptions = const ChartOptions.noLabels();
chartData = ChartData(
dataRows: const [
[10.0, 20.0, 5.0, 30.0, 5.0, 20.0],
[30.0, 60.0, 16.0, 100.0, 12.0, 120.0],
[25.0, 40.0, 20.0, 80.0, 12.0, 90.0],
[12.0, 30.0, 18.0, 40.0, 10.0, 30.0],
],
xUserLabels: const ['Wolf', 'Deer', 'Owl', 'Mouse', 'Hawk', 'Vole'],
dataRowsLegends: const [
'Spring',
'Summer',
'Fall',
'Winter',
],
chartOptions: chartOptions,
);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex35AnimalsBySeasonNoLabelsShown_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Set chart options to show no labels
chartOptions = const ChartOptions.noLabels();
chartData = ChartData(
dataRows: const [
[10.0, 20.0, 5.0, 30.0, 5.0, 20.0],
[30.0, 60.0, 16.0, 100.0, 12.0, 120.0],
[25.0, 40.0, 20.0, 80.0, 12.0, 90.0],
[12.0, 30.0, 18.0, 40.0, 10.0, 30.0],
],
xUserLabels: const ['Wolf', 'Deer', 'Owl', 'Mouse', 'Hawk', 'Vole'],
dataRowsLegends: const [
'Spring',
'Summer',
'Fall',
'Winter',
],
chartOptions: chartOptions,
);
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// User-Provided Data (Y values), User-Provided X Labels, User-Provided Data Rows Legends, User-Provided Y Labels, User-Provided Colors
// This example shows user defined Y Labels that derive order from data.
// When setting Y labels by user, the dataRows value scale
// is irrelevant. User can use for example interval <0, 1>,
// <0, 10>, or any other, even negative ranges. Here we use <0-10>.
// The only thing that matters is the relative values in the data Rows.
// Current implementation sets
// the minimum of dataRows range (1.0 in this example)
// on the level of the first Y Label ("Low" in this example),
// and the maximum of dataRows range (10.0 in this example)
// on the level of the last Y Label ("High" in this example).
chartData = ChartData(
dataRows: const [
[9.0, 4.0, 3.0, 9.0],
[7.0, 6.0, 7.0, 6.0],
[4.0, 9.0, 6.0, 8.0],
[3.0, 9.0, 10.0, 1.0],
],
xUserLabels: const ['Speed', 'Readability', 'Level of Novel', 'Usage'],
dataRowsColors: const [
Colors.blue,
Colors.yellow,
Colors.green,
Colors.amber,
],
dataRowsLegends: const ['Java', 'Dart', 'Python', 'Newspeak'],
yUserLabels: const [
'Low',
'Medium',
'High',
],
chartOptions: chartOptions,
);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex50StocksWithNegativesWithUserColors_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// User-Provided Data (Y values), User-Provided X Labels, User-Provided Data Rows Legends, Data-Based Y Labels, User-Provided Colors,
// This shows a bug where negatives go below X axis.
// If we want the chart to show User-Provided textual Y labels with
// In each column, adding it's absolute values should add to same number:
// todo-04-examples 100 would make more sense, to represent 100% of stocks in each category. Also columns should add to the same number?
chartData = ChartData(
// each column should add to same number. everything else is relative.
dataRows: const [
[-9.0, -8.0, -8.0, -5.0, -8.0],
[-1.0, -2.0, -4.0, -1.0, -1.0],
[7.0, 8.0, 7.0, 11.0, 9.0],
[3.0, 2.0, 1.0, 3.0, 3.0],
],
xUserLabels: const ['Energy', 'Health', 'Finance', 'Chips', 'Oil'],
dataRowsLegends: const [
'-2% or less',
'-2% to 0%',
'0% to +2%',
'more than +2%',
],
dataRowsColors: const [
Colors.red,
Colors.grey,
Colors.greenAccent,
Colors.black,
],
chartOptions: chartOptions,
);
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex52AnimalsBySeasonLogarithmicScale_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
chartOptions = const ChartOptions(
dataContainerOptions: DataContainerOptions(
yTransform: log10,
yInverseTransform: inverseLog10,
),
);
chartData = ChartData(
dataRows: const [
[10.0, 600.0, 1000000.0],
[20.0, 1000.0, 1500000.0],
],
xUserLabels: const ['Wolf', 'Deer', 'Mouse'],
dataRowsLegends: const [
'Spring',
'Summer',
],
chartOptions: chartOptions,
);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
ex52AnimalsBySeasonLogarithmicScale_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
chartOptions = const ChartOptions(
dataContainerOptions: DataContainerOptions(
yTransform: log10,
yInverseTransform: inverseLog10,
),
);
chartData = ChartData(
dataRows: const [
[10.0, 600.0, 1000000.0],
[20.0, 1000.0, 1500000.0],
],
xUserLabels: const ['Wolf', 'Deer', 'Mouse'],
dataRowsLegends: const [
'Spring',
'Summer',
],
chartOptions: chartOptions,
);
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex60LabelsIteration1_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example with side effects cannot be simply pasted to your code, as the _ExampleSideEffects is private
// This example shows the result with sufficient space to show all labels
chartData = ChartData(
dataRows: const [
[200.0, 190.0, 180.0, 200.0, 250.0, 300.0],
[300.0, 280.0, 260.0, 240.0, 300.0, 350.0],
],
xUserLabels: const ['January', 'February', 'March', 'April', 'May', 'June'],
dataRowsLegends: const [
'Owl count',
'Hawk count',
],
chartOptions: chartOptions,
);
exampleSideEffects = _ExampleSideEffects()..leftSqueezeText=''.. rightSqueezeText='';
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex60LabelsIteration2_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example with side effects cannot be simply pasted to your code, as the _ExampleSideEffects is private
// This example shows the result with sufficient space to show all labels, but not enough to be horizontal;
// The iterative layout strategy makes the labels to tilt but show fully.
chartData = ChartData(
dataRows: const [
[200.0, 190.0, 180.0, 200.0, 250.0, 300.0],
[300.0, 280.0, 260.0, 240.0, 300.0, 350.0],
],
xUserLabels: const ['January', 'February', 'March', 'April', 'May', 'June'],
dataRowsLegends: const [
'Owl count',
'Hawk count',
],
chartOptions: chartOptions,
);
exampleSideEffects = _ExampleSideEffects()..leftSqueezeText='>>'.. rightSqueezeText='<' * 3;
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex60LabelsIteration3_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example with side effects cannot be simply pasted to your code, as the _ExampleSideEffects is private
// This example shows the result with sufficient space to show all labels, not even tilted;
// The iterative layout strategy causes some labels to be skipped.
chartData = ChartData(
dataRows: const [
[200.0, 190.0, 180.0, 200.0, 250.0, 300.0],
[300.0, 280.0, 260.0, 240.0, 300.0, 350.0],
],
xUserLabels: const ['January', 'February', 'March', 'April', 'May', 'June'],
dataRowsLegends: const [
'Owl count',
'Hawk count',
],
chartOptions: chartOptions,
);
exampleSideEffects = _ExampleSideEffects()..leftSqueezeText='>>'.. rightSqueezeText='<' * 6;
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex60LabelsIteration4_verticalBarChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
// Example with side effects cannot be simply pasted to your code, as the _ExampleSideEffects is private
// This example shows the result with sufficient space to show all labels, not even tilted;
// The iterative layout strategy causes more labels to be skipped.
chartData = ChartData(
dataRows: const [
[200.0, 190.0, 180.0, 200.0, 250.0, 300.0],
[300.0, 280.0, 260.0, 240.0, 300.0, 350.0],
],
xUserLabels: const ['January', 'February', 'March', 'April', 'May', 'June'],
dataRowsLegends: const [
'Owl count',
'Hawk count',
],
chartOptions: chartOptions,
);
exampleSideEffects = _ExampleSideEffects()..leftSqueezeText='>>'.. rightSqueezeText='<' * 30;
var verticalBarChartContainer = VerticalBarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var verticalBarChart = VerticalBarChart(
painter: VerticalBarChartPainter(
verticalBarChartContainer: verticalBarChartContainer,
),
);
return verticalBarChart;
}
Result
ex900ErrorFixUserDataAllZero_lineChart
Code
Widget chartToRun() {
LabelLayoutStrategy? xContainerLabelLayoutStrategy;
ChartData chartData;
ChartOptions chartOptions = const ChartOptions();
/// Currently, setting [ChartDate.dataRows] requires to also set all of
/// [chartData.xUserLabels], [chartData.dataRowsLegends], [chartData.dataRowsColors]
// Fix was: Add default legend to ChartData constructor AND fix scaling util_dart.dart scaleValue.
chartData = ChartData(
dataRows: const [
[0.0, 0.0, 0.0],
],
// Note: When ChartData is defined,
// ALL OF xUserLabels, dataRowsLegends, dataRowsColors
// must be set by client
xUserLabels: const ['Wolf', 'Deer', 'Mouse'],
dataRowsLegends: const [
'Row 1',
],
dataRowsColors: const [
Colors.blue,
],
chartOptions: chartOptions,
);
var lineChartContainer = LineChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);
var lineChart = LineChart(
painter: LineChartPainter(
lineChartContainer: lineChartContainer,
),
);
return lineChart;
}
Result
Latest release changes
The latest release is 0.5.0
The <CHANGELOG.md> document describes new features and bug fixes in this and older versions.
Installation
Installing flutter_charts as a library package into your app
If you want to use the flutter_charts
library package in your app, please follow instructions in pub.dev/packages/flutter_charts/install. This will result in ability of your app to use flutter_charts
.
Installing the flutter_charts project as a local clone from Github
The advantage of installing the source of the flutter_charts
project locally from Github is that you can run the packaged example application and also run the integration and widget tests.
To install (clone) the flutter_charts
project from Github to your local system, follow these steps:
- Install Flutter, and items such as Android emulator. Instructions are on the Flutter website docs.flutter.dev/get-started/install.
- Go to github.com/mzimmerm/flutter_charts, click on the "Code" button, and follow the instuctions to checkout flutter_charts. A summary of one installation method (download method):
- Click the "Download zip" link github.com/mzimmerm/flutter_charts/archive/refs/heads/master.zip
- When prompted, save the file
flutter_charts-master.zip
one level above where you want the project. We will use$HOME/dev
- Unzip the file
flutter_charts-master.zip
- The project will be in the
$HOME/dev/flutter_charts-master/
directory
Running the examples included in flutter_charts
This section assumes you installed the flutter_charts project as a local clone from Github, as described in 4
There is an example application in flutter_charts: example/lib/main.dart
. It shows how the Flutter Charts library can be included in a Flutter application.
To run the example application, Android emulator or iOS emulator need to be installed. You can use an IDE or command line. Instructions here are for the command line. Start in the unzipped directory, and follow the steps below:
- Important: Make sure an Android or iOS emulator is running, or you have a physical device connected. See the 3.2 section.
cd $HOME/dev/flutter_charts-master/
- Paste any of the lines below to the command line.
-
To run one example (actually two, first line chart, next vertical bar chart), run:
tool/demo/run_all_examples.sh ex10RandomData
(press q in the terminal to quit the current example and run next)
-
To run all examples
tool/demo/run_all_examples.sh
(press q in the terminal to quit the current example and run next)
-
Sample screenshot from running the example app
Illustration of the "iterative auto layout" feature
This section illustrates how the auto layout behaves when less and less horizontal space is available to display the chart.
Flutter chart library automatically checks for the X label overlap, and follows with rule-based iterative re-layout, to prevent labels running into each other.
To illustrate "stressed" horizontal space for the chart, we are gradually adding a text widget containing and increasing number of '<' characters on the right of the chart.
Autolayout step 1
Let's say there are six labels on a chart, and there is sufficient space to display labels horizontally. The result may look like this: We can see all x axis labels displayed it full, horizontally oriented.
Autolayout step 2
Next, let us make less available space by taking away some space on the right with a wider text label such as '<<<<<<'
We can see the labels were automatically tilted by the angle LabelLayoutStrategy.labelTiltRadians
for the labels to fit.
Autolayout step 3
Next, let us make even less available space by taking away some space on the right with a wider text label such as '<<<<<<<<<<<'.
We can see that labels are not only tilted, but also automatically skipped for labels not to overlap (every 2nd label is skipped, see option ChartOptions.iterativeLayoutOptions.showEveryNthLabel
).
Autolayout step 4
Next, let us make even less available space some more compared to step 3, with even a wider text label such as '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'. We can see even more labels were skipped for labels to prevent overlap, the chart is showing every 5th label.
Autolayout step 5
Last, let us take away extreme amount of horizontal space by using '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<', Here we can see the "default auto layout" finally gave up, and overlaps labels. Also, the legend is now hidded, as the amount of horizontal space is not sufficient.
Known packages, libraries and apps that use this flutter_charts package
- Michael R. Fairhurst's Language reader app - see github.com/MichaelRFairhurst/flutter-language-reader-app
TODO Todos
X
During construction of DataRows, enforce default values of Legend names and colors for rows. This fixes issues such as github.com/mzimmerm/flutter_charts/issues/18, when users do not set them and expect (reasonably) a default chart to show anyway.X
Allow scaling y values using a function.
Internal notes for exporting this document
Before a new release, perform these steps:
-
Run the following babel script which refreshes the 'expected' screenshots and also creates a 150px wide version. Do so by clicking C-c twice in the begin_src section. If the test
tool/demo/run_all_examples.sh
succeeds, it is guarenteed the 'expected' screenshots are same as those produced by the code inexample/lib/main.dart
. Theexample/lib/main.dart
is also used to generate images gallery with links to code in this README file on top.Convert expected screenshots to readme_images, while converting to 2 versions, one with width=150, one with 300
for file in https://github.com/mzimmerm/flutter_charts/raw/master/doc/readme_images/ex*; do rm $file done for file in integration_test/screenshots_expected/ex*; do # cp $file https://github.com/mzimmerm/flutter_charts/raw/master/doc/readme_images convert $file -resize 300 https://github.com/mzimmerm/flutter_charts/raw/master/doc/readme_images/$(basename $file) done for file in https://github.com/mzimmerm/flutter_charts/raw/master/doc/readme_images/ex*; do copy_name="$(basename $file)" copy_name="${copy_name/%.*/}" convert $file -resize 150 $(dirname $file)/${copy_name}_w150.png done
-
Delete the section AFTER the end_src in 1, all the way to above the heading 2
-
Run once the script in 1. If generates examples from code. Should be run once, manually, before export to MD. Before export to MD, delete the line "RESULTS". The manually generated sections will be exported to MD during export. Before running again, go to Step 2, as the example sections would accumulate.
-
Remove the "RESULTS:" generated in the step before.