Table of Contents

  1. Examples with code
    1. ex10RandomData_lineChart
    2. ex10RandomData_verticalBarChart
    3. ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart
    4. ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart
    5. ex31SomeNegativeValues_lineChart
    6. ex31SomeNegativeValues_verticalBarChart
    7. ex32AllPositiveYsYAxisStartsAbove0_lineChart
    8. ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart
    9. ex33AllNegativeYsYAxisEndsBelow0_lineChart
    10. ex34OptionsDefiningUserTextStyleOnLabels_lineChart
    11. ex35AnimalsBySeasonNoLabelsShown_lineChart
    12. ex35AnimalsBySeasonNoLabelsShown_verticalBarChart
    13. ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart
    14. ex50StocksWithNegativesWithUserColors_verticalBarChart
    15. ex52AnimalsBySeasonLogarithmicScale_lineChart
    16. ex52AnimalsBySeasonLogarithmicScale_verticalBarChart
    17. ex60LabelsIteration1_verticalBarChart
    18. ex60LabelsIteration2_verticalBarChart
    19. ex60LabelsIteration3_verticalBarChart
    20. ex60LabelsIteration4_verticalBarChart
    21. ex900ErrorFixUserDataAllZero_lineChart
  2. Latest release changes
  3. Installation
    1. Installing flutter_charts as a library package into your app
    2. Installing the flutter_charts project as a local clone from Github
  4. Running the examples included in flutter_charts
  5. Illustration of the "iterative auto layout" feature
    1. Autolayout step 1
    2. Autolayout step 2
    3. Autolayout step 3
    4. Autolayout step 4
    5. Autolayout step 5
  6. Known packages, libraries and apps that use this flutter_charts package
  7. Todos
  8. 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.

nil nil nil nil
nil nil nil nil
nil nil nil nil
nil nil nil nil
nil nil nil nil
nil      

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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

img

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:

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

img

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.

img

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.

img

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).

img

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.

img

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.

img

Known packages, libraries and apps that use this flutter_charts package

  1. Michael R. Fairhurst's Language reader app - see github.com/MichaelRFairhurst/flutter-language-reader-app

TODO Todos

  1. 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.
  2. Replace `reduce(fn)` with `fold(initialValue, fn)` throughout code to deal with exceptions when lists are empty.
  3. X Allow scaling y values using a function.

Internal notes for exporting this document

Before a new release, perform these steps:

  1. 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 in example/lib/main.dart. The example/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
    
  2. Delete the section AFTER the end_src in 1, all the way to above the heading 2

  3. 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.

  4. Remove the "RESULTS:" generated in the step before.

Libraries

flutter_charts