flutter_charts 0.1.10

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 91

Table of Contents

New in the current release

Current release 0.1.8.

See <CHANGELOG.md> for the list of new features and bug fixes in this release.

As noted in the CHANGELOG, the two most important new features are:

  • Making the codebase Dart 2 clean
  • Adding the "iterative auto layout" of labels.

Labels auto layout is a sequence of steps, such as skipping some labels, tilting labels, or decreasing label font, that result in label 'fit' nicely, readably, without overflowing or running into each other.

Illustration of the new "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 '<' signs on the right of the chart.

Autolayout step 1

Let's say there are six labels on a chart, and sufficient space to display labels horizontally. The result may look like this:

img

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 like this '<<<<<<'

img

We can see the labels were automatically tilted by angle ChartOptions 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 like this '<<<<<<<<<<<'.

img

We can see that labels are not only tilted, but also automatically skipped (every 2nd) for labels not to overlap.

Autolayout step 4

Next, let us make even less available space some more compared to step 3, with even a wider text label like this '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'.

img

We can see even more labels were skipped for labels to prevent overlap, the chart is showing evey 5th label

Autolayout step 5

Last, let us take away extreme amount of horizontal space by using '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<',

img

Here we can see the "default auto layout" finally gave up, and overlaps labels. Also, the legend is now hidded, as there is not enough horizontal space.

How to include the flutter_charts library in your application

Flutter Charts is a charting library for Flutter, written in Flutter. Currently, column chart and line chart are supported.

The package is published on pub for inclusion in your application's pubspec.yaml: The Installing tab on https://pub.dartlang.org/packages/flutter_charts contains instructions on how to include the flutter_charts package in your application.

A chart created using flutter_charts - example application

There is an example application in flutter_charts: example/lib/main.dart. It shows how a Flutter Chart can be included in a Flutter application.

You can run the example application using one of the methods (6, 7) in the paragraph below.

This application is also used as a base to show several sample charts in the paragraphs below.

Here we show just two simple sample outputs, a column chart and a line chart.

A sample Vertical Bar Chart (Column Chart)

img

A sample point and Line Chart (Line Chart)

img

The output is generated from semi-random data. You can click the blue + button to rerun the chart with a different set of rows.

Known packages, libraries and apps that use this this flutter_charts package

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

Flutter Charts - an overview: data, options, classes

Before we show several examples of charts, a few notes.

  • The ChartData class: allows to define data - X labels, Y values, (optional) Y labels, each-dataRow (series) legends, each-dataRow (series) color. The list below provides a summary description of each item
    • X labels: ChartData.xLabels allow to define X labels. Setting xLabels is required, but client can set them to empty strings.
    • Y values: ChartData.dataRows allow to define Y values in rows. Assumption: size of each data row in ChartData.dataRows is the same, and each data row size == ChartData.xLabels.size
    • Y labels (optional): Normally, Y labels are generated from data. The option ChartOptions.useUserProvidedYLabels (default true), asks flutter_charts to data-generate Y labels. If this option is set to false, then ChartData.yLabels must be set. Any number of such user-provided Y labels is allowed.
    • Each-dataRow (each series) legends: ChartData.dataRowsLegends allow to define a legend for each data row in ChartData.dataRows. Assumption: ChartData.dataRows.size == ChartData.dataRowsLegends.size
    • Each-dataRow (each series) color: ChartData.dataRowsColors allow to define a color for each data row in ChartData.dataRows. Assumption: ChartData.dataRows.size == ChartData.dataRowsColors.size
  • The ChartOptions class: allows to define options, by using it's defaults, or setting some options to non default values. There are also LineChartOptions and VerticalBarChartOptions classes.
  • Support for randomly generated data, colors, labels: Flutter Charts also provides randomly generated data, in the class RandomChartData. This class generates:
    • Y values data,
    • X labels,
    • Series colors,
    • Series legends
  • Currently the only purpose of RandomChartData is for use in the examples below. To be clear, RandomChartData Y values, series colors, and series legends are not completely random - they hardcode some demoable label, legends, color values, and data ranges (data random within the range).

Flutter Charts - examples: LineChart and VerticalBarChart. Code and resulting charts

Flutter Charts code allow to define the following data elements:

*Data (Y values)* User-Provided or Random
*X Labels* User-Provided or Random
*Options including Colors* User-Provided or Random
*Data Rows Legends* User-Provided or Random
*Y Labels* User-Provided or Data-Generated

The examples below show a few alternative code snippets (User-Provided or Random data, labels, option) and the resulting charts.

The chart images were obtained by substituting the code snippet to the file:example/lib/main.dart code.

Random Data (Y values), Random X Labels, Random Colors, Random Data Rows Legends, Data-Generated Y Labels.

This example shows that Data-Generated Y labels is the default.
Flutter Charts support reasonably intelligently generated Y Labels from data, including dealing with negatives.

Code in defineOptionsAndData():

void defineOptionsAndData() {
  _lineChartOptions = new LineChartOptions();
  _verticalBarChartOptions = new VerticalBarChartOptions();
  _chartData = new RandomChartData(useUserProvidedYLabels: _lineChartOptions.useUserProvidedYLabels);
}

Result line chart:

img

Result vertical bar chart:

img

User-Provided Data (Y values), User-Provided X Labels, Random Colors, User-Provided Data Rows Legends, Data-Generated Y Labels,

