├── .gitignore
├── .idea
├── .gitignore
├── kotlinc.xml
├── libraries
│ ├── Dart_Packages.xml
│ ├── Dart_SDK.xml
│ ├── Flutter_Plugins.xml
│ └── KotlinJavaRuntime.xml
├── misc.xml
├── modules.xml
├── runConfigurations
│ └── main_dart.xml
├── vcs.xml
└── workspace.xml
├── .metadata
├── AUTHORS
├── CHANGELOG.md
├── LICENSE
├── README-source-for-md.org
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── flutter_charts
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── flutter_charts_android.iml
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── doc
├── notes
│ └── design-and-deploy
│ │ └── design-and-pub-publish-notes.org
└── readme_images
│ ├── README.org_20171102_154245_27063qmN.png
│ ├── README.org_20171102_154329_270633wT.png
│ ├── README.org_20171102_172324_27063E7Z.png
│ ├── README.org_20171102_173422_27063ePm.png
│ ├── README.org_20171102_180657_27063rZs.png
│ ├── README.org_20171102_180915_270634jy.png
│ ├── README.org_20171102_191037_27063qtB.png
│ ├── README.org_20171102_191138_2706333H.png
│ ├── README.org_20171102_195745_27063ECO.png
│ ├── README.org_iterative-layout-step-1.png
│ ├── README.org_iterative-layout-step-2.png
│ ├── README.org_iterative-layout-step-3.png
│ ├── README.org_iterative-layout-step-4.png
│ ├── README.org_iterative-layout-step-5.png
│ ├── ex10RandomData_lineChart.png
│ ├── ex10RandomData_lineChart_w150.png
│ ├── ex10RandomData_verticalBarChart.png
│ ├── ex10RandomData_verticalBarChart_w150.png
│ ├── ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart.png
│ ├── ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart_w150.png
│ ├── ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart.png
│ ├── ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart_w150.png
│ ├── ex31SomeNegativeValues_lineChart.png
│ ├── ex31SomeNegativeValues_lineChart_w150.png
│ ├── ex31SomeNegativeValues_verticalBarChart.png
│ ├── ex31SomeNegativeValues_verticalBarChart_w150.png
│ ├── ex32AllPositiveYsYAxisStartsAbove0_lineChart.png
│ ├── ex32AllPositiveYsYAxisStartsAbove0_lineChart_w150.png
│ ├── ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart.png
│ ├── ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart_w150.png
│ ├── ex33AllNegativeYsYAxisEndsBelow0_lineChart.png
│ ├── ex33AllNegativeYsYAxisEndsBelow0_lineChart_w150.png
│ ├── ex34OptionsDefiningUserTextStyleOnLabels_lineChart.png
│ ├── ex34OptionsDefiningUserTextStyleOnLabels_lineChart_w150.png
│ ├── ex35AnimalsBySeasonNoLabelsShown_lineChart.png
│ ├── ex35AnimalsBySeasonNoLabelsShown_lineChart_w150.png
│ ├── ex35AnimalsBySeasonNoLabelsShown_verticalBarChart.png
│ ├── ex35AnimalsBySeasonNoLabelsShown_verticalBarChart_w150.png
│ ├── ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart.png
│ ├── ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart_w150.png
│ ├── ex50StocksWithNegativesWithUserColors_verticalBarChart.png
│ ├── ex50StocksWithNegativesWithUserColors_verticalBarChart_w150.png
│ ├── ex51AnimalsBySeasonManualLogarithmicScale_lineChart.png
│ ├── ex51AnimalsBySeasonManualLogarithmicScale_lineChart_w150.png
│ ├── ex52AnimalsBySeasonLogarithmicScale_lineChart.png
│ ├── ex52AnimalsBySeasonLogarithmicScale_lineChart_w150.png
│ ├── ex52AnimalsBySeasonLogarithmicScale_verticalBarChart.png
│ ├── ex52AnimalsBySeasonLogarithmicScale_verticalBarChart_w150.png
│ ├── ex60LabelsIteration1_verticalBarChart.png
│ ├── ex60LabelsIteration1_verticalBarChart_w150.png
│ ├── ex60LabelsIteration2_verticalBarChart.png
│ ├── ex60LabelsIteration2_verticalBarChart_w150.png
│ ├── ex60LabelsIteration3_verticalBarChart.png
│ ├── ex60LabelsIteration3_verticalBarChart_w150.png
│ ├── ex60LabelsIteration4_verticalBarChart.png
│ ├── ex60LabelsIteration4_verticalBarChart_w150.png
│ ├── ex900ErrorFixUserDataAllZero_lineChart.png
│ └── ex900ErrorFixUserDataAllZero_lineChart_w150.png
├── example
└── main_run_doc_example.dart
├── flutter_charts.iml
├── google_fonts
├── Comforter-Regular.ttf
└── OFL.txt
├── integration_test
├── README.org
├── deprecated_v1
│ └── screenshot_create_deprecated_v1_test.dart
├── screenshot_create_test.dart
└── screenshots_expected
│ ├── ex10RandomData_barChart_column_stacked_oldManualLayouter.png
│ ├── ex10RandomData_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex30AnimalsBySeasonWithLabelLayoutStrategy_barChart_column_stacked_oldManualLayouter.png
│ ├── ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex31SomeNegativeValues_barChart_column_nonStacked_newAutoLayouter.png
│ ├── ex31SomeNegativeValues_barChart_column_stacked_newAutoLayouter.png
│ ├── ex31SomeNegativeValues_barChart_column_stacked_oldManualLayouter.png
│ ├── ex31SomeNegativeValues_barChart_row_nonStacked_newAutoLayouter.png
│ ├── ex31SomeNegativeValues_barChart_row_stacked_newAutoLayouter.png
│ ├── ex31SomeNegativeValues_lineChart_column_nonStacked_newAutoLayouter.png
│ ├── ex31SomeNegativeValues_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex31SomeNegativeValues_lineChart_row_nonStacked_newAutoLayouter.png
│ ├── ex32AllPositiveYsYAxisStartsAbove0_barChart_column_stacked_oldManualLayouter.png
│ ├── ex32AllPositiveYsYAxisStartsAbove0_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex33AllNegativeYsYAxisEndsBelow0_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex34OptionsDefiningUserTextStyleOnLabels_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex35AnimalsBySeasonNoLabelsShown_barChart_column_stacked_oldManualLayouter.png
│ ├── ex35AnimalsBySeasonNoLabelsShown_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex50StocksWithNegativesWithUserColors_barChart_column_stacked_oldManualLayouter.png
│ ├── ex52AnimalsBySeasonLogarithmicScale_barChart_column_stacked_oldManualLayouter.png
│ ├── ex52AnimalsBySeasonLogarithmicScale_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex60LabelsIteration1_barChart_column_stacked_oldManualLayouter.png
│ ├── ex60LabelsIteration2_barChart_column_stacked_oldManualLayouter.png
│ ├── ex60LabelsIteration3_barChart_column_stacked_oldManualLayouter.png
│ ├── ex60LabelsIteration4_barChart_column_stacked_oldManualLayouter.png
│ ├── ex70AnimalsBySeasonLegendIsColumnStartLooseItemIsRowStartLoose_barChart_column_stacked_oldManualLayouter.png
│ ├── ex71AnimalsBySeasonLegendIsColumnStartTightItemIsRowStartTight_barChart_column_stacked_oldManualLayouter.png
│ ├── ex72AnimalsBySeasonLegendIsRowCenterLooseItemIsRowEndLoose_barChart_column_stacked_oldManualLayouter.png
│ ├── ex73AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTight_barChart_column_stacked_oldManualLayouter.png
│ ├── ex74AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightSecondGreedy_barChart_column_stacked_oldManualLayouter.png
│ ├── ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_nonStacked_newAutoLayouter.png
│ ├── ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_stacked_newAutoLayouter.png
│ ├── ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_stacked_oldManualLayouter.png
│ ├── ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_row_nonStacked_newAutoLayouter.png
│ ├── ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_row_stacked_newAutoLayouter.png
│ ├── ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_column_nonStacked_newAutoLayouter.png
│ ├── ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_column_nonStacked_oldManualLayouter.png
│ ├── ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_row_nonStacked_newAutoLayouter.png
│ ├── ex76AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenAligned_barChart_column_stacked_oldManualLayouter.png
│ ├── ex800EU12CountriesHistoricalPopulation_barChart_column_nonStacked_newAutoLayouter.png
│ ├── ex800EU12CountriesHistoricalPopulation_barChart_column_stacked_newAutoLayouter.png
│ ├── ex800EU12CountriesHistoricalPopulation_barChart_row_nonStacked_newAutoLayouter.png
│ ├── ex800EU12CountriesHistoricalPopulation_barChart_row_stacked_newAutoLayouter.png
│ ├── ex800EU12CountriesHistoricalPopulation_lineChart_column_nonStacked_newAutoLayouter.png
│ ├── ex800EU12CountriesHistoricalPopulation_lineChart_row_nonStacked_newAutoLayouter.png
│ └── ex900ErrorFixUserDataAllZero_lineChart_column_nonStacked_oldManualLayouter.png
├── lib
├── flutter_charts.dart
├── src
│ ├── chart
│ │ ├── cartesian
│ │ │ ├── chart_type
│ │ │ │ ├── bar
│ │ │ │ │ ├── chart.dart
│ │ │ │ │ ├── container
│ │ │ │ │ │ ├── data_container.dart
│ │ │ │ │ │ └── root_container.dart
│ │ │ │ │ └── options.dart
│ │ │ │ └── line
│ │ │ │ │ ├── chart.dart
│ │ │ │ │ ├── container
│ │ │ │ │ ├── data_container.dart
│ │ │ │ │ └── root_container.dart
│ │ │ │ │ └── options.dart
│ │ │ └── container
│ │ │ │ ├── axis_corner_container.dart
│ │ │ │ ├── axislabels_axislines_gridlines_container.dart
│ │ │ │ ├── container_common.dart
│ │ │ │ ├── data_container.dart
│ │ │ │ ├── legend_container.dart
│ │ │ │ ├── line_segment_container.dart
│ │ │ │ └── root_container.dart
│ │ ├── chart.dart
│ │ ├── chart_label_container.dart
│ │ ├── future
│ │ │ └── container_future_additions_and_changes.dart
│ │ ├── iterative_layout_strategy.dart
│ │ ├── model
│ │ │ ├── data_model.dart
│ │ │ └── random_chart_data.dart
│ │ ├── options.dart
│ │ ├── painter.dart
│ │ ├── util
│ │ │ └── example_descriptor.dart
│ │ └── view_model
│ │ │ ├── label_model.dart
│ │ │ └── view_model.dart
│ ├── coded_layout
│ │ └── chart
│ │ │ ├── axis_container.dart
│ │ │ ├── chart_type
│ │ │ ├── bar
│ │ │ │ ├── presenter.dart
│ │ │ │ └── root_container.dart
│ │ │ └── line
│ │ │ │ ├── presenter.dart
│ │ │ │ └── root_container.dart
│ │ │ ├── container.dart
│ │ │ ├── data_container.dart
│ │ │ ├── label_container.dart
│ │ │ ├── line_container.dart
│ │ │ └── presenter.dart
│ ├── morphic
│ │ ├── container
│ │ │ ├── chart_support
│ │ │ │ └── chart_style.dart
│ │ │ ├── constraints.dart
│ │ │ ├── container_alignment.dart
│ │ │ ├── container_edge_padding.dart
│ │ │ ├── container_key.dart
│ │ │ ├── container_layouter_base.dart
│ │ │ ├── label_container.dart
│ │ │ ├── layouter_one_dimensional.dart
│ │ │ ├── morphic_dart_enums.dart
│ │ │ └── unused.dart
│ │ ├── ui2d
│ │ │ └── point.dart
│ │ └── util
│ │ │ └── extensible_enum.dart
│ ├── switch_view_model
│ │ ├── auto_layout
│ │ │ ├── bar
│ │ │ │ └── view_model.dart
│ │ │ └── line
│ │ │ │ └── view_model.dart
│ │ ├── coded_layout
│ │ │ ├── bar
│ │ │ │ └── view_model.dart
│ │ │ └── line
│ │ │ │ └── view_model.dart
│ │ ├── view_model.dart
│ │ └── view_model_cl.dart
│ └── util
│ │ ├── collection.dart
│ │ ├── extensions_dart.dart
│ │ ├── extensions_flutter.dart
│ │ ├── geometry.dart
│ │ ├── util_dart.dart
│ │ ├── util_flutter.dart
│ │ └── vector
│ │ ├── function_matrix_2d.dart
│ │ ├── matrix_2d.dart
│ │ └── vector_2d.dart
└── test
│ └── src
│ ├── README.org
│ ├── chart
│ ├── cartesian
│ │ └── container
│ │ │ └── legend_container.dart
│ └── options.dart
│ ├── switch_view_model
│ └── coded_layout
│ │ ├── bar
│ │ └── view_model.dart
│ │ └── line
│ │ └── view_model.dart
│ ├── test_main.dart
│ └── util
│ └── test_util.dart
├── pubspec.yaml
├── test
├── chart
│ ├── layouter_one_dimensional_test.dart
│ └── util
│ │ └── example_descriptor_test.dart
├── deprecated_v1
│ └── screenshot_validate_deprecated_v1_test.dart
├── screenshot_validate_test.dart
├── tmp
│ └── .gitignore
├── util
│ ├── extensions_dart_test.dart
│ ├── function_test.dart
│ ├── util_dart_test.dart
│ ├── util_flutter_test.dart
│ ├── util_labels_test.dart
│ └── vector
│ │ └── vector_test.dart
└── widget_test.dart
├── test_driver
└── integration_test.dart
└── tool
├── README-tool.org
├── demo
└── run_example.sh
├── frequent_commands.org
├── generate_chart_plantuml.sh
├── make_new_chart_type_structure.sh
└── test
├── deprecated_v1
├── deprecated_frequent_commands.org
├── deprecated_integration_test_create_then_validate_screenshots.sh
├── deprecated_run_all_tests.sh
├── deprecated_run_core_integration_tests.sh
├── deprecated_run_representative_tests.sh
└── deprecated_start_emulator_and_generate_example_descriptor.sh
├── run_all_tests.sh
├── run_core_dart_and_flutter_widget_tests.sh
├── run_screenshots_compare_integration_test.sh
└── start_emulator.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | # mz vvv
2 | # Ignore misc local ides, also .gnupg which is secret.
3 | .emacs.d/
4 | .emacs.d-psession/
5 | .emacs.d-desktop/
6 | .emacs.desktop
7 | .emacs.desktop.lock
8 | .project.el
9 | .projectile
10 | .gnupg/
11 |
12 | # Note: contents of the following folders is ignored via the special .gitignore in the folders.
13 | # - integration_test/screenshots_tested/
14 | # - test/tmp
15 |
16 | # Ignore Emacs, maybe other editors lock files, they are named starting with #.
17 | .\#*
18 |
19 | # Private notes, todos, readme
20 | INTERNAL-GITIGNORE/
21 |
22 | # Ignore my backup files of no interest.
23 | *mzchanged*
24 | *mzdel*
25 |
26 |
27 | # Most of android and ios dirs are needed to run the example/main_run_doc_example.dart sample app (on android, not sure about Ios)
28 | # android
29 | # ios
30 |
31 | # Ignore screenshots_tested/ directory, as screenshots are volatile and change often. Also ignore screenshots_expected_server/ and screenshots_expected_laptop/. Those maintain specific versions.
32 | integration_test/screenshots_tested/
33 | integration_test/screenshots_expected_laptop/
34 | integration_test/screenshots_expected_server/
35 | # mz ^^^
36 |
37 |
38 | # Miscellaneous
39 | *.class
40 | *.log
41 | *.pyc
42 | *.swp
43 | .DS_Store
44 | .atom/
45 | .buildlog/
46 | .history
47 | .svn/
48 |
49 | # 2022-10-17 : Keeping IntelliJ related
50 | # *.iml
51 | # *.ipr
52 | # *.iws
53 | # .idea/workspace.xml contains Edit->Run Configurations settings, so keeping the whole .idea directory.
54 | # Also, there is a .idea/.gitignore, so check that file if workspace.xml is not excluded.
55 | # .idea/
56 |
57 | # 2023-09-15 : IntelliJ : consider ignoring
58 | # .idea/libraries/Dart_Packages.xml
59 | # .idea/misc.xml
60 | # .idea/workspace.xml
61 |
62 | # gitignore-added-2025-01-01: Caches that idea keeps.
63 | .idea/caches/
64 | android/.idea/caches/
65 |
66 | # The .vscode folder contains launch configuration and tasks you configure in
67 | # VS Code which you may wish to be included in version control, so this line
68 | # is commented out by default.
69 | #.vscode/
70 |
71 | # Flutter/Dart/Pub related
72 | **/doc/api/
73 | **/ios/Flutter/.last_build_id
74 | # .dart_tool directory and .packages files are created after you’ve run pub get.
75 | # Don’t check them into source control.
76 | .dart_tool/
77 | .flutter-plugins
78 | .flutter-plugins-dependencies
79 | .packages
80 | .pub-cache/
81 | .pub/
82 | /build/
83 | # pubspec.lock file id created after you’ve run pub get. Leave it out of source control
84 | # because this package is a library package (not an application package, then we would commit it).
85 | pubspec.lock
86 |
87 | # Web related
88 | lib/generated_plugin_registrant.dart
89 |
90 | # Symbolication related
91 | app.*.symbols
92 |
93 | # Obfuscation related
94 | app.*.map.json
95 |
96 | # Android Studio will place build artifacts here
97 | /android/app/debug
98 | /android/app/profile
99 | /android/app/release
100 |
101 |
102 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | # workspace.xml contains Edit->Run Configurations, so keep it
4 | # /workspace.xml
5 | # Datasource local storage ignored files
6 | /dataSources/
7 | /dataSources.local.xml
8 | # Editor-based HTTP Client requests
9 | /httpRequests/
10 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_Plugins.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/KotlinJavaRuntime.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: "17025dd88227cd9532c33fa78f5250d548d87e9a"
8 | channel: "stable"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
17 | base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
18 | - platform: android
19 | create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
20 | base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
21 |
22 | # User provided section
23 |
24 | # List of Local paths (relative to this file) that should be
25 | # ignored by the migrate tool.
26 | #
27 | # Files that are not part of the templates will be ignored by default.
28 | unmanaged_files:
29 | - 'lib/main.dart'
30 | - 'ios/Runner.xcodeproj/project.pbxproj'
31 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | Milan Zimmermann (milan.zimmermann@gmail.com)
2 |
3 | see also: LICENSE
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017, 2018, 2019, 2020, 2021, 2022 Milan Zimmermann (milan.zimmermann@gmail.com)
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
24 | The views and conclusions contained in the software and documentation are those
25 | of the authors and should not be interpreted as representing official policies,
26 | either expressed or implied, of the FreeBSD Project.
27 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 | avoid_relative_lib_imports: false # todo-01 : remove this later. Need for example prevents this
28 | non_constant_identifier_names: false # todo-01 : remove this, but figure out better naming for long names
29 | hash_and_equals: true # todo-00-last : added this, probably included by default
30 |
31 | # Additional information about this file can be found at
32 | # https://dart.dev/guides/language/analysis-options
33 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
5 | id "dev.flutter.flutter-gradle-plugin"
6 | }
7 |
8 | android {
9 | namespace = "com.example.flutter_charts"
10 | compileSdk = flutter.compileSdkVersion
11 | // todo-00-done-mzchanged-2025-01-01: Build warning suggests to hardcode the ndkVersion.
12 | // ndkVersion = flutter.ndkVersion
13 | ndkVersion = "27.0.12077973"
14 | // ndkVersion = "28.0.12674087"
15 | //
16 |
17 | compileOptions {
18 | sourceCompatibility = JavaVersion.VERSION_17
19 | targetCompatibility = JavaVersion.VERSION_17
20 | }
21 |
22 | kotlinOptions {
23 | jvmTarget = JavaVersion.VERSION_17
24 | }
25 |
26 | defaultConfig {
27 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
28 | applicationId = "com.example.flutter_charts"
29 | // You can update the following values to match your application needs.
30 | // For more information, see: https://flutter.dev/to/review-gradle-config.
31 | minSdk = flutter.minSdkVersion
32 | targetSdk = flutter.targetSdkVersion
33 | versionCode = flutter.versionCode
34 | versionName = flutter.versionName
35 | }
36 |
37 | buildTypes {
38 | release {
39 | // TODO: Add your own signing config for the release build.
40 | // Signing with the debug keys for now, so `flutter run --release` works.
41 | signingConfig = signingConfigs.debug
42 | }
43 | }
44 | }
45 |
46 | flutter {
47 | source = "../.."
48 | }
49 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/flutter_charts/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.flutter_charts
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity()
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | rootProject.buildDir = "../build"
9 | subprojects {
10 | project.buildDir = "${rootProject.buildDir}/${project.name}"
11 | }
12 | subprojects {
13 | project.evaluationDependsOn(":app")
14 | }
15 |
16 | tasks.register("clean", Delete) {
17 | delete rootProject.buildDir
18 | }
19 |
--------------------------------------------------------------------------------
/android/flutter_charts_android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-all.zip
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }()
9 |
10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11 |
12 | repositories {
13 | google()
14 | mavenCentral()
15 | gradlePluginPortal()
16 | }
17 | }
18 |
19 | /* todo-00-done-mzchanged-2025-01-01: To fix error during build
20 | plugins {
21 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
22 | id "com.android.application" version "8.2.1" apply false
23 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false
24 | }
25 | */
26 |
27 | plugins {
28 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
29 | id 'com.android.application' version '8.7.3' apply false
30 | // id 'com.android.library' version '8.7.3' apply false
31 | id 'org.jetbrains.kotlin.android' version '2.0.20' apply false
32 | }
33 |
34 | include ":app"
35 |
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_154245_27063qmN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_154245_27063qmN.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_154329_270633wT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_154329_270633wT.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_172324_27063E7Z.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_172324_27063E7Z.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_173422_27063ePm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_173422_27063ePm.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_180657_27063rZs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_180657_27063rZs.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_180915_270634jy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_180915_270634jy.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_191037_27063qtB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_191037_27063qtB.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_191138_2706333H.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_191138_2706333H.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_20171102_195745_27063ECO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_20171102_195745_27063ECO.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_iterative-layout-step-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_iterative-layout-step-1.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_iterative-layout-step-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_iterative-layout-step-2.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_iterative-layout-step-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_iterative-layout-step-3.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_iterative-layout-step-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_iterative-layout-step-4.png
--------------------------------------------------------------------------------
/doc/readme_images/README.org_iterative-layout-step-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/README.org_iterative-layout-step-5.png
--------------------------------------------------------------------------------
/doc/readme_images/ex10RandomData_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex10RandomData_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex10RandomData_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex10RandomData_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex10RandomData_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex10RandomData_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex10RandomData_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex10RandomData_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex30AnimalsBySeasonWithLabelLayoutStrategy_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex31SomeNegativeValues_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex31SomeNegativeValues_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex31SomeNegativeValues_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex31SomeNegativeValues_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex31SomeNegativeValues_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex31SomeNegativeValues_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex31SomeNegativeValues_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex31SomeNegativeValues_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex32AllPositiveYsYAxisStartsAbove0_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex33AllNegativeYsYAxisEndsBelow0_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex33AllNegativeYsYAxisEndsBelow0_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex33AllNegativeYsYAxisEndsBelow0_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex33AllNegativeYsYAxisEndsBelow0_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex34OptionsDefiningUserTextStyleOnLabels_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex34OptionsDefiningUserTextStyleOnLabels_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex34OptionsDefiningUserTextStyleOnLabels_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex34OptionsDefiningUserTextStyleOnLabels_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex35AnimalsBySeasonNoLabelsShown_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex50StocksWithNegativesWithUserColors_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex50StocksWithNegativesWithUserColors_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex50StocksWithNegativesWithUserColors_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex50StocksWithNegativesWithUserColors_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex51AnimalsBySeasonManualLogarithmicScale_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex51AnimalsBySeasonManualLogarithmicScale_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex51AnimalsBySeasonManualLogarithmicScale_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex51AnimalsBySeasonManualLogarithmicScale_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_lineChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex52AnimalsBySeasonLogarithmicScale_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex60LabelsIteration1_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex60LabelsIteration1_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex60LabelsIteration1_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex60LabelsIteration1_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex60LabelsIteration2_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex60LabelsIteration2_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex60LabelsIteration2_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex60LabelsIteration2_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex60LabelsIteration3_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex60LabelsIteration3_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex60LabelsIteration3_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex60LabelsIteration3_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex60LabelsIteration4_verticalBarChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex60LabelsIteration4_verticalBarChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex60LabelsIteration4_verticalBarChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex60LabelsIteration4_verticalBarChart_w150.png
--------------------------------------------------------------------------------
/doc/readme_images/ex900ErrorFixUserDataAllZero_lineChart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex900ErrorFixUserDataAllZero_lineChart.png
--------------------------------------------------------------------------------
/doc/readme_images/ex900ErrorFixUserDataAllZero_lineChart_w150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/doc/readme_images/ex900ErrorFixUserDataAllZero_lineChart_w150.png
--------------------------------------------------------------------------------
/flutter_charts.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/google_fonts/Comforter-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/google_fonts/Comforter-Regular.ttf
--------------------------------------------------------------------------------
/google_fonts/OFL.txt:
--------------------------------------------------------------------------------
1 | Copyright 2015 The Comforter Project Authors (https://github.com/googlefonts/comforter)
2 |
3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 | This license is copied below, and is also available with a FAQ at:
5 | http://scripts.sil.org/OFL
6 |
7 |
8 | -----------------------------------------------------------
9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 | -----------------------------------------------------------
11 |
12 | PREAMBLE
13 | The goals of the Open Font License (OFL) are to stimulate worldwide
14 | development of collaborative font projects, to support the font creation
15 | efforts of academic and linguistic communities, and to provide a free and
16 | open framework in which fonts may be shared and improved in partnership
17 | with others.
18 |
19 | The OFL allows the licensed fonts to be used, studied, modified and
20 | redistributed freely as long as they are not sold by themselves. The
21 | fonts, including any derivative works, can be bundled, embedded,
22 | redistributed and/or sold with any software provided that any reserved
23 | names are not used by derivative works. The fonts and derivatives,
24 | however, cannot be released under any other type of license. The
25 | requirement for fonts to remain under this license does not apply
26 | to any document created using the fonts or their derivatives.
27 |
28 | DEFINITIONS
29 | "Font Software" refers to the set of files released by the Copyright
30 | Holder(s) under this license and clearly marked as such. This may
31 | include source files, build scripts and documentation.
32 |
33 | "Reserved Font Name" refers to any names specified as such after the
34 | copyright statement(s).
35 |
36 | "Original Version" refers to the collection of Font Software components as
37 | distributed by the Copyright Holder(s).
38 |
39 | "Modified Version" refers to any derivative made by adding to, deleting,
40 | or substituting -- in part or in whole -- any of the components of the
41 | Original Version, by changing formats or by porting the Font Software to a
42 | new environment.
43 |
44 | "Author" refers to any designer, engineer, programmer, technical
45 | writer or other person who contributed to the Font Software.
46 |
47 | PERMISSION & CONDITIONS
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 | redistribute, and sell modified and unmodified copies of the Font
51 | Software, subject to the following conditions:
52 |
53 | 1) Neither the Font Software nor any of its individual components,
54 | in Original or Modified Versions, may be sold by itself.
55 |
56 | 2) Original or Modified Versions of the Font Software may be bundled,
57 | redistributed and/or sold with any software, provided that each copy
58 | contains the above copyright notice and this license. These can be
59 | included either as stand-alone text files, human-readable headers or
60 | in the appropriate machine-readable metadata fields within text or
61 | binary files as long as those fields can be easily viewed by the user.
62 |
63 | 3) No Modified Version of the Font Software may use the Reserved Font
64 | Name(s) unless explicit written permission is granted by the corresponding
65 | Copyright Holder. This restriction only applies to the primary font name as
66 | presented to the users.
67 |
68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 | Software shall not be used to promote, endorse or advertise any
70 | Modified Version, except to acknowledge the contribution(s) of the
71 | Copyright Holder(s) and the Author(s) or with their explicit written
72 | permission.
73 |
74 | 5) The Font Software, modified or unmodified, in part or in whole,
75 | must be distributed entirely under this license, and must not be
76 | distributed under any other license. The requirement for fonts to
77 | remain under this license does not apply to any document created
78 | using the Font Software.
79 |
80 | TERMINATION
81 | This license becomes null and void if any of the above conditions are
82 | not met.
83 |
84 | DISCLAIMER
85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 | OTHER DEALINGS IN THE FONT SOFTWARE.
94 |
--------------------------------------------------------------------------------
/integration_test/README.org:
--------------------------------------------------------------------------------
1 | * Integration test in Flutter
2 |
3 | Flutter *integration test* is performed by the command ~flutter drive~; the test file
4 | is the file in the ~--target=path_to_test.dart~. The test files are executed ON THE DEVICE,
5 | AND COULD BE CALLED ON-DEVICE-TESTS.
6 |
7 | Files in this directory which end with '_test.dart' are such *integration tests*, performed
8 | in a command such as
9 |
10 | #+begin_src: sh
11 | # Note: "$examplesDescriptors" may be "allSupported" or similar single test or named group of tests,
12 | # or a list of single test names
13 | flutter drive \
14 | --dart-define=EXAMPLES_DESCRIPTORS="$examplesDescriptors" \
15 | --driver=test_driver/integration_test.dart \
16 | --target=integration_test/screenshot_create_test.dart
17 | #+end_src
18 |
19 | Optionally, the *integration test* can be controlled, from the computer, by another program, which could be described as
20 | 'on-computer driver for the on-device integration test'. Such 'on-computer driver' is the program
21 | ~--driver=test_driver/integration_test.dart~ program above; it runs on the computer,
22 | and controls the program in the ~--target=integration_test/screenshot_create_test.dart~ running on the device (drive).
23 |
24 | Note: The naming of the on-device integration test TARGET and it's on-computer controlling program DRIVER
25 | seems backwards, but Flutter seems to insist on it, by making the name 'integration_test.dart' for the DRIVER
26 | the default required name.
27 |
28 | See the "Testing in Flutter" heading in https://github.com/mzimmerm/flutter_experiments/blob/master/doc/flutter-notes.org
29 | for details of Dart unit test, Flutter widget test and Flutter integration test.
30 |
31 | See https://docs.flutter.dev/cookbook/testing/integration/introduction
32 | for integration testing in Flutter.
33 |
34 | See https://dev.to/mjablecnik/take-screenshot-during-flutter-integration-tests-435k
35 | for how to take a screenshot from your Flutter app inside flutter test integration_test/app_test.dart;
36 | but the same should work from an actual flutter run --device_id app.dart
37 |
38 |
--------------------------------------------------------------------------------
/integration_test/deprecated_v1/screenshot_create_deprecated_v1_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 | import 'package:integration_test/integration_test.dart' show IntegrationTestWidgetsFlutterBinding;
3 |
4 | import 'package:flutter_charts/src/chart/util/example_descriptor.dart' show ExampleDescriptor;
5 | import 'package:flutter_charts/test/src/util/test_util.dart';
6 | import 'package:flutter_charts/test/src/test_main.dart' as app;
7 |
8 | /// @Deprecated, see 'integration_test/screenshot_create_test_new.dart'.
9 | ///
10 | /// Integration testing by taking a screenshot from the example app,
11 | /// and comparing the produced screenshot with a known correct screenshot.
12 | ///
13 | void main() {
14 | final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
15 |
16 | testWidgets('screenshot', (WidgetTester tester) async {
17 | var screenshotPaths = ScreenshotPaths(exampleDescriptor: ExampleDescriptor.requestedExampleToRun());
18 | String screenshotPath = screenshotPaths.actualScreenshotPath;
19 |
20 | // Build the app and run it on device.
21 | app.main();
22 |
23 | // This is required prior to taking the screenshot (Android only).
24 | await binding.convertFlutterSurfaceToImage();
25 |
26 | // Trigger a frame.
27 | await tester.pumpAndSettle();
28 |
29 | // Take screenshot.
30 | await binding.takeScreenshot(screenshotPath);
31 |
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex10RandomData_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex10RandomData_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex10RandomData_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex10RandomData_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex30AnimalsBySeasonWithLabelLayoutStrategy_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex30AnimalsBySeasonWithLabelLayoutStrategy_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex30AnimalsBySeasonWithLabelLayoutStrategy_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_column_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_column_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_column_stacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_column_stacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_row_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_row_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_row_stacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex31SomeNegativeValues_barChart_row_stacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex31SomeNegativeValues_lineChart_column_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex31SomeNegativeValues_lineChart_column_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex31SomeNegativeValues_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex31SomeNegativeValues_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex31SomeNegativeValues_lineChart_row_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex31SomeNegativeValues_lineChart_row_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex32AllPositiveYsYAxisStartsAbove0_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex32AllPositiveYsYAxisStartsAbove0_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex32AllPositiveYsYAxisStartsAbove0_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex32AllPositiveYsYAxisStartsAbove0_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex33AllNegativeYsYAxisEndsBelow0_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex33AllNegativeYsYAxisEndsBelow0_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex34OptionsDefiningUserTextStyleOnLabels_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex34OptionsDefiningUserTextStyleOnLabels_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex35AnimalsBySeasonNoLabelsShown_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex35AnimalsBySeasonNoLabelsShown_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex35AnimalsBySeasonNoLabelsShown_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex35AnimalsBySeasonNoLabelsShown_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex40LanguagesWithYOrdinalUserLabelsAndUserColors_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex50StocksWithNegativesWithUserColors_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex50StocksWithNegativesWithUserColors_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex52AnimalsBySeasonLogarithmicScale_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex52AnimalsBySeasonLogarithmicScale_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex52AnimalsBySeasonLogarithmicScale_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex52AnimalsBySeasonLogarithmicScale_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex60LabelsIteration1_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex60LabelsIteration1_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex60LabelsIteration2_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex60LabelsIteration2_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex60LabelsIteration3_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex60LabelsIteration3_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex60LabelsIteration4_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex60LabelsIteration4_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex70AnimalsBySeasonLegendIsColumnStartLooseItemIsRowStartLoose_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex70AnimalsBySeasonLegendIsColumnStartLooseItemIsRowStartLoose_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex71AnimalsBySeasonLegendIsColumnStartTightItemIsRowStartTight_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex71AnimalsBySeasonLegendIsColumnStartTightItemIsRowStartTight_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex72AnimalsBySeasonLegendIsRowCenterLooseItemIsRowEndLoose_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex72AnimalsBySeasonLegendIsRowCenterLooseItemIsRowEndLoose_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex73AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTight_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex73AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTight_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex74AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightSecondGreedy_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex74AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightSecondGreedy_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_stacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_stacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_row_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_row_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_row_stacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_barChart_row_stacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_column_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_column_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_row_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded_lineChart_row_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex76AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenAligned_barChart_column_stacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex76AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenAligned_barChart_column_stacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_barChart_column_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_barChart_column_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_barChart_column_stacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_barChart_column_stacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_barChart_row_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_barChart_row_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_barChart_row_stacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_barChart_row_stacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_lineChart_column_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_lineChart_column_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_lineChart_row_nonStacked_newAutoLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex800EU12CountriesHistoricalPopulation_lineChart_row_nonStacked_newAutoLayouter.png
--------------------------------------------------------------------------------
/integration_test/screenshots_expected/ex900ErrorFixUserDataAllZero_lineChart_column_nonStacked_oldManualLayouter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzimmerm/flutter_charts/57b404cab0cb764e21167fa897fe3f2acdb0be85/integration_test/screenshots_expected/ex900ErrorFixUserDataAllZero_lineChart_column_nonStacked_oldManualLayouter.png
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/chart_type/bar/chart.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart' as widgets;
2 |
3 | // base libraries
4 | import 'package:flutter_charts/src/chart/chart.dart';
5 | import 'package:flutter_charts/src/chart/painter.dart' show FlutterChartPainter;
6 | import 'package:flutter_charts/src/chart/view_model/view_model.dart' show ChartViewModel;
7 |
8 | /// Provides paint for the vertical bar chart.
9 | ///
10 | /// It extends [CustomPaint] which is the flutter widget
11 | /// that provides a canvas on which to draw during the paint phase.
12 | /// The core override is to set the concrete [ChartContainer], and
13 | /// it's [ChartContainer.isStacked] setting.
14 | class BarChart extends FlutterChart {
15 | /// Default constructor accepts size
16 | BarChart({
17 | widgets.Key? key,
18 | required FlutterChartPainter flutterChartPainter,
19 | required ChartViewModel chartViewModel,
20 | widgets.CustomPainter? foregroundPainter,
21 | widgets.Size size = widgets.Size.zero,
22 | widgets.Widget? child,
23 | }) : super(
24 | key: key,
25 | flutterChartPainter: flutterChartPainter,
26 | chartViewModel: chartViewModel,
27 | foregroundPainter: foregroundPainter,
28 | size: size,
29 | child: child,
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/chart_type/bar/container/root_container.dart:
--------------------------------------------------------------------------------
1 | // base libraries
2 | import 'package:flutter_charts/src/chart/cartesian/container/root_container.dart';
3 | import 'package:flutter_charts/src/chart/cartesian/container/axislabels_axislines_gridlines_container.dart';
4 | import 'package:flutter_charts/src/chart/cartesian/container/data_container.dart';
5 | import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
6 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
7 |
8 | /// The container-hierarchy root container of the vertical bar chart.
9 | class BarChartRootContainer extends ChartRootContainer {
10 |
11 | BarChartRootContainer({
12 | required LegendContainer legendContainer,
13 | required TransposingAxisLabels horizontalAxisContainer,
14 | required TransposingAxisLabels verticalAxisContainerFirst,
15 | required TransposingAxisLabels verticalAxisContainer,
16 | required DataContainer dataContainer,
17 | required ChartViewModel chartViewModel,
18 | }) : super(
19 | legendContainer: legendContainer,
20 | horizontalAxisContainer: horizontalAxisContainer,
21 | verticalAxisContainerFirst: verticalAxisContainerFirst,
22 | verticalAxisContainer: verticalAxisContainer,
23 | dataContainer: dataContainer,
24 | chartViewModel: chartViewModel,
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/chart_type/bar/options.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart' show immutable;
2 |
3 | /// The options specific for the [BarChart].
4 | @immutable
5 | class BarChartOptions {
6 | /// Constructor of [BarChartOptions]. No options specific for vertical bar chart.
7 | const BarChartOptions();
8 | }
9 |
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/chart_type/line/chart.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart' as widgets;
2 |
3 | // base libraries
4 | import 'package:flutter_charts/src/chart/chart.dart';
5 | import 'package:flutter_charts/src/chart/painter.dart' show FlutterChartPainter;
6 | import 'package:flutter_charts/src/chart/view_model/view_model.dart' show ChartViewModel;
7 |
8 | /// Provides paint for the line chart.
9 | ///
10 | /// It extends [CustomPaint] which is the flutter widget
11 | /// that provides a canvas on which to draw during the paint phase.
12 | /// The core override is to set the concrete [ChartContainer], and
13 | /// it's [ChartContainer.isStacked] setting.
14 | ///
15 | /// Note: The [LineChart] constructor shows how to call a super
16 | /// with named parameters. The super's [CustomPaint] single constructor is
17 | /// `const CustomPaint({ Key key, this.painter, this.foregroundPainter,
18 | /// this.size: Size.zero, Widget child })`
19 | /// and syntax of a constructor with named parameters
20 | /// can be seen in the [LineChart] constructor.
21 | class LineChart extends FlutterChart {
22 | /// Default constructor accepts size
23 | LineChart({
24 | widgets.Key? key,
25 | required FlutterChartPainter flutterChartPainter,
26 | required ChartViewModel chartViewModel,
27 | widgets.CustomPainter? foregroundPainter,
28 | widgets.Size size = widgets.Size.zero,
29 | widgets.Widget? child,
30 | }) : super(
31 | key: key,
32 | flutterChartPainter: flutterChartPainter,
33 | chartViewModel: chartViewModel,
34 | foregroundPainter: foregroundPainter,
35 | size: size,
36 | child: child,
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/chart_type/line/container/root_container.dart:
--------------------------------------------------------------------------------
1 | // base libraries
2 | import 'package:flutter_charts/src/chart/cartesian/container/root_container.dart';
3 | import 'package:flutter_charts/src/chart/cartesian/container/axislabels_axislines_gridlines_container.dart';
4 | import 'package:flutter_charts/src/chart/cartesian/container/data_container.dart';
5 | import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
6 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
7 |
8 | /// The container-hierarchy root container of the line chart.
9 | class LineChartRootContainer extends ChartRootContainer {
10 | LineChartRootContainer({
11 | required LegendContainer legendContainer,
12 | required TransposingAxisLabels horizontalAxisContainer,
13 | required TransposingAxisLabels verticalAxisContainerFirst,
14 | required TransposingAxisLabels verticalAxisContainer,
15 | required DataContainer dataContainer,
16 | required ChartViewModel chartViewModel,
17 | }) : super(
18 | legendContainer: legendContainer,
19 | horizontalAxisContainer: horizontalAxisContainer,
20 | verticalAxisContainerFirst: verticalAxisContainerFirst,
21 | verticalAxisContainer: verticalAxisContainer,
22 | dataContainer: dataContainer,
23 | chartViewModel: chartViewModel,
24 | );
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/chart_type/line/options.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui' as ui show Color;
2 | import 'package:flutter/material.dart' as material show Colors; // any color we can use is from here, more descriptive
3 | import 'package:flutter/foundation.dart' show immutable;
4 |
5 | @immutable
6 | class LineChartOptions {
7 | /// Control the look of the circle on line chart
8 | final double hotspotInnerRadius;
9 | final double hotspotOuterRadius;
10 |
11 | /// Paint for the inner circle on line chart.
12 | /// Using common paint object for all circles, we
13 | /// force all circles to look the same.
14 | /// todo 3 - consider per valuesRow control.
15 | final ui.Color hotspotInnerPaintColor;
16 |
17 | final ui.Color hotspotOuterPaintColor;
18 |
19 | /// Width of the line connecting the circles on line chart.
20 | /// Paint for one series. Using one option for all series, we
21 | /// force all series width the same.
22 | /// todo 3 - consider per valuesRow width instances.
23 | final double lineStrokeWidth;
24 |
25 | /// Constructor with default values.
26 | const LineChartOptions({
27 | this.hotspotInnerRadius = 3.0,
28 | this.hotspotOuterRadius = 6.0,
29 | this.hotspotInnerPaintColor = material.Colors.yellow,
30 | this.hotspotOuterPaintColor = material.Colors.black,
31 | this.lineStrokeWidth = 3.0,
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/container/axis_corner_container.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui' as ui show Rect, Canvas, Paint;
2 | import 'package:flutter/material.dart' as material show Colors;
3 |
4 | // this level
5 | import 'package:flutter_charts/src/chart/cartesian/container/container_common.dart' as container_common;
6 |
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart' as view_model;
8 |
9 | // base libraries
10 | import 'package:flutter_charts/src/morphic/container/container_layouter_base.dart';
11 |
12 |
13 |
14 | class AxisCornerContainer extends container_common.ChartAreaContainer {
15 | AxisCornerContainer({
16 | required view_model.ChartViewModel chartViewModel,
17 | List? children,
18 | }) : super(
19 | chartViewModel: chartViewModel,
20 | children: children,
21 | );
22 |
23 | /// This default implementation has no children, it is leaf, so override the only method
24 | /// needed to override for leafs
25 | @override
26 | layout_Post_Leaf_SetSize_FromInternals() {
27 | /// Set some small layoutSize
28 | ui.Rect rect = const ui.Rect.fromLTWH(0.0, 0.0, 20.0, 20.0);
29 |
30 | layoutSize = rect.size;
31 | }
32 |
33 | @override
34 | paint(ui.Canvas canvas) {
35 | ui.Paint paint = (ui.Paint()..color = material.Colors.red);
36 | canvas.drawRect(offset & layoutSize, paint);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/container/container_common.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_charts/src/chart/iterative_layout_strategy.dart' show LabelLayoutStrategy;
2 | import 'package:flutter_charts/src/chart/view_model/view_model.dart' show ChartViewModel;
3 |
4 | import 'package:flutter_charts/src/morphic/container/container_layouter_base.dart';
5 | import 'package:flutter_charts/src/morphic/container/container_key.dart';
6 |
7 | // documentation
8 | import 'package:flutter_charts/src/chart/cartesian/container/root_container.dart';
9 | import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
10 | import 'package:flutter_charts/src/chart/cartesian/container/data_container.dart';
11 | import 'package:flutter_charts/src/chart/cartesian/container/axislabels_axislines_gridlines_container.dart';
12 |
13 | /// Base class which manages, lays out, offsets, and paints
14 | /// all [BoxContainer] derived classes used on charts.
15 | ///
16 | /// In addition to the [BoxContainer] responsibilities,
17 | /// this class has access to [chartViewModel], instance of [ChartViewModel],
18 | /// which builds the whole [ChartRootContainer] container hierarchy.
19 | ///
20 | /// The basic top level chart blocks are:
21 | /// - [ChartRootContainer] - the whole chart
22 | /// - [LegendContainer] - manages the legend
23 | /// - [TransposingOutputAxisLabels] - manages the output labels layout, which defines:
24 | /// - Y axis label sizes
25 | /// - Y positions of Y axis labels, defined as yTickY.
26 | /// yTicksY s are the Y points of extrapolated data values
27 | /// and also Y points on which the Y labels are centered.
28 | /// - [TransposingInputAxisLabels] - Equivalent to [TransposingOutputAxisLabels], but manages the input labels.
29 | /// - [DataContainer] and extensions - manages the area which displays:
30 | /// - Data as bar chart, line chart, or other chart type.
31 | /// - Grid (this includes the X and Y axis).
32 | ///
33 | /// See [BoxContainer] for discussion of roles of this class.
34 | /// This extension of [BoxContainer] has the added ability
35 | /// to access the container's parent, which is handled by
36 | /// [chartViewModel].
37 | abstract class ChartAreaContainer extends PositioningBoxContainer {
38 | /// Constructs instance, by providing (this derived class required) [chartViewModel].
39 | ///
40 | /// The instance of [ChartViewModel] is needed on all instances of [ChartAreaContainer]s
41 | /// tha
42 | ChartAreaContainer({
43 | required this.chartViewModel,
44 | List? children,
45 | ContainerKey? key,
46 | ConstraintsWeight constraintsWeight = ConstraintsWeight.defaultWeight,
47 | }) : super(
48 | children: children,
49 | key: key,
50 | constraintsWeight: constraintsWeight,
51 | );
52 |
53 | /// The instance of [ChartViewModel] which makes (produces) the chart view:
54 | /// both the view root, the [ChartRootContainer], and all [ChartAreaContainer]s inside.
55 | ///
56 | /// Needed to be held on this [ChartAreaContainer]s for the legacy subsystem
57 | /// to reach data model, as well as the view.
58 | // todo-02-design-legacy : can we move this on a CL class if only needed by legacy?
59 | final ChartViewModel chartViewModel;
60 |
61 | // todo-later : Go over all usages, and move child building to this method
62 | // from constructors.
63 | // In particular: why do we construct in buildAndReplaceChildren in DataContainer,
64 | // while construct in constructor in NewVerticalAxisContainer?
65 | // Etc
66 | @override
67 | void buildAndReplaceChildren() {
68 | buildAndReplaceChildrenDefault();
69 | }
70 | }
71 |
72 | /// [ChartAreaContainer] which provides ability to connect [LabelLayoutStrategy] to [BoxContainer].
73 | ///
74 | /// Extensions can create [ChartAreaContainer]s with default or custom layout strategy.
75 | abstract class AdjustableLabelsChartAreaContainer extends ChartAreaContainer implements AdjustableLabels {
76 | /// The strategy of this [AdjustableLabelsChartAreaContainer] and all instances
77 | /// is shared from the (single) [ChartViewModel.inputLabelLayoutStrategyInst].
78 | LabelLayoutStrategy get labelLayoutStrategy => chartViewModel.inputLabelLayoutStrategyInst;
79 |
80 | AdjustableLabelsChartAreaContainer({
81 | required ChartViewModel chartViewModel,
82 | }) : super(
83 | chartViewModel: chartViewModel,
84 | ) {
85 | chartViewModel.inputLabelLayoutStrategyInst.onContainer(this);
86 | }
87 | }
88 |
89 | /// A marker of container with adjustable contents,
90 | /// such as labels that can be skipped.
91 | // todo-05-morph LabelLayoutStrategy should be a member of AdjustableContainer, not
92 | // in AdjustableLabelsChartAreaContainer
93 | // Also, AdjustableLabels and perhaps AdjustableLabelsChartAreaContainer should be a mixin.
94 | // But Dart bug #25742 does not allow mixins with named parameters.
95 |
96 | abstract class AdjustableLabels {
97 | bool labelsOverlap();
98 | }
99 |
100 | /// The behavior mixin class allows to plug in to the [ChartRootContainer] a behavior that is specific for a line chart
101 | /// or vertical bar chart.
102 | ///
103 | /// The behavior is plugged in the [ChartViewModel].
104 | abstract class ChartBehavior {
105 | /// Behavior allows to start Y axis at data minimum (rather than 0).
106 | ///
107 | /// The request is asked by [DataContainerOptions.extendAxisToOriginRequested],
108 | /// but the implementation of this behavior must confirm it.
109 | /// See the extensions of this class for overrides of this method.
110 | ///
111 | /// [ChartBehavior] is mixed in to [ChartRootContainer]. This method
112 | /// is implemented by concrete [LineChartRootContainer] and [BarChartRootContainer].
113 | /// - In the stacked containers, such as [BarChartRootContainer], it should return [false],
114 | /// as stacked values should always start at zero, because stacked charts must show absolute values.
115 | /// See [BarChartRootContainer.extendAxisToOrigin].
116 | /// - In the unstacked containers such as [LineChartRootContainer], this is usually implemented to
117 | /// return the option [DataContainerOptions.extendAxisToOriginRequested],
118 | /// see [LineChartRootContainer.extendAxisToOrigin].
119 | ///
120 | bool get extendAxisToOrigin;
121 | }
122 |
--------------------------------------------------------------------------------
/lib/src/chart/cartesian/container/root_container.dart:
--------------------------------------------------------------------------------
1 | import 'package:logger/logger.dart' as logger;
2 |
3 | // This level
4 | import 'package:flutter_charts/src/chart/cartesian/container/container_common.dart';
5 | import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
6 | import 'package:flutter_charts/src/chart/cartesian/container/axislabels_axislines_gridlines_container.dart';
7 | import 'package:flutter_charts/src/chart/cartesian/container/data_container.dart';
8 | import 'package:flutter_charts/src/chart/cartesian/container/axis_corner_container.dart';
9 | import 'package:flutter_charts/src/morphic/container/container_layouter_base.dart';
10 |
11 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
12 |
13 | // comments
14 | import 'package:flutter_charts/src/chart/painter.dart';
15 |
16 | /// The root [BoxContainer] of the whole chart.
17 | ///
18 | /// Concrete [ChartRootContainer] instance is created new on every [FlutterChartPainter.paint] invocation
19 | /// in the [ChartViewModel.chartRootContainerCreateBuildLayoutPaint]. Note that [ChartViewModel]
20 | /// instance is created only once per chart, NOT recreated on every [FlutterChartPainter.paint] invocation.
21 | ///
22 | /// Child containers calculate coordinates of chart points used for painting grid, labels, chart points etc.
23 | ///
24 | class ChartRootContainer extends ChartAreaContainer {
25 |
26 | ChartRootContainer({
27 | required this.legendContainer,
28 | required this.horizontalAxisContainer,
29 | required this.verticalAxisContainer,
30 | required this.verticalAxisContainerFirst,
31 | required this.dataContainer,
32 | required ChartViewModel chartViewModel,
33 | }) : super(chartViewModel: chartViewModel) {
34 | logger.Logger().d(' Constructing ChartRootContainer');
35 | // Attach children passed in constructor, previously created in ViewModel, to self
36 |
37 | // Create YDEX_cellDefinersTable, with definers arranged the same way as cells,
38 | // - with 4 cells, in 2x2 arrangement
39 | // - layoutSequence, on each cell as we want
40 |
41 | // [vertAxisDefiner] : Definer for vertical axis container. Vertical axis determines the width
42 | // of the first table column, and also the width left for the remainder of the table.
43 | // Note: Everything pre-layout is ordered by the sequence, actual layout by the cell positions in table
44 | TableLayoutCellDefiner vertAxisDefiner = TableLayoutCellDefiner(
45 | layoutSequence: 2,
46 | cellMinSizer: TableLayoutCellMinSizer.fromMinima(
47 | cellWidthMinimum: 65.0, // todo-012 will go away when we use VerticalAxisContainerFirst pre-layout
48 | cellHeightMinimum: 0.0,
49 | ),
50 | );
51 |
52 | // [YDEX_cellDefinersTable] is table with the following order of containers (left to right, top to bottom):
53 | // VerticalAxisContainer, DataContainer, EmptyAxisCornerContainer, HorizontalAxisContainer
54 | List> YDEX_cellDefinersTable = [
55 | [vertAxisDefiner, TableLayoutCellDefiner(layoutSequence: 3)],
56 | [TableLayoutCellDefiner(layoutSequence: 1), TableLayoutCellDefiner(layoutSequence: 0)],
57 | ];
58 |
59 | TableLayoutDefiner tableLayoutDefiner = TableLayoutDefiner(
60 | cellDefinersTable: YDEX_cellDefinersTable,
61 | cellsAlignerDefiner: ChartTableLayoutCellsAlignerDefiner.sizeOf( // or just 2x2
62 | cellDefinersTable: YDEX_cellDefinersTable,
63 | ),
64 | );
65 |
66 | BoxContainer axisCornerContainer = AxisCornerContainer(chartViewModel: chartViewModel);
67 |
68 | // verticalAxisContainer and horizontalAxisContainer are already transposed during creation.
69 | TableLayouter chartBody = TableLayouter(
70 | tableLayoutDefiner: tableLayoutDefiner,
71 | cellsTable: [
72 | [verticalAxisContainer, dataContainer],
73 | [axisCornerContainer, horizontalAxisContainer],
74 | ],
75 | );
76 |
77 | // Configure children, Legend on top, Table Layouter with X, Y, DataContainer below.
78 | addChildren(
79 | [
80 | TableLayouter(
81 | tableLayoutDefiner: TableLayoutDefiner.defaultRowWiseForTableSize(
82 | numRows: 2,
83 | numColumns: 1,
84 | ),
85 | cellsTable: [
86 | [legendContainer],
87 | [chartBody],
88 | ],
89 | ),
90 | ],
91 | );
92 | }
93 |
94 | /// todo-012 The members are only needed during layout of deeper children (e.g., BarPointContainer) to access the members' sizes or constraints
95 | /// Maybe we can remove the members and access them inside children by key??? LIKELY NOT BY KEY, BECAUSE, DUE TO SURRONDING MEMBERS IN
96 | /// LAYOUT OBJECTS, THEY ARE NOT AMONG CHILDREN.
97 | /// Members that display the Areas of chart.
98 | late LegendContainer legendContainer;
99 | // covariant needed on some, probably not all
100 | covariant late TransposingAxisLabels horizontalAxisContainer;
101 | covariant late TransposingAxisLabels verticalAxisContainer;
102 | covariant late TransposingAxisLabels verticalAxisContainerFirst;
103 | covariant late DataContainer dataContainer;
104 |
105 | /// Override [BoxContainerHierarchy.isRoot] to prevent checking this root container on parent,
106 | /// which is never set on instances of this [ChartRootContainer].
107 | @override
108 | bool get isRoot => true;
109 | }
110 |
--------------------------------------------------------------------------------
/lib/src/chart/chart_label_container.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart' as widgets show TextSpan, TextPainter;
2 | import 'package:flutter_charts/src/morphic/container/container_layouter_base.dart';
3 | import 'package:vector_math/vector_math.dart' as vector_math show Matrix2;
4 |
5 | // this level or equivalent
6 | import 'package:flutter_charts/src/morphic/container/label_container.dart';
7 | import 'package:flutter_charts/src/chart/cartesian/container/container_common.dart' as container_common show ChartAreaContainer;
8 | import 'package:flutter_charts/src/chart/view_model/view_model.dart' as view_model;
9 | import 'package:flutter_charts/src/chart/options.dart' show ChartOptions;
10 |
11 | /// Container of one label anywhere on the chart, in Labels, Axis, Titles, etc.
12 | ///
13 | /// The [layoutSize] is exactly that of by the contained
14 | /// layed out [textPainter] (this [ChartLabelContainer] has no margins, padding,
15 | /// or additional content in addition to the [_textPainter).
16 | ///
17 | /// However, if this object is tilted, as specified by [labelTiltMatrix], the
18 | /// [layoutSize] is determined by the rotated layed out [textPainter]. The
19 | /// math and [layoutSize] of this tilt is provided by [_tiltedLabelEnvelope].
20 | ///
21 | /// Most members are mutable so that clients can experiment with different
22 | /// ways to set text style, until the label fits a predefined allowed size.
23 | ///
24 | /// Notes:
25 | /// - Instances manage the text to be presented as label,
26 | /// and create a member [textPainter], instance of [widgets.TextPainter]
27 | /// from the label. The contained [textPainter] is used for all layout
28 | /// and painting.
29 | /// - All methods (and constructor) of this class always call
30 | /// [textPainter.layout] immediately after a change.
31 | /// Consequently, there is no need to check for
32 | /// a "needs layout" method - the underlying [textPainter]
33 | /// is always layed out, ready to be painted.
34 | class ChartLabelContainer extends container_common.ChartAreaContainer with TiltableLabelContainerMixin {
35 |
36 | // Allows to configure certain sizes, colors, and layout.
37 | // final LabelStyle _labelStyle;
38 |
39 | /// Constructs an instance for a label, it's text style, and label's
40 | /// maximum width.
41 | ///
42 | /// Note: Does not set parent container's [_boxConstraints] and [chartViewModel].
43 | /// It is currently assumed clients will not call any methods using those members.
44 | ChartLabelContainer({
45 | required view_model.ChartViewModel chartViewModel,
46 | required String label,
47 | required vector_math.Matrix2 labelTiltMatrix,
48 | required LabelStyle labelStyle,
49 | }) :
50 | super(
51 | chartViewModel: chartViewModel,
52 | ) {
53 | this.labelTiltMatrix = labelTiltMatrix;
54 | textPainter = widgets.TextPainter(
55 | text: widgets.TextSpan(
56 | text: label,
57 | style: labelStyle.textStyle, // All labels share one style object
58 | ),
59 | textDirection: labelStyle.textDirection,
60 | textAlign: labelStyle.textAlign,
61 | // center in available space todo-02 textScaleFactor does nothing ??
62 | textScaleFactor: labelStyle.textScaleFactor,
63 | // removed, causes lockup: ellipsis: "...", // forces a single line - without it, wraps at width
64 | );
65 |
66 | // _labelStyle = labelStyle,
67 | // var text = new widgets.TextSpan(
68 | // text: label,
69 | // style: _labelStyle.textStyle, // All labels share one style object
70 | // );
71 | // _textPainter = new widgets.TextPainter(
72 | // text: text,
73 | // textDirection: _labelStyle.textDirection,
74 | // textAlign: _labelStyle.textAlign,
75 | // // center in available space
76 | // textScaleFactor: _labelStyle.textScaleFactor,
77 | // // todo-04 add to test - was removed, causes lockup: ellipsis: "...", // forces a single line - without it, wraps at width
78 | // ); // textScaleFactor does nothing ??
79 | }
80 |
81 | @override
82 | double calcLabelMaxWidthFromLayoutOptionsAndConstraints() {
83 | // todo-013 : this seems incorrect - used for all labels, yet it acts as legend label!!
84 | // used only to get label max size in rotated labels.
85 | ChartOptions options = chartViewModel.chartOptions;
86 | double indicatorSquareSide = options.legendOptions.legendColorIndicatorWidth;
87 | double indicatorToLabelPad = options.legendOptions.legendItemIndicatorToLabelPad;
88 | double betweenLegendItemsPadding = options.legendOptions.betweenLegendItemsPadding;
89 |
90 | // labelMaxWidth from options and constraints on class with this mixin
91 | return constraints.maxSize.width - (indicatorSquareSide + indicatorToLabelPad + betweenLegendItemsPadding);
92 | }
93 | }
94 |
95 | /// Container of an axis label, a marker extension of [ChartLabelContainer] with no additional operations to it's
96 | /// superclass.
97 | ///
98 | /// Should be used for axis labels, and layed out with any standard layouters,
99 | /// most likely an extension of the [ExternalTicksBoxLayouter].
100 | ///
101 | class AxisLabelContainer extends ChartLabelContainer {
102 | AxisLabelContainer({
103 | required view_model.ChartViewModel chartViewModel,
104 | required String label,
105 | required vector_math.Matrix2 labelTiltMatrix,
106 | required LabelStyle labelStyle,
107 | }) : super(
108 | chartViewModel: chartViewModel,
109 | label: label,
110 | labelTiltMatrix: labelTiltMatrix,
111 | labelStyle: labelStyle,
112 | );
113 | }
114 |
--------------------------------------------------------------------------------
/lib/src/chart/future/container_future_additions_and_changes.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui' as ui show Size, Offset;
2 | import 'dart:math' as math show Rectangle;
3 |
4 | import 'package:flutter_charts/src/morphic/container/constraints.dart' show ContainerConstraints;
5 |
6 | // todo-05: Container core rules:
7 | // 1) I do not expose position, offset, or layoutSize.
8 | // I stay put until someone calls transform on me, OR it's special case applyParentOffset.
9 | // Is that possible?
10 | // 2) The layout() method finds, iteratively, the sizes of all Container children of the top Container.
11 | // The paint() method must NOT paint beyond the size of any Container
12 |
13 |
14 | // todo-05 : Shape and extensions (Box, Pie), Container and extensions, Layout, Painter -------------------------------
15 |
16 | /// Shape is the set of points in a Container.
17 | ///
18 | /// Returned from [layout].
19 | class Shape {
20 | Object? get surface => null; // represents non positioned surface after getting size in layout
21 | Object? get positionedSurface => null; // represents surface after positioning during layout
22 | }
23 |
24 | class BoxShape extends Shape {
25 | @override
26 | ui.Size get surface => ui.Size.zero;
27 | @override
28 | math.Rectangle get positionedSurface => const math.Rectangle(0.0, 0.0, 0.0, 0.0);
29 | }
30 |
31 | /// Represents not-positioned pie shape. Internal coordinates are polar, but can ask for containing rectangle.
32 | /// Equivalent to Size in Box shapes (internally in cartesian coordinates)
33 | class Pie {
34 | // todo-05 add distance and angle, and implement
35 | double angle = 0.0; // radians
36 | double radius = 0.0; // pixels ?
37 | }
38 |
39 | /// Represents a positioned pie shape. Positioning is in Cartesian coordinates represented by Offset.
40 | /// Equivalent to Rectangle in Box shapes.
41 | class PositionedPie extends Pie {
42 | ui.Offset offset = const ui.Offset(0.0, 0.0);
43 | }
44 |
45 | // todo-05 implement
46 | class PieShape extends Shape {
47 | @override
48 | Pie get surface => Pie();
49 | @override
50 | PositionedPie get positionedSurface => PositionedPie();
51 | }
52 |
53 | // todo-05 : Constraints and extensions -------------------------------------------------------------------------------
54 |
55 | class PieContainerConstraints extends ContainerConstraints {
56 | }
57 |
58 | // todo-05 : BoxContainerConstraints - see constraints.dart ------------------------------------------------------------
59 |
60 | // todo-05 : split:
61 | // - Container to BoxContainer and PieContainer
62 | // - Shape to BoxShape (wraps Size) and PieShape
63 | // - ContainerConstraint to BoxContainerConstraint and PieContainerConstraint
64 | // todo-05 : Change Container.layout to
65 | // Shape layout({required covariant ContainerConstraints constraints}); // Must set Shape (Size for now) on layoutableBoxParentSandbox
66 | // This base layout maybe eventually configures some constraints caching and debugging.
67 | // Extensions of Container: BoxContainer, PieContainer override layout as
68 | // BoxShape layout({required covariant BoxContainerConstraints constraints}); // Must set BoxShape (essentially, this is Size) on layoutableBoxParentSandbox
69 | // PieShape layout({required covariant PieContainerConstraints constraints}); // Must set PieShape on layoutableBoxParentSandbox
70 |
71 |
72 |
--------------------------------------------------------------------------------
/lib/src/chart/model/random_chart_data.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math show Random;
2 |
3 | import 'package:flutter_charts/src/chart/options.dart';
4 | import 'package:flutter_charts/src/chart/model/data_model.dart';
5 |
6 | // The single unnamed constructor (like primary factory in Newspeak). Must call super.
7 | /// Generator of sample data for testing the charts.
8 | ///
9 | class RandomChartModel extends ChartModel {
10 | RandomChartModel({
11 | required dataRows,
12 | required inputUserLabels,
13 | required legendNames,
14 | required chartOptions,
15 | outputUserLabels,
16 | legendColors,
17 | }) : super(
18 | dataRows: dataRows,
19 | inputUserLabels: inputUserLabels,
20 | legendNames: legendNames,
21 | chartOptions: chartOptions,
22 | outputUserLabels: outputUserLabels,
23 | legendColors: legendColors,
24 | );
25 |
26 | // Redirecting constructors just redirects to an 'unnamed' constructor on same class - the RandomChartModel(args) constructor.
27 | /// Generate random data for chart, with number of x labels given by
28 | /// [numXLabels] and number of data series given by [numDataRows].
29 | ///
30 | /// If [useMonthNames] is set to false, random
31 | ///
32 | RandomChartModel.generated({
33 | required ChartOptions chartOptions,
34 | bool useUserProvidedYLabels = false,
35 | int numXLabels = 6,
36 | int numDataRows = 4,
37 | bool useMonthNames = true,
38 | int maxLabelLength = 8,
39 | bool overlapDataYs = false,
40 | legendColors,
41 | }) : this(
42 | dataRows: randomDataYs(numXLabels, numDataRows, overlapDataYs),
43 | inputUserLabels: randomDataXLabels(numXLabels),
44 | legendNames: randomDataRowsLegends(numDataRows),
45 | chartOptions: chartOptions,
46 | outputUserLabels: randomDataYLabels(useUserProvidedYLabels),
47 | legendColors: legendColors,
48 | );
49 | }
50 |
51 | /// Sets up legends names, first several explicitly, rest randomly.
52 | ///
53 | /// This is used if user does not set legends.
54 | /// This should be kept in sync with colors below.
55 | List randomDataRowsLegends(int dataRowsCount) {
56 | List defaultLegends = List.empty(growable: true);
57 |
58 | if (dataRowsCount >= 1) {
59 | defaultLegends.add('YELLOW' /*' with really long description'*/);
60 | }
61 | if (dataRowsCount >= 2) {
62 | defaultLegends.add('GREEN');
63 | }
64 | if (dataRowsCount >= 3) {
65 | defaultLegends.add('BLUE');
66 | }
67 | if (dataRowsCount >= 4) {
68 | defaultLegends.add('BLACK');
69 | }
70 | if (dataRowsCount >= 5) {
71 | defaultLegends.add('GREY');
72 | }
73 | if (dataRowsCount >= 6) {
74 | defaultLegends.add('ORANGE');
75 | }
76 | if (dataRowsCount > 6) {
77 | for (int i = 3; i < dataRowsCount; i++) {
78 | // todo-1 when large value is generated, it paints outside canvas, fix.
79 | int number = math.Random().nextInt(10000);
80 | defaultLegends.add('OTHER ${number.toString()}');
81 | }
82 | }
83 | return defaultLegends;
84 | }
85 |
86 | /// Generate list of "random" [inputUserLabels] as monthNames or weekday names.
87 | ///
88 | ///
89 | List randomDataXLabels(int numXLabels) {
90 | List xLabelsDows = ['First', 'Second', 'Third', 'Fourth', 'Fifth', 'Sixth', 'Seventh'];
91 | return xLabelsDows.getRange(0, numXLabels).toList();
92 | }
93 |
94 | List? randomDataYLabels(bool useUserProvidedYLabels) {
95 | List? outputUserLabels;
96 | if (useUserProvidedYLabels) {
97 | outputUserLabels = ['NONE', 'OK', 'GOOD', 'BETTER', '100%'];
98 | }
99 | return outputUserLabels;
100 | }
101 |
102 | List> randomDataYs(int numXLabels, int numDataRows, bool overlapDataYs) {
103 | List> dataRows = List.empty(growable: true);
104 |
105 | double scale = 200.0;
106 |
107 | math.Random rgen = math.Random();
108 |
109 | int maxDataY = 4;
110 | double pushUpStep = overlapDataYs ? 0.0 : maxDataY.toDouble();
111 |
112 | for (int rowIndex = 0; rowIndex < numDataRows; rowIndex++) {
113 | dataRows.add(_randomDataOneRow(
114 | rgen: rgen,
115 | max: maxDataY,
116 | pushUpBy: (rowIndex - 1) * pushUpStep,
117 | scale: scale,
118 | numXLabels: numXLabels,
119 | ));
120 | }
121 | return dataRows;
122 | }
123 |
124 | List _randomDataOneRow({
125 | required math.Random rgen,
126 | required int max,
127 | required double pushUpBy,
128 | required double scale,
129 | required int numXLabels,
130 | }) {
131 | List valuesRow = List.empty(growable: true);
132 | for (int i = 0; i < numXLabels; i++) {
133 | valuesRow.add((rgen.nextInt(max) + pushUpBy) * scale);
134 | }
135 | return valuesRow;
136 | }
137 |
--------------------------------------------------------------------------------
/lib/src/coded_layout/chart/chart_type/bar/presenter.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui' as ui show Rect, Offset, Paint;
2 | // base libraries
3 | import 'package:flutter_charts/src/coded_layout/chart/presenter.dart';
4 | import 'package:flutter_charts/src/coded_layout/chart/container.dart';
5 | import 'package:flutter_charts/src/coded_layout/chart/axis_container.dart';
6 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
7 |
8 | /// PointPresenter of the atomic/leaf element of one data point on the
9 | /// vertical bar chart - a simple rectangle, in member [presentedRect],
10 | /// for which it calculates size and color.
11 | ///
12 | /// See [PointPresenter].
13 | class VerticalBarPointPresenter extends PointPresenter {
14 | late ui.Rect presentedRect;
15 | late ui.Paint valuesRowPaint;
16 |
17 | VerticalBarPointPresenter({
18 | required StackableValuePoint point,
19 | StackableValuePoint? nextRightColumnValuePoint,
20 | required int rowIndex,
21 | required ChartViewModel chartViewModel,
22 | }) : super(
23 | nextRightColumnValuePoint: nextRightColumnValuePoint,
24 | rowIndex: rowIndex,
25 | chartViewModel: chartViewModel,
26 | ) {
27 | // todo-1 move colors creation to super (shared for VerticalBar and LineAndHotspot)
28 | valuesRowPaint = ui.Paint();
29 | valuesRowPaint.color = chartViewModel.getLegendItemAt(rowIndex).color;
30 |
31 | ui.Offset barMidBottom = point.scaledFrom;
32 | ui.Offset barMidTop = point.scaledTo;
33 | HorizontalAxisContainerCL horizontalAxisContainerCL = chartViewModel.chartRootContainer.horizontalAxisContainer as HorizontalAxisContainerCL;
34 | double barWidth = horizontalAxisContainerCL.xGridStep *
35 | chartViewModel.chartOptions.dataContainerOptions.gridStepWidthPortionUsedByAtomicPointPresenter;
36 |
37 | ui.Offset barLeftTop = barMidTop.translate(-1 * barWidth / 2, 0.0);
38 | ui.Offset barRightBottom = barMidBottom.translate(1 * barWidth / 2, 0.0);
39 |
40 | presentedRect = ui.Rect.fromPoints(barLeftTop, barRightBottom);
41 | }
42 | }
43 |
44 | /// Creator of the [VerticalBarPointPresenter] instances - the leaf visual
45 | /// elements on the bar chart (rectangle one data value).
46 | ///
47 | /// See [PointPresenterCreator].
48 | class VerticalBarLeafPointPresenterCreator extends PointPresenterCreator {
49 | VerticalBarLeafPointPresenterCreator() : super();
50 |
51 | @override
52 | PointPresenter createPointPresenter({
53 | required StackableValuePoint point,
54 | StackableValuePoint? nextRightColumnValuePoint,
55 | required int rowIndex,
56 | required ChartViewModel chartViewModel,
57 | }) {
58 | return VerticalBarPointPresenter(
59 | point: point,
60 | nextRightColumnValuePoint: nextRightColumnValuePoint,
61 | rowIndex: rowIndex,
62 | chartViewModel: chartViewModel,
63 | );
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/lib/src/coded_layout/chart/chart_type/bar/root_container.dart:
--------------------------------------------------------------------------------
1 | // base libraries
2 | import 'package:flutter_charts/src/coded_layout/chart/container.dart';
3 | import 'package:flutter_charts/src/coded_layout/chart/axis_container.dart';
4 | import 'package:flutter_charts/src/coded_layout/chart/data_container.dart';
5 | import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
6 | import 'package:flutter_charts/src/chart/cartesian/container/root_container.dart';
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
8 | import 'package:flutter_charts/src/switch_view_model/view_model_cl.dart';
9 |
10 | // this level
11 | import 'presenter.dart'; // OLD
12 |
13 |
14 | /// The container-hierarchy root container of the vertical bar chart in the coded_layout legacy version.
15 | class BarChartRootContainerCL extends ChartRootContainerCL implements ChartRootContainer {
16 | BarChartRootContainerCL({
17 | required LegendContainer legendContainer,
18 | required HorizontalAxisContainerCL horizontalAxisContainer,
19 | required OutputAxisContainerCL verticalAxisContainerFirst,
20 | required OutputAxisContainerCL verticalAxisContainer,
21 | required DataContainerCL dataContainer,
22 | required ChartViewModel chartViewModel,
23 | }) : super(
24 | legendContainer: legendContainer,
25 | horizontalAxisContainer: horizontalAxisContainer,
26 | verticalAxisContainerFirst: verticalAxisContainerFirst,
27 | verticalAxisContainer: verticalAxisContainer,
28 | dataContainer: dataContainer,
29 | chartViewModel: chartViewModel,
30 | ) {
31 | (chartViewModel as SwitchChartViewModelCL).pointPresenterCreator = VerticalBarLeafPointPresenterCreator();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/lib/src/coded_layout/chart/chart_type/line/presenter.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui' as ui show Offset, Paint;
2 |
3 | // base libraries
4 | import 'package:flutter_charts/src/coded_layout/chart/container.dart';
5 | import 'package:flutter_charts/src/coded_layout/chart/line_container.dart';
6 | import 'package:flutter_charts/src/coded_layout/chart/presenter.dart'; // OLD
7 |
8 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
9 |
10 | /// PointPresenter of the atomic/leaf element of one data point on the
11 | /// line chart - the point at which data value is shown,
12 | /// and the line from this data value point to the next data value point
13 | /// on the right.
14 | ///
15 | /// The line leads from this [offsetPoint]
16 | /// to the [offsetPoint] of the [LineAndHotspotPointPresenter]
17 | /// which is next in the [PointPresentersColumn.pointPresenters] list.
18 | class LineAndHotspotPointPresenter extends PointPresenter {
19 | late LineContainerCL lineContainer;
20 | late ui.Offset offsetPoint; // offset where the data point will be painted
21 | late ui.Paint innerPaint;
22 | late ui.Paint outerPaint;
23 | double innerRadius = 0.0;
24 | double outerRadius = 0.0;
25 |
26 | late ui.Paint rowDataPaint;
27 |
28 | LineAndHotspotPointPresenter({
29 | required StackableValuePoint point,
30 | StackableValuePoint? nextRightColumnValuePoint,
31 | required int rowIndex,
32 | required ChartViewModel chartViewModel,
33 | }) : super(
34 | nextRightColumnValuePoint: nextRightColumnValuePoint,
35 | rowIndex: rowIndex,
36 | chartViewModel: chartViewModel,
37 | ) {
38 | var options = chartViewModel.chartOptions;
39 |
40 | // todo-1 move colors creation to super (shared for VerticalBar and LineAndHotspot)
41 | rowDataPaint = ui.Paint();
42 | rowDataPaint.color = chartViewModel.getLegendItemAt(rowIndex).color;
43 |
44 | ui.Offset fromPoint = point.scaledTo;
45 | ui.Offset? toPoint = nextRightColumnValuePoint?.scaledTo;
46 | toPoint ??= fromPoint;
47 | lineContainer = LineContainerCL(
48 | chartViewModel: chartViewModel,
49 | lineFrom: fromPoint,
50 | lineTo: toPoint,
51 | linePaint: rowDataPaint..strokeWidth = options.lineChartOptions.lineStrokeWidth);
52 | offsetPoint = fromPoint; // point is the left (from) end of the line
53 | innerPaint = ui.Paint()..color = options.lineChartOptions.hotspotInnerPaintColor;
54 | outerPaint = ui.Paint()..color = options.lineChartOptions.hotspotOuterPaintColor;
55 | innerRadius = options.lineChartOptions.hotspotInnerRadius;
56 | outerRadius = options.lineChartOptions.hotspotOuterRadius;
57 | }
58 | }
59 |
60 | /// Creator of the [LineAndHotspotPointPresenter] instances - the leaf visual
61 | /// elements on the line chart (point and line showing one data value).
62 | ///
63 | /// See [PointPresenterCreator].
64 | class LineAndHotspotLeafPointPresenterCreator extends PointPresenterCreator {
65 | LineAndHotspotLeafPointPresenterCreator() : super();
66 |
67 | @override
68 | PointPresenter createPointPresenter({
69 | required StackableValuePoint point,
70 | StackableValuePoint? nextRightColumnValuePoint,
71 | required int rowIndex,
72 | required ChartViewModel chartViewModel,
73 | }) {
74 | return LineAndHotspotPointPresenter(
75 | point: point,
76 | nextRightColumnValuePoint: nextRightColumnValuePoint,
77 | rowIndex: rowIndex,
78 | chartViewModel: chartViewModel,
79 | );
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/lib/src/coded_layout/chart/chart_type/line/root_container.dart:
--------------------------------------------------------------------------------
1 | // base libraries
2 | import 'package:flutter_charts/src/coded_layout/chart/container.dart';
3 | import 'package:flutter_charts/src/coded_layout/chart/axis_container.dart';
4 | import 'package:flutter_charts/src/coded_layout/chart/data_container.dart';
5 | import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
6 | import 'package:flutter_charts/src/chart/cartesian/container/root_container.dart';
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
8 | import 'package:flutter_charts/src/switch_view_model/view_model_cl.dart';
9 |
10 | // this level
11 | import 'presenter.dart'; // OLD
12 |
13 | /// The container-hierarchy root container of the line chart in the coded_layout legacy version.
14 | class LineChartRootContainerCL extends ChartRootContainerCL implements ChartRootContainer {
15 | LineChartRootContainerCL({
16 | required LegendContainer legendContainer,
17 | required HorizontalAxisContainerCL horizontalAxisContainer,
18 | required OutputAxisContainerCL verticalAxisContainerFirst,
19 | required OutputAxisContainerCL verticalAxisContainer,
20 | required DataContainerCL dataContainer,
21 | required ChartViewModel chartViewModel,
22 | }) : super(
23 | legendContainer: legendContainer,
24 | horizontalAxisContainer: horizontalAxisContainer,
25 | verticalAxisContainerFirst: verticalAxisContainerFirst,
26 | verticalAxisContainer: verticalAxisContainer,
27 | dataContainer: dataContainer,
28 | chartViewModel: chartViewModel,
29 | ) {
30 | (chartViewModel as SwitchChartViewModelCL).pointPresenterCreator = LineAndHotspotLeafPointPresenterCreator();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/src/coded_layout/chart/line_container.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui' as ui show Offset, Paint, Canvas;
2 |
3 | // this level
4 |
5 | import 'package:flutter_charts/src/morphic/container/container_layouter_base.dart' show LayoutableBox;
6 | import 'package:flutter_charts/src/chart/cartesian/container/container_common.dart' as container_common show ChartAreaContainer;
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
8 |
9 |
10 | /// Manages [lineFrom] and [lineTo] positions and [linePaint] for a line segment.
11 | class LineContainerCL extends container_common.ChartAreaContainer {
12 | /// Points from which line starts and ends. NOT added to children ATM.
13 | ui.Offset lineFrom;
14 | ui.Offset lineTo;
15 | ui.Paint linePaint;
16 |
17 | // todo-02-full-autolayout : manualLayedOutFromX and friends ADDED TEMPORARILY to be set during construction
18 | // : of [LineContainer] in [GridLinesContainer.buildAndReplaceChildren]
19 | // : where these layout values are calculated, held on,
20 | // : and used later in self [layout], to set [lineFrom] and [lineTo]
21 | // : THIS IS TEMPORARY FOR MANUAL LAYOUT TO SHUFFLE VALUES FROM PARENT LAYOUT
22 | // : (GridLinesContainer, something else??) TO LineContainer.layout()
23 | /// With manual layout, holds on to the layout value of horizontal or vertical lines,
24 | /// between the lifecycle events of [LineContainerCL]
25 | /// creation in parent [buildAndReplaceChildren]
26 | /// and it's layout in parent [layout].
27 | ///
28 | /// ONLY used on horizontal xLineContainer or vertical yLineContainer, maintains the
29 | /// coordinate that remains the same: y on xLineContainer, x on yLineContainer.
30 | ///
31 | double manualLayedOutFromX;
32 | double manualLayedOutFromY;
33 | double manualLayedOutToX;
34 | double manualLayedOutToY;
35 |
36 | LineContainerCL({
37 | required ChartViewModel chartViewModel,
38 | required this.lineFrom,
39 | required this.lineTo,
40 | required this.linePaint,
41 | this.manualLayedOutFromX = 0.0,
42 | this.manualLayedOutFromY = 0.0,
43 | this.manualLayedOutToX = 0.0,
44 | this.manualLayedOutToY = 0.0,
45 | }) : super(
46 | chartViewModel: chartViewModel,
47 | );
48 |
49 | // ##### Implementors of method in superclass [Container].
50 |
51 | /// Implementor of method in superclass [Container].
52 | ///
53 | /// Ensure [layoutSize] is set.
54 | /// Note that because this leaf container overrides [layout] here,
55 | /// it does not need to override [layout_Post_Leaf_SetSize_FromInternals].
56 | @override
57 | void layout() {
58 | buildAndReplaceChildren();
59 | // Use the coordinates manually layed out during creation in [GridLinesContainer] by
60 | lineFrom = ui.Offset(manualLayedOutFromX, manualLayedOutFromY);
61 | lineTo = ui.Offset(manualLayedOutToX, manualLayedOutToY);
62 |
63 | layoutSize = constraints.size;
64 | }
65 |
66 | /// Override method in superclass [Container].
67 | @override
68 | void applyParentOffset(LayoutableBox caller, ui.Offset offset) {
69 | super.applyParentOffset(caller, offset);
70 | lineFrom += offset;
71 | lineTo += offset;
72 | }
73 |
74 | @override
75 | void paint(ui.Canvas canvas) {
76 | canvas.drawLine(lineFrom, lineTo, linePaint);
77 | }
78 |
79 | @override
80 | void buildAndReplaceChildren() {
81 | buildAndReplaceChildrenDefault();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/src/morphic/container/container_edge_padding.dart:
--------------------------------------------------------------------------------
1 |
2 | // this level
3 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
4 |
5 | /// Edge padding for the [Padder] layouter.
6 | ///
7 | /// Script-writing order dependent members [start] and [end] define padding in logical pixels
8 | /// on the left and the right of the child for left-to-right scripts;
9 | /// on the right and the left for right-to-left scripts
10 | ///
11 | /// [top] and [bottom] define padding in logical pixels on the top and the bottom of the child.
12 | ///
13 | /// Assuming left to right, using a construct such as
14 | /// ```dart
15 | /// Padder(
16 | /// edgePadding: EdgePadding(start: 1, top: 2, end: 3, bottom:4),
17 | /// child: Child(),
18 | /// )
19 | /// ```
20 | /// The child is surrounded by 1, 2, 3, and 4 pixels, and it's width is increased by 1+3 pixels,
21 | /// it's height by 2+4 pixels from child's width and height.
22 | class EdgePadding {
23 |
24 | // Generative unnamed
25 | const EdgePadding({
26 | required this.start,
27 | required this.top,
28 | required this.end,
29 | required this.bottom,
30 | });
31 |
32 | const EdgePadding.withSides({
33 | this.start = 0.0,
34 | this.top = 0.0,
35 | this.end = 0.0,
36 | this.bottom = 0.0,
37 | });
38 |
39 | factory EdgePadding.TransposingWithSides({
40 | required ChartOrientation chartOrientation,
41 | double start = 0.0,
42 | double top = 0.0,
43 | double end = 0.0,
44 | double bottom = 0.0,
45 | }) {
46 | switch(chartOrientation) {
47 | case ChartOrientation.column:
48 | return EdgePadding.withSides(start: start, top: top, end: end, bottom: bottom);
49 | case ChartOrientation.row:
50 | return EdgePadding.withSides(start: bottom, top: end, end: top, bottom: start);
51 | }
52 | }
53 |
54 | // constructor const EdgePadding.none() : this.withSides();
55 | static const EdgePadding none = EdgePadding.withSides(); // member field
56 |
57 | const EdgePadding.withAllSides(double value)
58 | : start = value,
59 | top = value,
60 | end = value,
61 | bottom = value;
62 |
63 | /// Padding copy of self with all sides reversed signs.
64 | ///
65 | /// Useful for inflating and deflating Rectangles.
66 | EdgePadding negate() => EdgePadding(start: -start, top: -top, end: -end, bottom: -bottom);
67 |
68 | final double start;
69 |
70 | final double top;
71 |
72 | final double end;
73 |
74 | final double bottom;
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/lib/src/morphic/container/container_key.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart' show immutable;
2 |
3 | // this level
4 | import 'package:flutter_charts/src/morphic/container/container_layouter_base.dart';
5 |
6 | /// [ContainerKey] is a unique identifier of a [BoxContainer].
7 | ///
8 | /// The meaning of 'unique' depends on the 'context'.
9 | ///
10 | /// In the current implementation, the only supported 'uniqueness context' is 'siblings of [BoxContainerHierarchy]'.
11 | /// In other words, extensions of [ContainerKey] currently support the ability to identify [BoxContainer]
12 | /// uniquely among it's children in the [BoxContainerHierarchy].
13 | ///
14 | /// In the future the 'uniqueness context' may be 'application', or other well-defined subsets of it.
15 | @immutable
16 | abstract class ContainerKey {
17 |
18 | /// Single generative constructor constructs Key without value,
19 | /// allows extensions to define `const` constructor.
20 | ///
21 | /// This trick ensures the default no-arg constructor `ContainerKey()` is not generated,
22 | /// and so ContainerKey cannot be extended outside of this library `container_key.dart`.
23 | ///
24 | /// Note:
25 | /// Trying to use
26 | /// `ContainerKey();`
27 | /// causes a compile error 'the unnamed constructor is already defined'
28 | ///
29 | const ContainerKey._simple();
30 |
31 | /// Default way to create instance of [ContainerKey] extension.
32 | ///
33 | /// Note this creates a siblings unique key.
34 | /// Must override if uniqueness in other context key is needed.
35 | const factory ContainerKey(String value) = SiblingsValueKey;
36 | }
37 |
38 | /// [SiblingsKey] is a [ContainerKey] intended to be unique among siblings
39 | /// of the same parent in the [BoxContainerHierarchy].
40 | ///
41 | @immutable
42 | abstract class SiblingsKey extends ContainerKey {
43 | /// Default constructor.
44 | ///
45 | /// Must be [const] to enable extensions' [const] constructors.
46 | const SiblingsKey() : super._simple();
47 |
48 | }
49 |
50 | /// A [SiblingsKey] extension uses a parametrized [value] as identifier.
51 | ///
52 | /// It is assumed to be created and set on [BoxContainer] during construction, unique
53 | /// among siblings. That means, the creator of the [BoxContainer]s must be aware
54 | /// of any future siblings, or generate the key sufficiently randomly.
55 | @immutable
56 | class SiblingsValueKey extends SiblingsKey {
57 | final T value;
58 |
59 | const SiblingsValueKey(this.value) : super();
60 |
61 | @override
62 | String toString() {
63 | return '$runtimeType: value=$value';
64 | }
65 |
66 | @override
67 | bool operator ==(Object other) =>
68 | other is SiblingsValueKey && other.runtimeType == runtimeType && other.value == value;
69 |
70 | @override
71 | int get hashCode => value.hashCode * 17;
72 | }
73 |
74 | /// Allows implementations to be identified by a user-defined unique key.
75 | ///
76 | /// Uniqueness depends on context, and is not described by this class:
77 | /// Uniqueness can be global, in hierarchy, among siblings etc.
78 | abstract class Keyed {
79 | ContainerKey get key;
80 | }
81 |
82 | /// Manager of [Keyed] objects in member list [keyedMembers] which [ContainerKey]s must be kept unique
83 | /// within the [keyedMembers].
84 | ///
85 | /// Works as a mixin on behalf of it's extension, by delegating the [keyedMembers] getter (a list of [Keyed] objects)
86 | /// to it's extension's member.
87 | ///
88 | /// The method [ensureKeyedMembersHaveUniqueKeys] must be called by the extension
89 | /// every time after the list underlying the [keyedMembers] getter is changed.
90 | ///
91 | /// For example, a [BoxContainer] we want siblings should be unique,
92 | /// so we ensure [BoxContainer] implements the [UniqueKeyedObjectsManager],
93 | /// and we forward the [BoxContainer]'s [_children] to the [UniqueKeyedObjectsManager]'s [keyedMembers];
94 | /// we also ensure that in [BoxContainer]'s constructor, after [BoxContainer]'s [_children] change, we call [ensureKeyedMembersHaveUniqueKeys].
95 | abstract class UniqueKeyedObjectsManager {
96 |
97 | /// Holder of the [Keyed] members, which keys must stay unique.
98 | ///
99 | /// Serves as a backing [Iterable] of the [Keyed] objects
100 | /// this holder manages.
101 | ///
102 | /// Implementors need to override this
103 | /// method to start holding uniquely [Keyed] objects.
104 | List get keyedMembers;
105 |
106 | Iterable get _memberKeys => keyedMembers.map((Keyed keyed) => keyed.key);
107 |
108 | Keyed getKeyedByKey(ContainerKey containerKey) {
109 | return keyedMembers.firstWhere((Keyed keyed) => keyed.key == containerKey);
110 | }
111 |
112 | /// Checks uniqueness of all managed [Keyed] members.
113 | ///
114 | /// Implementors must call this method every time after the list backing
115 | /// the [keyedMembers] is modified.
116 | ///
117 | /// As by default, the [BoxContainer._children], is the list backing the [UniqueKeyedObjectsManager.keyedMembers],
118 | /// this method must be called after changing [_children].
119 | void ensureKeyedMembersHaveUniqueKeys() {
120 | // toSet converts to set using ==.
121 | // If lengths do not match, there are at least two == keys in [keys].
122 | Set toSet = _memberKeys.toSet();
123 | if (toSet.length != _memberKeys.length) {
124 | throw StateError('ensureKeyedMembersHaveUniqueKeys: keys $_memberKeys of members $keyedMembers are not unique');
125 | }
126 | }
127 | }
--------------------------------------------------------------------------------
/lib/src/morphic/container/morphic_dart_enums.dart:
--------------------------------------------------------------------------------
1 |
2 | // this level
3 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
4 |
5 | /// Library defines enums which belong to Flutter-dependent [container_layouter_base.dart]
6 | /// but packaged here for testability in dart testing.
7 |
8 |
9 | /// Position in label on which the axis tick, defining the label's data position, is placed.
10 | enum ExternalTickAtPosition {
11 | childStart,
12 | childCenter,
13 | childEnd,
14 | }
15 |
16 | /// Describes axis orientation in culture-neutral, and data dependent/independent neutral terms.
17 | ///
18 | enum LayoutAxis {
19 | horizontal,
20 | vertical;
21 |
22 | LayoutAxis perpendicularAxis() {
23 | switch (this) {
24 | case LayoutAxis.horizontal:
25 | return LayoutAxis.vertical;
26 | case LayoutAxis.vertical:
27 | return LayoutAxis.horizontal;
28 | }
29 | }
30 |
31 | }
32 |
33 | /// Describes the type of data shown on a [LayoutAxis], for a [ChartOrientation].
34 | ///
35 | /// Given a [ChartOrientation], the [LayoutAxis] on which a given [DataDependency]
36 | /// is shown, is defined by [ChartOrientation.layoutAxisForDataDependency].
37 | enum DataDependency {
38 | inputData,
39 | outputData,
40 | }
41 |
42 | /// On behalf of [PointsBarModel], represents the sign of the values of [PointModel] points
43 | /// which should be added to the [PointsBarModel].
44 | ///
45 | /// Motivation: In order to display both negative and positive values on the bar chart or line chart,
46 | /// the [ChartModel] manages the positive and negative values separately in
47 | /// [ChartModel.dataColumnPointsModelPositiveList] and [ChartModel.dataColumnPointsModelNegativeList].
48 | /// This enum supports creating and later using (processing, view making) the positive and negative
49 | /// bars separately.
50 | enum Sign {
51 | positiveOr0,
52 | negative,
53 | any;
54 |
55 | /// Checks if the sign of a the passed [value] is the sign required by this enum instance.
56 | bool isValueMySign({
57 | required double value,
58 | }) {
59 | switch (this) {
60 | case Sign.positiveOr0:
61 | return (value >= 0.0);
62 | case Sign.negative:
63 | return (value < 0.0);
64 | case Sign.any:
65 | return true;
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lib/src/morphic/util/extensible_enum.dart:
--------------------------------------------------------------------------------
1 | /// Base class for extensible pseudo-enums.
2 | ///
3 | abstract class BaseExtensibleEnum {
4 |
5 | const BaseExtensibleEnum(this.i);
6 |
7 | final int i;
8 |
9 | @override
10 | String toString() => '$runtimeType: instance i=$i';
11 | }
12 |
--------------------------------------------------------------------------------
/lib/src/switch_view_model/auto_layout/bar/view_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:logger/logger.dart' as logger;
2 |
3 | import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
4 | import 'package:flutter_charts/src/chart/cartesian/container/axislabels_axislines_gridlines_container.dart';
5 |
6 | // base libraries
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
8 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
9 | import 'package:flutter_charts/src/chart/cartesian/chart_type/bar/container/root_container.dart';
10 | import 'package:flutter_charts/src/chart/model/data_model.dart';
11 | import 'package:flutter_charts/src/chart/iterative_layout_strategy.dart' as strategy show LabelLayoutStrategy;
12 | import 'package:flutter_charts/src/chart/cartesian/chart_type/bar/container/data_container.dart';
13 |
14 | // this level: switch/auto_layout/bar
15 | import 'package:flutter_charts/src/switch_view_model/view_model.dart'; // NEW SWITCH
16 |
17 | /// Concrete [ChartViewModel] for [BarChart].
18 | ///
19 | /// See [ChartViewModel] for help.
20 | class SwitchBarChartViewModel extends SwitchChartViewModel {
21 | SwitchBarChartViewModel({
22 | required ChartModel chartModel,
23 | required ChartType chartType,
24 | required ChartOrientation chartOrientation,
25 | required LiveOrTesting liveOrTesting,
26 | required ChartStacking chartStacking,
27 | strategy.LabelLayoutStrategy? inputLabelLayoutStrategy,
28 | }) : super(
29 | chartModel: chartModel,
30 | chartType: chartType,
31 | chartOrientation: chartOrientation,
32 | chartStacking: chartStacking,
33 | liveOrTesting: liveOrTesting,
34 | inputLabelLayoutStrategy: inputLabelLayoutStrategy,
35 | ) {
36 | logger.Logger().d('$runtimeType created');
37 | }
38 |
39 | /// Concrete implementation returns the root for vertical bar chart.
40 | @override
41 | BarChartRootContainer makeChartRootContainer({required ChartViewModel chartViewModel}) {
42 | return BarChartRootContainer(
43 | legendContainer: LegendContainer(chartViewModel: this),
44 | horizontalAxisContainer: TransposingAxisLabels.HorizontalAxis(chartViewModel: this),
45 | verticalAxisContainerFirst: TransposingAxisLabels.VerticalAxis(chartViewModel: this),
46 | verticalAxisContainer: TransposingAxisLabels.VerticalAxis(chartViewModel: this),
47 | dataContainer: BarChartDataContainer(chartViewModel: this),
48 | chartViewModel: chartViewModel,
49 | );
50 | }
51 |
52 | /// Implements [ChartBehavior] mixin abstract method.
53 | ///
54 | /// Overridden to [false] on this bar chart container, where the y axis must start from 0.
55 | ///
56 | @override
57 | bool get extendAxisToOrigin => true;
58 | }
59 |
--------------------------------------------------------------------------------
/lib/src/switch_view_model/auto_layout/line/view_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:logger/logger.dart' as logger;
2 |
3 |
4 | // base libraries
5 | import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
6 | import 'package:flutter_charts/src/chart/cartesian/container/axislabels_axislines_gridlines_container.dart';
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
8 | import 'package:flutter_charts/src/chart/model/data_model.dart';
9 | import 'package:flutter_charts/src/chart/iterative_layout_strategy.dart' as strategy show LabelLayoutStrategy;
10 | import 'package:flutter_charts/src/chart/cartesian/chart_type/line/container/data_container.dart';
11 |
12 | import 'package:flutter_charts/src/chart/cartesian/chart_type/line/container/root_container.dart';
13 |
14 | // this level: switch/auto_layout/bar
15 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
16 | import 'package:flutter_charts/src/switch_view_model/view_model.dart'; // NEW SWITCH
17 |
18 | /// Concrete [ChartViewModel] for [LineChart].
19 | ///
20 | /// See [ChartViewModel] for help.
21 | class SwitchLineChartViewModel extends SwitchChartViewModel {
22 | SwitchLineChartViewModel({
23 | required ChartModel chartModel,
24 | required ChartType chartType,
25 | required ChartOrientation chartOrientation,
26 | required ChartStacking chartStacking,
27 | required LiveOrTesting liveOrTesting,
28 | strategy.LabelLayoutStrategy? inputLabelLayoutStrategy,
29 | }) : super(
30 | chartModel: chartModel,
31 | chartType: chartType,
32 | chartOrientation: chartOrientation,
33 | chartStacking: chartStacking,
34 | liveOrTesting: liveOrTesting,
35 | inputLabelLayoutStrategy: inputLabelLayoutStrategy,
36 | ) {
37 | logger.Logger().d('$runtimeType created');
38 | }
39 |
40 | /// Concrete implementation returns the root for vertical bar chart.
41 | @override
42 | LineChartRootContainer makeChartRootContainer({required ChartViewModel chartViewModel}) {
43 | return LineChartRootContainer(
44 | legendContainer: LegendContainer(chartViewModel: this),
45 | horizontalAxisContainer: TransposingAxisLabels.HorizontalAxis(chartViewModel: this),
46 | verticalAxisContainerFirst: TransposingAxisLabels.VerticalAxis(chartViewModel: this),
47 | verticalAxisContainer: TransposingAxisLabels.VerticalAxis(chartViewModel: this),
48 | dataContainer: LineChartDataContainer(chartViewModel: this),
49 | chartViewModel: chartViewModel,
50 | );
51 | }
52 |
53 | /// Implements [ChartBehavior] mixin abstract method.
54 | ///
55 | /// If resolved to [true], Y axis will start on the minimum of Y values, otherwise at [0.0].
56 | ///
57 | /// This is the method used in code logic when building the Y labels and axis.
58 | ///
59 | /// The related variable [DataContainerOptions.extendAxisToOriginRequested],
60 | /// is merely a request that may not be granted in some situations.
61 | ///
62 | /// On this line chart container, allow the y axis start from 0 if requested by options.
63 | @override
64 | bool get extendAxisToOrigin => chartOptions.dataContainerOptions.extendAxisToOriginRequested;
65 | }
66 |
--------------------------------------------------------------------------------
/lib/src/switch_view_model/coded_layout/bar/view_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:logger/logger.dart' as logger;
2 |
3 | // this level
4 | import 'package:flutter_charts/src/coded_layout/chart/chart_type/bar/root_container.dart';
5 |
6 | // base libraries
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
8 | import 'package:flutter_charts/src/coded_layout/chart/axis_container.dart';
9 | import 'package:flutter_charts/src/coded_layout/chart/data_container.dart';
10 | import 'package:flutter_charts/src/chart/model/data_model.dart';
11 | import 'package:flutter_charts/src/chart/iterative_layout_strategy.dart' as strategy show LabelLayoutStrategy;
12 |
13 | import 'package:flutter_charts/src/switch_view_model/view_model_cl.dart'; // OLD
14 | import 'package:flutter_charts/src/switch_view_model/view_model.dart' show directionWrapperAroundCL;
15 |
16 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
17 |
18 | import 'package:flutter_charts/test/src/chart/cartesian/container/legend_container.dart' as testing_legend_container;
19 |
20 |
21 | class SwitchBarChartViewModelCL extends SwitchChartViewModelCL {
22 | SwitchBarChartViewModelCL({
23 | required ChartModel chartModel,
24 | required ChartType chartType,
25 | required ChartOrientation chartOrientation,
26 | required ChartStacking chartStacking,
27 | required LiveOrTesting liveOrTesting,
28 | strategy.LabelLayoutStrategy? inputLabelLayoutStrategy,
29 | }) : super(
30 | chartModel: chartModel,
31 | chartType: chartType,
32 | chartOrientation: chartOrientation,
33 | chartStacking: chartStacking,
34 | liveOrTesting: liveOrTesting,
35 | inputLabelLayoutStrategy: inputLabelLayoutStrategy,
36 | ) {
37 | logger.Logger().d('$runtimeType created');
38 | }
39 |
40 | @override
41 | BarChartRootContainerCL makeChartRootContainer({required ChartViewModel chartViewModel}) {
42 | return BarChartRootContainerCL(
43 | legendContainer: testing_legend_container.LegendContainer(chartViewModel: this),
44 | horizontalAxisContainer: HorizontalAxisContainerCL(
45 | chartViewModel: this,
46 | directionWrapperAround: directionWrapperAroundCL,
47 | ),
48 | verticalAxisContainerFirst: OutputAxisContainerCL(
49 | chartViewModel: this,
50 | directionWrapperAround: directionWrapperAroundCL,
51 | ),
52 | verticalAxisContainer: OutputAxisContainerCL(
53 | chartViewModel: this,
54 | directionWrapperAround: directionWrapperAroundCL,
55 | ),
56 | dataContainer: BarChartDataContainerCL(chartViewModel: this),
57 | chartViewModel: chartViewModel,
58 | );
59 | }
60 |
61 | @override
62 | bool get extendAxisToOrigin => true;
63 | }
64 |
--------------------------------------------------------------------------------
/lib/src/switch_view_model/coded_layout/line/view_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:logger/logger.dart' as logger;
2 |
3 | // base libraries
4 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
5 | import 'package:flutter_charts/src/coded_layout/chart/axis_container.dart';
6 | import 'package:flutter_charts/src/coded_layout/chart/data_container.dart';
7 | import 'package:flutter_charts/src/chart/model/data_model.dart';
8 |
9 | import 'package:flutter_charts/src/chart/iterative_layout_strategy.dart' as strategy show LabelLayoutStrategy;
10 |
11 | // this level
12 | import 'package:flutter_charts/src/coded_layout/chart/chart_type/line/root_container.dart';
13 |
14 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
15 | import 'package:flutter_charts/src/switch_view_model/view_model_cl.dart'; // OLD
16 | import 'package:flutter_charts/src/switch_view_model/view_model.dart' show directionWrapperAroundCL;
17 |
18 | import 'package:flutter_charts/test/src/chart/cartesian/container/legend_container.dart' as testing_legend_container;
19 |
20 | class SwitchLineChartViewModelCL extends SwitchChartViewModelCL {
21 | SwitchLineChartViewModelCL({
22 | required ChartModel chartModel,
23 | required ChartType chartType,
24 | required ChartOrientation chartOrientation,
25 | required ChartStacking chartStacking,
26 | required LiveOrTesting liveOrTesting,
27 | strategy.LabelLayoutStrategy? inputLabelLayoutStrategy,
28 | }) : super(
29 | chartModel: chartModel,
30 | chartType: chartType,
31 | chartOrientation: chartOrientation,
32 | chartStacking: chartStacking,
33 | liveOrTesting: liveOrTesting,
34 | inputLabelLayoutStrategy: inputLabelLayoutStrategy,
35 | ) {
36 | logger.Logger().d('$runtimeType created');
37 | }
38 |
39 | @override
40 | LineChartRootContainerCL makeChartRootContainer({required ChartViewModel chartViewModel}) {
41 | return LineChartRootContainerCL(
42 | legendContainer: testing_legend_container.LegendContainer(chartViewModel: this),
43 | horizontalAxisContainer: HorizontalAxisContainerCL(
44 | chartViewModel: this,
45 | directionWrapperAround: directionWrapperAroundCL,
46 | ),
47 | verticalAxisContainerFirst: OutputAxisContainerCL(
48 | chartViewModel: this,
49 | directionWrapperAround: directionWrapperAroundCL,
50 | ),
51 | verticalAxisContainer: OutputAxisContainerCL(
52 | chartViewModel: this,
53 | directionWrapperAround: directionWrapperAroundCL,
54 | ),
55 | dataContainer: LineChartDataContainerCL(chartViewModel: this),
56 | chartViewModel: chartViewModel,
57 | );
58 | }
59 |
60 | /// Implements [ChartBehavior] mixin abstract method.
61 | ///
62 | /// If resolved to [true], Y axis will start on the minimum of Y values, otherwise at [0.0].
63 | ///
64 | /// This is the method used in code logic when building the Y labels and axis.
65 | ///
66 | /// The related variable [DataContainerOptions.extendAxisToOriginRequested],
67 | /// is merely a request that may not be granted in some situations.
68 | ///
69 | /// On this line chart container, allow the y axis start from 0 if requested by options.
70 | @override
71 | bool get extendAxisToOrigin => chartOptions.dataContainerOptions.extendAxisToOriginRequested;
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/lib/src/switch_view_model/view_model_cl.dart:
--------------------------------------------------------------------------------
1 | // import 'package:logger/logger.dart' as logger;
2 | // import 'dart:developer' as dart_developer;
3 |
4 | // this level
5 | import 'package:flutter_charts/src/switch_view_model/view_model.dart'; // NEW SWITCH
6 |
7 | import 'package:flutter_charts/src/coded_layout/chart/container.dart' as container; // OLD CONTAINER
8 | import 'package:flutter_charts/src/chart/view_model/view_model.dart'; // NEW
9 | import 'package:flutter_charts/src/chart/model/data_model.dart' as model;
10 | import 'package:flutter_charts/src/chart/iterative_layout_strategy.dart' as strategy show LabelLayoutStrategy;
11 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
12 |
13 | import 'package:flutter_charts/src/coded_layout/chart/presenter.dart' as presenter; // OLD - ok to use in switch
14 |
15 | abstract class SwitchChartViewModelCL extends SwitchChartViewModel {
16 |
17 | SwitchChartViewModelCL({
18 | required model.ChartModel chartModel,
19 | required ChartType chartType,
20 | required ChartOrientation chartOrientation,
21 | required ChartStacking chartStacking,
22 | required LiveOrTesting liveOrTesting,
23 | strategy.LabelLayoutStrategy? inputLabelLayoutStrategy,
24 | }) : super(
25 | chartModel: chartModel,
26 | chartType: chartType,
27 | chartOrientation: chartOrientation,
28 | chartStacking: chartStacking,
29 | liveOrTesting: liveOrTesting,
30 | inputLabelLayoutStrategy: inputLabelLayoutStrategy,
31 | );
32 |
33 | /// Makes pointPresenters, the visuals painted on each chart column that
34 | /// represent data, (points and lines for the line chart,
35 | /// rectangles for the bar chart, and so on).
36 | ///
37 | /// See [PointPresenterCreator] and [PointPresenter] for more details.
38 | late presenter.PointPresenterCreator pointPresenterCreator; // equivalent of NEW ChartViewModel in OLD layout
39 |
40 | /// Overridden view models for chart areas.
41 | @override
42 | container.ChartRootContainerCL makeChartRootContainer({required ChartViewModel chartViewModel});
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/lib/src/util/collection.dart:
--------------------------------------------------------------------------------
1 | import 'dart:collection' as collection show ListBase;
2 |
3 | class CustomList extends collection.ListBase {
4 |
5 | /// Makes this custom list growable on/off on construction.
6 | final bool _growable;
7 |
8 | /// Delegate to which we pass all concrete methods of the [CustomList] class.
9 | late final List delegate;
10 |
11 | /// The single UNNAMED, and one of GENERATIVE constructors. 1 unnamed which is also generative always works.
12 | CustomList({required bool growable})
13 | : _growable = growable,
14 | super() {
15 | delegate = List.empty(growable: _growable);
16 | }
17 |
18 | // ListBase implements all read operations using only the
19 | // - `length` and
20 | // - `operator[]` and members.
21 | // It implements write operations using those and
22 | // - `add`,
23 | // - `length=` and
24 | // - `operator[]=`
25 | // Classes using this base classs should implement those five operations.
26 |
27 | @override
28 | set length(int newLength) {
29 | delegate.length = newLength;
30 | }
31 |
32 | @override
33 | int get length => delegate.length;
34 |
35 | @override
36 | E operator [](int index) => delegate[index];
37 |
38 | @override
39 | void operator []=(int index, E value) {
40 | delegate[index] = value;
41 | }
42 |
43 | /// The [add] method must be overridden for lists that do NOT
44 | /// allow `null` as element.
45 | @override
46 | void add(E element) {
47 | delegate.add(element);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/lib/src/util/extensions_dart.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math show min, max;
2 |
3 | // this level
4 | import 'package:flutter_charts/src/util/util_dart.dart';
5 |
6 | import 'package:flutter_charts/src/morphic/container/morphic_dart_enums.dart' show Sign;
7 |
8 | /// Extensions on the [String] class.
9 | ///
10 | extension StringExtension on String {
11 | /// Convert this string to enum.
12 | ///
13 | /// In more detail:
14 | /// - If this string is a valid enum name in the passed enumValues, returns the enum value
15 | /// represented by this string.
16 | /// - If this string does not represent an enum in the passed enumValues,
17 | /// a StateError is thrown, indicating the values that failed.
18 | T asEnum(List enumValues) {
19 | try {
20 | return enumValues.singleWhere((v) => this == enumName(v));
21 | } on Error {
22 | // on Error catch (e) {
23 | throw StateError('String $this is not in enum list $enumValues.');
24 | }
25 | }
26 | }
27 |
28 | extension IterableExtension on Iterable {
29 | E reduceOrElse(E Function(E value, E element) combine, {E Function()? orElse}) {
30 | if (isNotEmpty) {
31 | return reduce(combine);
32 | }
33 | if (orElse != null) {
34 | return orElse();
35 | }
36 | throw StateError('Iterable $this has no elements. this=${toList()}');
37 | }
38 |
39 | double extremeValueWithSign(Sign sign) {
40 | switch(sign) {
41 | case Sign.positiveOr0:
42 | return fold(0.0, (prev, element) => math.max(prev, element as double));
43 | case Sign.negative:
44 | return fold(0.0, (prev, element) => math.min(prev, element as double));
45 | case Sign.any:
46 | throw StateError('method extremeWithSign cannot be applied on Sign.any');
47 | }
48 | }
49 | }
50 |
51 | extension ListExtension on List> {
52 | List expandIt() => expand((item) => item).toList();
53 |
54 | /// Replace each element of this list with multiple elements, each element in the multiple
55 | /// is a list of two items: first item is the element of this list, the second item is element of the
56 | /// passed [multiplyBy] list in order.
57 | ///
58 | /// Example:
59 | /// ['1', '2', '3'].multiplyElementsBy( ['a', 'b'] ) -> [[1, a], [1, b], [2, a], [2, b], [3, a], [3, b]]
60 | List multiplyElementsBy(List multiplyBy) {
61 | return map((item) => List.generate(multiplyBy.length, (int index) => [item, multiplyBy[index]])).expand((item) => item).toList();
62 | }
63 | }
64 |
65 | List expandList(List listList) => listList.expand((item) => item).toList();
66 |
67 | // List is List<[E, T]>
68 | List multiplyListElementsBy(List list, List multiplyBy) =>
69 | list.map((item) => List.generate(multiplyBy.length, (int index) => [item, multiplyBy[index]])).expand((item) => item).toList();
70 |
71 | /* No practical use as * is not overridable for vector and matrix
72 | import 'vector/vector_2d.dart';
73 | import 'vector/matrix_2d.dart';
74 | extension NumExtension on num {
75 | /// Multiply (scale) vector by number, for use in linear algebra.
76 | Vector operator *(Vector v) {
77 | return v.scaleBy(this);
78 | }
79 |
80 | /// Multiply (scale) matrix by number, for use in linear algebra.
81 | Matrix operator *(Matrix m) {
82 | return m.scaleBy(this);
83 | }
84 | }
85 | */
86 |
--------------------------------------------------------------------------------
/lib/src/util/util_flutter.dart:
--------------------------------------------------------------------------------
1 | /// Utility that contain only Dart code BUT DOES import 'dart:ui' or anything Flutter.
2 | /// See util_dart.dart for reason.
3 | import 'dart:math' as math;
4 | import 'dart:ui' show Rect, Size, Offset;
5 |
6 | // this level
7 | import 'package:flutter_charts/src/util/util_dart.dart';
8 | import 'package:flutter_charts/src/util/extensions_dart.dart';
9 |
10 | import 'package:flutter_charts/src/morphic/ui2d/point.dart';
11 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart' show ChartOrientation;
12 |
13 |
14 | /// Returns the smallest rectangle which contains all passed [rectangles].
15 | ///
16 | /// If the [rectangles] list is empty, an origin-based, zero-sized rectangle is returned.
17 | Rect boundingRect(List rectangles, /*{double Function()? orElse}*/) {
18 | return Rect.fromLTRB(
19 | rectangles.map((Rect rectangle) => rectangle.left).reduceOrElse(math.min, orElse: () => 0.0), // left
20 | rectangles.map((Rect rectangle) => rectangle.top).reduceOrElse(math.min, orElse: () => 0.0), // top,
21 | rectangles.map((Rect rectangle) => rectangle.right).reduceOrElse(math.max, orElse: () => 0.0), // right
22 | rectangles.map((Rect rectangle) => rectangle.bottom).reduceOrElse(math.max, orElse: () => 0.0), // bottom
23 | );
24 | }
25 |
26 | void assertSizeResultsSame(Size result, Size otherResult) {
27 | if (!(isCloserThanEpsilon(result.width, otherResult.width) &&
28 | isCloserThanEpsilon(result.height, otherResult.height))) {
29 | String msg = ' ### Log.Warning: Size results do not match. Result was $result, Other result was $otherResult.';
30 | print(msg);
31 | throw StateError(msg);
32 | }
33 | }
34 |
35 | void assertOffsetResultsSame(Offset result, Offset otherResult) {
36 | if (!(isCloserThanEpsilon(result.dx, otherResult.dx) &&
37 | isCloserThanEpsilon(result.dy, otherResult.dy))) {
38 | String msg = ' ### Log.Warning: Offset results do not match. Result was $result, Other result was $otherResult.';
39 | print(msg);
40 | throw StateError(msg);
41 | }
42 | }
43 |
44 | /// Holder class defining the ranges and orientation in one place for the benefit
45 | /// of [PointOffset.affmapBetweenRanges].
46 | ///
47 | /// todo-02-design : Should it contain ChartStacking information?
48 | class FromTransposing2DValueRange {
49 |
50 | FromTransposing2DValueRange ({
51 | required this.inputDataRange,
52 | required this.outputDataRange,
53 | required this.chartOrientation,
54 | });
55 |
56 | final Interval inputDataRange;
57 | final Interval outputDataRange;
58 | final ChartOrientation chartOrientation;
59 |
60 | FromTransposing2DValueRange subsetForSignOfPointOffsetBeforeAffmap({required PointOffset pointOffset,}) {
61 | return FromTransposing2DValueRange(
62 | inputDataRange: inputDataRange.portionForSignOfValue(pointOffset.inputValue),
63 | outputDataRange: outputDataRange.portionForSignOfValue(pointOffset.outputValue),
64 | chartOrientation: chartOrientation,
65 | );
66 | }
67 | }
68 |
69 | /// Pixel 2D range encapsulates the 'to range' of values that ore affmap-ed
70 | /// from a [FromTransposing2DValueRange] instance.
71 | ///
72 | /// Always starts both dimensions from 0.
73 | ///
74 | /// Although this mentions 'pixels', it should be part of model,
75 | /// as the name is merely a convenience to define a 'to range' of
76 | /// values that ore affmap-ed from [FromTransposing2DValueRange].
77 | class To2DPixelRange {
78 |
79 | To2DPixelRange({
80 | // sizerWidth or constraints width
81 | required double width,
82 | // sizerHeight or constraints height
83 | required double height,
84 | }) : horizontalPixelRange = Interval(0, width), verticalPixelRange = Interval(0, height);
85 |
86 | final Interval horizontalPixelRange;
87 | final Interval verticalPixelRange;
88 |
89 | Size get size => Size(horizontalPixelRange.max, verticalPixelRange.max);
90 | }
91 |
--------------------------------------------------------------------------------
/lib/src/util/vector/vector_2d.dart:
--------------------------------------------------------------------------------
1 |
2 | /// Vector. Equivalent to 1 Dimensional matrix.
3 | class Vector {
4 | Vector(List from)
5 | : _storage = from;
6 |
7 | final List _storage;
8 | get length => _storage.length;
9 |
10 | /// Vector addition
11 | Vector operator +(Vector other) {
12 | _validate(other);
13 | return Vector(List.generate(length, (index) => _storage[index] + other._storage[index]));
14 | }
15 |
16 | /// Point-wise product
17 | Vector operator *(Vector other) {
18 | _validate(other);
19 | return Vector(List.generate(length, (index) => _storage[index] * other._storage[index]));
20 | }
21 |
22 | T operator [](int index) => _storage[index];
23 |
24 | Vector abs() {
25 | return Vector(_storage.map((element) => element.abs()).toList());
26 | }
27 |
28 | /// Inner product
29 | num innerProduct(Vector other) {
30 | _validate(other);
31 | return List.generate(length, (index) => _storage[index] * other._storage[index]).fold(0, (a,b) => a + b);
32 | }
33 |
34 | Vector scaleBy(num scale) {
35 | return Vector(List.generate(length, (index) => scale * this[index])); // this[index] == _storage[index]
36 | }
37 |
38 | void _validate(Vector other) {
39 | if (length != other.length) throw StateError('$runtimeType: Uneven length, this=$length, other=${other.length}');
40 | }
41 |
42 | void ensureLength(int length, {String? elseMessage}) {
43 | if (this.length != length) {
44 | throw StateError('$runtimeType instance=$this ${elseMessage ?? ""}');
45 | }
46 | }
47 |
48 | @override
49 | bool operator ==(Object other) {
50 | if (other is! Vector) return false;
51 | if (_storage.length != other._storage.length) return false;
52 |
53 | for (int i = 0; i < _storage.length; i++) {
54 | if (_storage[i] != other._storage[i]) {
55 | return false;
56 | }
57 | }
58 | return true;
59 | }
60 |
61 | @override
62 | int get hashCode => _storage.hashCode;
63 |
64 | }
--------------------------------------------------------------------------------
/lib/test/src/README.org:
--------------------------------------------------------------------------------
1 | This directory
2 |
3 | ~flutter_charts/test/src~
4 |
5 | has subdirectory structure equivalent to
6 |
7 | ~flutter_charts/lib/src~
8 |
9 | and contains classes used only in tests, but are not test classes.
10 |
11 | Most it's classes are testing extensions of base classes; those testing extensions are used in tests and integration tests.
12 |
13 | Note:
14 |
15 | The subdirectory ~flutter_charts/test/src/example~ is not equivalently placed; it contains the main example used in tests.
16 |
17 | The intent of this ~example~ subdirectory is to hold a ~main.dart~ used in tests and integration tests,
18 | while the ~flutter_charts/example~ is used to be published on *pub*.
--------------------------------------------------------------------------------
/lib/test/src/chart/options.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_charts/src/chart/options.dart' as chart_options;
2 |
3 | class LegendAndItemLayoutEnum extends chart_options.LegendAndItemLayoutEnum {
4 |
5 | const LegendAndItemLayoutEnum(super.i);
6 |
7 | static const legendIsColumnStartLooseItemIsRowStartLoose = chart_options.LegendAndItemLayoutEnum(1001); // See comment on legendIsColumnStartTightItemIsRowStartTight
8 | static const legendIsColumnStartTightItemIsRowStartTight = chart_options.LegendAndItemLayoutEnum(1002); // legend items in column
9 | static const legendIsRowCenterLooseItemIsRowEndLoose = chart_options.LegendAndItemLayoutEnum(1003); // Item row is not top = chart_options.LegendAndItemLayoutEnum(XX); forced to 'start' = chart_options.LegendAndItemLayoutEnum(XX); 'tight' = chart_options.LegendAndItemLayoutEnum(XX); so noop
10 | static const legendIsRowStartTightItemIsRowStartTightSecondGreedy = chart_options.LegendAndItemLayoutEnum(1005); // second Item is greedy wrapped
11 | static const legendIsRowStartTightItemIsRowStartTightItemChildrenPadded = chart_options.LegendAndItemLayoutEnum(1006);
12 | static const legendIsRowStartTightItemIsRowStartTightItemChildrenAligned = chart_options.LegendAndItemLayoutEnum(1007);
13 | }
--------------------------------------------------------------------------------
/lib/test/src/switch_view_model/coded_layout/bar/view_model.dart:
--------------------------------------------------------------------------------
1 | // import 'package:logger/logger.dart' as logger;
2 |
3 | import 'package:flutter_charts/test/src/chart/cartesian/container/legend_container.dart' as testing_legend_container;
4 | import 'package:flutter_charts/src/chart/cartesian/container/axislabels_axislines_gridlines_container.dart';
5 |
6 | // base libraries
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
8 | import 'package:flutter_charts/src/switch_view_model/auto_layout/bar/view_model.dart' as bar_chart_view_model;
9 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
10 | import 'package:flutter_charts/src/chart/cartesian/chart_type/bar/container/root_container.dart';
11 | import 'package:flutter_charts/src/chart/model/data_model.dart';
12 | import 'package:flutter_charts/src/chart/iterative_layout_strategy.dart' as strategy show LabelLayoutStrategy;
13 | import 'package:flutter_charts/src/chart/cartesian/chart_type/bar/container/data_container.dart';
14 |
15 | /// Concrete [ChartViewModel] for [BarChart].
16 | ///
17 | /// See [ChartViewModel] for help.
18 | class SwitchBarChartViewModel extends bar_chart_view_model.SwitchBarChartViewModel {
19 | SwitchBarChartViewModel({
20 | required ChartModel chartModel,
21 | required ChartType chartType,
22 | required ChartOrientation chartOrientation,
23 | required LiveOrTesting liveOrTesting,
24 | required ChartStacking chartStacking,
25 | strategy.LabelLayoutStrategy? inputLabelLayoutStrategy,
26 | }) : super(
27 | chartModel: chartModel,
28 | chartType: chartType,
29 | chartOrientation: chartOrientation,
30 | chartStacking: chartStacking,
31 | liveOrTesting: liveOrTesting,
32 | inputLabelLayoutStrategy: inputLabelLayoutStrategy,
33 | );
34 |
35 | /// Concrete implementation returns the root for vertical bar chart.
36 | @override
37 | BarChartRootContainer makeChartRootContainer({required ChartViewModel chartViewModel}) {
38 | return BarChartRootContainer(
39 | legendContainer: testing_legend_container.LegendContainer(chartViewModel: this),
40 | horizontalAxisContainer: TransposingAxisLabels.HorizontalAxis(chartViewModel: this),
41 | verticalAxisContainerFirst: TransposingAxisLabels.VerticalAxis(chartViewModel: this),
42 | verticalAxisContainer: TransposingAxisLabels.VerticalAxis(chartViewModel: this),
43 | dataContainer: BarChartDataContainer(chartViewModel: this),
44 | chartViewModel: chartViewModel,
45 | );
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/lib/test/src/switch_view_model/coded_layout/line/view_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:logger/logger.dart' as logger;
2 |
3 | // base libraries
4 | // import 'package:flutter_charts/src/chart/cartesian/container/legend_container.dart';
5 | import 'package:flutter_charts/test/src/chart/cartesian/container/legend_container.dart' as testing_legend_container;
6 | import 'package:flutter_charts/src/chart/cartesian/container/axislabels_axislines_gridlines_container.dart';
7 | import 'package:flutter_charts/src/chart/view_model/view_model.dart';
8 | import 'package:flutter_charts/src/switch_view_model/auto_layout/line/view_model.dart' as line_chart_view_model;
9 | import 'package:flutter_charts/src/chart/model/data_model.dart';
10 | import 'package:flutter_charts/src/chart/iterative_layout_strategy.dart' as strategy show LabelLayoutStrategy;
11 | import 'package:flutter_charts/src/chart/cartesian/chart_type/line/container/data_container.dart';
12 |
13 | import 'package:flutter_charts/src/chart/cartesian/chart_type/line/container/root_container.dart';
14 |
15 | // this level: switch/auto_layout/bar
16 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
17 |
18 | /// Concrete [ChartViewModel] for [LineChart].
19 | ///
20 | /// See [ChartViewModel] for help.
21 | class SwitchLineChartViewModel extends line_chart_view_model.SwitchLineChartViewModel {
22 | SwitchLineChartViewModel({
23 | required ChartModel chartModel,
24 | required ChartType chartType,
25 | required ChartOrientation chartOrientation,
26 | required ChartStacking chartStacking,
27 | required LiveOrTesting liveOrTesting,
28 | strategy.LabelLayoutStrategy? inputLabelLayoutStrategy,
29 | }) : super(
30 | chartModel: chartModel,
31 | chartType: chartType,
32 | chartOrientation: chartOrientation,
33 | chartStacking: chartStacking,
34 | liveOrTesting: liveOrTesting,
35 | inputLabelLayoutStrategy: inputLabelLayoutStrategy,
36 | ) {
37 | logger.Logger().d('$runtimeType created');
38 | }
39 |
40 | /// Concrete implementation returns the root for vertical bar chart.
41 | @override
42 | LineChartRootContainer makeChartRootContainer({required ChartViewModel chartViewModel}) {
43 | return LineChartRootContainer(
44 | legendContainer: testing_legend_container.LegendContainer(chartViewModel: this),
45 | horizontalAxisContainer: TransposingAxisLabels.HorizontalAxis(chartViewModel: this),
46 | verticalAxisContainerFirst: TransposingAxisLabels.VerticalAxis(chartViewModel: this),
47 | verticalAxisContainer: TransposingAxisLabels.VerticalAxis(chartViewModel: this),
48 | dataContainer: LineChartDataContainer(chartViewModel: this),
49 | chartViewModel: chartViewModel,
50 | );
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/lib/test/src/util/test_util.dart:
--------------------------------------------------------------------------------
1 | /// Utilities used in tests and integration tests.
2 | ///
3 |
4 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
5 | import 'package:flutter_charts/flutter_charts.dart' show enumName;
6 | import 'package:flutter_charts/src/chart/util/example_descriptor.dart' show ExampleDescriptor;
7 |
8 | /// Extract paths to screenshots for tests.
9 | ///
10 | /// Paths include filename, and are relative to project root.
11 | class ScreenshotPaths {
12 |
13 | ScreenshotPaths({
14 | required this.exampleDescriptor,
15 | });
16 |
17 | final ExampleDescriptor exampleDescriptor;
18 |
19 | late final String _expectedScreenshotPath = _relativePath(_expectedScreenshotDirName(), exampleDescriptor);
20 | String get expectedScreenshotPath => _expectedScreenshotPath;
21 | late final String _actualScreenshotPath = _relativePath(_screenshotDirName(), exampleDescriptor);
22 | String get actualScreenshotPath => _actualScreenshotPath;
23 |
24 | /// Path to screenshot file the test uses for each test.
25 | String _relativePath(String screenshotDirName, ExampleDescriptor exampleDescriptor) {
26 | return '$screenshotDirName/${_screenshotFileName(exampleDescriptor)}';
27 | }
28 |
29 | /// Path to screenshot file which this test generates.
30 | ///
31 | /// Generated from enum values.
32 | /// Examples:
33 | /// - 'ex10RandomData_lineChart.png' (for old layout)
34 | /// - 'ex10RandomData_lineChart_NEW.png' (for new layout)
35 | String _screenshotFileName(
36 | ExampleDescriptor exampleDescriptor,
37 | ) {
38 | /* todo-00-done
39 | ChartLayouter chartLayouter = exampleDescriptor.chartLayouter;
40 | String newLayoutSuffix = '';
41 | if (!(chartLayouter == ChartLayouter.oldManualLayouter)) {
42 | newLayoutSuffix =
43 | '_NEW_orientation_${exampleDescriptor.chartOrientation.name}_stacking_${exampleDescriptor.chartStacking.name}';
44 | }
45 |
46 | return '${enumName(exampleDescriptor.exampleEnum)}_${enumName(exampleDescriptor.chartType)}$newLayoutSuffix.png';
47 | */
48 | String version;
49 | switch (exampleDescriptor.chartLayouter) {
50 | case ChartLayouter.newAutoLayouter:
51 | version = 'NEW';
52 | break;
53 | case ChartLayouter.oldManualLayouter:
54 | version = 'OLD';
55 | break;
56 | }
57 | // return '${enumName(exampleDescriptor.exampleEnum)}_${enumName(exampleDescriptor.chartType)}$newLayoutSuffix.png';
58 | return '${enumName(exampleDescriptor.exampleEnum)}'
59 | '_${exampleDescriptor.chartType.name}'
60 | '_${exampleDescriptor.chartOrientation.name}'
61 | '_${exampleDescriptor.chartStacking.name}'
62 | '_${exampleDescriptor.chartLayouter.name}'
63 | '.png';
64 | }
65 |
66 | /// The name of the directory where screenshots are placed.
67 | ///
68 | /// This test is assumed to run from project's root.
69 | String _screenshotDirName() {
70 | return 'integration_test/screenshots_tested';
71 | }
72 |
73 | String _expectedScreenshotDirName() {
74 | return 'integration_test/screenshots_expected';
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/test/chart/util/example_descriptor_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_charts/src/chart/util/example_descriptor.dart';
2 | import 'package:flutter_charts/src/morphic/container/chart_support/chart_style.dart';
3 | import 'package:test/test.dart';
4 |
5 | main() {
6 | group('Single valid descriptor string', () {
7 |
8 | test('Valid descriptor: Fully descriptive single-ex-matching String', () {
9 | var descriptor = 'ex10RandomData_barChart_column_stacked_oldManualLayouter';
10 | var exampleDescriptors = ExampleDescriptor.parseDescriptors([descriptor]);
11 |
12 | expect(exampleDescriptors.length, 1);
13 | expect(exampleDescriptors[0].exampleEnum, ExampleEnum.ex10RandomData);
14 | expect(exampleDescriptors[0].chartType, ChartType.barChart);
15 | expect(exampleDescriptors[0].chartOrientation, ChartOrientation.column);
16 | expect(exampleDescriptors[0].chartStacking, ChartStacking.stacked);
17 | expect(exampleDescriptors[0].chartLayouter, ChartLayouter.oldManualLayouter);
18 |
19 | });
20 |
21 | test('Valid descriptor: Partially descriptive single-ex-matching String', () {
22 | var descriptor = 'ex10_barChart_column_stacked_oldManualLayouter';
23 | var exampleDescriptors = ExampleDescriptor.parseDescriptors([descriptor]);
24 |
25 | expect(exampleDescriptors.length, 1);
26 | expect(exampleDescriptors[0].exampleEnum, ExampleEnum.ex10RandomData);
27 | expect(exampleDescriptors[0].chartType, ChartType.barChart);
28 | expect(exampleDescriptors[0].chartOrientation, ChartOrientation.column);
29 | expect(exampleDescriptors[0].chartStacking, ChartStacking.stacked);
30 | expect(exampleDescriptors[0].chartLayouter, ChartLayouter.oldManualLayouter);
31 |
32 | });
33 |
34 | test('Valid descriptor: Partially descriptive multi-ex-matching String', () {
35 | var descriptor = 'ex_barChart_column_stacked_oldManualLayouter';
36 | var exampleDescriptors = ExampleDescriptor.parseDescriptors([descriptor]);
37 |
38 | expect(exampleDescriptors.length > 1, true);
39 |
40 | /* not true, although they look the same on toString :
41 | var sortedExampleDescriptors = List.from(exampleDescriptors)
42 | ..sort((d1, d2) {
43 | return d1.exampleEnum.toString().compareTo(d2.exampleEnum.toString());
44 | });
45 | print(exampleDescriptors);
46 | print(sortedExampleDescriptors);
47 | expect(exampleDescriptors == sortedExampleDescriptors, true);
48 | */
49 |
50 | });
51 |
52 | test('Valid descriptor: Fuzzy descriptive single-ex-matching String', () {
53 | var descriptor = 'ex10RandomData_*_column_stacked_oldManualLayouter';
54 | var exampleDescriptors = ExampleDescriptor.parseDescriptors([descriptor]);
55 |
56 | expect(exampleDescriptors.length, 2);
57 | expect(exampleDescriptors[0].exampleEnum, ExampleEnum.ex10RandomData);
58 | expect(exampleDescriptors[0].chartType, ChartType.lineChart);
59 | expect(exampleDescriptors[0].chartOrientation, ChartOrientation.column);
60 | expect(exampleDescriptors[0].chartStacking, ChartStacking.stacked);
61 | expect(exampleDescriptors[0].chartLayouter, ChartLayouter.oldManualLayouter);
62 |
63 | expect(exampleDescriptors[1].exampleEnum, ExampleEnum.ex10RandomData);
64 | expect(exampleDescriptors[1].chartType, ChartType.barChart);
65 | expect(exampleDescriptors[1].chartOrientation, ChartOrientation.column);
66 | expect(exampleDescriptors[1].chartStacking, ChartStacking.stacked);
67 | expect(exampleDescriptors[1].chartLayouter, ChartLayouter.oldManualLayouter);
68 | });
69 |
70 | });
71 |
72 | group('Invalid descriptor string', () {
73 | test('Invalid descriptor: throws StateError with appropriate message', () {
74 | var descriptor = 'ex10_YYYChart_column_stacked_oldManualLayouter';
75 | // Note: reason does not seem to matter. Not sure how to check for exception text
76 | expect(
77 | () => ExampleDescriptor.parseDescriptors([descriptor]),
78 | throwsStateError,
79 | reason: 'Invalid (zero based) ChartType field 1',
80 | );
81 | });
82 | });
83 |
84 | group('Multi descriptor string', () {
85 |
86 | test('Valid descriptor: 2 Fully descriptive single-ex-matching Strings', () {
87 | var descriptor1 = 'ex10RandomData_barChart_column_stacked_oldManualLayouter';
88 | var descriptor2 = 'ex10RandomData_barChart_column_stacked_newAutoLayouter';
89 | var exampleDescriptors = ExampleDescriptor.parseDescriptors([descriptor1, descriptor2]);
90 |
91 | expect(exampleDescriptors.length, 2);
92 |
93 | expect(exampleDescriptors[0].exampleEnum, ExampleEnum.ex10RandomData);
94 | expect(exampleDescriptors[0].chartType, ChartType.barChart);
95 | expect(exampleDescriptors[0].chartOrientation, ChartOrientation.column);
96 | expect(exampleDescriptors[0].chartStacking, ChartStacking.stacked);
97 | expect(exampleDescriptors[0].chartLayouter, ChartLayouter.oldManualLayouter);
98 |
99 | expect(exampleDescriptors[1].exampleEnum, ExampleEnum.ex10RandomData);
100 | expect(exampleDescriptors[1].chartType, ChartType.barChart);
101 | expect(exampleDescriptors[1].chartOrientation, ChartOrientation.column);
102 | expect(exampleDescriptors[1].chartStacking, ChartStacking.stacked);
103 | expect(exampleDescriptors[1].chartLayouter, ChartLayouter.newAutoLayouter);
104 | });
105 |
106 | test('Valid descriptor: 2 Fully descriptive multi-ex-matching Strings', () {
107 | var descriptor1 = 'ex10RandomData_*_column_stacked_*';
108 | var descriptor2 = 'ex10RandomData_barChart_*_*_newAutoLayouter';
109 | var exampleDescriptors = ExampleDescriptor.parseDescriptors([descriptor1, descriptor2]);
110 |
111 | expect(exampleDescriptors.length, 8);
112 |
113 | });
114 | });
115 | }
--------------------------------------------------------------------------------
/test/deprecated_v1/screenshot_validate_deprecated_v1_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 | import 'dart:io';
3 |
4 | import '../../lib/test/src/util/test_util.dart';
5 |
6 | import 'package:flutter_charts/src/chart/util/example_descriptor.dart'
7 | show ExampleDescriptor;
8 |
9 | /// @Deprecated, see 'test/screenshot_validate_test_new.dart'.
10 | void main() {
11 | test('after screenshot integration, test for sameness', () {
12 |
13 | ExampleDescriptor exampleDescriptor = ExampleDescriptor.requestedExampleToRun();
14 |
15 | var screenshotPaths = ScreenshotPaths(exampleDescriptor: exampleDescriptor);
16 | String expectedScreenshotPath = screenshotPaths.expectedScreenshotPath;
17 | String screenshotPath = screenshotPaths.actualScreenshotPath;
18 |
19 | // Flag controls if this test runs 'expect'.
20 | // Set to false to generate initial validated screenshots.
21 | bool runExpect = true;
22 |
23 | if (runExpect && !ExampleDescriptor.isExampleWithRandomData(exampleDescriptor)) {
24 | File expectedFile = File(expectedScreenshotPath);
25 | File actualFile = File(screenshotPath);
26 |
27 | // Compare the screenshot just generated with one that was stored as expected.
28 | expectSync(
29 | expectedFile.readAsBytesSync(),
30 | actualFile.readAsBytesSync(),
31 | );
32 | }
33 | });
34 | }
35 |
--------------------------------------------------------------------------------
/test/screenshot_validate_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 | import 'dart:io';
3 |
4 | import '../lib/test/src/util/test_util.dart';
5 |
6 | import 'package:flutter_charts/src/chart/util/example_descriptor.dart'
7 | show ExampleDescriptor;
8 |
9 | /// Flutter test compares expected screenshots to actual screenshots for all chart examples
10 | /// defined by the '--dart-define' environment variable 'EXAMPLES_DESCRIPTORS',
11 | /// and resolved in [ExampleDescriptor.extractExamplesDescriptorsFromDartDefine].
12 | ///
13 | void main() {
14 |
15 | // Extract descriptors for examples to run. examplesDescriptors must be pushed via --dart-define=EXAMPLES_DESCRIPTORS.
16 | List examplesDescriptors = ExampleDescriptor.extractExamplesDescriptorsFromDartDefine(
17 | message: 'main() of screenshot_validate_test.dart',
18 | );
19 |
20 | test('after screenshot integration, test for sameness', () {
21 |
22 | for (var exampleDescriptor in examplesDescriptors) {
23 |
24 | print(' \n\n######### Log.Info.Level1: screenshot_validate_test.dart: Will COMPARE SCREENSHOT of $exampleDescriptor');
25 |
26 | var screenshotPaths = ScreenshotPaths(exampleDescriptor: exampleDescriptor);
27 | String expectedScreenshotPath = screenshotPaths.expectedScreenshotPath;
28 | String screenshotPath = screenshotPaths.actualScreenshotPath;
29 |
30 | // Flag controls if this test runs 'expect'.
31 | // Set to false to generate initial validated screenshots.
32 | bool runExpect = true;
33 |
34 | if (runExpect && !ExampleDescriptor.isExampleWithRandomData(exampleDescriptor)) {
35 | File expectedFile = File(expectedScreenshotPath);
36 | File actualFile = File(screenshotPath);
37 |
38 | // Compare the screenshot just generated with one that was stored as expected.
39 | expectSync(
40 | expectedFile.readAsBytesSync(),
41 | actualFile.readAsBytesSync(),
42 | );
43 | }
44 | }
45 | });
46 | }
47 |
--------------------------------------------------------------------------------
/test/tmp/.gitignore:
--------------------------------------------------------------------------------
1 | # The parent directory tmp is for programs and files generated during tests.
2 |
3 | # Presence of this .gitignore commands to ignore everything but itself.
4 | # This achieves the directory is NOT ignored, and shows up on github,
5 | # while all files in this directory (which are temporary) are ignored.
6 |
7 | # * ignores everything (files and subfolders), !.gitignore keeps this file.
8 | *
9 | !.gitignore
10 |
--------------------------------------------------------------------------------
/test/util/extensions_dart_test.dart:
--------------------------------------------------------------------------------
1 | /// Tests the methods in the `string_extension` package.
2 |
3 | import 'package:test/test.dart';
4 |
5 | // Tested package
6 | import 'package:flutter_charts/src/util/extensions_dart.dart' show StringExtension;
7 |
8 | enum TestedEnum { enum1, enum2 }
9 |
10 | void main() {
11 | // enum related string extensions.
12 | group('enum', () {
13 | test('Convert string literal (representing a valid enum name) to enum', () {
14 | final TestedEnum testedEnum = 'enum1'.asEnum(TestedEnum.values);
15 | expect(testedEnum, TestedEnum.enum1);
16 | });
17 |
18 | test('Convert string object (representing a valid enum name) to enum', () {
19 | const String enum1 = 'enum1';
20 | final TestedEnum testedEnum = enum1.asEnum(TestedEnum.values);
21 | expect(testedEnum, TestedEnum.enum1);
22 | });
23 |
24 | test('Convert string which does not have representation should cause exception', () {
25 | // Checking error thrown requires first argument to be a Function,
26 | // NOT a function call such as just "NOT_IN_ENUM".asEnum(TestedEnum.values).
27 | expect(() => 'NOT_IN_ENUM'.asEnum(TestedEnum.values), throwsStateError);
28 | });
29 |
30 | test('Convert string which does not have representation should cause exception. Test the exception string.', () {
31 | String errorText = '';
32 | try {
33 | 'NOT_IN_ENUM'.asEnum(TestedEnum.values);
34 | } on Error catch (e) {
35 | errorText = e.toString();
36 | }
37 | expect(errorText.contains('String NOT_IN_ENUM is not in enum list [TestedEnum.enum1, TestedEnum.enum2]'), true);
38 | });
39 | });
40 |
41 | // next group
42 | }
43 |
--------------------------------------------------------------------------------
/test/util/function_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:test/test.dart';
2 |
3 | void main() {
4 |
5 | group('Functions', () {
6 | group('Functions == : Same result producing functions are not ==', () {
7 | double f(double arg) => arg * arg;
8 | double g(double arg) => arg * arg;
9 | test('f == g', () {
10 | assert(f == f, true);
11 | assert(g == g, true);
12 | // Always throws, whether true or false. Use expect instead of assert: assert(f == g, true);
13 | expect((f == f), true);
14 | expect((g == g), true);
15 | expect((f == g), false);
16 | });
17 | });
18 | });
19 |
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/test/util/vector/vector_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:test/test.dart';
2 |
3 | // import 'package:flutter_charts/src/util/util_dart.dart';
4 |
5 | import 'package:flutter_charts/src/util/vector/vector_2d.dart';
6 | import 'package:flutter_charts/src/util/vector/matrix_2d.dart';
7 | import 'package:flutter_charts/src/util/vector/function_matrix_2d.dart';
8 |
9 | void main() {
10 | group('double matrices and vectors', () {
11 |
12 | test('doubleMatrix.applyOnVector', () {
13 | var v = Vector([1.0, 2.0]);
14 | var m = DoubleMatrix2D([
15 | [10.0, 20.0],
16 | [100.0, 200.0],
17 | ]);
18 | var result = Vector([50.0, 500.0]);
19 |
20 | expect(result == m.applyOnVector(v), true);
21 | });
22 |
23 | test('doubleMatrix * doubleMatrix', () {
24 | var m1 = DoubleMatrix2D([
25 | [10.0, 20.0],
26 | [100.0, 200.0],
27 | ]);
28 | var m2 = DoubleMatrix2D([
29 | [1.0, 2.0],
30 | [3.0, 4.0],
31 | ]);
32 | var result = DoubleMatrix2D([
33 | [70.0, 100.0],
34 | [700.0, 1000.0],
35 | ]);
36 | var wrongResult = DoubleMatrix2D([
37 | [70.0, 100.0],
38 | [700.0, 1111.0],
39 | ]);
40 |
41 | expect(result == (m1 * m2), true);
42 |
43 | expect(wrongResult == (m1 * m2), false);
44 | });
45 |
46 | test('doubleMatrix + doubleMatrix', () {
47 | var m1 = DoubleMatrix2D([
48 | [10.0, 20.0],
49 | [100.0, 200.0],
50 | ]);
51 | var m2 = DoubleMatrix2D([
52 | [1.0, 2.0],
53 | [3.0, 4.0],
54 | ]);
55 | var result = DoubleMatrix2D([
56 | [11.0, 22.0],
57 | [103.0, 204.0],
58 | ]);
59 | var wrongResult = DoubleMatrix2D([
60 | [11.0, 22.0],
61 | [103.0, 1111.0],
62 | ]);
63 |
64 | expect(result == (m1 + m2), true);
65 |
66 | expect(wrongResult == (m1 + m2), false);
67 | });
68 | });
69 |
70 | group('functional matrices and vectors', () {
71 | test('funcMatrix.applyOnVector', () {
72 | var v = Vector([1.0, 2.0]);
73 | var m = FunctionalMatrix2D([
74 | [(x) => 10 * x, (x) => 20 * x],
75 | [(x) => 100 * x, (x) => 200 * x],
76 | ]);
77 | var result = Vector([50.0, 500.0]);
78 |
79 | expect(result == m.applyOnVector(v), true);
80 | });
81 |
82 | test('funcMatrix * funcMatrix', () {
83 | var m1 = FunctionalMatrix2D([
84 | [(x) => 10 * x, (x) => 20 * x],
85 | [(x) => 100 * x, (x) => 200 * x],
86 | ]);
87 | var m2 = FunctionalMatrix2D([
88 | [(x) => 1 * x, (x) => 2 * x],
89 | [(x) => 3 * x, (x) => 4 * x],
90 | ]);
91 | var result = FunctionalMatrix2D([
92 | [(x) => 70 * x, (x) => 100 * x],
93 | [(x) => 700 * x, (x) => 1000 * x],
94 | ]);
95 | var wrongResult = FunctionalMatrix2D([
96 | [(x) => 70 * x, (x) => 100 * x],
97 | [(x) => 700 * x, (x) => 1111 * x],
98 | ]);
99 |
100 | expect(result == (m1 * m2), true);
101 |
102 | expect(wrongResult == (m1 * m2), false);
103 | });
104 |
105 | test('funcMatrix + funcMatrix', () {
106 | var m1 = FunctionalMatrix2D([
107 | [(x) => 10 * x, (x) => 20 * x],
108 | [(x) => 100 * x, (x) => 200 * x],
109 | ]);
110 | var m2 = FunctionalMatrix2D([
111 | [(x) => 1 * x, (x) => 2 * x],
112 | [(x) => 3 * x, (x) => 4 * x],
113 | ]);
114 | var result = FunctionalMatrix2D([
115 | [(x) => 11 * x, (x) => 22 * x],
116 | [(x) => 103 * x, (x) => 204 * x],
117 | ]);
118 | var wrongResult = FunctionalMatrix2D([
119 | [(x) => 11 * x, (x) => 22 * x],
120 | [(x) => 103 * x, (x) => 1111 * x],
121 | ]);
122 |
123 | expect(result == (m1 + m2), true);
124 |
125 | expect(wrongResult == (m1 + m2), false);
126 | });
127 |
128 | });
129 |
130 | }
131 |
132 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 |
3 | import 'package:flutter_charts/test/src/test_main.dart' as app;
4 | import 'package:flutter_charts/src/chart/util/example_descriptor.dart' show ExampleMainAndTestSupport;
5 |
6 | /// Flutter widget tests for the example app in 'lib/test/src/test_main.dart'.
7 | ///
8 | /// Tests check some expected values on the main page of the app.
9 | ///
10 | /// Run as
11 | /// ``` shell
12 | /// flutter clean; flutter test test/widget_test.dart
13 | /// ```
14 | void main() {
15 | group('Widget tests on page 1', () {
16 | testWidgets('find expected text on widgets', (WidgetTester tester) async {
17 | // Build the app.
18 | app.main();
19 |
20 | await tester.pumpAndSettle();
21 |
22 | // Verify the counter starts at 0.
23 | expect(find.text('vvvvvvvv:'), findsOneWidget);
24 |
25 | // Finds the floating action button to tap on.
26 | final Finder floatingButton = find.byTooltip(ExampleMainAndTestSupport.floatingButtonTooltipMoveToNextExample);
27 |
28 | // Emulate a tap on the floating action button.
29 | await tester.tap(floatingButton);
30 |
31 | // Trigger a frame.
32 | await tester.pumpAndSettle();
33 |
34 | // Verify the counter increments by 1.
35 | expect(find.text('vvvvvvvv:'), findsOneWidget);
36 | });
37 | });
38 | }
39 |
--------------------------------------------------------------------------------
/test_driver/integration_test.dart:
--------------------------------------------------------------------------------
1 | /* todo keep this: Active code is to take a screenshot, but this is what we should have for normal testing:
2 | import 'package:integration_test/integration_test_driver.dart';
3 | Future main() => integrationDriver();
4 |
5 | // Note: This file is needed for the new integration_test (Flutter 2.5 and later) to work.
6 | // Without this file, there is a warning on
7 | // import 'package:integration_test/integration_test_driver.dart';
8 | */
9 |
10 | /// Allows to control apps from tests, while test code runs on a native device, physical or emulated.
11 | import 'dart:io';
12 | import 'package:flutter_charts/src/chart/util/example_descriptor.dart';
13 | import 'package:integration_test/integration_test_driver_extended.dart';
14 |
15 | Future main() async {
16 |
17 | // Extract descriptors for examples to run. examplesDescriptors must be pushed via --dart-define=EXAMPLES_DESCRIPTORS.
18 | // This is here only to show a message whether the env variable was picked up.
19 | // List examplesDescriptors =
20 | ExampleDescriptor.extractExamplesDescriptorsFromDartDefine(
21 | message: 'main() of screenshot_create_test.dart',
22 | );
23 |
24 | // KEEP NOTE: 2023-05-23: Broken in Flutter somewhere between 3.7(?) and 3.10.
25 | // Added ', [Map? optionalArgs]' optional argument to keep analyzer happy
26 | onScreenshot(String screenshotName, List screenshotBytes, [Map? optionalArgs]) async {
27 | final File image = File(screenshotName);
28 | // Write the image as bytes; flush ensures close before dart exit.
29 | image.writeAsBytesSync(screenshotBytes, mode: FileMode.write, flush: true);
30 | if (image.existsSync()) {
31 | return true;
32 | }
33 | // Return false if the screenshot is invalid.
34 | return false;
35 | }
36 |
37 | try {
38 | await integrationDriver(
39 | onScreenshot: onScreenshot,
40 | );
41 | } catch (e) {
42 | print(' ### Log.Error: Screenshot test driver "integration_test.dart" threw exception $e');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tool/README-tool.org:
--------------------------------------------------------------------------------
1 | This directory,
2 |
3 | flutter_charts/tool
4 |
5 | Should contain private tools such as shell scripts to build something or run tests.
6 |
7 | From https://dart.dev/tools/pub/package-layout#internal-tools-and-scripts :
8 |
9 | Mature packages often have little helper scripts and programs that people run while developing the package itself. Think things like test runners, documentation generators, or other bits of automation.
10 |
11 | Unlike the scripts in bin, these are not for external users of the package. If you have any of these, place them in a directory called tool.
12 |
--------------------------------------------------------------------------------
/tool/demo/run_example.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Runs, on device or in emulator, the single example chart in examples/main_run_doc_example.dart
4 |
5 | set -o errexit
6 |
7 | if [[ "$1" == "--help" ]]; then
8 | echo Usage: $0 [exampleEnum]
9 | exit 0
10 | fi
11 |
12 | # if [[ -z "$1" ]]; then
13 | # echo Usage:
14 | # echo $0 ex31_barChart_column_nonStacked_newAutoLayouter
15 | # echo NOT: $0 allSupported
16 | # echo NOT: $0 absoluteMinimumNew
17 | # echo
18 | # echo A single argument giving an example to run is missing, defaulting to ex31_barChart_column_nonStacked_newAutoLayouter.
19 | # exampleEnum="ex31_barChart_column_nonStacked_newAutoLayouter"
20 | # else
21 | # exampleEnum="$1"
22 | # fi
23 |
24 | # This script can only run from project top directory.
25 | if [ -z "$(find . -maxdepth 1 -type d -name integration_test)" ]; then
26 | echo Execution directory must be from project top directory. Failed the test for presence of directory integration_test, exiting.
27 | exit 1
28 | fi
29 |
30 | # To quit the running example, type 'q' on the command line.
31 |
32 | # flutter run \
33 | # --dart-define=EXAMPLES_DESCRIPTORS="$exampleEnum" \
34 | # example/main_run_doc_example.dart
35 |
36 | flutter run \
37 | example/main_run_doc_example.dart
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/tool/frequent_commands.org:
--------------------------------------------------------------------------------
1 | * A list of frequent commands in this project.
2 |
3 | ** Most commonly used
4 |
5 | # Run unit tests + all screen-comparing integration tests (allSupported = allSupportedNew + allSupportedOld)
6 | tool/test/run_all_tests.sh allSupported
7 | # Run unit tests + auto-layout screen-comparing integration tests
8 | tool/test/run_all_tests.sh allSupportedNew
9 | # Run unit tests + manual-layout screen-comparing integration tests
10 | tool/test/run_all_tests.sh allSupportedOld
11 | # Run unit tests + single screen-comparing integration test
12 | tool/test/run_all_tests.sh ex31_barChart_column_nonStacked_newAutoLayouter
13 |
14 |
15 | # Create screenshot - needs 'flutter drive' and --driver=integration_test.dart
16 | #+begin_src: sh
17 | # emulator required
18 | flutter emulator --launch "Nexus_6_API_35"
19 |
20 | # Run allSupported tests
21 | flutter drive \
22 | --dart-define=EXAMPLES_DESCRIPTORS="allSupported" \
23 | --driver=test_driver/integration_test.dart \
24 | --target=integration_test/screenshot_create_test.dart
25 | #+end_src
26 |
27 |
28 | ** Misc
29 |
30 | # Launch the emulator
31 | flutter emulator --launch "Nexus_6_API_35"
32 |
33 | # Create app template
34 | flutter create --template=app flutter_charts_app
35 |
36 | # pub related
37 | flutter pub get
38 | flutter pub upgrade
39 | flutter clean; flutter pub get;
40 |
--------------------------------------------------------------------------------
/tool/generate_chart_plantuml.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # dcdg is a package which generates uml
4 | # if installed 'globally', it will add executable to ~~/.pub-cache/bin~
5 | # this dir should be added to path
6 | # flutter pub global activate dcdg # Installs ~/.pub-cache/bin/dcdg executable
7 | # export PATH="$PATH":"$HOME/.pub-cache/bin"
8 | # cd my_package
9 | flutter pub global run dcdg -o flutter_charts.plantuml # creates a file with plantuml text
10 | java -jar ~/software/java-based/plantuml/plantuml.1.2017.12.jar flutter_charts.plantuml # Generates flutter_charts.png UML
11 |
--------------------------------------------------------------------------------
/tool/make_new_chart_type_structure.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Creates a set of directories and empty dart files for a new chart type.
4 | echo Usage: $0 newChartType
5 |
6 | chartType=${1:-UNSET}
7 |
8 | if [[ -z "$chartType" ]]; then
9 | echo Invalid chartType="$chartType", exiting
10 | exit 1
11 | fi
12 |
13 | echo chartType = $chartType
14 |
15 | mkdir {$chartType}
16 |
17 | for file in \
18 | $chartType/chart.dart \
19 | $chartType/container.dart \
20 | $chartType/options.dart \
21 | $chartType/painter.dart \
22 | $chartType/presenters.dart
23 | do
24 | echo "" >> $file
25 | done
--------------------------------------------------------------------------------
/tool/test/deprecated_v1/deprecated_frequent_commands.org:
--------------------------------------------------------------------------------
1 | * A list of DEPRECATED frequent commands in this project.
2 |
3 | flutter drive \
4 | --dart-define=EXAMPLE_TO_RUN=ex31SomeNegativeValues \
5 | --dart-define=CHART_TYPE=lineChart \
6 | --driver=test_driver/integration_test.dart \
7 | --target=integration_test/deprecated_v1/screenshot_create_deprecated_v1_test.dart
8 |
9 | # Test screenshot for equality - only needs unit test 'flutter test' (unit = unit OR integration non-drive test)
10 | flutter test \
11 | --dart-define=EXAMPLE_TO_RUN=ex31SomeNegativeValues \
12 | --dart-define=CHART_TYPE=barChart \
13 | test/deprecated_v1/screenshot_validate_deprecated_v1_test.dart
14 |
15 | # No clean: Run mini set of flutter integration tests in bash using:
16 | d1=$(date +%s); tool/test/deprecated_v1/run_representative_mini_tests.sh; echo TOOK $(($(date +%s) - $d1)) seconds
17 |
18 | # No clean: Run mini set of flutter integration tests in eshell using:
19 | setq d1 (string-to-number (format-time-string "%s")); tool/test/deprecated_v1/run_representative_mini_tests.sh ; setq d2 (string-to-number (format-time-string "%s")); echo "TOOK $(- d2 d1) seconds"
20 |
21 | # Bash with clean: Run all tests of all examples:
22 | d1=$(date +%s); flutter clean; flutter pub upgrade; flutter pub get; tool/test/deprecated_v1/run_deprecated_all_tests.sh; echo TOOK $(($(date +%s) - $d1)) seconds
23 |
24 | # Eshell with clean: Run all tests of all examples:
25 | setq d1 (string-to-number (format-time-string "%s")); flutter clean; flutter pub upgrade; flutter pub get; tool/test/deprecated_v1/run_deprecated_all_tests.sh; ; setq d2 (string-to-number (format-time-string "%s")); echo "TOOK $(- d2 d1) seconds"
26 |
27 | # No clean: Run one example test + it's screenshot sameness:
28 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh "firstRun" ex31SomeNegativeValues
29 | # No clean: Run one example test + it's screenshot sameness:
30 | tool/test/deprecated_v1/run_deprecated_all_tests.sh ex31SomeNegativeValues
31 |
32 | # Run all deprecated tests
33 | tool/test/deprecated_v1/run_deprecated_all_tests.sh
34 |
35 |
--------------------------------------------------------------------------------
/tool/test/deprecated_v1/deprecated_run_all_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Bash with clean: Run all tests of all examples:
4 | # d1=$(date +%s); flutter clean; flutter pub upgrade; flutter pub get; tool/test/deprecated_v1/deprecated_run_all_tests.sh; echo TOOK $(($(date +%s) - $d1)) seconds
5 |
6 | # Eshell with clean: Run all tests of all examples:
7 | # setq d1 (string-to-number (format-time-string "%s")); flutter clean; flutter pub upgrade; flutter pub get; tool/test/deprecated_v1/deprecated_run_all_tests.sh; ; setq d2 (string-to-number (format-time-string "%s")); echo "TOOK $(- d2 d1) seconds"
8 |
9 | # No clean: Run one example:
10 | # tool/test/deprecated_v1/deprecated_run_all_tests.sh ex31SomeNegativeValues
11 |
12 | set -o errexit
13 |
14 | # Run Dart tests (still as 'flutter test') and Flutter widget tests 'flutter test'
15 | tool/test/run_core_dart_and_flutter_widget_tests.sh
16 |
17 | # Run tests using old layouter
18 | echo
19 | echo -------------------------------------
20 | echo -------------------------------------
21 | echo Running screenshot differences tests screenshots validation
22 | echo This runs an integration [drive] screenshot create test first, followed by widget test that compares screenshots actual/expected
23 | echo First argument is $1
24 |
25 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh firstRun ex900ErrorFixUserDataAllZero
26 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun
27 |
28 | # Run tests using the new layouter
29 | tool/test/deprecated_v1/run_deprecated_core_integration_tests.sh
30 |
--------------------------------------------------------------------------------
/tool/test/deprecated_v1/deprecated_run_core_integration_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o errexit
4 |
5 | echo
6 | echo -------------------------------------
7 | echo -------------------------------------
8 | echo Running representative MINI screenshot validations
9 | echo Runs an integration [drive] screenshot create test first, followed by widget test that compares screenshots actual/expected
10 | echo firstRun does --pub, nextRun ignores it.
11 |
12 |
13 | echo
14 | echo -------------------------------------
15 | echo -------------------------------------
16 | echo Running screenshot actual/expected test for NEW LAYOUT
17 |
18 | # ------------------------------------------
19 | # ex75 - only positives : barChart
20 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=column CHART_STACKING=stacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh firstRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded barChart
21 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=column CHART_STACKING=nonStacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded barChart
22 |
23 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=row CHART_STACKING=stacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded barChart
24 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=row CHART_STACKING=nonStacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded barChart
25 |
26 | # ex75 - only positives : lineChart, only nonStacked
27 | # CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=column CHART_STACKING=stacked tool/test/deprecated_v1/deprecated_integration_test_create_then_validate_screenshots.sh nextRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded lineChart
28 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=column CHART_STACKING=nonStacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded lineChart
29 |
30 | # CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=row CHART_STACKING=stacked tool/test/deprecated_v1/deprecated_integration_test_create_then_validate_screenshots.sh nextRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded lineChart
31 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=row CHART_STACKING=nonStacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded lineChart
32 |
33 | # ------------------------------------------
34 | # ex31 - positives and negatives - barChart
35 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=column CHART_STACKING=stacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex31SomeNegativeValues barChart
36 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=column CHART_STACKING=nonStacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex31SomeNegativeValues barChart
37 |
38 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=row CHART_STACKING=stacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex31SomeNegativeValues barChart
39 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=row CHART_STACKING=nonStacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex31SomeNegativeValues barChart
40 |
41 | # ex31 - positives and negatives - lineChart, only nonStacked
42 | # CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=column CHART_STACKING=stacked tool/test/deprecated_v1/deprecated_integration_test_create_then_validate_screenshots.sh nextRun ex31SomeNegativeValues lineChart
43 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=column CHART_STACKING=nonStacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex31SomeNegativeValues lineChart
44 |
45 | # CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=row CHART_STACKING=stacked tool/test/deprecated_v1/deprecated_integration_test_create_then_validate_screenshots.sh nextRun ex31SomeNegativeValues lineChart
46 | CHART_LAYOUTER=newAutoLayouter CHART_ORIENTATION=row CHART_STACKING=nonStacked tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex31SomeNegativeValues lineChart
47 |
48 |
--------------------------------------------------------------------------------
/tool/test/deprecated_v1/deprecated_run_representative_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o errexit
4 |
5 | # Run Dart tests (still as 'flutter test') and Flutter widget tests 'flutter test'
6 | tool/test/run_core_dart_and_flutter_widget_tests.sh
7 |
8 | # Run mini set of flutter integration tests in bash using:
9 | # d1=$(date +%s); tool/test/deprecated_v1/deprecated_run_representative_tests.sh; echo TOOK $(($(date +%s) - $d1)) seconds
10 | # Run mini set of flutter integration tests in eshell using:
11 | # setq d1 (string-to-number (format-time-string "%s")); tool/test/deprecated_v1/deprecated_run_representative_tests.sh ; setq d2 (string-to-number (format-time-string "%s")); echo "TOOK $(- d2 d1) seconds"
12 | # with clean, add before tool/test/deprecated_v1/run: ; flutter clean; flutter pub upgrade; flutter pub get;
13 | # To run one example:
14 | # tool/test/deprecated_v1/deprecated_run_all_tests.sh ex31SomeNegativeValues
15 |
16 | echo
17 | echo -------------------------------------
18 | echo -------------------------------------
19 | echo Running representative screenshot validations
20 | echo Runs an integration [drive] screenshot create test first, followed by widget test that compares screenshots actual/expected
21 | echo firstRun does --pub, nextRun ignores it.
22 |
23 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh firstRun ex900ErrorFixUserDataAllZero
24 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex30AnimalsBySeasonWithLabelLayoutStrategy
25 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex35AnimalsBySeasonNoLabelsShown
26 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex40LanguagesWithYOrdinalUserLabelsAndUserColors
27 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex52AnimalsBySeasonLogarithmicScale
28 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex60LabelsIteration2 #
29 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex60LabelsIteration3
30 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex60LabelsIteration4
31 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex70AnimalsBySeasonLegendIsColumnStartLooseItemIsRowStartLoose
32 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex71AnimalsBySeasonLegendIsColumnStartTightItemIsRowStartTight #
33 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex72AnimalsBySeasonLegendIsRowCenterLooseItemIsRowEndLoose
34 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex73AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTight #
35 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex74AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightSecondGreedy #
36 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex75AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenPadded #
37 | tool/test/deprecated_v1/integration_test_create_then_validate_screenshots.sh nextRun ex76AnimalsBySeasonLegendIsRowStartTightItemIsRowStartTightItemChildrenAligned
38 |
39 | # Run tests using the new layouter
40 | tool/test/deprecated_v1/run_deprecated_core_integration_tests.sh
41 |
--------------------------------------------------------------------------------
/tool/test/deprecated_v1/deprecated_start_emulator_and_generate_example_descriptor.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Generates a program that can be used to run or test all examples
4 | # defined in enum 'ExampleEnum'.
5 | #
6 | # Should be 'sourced', as it results in setting an environment variable which contains a program name,
7 | # which the calling script can run.
8 | #
9 | # In more detail, this script does the following:
10 | # - If Android AVD emulator is not running, starts one.
11 | # - Next, uses the program
12 | # 'dart run lib/src/chart/util/example_descriptor.dart'
13 | # to generate a temp script, which name is placed in the variable named
14 | # 'example_descriptor_generated_program'
15 | # The program $example_descriptor_generated_program
16 | # can be executed from the script sourcing this script,
17 | # to run the or tests all examples declared in ExampleEnum.
18 |
19 | # Input $1: ExampleEnum value, for example ex10RandomData.
20 | # If empty or not set, all examples are included in the generated run.
21 | # Output: variable name 'example_descriptor_generated_program', which contains the name of the
22 | # generated program
23 |
24 | isFirstRun=$1
25 | exampleEnum=$2
26 | chartTypeEnum=$3
27 | chartOrientation=$4
28 | chartStacking=$5
29 | isUseOldLayouter=$6
30 |
31 | # if [[ $isFirstRun == true ]]; then
32 | tool/test/start_emulator.sh
33 | # fi
34 |
35 | # Define the name of the program which the scripts sourcing this file can execute.
36 | example_descriptor_generated_program=test/tmp/example_descriptor_generated_program_$RANDOM.sh
37 |
38 | # Dart run example_descriptor.dart which generates a script with dart_defines.
39 | echo Running \"dart run lib/src/chart/util/example_descriptor.dart \'"$exampleEnum"\' \'"$chartTypeEnum"\' \'"$chartOrientation"\' \'"$chartStacking"\' \'"$isUseOldLayouter"\'\"
40 | echo which creates $example_descriptor_generated_program
41 |
42 | echo "# Sample of how this runs:" > $example_descriptor_generated_program
43 | echo "# flutter drive \
44 | --dart-define=EXAMPLE_TO_RUN=ex75 \
45 | --dart-define=CHART_TYPE=barChart \
46 | --dart-define=CHART_ORIENTATION=row \
47 | --dart-define=CHART_STACKING=stacked \
48 | --dart-define=CHART_LAYOUTER=newAutoLayouter \
49 | --driver=test_driver/integration_test.dart --target=integration_test/deprecated_v1/screenshot_create_deprecated_v1_test.dart" >> $example_descriptor_generated_program
50 |
51 | dart run lib/src/chart/util/example_descriptor.dart \
52 | "$exampleEnum" \
53 | "$chartTypeEnum" \
54 | "$chartOrientation" \
55 | "$chartStacking" \
56 | "$isUseOldLayouter" >> $example_descriptor_generated_program
57 |
58 | chmod u+x $example_descriptor_generated_program
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/tool/test/run_all_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Bash with clean: Run all tests of all examples:
4 | # d1=$(date +%s); flutter clean; flutter pub upgrade; flutter pub get; tool/test/run_all_tests.sh absoluteMinimumNew; echo TOOK $(($(date +%s) - $d1)) seconds
5 |
6 | # Eshell with clean: Run all tests of all examples:
7 | # setq d1 (string-to-number (format-time-string "%s")); flutter clean; flutter pub upgrade; flutter pub get; tool/test/run_all_tests.sh absoluteMinimumNew; ; setq d2 (string-to-number (format-time-string "%s")); echo "TOOK $(- d2 d1) seconds"
8 |
9 | # No clean: Run one example:
10 | # tool/test/run_all_tests.sh ex31_barChart_column_stacked_newAutoLayouter ex75_lineChart_row_nonStacked_newAutoLayouter
11 |
12 | # Possible groups:
13 | # minimumNew
14 | # allSupportedNew
15 | # minimumOld
16 | # allSupportedOld
17 | # minimum
18 | # allSupported
19 |
20 |
21 | set -o errexit
22 |
23 | # Run Dart tests (still as 'flutter test') and Flutter widget tests 'flutter test'
24 | tool/test/run_core_dart_and_flutter_widget_tests.sh
25 |
26 | # Run on-device-driven 'flutter drive' integration test 'screenshot_create_test.dart',
27 | # followed by on-computer 'flutter test' unit test 'screenshot_validate_test.dart'.
28 | tool/test/run_screenshots_compare_integration_test.sh "$@"
29 |
30 |
31 |
--------------------------------------------------------------------------------
/tool/test/run_core_dart_and_flutter_widget_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Runs all tests except screenshot tests
4 |
5 | set -o errexit
6 |
7 | echo
8 | echo -------------------------------------
9 | echo -------------------------------------
10 | echo Running Dart files testing, which is still run with Flutter: flutter test test/util/util_labels_test.dart - etc..
11 | flutter test test/chart/util/example_descriptor_test.dart
12 |
13 | flutter test test/chart/layouter_one_dimensional_test.dart
14 |
15 | flutter test test/util/vector/vector_test.dart
16 |
17 | flutter test test/util/extensions_dart_test.dart
18 | flutter test test/util/util_dart_test.dart
19 | flutter test test/util/util_flutter_test.dart
20 | flutter test test/util/util_labels_test.dart
21 | flutter test test/util/function_test.dart
22 |
23 | echo
24 | echo -------------------------------------
25 | echo -------------------------------------
26 | echo Running Flutter widget tests: flutter test test/widget_test.dart
27 | flutter test test/widget_test.dart
28 |
29 | echo
30 | echo -------------------------------------
31 | echo -------------------------------------
32 | echo RERUNNING All Flutter widget tests, showing all names: flutter test --reporter expanded
33 | flutter test --reporter expanded
34 |
--------------------------------------------------------------------------------
/tool/test/run_screenshots_compare_integration_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Run test which generates screenshots of all examples named in the passed arguments
4 | # followed by screenshot expected/actual comparison for the same set of examples.
5 |
6 | set -o errexit
7 |
8 | if [[ $# -eq 0 ]]; then
9 | echo 'Specify at least one example or group from the command line, exiting'
10 | exit 1
11 | fi
12 |
13 | examplesDescriptors="$@"
14 |
15 | # Start emulator
16 | tool/test/start_emulator.sh
17 |
18 | flutter drive \
19 | --dart-define=EXAMPLES_DESCRIPTORS="$examplesDescriptors" \
20 | --driver=test_driver/integration_test.dart \
21 | --target=integration_test/screenshot_create_test.dart
22 |
23 | flutter test \
24 | --dart-define=EXAMPLES_DESCRIPTORS="$examplesDescriptors" \
25 | test/screenshot_validate_test.dart
26 |
--------------------------------------------------------------------------------
/tool/test/start_emulator.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # - If Android AVD emulator is not running, starts one.
4 |
5 | # This is the AVD emulator we request to exist
6 | emulator_used="Nexus_6_API_35"
7 |
8 | echo Check if emulator exists
9 | if ! flutter emulators 2>/dev/null | grep --quiet "$emulator_used "; then
10 | echo "Emulator $emulator_used does not exist. Please create it, our integration tests depend on it. Exiting"
11 | exit 1
12 | fi
13 |
14 | echo Check if the emulator named $emulator_used is connected to a running device.
15 | # The only way to find out if the emulator is connected is to run ps, searching for the device name.
16 | # The potential alternative "flutter devices" lists only the short device name such as e3565.
17 | if ! ps -alef | grep "$emulator_used" | grep -v grep ; then
18 | echo No AVD devices running using the emulator $emulator_used. Launching the emulator.
19 | flutter emulators --launch "$emulator_used"
20 | echo Sleep 22 on server to give the emulator time to start fully. Sleep 40 on laptop.
21 | sleep 22
22 | echo The AVD emulator $emulator_used succesfully launched.
23 | else
24 | echo The emulator $emulator_used appears running and connected.
25 | fi
26 |
27 | # Sleep for a bit and check that SOME device is running
28 | sleep 1
29 | if ! flutter devices 2>/dev/null | grep --quiet "emulator-"; then
30 | echo "Unexpected error: flutter devices is telling us that no emulators are connected to a device. Exiting"
31 | exit 1
32 | fi
33 |
34 | echo Checking processes for running emulator name.
35 | device_id=$(flutter devices 2>/dev/null | grep "emulator-" | sed 's/.*\(emulator\-[0-9]\+\).*/\1/')
36 | echo Emulator $emulator_used is running as device_id="$device_id".
37 |
--------------------------------------------------------------------------------