Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/mzimmerm/flutter_charts

Charts Library for Flutter, written in Dart with Flutter.
https://github.com/mzimmerm/flutter_charts

Last synced: 3 months ago
JSON representation

Charts Library for Flutter, written in Dart with Flutter.

Lists

README

        

#+OPTIONS: toc:3
#+TODO: TODO IN-PROGRESS LATER DONE NOTE

* Table of contents :TOC:noexport:
- [[#examples-with-code][Examples with code]]
- [[#ex10randomdata_linechart-ex10randomdata_linechart][ex10RandomData_lineChart <>]]
- [[#ex10randomdata_verticalbarchart-ex10randomdata_verticalbarchart][ex10RandomData_barChart <>]]
- [[#ex30animalsbyseasonwithlabellayoutstrategy_linechart-ex30animalsbyseasonwithlabellayoutstrategy_linechart][ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart <>]]
- [[#ex30animalsbyseasonwithlabellayoutstrategy_verticalbarchart-ex30animalsbyseasonwithlabellayoutstrategy_verticalbarchart][ex30AnimalsBySeasonWithLabelLayoutStrategy_barChart <>]]
- [[#ex31somenegativevalues_linechart-ex31somenegativevalues_linechart][ex31SomeNegativeValues_lineChart <>]]
- [[#ex31somenegativevalues_verticalbarchart-ex31somenegativevalues_verticalbarchart][ex31SomeNegativeValues_barChart <>]]
- [[#ex32allpositiveysyaxisstartsabove0_linechart-ex32allpositiveysyaxisstartsabove0_linechart][ex32AllPositiveYsYAxisStartsAbove0_lineChart <>]]
- [[#ex32allpositiveysyaxisstartsabove0_verticalbarchart-ex32allpositiveysyaxisstartsabove0_verticalbarchart][ex32AllPositiveYsYAxisStartsAbove0_barChart <>]]
- [[#ex33allnegativeysyaxisendsbelow0_linechart-ex33allnegativeysyaxisendsbelow0_linechart][ex33AllNegativeYsYAxisEndsBelow0_lineChart <>]]
- [[#ex34optionsdefiningusertextstyleonlabels_linechart-ex34optionsdefiningusertextstyleonlabels_linechart][ex34OptionsDefiningUserTextStyleOnLabels_lineChart <>]]
- [[#ex35animalsbyseasonnolabelsshown_linechart-ex35animalsbyseasonnolabelsshown_linechart][ex35AnimalsBySeasonNoLabelsShown_lineChart <>]]
- [[#ex35animalsbyseasonnolabelsshown_verticalbarchart-ex35animalsbyseasonnolabelsshown_verticalbarchart][ex35AnimalsBySeasonNoLabelsShown_barChart <>]]
- [[#ex40languageswithyordinaluserlabelsandusercolors_linechart-ex40languageswithyordinaluserlabelsandusercolors_linechart][ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart <>]]
- [[#ex50stockswithnegativeswithusercolors_verticalbarchart-ex50stockswithnegativeswithusercolors_verticalbarchart][ex50StocksWithNegativesWithUserColors_barChart <>]]
- [[#ex52animalsbyseasonlogarithmicscale_linechart-ex52animalsbyseasonlogarithmicscale_linechart][ex52AnimalsBySeasonLogarithmicScale_lineChart <>]]
- [[#ex52animalsbyseasonlogarithmicscale_verticalbarchart-ex52animalsbyseasonlogarithmicscale_verticalbarchart][ex52AnimalsBySeasonLogarithmicScale_barChart <>]]
- [[#ex60labelsiteration1_verticalbarchart-ex60labelsiteration1_verticalbarchart][ex60LabelsIteration1_barChart <>]]
- [[#ex60labelsiteration2_verticalbarchart-ex60labelsiteration2_verticalbarchart][ex60LabelsIteration2_barChart <>]]
- [[#ex60labelsiteration3_verticalbarchart-ex60labelsiteration3_verticalbarchart][ex60LabelsIteration3_barChart <>]]
- [[#ex60labelsiteration4_verticalbarchart-ex60labelsiteration4_verticalbarchart][ex60LabelsIteration4_barChart <>]]
- [[#ex900errorfixuserdataallzero_linechart-ex900errorfixuserdataallzero_linechart][ex900ErrorFixUserDataAllZero_lineChart <>]]
- [[#latest-release-changes][Latest release changes]]
- [[#installation][Installation]]
- [[#installing-flutter_charts-as-a-library-package-into-your-app][Installing flutter_charts as a library package into your app]]
- [[#installing-the-flutter_charts-project-as-a-local-clone-from-github][Installing the flutter_charts project as a local clone from Github]]
- [[#running-the-examples-included-in-flutter_charts][Running the examples included in flutter_charts]]
- [[#illustration-of-the-iterative-auto-layout-feature][Illustration of the "iterative auto layout" feature]]
- [[#autolayout-step-1][Autolayout step 1]]
- [[#autolayout-step-2][Autolayout step 2]]
- [[#autolayout-step-3][Autolayout step 3]]
- [[#autolayout-step-4][Autolayout step 4]]
- [[#autolayout-step-5][Autolayout step 5]]
- [[#known-packages-libraries-and-apps-that-use-this-flutter_charts-package][Known packages, libraries and apps that use this flutter_charts package]]
- [[#testing][Testing]]
- [[#todos][Todos]]
- [[#internal-notes-for-exporting-this-document][Internal notes for exporting this document]]

* Examples with code

This section contains sample charts created by flutter_charts, with code that generated the charts. The code for each chart is in a method

#+begin_src dart
Widget chartToRun() {
// .. code which generates the sample chart
}
#+end_src

To quickly test the code, you can paste the method ~chartToRun()~ into the sample main app provided in https://github.com/mzimmerm/flutter_charts/blob/master/example/lib/main_run_doc_example.dart.

#+BEGIN_SRC bash :results output raw replace :eval no-export :exports none

# This Org Babel bash script is a generator of a section
# in exported README.md (html, whatever export is supported)
# That shows sample Flutter Charts created images, along with code that
# generated the images.
# This scipt runs during export, when run, it inserts it's output
# into the buffer. The output is a HTML table with cells, each cell
# contaings a sample Flutter Chart image; each image has a link
# to Flutter Charts sample code that would generate the image.
# The code is also generated by this script, by cutting snippets
# of actual code examples from 'example/main_run_doc_example.dart'.

NEWLINE=$'\n'

declare -a exampleEnumWithChartTypes

# Read examples descriptor file and pull out example enum names and chart types
# which are supported in tests. All those examples are guaranteed to be run in example/main_run_doc_example.dart,
# and also screenshot-generated and tested for sameness with expected screenshots
# in integration_test/screenshot_create_test.dart and test/screenshot_create_test.dart.
while read enumLine; do
if [[ $enumLine =~ "const Tuple2" ]]; then

exampleEnum=${enumLine#*.}
exampleEnum=${exampleEnum%%,*}

chartType=${enumLine##*.}
chartType=${chartType/%Chart*/Chart}

# Each element has a string with 2 items (space separated items, no spaces inside items allowed)
exampleEnumWithChartTypes+=("$exampleEnum $chartType")
fi
done < example/lib/src/util/example_descriptor.dart

# Generate and write-out the section with small chart images in one table row.
tableCellLinks=""
ncells=1
for exampleEnumWithChartType in "${exampleEnumWithChartTypes[@]}"; do
exampleEnum="${exampleEnumWithChartType% *}"
chartType="${exampleEnumWithChartType#* }"
exampleName="${exampleEnum}_${chartType}"
tableCellLinks="${tableCellLinks}| [[${exampleName}][file:doc/readme_images/${exampleName}_w150.png]] "
# New row after 4 cells: close last cell with | and a newline
if [[ $ncells -eq 4 ]]; then
tableCellLinks="${tableCellLinks}|${NEWLINE}"
ncells=0
fi
$((ncells=ncells+1))
done

# Write out the table cells with images and links to headings
emptyCells=""
for i in $(seq $((4-$ncells)) 4); do
emptyCells="$emptyCells |"
done
echo "${tableCellLinks} ${emptyCells}"

for exampleEnumWithChartType in "${exampleEnumWithChartTypes[@]}"; do
exampleEnum="${exampleEnumWithChartType% *}"
chartType="${exampleEnumWithChartType#* }"
exampleName="${exampleEnum}_${chartType}"

# if [[ "$exampleEnum" = ex10RandomData ]]; then
# Initialize vars
codeStr=""
printOn=0

# Generate section which writes out header with code
codeStr="${codeStr}${NEWLINE}"
codeStr="${codeStr}${NEWLINE}** ${exampleName} <<${exampleName}>>"
codeStr="${codeStr}${NEWLINE}"
codeStr="${codeStr}${NEWLINE}Code"
codeStr="${codeStr}${NEWLINE}"
codeStr="${codeStr}${NEWLINE}#+begin_src dart"
codeStr="${codeStr}${NEWLINE} Widget chartToRun() {"
codeStr="${codeStr}${NEWLINE} LabelLayoutStrategy? xContainerLabelLayoutStrategy;"
codeStr="${codeStr}${NEWLINE} ChartData chartData;"
codeStr="${codeStr}${NEWLINE} ChartOptions chartOptions = const ChartOptions();"

# Read the whole 'example/main_run_doc_example.dart' and generate only the section between the line containing
# "case ExampleEnum.ex10RandomData", and the line containing "break;".
# This is the section of code that is verified by tests to produce images in "integration_test/expected_screenshots"
# which were copied to "doc/readme_images" prior to this Babel script runs in release preparation.
while read codeLine; do
if [[ $codeLine =~ "break;" ]]; then
printOn=0
fi
if [[ $printOn -eq 1 ]]; then
# Do not include the side effects line in code
# if [[ ! $codeLine =~ "SideEffects" ]]; then
codeStr="${codeStr}${NEWLINE} ${codeLine}"
# fi
fi
if [[ $codeLine =~ "case ExampleEnum.${exampleEnum}:" ]]; then
printOn=1
fi
done < example/main_run_doc_example.dart

# Finish code
if [[ $chartType = "lineChart" ]]; then
lower="line"
upper="Line"
else
lower="verticalBar"
upper="VerticalBar"
fi

codeStr="${codeStr}${NEWLINE} var ${lower}ChartContainer = ${upper}ChartTopContainer("
codeStr="${codeStr}${NEWLINE} chartData: chartData,"
codeStr="${codeStr}${NEWLINE} xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,"
codeStr="${codeStr}${NEWLINE} );"
codeStr="${codeStr}${NEWLINE} "
codeStr="${codeStr}${NEWLINE} var ${lower}Chart = ${upper}Chart("
codeStr="${codeStr}${NEWLINE} painter: ${upper}ChartPainter("
codeStr="${codeStr}${NEWLINE} ${lower}ChartContainer: ${lower}ChartContainer,"
codeStr="${codeStr}${NEWLINE} ),"
codeStr="${codeStr}${NEWLINE} );"
codeStr="${codeStr}${NEWLINE} return ${lower}Chart;"
codeStr="${codeStr}${NEWLINE} }"
codeStr="${codeStr}${NEWLINE}#+end_src"
codeStr="${codeStr}${NEWLINE}"
codeStr="${codeStr}${NEWLINE}Result"
codeStr="${codeStr}${NEWLINE}"
codeStr="${codeStr}${NEWLINE}#+CAPTION: Line Chart caption"
codeStr="${codeStr}${NEWLINE}#+ATTR_ORG: :width 300"
codeStr="${codeStr}${NEWLINE}#+ATTR_LATEX: :width 2.0in"
codeStr="${codeStr}${NEWLINE}#+ATTR_HTML: :width 300"
codeStr="${codeStr}${NEWLINE}[[file:doc/readme_images/${exampleName}.png]]"

# One example code between "case ExampleEnum.ex10RandomData", and the line containing "break;" processed,
# so write out the header with code and initialize it
echo "${codeStr}"
# fi
done

#+END_SRC

| [[ex10RandomData_lineChart][file:doc/readme_images/ex10RandomData_lineChart_w150.png]] | [[ex10RandomData_barChart][file:doc/readme_images/ex10RandomData_barChart_w150.png]] | [[ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart][file:doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart_w150.png]] | [[ex30AnimalsBySeasonWithLabelLayoutStrategy_barChart][file:doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_barChart_w150.png]] |
| [[ex31SomeNegativeValues_lineChart][file:doc/readme_images/ex31SomeNegativeValues_lineChart_w150.png]] | [[ex31SomeNegativeValues_barChart][file:doc/readme_images/ex31SomeNegativeValues_barChart_w150.png]] | [[ex32AllPositiveYsYAxisStartsAbove0_lineChart][file:doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_lineChart_w150.png]] | [[ex32AllPositiveYsYAxisStartsAbove0_barChart][file:doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_barChart_w150.png]] |
| [[ex33AllNegativeYsYAxisEndsBelow0_lineChart][file:doc/readme_images/ex33AllNegativeYsYAxisEndsBelow0_lineChart_w150.png]] | [[ex34OptionsDefiningUserTextStyleOnLabels_lineChart][file:doc/readme_images/ex34OptionsDefiningUserTextStyleOnLabels_lineChart_w150.png]] | [[ex35AnimalsBySeasonNoLabelsShown_lineChart][file:doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_lineChart_w150.png]] | [[ex35AnimalsBySeasonNoLabelsShown_barChart][file:doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_barChart_w150.png]] |
| [[ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart][file:doc/readme_images/ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart_w150.png]] | [[ex50StocksWithNegativesWithUserColors_barChart][file:doc/readme_images/ex50StocksWithNegativesWithUserColors_barChart_w150.png]] | [[ex52AnimalsBySeasonLogarithmicScale_lineChart][file:doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_lineChart_w150.png]] | [[ex52AnimalsBySeasonLogarithmicScale_barChart][file:doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_barChart_w150.png]] |
| [[ex60LabelsIteration1_barChart][file:doc/readme_images/ex60LabelsIteration1_barChart_w150.png]] | [[ex60LabelsIteration2_barChart][file:doc/readme_images/ex60LabelsIteration2_barChart_w150.png]] | [[ex60LabelsIteration3_barChart][file:doc/readme_images/ex60LabelsIteration3_barChart_w150.png]] | [[ex60LabelsIteration4_barChart][file:doc/readme_images/ex60LabelsIteration4_barChart_w150.png]] |
| [[ex900ErrorFixUserDataAllZero_lineChart][file:doc/readme_images/ex900ErrorFixUserDataAllZero_lineChart_w150.png]] | | | |

** ex10RandomData_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex10RandomData_lineChart.png]]

** ex10RandomData_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex10RandomData_barChart.png]]

** ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart.png]]

** ex30AnimalsBySeasonWithLabelLayoutStrategy_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_barChart.png]]

** ex31SomeNegativeValues_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex31SomeNegativeValues_lineChart.png]]

** ex31SomeNegativeValues_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex31SomeNegativeValues_barChart.png]]

** ex32AllPositiveYsYAxisStartsAbove0_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_lineChart.png]]

** ex32AllPositiveYsYAxisStartsAbove0_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_barChart.png]]

** ex33AllNegativeYsYAxisEndsBelow0_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex33AllNegativeYsYAxisEndsBelow0_lineChart.png]]

** ex34OptionsDefiningUserTextStyleOnLabels_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex34OptionsDefiningUserTextStyleOnLabels_lineChart.png]]

** ex35AnimalsBySeasonNoLabelsShown_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_lineChart.png]]

** ex35AnimalsBySeasonNoLabelsShown_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_barChart.png]]

** ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart.png]]

** ex50StocksWithNegativesWithUserColors_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex50StocksWithNegativesWithUserColors_barChart.png]]

** ex52AnimalsBySeasonLogarithmicScale_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_lineChart.png]]

** ex52AnimalsBySeasonLogarithmicScale_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_barChart.png]]

** ex60LabelsIteration1_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex60LabelsIteration1_barChart.png]]

** ex60LabelsIteration2_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex60LabelsIteration2_barChart.png]]

** ex60LabelsIteration3_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex60LabelsIteration3_barChart.png]]

** ex60LabelsIteration4_barChart <>

Code

#+begin_src dart
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 barChartContainer = BarChartTopContainer(
chartData: chartData,
xContainerLabelLayoutStrategy: xContainerLabelLayoutStrategy,
);

var barChart = BarChart(
painter: BarChartPainter(
barChartContainer: barChartContainer,
),
);
return barChart;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex60LabelsIteration4_barChart.png]]

** ex900ErrorFixUserDataAllZero_lineChart <>

Code

#+begin_src dart
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;
}
#+end_src

Result

#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex900ErrorFixUserDataAllZero_lineChart.png]]

* Latest release changes

The latest release is 0.5.0

The file: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 https://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 https://docs.flutter.dev/get-started/install.
- Go to https://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 https://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 [[*Running the examples included in flutter_charts]]

There is an example application in flutter_charts: ~example/main_run_doc_example.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 [[*Installing the flutter_charts project as a local clone from Github]] section.
- ~cd $HOME/dev/flutter_charts-master/~
- Paste any of the lines below to the command line.
- To run the example in examples/main_run_doc_example.sh:
#+begin_src bash
tool/demo/run_example.sh
#+end_src
or the equivalent
#+begin_src bash
flutter run examples/main_run_doc_example.sh
#+end_src

(press q in the terminal to quit the current example)

Sample screenshot from running the example app

#+NAME: fig:Line Chart
#+CAPTION: Line Chart caption
#+ATTR_ORG: :width 300
#+ATTR_LATEX: :width 2.0in
#+ATTR_HTML: :width 300
[[file:doc/readme_images/ex10RandomData_lineChart.png]]

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

[[file:doc/readme_images/README.org_iterative-layout-step-1.png]]

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

[[file:doc/readme_images/README.org_iterative-layout-step-2.png]]

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

[[file:doc/readme_images/README.org_iterative-layout-step-3.png]]

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

[[file:doc/readme_images/README.org_iterative-layout-step-4.png]]

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

[[file:doc/readme_images/README.org_iterative-layout-step-5.png]]

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

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

* Testing

To run all unit tests followed by one screenshot-comparing integration test

~tool/test/run_all_tests.sh ex31SomeNegativeValues~

To run all unit tests with all screenshot-comparing integration tests

~tool/test/run_all_tests.sh allSupported~

To run all unit tests with a minimum screenshot-comparing integration tests

~tool/test/run_all_tests.sh minimumNew~

To run one screenshot-comparing integration test without unit tests

~tool/test/run_screenshots_compare_integration_test.sh ex31SomeNegativeValues~

In all above, you can add cleanup and timing as follows:

~d1=$(date +%s); flutter clean; flutter pub upgrade; flutter pub get; tool/test/run_all_tests.sh; echo TOOK $(($(date +%s) - $d1)) seconds~

* TODO Todos

1. [X] During construction of DataRows, enforce default values of Legend names and colors for rows. This fixes issues such as https://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.
The code in ~example/main_run_doc_example.dart~ runs the chart example within; it 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
#+begin_src bash :results output silent :eval no-export
for file in doc/readme_images/ex*; do
rm $file
done
for file in integration_test/screenshots_expected/ex*; do
# cp $file doc/readme_images
convert $file -resize 300 doc/readme_images/$(basename $file)
done
for file in doc/readme_images/ex*; do
copy_name="$(basename $file)"
copy_name="${copy_name/%.*/}"
convert $file -resize 150 $(dirname $file)/${copy_name}_w150.png
done
#+end_src

2. Delete the section AFTER the end_src in [[* Examples with code]], all the way to above the heading [[* Latest release changes]]

3. Run once the script in [[* Examples with code]]. 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.