Code in defineOptionsAndData():

void defineOptionsAndData() {
  _lineChartOptions = new LineChartOptions();
  _verticalBarChartOptions = new VerticalBarChartOptions();
  _chartData = new ChartData();
  _chartData.dataRowsLegends = [
    "Spring",
    "Summer",
    "Fall",
    "Winter"];
  _chartData.dataRows = [
    [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, ],
  ];
  _chartData.xLabels =  ["Wolf", "Deer", "Owl", "Mouse", "Hawk", "Vole"];
  _chartData.assignDataRowsDefaultColors();
  // Note: ChartOptions.useUserProvidedYLabels default is still used (false);
}

Result line chart:

img

Result vertical bar chart:

img

User-Provided Data (Y values), User-Provided X Labels, Random Colors, User-Provided Data Rows Legends, User-Provided Y Labels

This example show how to use the option useUserProvidedYLabels, and scaling of data to the Y labels range.

Code in defineOptionsAndData():

void defineOptionsAndData() {
  // This example shows user defined Y Labels.
  //   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.

  // Note that current implementation sets
  // the minimum of dataRows range (1.0 in this example)
  // on the level of the first Y Label ("Ok" 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).
  // This is not desirable, we need to add a userProvidedYLabelsBoundaryMin/Max.
  _lineChartOptions = new LineChartOptions();
  _verticalBarChartOptions = new VerticalBarChartOptions();
  _chartData = new ChartData();
  _chartData.dataRowsLegends = [
    "Java",
    "Dart",
    "Python",
    "Newspeak"];
  _chartData.dataRows = [
    [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, ],
  ];
  _chartData.xLabels =  ["Fast", "Readable", "Novel", "Use"];
  _chartData.dataRowsColors = [
    Colors.blue,
    Colors.yellow,
    Colors.green,
    Colors.amber,
  ];
  _lineChartOptions.useUserProvidedYLabels = true; // use the labels below on Y axis
  _chartData.yLabels = [
    "Ok",
    "Higher",
    "High",
  ];
}

Result line chart:

img (Disclaimer: Not actually measured)

Result vertical bar chart: Here the Y values should be numeric (if any) as manual labeling "Ok", "Higher", High" does not make sense for stacked type charts.

img (Disclaimer: Not actually measured)

VerticalBar Chart - one more example, showing positive/negative stacks:

User-Provided Data (Y values), User-Provided X Labels, User-Provided Colors, User-Provided Data Rows Legends, User-Provided Y Labels

This example has again user defined Y Labels, with a bar chart, using the smart auto-layout of user defined Y Labels. The chart shows negative and positive values similar to %down/%up stock charts.

Code in defineOptionsAndData():

void defineOptionsAndData() {
  // This example shows user defined Y Labels with
  // a bar chart, showing negative and positive values
  // similar to %down/%up stock charts.
  _lineChartOptions = new LineChartOptions();
  _verticalBarChartOptions = new VerticalBarChartOptions();
  _chartData = new ChartData();
  _chartData.dataRowsLegends = [
    "-2%_0%",
    "<-2%",
    "0%_+2%",
    ">+2%"];
  // each column absolute values should add to same number todo- 100 would make more sense, to represent 100% of stocks in each category
  _chartData.dataRows = [
    [-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, ],
  ];
  _chartData.xLabels =  ["Energy", "Health", "Finance", "Chips", "Oil"];
  _chartData.dataRowsColors = [
    Colors.grey,
    Colors.red,
    Colors.greenAccent,
    Colors.black,
  ];
  _lineChartOptions.useUserProvidedYLabels = false; // use labels below
  //_chartData.yLabels = [
  //  "Ok",
  //  "Higher",
  //  "High",
  //];
}

Result vertical bar chart:

img

(there is a bug here,see Known Bugs)

version 0.1.10 (2018-09-30)

Corrected formatting, and a few formal changes from pub auto-checking.

version 0.1.9 (2018-09-28)

Compatibility with Dart 2.0

version 0.1.8 (2018-06-20)

Enhancements

Making the codebase Dart 2 clean

Made changes to remove any analyser messages with Dart 2.

Labels auto layout - added pluggable and automated ability to ensure that labels "fit", and do not overlap

This release added the ability to "iteratively auto layout" labels.

Labels auto layout is a sequence of steps, such as skipping some labels, tilting labels, or decreasing label font, that result in label 'fit' nicely, readably, without overflowing or running into each other.

The ability to auto layout labels is implemented using a pluggable base class LabelLayoutStrategy, and a concrete implemented extension DefaultIterativeLabelLayoutStrategy. This default implementation of the iterative auto layout achieves that labels, defines a zero or more sequences of steps, each performing a specific code to achieve labels fit, such as:

  • Skipping every 2nd label
  • Tilting all labels
  • Decreasing label font size

The term "iterative" in "iteratively auto layout" refers to the fact the LabelLayoutStrategy repeates the layout steps multiple times, until a good fit is achieved.

The LabelLayoutStrategy and extensions, including the default DefaultIterativeLabelLayoutStrategy, are members of containers which implement the AdjustableContent, or extend the abstract AdjustableContentChartAreaContainer. The term "adjustable content" here refers to ability to adjust sizes of child components, or even remove child components which would overlap in default conditions (sizes, and mumbers). See usages of _xContainerLabelLayoutStrategy in the sample app example/lib/main.dart for an example how to use custom LabelLayoutStrategy extensions. In practice, AdjustableContent is only used for multiple potentially overlaping labels. This knowledge is not necessary for most users who are merely using the default (not built in) iterative auto layout provided by the AdjustableContentChartAreaContainer.

To learn more about the new auto layout process, see the README.md section "Illustration of the new "iterative auto layout" feature".

Graceful skipping of legend

This release added the ability to skip the legend, when there is insufficient horizontal space.

Fixes

Fixed a bug reported by Lorenzo Tejera, using this data

  void defineOptionsAndData() {
    _lineChartOptions = new LineChartOptions();
    _verticalBarChartOptions = new VerticalBarChartOptions();
    _chartData = new ChartData();
    _chartData.dataRowsLegends = [
      "Spring",
      "Summer"
    ];
    _chartData.dataRows = [
      [1.0, 2.0, 3.0, 4.0],
      [4.0, 3.0, 5.0, 6.0]
    ];
    _chartData.xLabels = ["One", "Two", "Three", "Four"];
    _chartData.assignDataRowsDefaultColors();
    // Note: ChartOptions.useUserProvidedYLabels default is still used (false);
  }

Reason: This code - revisit when removing need for double data

        if (signMax <= 0) {
          from = min;
          to = 0.0; // was 0, caused issues in Interval typed as double.
        } else {
          from = 0.0;// was 0, caused issues in Interval typed as double.
          to = max;
        }

v0.1.7 (2017-12-17)

Fixed README.md error - images failing to show (https://github.com/mzimmerm/flutter_charts/issues/8)

v0.1.6 (2017-12-03)

Implemented change in https://github.com/mzimmerm/flutter_charts/issues/5 - allows to set paint on line chart hotspot circles

Added the following new line chart options in charts/line/options.dart

  ui.Paint hotspotInnerPaint = new ui.Paint()
    ..color = material.Colors.yellow;

  ui.Paint hotspotOuterPaint = new ui.Paint()
    ..color = material.Colors.black;

  double lineStrokeWidth = 3.0;

Implemented change in https://github.com/mzimmerm/flutter_charts/issues/6 - line chart allows to reverse order of data series (dataRows) to make the significant series line to be on top

Added the following new chart options in charts/options.dart

  bool firstDataRowPaintedFirst = true;

Made several text options configurable

Moved the following to options in charts/options.dart (from being hardcoded)

  painting.TextStyle labelTextStyle = new painting.TextStyle(
    color: material.Colors.grey[600],
    fontSize: 14.0,);

  ui.TextDirection labelTextDirection   = ui.TextDirection.ltr;
  ui.TextAlign     labelTextAlign       = ui.TextAlign.center;
  double           labelTextScaleFactor = 1.0;

Renamed option xTopMinTicksHeight to xTopPaddingAboveTicksHeight

New name reflects the usage better.

v0.1.5 (2017-10-27)

This version finally fixed issue https://github.com/mzimmerm/flutter_charts/issues/2 - flutter charts not actually working as a library package (reason: incorrectly specified dependencies).

v0.1.4 (2017-10-27)

  • Only changes in documentation. Also publishing using flutter packages pub publish instead of previously incorrect pub publish which resulted in a package that reports error on clients' getting the package using flutter pub get. Hopefully this change will fix the issue. Below is the full error this new version is trying to fix:

The following log is from a test app in https://github.com/mzimmerm/flutter_charts_sample_app. It is mostly relevant as a documentation of the issue, client apps can ignore this.

flutter_charts_sample_app> flutter pub get      
Running "flutter packages get" in flutter_charts_sample_app...      
Package flutter_charts has no versions that match >=0.1.3 <0.2.0 derived from:
- flutter_charts_sample_app depends on version ^0.1.3
---- Log transcript ----
FINE: Pub 1.25.0-dev.11.0
MSG : Resolving dependencies...
SLVR: Solving dependencies:
    | - flutter_charts ^0.1.3 from hosted (flutter_charts)
    | - flutter any from sdk (flutter) (locked to 0.0.37)
IO  : Get versions from https://pub.dartlang.org/api/packages/flutter_charts.
IO  : HTTP GET https://pub.dartlang.org/api/packages/flutter_charts
    | Accept: application/vnd.pub.v2+json
    | X-Pub-OS: linux
    | X-Pub-Command: get
    | X-Pub-Session-ID: 8D558B08-DBBE-4D24-AB8F-C0EEC36157B2
    | X-Pub-Environment: flutter_cli
    | X-Pub-Reason: direct
    | user-agent: Dart pub 1.25.0-dev.11.0
IO  : HTTP response 200 OK for GET https://pub.dartlang.org/api/packages/flutter_charts
    | took 0:00:00.332100
    | transfer-encoding: chunked
    | date: Tue, 28 Nov 2017 05:32:06 GMT
    | content-encoding: gzip
    | vary: Accept-Encoding
    | via: 1.1 google
    | content-type: application/json
    | x-frame-options: SAMEORIGIN
    | x-xss-protection: 1; mode=block
    | x-content-type-options: nosniff
    | server: nginx
SLVR: * start at root
SLVR: | flutter 0.0.37 from sdk is locked
SLVR: | * select flutter 0.0.37 from sdk
SLVR: | | collection 1.14.3 from hosted is locked
SLVR: | | * select collection 1.14.3 from hosted
SLVR: | | | http 0.11.3+14 from hosted is locked
SLVR: | | | * select http 0.11.3+14 from hosted
SLVR: | | | | async 1.13.3 from hosted is locked
SLVR: | | | | * select async 1.13.3 from hosted
SLVR: | | | | | http_parser 3.1.1 from hosted is locked
SLVR: | | | | | * select http_parser 3.1.1 from hosted
SLVR: | | | | | | charcode 1.1.1 from hosted is locked
SLVR: | | | | | | * select charcode 1.1.1 from hosted
SLVR: | | | | | | | meta 1.1.1 from hosted is locked
SLVR: | | | | | | | * select meta 1.1.1 from hosted
SLVR: | | | | | | | | path 1.4.2 from hosted is locked
SLVR: | | | | | | | | * select path 1.4.2 from hosted
SLVR: | | | | | | | | | sky_engine 0.0.99 from path is locked
SLVR: | | | | | | | | | * select sky_engine 0.0.99 from path
SLVR: | | | | | | | | | | source_span 1.4.0 from hosted is locked
SLVR: | | | | | | | | | | * select source_span 1.4.0 from hosted
SLVR: | | | | | | | | | | | stack_trace 1.8.2 from hosted is locked
SLVR: | | | | | | | | | | | * select stack_trace 1.8.2 from hosted
SLVR: | | | | | | | | | | | | string_scanner 1.0.2 from hosted is locked
SLVR: | | | | | | | | | | | | * select string_scanner 1.0.2 from hosted
SLVR: | | | | | | | | | | | | | typed_data 1.1.4 from hosted is locked
SLVR: | | | | | | | | | | | | | * select typed_data 1.1.4 from hosted
SLVR: | | | | | | | | | | | | | | vector_math 2.0.5 from hosted is locked
SLVR: | | | | | | | | | | | | | | * select vector_math 2.0.5 from hosted
SLVR: | | | | | | | | | | | | | | | inconsistent source "hosted" for flutter:
    | | | | | | | | | | | | | | | |   flutter_charts 0.1.3 from hosted -> flutter >=0.0.20 <0.1.0 from hosted (flutter)
    | | | | | | | | | | | | | | | |   flutter_charts_sample_app 0.0.0 (root) -> flutter any from sdk (flutter)
SLVR: | | | | | | | | | | | | | | | version 0.1.2 of flutter_charts doesn't match >=0.1.3 <0.2.0:
    | | | | | | | | | | | | | | | |   flutter_charts_sample_app 0.0.0 (root) -> flutter_charts ^0.1.3 from hosted (flutter_charts)
SLVR: | | | | | | | | | | | | | | | version 0.1.1 of flutter_charts doesn't match >=0.1.3 <0.2.0:
    | | | | | | | | | | | | | | | |   flutter_charts_sample_app 0.0.0 (root) -> flutter_charts ^0.1.3 from hosted (flutter_charts)
SLVR: | | | | | | | | | | | | | | | version 0.1.0 of flutter_charts doesn't match >=0.1.3 <0.2.0:
    | | | | | | | | | | | | | | | |   flutter_charts_sample_app 0.0.0 (root) -> flutter_charts ^0.1.3 from hosted (flutter_charts)
SLVR: BacktrackingSolver took 0:00:00.516136 seconds.
    | - Tried 1 solutions
    | - Requested 1 version lists
    | - Looked up 1 cached version lists
    | 
FINE: Resolving dependencies finished (0.5s).
ERR : Package flutter_charts has no versions that match >=0.1.3 <0.2.0 derived from:
    | - flutter_charts_sample_app depends on version ^0.1.3
FINE: Exception type: NoVersionException
FINE: package:pub/src/entrypoint.dart 195                                             Entrypoint.acquireDependencies
    | package:pub/src/command/get.dart 38                                             GetCommand.run
    | package:args/command_runner.dart 194                                            CommandRunner.runCommand
    | package:pub/src/command_runner.dart 168                                         PubCommandRunner.runCommand.<fn>
    | dart:async                                                                      new Future.sync
    | package:pub/src/utils.dart 102                                                  captureErrors.<fn>
    | package:stack_trace                                                             Chain.capture
    | package:pub/src/utils.dart 117                                                  captureErrors
    | package:pub/src/command_runner.dart 168                                         PubCommandRunner.runCommand
    | package:pub/src/command_runner.dart 117                                         PubCommandRunner.run
    | /b/build/slave/dart-sdk-linux-dev/build/sdk/third_party/pkg/pub/bin/pub.dart 8  main
    | ===== asynchronous gap ===========================
    | dart:async                                                                      _Completer.completeError
    | package:pub/src/entrypoint.dart 243                                             Entrypoint.acquireDependencies
    | ===== asynchronous gap ===========================
    | dart:async                                                                      _asyncThenWrapperHelper
    | package:pub/src/entrypoint.dart 192                                             Entrypoint.acquireDependencies
    | package:pub/src/command/get.dart 38                                             GetCommand.run
    | package:args/command_runner.dart 194                                            CommandRunner.runCommand
    | ===== asynchronous gap ===========================
    | dart:async                                                                      new Future.microtask
    | package:args/command_runner.dart 142                                            CommandRunner.runCommand
    | package:pub/src/command_runner.dart 168                                         PubCommandRunner.runCommand.<fn>
    | dart:async                                                                      new Future.sync
    | package:pub/src/utils.dart 102                                                  captureErrors.<fn>
    | package:stack_trace                                                             Chain.capture
    | package:pub/src/utils.dart 117                                                  captureErrors
    | package:pub/src/command_runner.dart 168                                         PubCommandRunner.runCommand
---- End log transcript ----
pub get failed (1)

v0.1.3 (2017-10-03)

  • Only changes in README, to figure out how to include images (turns out all links must be external)

v0.1.0 (2017-10-03)

  • Initial push. Line chart and (vertical) bar chart support. Various options supported.

Semantic Version 2.0.0 Conventions

This package follows Semantic Version 2.0.0. http://semver.org/

Example: 1.2.3 means MAJOR.MINOR.PATCH

Development: Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.

API Stable versions: All versions with the same MAJOR, where MAJOR>0 must have the same API.

example/lib/main.dart

// note: All classes without prefix in this code are either
//       - from material.dart or
//       - from flutter_charts.dart exports (this library)
//       Also, material.dart exports many dart files, including widgets.dart,
//         so Widget classes are referred to without prefix
import 'package:flutter/material.dart';
// import 'dart:ui' as ui;

// provides: data.dart, random_chart_data.dart, line_chart_options.dart
import 'package:flutter_charts/flutter_charts.dart';

/// Example of simple line chart usage in an application.
///
/// Library note: This file is on the same level as _lib_ so everything from _lib_ must
/// be imported using the "package:" scheme, e.g.
/// > import 'package:flutter_charts/flutter_charts.dart';
void main() {
  // runApp is function (not method) in PROJ/packages/flutter/lib/src/widgets/binding.dart.
  //
  // Why we do not have to import binding.dart?
  //
  // In brief, because it is imported through another file, material.dart.
  //
  // Longer reason
  //
  //      - Because Any Flutter app must have:
  //        1) main() { runApp(new MyApp()) } // entry point
  //        2) import 'package:flutter/material.dart';
  //          Note: *NOT* 'package:flutter/material/material.dart'.
  //          Note: material.dart is on path: PROJ/packages/flutter/lib/material.dart
  //          so another note:
  //             * the lib level is skipped int the import reference
  //             * package: represent a directory where packages
  //               for this project are installed in pub update package
  //      - And:
  //        3) The imported 'package:flutter/material.dart' contains line:
  //            export 'widgets.dart';
  //            which references, at the same level, a path:
  //               PROJ/packages/flutter/lib/widgets.dart
  //            which contains:
  //               export 'src/widgets/binding.dart';
  //               on path: PROJ/packages/flutter/lib/src/widgets/binding.dart
  //            which contains the function runApp().
  //
  //  So, eventually, the loading of binding.dart, and it's runApp() function
  //  in MyApp is achieved this way:
  //    1) This file (example/lib/main.dart) has
  //        - import 'package:flutter/material.dart' (references PROJ/packages/flutter/lib/material.dart)
  //    2) material.dart has
  //        - export 'widgets.dart'; (references same dir        PROJ/packages/flutter/lib/widgets.dart)
  //    3) widgets.dart has
  //        - export 'src/widgets/binding.dart'; (references dir PROJ/packages/flutter/lib/src/widgets/binding.dart)
  //    4) binding.dart has
  //        - the runApp() function
  //
  // This process achieves importing (heh via exports) the file
  //    packages/flutter/lib/src/widgets/binding.dart
  //    which has the runApp() function.
  //
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of the application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Charts Demo Title',
      debugShowCheckedModeBanner: false,
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Charts Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful,
  // meaning that it has a State object (defined below) that contains
  // fields that affect how it looks.

  // This class is the configuration for the state. It holds the
  // values (in this case the title) provided by the parent (in this
  // case the App widget) and used by the build method of the State.
  // Fields in a Widget subclass are always marked "final".

  final String title;

  /// Stateful widgets must implement the [createState()] method.
  ///
  /// The [createState()] method will typically return the
  /// new state of the widget.
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

/// State of the page.
class _MyHomePageState extends State<MyHomePage> {
  LineChartOptions _lineChartOptions;
  ChartOptions _verticalBarChartOptions;
  LabelLayoutStrategy _xContainerLabelLayoutStrategy;
  ChartData _chartData;

  _MyHomePageState() {
    // defineOptionsAndData();
  }

  void defineOptionsAndData() {
    _lineChartOptions = new LineChartOptions();
    _verticalBarChartOptions = new VerticalBarChartOptions();
    // If you were to use your own extension of
    //   DefaultIterativeLabelLayoutStrategy or LayoutStrategy,
    //   this is how to create an instance.
    // If _xContainerLabelLayoutStrategy
    //   is not set (remains null), the charts instantiate
    //   the DefaultIterativeLabelLayoutStrategy.
    _xContainerLabelLayoutStrategy = new DefaultIterativeLabelLayoutStrategy(
      options: _verticalBarChartOptions,
    );
    // _xContainerLabelLayoutStrategy = null;
    _chartData = new RandomChartData(
        useUserProvidedYLabels: _lineChartOptions.useUserProvidedYLabels);
  }

  /* ALWAYS ON TOP - DEFAULT - Default - Random data
  void defineOptionsAndData() {
    _lineChartOptions = new LineChartOptions();
    _verticalBarChartOptions = new VerticalBarChartOptions();
    _chartData = new RandomChartData(
        useUserProvidedYLabels: _lineChartOptions.useUserProvidedYLabels);
  }
  */

  /* 9  - Explicit use of DefaultIterativeLabelLayoutStrategy.
          The _xContainerLabelLayoutStrategy must also work commented out.

  void defineOptionsAndData() {
    _lineChartOptions = new LineChartOptions();
    _verticalBarChartOptions = new VerticalBarChartOptions();
    // If you were to use your own extension of
    //   DefaultIterativeLabelLayoutStrategy or LayoutStrategy,
    //   this is how to create an instance.
    // If _xContainerLabelLayoutStrategy
    //   is not set (remains null), the charts instantiate
    //   the DefaultIterativeLabelLayoutStrategy.
    _xContainerLabelLayoutStrategy = new DefaultIterativeLabelLayoutStrategy(
      options: _verticalBarChartOptions,
    );
    // _xContainerLabelLayoutStrategy = null;
    _chartData = new RandomChartData(
        useUserProvidedYLabels: _lineChartOptions.useUserProvidedYLabels);
  }
   */

  /* 8 - Explicit use of DefaultIterativeLabelLayoutStrategy (see also 9),
         to show how to use in case extensions are needed

  void defineOptionsAndData() {
    _lineChartOptions = new LineChartOptions();
    _verticalBarChartOptions = new VerticalBarChartOptions();
    _xContainerLabelLayoutStrategy = new DefaultIterativeLabelLayoutStrategy(
      options: _verticalBarChartOptions,
    );
    _chartData = new ChartData();
    _chartData.dataRowsLegends = ["Spring", "Summer", "Fall", "Winter"];
    _chartData.dataRows = [
      [1.0, 2.0, 3.0, 4.0, 6.0],
      [4.0, 3.0, 5.0, 6.0, 1.0],
    ];
    _chartData.xLabels = ["One", "Two", "Three", "Four", "Five"];
    _chartData.assignDataRowsDefaultColors();
    // Note: ChartOptions.useUserProvidedYLabels default is still used (false);
  }
   */

  /* 7 - Default - Random data
  void defineOptionsAndData() {
    _lineChartOptions = new LineChartOptions();
    _verticalBarChartOptions = new VerticalBarChartOptions();
    _chartData = new RandomChartData(
        useUserProvidedYLabels: _lineChartOptions.useUserProvidedYLabels);
  }
  */

  /* 6 Test a bug reported by Lonenzo Tejera - todo-1 - also check Y range that should have more points.

  void defineOptionsAndData() {
    _lineChartOptions = new LineChartOptions();
    _verticalBarChartOptions = new VerticalBarChartOptions();
    _chartData = new ChartData();
    _chartData.dataRowsLegends = [
      "Spring",
      "Summer",
      "Fall",
      "Winter"];
    _chartData.dataRows = [
      [1.0, 2.0, 3.0, 4.0, 6.0],
      [4.0, 3.0, 5.0, 6.0, 1.0],
    ];
    _chartData.xLabels =  ["One", "Two", "Three", "Four", "Five"];
    _chartData.assignDataRowsDefaultColors();
    // Note: ChartOptions.useUserProvidedYLabels default is still used (false);
  }
   */

  /* 5 Demonstrate order of painting lines on the line chart,
       when dataRows lines are on top of each other

  void defineOptionsAndData() {
    _lineChartOptions = new LineChartOptions();
    _verticalBarChartOptions = new VerticalBarChartOptions();
    _chartData = new ChartData();
    _chartData.dataRowsLegends = [
      "Spring",
      "Summer",
      "Fall",
      "Winter"];
    _chartData.dataRows = [
      [10.0, 20.0,  5.0,  30.0,  5.0,  20.0, ],
      [10.0, 20.0,  5.0,  30.0,  5.0,  30.0, ],
      [25.0, 40.0, 20.0,  80.0, 12.0,  90.0, ],
      [25.0, 40.0, 20.0,  80.0, 12.0, 100.0, ],
    ];
    _chartData.xLabels =  ["Wolf", "Deer", "Owl", "Mouse", "Hawk", "Vole"];
    _chartData.assignDataRowsDefaultColors();
    // Note: ChartOptions.useUserProvidedYLabels default is still used (false);
  }
   */

  /* 4 Basic simpliest demo

   void defineOptionsAndData() {
     _lineChartOptions = new LineChartOptions();
     _verticalBarChartOptions = new VerticalBarChartOptions();
     _chartData = new RandomChartData(useUserProvidedYLabels: _lineChartOptions.useUserProvidedYLabels);
   }
   */

  /* 3
   void defineOptionsAndData() {
     _lineChartOptions = new LineChartOptions();
     _verticalBarChartOptions = new VerticalBarChartOptions();
     _chartData = new ChartData();
     _chartData.dataRowsLegends = [
       "Spring",
       "Summer",
       "Fall",
       "Winter"];
     _chartData.dataRows = [
       [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, ],
     ];
     _chartData.xLabels =  ["Wolf", "Deer", "Owl", "Mouse", "Hawk", "Vole"];
     _chartData.assignDataRowsDefaultColors();
     // Note: ChartOptions.useUserProvidedYLabels default is still used (false);
   }
   */

  /* 2
   void defineOptionsAndData() {
     // This example shows user defined Y Labels.
     //   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.

     // Note that current implementation sets
     // the minimum of dataRows range (1.0 in this example)
     // on the level of the first Y Label ("Ok" 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).
     // This is not desirable, we need to add a userProvidedYLabelsBoundaryMin/Max.
     _lineChartOptions = new LineChartOptions();
     _verticalBarChartOptions = new VerticalBarChartOptions();
     _chartData = new ChartData();
     _chartData.dataRowsLegends = [
       "Java",
       "Dart",
       "Python",
       "Newspeak"];
     _chartData.dataRows = [
       [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, ],
     ];
     _chartData.xLabels =  ["Fast", "Readable", "Novel", "Use"];
     _chartData.dataRowsColors = [
       Colors.blue,
       Colors.yellow,
       Colors.green,
       Colors.amber,
     ];
     _lineChartOptions.useUserProvidedYLabels = true; // use labels below
     _chartData.yLabels = [
       "Ok",
       "Higher",
       "High",

     ];
   }
  */

  /* 1
   void defineOptionsAndData() {
     // In each column, adding it's absolute values should add to same number:
     // 100 would make more sense, to represent 100% of stocks in each category.
    _lineChartOptions = new LineChartOptions();
     _verticalBarChartOptions = new VerticalBarChartOptions();
     _chartData = new ChartData();
     _chartData.dataRowsLegends = [
       "-2%_0%",
       "<-2%",
       "0%_+2%",
       ">+2%"];
     // each column should add to same number. everything else is relative.
     _chartData.dataRows = [
       [-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, ],
     ];
     _chartData.xLabels =  ["Energy", "Health", "Finance", "Chips", "Oil"];
     _chartData.dataRowsColors = [
       Colors.grey,
       Colors.red,
       Colors.greenAccent,
       Colors.black,
     ];
     _lineChartOptions.useUserProvidedYLabels = false; // use labels below
     //_chartData.yLabels = [
     //  "Ok",
     //  "Higher",
     //  "High",
     //];
   }
  */

  void _chartStateChanger() {
    setState(() {
      // This call to setState tells the Flutter framework that
      // something has changed in this State, which causes it to rerun
      // the build method below so that the display can reflect the
      // updated values. If we changed state without calling
      // setState(), then the build method would not be called again,
      // and so nothing would appear to happen.

      /// here we create new random data to illustrate state change
      // defineOptionsAndData();
    });
  }

  @override
  Widget build(BuildContext context) {
    // The (singleton?) window object is available anywhere using ui.
    // From window, we can get  ui.window.devicePixelRatio, and also
    //   ui.Size windowLogicalSize = ui.window.physicalSize / devicePixelRatio
    // Note: Do not use ui.window for any sizing: see
    //       https://github.com/flutter/flutter/issues/11697

    // Use MediaQuery.of(context) for any sizing.
    // note: mediaQueryData can still return 0 size,
    //       but if MediaQuery.of(context) is used, Flutter will guarantee
    //       the build(context) will be called again !
    //        (once non 0 size becomes available)
    // MediaQueryData mediaQueryData = MediaQuery.of(context);

    // note: windowLogicalSize = size of the media (screen) in logical pixels
    // note: same as ui.window.physicalSize / ui.window.devicePixelRatio;
    // ui.Size windowLogicalSize = mediaQueryData.size;

    // devicePixelRatio = number of device pixels for each logical pixel.
    // note: in all known hardware, size(logicalPixel) > size(devicePixel)
    // note: this is also, practically, never needed
    // double logicalToDevicePixelSize = mediaQueryData.devicePixelRatio;

    // textScaleFactor = number of font pixels for each logical pixel.
    // note: with some fontSize, if text scale factor is 1.5
    //       => text is 1.5x larger than the font size.
    // double fontScale = mediaQueryData.textScaleFactor;

    // Let us give the LineChart full width and half of height of window.
    // final ui.Size chartLogicalSize =
    //     new Size(windowLogicalSize.width, windowLogicalSize.height / 2);
    //
    // print(" ### Size: ui.window.physicalSize=${ui.window.physicalSize}, "
    //     "windowLogicalSize = mediaQueryData.size = $windowLogicalSize,"
    //     "chartLogicalSize=$chartLogicalSize");

    defineOptionsAndData();

    /* keep
    LineChart lineChart = new LineChart(
      painter: new LineChartPainter(),
      container: new LineChartContainer(
        chartData: _chartData, // @required
        chartOptions: _lineChartOptions, // @required
        xContainerLabelLayoutStrategy: _xContainerLabelLayoutStrategy, // @optional
      ),
    );
    */

    VerticalBarChart verticalBarChart = new VerticalBarChart(
      painter: new VerticalBarChartPainter(),
      container: new VerticalBarChartContainer(
        chartData: _chartData, // @required
        chartOptions: _verticalBarChartOptions, // @required
        xContainerLabelLayoutStrategy:
            _xContainerLabelLayoutStrategy, // @optional
      ),
    );

    // [MyHomePage] extends [StatefulWidget].
    // [StatefulWidget] calls build(context) every time setState is called,
    // for instance as done by the _chartStateChanger method above.
    // The Flutter framework has been optimized to make rerunning
    // build methods fast, so that you can just rebuild anything that
    // needs updating rather than having to individually change
    // instances of widgets.
    return new Scaffold(
      appBar: new AppBar(
        // Here we take the value from the MyHomePage object that
        // was created by the App.build method, and use it to set
        // our appbar title.
        title: new Text(widget.title),
      ),
      body: new Center(
        // Center is a layout widget. It takes a single child and
        // positions it in the middle of the parent.
        child: new Column(
          // Column is also layout widget. It takes a list of children
          // and arranges them vertically. By default, it sizes itself
          // to fit its children horizontally, and tries to be as tall
          // as its parent.
          //
          // Invoke "debug paint" (press "p" in the console where you
          // ran "flutter run", or select "Toggle Debug Paint" from the
          // Flutter tool window in IntelliJ) to see the wireframe for
          // each widget.
          //
          // Column has various properties to control how it sizes
          // itself and how it positions its children. Here we use
          // mainAxisAlignment to center the children vertically; the
          // main axis here is the vertical axis because Columns are
          // vertical (the cross axis would be horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new RaisedButton(
              color: Colors.green,
              onPressed: _chartStateChanger,
            ),
            new Text(
              'vvvvvvvv:',
            ),

            // Expanded can be around one child of a Row or a Column
            // (there can be one or more children of those layouts).
            //
            // In this document below, we use | as abbreviation for vertical expansion,
            // <--> for horizontal expansion.
            //
            // "new Expanded()" around one of children of Row, or Column,
            // stretches/pulls the expanded child in the parent's
            // "growing" direction.
            //
            // So:
            //   - Inside Column (e.g. children: [A, B, Expanded (C)]) stretches C in
            //     column's "growing" direction (that is vertically |)
            //     to the fullest available outside height.
            //   - For Row  (e.g. children: [A, B, Expanded (C)]) stretches C in
            //     rows's "growing" direction (that is horizontally <-->)
            //     to the fullest available outside width.
            // The layout of this code, is, structurally like this:
            //   Column (children: [
            //      vvv,
            //      Expanded (
            //        Row  (children: [
            //        >>>, Expanded (Chart), <<<,
            //        ]),
            //      ^^^
            //    ])
            // The outer | expansion, in the Column's middle child
            //   pulls/stretches the row vertically |
            //   BUT also needs explicit
            //   crossAxisAlignment: CrossAxisAlignment.stretch.
            //   The cross alignment stretch carries
            //   the | expansion to all <--> expanded children.
            //  Basically, while "Expanded" only applies stretch in one
            //    direction, another outside "Expanded" with CrossAxisAlignment.stretch
            //    can force the innermost child to be stretched in both directions.
            new Expanded(
              // expansion inside Column pulls contents |
              child: new Row(
                // this stretch carries | expansion to <--> Expanded children
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  new Text('>>>'),
                  // LineChart is CustomPaint:
                  // A widget that provides a canvas on which to draw
                  // during the paint phase.

                  // Row -> Expanded -> Chart expands chart horizontally <-->
                  new Expanded(
                    child: verticalBarChart, // verticalBarChart, lineChart
                  ),
                  // new Text('<<'), // horizontal
                  // new Text('<<<<<<'),   // tilted
                  // new Text('<<<<<<<<<<<'),   // skiped (shows 3 labels, legend present)
                  // new Text('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'), // skiped (shows 2 labels, legend present but text vertical)
                  // new Text('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'),// labels do overlap, legend NOT present
                  new Text('<<<<<<'), // labels do overlap, legend NOT present
                ],
              ),
            ),

            new Text('^^^^^^:'),
            new RaisedButton(
              color: Colors.green,
              onPressed: _chartStateChanger,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _chartStateChanger,
        tooltip: 'New Random Data',
        child: new Icon(Icons.add),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flutter_charts: ^0.1.10

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_charts/flutter_charts.dart';
  
Version Uploaded Documentation Archive
0.1.10 Sep 30, 2018 Go to the documentation of flutter_charts 0.1.10 Download flutter_charts 0.1.10 archive
0.1.9 Sep 28, 2018 Go to the documentation of flutter_charts 0.1.9 Download flutter_charts 0.1.9 archive
0.1.8 Aug 28, 2018 Go to the documentation of flutter_charts 0.1.8 Download flutter_charts 0.1.8 archive
0.1.7 Dec 17, 2017 Go to the documentation of flutter_charts 0.1.7 Download flutter_charts 0.1.7 archive
0.1.6 Dec 4, 2017 Go to the documentation of flutter_charts 0.1.6 Download flutter_charts 0.1.6 archive
0.1.5 Nov 28, 2017 Go to the documentation of flutter_charts 0.1.5 Download flutter_charts 0.1.5 archive
0.1.4 Nov 28, 2017 Go to the documentation of flutter_charts 0.1.4 Download flutter_charts 0.1.4 archive
0.1.3 Nov 3, 2017 Go to the documentation of flutter_charts 0.1.3 Download flutter_charts 0.1.3 archive
0.1.2 Nov 3, 2017 Go to the documentation of flutter_charts 0.1.2 Download flutter_charts 0.1.2 archive
0.1.1 Nov 3, 2017 Go to the documentation of flutter_charts 0.1.1 Download flutter_charts 0.1.1 archive

All 11 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
81
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
91
Learn more about scoring.

We analyzed this package on Dec 5, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.1.0
  • pana: 0.12.7
  • Flutter: 1.0.0

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
decimal ^0.3.2 0.3.2
flutter 0.0.0
vector_math ^2.0.8 2.0.8
Transitive dependencies
collection 1.14.11
meta 1.1.6
rational 0.3.1
sky_engine 0.0.99
typed_data 1.1.6
Dev dependencies
flutter_test
test any