1
0
mirror of https://github.com/flutter/samples.git synced 2026-03-26 14:22:03 +00:00

Add flutter_web samples (#75)

This commit is contained in:
Kevin Moore
2019-05-07 13:32:08 -07:00
committed by Andrew Brogdon
parent 42f2dce01b
commit 3fe927cb29
697 changed files with 241026 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
Examples of the [charts_flutter](https://pub.dev/packages/charts_flutter) package running on the web.
Original source at [github.com/google/charts](https://github.com/google/charts).
Copied from [github.com/google/charts](https://github.com/google/charts) at
[35aeffe7c9](https://github.com/google/charts/commit/35aeffe7c96aa7d231c90fddd9766998545f1080).
With changes to run on the web.

View File

@@ -0,0 +1,29 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'domain_a11y_explore_bar_chart.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.accessibility),
title: 'Screen reader enabled bar chart',
subtitle: 'Requires TalkBack or Voiceover turned on to work. '
'Bar chart with domain selection explore mode behavior.',
childBuilder: () => new DomainA11yExploreBarChart.withRandomData(),
),
];
}

View File

@@ -0,0 +1,215 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a bar chart with domain selection A11y behavior.
///
/// The OS screen reader (TalkBack / VoiceOver) setting must be turned on, or
/// the behavior does not do anything.
///
/// Note that the screenshot does not show any visual differences but when the
/// OS screen reader is enabled, the node that is being read out loud will be
/// surrounded by a rectangle.
///
/// When [DomainA11yExploreBehavior] is added to the chart, the chart will
/// listen for the gesture that triggers "explore mode".
/// "Explore mode" creates semantic nodes for each domain value in the chart
/// with a description (customizable, defaults to domain value) and a bounding
/// box that surrounds the domain.
///
/// These semantic node descriptions are read out loud by the OS screen reader
/// when the user taps within the bounding box, or when the user cycles through
/// the screen's elements (such as swiping left and right).
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class DomainA11yExploreBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DomainA11yExploreBarChart(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory DomainA11yExploreBarChart.withSampleData() {
return new DomainA11yExploreBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DomainA11yExploreBarChart.withRandomData() {
return new DomainA11yExploreBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final mobileData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tabletData = [
// Purposely missing data to show that only measures that are available
// are vocalized.
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Mobile Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet Sales',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletData,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
/// An example of how to generate a customized vocalization for
/// [DomainA11yExploreBehavior] from a list of [SeriesDatum]s.
///
/// The list of series datums is for one domain.
///
/// This example vocalizes the domain, then for each series that has that
/// domain, it vocalizes the series display name and the measure and a
/// description of that measure.
String vocalizeDomainAndMeasures(List<charts.SeriesDatum> seriesDatums) {
final buffer = new StringBuffer();
// The datum's type in this case is [OrdinalSales].
// So we can access year and sales information here.
buffer.write(seriesDatums.first.datum.year);
for (charts.SeriesDatum seriesDatum in seriesDatums) {
final series = seriesDatum.series;
final datum = seriesDatum.datum;
buffer.write(' ${series.displayName} '
'${datum.sales / 1000} thousand dollars');
}
return buffer.toString();
}
@override
Widget build(BuildContext context) {
return new Semantics(
// Describe your chart
label: 'Yearly sales bar chart',
// Optionally provide a hint for the user to know how to trigger
// explore mode.
hint: 'Press and hold to enable explore',
child: new charts.BarChart(
seriesList,
animate: animate,
// To prevent conflict with the select nearest behavior that uses the
// tap gesture, turn off default interactions when the user is using
// an accessibility service like TalkBack or VoiceOver to interact
// with the application.
defaultInteractions: !MediaQuery.of(context).accessibleNavigation,
behaviors: [
new charts.DomainA11yExploreBehavior(
// Callback for generating the message that is vocalized.
// An example of how to use is in [vocalizeDomainAndMeasures].
// If none is set, the default only vocalizes the domain value.
vocalizationCallback: vocalizeDomainAndMeasures,
// The following settings are optional, but shown here for
// demonstration purchases.
// [exploreModeTrigger] Default is press and hold, can be
// changed to tap.
exploreModeTrigger: charts.ExploreModeTrigger.pressHold,
// [exploreModeEnabledAnnouncement] Optionally notify the OS
// when explore mode is enabled.
exploreModeEnabledAnnouncement: 'Explore mode enabled',
// [exploreModeDisabledAnnouncement] Optionally notify the OS
// when explore mode is disabled.
exploreModeDisabledAnnouncement: 'Explore mode disabled',
// [minimumWidth] Default and minimum is 1.0. This is the
// minimum width of the screen reader bounding box. The bounding
// box width is calculated based on the domain axis step size.
// Minimum width will be used if the step size is smaller.
minimumWidth: 1.0,
),
// Optionally include domain highlighter as a behavior.
// This behavior is included in this example to show that when an
// a11y node has focus, the chart's internal selection model is
// also updated.
new charts.DomainHighlighter(charts.SelectionModelType.info),
],
));
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final mobileData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletData = [
// Purposely missing data to show that only measures that are available
// are vocalized.
new OrdinalSales('2016', 25),
new OrdinalSales('2017', 50),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Mobile Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet Sales',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletData,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,40 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
/// A particular configuration of the app.
class AppConfig {
final String appName;
final String appLink;
final ThemeData theme;
final bool showPerformanceOverlay;
AppConfig(
{this.appName, this.appLink, this.theme, this.showPerformanceOverlay});
}
/// The default configuration of the app.
AppConfig get defaultConfig {
return new AppConfig(
appName: 'Charts Gallery',
appLink: '',
theme: new ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.lightBlue,
),
showPerformanceOverlay: false,
);
}

View File

@@ -0,0 +1,137 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'bar_secondary_axis.dart';
import 'bar_secondary_axis_only.dart';
import 'custom_axis_tick_formatters.dart';
import 'custom_font_size_and_color.dart';
import 'custom_measure_tick_count.dart';
import 'gridline_dash_pattern.dart';
import 'hidden_ticks_and_labels_axis.dart';
import 'horizontal_bar_secondary_axis.dart';
import 'integer_only_measure_axis.dart';
import 'line_disjoint_axis.dart';
import 'measure_axis_label_alignment.dart';
import 'numeric_initial_viewport.dart';
import 'nonzero_bound_measure_axis.dart';
import 'ordinal_initial_viewport.dart';
import 'short_tick_length_axis.dart';
import 'statically_provided_ticks.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Bar chart with Secondary Measure Axis',
subtitle: 'Bar chart with a series using a secondary measure axis',
childBuilder: () => new BarChartWithSecondaryAxis.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Bar chart with Secondary Measure Axis only',
subtitle: 'Bar chart with both series using secondary measure axis',
childBuilder: () => new BarChartWithSecondaryAxisOnly.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Transform.rotate(
angle: 1.5708, child: new Icon(Icons.insert_chart)),
title: 'Horizontal bar chart with Secondary Measure Axis',
subtitle:
'Horizontal Bar chart with a series using secondary measure axis',
childBuilder: () =>
new HorizontalBarChartWithSecondaryAxis.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Short Ticks Axis',
subtitle: 'Bar chart with the primary measure axis having short ticks',
childBuilder: () => new ShortTickLengthAxis.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Custom Axis Fonts',
subtitle: 'Bar chart with custom axis font size and color',
childBuilder: () => new CustomFontSizeAndColor.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Label Alignment Axis',
subtitle: 'Bar chart with custom measure axis label alignments',
childBuilder: () => new MeasureAxisLabelAlignment.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'No Axis',
subtitle: 'Bar chart with only the axis line drawn',
childBuilder: () => new HiddenTicksAndLabelsAxis.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Statically Provided Ticks',
subtitle: 'Bar chart with statically provided ticks',
childBuilder: () => new StaticallyProvidedTicks.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Custom Formatter',
subtitle: 'Timeseries with custom domain and measure tick formatters',
childBuilder: () => new CustomAxisTickFormatters.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Custom Tick Count',
subtitle: 'Timeseries with custom measure axis tick count',
childBuilder: () => new CustomMeasureTickCount.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Integer Measure Ticks',
subtitle: 'Timeseries with only whole number measure axis ticks',
childBuilder: () => new IntegerOnlyMeasureAxis.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Non-zero bound Axis',
subtitle: 'Timeseries with measure axis that does not include zero',
childBuilder: () => new NonzeroBoundMeasureAxis.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Ordinal axis with initial viewport',
subtitle: 'Single series with initial viewport',
childBuilder: () => new OrdinalInitialViewport.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Numeric axis with initial viewport',
subtitle: 'Initial viewport is set to a subset of the data',
childBuilder: () => new NumericInitialViewport.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Gridline dash pattern',
subtitle: 'Timeseries with measure gridlines that have a dash pattern',
childBuilder: () => new GridlineDashPattern.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Disjoint Measure Axes',
subtitle: 'Line chart with disjoint measure axes',
childBuilder: () => new DisjointMeasureAxisLineChart.withRandomData(),
),
];
}

View File

@@ -0,0 +1,158 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of using a primary and secondary axis (left & right respectively)
/// for a set of grouped bars. This is useful for comparing Series that have
/// different units (revenue vs clicks by region), or different magnitudes (2017
/// revenue vs 1/1/2017 revenue by region).
///
/// The first series plots using the primary axis to position its measure
/// values (bar height). This is the default axis used if the measureAxisId is
/// not set.
///
/// The second series plots using the secondary axis due to the measureAxisId of
/// secondaryMeasureAxisId.
///
/// Note: primary and secondary may flip left and right positioning when
/// RTL.flipAxisLocations is set.
class BarChartWithSecondaryAxis extends StatelessWidget {
static const secondaryMeasureAxisId = 'secondaryMeasureAxisId';
final List<charts.Series> seriesList;
final bool animate;
BarChartWithSecondaryAxis(this.seriesList, {this.animate});
factory BarChartWithSecondaryAxis.withSampleData() {
return new BarChartWithSecondaryAxis(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory BarChartWithSecondaryAxis.withRandomData() {
return new BarChartWithSecondaryAxis(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2014', random.nextInt(100) * 100),
new OrdinalSales('2015', random.nextInt(100) * 100),
new OrdinalSales('2016', random.nextInt(100) * 100),
new OrdinalSales('2017', random.nextInt(100) * 100),
];
final losAngelesSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Los Angeles Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: losAngelesSalesData,
)..setAttribute(charts.measureAxisIdKey, secondaryMeasureAxisId)
// Set the 'Los Angeles Revenue' series to use the secondary measure axis.
// All series that have this set will use the secondary measure axis.
// All other series will use the primary measure axis.
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
// It is important when using both primary and secondary axes to choose
// the same number of ticks for both sides to get the gridlines to line
// up.
primaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec:
new charts.BasicNumericTickProviderSpec(desiredTickCount: 3)),
secondaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec:
new charts.BasicNumericTickProviderSpec(desiredTickCount: 3)),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2014', 5000),
new OrdinalSales('2015', 25000),
new OrdinalSales('2016', 100000),
new OrdinalSales('2017', 750000),
];
final losAngelesSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Los Angeles Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: losAngelesSalesData,
)..setAttribute(charts.measureAxisIdKey, secondaryMeasureAxisId)
// Set the 'Los Angeles Revenue' series to use the secondary measure axis.
// All series that have this set will use the secondary measure axis.
// All other series will use the primary measure axis.
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,114 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of using only a secondary axis (on the right) for a set of grouped
/// bars.
///
/// Both series plots using the secondary axis due to the measureAxisId of
/// secondaryMeasureAxisId.
///
/// Note: secondary may flip left and right positioning when
/// RTL.flipAxisLocations is set.
class BarChartWithSecondaryAxisOnly extends StatelessWidget {
static const secondaryMeasureAxisId = 'secondaryMeasureAxisId';
final List<charts.Series> seriesList;
final bool animate;
BarChartWithSecondaryAxisOnly(this.seriesList, {this.animate});
factory BarChartWithSecondaryAxisOnly.withSampleData() {
return new BarChartWithSecondaryAxisOnly(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory BarChartWithSecondaryAxisOnly.withRandomData() {
return new BarChartWithSecondaryAxisOnly(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2014', random.nextInt(100) * 100),
new OrdinalSales('2015', random.nextInt(100) * 100),
new OrdinalSales('2016', random.nextInt(100) * 100),
new OrdinalSales('2017', random.nextInt(100) * 100),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
)
// Set series to use the secondary measure axis.
..setAttribute(charts.measureAxisIdKey, secondaryMeasureAxisId),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2014', 500),
new OrdinalSales('2015', 2500),
new OrdinalSales('2016', 1000),
new OrdinalSales('2017', 7500),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
)
// Set series to use the secondary measure axis.
..setAttribute(charts.measureAxisIdKey, secondaryMeasureAxisId),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,144 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of timeseries chart with custom measure and domain formatters.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
import 'package:intl/intl.dart';
class CustomAxisTickFormatters extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
CustomAxisTickFormatters(this.seriesList, {this.animate});
/// Creates a [TimeSeriesChart] with sample data and no transition.
factory CustomAxisTickFormatters.withSampleData() {
return new CustomAxisTickFormatters(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory CustomAxisTickFormatters.withRandomData() {
return new CustomAxisTickFormatters(_createRandomData());
}
/// Create random data.
static List<charts.Series<MyRow, DateTime>> _createRandomData() {
final random = new Random();
final data = [
new MyRow(new DateTime(2017, 9, 25), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 26), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 27), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 28), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 29), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 30), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 01), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 02), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 03), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 04), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 05), random.nextInt(100)),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Cost',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.cost,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
/// Formatter for numeric ticks using [NumberFormat] to format into currency
///
/// This is what is used in the [NumericAxisSpec] below.
final simpleCurrencyFormatter =
new charts.BasicNumericTickFormatterSpec.fromNumberFormat(
new NumberFormat.compactSimpleCurrency());
/// Formatter for numeric ticks that uses the callback provided.
///
/// Use this formatter if you need to format values that [NumberFormat]
/// cannot provide.
///
/// To see this formatter, change [NumericAxisSpec] to use this formatter.
// final customTickFormatter =
// charts.BasicNumericTickFormatterSpec((num value) => 'MyValue: $value');
return new charts.TimeSeriesChart(seriesList,
animate: animate,
// Sets up a currency formatter for the measure axis.
primaryMeasureAxis: new charts.NumericAxisSpec(
tickFormatterSpec: simpleCurrencyFormatter),
/// Customizes the date tick formatter. It will print the day of month
/// as the default format, but include the month and year if it
/// transitions to a new month.
///
/// minute, hour, day, month, and year are all provided by default and
/// you can override them following this pattern.
domainAxis: new charts.DateTimeAxisSpec(
tickFormatterSpec: new charts.AutoDateTimeTickFormatterSpec(
day: new charts.TimeFormatterSpec(
format: 'd', transitionFormat: 'MM/dd/yyyy'))));
}
/// Create one series with sample hard coded data.
static List<charts.Series<MyRow, DateTime>> _createSampleData() {
final data = [
new MyRow(new DateTime(2017, 9, 25), 6),
new MyRow(new DateTime(2017, 9, 26), 8),
new MyRow(new DateTime(2017, 9, 27), 6),
new MyRow(new DateTime(2017, 9, 28), 9),
new MyRow(new DateTime(2017, 9, 29), 11),
new MyRow(new DateTime(2017, 9, 30), 15),
new MyRow(new DateTime(2017, 10, 01), 25),
new MyRow(new DateTime(2017, 10, 02), 33),
new MyRow(new DateTime(2017, 10, 03), 27),
new MyRow(new DateTime(2017, 10, 04), 31),
new MyRow(new DateTime(2017, 10, 05), 23),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Cost',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.cost,
data: data,
)
];
}
}
/// Sample time series data type.
class MyRow {
final DateTime timeStamp;
final int cost;
MyRow(this.timeStamp, this.cost);
}

View File

@@ -0,0 +1,136 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Custom Font Style Example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of using a custom primary measure and domain axis replacing the
/// renderSpec with one with a custom font size and a custom color.
///
/// There are many axis styling options in the SmallTickRenderer allowing you
/// to customize the font, tick lengths, and offsets.
class CustomFontSizeAndColor extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
CustomFontSizeAndColor(this.seriesList, {this.animate});
factory CustomFontSizeAndColor.withSampleData() {
return new CustomFontSizeAndColor(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory CustomFontSizeAndColor.withRandomData() {
return new CustomFontSizeAndColor(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2014', random.nextInt(100) * 100),
new OrdinalSales('2015', random.nextInt(100) * 100),
new OrdinalSales('2016', random.nextInt(100) * 100),
new OrdinalSales('2017', random.nextInt(100) * 100),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
/// Assign a custom style for the domain axis.
///
/// This is an OrdinalAxisSpec to match up with BarChart's default
/// ordinal domain axis (use NumericAxisSpec or DateTimeAxisSpec for
/// other charts).
domainAxis: new charts.OrdinalAxisSpec(
renderSpec: new charts.SmallTickRendererSpec(
// Tick and Label styling here.
labelStyle: new charts.TextStyleSpec(
fontSize: 18, // size in Pts.
color: charts.MaterialPalette.black),
// Change the line colors to match text color.
lineStyle: new charts.LineStyleSpec(
color: charts.MaterialPalette.black))),
/// Assign a custom style for the measure axis.
primaryMeasureAxis: new charts.NumericAxisSpec(
renderSpec: new charts.GridlineRendererSpec(
// Tick and Label styling here.
labelStyle: new charts.TextStyleSpec(
fontSize: 18, // size in Pts.
color: charts.MaterialPalette.black),
// Change the line colors to match text color.
lineStyle: new charts.LineStyleSpec(
color: charts.MaterialPalette.black))),
);
}
/// Create series list with single series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2014', 5000),
new OrdinalSales('2015', 25000),
new OrdinalSales('2016', 100000),
new OrdinalSales('2017', 750000),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,122 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of timeseries chart with a custom number of ticks
///
/// The tick count can be set by setting the [desiredMinTickCount] and
/// [desiredMaxTickCount] for automatically adjusted tick counts (based on
/// how 'nice' the ticks are) or [desiredTickCount] for a fixed tick count.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class CustomMeasureTickCount extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
CustomMeasureTickCount(this.seriesList, {this.animate});
/// Creates a [TimeSeriesChart] with sample data and no transition.
factory CustomMeasureTickCount.withSampleData() {
return new CustomMeasureTickCount(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory CustomMeasureTickCount.withRandomData() {
return new CustomMeasureTickCount(_createRandomData());
}
/// Create random data.
static List<charts.Series<MyRow, DateTime>> _createRandomData() {
final random = new Random();
final data = [
new MyRow(new DateTime(2017, 9, 25), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 26), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 27), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 28), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 29), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 30), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 01), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 02), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 03), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 04), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 05), random.nextInt(100)),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Cost',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.cost,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.TimeSeriesChart(seriesList,
animate: animate,
/// Customize the measure axis to have 2 ticks,
primaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec:
new charts.BasicNumericTickProviderSpec(desiredTickCount: 2)));
}
/// Create one series with sample hard coded data.
static List<charts.Series<MyRow, DateTime>> _createSampleData() {
final data = [
new MyRow(new DateTime(2017, 9, 25), 6),
new MyRow(new DateTime(2017, 9, 26), 8),
new MyRow(new DateTime(2017, 9, 27), 6),
new MyRow(new DateTime(2017, 9, 28), 9),
new MyRow(new DateTime(2017, 9, 29), 11),
new MyRow(new DateTime(2017, 9, 30), 15),
new MyRow(new DateTime(2017, 10, 01), 25),
new MyRow(new DateTime(2017, 10, 02), 33),
new MyRow(new DateTime(2017, 10, 03), 27),
new MyRow(new DateTime(2017, 10, 04), 31),
new MyRow(new DateTime(2017, 10, 05), 23),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Cost',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.cost,
data: data,
)
];
}
}
/// Sample time series data type.
class MyRow {
final DateTime timeStamp;
final int cost;
MyRow(this.timeStamp, this.cost);
}

View File

@@ -0,0 +1,114 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of flipping the vertical measure axis direction so that larger
/// values render downward instead of the usual rendering up.
///
/// flipVerticalAxis, when set, flips the vertical axis from its default
/// direction.
///
/// Note: primary and secondary may flip left and right positioning when
/// RTL.flipAxisLocations is set.
class FlippedVerticalAxis extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
FlippedVerticalAxis(this.seriesList, {this.animate});
factory FlippedVerticalAxis.withSampleData() {
return new FlippedVerticalAxis(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory FlippedVerticalAxis.withRandomData() {
return new FlippedVerticalAxis(_createRandomData());
}
/// Create random data.
static List<charts.Series<RunnerRank, String>> _createRandomData() {
final random = new Random();
const runners = ['Smith', 'Jones', 'Brown', 'Doe'];
// Randomly assign runners, but leave the order of the places.
final raceData = [
new RunnerRank(runners.removeAt(random.nextInt(runners.length)), 1),
new RunnerRank(runners.removeAt(random.nextInt(runners.length)), 2),
new RunnerRank(runners.removeAt(random.nextInt(runners.length)), 3),
new RunnerRank(runners.removeAt(random.nextInt(runners.length)), 4),
];
return [
new charts.Series<RunnerRank, String>(
id: 'Race Results',
domainFn: (RunnerRank row, _) => row.name,
measureFn: (RunnerRank row, _) => row.place,
data: raceData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
// Known Issue, the bar chart cannot render negative direction bars at this
// time so the result is an empty chart.
// TODO: Remove this comment
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
flipVerticalAxis: true,
);
}
/// Create series list with multiple series
static List<charts.Series<RunnerRank, String>> _createSampleData() {
final raceData = [
new RunnerRank('Smith', 1),
new RunnerRank('Jones', 2),
new RunnerRank('Brown', 3),
new RunnerRank('Doe', 4),
];
return [
new charts.Series<RunnerRank, String>(
id: 'Race Results',
domainFn: (RunnerRank row, _) => row.name,
measureFn: (RunnerRank row, _) => row.place,
data: raceData),
];
}
}
/// Datum/Row for the chart.
class RunnerRank {
final String name;
final int place;
RunnerRank(this.name, this.place);
}

View File

@@ -0,0 +1,120 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of timeseries chart with gridlines that have a dash pattern.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class GridlineDashPattern extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
GridlineDashPattern(this.seriesList, {this.animate});
/// Creates a [TimeSeriesChart] with sample data and no transition.
factory GridlineDashPattern.withSampleData() {
return new GridlineDashPattern(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory GridlineDashPattern.withRandomData() {
return new GridlineDashPattern(_createRandomData());
}
/// Create random data.
static List<charts.Series<MyRow, DateTime>> _createRandomData() {
final random = new Random();
final data = [
new MyRow(new DateTime(2017, 9, 25), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 26), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 27), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 28), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 29), random.nextInt(100)),
new MyRow(new DateTime(2017, 9, 30), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 01), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 02), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 03), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 04), random.nextInt(100)),
new MyRow(new DateTime(2017, 10, 05), random.nextInt(100)),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Cost',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.cost,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.TimeSeriesChart(seriesList,
animate: animate,
/// Customize the gridlines to use a dash pattern.
primaryMeasureAxis: new charts.NumericAxisSpec(
renderSpec: charts.GridlineRendererSpec(
lineStyle: charts.LineStyleSpec(
dashPattern: [4, 4],
))));
}
/// Create one series with sample hard coded data.
static List<charts.Series<MyRow, DateTime>> _createSampleData() {
final data = [
new MyRow(new DateTime(2017, 9, 25), 6),
new MyRow(new DateTime(2017, 9, 26), 8),
new MyRow(new DateTime(2017, 9, 27), 6),
new MyRow(new DateTime(2017, 9, 28), 9),
new MyRow(new DateTime(2017, 9, 29), 11),
new MyRow(new DateTime(2017, 9, 30), 15),
new MyRow(new DateTime(2017, 10, 01), 25),
new MyRow(new DateTime(2017, 10, 02), 33),
new MyRow(new DateTime(2017, 10, 03), 27),
new MyRow(new DateTime(2017, 10, 04), 31),
new MyRow(new DateTime(2017, 10, 05), 23),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Cost',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.cost,
data: data,
)
];
}
}
/// Sample time series data type.
class MyRow {
final DateTime timeStamp;
final int cost;
MyRow(this.timeStamp, this.cost);
}

View File

@@ -0,0 +1,118 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// No Axis Example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of hiding both axis.
class HiddenTicksAndLabelsAxis extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
HiddenTicksAndLabelsAxis(this.seriesList, {this.animate});
factory HiddenTicksAndLabelsAxis.withSampleData() {
return new HiddenTicksAndLabelsAxis(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory HiddenTicksAndLabelsAxis.withRandomData() {
return new HiddenTicksAndLabelsAxis(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2014', random.nextInt(100) * 100),
new OrdinalSales('2015', random.nextInt(100) * 100),
new OrdinalSales('2016', random.nextInt(100) * 100),
new OrdinalSales('2017', random.nextInt(100) * 100),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
/// Assign a custom style for the measure axis.
///
/// The NoneRenderSpec can still draw an axis line with
/// showAxisLine=true.
primaryMeasureAxis:
new charts.NumericAxisSpec(renderSpec: new charts.NoneRenderSpec()),
/// This is an OrdinalAxisSpec to match up with BarChart's default
/// ordinal domain axis (use NumericAxisSpec or DateTimeAxisSpec for
/// other charts).
domainAxis: new charts.OrdinalAxisSpec(
// Make sure that we draw the domain axis line.
showAxisLine: true,
// But don't draw anything else.
renderSpec: new charts.NoneRenderSpec()),
);
}
/// Create series list with single series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2014', 5000),
new OrdinalSales('2015', 25000),
new OrdinalSales('2016', 100000),
new OrdinalSales('2017', 750000),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,160 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of using a primary and secondary axis (left & right respectively)
/// for a set of grouped bars. This is useful for comparing Series that have
/// different units (revenue vs clicks by region), or different magnitudes (2017
/// revenue vs 1/1/2017 revenue by region).
///
/// The first series plots using the primary axis to position its measure
/// values (bar height). This is the default axis used if the measureAxisId is
/// not set.
///
/// The second series plots using the secondary axis due to the measureAxisId of
/// secondaryMeasureAxisId.
///
/// Note: primary and secondary may flip left and right positioning when
/// RTL.flipAxisLocations is set.
class HorizontalBarChartWithSecondaryAxis extends StatelessWidget {
static const secondaryMeasureAxisId = 'secondaryMeasureAxisId';
final List<charts.Series> seriesList;
final bool animate;
HorizontalBarChartWithSecondaryAxis(this.seriesList, {this.animate});
factory HorizontalBarChartWithSecondaryAxis.withSampleData() {
return new HorizontalBarChartWithSecondaryAxis(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory HorizontalBarChartWithSecondaryAxis.withRandomData() {
return new HorizontalBarChartWithSecondaryAxis(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2014', random.nextInt(100) * 100),
new OrdinalSales('2015', random.nextInt(100) * 100),
new OrdinalSales('2016', random.nextInt(100) * 100),
new OrdinalSales('2017', random.nextInt(100) * 100),
];
final losAngelesSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Los Angeles Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: losAngelesSalesData,
)..setAttribute(charts.measureAxisIdKey, secondaryMeasureAxisId)
// Set the 'Los Angeles Revenue' series to use the secondary measure axis.
// All series that have this set will use the secondary measure axis.
// All other series will use the primary measure axis.
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// For horizontal bar charts, set the [vertical] flag to false.
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
vertical: false,
// It is important when using both primary and secondary axes to choose
// the same number of ticks for both sides to get the gridlines to line
// up.
primaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec:
new charts.BasicNumericTickProviderSpec(desiredTickCount: 3)),
secondaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec:
new charts.BasicNumericTickProviderSpec(desiredTickCount: 3)),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2014', 5000),
new OrdinalSales('2015', 25000),
new OrdinalSales('2016', 100000),
new OrdinalSales('2017', 750000),
];
final losAngelesSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Los Angeles Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: losAngelesSalesData,
)..setAttribute(charts.measureAxisIdKey, secondaryMeasureAxisId)
// Set the 'Los Angeles Revenue' series to use the secondary measure axis.
// All series that have this set will use the secondary measure axis.
// All other series will use the primary measure axis.
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,129 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of timeseries chart forcing the measure axis to have whole number
/// ticks. This is useful if the measure units don't make sense to present as
/// fractional.
///
/// This is done by customizing the measure axis and setting
/// [dataIsInWholeNumbers] on the tick provider.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class IntegerOnlyMeasureAxis extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
IntegerOnlyMeasureAxis(this.seriesList, {this.animate});
/// Creates a [TimeSeriesChart] with sample data and no transition.
factory IntegerOnlyMeasureAxis.withSampleData() {
return new IntegerOnlyMeasureAxis(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory IntegerOnlyMeasureAxis.withRandomData() {
return new IntegerOnlyMeasureAxis(_createRandomData());
}
/// Create random data.
static List<charts.Series<MyRow, DateTime>> _createRandomData() {
final random = new Random();
final data = [
new MyRow(new DateTime(2017, 9, 25), random.nextDouble().round()),
new MyRow(new DateTime(2017, 9, 26), random.nextDouble().round()),
new MyRow(new DateTime(2017, 9, 27), random.nextDouble().round()),
new MyRow(new DateTime(2017, 9, 28), random.nextDouble().round()),
new MyRow(new DateTime(2017, 9, 29), random.nextDouble().round()),
new MyRow(new DateTime(2017, 9, 30), random.nextDouble().round()),
new MyRow(new DateTime(2017, 10, 01), random.nextDouble().round()),
new MyRow(new DateTime(2017, 10, 02), random.nextDouble().round()),
new MyRow(new DateTime(2017, 10, 03), random.nextDouble().round()),
new MyRow(new DateTime(2017, 10, 04), random.nextDouble().round()),
new MyRow(new DateTime(2017, 10, 05), random.nextDouble().round()),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Headcount',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.headcount,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.TimeSeriesChart(
seriesList,
animate: animate,
// Provides a custom axis ensuring that the ticks are in whole numbers.
primaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec: new charts.BasicNumericTickProviderSpec(
// Make sure we don't have values less than 1 as ticks
// (ie: counts).
dataIsInWholeNumbers: true,
// Fixed tick count to highlight the integer only behavior
// generating ticks [0, 1, 2, 3, 4].
desiredTickCount: 5)),
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<MyRow, DateTime>> _createSampleData() {
final data = [
new MyRow(new DateTime(2017, 9, 25), 0),
new MyRow(new DateTime(2017, 9, 26), 0),
new MyRow(new DateTime(2017, 9, 27), 0),
new MyRow(new DateTime(2017, 9, 28), 0),
new MyRow(new DateTime(2017, 9, 29), 0),
new MyRow(new DateTime(2017, 9, 30), 0),
new MyRow(new DateTime(2017, 10, 01), 1),
new MyRow(new DateTime(2017, 10, 02), 1),
new MyRow(new DateTime(2017, 10, 03), 1),
new MyRow(new DateTime(2017, 10, 04), 1),
new MyRow(new DateTime(2017, 10, 05), 1),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Headcount',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.headcount,
data: data,
)
];
}
}
/// Sample time series data type.
class MyRow {
final DateTime timeStamp;
final int headcount;
MyRow(this.timeStamp, this.headcount);
}

View File

@@ -0,0 +1,268 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of using disjoint measure axes to render 4 series of lines with
/// separate scales. The general use case for this type of chart is to show
/// differences in the trends of the data, without comparing their absolute
/// values.
///
/// Disjoint measure axes will be used to scale the series associated with them,
/// but they will not render any tick elements on either side of the chart.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:collection' show LinkedHashMap;
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class DisjointMeasureAxisLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DisjointMeasureAxisLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory DisjointMeasureAxisLineChart.withSampleData() {
return new DisjointMeasureAxisLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DisjointMeasureAxisLineChart.withRandomData() {
return new DisjointMeasureAxisLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearClicks, num>> _createRandomData() {
final random = new Random();
// The first three series contain similar data with different magnitudes.
// This demonstrates the ability to graph the trends in each series relative
// to each other, without the largest magnitude series compressing the
// smallest.
final myFakeDesktopData = [
new LinearClicks(0, clickCount: random.nextInt(100)),
new LinearClicks(1, clickCount: random.nextInt(100)),
new LinearClicks(2, clickCount: random.nextInt(100)),
new LinearClicks(3, clickCount: random.nextInt(100)),
];
final myFakeTabletData = [
new LinearClicks(0, clickCount: random.nextInt(100) * 100),
new LinearClicks(1, clickCount: random.nextInt(100) * 100),
new LinearClicks(2, clickCount: random.nextInt(100) * 100),
new LinearClicks(3, clickCount: random.nextInt(100) * 100),
];
final myFakeMobileData = [
new LinearClicks(0, clickCount: random.nextInt(100) * 1000),
new LinearClicks(1, clickCount: random.nextInt(100) * 1000),
new LinearClicks(2, clickCount: random.nextInt(100) * 1000),
new LinearClicks(3, clickCount: random.nextInt(100) * 1000),
];
// The fourth series renders with decimal values, representing a very
// different sort ratio-based data. If this was on the same axis as any of
// the other series, it would be squashed near zero.
final myFakeClickRateData = [
new LinearClicks(0, clickRate: .25),
new LinearClicks(1, clickRate: .65),
new LinearClicks(2, clickRate: .50),
new LinearClicks(3, clickRate: .30),
];
return [
// We render an empty series on the primary measure axis to ensure that
// the axis itself gets rendered. This helps us draw the gridlines on the
// chart.
new charts.Series<LinearClicks, int>(
id: 'Fake Series',
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: []),
new charts.Series<LinearClicks, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: myFakeDesktopData,
)
// Set the 'Desktop' series to use a disjoint axis.
..setAttribute(charts.measureAxisIdKey, 'axis 1'),
new charts.Series<LinearClicks, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: myFakeTabletData,
)
// Set the 'Tablet' series to use a disjoint axis.
..setAttribute(charts.measureAxisIdKey, 'axis 2'),
new charts.Series<LinearClicks, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: myFakeMobileData,
)
// Set the 'Mobile' series to use a disjoint axis.
..setAttribute(charts.measureAxisIdKey, 'axis 3'),
new charts.Series<LinearClicks, int>(
id: 'Click Rate',
colorFn: (_, __) => charts.MaterialPalette.purple.shadeDefault,
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: myFakeClickRateData,
)
// Set the 'Click Rate' series to use a disjoint axis.
..setAttribute(charts.measureAxisIdKey, 'axis 4'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList,
animate: animate,
// Configure a primary measure axis that will render gridlines across
// the chart. This axis uses fake ticks with no labels to ensure that we
// get 5 grid lines.
//
// We do this because disjoint measure axes do not draw any tick
// elements on the chart.
primaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec: new charts.StaticNumericTickProviderSpec(
// Create the ticks to be used the domain axis.
<charts.TickSpec<num>>[
new charts.TickSpec(0, label: ''),
new charts.TickSpec(1, label: ''),
new charts.TickSpec(2, label: ''),
new charts.TickSpec(3, label: ''),
new charts.TickSpec(4, label: ''),
],
)),
// Create one disjoint measure axis per series on the chart.
//
// Disjoint measure axes will be used to scale the rendered data,
// without drawing any tick elements on either side of the chart.
disjointMeasureAxes:
new LinkedHashMap<String, charts.NumericAxisSpec>.from({
'axis 1': new charts.NumericAxisSpec(),
'axis 2': new charts.NumericAxisSpec(),
'axis 3': new charts.NumericAxisSpec(),
'axis 4': new charts.NumericAxisSpec(),
}));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearClicks, int>> _createSampleData() {
// The first three series contain similar data with different magnitudes.
// This demonstrates the ability to graph the trends in each series relative
// to each other, without the largest magnitude series compressing the
// smallest.
final myFakeDesktopData = [
new LinearClicks(0, clickCount: 25),
new LinearClicks(1, clickCount: 125),
new LinearClicks(2, clickCount: 920),
new LinearClicks(3, clickCount: 375),
];
final myFakeTabletData = [
new LinearClicks(0, clickCount: 375),
new LinearClicks(1, clickCount: 1850),
new LinearClicks(2, clickCount: 9700),
new LinearClicks(3, clickCount: 5000),
];
final myFakeMobileData = [
new LinearClicks(0, clickCount: 5000),
new LinearClicks(1, clickCount: 25000),
new LinearClicks(2, clickCount: 100000),
new LinearClicks(3, clickCount: 75000),
];
// The fourth series renders with decimal values, representing a very
// different sort ratio-based data. If this was on the same axis as any of
// the other series, it would be squashed near zero.
final myFakeClickRateData = [
new LinearClicks(0, clickRate: .25),
new LinearClicks(1, clickRate: .65),
new LinearClicks(2, clickRate: .50),
new LinearClicks(3, clickRate: .30),
];
return [
// We render an empty series on the primary measure axis to ensure that
// the axis itself gets rendered. This helps us draw the gridlines on the
// chart.
new charts.Series<LinearClicks, int>(
id: 'Fake Series',
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: []),
new charts.Series<LinearClicks, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: myFakeDesktopData,
)
// Set the 'Desktop' series to use a disjoint axis.
..setAttribute(charts.measureAxisIdKey, 'axis 1'),
new charts.Series<LinearClicks, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: myFakeTabletData,
)
// Set the 'Tablet' series to use a disjoint axis.
..setAttribute(charts.measureAxisIdKey, 'axis 2'),
new charts.Series<LinearClicks, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickCount,
data: myFakeMobileData,
)
// Set the 'Mobile' series to use a disjoint axis.
..setAttribute(charts.measureAxisIdKey, 'axis 3'),
new charts.Series<LinearClicks, int>(
id: 'Click Rate',
colorFn: (_, __) => charts.MaterialPalette.purple.shadeDefault,
domainFn: (LinearClicks clickCount, _) => clickCount.year,
measureFn: (LinearClicks clickCount, _) => clickCount.clickRate,
data: myFakeClickRateData,
)
// Set the 'Click Rate' series to use a disjoint axis.
..setAttribute(charts.measureAxisIdKey, 'axis 4'),
];
}
}
/// Sample linear data type.
class LinearClicks {
final int year;
final int clickCount;
final double clickRate;
LinearClicks(this.year, {this.clickCount = null, this.clickRate = null});
}

View File

@@ -0,0 +1,122 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Custom Tick Label Alignment Example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of using a custom primary measure replacing the renderSpec with one
/// that aligns the text under the tick and left justifies.
class MeasureAxisLabelAlignment extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
MeasureAxisLabelAlignment(this.seriesList, {this.animate});
factory MeasureAxisLabelAlignment.withSampleData() {
return new MeasureAxisLabelAlignment(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory MeasureAxisLabelAlignment.withRandomData() {
return new MeasureAxisLabelAlignment(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2014', random.nextInt(100) * 100),
new OrdinalSales('2015', random.nextInt(100) * 100),
new OrdinalSales('2016', random.nextInt(100) * 100),
new OrdinalSales('2017', random.nextInt(100) * 100),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
/// Customize the primary measure axis using a small tick renderer.
/// Use String instead of num for ordinal domain axis
/// (typically bar charts).
primaryMeasureAxis: new charts.NumericAxisSpec(
renderSpec: new charts.GridlineRendererSpec(
// Display the measure axis labels below the gridline.
//
// 'Before' & 'after' follow the axis value direction.
// Vertical axes draw 'before' below & 'after' above the tick.
// Horizontal axes draw 'before' left & 'after' right the tick.
labelAnchor: charts.TickLabelAnchor.before,
// Left justify the text in the axis.
//
// Note: outside means that the secondary measure axis would right
// justify.
labelJustification: charts.TickLabelJustification.outside,
)),
);
}
/// Create series list with single series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2014', 5000),
new OrdinalSales('2015', 25000),
new OrdinalSales('2016', 100000),
new OrdinalSales('2017', 750000),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,119 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of timeseries chart that has a measure axis that does NOT include
/// zero. It starts at 100 and goes to 140.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class NonzeroBoundMeasureAxis extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
NonzeroBoundMeasureAxis(this.seriesList, {this.animate});
/// Creates a [TimeSeriesChart] with sample data and no transition.
factory NonzeroBoundMeasureAxis.withSampleData() {
return new NonzeroBoundMeasureAxis(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory NonzeroBoundMeasureAxis.withRandomData() {
return new NonzeroBoundMeasureAxis(_createRandomData());
}
/// Create random data.
static List<charts.Series<MyRow, DateTime>> _createRandomData() {
final random = new Random();
final data = [
new MyRow(new DateTime(2017, 9, 25), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 9, 26), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 9, 27), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 9, 28), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 9, 29), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 9, 30), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 10, 01), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 10, 02), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 10, 03), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 10, 04), random.nextInt(100) + 100),
new MyRow(new DateTime(2017, 10, 05), random.nextInt(100) + 100),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Headcount',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.headcount,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.TimeSeriesChart(seriesList,
animate: animate,
// Provide a tickProviderSpec which does NOT require that zero is
// included.
primaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec:
new charts.BasicNumericTickProviderSpec(zeroBound: false)));
}
/// Create one series with sample hard coded data.
static List<charts.Series<MyRow, DateTime>> _createSampleData() {
final data = [
new MyRow(new DateTime(2017, 9, 25), 106),
new MyRow(new DateTime(2017, 9, 26), 108),
new MyRow(new DateTime(2017, 9, 27), 106),
new MyRow(new DateTime(2017, 9, 28), 109),
new MyRow(new DateTime(2017, 9, 29), 111),
new MyRow(new DateTime(2017, 9, 30), 115),
new MyRow(new DateTime(2017, 10, 01), 125),
new MyRow(new DateTime(2017, 10, 02), 133),
new MyRow(new DateTime(2017, 10, 03), 127),
new MyRow(new DateTime(2017, 10, 04), 131),
new MyRow(new DateTime(2017, 10, 05), 123),
];
return [
new charts.Series<MyRow, DateTime>(
id: 'Headcount',
domainFn: (MyRow row, _) => row.timeStamp,
measureFn: (MyRow row, _) => row.headcount,
data: data,
)
];
}
}
/// Sample time series data type.
class MyRow {
final DateTime timeStamp;
final int headcount;
MyRow(this.timeStamp, this.headcount);
}

View File

@@ -0,0 +1,133 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of setting an initial viewport for ordinal axis.
///
/// This allows for specifying the specific range of data to show that differs
/// from what was provided in the series list.
///
/// In this example, the series list has numeric data from 0 to 10, but we
/// want to show from 3 to 7.
/// We can do this by specifying an [NumericExtents] in [NumericAxisSpec].
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class NumericInitialViewport extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
NumericInitialViewport(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory NumericInitialViewport.withSampleData() {
return new NumericInitialViewport(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory NumericInitialViewport.withRandomData() {
return new NumericInitialViewport(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
new LinearSales(4, random.nextInt(100)),
new LinearSales(5, random.nextInt(100)),
new LinearSales(6, random.nextInt(100)),
new LinearSales(7, random.nextInt(100)),
new LinearSales(8, random.nextInt(100)),
new LinearSales(9, random.nextInt(100)),
new LinearSales(10, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(
seriesList,
animate: animate,
domainAxis: new charts.NumericAxisSpec(
// Set the initial viewport by providing a new AxisSpec with the
// desired viewport, in NumericExtents.
viewport: new charts.NumericExtents(3.0, 7.0)),
// Optionally add a pan or pan and zoom behavior.
// If pan/zoom is not added, the viewport specified remains the viewport.
behaviors: [new charts.PanAndZoomBehavior()],
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
new LinearSales(4, 55),
new LinearSales(5, 66),
new LinearSales(6, 110),
new LinearSales(7, 70),
new LinearSales(8, 20),
new LinearSales(9, 25),
new LinearSales(10, 45),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,145 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of setting an initial viewport for ordinal axis.
///
/// This allows for specifying the specific range of data to show that differs
/// from what was provided in the series list.
///
/// In this example, the series list has ordinal data from year 2014 to 2030,
/// but we want to show starting at 2018 and we only want to show 4 values.
/// We can do this by specifying an [OrdinalViewport] in [OrdinalAxisSpec].
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class OrdinalInitialViewport extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
OrdinalInitialViewport(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory OrdinalInitialViewport.withSampleData() {
return new OrdinalInitialViewport(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory OrdinalInitialViewport.withRandomData() {
return new OrdinalInitialViewport(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
new OrdinalSales('2018', random.nextInt(100)),
new OrdinalSales('2019', random.nextInt(100)),
new OrdinalSales('2020', random.nextInt(100)),
new OrdinalSales('2021', random.nextInt(100)),
new OrdinalSales('2022', random.nextInt(100)),
new OrdinalSales('2023', random.nextInt(100)),
new OrdinalSales('2024', random.nextInt(100)),
new OrdinalSales('2025', random.nextInt(100)),
new OrdinalSales('2026', random.nextInt(100)),
new OrdinalSales('2027', random.nextInt(100)),
new OrdinalSales('2028', random.nextInt(100)),
new OrdinalSales('2029', random.nextInt(100)),
new OrdinalSales('2030', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
// Set the initial viewport by providing a new AxisSpec with the
// desired viewport: a starting domain and the data size.
domainAxis: new charts.OrdinalAxisSpec(
viewport: new charts.OrdinalViewport('2018', 4)),
// Optionally add a pan or pan and zoom behavior.
// If pan/zoom is not added, the viewport specified remains the viewport.
behaviors: [new charts.PanAndZoomBehavior()],
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
new OrdinalSales('2018', 33),
new OrdinalSales('2019', 80),
new OrdinalSales('2020', 21),
new OrdinalSales('2021', 77),
new OrdinalSales('2022', 8),
new OrdinalSales('2023', 12),
new OrdinalSales('2024', 42),
new OrdinalSales('2025', 70),
new OrdinalSales('2026', 77),
new OrdinalSales('2027', 55),
new OrdinalSales('2028', 19),
new OrdinalSales('2029', 66),
new OrdinalSales('2030', 27),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,115 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Custom Tick Style Example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of using a custom primary measure axis replacing the default
/// gridline rendering with a short tick rendering. It also turns on the axis
/// line so that the ticks have something to line up against.
///
/// There are many axis styling options in the SmallTickRenderer allowing you
/// to customize the font, tick lengths, and offsets.
class ShortTickLengthAxis extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
ShortTickLengthAxis(this.seriesList, {this.animate});
factory ShortTickLengthAxis.withSampleData() {
return new ShortTickLengthAxis(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory ShortTickLengthAxis.withRandomData() {
return new ShortTickLengthAxis(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2014', random.nextInt(100) * 100),
new OrdinalSales('2015', random.nextInt(100) * 100),
new OrdinalSales('2016', random.nextInt(100) * 100),
new OrdinalSales('2017', random.nextInt(100) * 100),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
/// Customize the primary measure axis using a small tick renderer.
/// Note: use String instead of num for ordinal domain axis
/// (typically bar charts).
primaryMeasureAxis: new charts.NumericAxisSpec(
renderSpec: new charts.SmallTickRendererSpec(
// Tick and Label styling here.
)),
);
}
/// Create series list with single series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2014', 5000),
new OrdinalSales('2015', 25000),
new OrdinalSales('2016', 100000),
new OrdinalSales('2017', 750000),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,134 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of axis using statically provided ticks.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of specifying a custom set of ticks to be used on the domain axis.
///
/// Specifying custom set of ticks allows specifying exactly what ticks are
/// used in the axis. Each tick is also allowed to have a different style set.
///
/// For an ordinal axis, the [StaticOrdinalTickProviderSpec] is shown in this
/// example defining ticks to be used with [TickSpec] of String.
///
/// For numeric axis, the [StaticNumericTickProviderSpec] can be used by passing
/// in a list of ticks defined with [TickSpec] of num.
///
/// For datetime axis, the [StaticDateTimeTickProviderSpec] can be used by
/// passing in a list of ticks defined with [TickSpec] of datetime.
class StaticallyProvidedTicks extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
StaticallyProvidedTicks(this.seriesList, {this.animate});
factory StaticallyProvidedTicks.withSampleData() {
return new StaticallyProvidedTicks(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory StaticallyProvidedTicks.withRandomData() {
return new StaticallyProvidedTicks(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2014', random.nextInt(100) * 100),
new OrdinalSales('2015', random.nextInt(100) * 100),
new OrdinalSales('2016', random.nextInt(100) * 100),
new OrdinalSales('2017', random.nextInt(100) * 100),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// Create the ticks to be used the domain axis.
final staticTicks = <charts.TickSpec<String>>[
new charts.TickSpec(
// Value must match the domain value.
'2014',
// Optional label for this tick, defaults to domain value if not set.
label: 'Year 2014',
// The styling for this tick.
style: new charts.TextStyleSpec(
color: new charts.Color(r: 0x4C, g: 0xAF, b: 0x50))),
// If no text style is specified - the style from renderSpec will be used
// if one is specified.
new charts.TickSpec('2015'),
new charts.TickSpec('2016'),
new charts.TickSpec('2017'),
];
return new charts.BarChart(
seriesList,
animate: animate,
domainAxis: new charts.OrdinalAxisSpec(
tickProviderSpec:
new charts.StaticOrdinalTickProviderSpec(staticTicks)),
);
}
/// Create series list with single series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2014', 5000),
new OrdinalSales('2015', 25000),
new OrdinalSales('2016', 100000),
new OrdinalSales('2017', 750000),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,156 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'custom_rounded_bars.dart';
import 'grouped.dart';
import 'grouped_fill_color.dart';
import 'grouped_single_target_line.dart';
import 'grouped_stacked.dart';
import 'grouped_stacked_weight_pattern.dart';
import 'grouped_target_line.dart';
import 'horizontal.dart';
import 'horizontal_bar_label.dart';
import 'horizontal_bar_label_custom.dart';
import 'horizontal_pattern_forward_hatch.dart';
import 'pattern_forward_hatch.dart';
import 'simple.dart';
import 'stacked.dart';
import 'stacked_fill_color.dart';
import 'stacked_horizontal.dart';
import 'stacked_target_line.dart';
import 'spark_bar.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Simple Bar Chart',
subtitle: 'Simple bar chart with a single series',
childBuilder: () => new SimpleBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Stacked Bar Chart',
subtitle: 'Stacked bar chart with multiple series',
childBuilder: () => new StackedBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Grouped Bar Chart',
subtitle: 'Grouped bar chart with multiple series',
childBuilder: () => new GroupedBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Grouped Stacked Bar Chart',
subtitle: 'Grouped and stacked bar chart with multiple series',
childBuilder: () => new GroupedStackedBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Grouped Bar Target Line Chart',
subtitle: 'Grouped bar target line chart with multiple series',
childBuilder: () => new GroupedBarTargetLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Grouped Bar Single Target Line Chart',
subtitle:
'Grouped bar target line chart with multiple series and a single target',
childBuilder: () => new GroupedBarSingleTargetLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Stacked Bar Target Line Chart',
subtitle: 'Stacked bar target line chart with multiple series',
childBuilder: () => new StackedBarTargetLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Transform.rotate(
angle: 1.5708, child: new Icon(Icons.insert_chart)),
title: 'Horizontal Bar Chart',
subtitle: 'Horizontal bar chart with a single series',
childBuilder: () => new HorizontalBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Transform.rotate(
angle: 1.5708, child: new Icon(Icons.insert_chart)),
title: 'Stacked Horizontal Bar Chart',
subtitle: 'Stacked horizontal bar chart with multiple series',
childBuilder: () => new StackedHorizontalBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Transform.rotate(
angle: 1.5708, child: new Icon(Icons.insert_chart)),
title: 'Horizontal Bar Chart with Bar Labels',
subtitle: 'Horizontal bar chart with a single series and bar labels',
childBuilder: () => new HorizontalBarLabelChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Transform.rotate(
angle: 1.5708, child: new Icon(Icons.insert_chart)),
title: 'Horizontal Bar Chart with Custom Bar Labels',
subtitle: 'Bar labels with customized styling',
childBuilder: () => new HorizontalBarLabelCustomChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Spark Bar Chart',
subtitle: 'Spark Bar Chart',
childBuilder: () => new SparkBar.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Grouped Fill Color Bar Chart',
subtitle: 'Grouped bar chart with fill colors',
childBuilder: () => new GroupedFillColorBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Stacked Fill Color Bar Chart',
subtitle: 'Stacked bar chart with fill colors',
childBuilder: () => new StackedFillColorBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Pattern Forward Hatch Bar Chart',
subtitle: 'Pattern Forward Hatch Bar Chart',
childBuilder: () => new PatternForwardHatchBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Transform.rotate(
angle: 1.5708, child: new Icon(Icons.insert_chart)),
title: 'Horizontal Pattern Forward Hatch Bar Chart',
subtitle: 'Horizontal Pattern Forward Hatch Bar Chart',
childBuilder: () =>
new HorizontalPatternForwardHatchBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Weight Pattern Bar Chart',
subtitle: 'Grouped and stacked bar chart with a weight pattern',
childBuilder: () =>
new GroupedStackedWeightPatternBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Bar Chart with custom bar radius',
subtitle: 'Custom rounded bar corners',
childBuilder: () => new CustomRoundedBars.withRandomData(),
),
];
}

View File

@@ -0,0 +1,110 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class CustomRoundedBars extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
CustomRoundedBars(this.seriesList, {this.animate});
/// Creates a [BarChart] with custom rounded bars.
factory CustomRoundedBars.withSampleData() {
return new CustomRoundedBars(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory CustomRoundedBars.withRandomData() {
return new CustomRoundedBars(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
defaultRenderer: new charts.BarRendererConfig(
// By default, bar renderer will draw rounded bars with a constant
// radius of 30.
// To not have any rounded corners, use [NoCornerStrategy]
// To change the radius of the bars, use [ConstCornerStrategy]
cornerStrategy: const charts.ConstCornerStrategy(30)),
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,154 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class GroupedBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
GroupedBarChart(this.seriesList, {this.animate});
factory GroupedBarChart.withSampleData() {
return new GroupedBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory GroupedBarChart.withRandomData() {
return new GroupedBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,178 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of a grouped bar chart with three series, each rendered with
/// different fill colors.
class GroupedFillColorBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
GroupedFillColorBarChart(this.seriesList, {this.animate});
factory GroupedFillColorBarChart.withSampleData() {
return new GroupedFillColorBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory GroupedFillColorBarChart.withRandomData() {
return new GroupedFillColorBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
// Blue bars with a lighter center color.
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
fillColorFn: (_, __) =>
charts.MaterialPalette.blue.shadeDefault.lighter,
),
// Solid red bars. Fill color will default to the series color if no
// fillColorFn is configured.
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
),
// Hollow green bars.
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
fillColorFn: (_, __) => charts.MaterialPalette.transparent,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
// Configure a stroke width to enable borders on the bars.
defaultRenderer: new charts.BarRendererConfig(
groupingType: charts.BarGroupingType.grouped, strokeWidthPx: 2.0),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
// Blue bars with a lighter center color.
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
fillColorFn: (_, __) =>
charts.MaterialPalette.blue.shadeDefault.lighter,
),
// Solid red bars. Fill color will default to the series color if no
// fillColorFn is configured.
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
),
// Hollow green bars.
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
fillColorFn: (_, __) => charts.MaterialPalette.transparent,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,180 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class GroupedBarSingleTargetLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
GroupedBarSingleTargetLineChart(this.seriesList, {this.animate});
factory GroupedBarSingleTargetLineChart.withSampleData() {
return new GroupedBarSingleTargetLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory GroupedBarSingleTargetLineChart.withRandomData() {
return new GroupedBarSingleTargetLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final targetLineData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Desktop Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: targetLineData)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
customSeriesRenderers: [
new charts.BarTargetLineRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customTargetLine',
groupingType: charts.BarGroupingType.grouped)
]);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final targetLineData = [
new OrdinalSales('2014', 30),
new OrdinalSales('2015', 55),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 25),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Desktop Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: targetLineData)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,244 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a bar chart with grouped, stacked series oriented vertically.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class GroupedStackedBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
GroupedStackedBarChart(this.seriesList, {this.animate});
factory GroupedStackedBarChart.withSampleData() {
return new GroupedStackedBarChart(
createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory GroupedStackedBarChart.withRandomData() {
return new GroupedStackedBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final desktopSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataB,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.groupedStacked,
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> createSampleData() {
final desktopSalesDataA = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesDataA = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesDataA = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final desktopSalesDataB = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesDataB = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesDataB = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataB,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,256 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a bar chart with grouped, stacked series oriented vertically with
/// a custom weight pattern.
///
/// This is a pattern of weights used to calculate the width of bars within a
/// bar group. If not specified, each bar in the group will have an equal width.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class GroupedStackedWeightPatternBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
GroupedStackedWeightPatternBarChart(this.seriesList, {this.animate});
factory GroupedStackedWeightPatternBarChart.withSampleData() {
return new GroupedStackedWeightPatternBarChart(
createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory GroupedStackedWeightPatternBarChart.withRandomData() {
return new GroupedStackedWeightPatternBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final desktopSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataB,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
// Configure the bar renderer in grouped stacked rendering mode with a
// custom weight pattern.
//
// The first stack of bars in each group is configured to be twice as wide
// as the second stack of bars in each group.
defaultRenderer: new charts.BarRendererConfig(
groupingType: charts.BarGroupingType.groupedStacked,
weightPattern: [2, 1],
),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> createSampleData() {
final desktopSalesDataA = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesDataA = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesDataA = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final desktopSalesDataB = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesDataB = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesDataB = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataB,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,248 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class GroupedBarTargetLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
GroupedBarTargetLineChart(this.seriesList, {this.animate});
factory GroupedBarTargetLineChart.withSampleData() {
return new GroupedBarTargetLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory GroupedBarTargetLineChart.withRandomData() {
return new GroupedBarTargetLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final desktopTargetLineData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableTargetLineData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileTargetLineData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
new charts.Series<OrdinalSales, String>(
id: 'Tablet Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
new charts.Series<OrdinalSales, String>(
id: 'Mobile Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
customSeriesRenderers: [
new charts.BarTargetLineRendererConfig<String>(
// ID used to link series to this renderer.
customRendererId: 'customTargetLine',
groupingType: charts.BarGroupingType.grouped)
]);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final desktopTargetLineData = [
new OrdinalSales('2014', 4),
new OrdinalSales('2015', 20),
new OrdinalSales('2016', 80),
new OrdinalSales('2017', 65),
];
final tableTargetLineData = [
new OrdinalSales('2014', 30),
new OrdinalSales('2015', 55),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 25),
];
final mobileTargetLineData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 5),
new OrdinalSales('2016', 45),
new OrdinalSales('2017', 35),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
new charts.Series<OrdinalSales, String>(
id: 'Tablet Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
new charts.Series<OrdinalSales, String>(
id: 'Mobile Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,104 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Horizontal bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class HorizontalBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
HorizontalBarChart(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory HorizontalBarChart.withSampleData() {
return new HorizontalBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory HorizontalBarChart.withRandomData() {
return new HorizontalBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// For horizontal bar charts, set the [vertical] flag to false.
return new charts.BarChart(
seriesList,
animate: animate,
vertical: false,
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,123 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Horizontal bar chart with bar label renderer example and hidden domain axis.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class HorizontalBarLabelChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
HorizontalBarLabelChart(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory HorizontalBarLabelChart.withSampleData() {
return new HorizontalBarLabelChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory HorizontalBarLabelChart.withRandomData() {
return new HorizontalBarLabelChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
// Set a label accessor to control the text of the bar label.
labelAccessorFn: (OrdinalSales sales, _) =>
'${sales.year}: \$${sales.sales.toString()}')
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
// [BarLabelDecorator] will automatically position the label
// inside the bar if the label will fit. If the label will not fit and the
// area outside of the bar is larger than the bar, it will draw outside of the
// bar. Labels can always display inside or outside using [LabelPosition].
//
// Text style for inside / outside can be controlled independently by setting
// [insideLabelStyleSpec] and [outsideLabelStyleSpec].
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
vertical: false,
// Set a bar label decorator.
// Example configuring different styles for inside/outside:
// barRendererDecorator: new charts.BarLabelDecorator(
// insideLabelStyleSpec: new charts.TextStyleSpec(...),
// outsideLabelStyleSpec: new charts.TextStyleSpec(...)),
barRendererDecorator: new charts.BarLabelDecorator<String>(),
// Hide domain axis.
domainAxis:
new charts.OrdinalAxisSpec(renderSpec: new charts.NoneRenderSpec()),
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
// Set a label accessor to control the text of the bar label.
labelAccessorFn: (OrdinalSales sales, _) =>
'${sales.year}: \$${sales.sales.toString()}')
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,140 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Horizontal bar chart with custom style for each datum in the bar label.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class HorizontalBarLabelCustomChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
HorizontalBarLabelCustomChart(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
static HorizontalBarLabelCustomChart createWithSampleData() {
return new HorizontalBarLabelCustomChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory HorizontalBarLabelCustomChart.withRandomData() {
return new HorizontalBarLabelCustomChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
// Set a label accessor to control the text of the bar label.
labelAccessorFn: (OrdinalSales sales, _) =>
'${sales.year}: \$${sales.sales.toString()}',
insideLabelStyleAccessorFn: (OrdinalSales sales, _) {
final color = (sales.year == '2014')
? charts.MaterialPalette.red.shadeDefault
: charts.MaterialPalette.yellow.shadeDefault.darker;
return new charts.TextStyleSpec(color: color);
},
outsideLabelStyleAccessorFn: (OrdinalSales sales, _) {
final color = (sales.year == '2014')
? charts.MaterialPalette.red.shadeDefault
: charts.MaterialPalette.yellow.shadeDefault.darker;
return new charts.TextStyleSpec(color: color);
},
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
// The [BarLabelDecorator] has settings to set the text style for all labels
// for inside the bar and outside the bar. To be able to control each datum's
// style, set the style accessor functions on the series.
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
vertical: false,
barRendererDecorator: new charts.BarLabelDecorator<String>(),
// Hide domain axis.
domainAxis:
new charts.OrdinalAxisSpec(renderSpec: new charts.NoneRenderSpec()),
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
// Set a label accessor to control the text of the bar label.
labelAccessorFn: (OrdinalSales sales, _) =>
'${sales.year}: \$${sales.sales.toString()}',
insideLabelStyleAccessorFn: (OrdinalSales sales, _) {
final color = (sales.year == '2014')
? charts.MaterialPalette.red.shadeDefault
: charts.MaterialPalette.yellow.shadeDefault.darker;
return new charts.TextStyleSpec(color: color);
},
outsideLabelStyleAccessorFn: (OrdinalSales sales, _) {
final color = (sales.year == '2014')
? charts.MaterialPalette.red.shadeDefault
: charts.MaterialPalette.yellow.shadeDefault.darker;
return new charts.TextStyleSpec(color: color);
},
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,163 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Forward pattern hatch bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Forward hatch pattern horizontal bar chart example.
///
/// The second series of bars is rendered with a pattern by defining a
/// fillPatternFn mapping function.
class HorizontalPatternForwardHatchBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
HorizontalPatternForwardHatchBarChart(this.seriesList, {this.animate});
factory HorizontalPatternForwardHatchBarChart.withSampleData() {
return new HorizontalPatternForwardHatchBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory HorizontalPatternForwardHatchBarChart.withRandomData() {
return new HorizontalPatternForwardHatchBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
fillPatternFn: (OrdinalSales sales, _) =>
charts.FillPatternType.forwardHatch,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
vertical: false,
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
fillPatternFn: (OrdinalSales sales, _) =>
charts.FillPatternType.forwardHatch,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,161 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Forward hatch pattern bar chart example.
///
/// The second series of bars is rendered with a pattern by defining a
/// fillPatternFn mapping function.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class PatternForwardHatchBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
PatternForwardHatchBarChart(this.seriesList, {this.animate});
factory PatternForwardHatchBarChart.withSampleData() {
return new PatternForwardHatchBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory PatternForwardHatchBarChart.withRandomData() {
return new PatternForwardHatchBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
fillPatternFn: (OrdinalSales sales, _) =>
charts.FillPatternType.forwardHatch,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
fillPatternFn: (OrdinalSales sales, _) =>
charts.FillPatternType.forwardHatch,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,104 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SimpleBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SimpleBarChart(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory SimpleBarChart.withSampleData() {
return new SimpleBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SimpleBarChart.withRandomData() {
return new SimpleBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,140 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Spark Bar Example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of a Spark Bar by hiding both axis, reducing the chart margins.
class SparkBar extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SparkBar(this.seriesList, {this.animate});
factory SparkBar.withSampleData() {
return new SparkBar(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SparkBar.withRandomData() {
return new SparkBar(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final globalSalesData = [
new OrdinalSales('2007', random.nextInt(100)),
new OrdinalSales('2008', random.nextInt(100)),
new OrdinalSales('2009', random.nextInt(100)),
new OrdinalSales('2010', random.nextInt(100)),
new OrdinalSales('2011', random.nextInt(100)),
new OrdinalSales('2012', random.nextInt(100)),
new OrdinalSales('2013', random.nextInt(100)),
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
/// Assign a custom style for the measure axis.
///
/// The NoneRenderSpec only draws an axis line (and even that can be hidden
/// with showAxisLine=false).
primaryMeasureAxis:
new charts.NumericAxisSpec(renderSpec: new charts.NoneRenderSpec()),
/// This is an OrdinalAxisSpec to match up with BarChart's default
/// ordinal domain axis (use NumericAxisSpec or DateTimeAxisSpec for
/// other charts).
domainAxis: new charts.OrdinalAxisSpec(
// Make sure that we draw the domain axis line.
showAxisLine: true,
// But don't draw anything else.
renderSpec: new charts.NoneRenderSpec()),
// With a spark chart we likely don't want large chart margins.
// 1px is the smallest we can make each margin.
layoutConfig: new charts.LayoutConfig(
leftMarginSpec: new charts.MarginSpec.fixedPixel(0),
topMarginSpec: new charts.MarginSpec.fixedPixel(0),
rightMarginSpec: new charts.MarginSpec.fixedPixel(0),
bottomMarginSpec: new charts.MarginSpec.fixedPixel(0)),
);
}
/// Create series list with single series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final globalSalesData = [
new OrdinalSales('2007', 3100),
new OrdinalSales('2008', 3500),
new OrdinalSales('2009', 5000),
new OrdinalSales('2010', 2500),
new OrdinalSales('2011', 3200),
new OrdinalSales('2012', 4500),
new OrdinalSales('2013', 4400),
new OrdinalSales('2014', 5000),
new OrdinalSales('2015', 5000),
new OrdinalSales('2016', 4500),
new OrdinalSales('2017', 4300),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Global Revenue',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: globalSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,155 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class StackedBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
StackedBarChart(this.seriesList, {this.animate});
/// Creates a stacked [BarChart] with sample data and no transition.
factory StackedBarChart.withSampleData() {
return new StackedBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory StackedBarChart.withRandomData() {
return new StackedBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.stacked,
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,178 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example of a stacked bar chart with three series, each rendered with
/// different fill colors.
class StackedFillColorBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
StackedFillColorBarChart(this.seriesList, {this.animate});
factory StackedFillColorBarChart.withSampleData() {
return new StackedFillColorBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory StackedFillColorBarChart.withRandomData() {
return new StackedFillColorBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
// Blue bars with a lighter center color.
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
fillColorFn: (_, __) =>
charts.MaterialPalette.blue.shadeDefault.lighter,
),
// Solid red bars. Fill color will default to the series color if no
// fillColorFn is configured.
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
),
// Hollow green bars.
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
fillColorFn: (_, __) => charts.MaterialPalette.transparent,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
// Configure a stroke width to enable borders on the bars.
defaultRenderer: new charts.BarRendererConfig(
groupingType: charts.BarGroupingType.stacked, strokeWidthPx: 2.0),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
// Blue bars with a lighter center color.
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
fillColorFn: (_, __) =>
charts.MaterialPalette.blue.shadeDefault.lighter,
),
// Solid red bars. Fill color will default to the series color if no
// fillColorFn is configured.
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
),
// Hollow green bars.
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
fillColorFn: (_, __) => charts.MaterialPalette.transparent,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,157 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class StackedHorizontalBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
StackedHorizontalBarChart(this.seriesList, {this.animate});
/// Creates a stacked [BarChart] with sample data and no transition.
factory StackedHorizontalBarChart.withSampleData() {
return new StackedHorizontalBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory StackedHorizontalBarChart.withRandomData() {
return new StackedHorizontalBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// For horizontal bar charts, set the [vertical] flag to false.
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.stacked,
vertical: false,
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,249 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class StackedBarTargetLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
StackedBarTargetLineChart(this.seriesList, {this.animate});
/// Creates a stacked [BarChart] with sample data and no transition.
factory StackedBarTargetLineChart.withSampleData() {
return new StackedBarTargetLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory StackedBarTargetLineChart.withRandomData() {
return new StackedBarTargetLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final desktopTargetLineData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableTargetLineData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileTargetLineData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
new charts.Series<OrdinalSales, String>(
id: 'Tablet Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
new charts.Series<OrdinalSales, String>(
id: 'Mobile Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.stacked,
customSeriesRenderers: [
new charts.BarTargetLineRendererConfig<String>(
// ID used to link series to this renderer.
customRendererId: 'customTargetLine',
groupingType: charts.BarGroupingType.stacked)
]);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final desktopTargetLineData = [
new OrdinalSales('2014', 4),
new OrdinalSales('2015', 20),
new OrdinalSales('2016', 80),
new OrdinalSales('2017', 65),
];
final tableTargetLineData = [
new OrdinalSales('2014', 30),
new OrdinalSales('2015', 55),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 25),
];
final mobileTargetLineData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 5),
new OrdinalSales('2016', 45),
new OrdinalSales('2017', 35),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
new charts.Series<OrdinalSales, String>(
id: 'Tablet Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
new charts.Series<OrdinalSales, String>(
id: 'Mobile Target Line',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileTargetLineData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customTargetLine'),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,126 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'chart_title.dart';
import 'initial_hint_animation.dart';
import 'initial_selection.dart';
import 'percent_of_domain.dart';
import 'percent_of_domain_by_category.dart';
import 'percent_of_series.dart';
import 'selection_bar_highlight.dart';
import 'selection_line_highlight.dart';
import 'selection_line_highlight_custom_shape.dart';
import 'selection_callback_example.dart';
import 'selection_scatter_plot_highlight.dart';
import 'selection_user_managed.dart';
import 'slider.dart';
import 'sliding_viewport_on_selection.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'Selection Bar Highlight',
subtitle: 'Simple bar chart with tap activation',
childBuilder: () => new SelectionBarHighlight.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'Selection Line Highlight',
subtitle: 'Line chart with tap and drag activation',
childBuilder: () => new SelectionLineHighlight.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'Selection Line Highlight Custom Shape',
subtitle: 'Line chart with tap and drag activation and a custom shape',
childBuilder: () =>
new SelectionLineHighlightCustomShape.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'Selection Scatter Plot Highlight',
subtitle: 'Scatter plot chart with tap and drag activation',
childBuilder: () => new SelectionScatterPlotHighlight.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'Selection Callback Example',
subtitle: 'Timeseries that updates external components on selection',
childBuilder: () => new SelectionCallbackExample.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'User managed selection',
subtitle:
'Example where selection can be set and cleared programmatically',
childBuilder: () => new SelectionUserManaged.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Bar Chart with initial selection',
subtitle: 'Single series with initial selection',
childBuilder: () => new InitialSelection.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'Line Chart with Chart Titles',
subtitle: 'Line chart with four chart titles',
childBuilder: () => new ChartTitleLine.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'Line Chart with Slider',
subtitle: 'Line chart with a slider behavior',
childBuilder: () => new SliderLine.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Percent of Domain',
subtitle: 'Stacked bar chart with measures calculated as percent of ' +
'domain',
childBuilder: () => new PercentOfDomainBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Percent of Domain by Category',
subtitle: 'Grouped stacked bar chart with measures calculated as '
'percent of domain and series category',
childBuilder: () =>
new PercentOfDomainByCategoryBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Percent of Series',
subtitle: 'Grouped bar chart with measures calculated as percent of ' +
'series',
childBuilder: () => new PercentOfSeriesBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Sliding viewport on domain selection',
subtitle: 'Center viewport on selected domain',
childBuilder: () => new SlidingViewportOnSelection.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Initial hint animation ',
subtitle: 'Animate into final viewport',
childBuilder: () => new InitialHintAnimation.withRandomData(),
),
];
}

View File

@@ -0,0 +1,131 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
/// This is a line chart with a title text in every margin.
///
/// A series of [ChartTitle] behaviors are used to render titles, one per
/// margin.
class ChartTitleLine extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
ChartTitleLine(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory ChartTitleLine.withSampleData() {
return new ChartTitleLine(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory ChartTitleLine.withRandomData() {
return new ChartTitleLine(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(
seriesList,
animate: animate,
// Configures four [ChartTitle] behaviors to render titles in each chart
// margin. The top title has a sub-title, and is aligned to the left edge
// of the chart. The other titles are aligned with the middle of the draw
// area.
behaviors: [
new charts.ChartTitle('Top title text',
subTitle: 'Top sub-title text',
behaviorPosition: charts.BehaviorPosition.top,
titleOutsideJustification: charts.OutsideJustification.start,
// Set a larger inner padding than the default (10) to avoid
// rendering the text too close to the top measure axis tick label.
// The top tick label may extend upwards into the top margin region
// if it is located at the top of the draw area.
innerPadding: 18),
new charts.ChartTitle('Bottom title text',
behaviorPosition: charts.BehaviorPosition.bottom,
titleOutsideJustification:
charts.OutsideJustification.middleDrawArea),
new charts.ChartTitle('Start title',
behaviorPosition: charts.BehaviorPosition.start,
titleOutsideJustification:
charts.OutsideJustification.middleDrawArea),
new charts.ChartTitle('End title',
behaviorPosition: charts.BehaviorPosition.end,
titleOutsideJustification:
charts.OutsideJustification.middleDrawArea),
],
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,175 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of initial hint animation behavior.
///
/// To see the animation, please run the example app and select
/// "Initial hint animation".
///
/// This behavior is intended to be used with charts that also have pan/zoom
/// behaviors added and/or the initial viewport set in [AxisSpec].
///
/// Adding this behavior will cause the chart to animate from a scale and/or
/// offset of the desired final viewport. If the user taps the widget prior
/// to the animation being completed, animation will stop.
///
/// [maxHintScaleFactor] is the amount the domain axis will be scaled at the
/// start of te hint. By default, this is null, indicating that there will be
/// no scale factor hint. A value of 1.0 means the viewport is showing all
/// domains in the viewport. If a value is provided, it cannot be less than 1.0.
///
/// [maxHintTranslate] is the amount of ordinal values to translate the viewport
/// from the desired initial viewport. Currently only works for ordinal axis.
///
/// In this example, the series list has ordinal data from year 2014 to 2030,
/// and we have the initial viewport set to start at 2018 that shows 4 values by
/// specifying an [OrdinalViewport] in [OrdinalAxisSpec]. We can add the hint
/// animation by adding behavior [InitialHintBehavior] with [maxHintTranslate]
/// of 4. When the chart is drawn for the first time, the viewport will show
/// 2022 as the first value and the viewport will animate by panning values to
/// the right until 2018 is the first value in the viewport.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class InitialHintAnimation extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
InitialHintAnimation(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory InitialHintAnimation.withSampleData() {
return new InitialHintAnimation(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory InitialHintAnimation.withRandomData() {
return new InitialHintAnimation(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
new OrdinalSales('2018', random.nextInt(100)),
new OrdinalSales('2019', random.nextInt(100)),
new OrdinalSales('2020', random.nextInt(100)),
new OrdinalSales('2021', random.nextInt(100)),
new OrdinalSales('2022', random.nextInt(100)),
new OrdinalSales('2023', random.nextInt(100)),
new OrdinalSales('2024', random.nextInt(100)),
new OrdinalSales('2025', random.nextInt(100)),
new OrdinalSales('2026', random.nextInt(100)),
new OrdinalSales('2027', random.nextInt(100)),
new OrdinalSales('2028', random.nextInt(100)),
new OrdinalSales('2029', random.nextInt(100)),
new OrdinalSales('2030', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
// Optionally turn off the animation that animates values up from the
// bottom of the domain axis. If animation is on, the bars will animate up
// and then animate to the final viewport.
animationDuration: Duration.zero,
// Set the initial viewport by providing a new AxisSpec with the
// desired viewport: a starting domain and the data size.
domainAxis: new charts.OrdinalAxisSpec(
viewport: new charts.OrdinalViewport('2018', 4)),
behaviors: [
// Add this behavior to show initial hint animation that will pan to the
// final desired viewport.
// The duration of the animation can be adjusted by pass in
// [hintDuration]. By default this is 3000ms.
new charts.InitialHintBehavior(maxHintTranslate: 4.0),
// Optionally add a pan or pan and zoom behavior.
// If pan/zoom is not added, the viewport specified remains the viewport
new charts.PanAndZoomBehavior(),
],
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
new OrdinalSales('2018', 33),
new OrdinalSales('2019', 80),
new OrdinalSales('2020', 21),
new OrdinalSales('2021', 77),
new OrdinalSales('2022', 8),
new OrdinalSales('2023', 12),
new OrdinalSales('2024', 42),
new OrdinalSales('2025', 70),
new OrdinalSales('2026', 77),
new OrdinalSales('2027', 55),
new OrdinalSales('2028', 19),
new OrdinalSales('2029', 66),
new OrdinalSales('2030', 27),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,129 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of adding an initial selection behavior.
///
/// This example adds initial selection to a bar chart, but any chart can use
/// the initial selection behavior.
///
/// Initial selection is only set on the very first draw and will not be set
/// again in subsequent draws unless the behavior is reconfigured.
///
/// The selection will remain on the chart unless another behavior is added
/// that updates the selection.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class InitialSelection extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
InitialSelection(this.seriesList, {this.animate});
/// Creates a [BarChart] with initial selection behavior.
factory InitialSelection.withSampleData() {
return new InitialSelection(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory InitialSelection.withRandomData() {
return new InitialSelection(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
behaviors: [
// Initial selection can be configured by passing in:
//
// A list of datum config, specified with series ID and domain value.
// A list of series config, which is a list of series ID(s).
//
// Initial selection can be applied to any chart type.
//
// [BarChart] by default includes behaviors [SelectNearest] and
// [DomainHighlighter]. So this behavior shows the initial selection
// highlighted and when another datum is tapped, the selection changes.
new charts.InitialSelection(selectedDataConfig: [
new charts.SeriesDatumConfig<String>('Sales', '2016')
])
],
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,167 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a percentage bar chart with stacked series oriented vertically.
///
/// Each bar stack shows the percentage of each measure out of the total measure
/// value of the stack.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class PercentOfDomainBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
PercentOfDomainBarChart(this.seriesList, {this.animate});
/// Creates a stacked [BarChart] with sample data and no transition.
factory PercentOfDomainBarChart.withSampleData() {
return new PercentOfDomainBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory PercentOfDomainBarChart.withRandomData() {
return new PercentOfDomainBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.stacked,
// Configures a [PercentInjector] behavior that will calculate measure
// values as the percentage of the total of all data that shares a
// domain value.
behaviors: [
new charts.PercentInjector(
totalType: charts.PercentInjectorTotalType.domain)
],
// Configure the axis spec to show percentage values.
primaryMeasureAxis: new charts.PercentAxisSpec(),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,261 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a percentage bar chart with grouped, stacked series oriented
/// vertically.
///
/// Each bar stack shows the percentage of each measure out of the total measure
/// value of the stack.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class PercentOfDomainByCategoryBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
PercentOfDomainByCategoryBarChart(this.seriesList, {this.animate});
factory PercentOfDomainByCategoryBarChart.withSampleData() {
return new PercentOfDomainByCategoryBarChart(
createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory PercentOfDomainByCategoryBarChart.withRandomData() {
return new PercentOfDomainByCategoryBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesDataA = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final desktopSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesDataB = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataB,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.groupedStacked,
// Configures a [PercentInjector] behavior that will calculate measure
// values as the percentage of the total of all data that shares both a
// domain and a series category.
//
// We use this option on a grouped stacked bar chart to ensure that the
// total value for each bar stack is 100%. A stacked bar chart that does
// not group by series category would use the "domain" option.
behaviors: [
new charts.PercentInjector(
totalType: charts.PercentInjectorTotalType.domainBySeriesCategory)
],
// Configure the axis spec to show percentage values.
primaryMeasureAxis: new charts.PercentAxisSpec(),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> createSampleData() {
final desktopSalesDataA = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesDataA = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesDataA = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final desktopSalesDataB = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesDataB = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesDataB = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile A',
seriesCategory: 'A',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataA,
),
new charts.Series<OrdinalSales, String>(
id: 'Desktop B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesDataB,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile B',
seriesCategory: 'B',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesDataB,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,120 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a percentage bar chart which shows each bar as the percentage of
/// the total series measure value.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class PercentOfSeriesBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
PercentOfSeriesBarChart(this.seriesList, {this.animate});
/// Creates a stacked [BarChart] with sample data and no transition.
factory PercentOfSeriesBarChart.withSampleData() {
return new PercentOfSeriesBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory PercentOfSeriesBarChart.withRandomData() {
return new PercentOfSeriesBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
// Configures a [PercentInjector] behavior that will calculate measure
// values as the percentage of the total of all data in its series.
behaviors: [
new charts.PercentInjector(
totalType: charts.PercentInjectorTotalType.series)
],
// Configure the axis spec to show percentage values.
primaryMeasureAxis: new charts.PercentAxisSpec(),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2011', 5),
new OrdinalSales('2012', 25),
new OrdinalSales('2013', 50),
new OrdinalSales('2014', 75),
new OrdinalSales('2015', 100),
new OrdinalSales('2016', 125),
new OrdinalSales('2017', 200),
new OrdinalSales('2018', 150),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,110 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SelectionBarHighlight extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SelectionBarHighlight(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory SelectionBarHighlight.withSampleData() {
return new SelectionBarHighlight(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SelectionBarHighlight.withRandomData() {
return new SelectionBarHighlight(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// This is just a simple bar chart with optional property
// [defaultInteractions] set to true to include the default
// interactions/behaviors when building the chart.
// This includes bar highlighting.
//
// Note: defaultInteractions defaults to true.
//
// [defaultInteractions] can be set to false to avoid the default
// interactions.
return new charts.BarChart(
seriesList,
animate: animate,
defaultInteractions: true,
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,201 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Timeseries chart with example of updating external state based on selection.
///
/// A SelectionModelConfig can be provided for each of the different
/// [SelectionModel] (currently info and action).
///
/// [SelectionModelType.info] is the default selection chart exploration type
/// initiated by some tap event. This is a different model from
/// [SelectionModelType.action] which is typically used to select some value as
/// an input to some other UI component. This allows dual state of exploring
/// and selecting data via different touch events.
///
/// See [SelectNearest] behavior on setting the different ways of triggering
/// [SelectionModel] updates from hover & click events.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SelectionCallbackExample extends StatefulWidget {
final List<charts.Series> seriesList;
final bool animate;
SelectionCallbackExample(this.seriesList, {this.animate});
/// Creates a [charts.TimeSeriesChart] with sample data and no transition.
factory SelectionCallbackExample.withSampleData() {
return new SelectionCallbackExample(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SelectionCallbackExample.withRandomData() {
return new SelectionCallbackExample(_createRandomData());
}
/// Create random data.
static List<charts.Series<TimeSeriesSales, DateTime>> _createRandomData() {
final random = new Random();
final us_data = [
new TimeSeriesSales(new DateTime(2017, 9, 19), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 9, 26), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 10, 3), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 10, 10), random.nextInt(100)),
];
final uk_data = [
new TimeSeriesSales(new DateTime(2017, 9, 19), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 9, 26), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 10, 3), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 10, 10), random.nextInt(100)),
];
return [
new charts.Series<TimeSeriesSales, DateTime>(
id: 'US Sales',
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: us_data,
),
new charts.Series<TimeSeriesSales, DateTime>(
id: 'UK Sales',
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: uk_data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
// We need a Stateful widget to build the selection details with the current
// selection as the state.
@override
State<StatefulWidget> createState() => new _SelectionCallbackState();
/// Create one series with sample hard coded data.
static List<charts.Series<TimeSeriesSales, DateTime>> _createSampleData() {
final us_data = [
new TimeSeriesSales(new DateTime(2017, 9, 19), 5),
new TimeSeriesSales(new DateTime(2017, 9, 26), 25),
new TimeSeriesSales(new DateTime(2017, 10, 3), 78),
new TimeSeriesSales(new DateTime(2017, 10, 10), 54),
];
final uk_data = [
new TimeSeriesSales(new DateTime(2017, 9, 19), 15),
new TimeSeriesSales(new DateTime(2017, 9, 26), 33),
new TimeSeriesSales(new DateTime(2017, 10, 3), 68),
new TimeSeriesSales(new DateTime(2017, 10, 10), 48),
];
return [
new charts.Series<TimeSeriesSales, DateTime>(
id: 'US Sales',
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: us_data,
),
new charts.Series<TimeSeriesSales, DateTime>(
id: 'UK Sales',
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: uk_data,
)
];
}
}
class _SelectionCallbackState extends State<SelectionCallbackExample> {
DateTime _time;
Map<String, num> _measures;
// Listens to the underlying selection changes, and updates the information
// relevant to building the primitive legend like information under the
// chart.
_onSelectionChanged(charts.SelectionModel model) {
final selectedDatum = model.selectedDatum;
DateTime time;
final measures = <String, num>{};
// We get the model that updated with a list of [SeriesDatum] which is
// simply a pair of series & datum.
//
// Walk the selection updating the measures map, storing off the sales and
// series name for each selection point.
if (selectedDatum.isNotEmpty) {
time = selectedDatum.first.datum.time;
selectedDatum.forEach((charts.SeriesDatum datumPair) {
measures[datumPair.series.displayName] = datumPair.datum.sales;
});
}
// Request a build.
setState(() {
_time = time;
_measures = measures;
});
}
@override
Widget build(BuildContext context) {
// The children consist of a Chart and Text widgets below to hold the info.
final children = <Widget>[
new SizedBox(
height: 150.0,
child: new charts.TimeSeriesChart(
widget.seriesList,
animate: widget.animate,
selectionModels: [
new charts.SelectionModelConfig(
type: charts.SelectionModelType.info,
changedListener: _onSelectionChanged,
)
],
)),
];
// If there is a selection, then include the details.
if (_time != null) {
children.add(new Padding(
padding: new EdgeInsets.only(top: 5.0),
child: new Text(_time.toString())));
}
_measures?.forEach((String series, num value) {
children.add(new Text('${series}: ${value}'));
});
return new Column(children: children);
}
}
/// Sample time series data type.
class TimeSeriesSales {
final DateTime time;
final int sales;
TimeSeriesSales(this.time, this.sales);
}

View File

@@ -0,0 +1,127 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SelectionLineHighlight extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SelectionLineHighlight(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory SelectionLineHighlight.withSampleData() {
return new SelectionLineHighlight(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SelectionLineHighlight.withRandomData() {
return new SelectionLineHighlight(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// This is just a simple line chart with a behavior that highlights the
// selected points along the lines. A point will be drawn at the selected
// datum's x,y coordinate, and a vertical follow line will be drawn through
// it.
//
// A [Charts.LinePointHighlighter] behavior is added manually to enable the
// highlighting effect.
//
// As an alternative, [defaultInteractions] can be set to true to include
// the default chart interactions, including a LinePointHighlighter.
return new charts.LineChart(seriesList, animate: animate, behaviors: [
// Optional - Configures a [LinePointHighlighter] behavior with a
// vertical follow line. A vertical follow line is included by
// default, but is shown here as an example configuration.
//
// By default, the line has default dash pattern of [1,3]. This can be
// set by providing a [dashPattern] or it can be turned off by passing in
// an empty list. An empty list is necessary because passing in a null
// value will be treated the same as not passing in a value at all.
new charts.LinePointHighlighter(
showHorizontalFollowLine:
charts.LinePointHighlighterFollowLineType.none,
showVerticalFollowLine:
charts.LinePointHighlighterFollowLineType.nearest),
// Optional - By default, select nearest is configured to trigger
// with tap so that a user can have pan/zoom behavior and line point
// highlighter. Changing the trigger to tap and drag allows the
// highlighter to follow the dragging gesture but it is not
// recommended to be used when pan/zoom behavior is enabled.
new charts.SelectNearest(eventTrigger: charts.SelectionTrigger.tapAndDrag)
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,130 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SelectionLineHighlightCustomShape extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SelectionLineHighlightCustomShape(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory SelectionLineHighlightCustomShape.withSampleData() {
return new SelectionLineHighlightCustomShape(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SelectionLineHighlightCustomShape.withRandomData() {
return new SelectionLineHighlightCustomShape(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// This is a simple line chart with a behavior that highlights hovered
// lines. A hollow rectangular shape will be drawn at the hovered datum's
// x,y coordinate, and a vertical follow line will be drawn through it.
//
// A [Charts.LinePointHighlighter] behavior is added manually to enable the
// highlighting effect.
//
// As an alternative, [defaultInteractions] can be set to true to include
// the default chart interactions, including a LinePointHighlighter.
return new charts.LineChart(seriesList, animate: animate, behaviors: [
// Optional - Configures a [LinePointHighlighter] behavior with a
// vertical follow line. A vertical follow line is included by
// default, but is shown here as an example configuration.
//
// By default, the line has default dash pattern of [1,3]. This can be
// set by providing a [dashPattern] or it can be turned off by passing in
// an empty list. An empty list is necessary because passing in a null
// value will be treated the same as not passing in a value at all.
//
// The symbol renderer is configured to render a hollow shape, for
// demonstration.
new charts.LinePointHighlighter(
showHorizontalFollowLine:
charts.LinePointHighlighterFollowLineType.none,
showVerticalFollowLine:
charts.LinePointHighlighterFollowLineType.nearest,
symbolRenderer: new charts.RectSymbolRenderer(isSolid: false)),
// Optional - By default, select nearest is configured to trigger
// with tap so that a user can have pan/zoom behavior and line point
// highlighter. Changing the trigger to tap and drag allows the
// highlighter to follow the dragging gesture but it is not
// recommended to be used when pan/zoom behavior is enabled.
new charts.SelectNearest(eventTrigger: charts.SelectionTrigger.tapAndDrag)
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,235 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a scatter plot chart using custom symbols for the points and a
/// behavior that highlights selected points.
///
/// An optional [charts.LinePointHighlighter] behavior has been added to enable
/// a highlighting effect. This behavior will draw a larger symbol on top of the
/// point nearest to the point where a user taps on the chart. It will also draw
/// follow lines.
///
/// The series has been configured to draw each point as a square by default.
///
/// Some data will be drawn as a circle, indicated by defining a custom "circle"
/// value referenced by [charts.pointSymbolRendererFnKey].
///
/// Some other data have will be drawn as a hollow circle. In addition to the
/// custom renderer key, these data also have stroke and fillColor values
/// defined. Configuring a separate fillColor will cause the center of the shape
/// to be filled in, with white in these examples. The border of the shape will
/// be color with the color of the data.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SelectionScatterPlotHighlight extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SelectionScatterPlotHighlight(this.seriesList, {this.animate});
/// Creates a [ScatterPlotChart] with sample data and no transition.
factory SelectionScatterPlotHighlight.withSampleData() {
return new SelectionScatterPlotHighlight(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SelectionScatterPlotHighlight.withRandomData() {
return new SelectionScatterPlotHighlight(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final makeRadius = (int value) => (random.nextInt(value) + 2).toDouble();
final data = [
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
'circle', null, null),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
null, null, null),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
null, null, null),
// Render a hollow circle, filled in with white.
new LinearSales(random.nextInt(100), random.nextInt(100),
makeRadius(4) + 4, 'circle', charts.MaterialPalette.white, 2.0),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
null, null, null),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
null, null, null),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
'circle', null, null),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
null, null, null),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
null, null, null),
// Render a hollow circle, filled in with white.
new LinearSales(random.nextInt(100), random.nextInt(100),
makeRadius(4) + 4, 'circle', charts.MaterialPalette.white, 2.0),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6),
null, null, null),
// Render a hollow square, filled in with white.
new LinearSales(random.nextInt(100), random.nextInt(100),
makeRadius(4) + 4, null, charts.MaterialPalette.white, 2.0),
];
final maxMeasure = 100;
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
colorFn: (LinearSales sales, _) {
// Color bucket the measure column value into 3 distinct colors.
final bucket = sales.sales / maxMeasure;
if (bucket < 1 / 3) {
return charts.MaterialPalette.blue.shadeDefault;
} else if (bucket < 2 / 3) {
return charts.MaterialPalette.red.shadeDefault;
} else {
return charts.MaterialPalette.green.shadeDefault;
}
},
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
radiusPxFn: (LinearSales sales, _) => sales.radius,
fillColorFn: (LinearSales row, _) => row.fillColor,
strokeWidthPxFn: (LinearSales row, _) => row.strokeWidth,
data: data,
)
// Accessor function that associates each datum with a symbol renderer.
..setAttribute(
charts.pointSymbolRendererFnKey, (int index) => data[index].shape)
// Default symbol renderer ID for data that have no defined shape.
..setAttribute(charts.pointSymbolRendererIdKey, 'rect')
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.ScatterPlotChart(seriesList,
animate: animate,
behaviors: [
// Optional - Configures a [LinePointHighlighter] behavior with
// horizontal and vertical follow lines. The highlighter will increase
// the size of the selected points on the chart.
//
// By default, the line has default dash pattern of [1,3]. This can be
// set by providing a [dashPattern] or it can be turned off by passing
// in an empty list. An empty list is necessary because passing in a
// null value will be treated the same as not passing in a value at
// all.
new charts.LinePointHighlighter(
showHorizontalFollowLine:
charts.LinePointHighlighterFollowLineType.nearest,
showVerticalFollowLine:
charts.LinePointHighlighterFollowLineType.nearest),
// Optional - By default, select nearest is configured to trigger
// with tap so that a user can have pan/zoom behavior and line point
// highlighter. Changing the trigger to tap and drag allows the
// highlighter to follow the dragging gesture but it is not
// recommended to be used when pan/zoom behavior is enabled.
new charts.SelectNearest(
eventTrigger: charts.SelectionTrigger.tapAndDrag),
],
// Configure the point renderer to have a map of custom symbol
// renderers.
defaultRenderer:
new charts.PointRendererConfig<num>(customSymbolRenderers: {
'circle': new charts.CircleSymbolRenderer(),
'rect': new charts.RectSymbolRenderer(),
}));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5, 3.0, 'circle', null, null),
new LinearSales(10, 25, 5.0, null, null, null),
new LinearSales(12, 75, 4.0, null, null, null),
// Render a hollow circle, filled in with white.
new LinearSales(
13, 225, 5.0, 'circle', charts.MaterialPalette.white, 2.0),
new LinearSales(16, 50, 4.0, null, null, null),
new LinearSales(24, 75, 3.0, null, null, null),
new LinearSales(25, 100, 3.0, 'circle', null, null),
new LinearSales(34, 150, 5.0, null, null, null),
new LinearSales(37, 10, 4.5, null, null, null),
// Render a hollow circle, filled in with white.
new LinearSales(
45, 300, 8.0, 'circle', charts.MaterialPalette.white, 2.0),
new LinearSales(52, 15, 4.0, null, null, null),
// Render a hollow square, filled in with white.
new LinearSales(56, 200, 7.0, null, charts.MaterialPalette.white, 2.0),
];
final maxMeasure = 300;
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
// Providing a color function is optional.
colorFn: (LinearSales sales, _) {
// Bucket the measure column value into 3 distinct colors.
final bucket = sales.sales / maxMeasure;
if (bucket < 1 / 3) {
return charts.MaterialPalette.blue.shadeDefault;
} else if (bucket < 2 / 3) {
return charts.MaterialPalette.red.shadeDefault;
} else {
return charts.MaterialPalette.green.shadeDefault;
}
},
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
radiusPxFn: (LinearSales sales, _) => sales.radius,
fillColorFn: (LinearSales row, _) => row.fillColor,
strokeWidthPxFn: (LinearSales row, _) => row.strokeWidth,
data: data,
)
// Accessor function that associates each datum with a symbol renderer.
..setAttribute(
charts.pointSymbolRendererFnKey, (int index) => data[index].shape)
// Default symbol renderer ID for data that have no defined shape.
..setAttribute(charts.pointSymbolRendererIdKey, 'rect')
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
final double radius;
final String shape;
final charts.Color fillColor;
final double strokeWidth;
LinearSales(this.year, this.sales, this.radius, this.shape, this.fillColor,
this.strokeWidth);
}

View File

@@ -0,0 +1,164 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of using user managed state to programmatically set selection.
///
/// In this example, clicking the "clear selection" button sets the selection
/// to an empty selection. This example also shows that initial selection
/// behavior can still be used with user managed state.
///
/// Note that the picture in this example is not interactive, please run the
/// gallery app to try out using the button to clear selection.
///
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SelectionUserManaged extends StatefulWidget {
final List<charts.Series> seriesList;
final bool animate;
SelectionUserManaged(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory SelectionUserManaged.withSampleData() {
return new SelectionUserManaged(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SelectionUserManaged.withRandomData() {
return new SelectionUserManaged(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
@override
SelectionUserManagedState createState() {
return new SelectionUserManagedState();
}
}
class SelectionUserManagedState extends State<SelectionUserManaged> {
final _myState = new charts.UserManagedState<String>();
@override
Widget build(BuildContext context) {
final chart = new charts.BarChart(
widget.seriesList,
animate: false, //widget.animate,
selectionModels: [
new charts.SelectionModelConfig(
type: charts.SelectionModelType.info,
updatedListener: _infoSelectionModelUpdated)
],
// Pass in the state you manage to the chart. This will be used to
// override the internal chart state.
userManagedState: _myState,
// The initial selection can still be optionally added by adding the
// initial selection behavior.
behaviors: [
new charts.InitialSelection(selectedDataConfig: [
new charts.SeriesDatumConfig<String>('Sales', '2016')
])
],
);
final clearSelection = new MaterialButton(
onPressed: _handleClearSelection, child: new Text('Clear Selection'));
return new Column(
children: [new SizedBox(child: chart, height: 150.0), clearSelection]);
}
void _infoSelectionModelUpdated(charts.SelectionModel<String> model) {
// If you want to allow the chart to continue to respond to select events
// that update the selection, add an updatedListener that saves off the
// selection model each time the selection model is updated, regardless of
// if there are changes.
//
// This also allows you to listen to the selection model update events and
// alter the selection.
_myState.selectionModels[charts.SelectionModelType.info] =
new charts.UserManagedSelectionModel(model: model);
}
void _handleClearSelection() {
// Call set state to request a rebuild, to pass in the modified selection.
// In this case, passing in an empty [UserManagedSelectionModel] creates a
// no selection model to clear all selection when rebuilt.
setState(() {
_myState.selectionModels[charts.SelectionModelType.info] =
new charts.UserManagedSelectionModel();
});
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,196 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
import 'package:flutter_web/rendering.dart';
import 'package:flutter_web/scheduler.dart';
/// This is just a simple line chart with a behavior that adds slider controls.
///
/// A [Slider] behavior is added manually to enable slider controls, with an
/// initial position at 1 along the domain axis.
///
/// An onChange event handler has been configured to demonstrate updating a div
/// with data from the slider's current position. An "initial" drag state event
/// will be fired when the chart is drawn because an initial domain value is
/// set.
///
/// [Slider.moveSliderToDomain] can be called to programmatically position the
/// slider. This is useful for synchronizing the slider with external elements.
class SliderLine extends StatefulWidget {
final List<charts.Series> seriesList;
final bool animate;
SliderLine(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory SliderLine.withSampleData() {
return new SliderLine(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SliderLine.withRandomData() {
return new SliderLine(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
// We need a Stateful widget to build the selection details with the current
// selection as the state.
@override
State<StatefulWidget> createState() => new _SliderCallbackState();
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
class _SliderCallbackState extends State<SliderLine> {
num _sliderDomainValue;
String _sliderDragState;
Point<int> _sliderPosition;
// Handles callbacks when the user drags the slider.
_onSliderChange(Point<int> point, dynamic domain, String roleId,
charts.SliderListenerDragState dragState) {
// Request a build.
void rebuild(_) {
setState(() {
_sliderDomainValue = (domain * 10).round() / 10;
_sliderDragState = dragState.toString();
_sliderPosition = point;
});
}
SchedulerBinding.instance.addPostFrameCallback(rebuild);
}
@override
Widget build(BuildContext context) {
// The children consist of a Chart and Text widgets below to hold the info.
final children = <Widget>[
new SizedBox(
height: 150.0,
child: new charts.LineChart(
widget.seriesList,
animate: widget.animate,
// Configures a [Slider] behavior.
//
// Available options include:
//
// [eventTrigger] configures the type of mouse gesture that controls
// the slider.
//
// [handleRenderer] draws a handle for the slider. Defaults to a
// rectangle.
//
// [initialDomainValue] sets the initial position of the slider in
// domain units. The default is the center of the chart.
//
// [onChangeCallback] will be called when the position of the slider
// changes during a drag event.
//
// [roleId] optional custom role ID for the slider. This can be used to
// allow multiple [Slider] behaviors on the same chart. Normally, there can
// only be one slider (per event trigger type) on a chart. This setting
// allows for configuring multiple independent sliders.
//
// [snapToDatum] configures the slider to snap snap onto the nearest
// datum (by domain distance) when dragged. By default, the slider
// can be positioned anywhere along the domain axis.
//
// [style] takes in a [SliderStyle] configuration object, and
// configures the color and sizing of the slider line and handle.
behaviors: [
new charts.Slider(
initialDomainValue: 1.0, onChangeCallback: _onSliderChange),
],
)),
];
// If there is a slider change event, then include the details.
if (_sliderDomainValue != null) {
children.add(new Padding(
padding: new EdgeInsets.only(top: 5.0),
child: new Text('Slider domain value: ${_sliderDomainValue}')));
}
if (_sliderPosition != null) {
children.add(new Padding(
padding: new EdgeInsets.only(top: 5.0),
child: new Text(
'Slider position: ${_sliderPosition.x}, ${_sliderPosition.y}')));
}
if (_sliderDragState != null) {
children.add(new Padding(
padding: new EdgeInsets.only(top: 5.0),
child: new Text('Slider drag state: ${_sliderDragState}')));
}
return new Column(children: children);
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,144 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of the chart behavior that centers the viewport on domain selection.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SlidingViewportOnSelection extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SlidingViewportOnSelection(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory SlidingViewportOnSelection.withSampleData() {
return new SlidingViewportOnSelection(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SlidingViewportOnSelection.withRandomData() {
return new SlidingViewportOnSelection(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
new OrdinalSales('2018', random.nextInt(100)),
new OrdinalSales('2019', random.nextInt(100)),
new OrdinalSales('2020', random.nextInt(100)),
new OrdinalSales('2021', random.nextInt(100)),
new OrdinalSales('2022', random.nextInt(100)),
new OrdinalSales('2023', random.nextInt(100)),
new OrdinalSales('2024', random.nextInt(100)),
new OrdinalSales('2025', random.nextInt(100)),
new OrdinalSales('2026', random.nextInt(100)),
new OrdinalSales('2027', random.nextInt(100)),
new OrdinalSales('2028', random.nextInt(100)),
new OrdinalSales('2029', random.nextInt(100)),
new OrdinalSales('2030', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
behaviors: [
// Add the sliding viewport behavior to have the viewport center on the
// domain that is currently selected.
new charts.SlidingViewport(),
// A pan and zoom behavior helps demonstrate the sliding viewport
// behavior by allowing the data visible in the viewport to be adjusted
// dynamically.
new charts.PanAndZoomBehavior(),
],
// Set an initial viewport to demonstrate the sliding viewport behavior on
// initial chart load.
domainAxis: new charts.OrdinalAxisSpec(
viewport: new charts.OrdinalViewport('2018', 4)),
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
new OrdinalSales('2018', 33),
new OrdinalSales('2019', 80),
new OrdinalSales('2020', 21),
new OrdinalSales('2021', 77),
new OrdinalSales('2022', 8),
new OrdinalSales('2023', 12),
new OrdinalSales('2024', 42),
new OrdinalSales('2025', 70),
new OrdinalSales('2026', 77),
new OrdinalSales('2027', 55),
new OrdinalSales('2028', 19),
new OrdinalSales('2029', 66),
new OrdinalSales('2030', 27),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,57 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'date_time_line_point.dart';
import 'numeric_line_bar.dart';
import 'numeric_line_point.dart';
import 'ordinal_bar_line.dart';
import 'scatter_plot_line.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Ordinal Combo Chart',
subtitle: 'Ordinal combo chart with bars and lines',
childBuilder: () => new OrdinalComboBarLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Numeric Line Bar Combo Chart',
subtitle: 'Numeric combo chart with lines and bars',
childBuilder: () => new NumericComboLineBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Numeric Line Points Combo Chart',
subtitle: 'Numeric combo chart with lines and points',
childBuilder: () => new NumericComboLinePointChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Time Series Combo Chart',
subtitle: 'Time series combo chart with lines and points',
childBuilder: () => new DateTimeComboLinePointChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.scatter_plot),
title: 'Scatter Plot Combo Chart',
subtitle: 'Scatter plot combo chart with a line',
childBuilder: () => new ScatterPlotComboLineChart.withRandomData(),
),
];
}

View File

@@ -0,0 +1,183 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a combo time series chart with two series rendered as lines, and
/// a third rendered as points along the top line with a different color.
///
/// This example demonstrates a method for drawing points along a line using a
/// different color from the main series color. The line renderer supports
/// drawing points with the "includePoints" option, but those points will share
/// the same color as the line.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class DateTimeComboLinePointChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DateTimeComboLinePointChart(this.seriesList, {this.animate});
/// Creates a [TimeSeriesChart] with sample data and no transition.
factory DateTimeComboLinePointChart.withSampleData() {
return new DateTimeComboLinePointChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DateTimeComboLinePointChart.withRandomData() {
return new DateTimeComboLinePointChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<TimeSeriesSales, DateTime>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new TimeSeriesSales(new DateTime(2017, 9, 19), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 9, 26), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 10, 3), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 10, 10), random.nextInt(100)),
];
final tableSalesData = [
new TimeSeriesSales(new DateTime(2017, 9, 19), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 9, 26), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 10, 3), random.nextInt(100)),
new TimeSeriesSales(new DateTime(2017, 10, 10), random.nextInt(100)),
];
final mobileSalesData = [
new TimeSeriesSales(new DateTime(2017, 9, 19), tableSalesData[0].sales),
new TimeSeriesSales(new DateTime(2017, 9, 26), tableSalesData[1].sales),
new TimeSeriesSales(new DateTime(2017, 10, 3), tableSalesData[2].sales),
new TimeSeriesSales(new DateTime(2017, 10, 10), tableSalesData[3].sales),
];
return [
new charts.Series<TimeSeriesSales, DateTime>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<TimeSeriesSales, DateTime>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<TimeSeriesSales, DateTime>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: mobileSalesData)
// Configure our custom point renderer for this series.
..setAttribute(charts.rendererIdKey, 'customPoint'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.TimeSeriesChart(
seriesList,
animate: animate,
// Configure the default renderer as a line renderer. This will be used
// for any series that does not define a rendererIdKey.
//
// This is the default configuration, but is shown here for illustration.
defaultRenderer: new charts.LineRendererConfig(),
// Custom renderer configuration for the point series.
customSeriesRenderers: [
new charts.PointRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customPoint')
],
// Optionally pass in a [DateTimeFactory] used by the chart. The factory
// should create the same type of [DateTime] as the data provided. If none
// specified, the default creates local date time.
dateTimeFactory: const charts.LocalDateTimeFactory(),
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<TimeSeriesSales, DateTime>> _createSampleData() {
final desktopSalesData = [
new TimeSeriesSales(new DateTime(2017, 9, 19), 5),
new TimeSeriesSales(new DateTime(2017, 9, 26), 25),
new TimeSeriesSales(new DateTime(2017, 10, 3), 100),
new TimeSeriesSales(new DateTime(2017, 10, 10), 75),
];
final tableSalesData = [
new TimeSeriesSales(new DateTime(2017, 9, 19), 10),
new TimeSeriesSales(new DateTime(2017, 9, 26), 50),
new TimeSeriesSales(new DateTime(2017, 10, 3), 200),
new TimeSeriesSales(new DateTime(2017, 10, 10), 150),
];
final mobileSalesData = [
new TimeSeriesSales(new DateTime(2017, 9, 19), 10),
new TimeSeriesSales(new DateTime(2017, 9, 26), 50),
new TimeSeriesSales(new DateTime(2017, 10, 3), 200),
new TimeSeriesSales(new DateTime(2017, 10, 10), 150),
];
return [
new charts.Series<TimeSeriesSales, DateTime>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<TimeSeriesSales, DateTime>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<TimeSeriesSales, DateTime>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (TimeSeriesSales sales, _) => sales.time,
measureFn: (TimeSeriesSales sales, _) => sales.sales,
data: mobileSalesData)
// Configure our custom point renderer for this series.
..setAttribute(charts.rendererIdKey, 'customPoint'),
];
}
}
/// Sample time series data type.
class TimeSeriesSales {
final DateTime time;
final int sales;
TimeSeriesSales(this.time, this.sales);
}

View File

@@ -0,0 +1,174 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a numeric combo chart with two series rendered as bars, and a
/// third rendered as a line.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class NumericComboLineBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
NumericComboLineBarChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory NumericComboLineBarChart.withSampleData() {
return new NumericComboLineBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory NumericComboLineBarChart.withRandomData() {
return new NumericComboLineBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
final tableSalesData = [
new LinearSales(0, desktopSalesData[0].sales),
new LinearSales(1, desktopSalesData[1].sales),
new LinearSales(2, desktopSalesData[2].sales),
new LinearSales(3, desktopSalesData[3].sales),
];
final mobileSalesData = [
new LinearSales(0, tableSalesData[0].sales * 2),
new LinearSales(1, tableSalesData[1].sales * 2),
new LinearSales(2, tableSalesData[2].sales * 2),
new LinearSales(3, tableSalesData[3].sales * 2),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: desktopSalesData,
)
// Configure our custom bar renderer for this series.
..setAttribute(charts.rendererIdKey, 'customBar'),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: tableSalesData,
)
// Configure our custom bar renderer for this series.
..setAttribute(charts.rendererIdKey, 'customBar'),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: mobileSalesData),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.NumericComboChart(seriesList,
animate: animate,
// Configure the default renderer as a line renderer. This will be used
// for any series that does not define a rendererIdKey.
defaultRenderer: new charts.LineRendererConfig(),
// Custom renderer configuration for the bar series.
customSeriesRenderers: [
new charts.BarRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customBar')
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final desktopSalesData = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
final tableSalesData = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
final mobileSalesData = [
new LinearSales(0, 10),
new LinearSales(1, 50),
new LinearSales(2, 200),
new LinearSales(3, 150),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: desktopSalesData,
)
// Configure our custom bar renderer for this series.
..setAttribute(charts.rendererIdKey, 'customBar'),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: tableSalesData,
)
// Configure our custom bar renderer for this series.
..setAttribute(charts.rendererIdKey, 'customBar'),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: mobileSalesData),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,175 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a numeric combo chart with two series rendered as lines, and a
/// third rendered as points along the top line with a different color.
///
/// This example demonstrates a method for drawing points along a line using a
/// different color from the main series color. The line renderer supports
/// drawing points with the "includePoints" option, but those points will share
/// the same color as the line.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class NumericComboLinePointChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
NumericComboLinePointChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory NumericComboLinePointChart.withSampleData() {
return new NumericComboLinePointChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory NumericComboLinePointChart.withRandomData() {
return new NumericComboLinePointChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
final tableSalesData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
final mobileSalesData = [
new LinearSales(0, tableSalesData[0].sales),
new LinearSales(1, tableSalesData[1].sales),
new LinearSales(2, tableSalesData[2].sales),
new LinearSales(3, tableSalesData[3].sales),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: mobileSalesData)
// Configure our custom point renderer for this series.
..setAttribute(charts.rendererIdKey, 'customPoint'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.NumericComboChart(seriesList,
animate: animate,
// Configure the default renderer as a line renderer. This will be used
// for any series that does not define a rendererIdKey.
defaultRenderer: new charts.LineRendererConfig(),
// Custom renderer configuration for the point series.
customSeriesRenderers: [
new charts.PointRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customPoint')
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final desktopSalesData = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
final tableSalesData = [
new LinearSales(0, 10),
new LinearSales(1, 50),
new LinearSales(2, 200),
new LinearSales(3, 150),
];
final mobileSalesData = [
new LinearSales(0, 10),
new LinearSales(1, 50),
new LinearSales(2, 200),
new LinearSales(3, 150),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: tableSalesData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: mobileSalesData)
// Configure our custom point renderer for this series.
..setAttribute(charts.rendererIdKey, 'customPoint'),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,166 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of an ordinal combo chart with two series rendered as bars, and a
/// third rendered as a line.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class OrdinalComboBarLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
OrdinalComboBarLineChart(this.seriesList, {this.animate});
factory OrdinalComboBarLineChart.withSampleData() {
return new OrdinalComboBarLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory OrdinalComboBarLineChart.withRandomData() {
return new OrdinalComboBarLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tableSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData)
// Configure our custom line renderer for this series.
..setAttribute(charts.rendererIdKey, 'customLine'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.OrdinalComboChart(seriesList,
animate: animate,
// Configure the default renderer as a bar renderer.
defaultRenderer: new charts.BarRendererConfig(
groupingType: charts.BarGroupingType.grouped),
// Custom renderer configuration for the line series. This will be used for
// any series that does not define a rendererIdKey.
customSeriesRenderers: [
new charts.LineRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customLine')
]);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tableSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 200),
new OrdinalSales('2017', 150),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tableSalesData),
new charts.Series<OrdinalSales, String>(
id: 'Mobile ',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData)
// Configure our custom line renderer for this series.
..setAttribute(charts.rendererIdKey, 'customLine'),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,198 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a combo scatter plot chart with a second series rendered as a
/// line.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class ScatterPlotComboLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
ScatterPlotComboLineChart(this.seriesList, {this.animate});
/// Creates a [ScatterPlotChart] with sample data and no transition.
factory ScatterPlotComboLineChart.withSampleData() {
return new ScatterPlotComboLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory ScatterPlotComboLineChart.withRandomData() {
return new ScatterPlotComboLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final makeRadius = (int value) => (random.nextInt(value) + 2).toDouble();
final desktopSalesData = [
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
new LinearSales(random.nextInt(100), random.nextInt(100), makeRadius(6)),
];
var myRegressionData = [
new LinearSales(0, desktopSalesData[0].sales, 3.5),
new LinearSales(
100, desktopSalesData[desktopSalesData.length - 1].sales, 7.5),
];
final maxMeasure = 100;
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
// Providing a color function is optional.
colorFn: (LinearSales sales, _) {
// Bucket the measure column value into 3 distinct colors.
final bucket = sales.sales / maxMeasure;
if (bucket < 1 / 3) {
return charts.MaterialPalette.blue.shadeDefault;
} else if (bucket < 2 / 3) {
return charts.MaterialPalette.red.shadeDefault;
} else {
return charts.MaterialPalette.green.shadeDefault;
}
},
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
// Providing a radius function is optional.
radiusPxFn: (LinearSales sales, _) => sales.radius,
data: desktopSalesData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.purple.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myRegressionData)
// Configure our custom line renderer for this series.
..setAttribute(charts.rendererIdKey, 'customLine'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.ScatterPlotChart(seriesList,
animate: animate,
// Configure the default renderer as a point renderer. This will be used
// for any series that does not define a rendererIdKey.
//
// This is the default configuration, but is shown here for
// illustration.
defaultRenderer: new charts.PointRendererConfig(),
// Custom renderer configuration for the line series.
customSeriesRenderers: [
new charts.LineRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customLine',
// Configure the regression line to be painted above the points.
//
// By default, series drawn by the point renderer are painted on
// top of those drawn by a line renderer.
layoutPaintOrder: charts.LayoutViewPaintOrder.point + 1)
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final desktopSalesData = [
new LinearSales(0, 5, 3.0),
new LinearSales(10, 25, 5.0),
new LinearSales(12, 75, 4.0),
new LinearSales(13, 225, 5.0),
new LinearSales(16, 50, 4.0),
new LinearSales(24, 75, 3.0),
new LinearSales(25, 100, 3.0),
new LinearSales(34, 150, 5.0),
new LinearSales(37, 10, 4.5),
new LinearSales(45, 300, 8.0),
new LinearSales(52, 15, 4.0),
new LinearSales(56, 200, 7.0),
];
var myRegressionData = [
new LinearSales(0, 5, 3.5),
new LinearSales(56, 240, 3.5),
];
final maxMeasure = 300;
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
// Providing a color function is optional.
colorFn: (LinearSales sales, _) {
// Bucket the measure column value into 3 distinct colors.
final bucket = sales.sales / maxMeasure;
if (bucket < 1 / 3) {
return charts.MaterialPalette.blue.shadeDefault;
} else if (bucket < 2 / 3) {
return charts.MaterialPalette.red.shadeDefault;
} else {
return charts.MaterialPalette.green.shadeDefault;
}
},
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
// Providing a radius function is optional.
radiusPxFn: (LinearSales sales, _) => sales.radius,
data: desktopSalesData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.purple.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myRegressionData)
// Configure our custom line renderer for this series.
..setAttribute(charts.rendererIdKey, 'customLine'),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
final double radius;
LinearSales(this.year, this.sales, this.radius);
}

View File

@@ -0,0 +1,51 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
/// A menu drawer supporting toggling theme and performance overlay.
class GalleryDrawer extends StatelessWidget {
final bool showPerformanceOverlay;
final ValueChanged<bool> onShowPerformanceOverlayChanged;
GalleryDrawer(
{Key key,
this.showPerformanceOverlay,
this.onShowPerformanceOverlayChanged})
: super(key: key);
@override
Widget build(BuildContext context) {
return new Drawer(
child: new ListView(children: <Widget>[
// Performance overlay toggle.
new ListTile(
leading: new Icon(Icons.assessment),
title: new Text('Performance Overlay'),
onTap: () {
onShowPerformanceOverlayChanged(!showPerformanceOverlay);
},
selected: showPerformanceOverlay,
trailing: new Checkbox(
value: showPerformanceOverlay,
onChanged: (bool value) {
onShowPerformanceOverlayChanged(!showPerformanceOverlay);
},
),
),
]),
);
}
}

View File

@@ -0,0 +1,62 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
typedef Widget GalleryWidgetBuilder();
/// Helper to build gallery.
class GalleryScaffold extends StatefulWidget {
/// The widget used for leading in a [ListTile].
final Widget listTileIcon;
final String title;
final String subtitle;
final GalleryWidgetBuilder childBuilder;
GalleryScaffold(
{this.listTileIcon, this.title, this.subtitle, this.childBuilder});
/// Gets the gallery
Widget buildGalleryListTile(BuildContext context) => new ListTile(
leading: listTileIcon,
title: new Text(title),
subtitle: new Text(subtitle),
onTap: () {
Navigator.push(context, new MaterialPageRoute(builder: (_) => this));
});
@override
_GalleryScaffoldState createState() => new _GalleryScaffoldState();
}
class _GalleryScaffoldState extends State<GalleryScaffold> {
void _handleButtonPress() {
setState(() {});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text(widget.title)),
body: new Padding(
padding: const EdgeInsets.all(8.0),
child: new Column(children: <Widget>[
new SizedBox(height: 250.0, child: widget.childBuilder()),
])),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.refresh), onPressed: _handleButtonPress),
);
}
}

View File

@@ -0,0 +1,127 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
import 'dart:developer';
import 'app_config.dart';
import 'drawer.dart';
import 'a11y/a11y_gallery.dart' as a11y show buildGallery;
import 'bar_chart/bar_gallery.dart' as bar show buildGallery;
import 'time_series_chart/time_series_gallery.dart' as time_series
show buildGallery;
import 'line_chart/line_gallery.dart' as line show buildGallery;
import 'scatter_plot_chart/scatter_plot_gallery.dart' as scatter_plot
show buildGallery;
import 'combo_chart/combo_gallery.dart' as combo show buildGallery;
import 'pie_chart/pie_gallery.dart' as pie show buildGallery;
import 'axes/axes_gallery.dart' as axes show buildGallery;
import 'behaviors/behaviors_gallery.dart' as behaviors show buildGallery;
import 'i18n/i18n_gallery.dart' as i18n show buildGallery;
import 'legends/legends_gallery.dart' as legends show buildGallery;
/// Main entry point of the gallery app.
///
/// This renders a list of all available demos.
class Home extends StatelessWidget {
final bool showPerformanceOverlay;
final ValueChanged<bool> onShowPerformanceOverlayChanged;
final a11yGalleries = a11y.buildGallery();
final barGalleries = bar.buildGallery();
final timeSeriesGalleries = time_series.buildGallery();
final lineGalleries = line.buildGallery();
final scatterPlotGalleries = scatter_plot.buildGallery();
final comboGalleries = combo.buildGallery();
final pieGalleries = pie.buildGallery();
final axesGalleries = axes.buildGallery();
final behaviorsGalleries = behaviors.buildGallery();
final i18nGalleries = i18n.buildGallery();
final legendsGalleries = legends.buildGallery();
Home(
{Key key,
this.showPerformanceOverlay,
this.onShowPerformanceOverlayChanged})
: super(key: key) {
assert(onShowPerformanceOverlayChanged != null);
}
@override
Widget build(BuildContext context) {
var galleries = <Widget>[];
galleries.addAll(
a11yGalleries.map((gallery) => gallery.buildGalleryListTile(context)));
// Add example bar charts.
galleries.addAll(
barGalleries.map((gallery) => gallery.buildGalleryListTile(context)));
// Add example time series charts.
galleries.addAll(timeSeriesGalleries
.map((gallery) => gallery.buildGalleryListTile(context)));
// Add example line charts.
galleries.addAll(
lineGalleries.map((gallery) => gallery.buildGalleryListTile(context)));
// Add example scatter plot charts.
galleries.addAll(scatterPlotGalleries
.map((gallery) => gallery.buildGalleryListTile(context)));
// Add example pie charts.
galleries.addAll(
comboGalleries.map((gallery) => gallery.buildGalleryListTile(context)));
// Add example pie charts.
galleries.addAll(
pieGalleries.map((gallery) => gallery.buildGalleryListTile(context)));
// Add example custom axis.
galleries.addAll(
axesGalleries.map((gallery) => gallery.buildGalleryListTile(context)));
galleries.addAll(behaviorsGalleries
.map((gallery) => gallery.buildGalleryListTile(context)));
// Add legends examples
galleries.addAll(legendsGalleries
.map((gallery) => gallery.buildGalleryListTile(context)));
// Add examples for i18n.
galleries.addAll(
i18nGalleries.map((gallery) => gallery.buildGalleryListTile(context)));
_setupPerformance();
return new Scaffold(
drawer: new GalleryDrawer(
showPerformanceOverlay: showPerformanceOverlay,
onShowPerformanceOverlayChanged: onShowPerformanceOverlayChanged),
appBar: new AppBar(title: new Text(defaultConfig.appName)),
body: new ListView(padding: kMaterialListPadding, children: galleries),
);
}
void _setupPerformance() {
// Change [printPerformance] to true and set the app to release mode to
// print performance numbers to console. By default, Flutter builds in debug
// mode and this mode is slow. To build in release mode, specify the flag
// blaze-run flag "--define flutter_build_mode=release".
// The build target must also be an actual device and not the emulator.
charts.Performance.time = (String tag) => Timeline.startSync(tag);
charts.Performance.timeEnd = (_) => Timeline.finishSync();
}
}

View File

@@ -0,0 +1,50 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'rtl_bar_chart.dart';
import 'rtl_line_chart.dart';
import 'rtl_line_segments.dart';
import 'rtl_series_legend.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'RTL Bar Chart',
subtitle: 'Simple bar chart in RTL',
childBuilder: () => new RTLBarChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'RTL Line Chart',
subtitle: 'Simple line chart in RTL',
childBuilder: () => new RTLLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'RTL Line Segments',
subtitle: 'Stacked area chart with style segments in RTL',
childBuilder: () => new RTLLineSegments.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.flag),
title: 'RTL Series Legend',
subtitle: 'Series legend in RTL',
childBuilder: () => new RTLSeriesLegend.withRandomData(),
),
];
}

View File

@@ -0,0 +1,119 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// RTL Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class RTLBarChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
RTLBarChart(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory RTLBarChart.withSampleData() {
return new RTLBarChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory RTLBarChart.withRandomData() {
return new RTLBarChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final data = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// Charts will determine if RTL is enabled by checking the directionality by
// requesting Directionality.of(context). This returns the text direction
// from the closest instance of that encloses the context passed to build
// the chart. A [TextDirection.rtl] will be treated as a RTL chart. This
// means that the directionality widget does not have to directly wrap each
// chart. It is show here as an example only.
//
// By default, when a chart detects RTL:
// Measure axis positions are flipped. Primary measure axis is on the right
// and the secondary measure axis is on the left (when used).
// Domain axis' first domain starts on the right and grows left.
//
// Optionally, [RTLSpec] can be passed in when creating the chart to specify
// chart display settings in RTL mode.
return new Directionality(
textDirection: TextDirection.rtl,
child: new charts.BarChart(
seriesList,
animate: animate,
vertical: false,
));
}
/// Create one series with sample hard coded data.
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final data = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Sales',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,115 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// RTL Line chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class RTLLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
RTLLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory RTLLineChart.withSampleData() {
return new RTLLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory RTLLineChart.withRandomData() {
return new RTLLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// Charts will determine if RTL is enabled by checking the directionality by
// requesting Directionality.of(context). This returns the text direction
// from the closest instance of that encloses the context passed to build
// the chart. A [TextDirection.rtl] will be treated as a RTL chart. This
// means that the directionality widget does not have to directly wrap each
// chart. It is show here as an example only.
//
// By default, when a chart detects RTL:
// Measure axis positions are flipped. Primary measure axis is on the right
// and the secondary measure axis is on the left (when used).
// Domain axis' first domain starts on the right and grows left.
return new Directionality(
textDirection: TextDirection.rtl,
child: new charts.LineChart(
seriesList,
animate: animate,
));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,248 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a RTL stacked area chart with changing styles within each line.
///
/// Each series of data in this example contains different values for color,
/// dashPattern, or strokeWidthPx between each datum. The line and area skirt
/// will be rendered in segments, with the styling of the series changing when
/// these data attributes change.
///
/// Note that if a dashPattern or strokeWidth value is not found for a
/// particular datum, then the chart will fall back to use the value defined in
/// the [charts.LineRendererConfig]. This could be used, for example, to define
/// a default dash pattern for the series, with only a specific datum called out
/// with a different pattern.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class RTLLineSegments extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
RTLLineSegments(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory RTLLineSegments.withSampleData() {
return new RTLLineSegments(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory RTLLineSegments.withRandomData() {
return new RTLLineSegments(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
// Series of data with static dash pattern and stroke width. The colorFn
// accessor will colorize each datum (for all three series).
final colorChangeData = [
new LinearSales(0, random.nextInt(100), null, 2.0),
new LinearSales(1, random.nextInt(100), null, 2.0),
new LinearSales(2, random.nextInt(100), null, 2.0),
new LinearSales(3, random.nextInt(100), null, 2.0),
new LinearSales(4, random.nextInt(100), null, 2.0),
new LinearSales(5, random.nextInt(100), null, 2.0),
new LinearSales(6, random.nextInt(100), null, 2.0),
];
// Series of data with changing color and dash pattern.
final dashPatternChangeData = [
new LinearSales(0, random.nextInt(100), [2, 2], 2.0),
new LinearSales(1, random.nextInt(100), [2, 2], 2.0),
new LinearSales(2, random.nextInt(100), [4, 4], 2.0),
new LinearSales(3, random.nextInt(100), [4, 4], 2.0),
new LinearSales(4, random.nextInt(100), [4, 4], 2.0),
new LinearSales(5, random.nextInt(100), [8, 3, 2, 3], 2.0),
new LinearSales(6, random.nextInt(100), [8, 3, 2, 3], 2.0),
];
// Series of data with changing color and stroke width.
final strokeWidthChangeData = [
new LinearSales(0, random.nextInt(100), null, 2.0),
new LinearSales(1, random.nextInt(100), null, 2.0),
new LinearSales(2, random.nextInt(100), null, 4.0),
new LinearSales(3, random.nextInt(100), null, 4.0),
new LinearSales(4, random.nextInt(100), null, 4.0),
new LinearSales(5, random.nextInt(100), null, 6.0),
new LinearSales(6, random.nextInt(100), null, 6.0),
];
// Generate 2 shades of each color so that we can style the line segments.
final blue = charts.MaterialPalette.blue.makeShades(2);
final red = charts.MaterialPalette.red.makeShades(2);
final green = charts.MaterialPalette.green.makeShades(2);
return [
new charts.Series<LinearSales, int>(
id: 'Color Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? blue[1] : blue[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: colorChangeData,
),
new charts.Series<LinearSales, int>(
id: 'Dash Pattern Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? red[1] : red[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: dashPatternChangeData,
),
new charts.Series<LinearSales, int>(
id: 'Stroke Width Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? green[1] : green[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: strokeWidthChangeData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// Charts will determine if RTL is enabled by checking the directionality by
// requesting Directionality.of(context). This returns the text direction
// from the closest instance of that encloses the context passed to build
// the chart. A [TextDirection.rtl] will be treated as a RTL chart. This
// means that the directionality widget does not have to directly wrap each
// chart. It is show here as an example only.
//
// By default, when a chart detects RTL:
// Measure axis positions are flipped. Primary measure axis is on the right
// and the secondary measure axis is on the left (when used).
// Domain axis' first domain starts on the right and grows left.
return new Directionality(
textDirection: TextDirection.rtl,
child: new charts.LineChart(
seriesList,
defaultRenderer:
new charts.LineRendererConfig(includeArea: true, stacked: true),
animate: animate,
));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
// Series of data with static dash pattern and stroke width. The colorFn
// accessor will colorize each datum (for all three series).
final colorChangeData = [
new LinearSales(0, 5, null, 2.0),
new LinearSales(1, 15, null, 2.0),
new LinearSales(2, 25, null, 2.0),
new LinearSales(3, 75, null, 2.0),
new LinearSales(4, 100, null, 2.0),
new LinearSales(5, 90, null, 2.0),
new LinearSales(6, 75, null, 2.0),
];
// Series of data with changing color and dash pattern.
final dashPatternChangeData = [
new LinearSales(0, 5, [2, 2], 2.0),
new LinearSales(1, 15, [2, 2], 2.0),
new LinearSales(2, 25, [4, 4], 2.0),
new LinearSales(3, 75, [4, 4], 2.0),
new LinearSales(4, 100, [4, 4], 2.0),
new LinearSales(5, 90, [8, 3, 2, 3], 2.0),
new LinearSales(6, 75, [8, 3, 2, 3], 2.0),
];
// Series of data with changing color and stroke width.
final strokeWidthChangeData = [
new LinearSales(0, 5, null, 2.0),
new LinearSales(1, 15, null, 2.0),
new LinearSales(2, 25, null, 4.0),
new LinearSales(3, 75, null, 4.0),
new LinearSales(4, 100, null, 4.0),
new LinearSales(5, 90, null, 6.0),
new LinearSales(6, 75, null, 6.0),
];
// Generate 2 shades of each color so that we can style the line segments.
final blue = charts.MaterialPalette.blue.makeShades(2);
final red = charts.MaterialPalette.red.makeShades(2);
final green = charts.MaterialPalette.green.makeShades(2);
return [
new charts.Series<LinearSales, int>(
id: 'Color Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? blue[1] : blue[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: colorChangeData,
),
new charts.Series<LinearSales, int>(
id: 'Dash Pattern Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? red[1] : red[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: dashPatternChangeData,
),
new charts.Series<LinearSales, int>(
id: 'Stroke Width Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? green[1] : green[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: strokeWidthChangeData,
),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
final List<int> dashPattern;
final double strokeWidthPx;
LinearSales(this.year, this.sales, this.dashPattern, this.strokeWidthPx);
}

View File

@@ -0,0 +1,206 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// RTL Bar chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class RTLSeriesLegend extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
RTLSeriesLegend(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory RTLSeriesLegend.withSampleData() {
return new RTLSeriesLegend(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory RTLSeriesLegend.withRandomData() {
return new RTLSeriesLegend(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tabletSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final otherSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// Charts will determine if RTL is enabled by checking the directionality by
// requesting Directionality.of(context). This returns the text direction
// from the closest instance of that encloses the context passed to build
// the chart. A [TextDirection.rtl] will be treated as a RTL chart. This
// means that the directionality widget does not have to directly wrap each
// chart. It is show here as an example only.
//
// When the legend behavior detects RTL:
// [BehaviorPosition.start] is to the right of the chart.
// [BehaviorPosition.end] is to the left of the chart.
//
// If the [BehaviorPosition] is top or bottom, the start justification
// is to the right, and the end justification is to the left.
//
// The legend's tabular layout will also layout rows and columns from right
// to left.
//
// The below example changes the position to 'start' and max rows of 2 in
// order to show these effects, but are not required for SeriesLegend to
// work with the correct directionality.
return new Directionality(
textDirection: TextDirection.rtl,
child: new charts.BarChart(
seriesList,
animate: animate,
behaviors: [
new charts.SeriesLegend(
position: charts.BehaviorPosition.end, desiredMaxRows: 2)
],
));
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final otherSalesData = [
new OrdinalSales('2014', 20),
new OrdinalSales('2015', 35),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 10),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,136 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Pie chart with example of a legend with customized position, justification,
/// desired max rows, padding, and entry text styles. These options are shown as
/// an example of how to use the customizations, they do not necessary have to
/// be used together in this way. Choosing [end] as the position does not
/// require the justification to also be [endDrawArea].
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class DatumLegendOptions extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DatumLegendOptions(this.seriesList, {this.animate});
factory DatumLegendOptions.withSampleData() {
return new DatumLegendOptions(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DatumLegendOptions.withRandomData() {
return new DatumLegendOptions(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, int>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.PieChart(
seriesList,
animate: animate,
// Add the legend behavior to the chart to turn on legends.
// This example shows how to change the position and justification of
// the legend, in addition to altering the max rows and padding.
behaviors: [
new charts.DatumLegend(
// Positions for "start" and "end" will be left and right respectively
// for widgets with a build context that has directionality ltr.
// For rtl, "start" and "end" will be right and left respectively.
// Since this example has directionality of ltr, the legend is
// positioned on the right side of the chart.
position: charts.BehaviorPosition.end,
// For a legend that is positioned on the left or right of the chart,
// setting the justification for [endDrawArea] is aligned to the
// bottom of the chart draw area.
outsideJustification: charts.OutsideJustification.endDrawArea,
// By default, if the position of the chart is on the left or right of
// the chart, [horizontalFirst] is set to false. This means that the
// legend entries will grow as new rows first instead of a new column.
horizontalFirst: false,
// By setting this value to 2, the legend entries will grow up to two
// rows before adding a new column.
desiredMaxRows: 2,
// This defines the padding around each legend entry.
cellPadding: new EdgeInsets.only(right: 4.0, bottom: 4.0),
// Render the legend entry text with custom styles.
entryTextStyle: charts.TextStyleSpec(
color: charts.MaterialPalette.purple.shadeDefault,
fontFamily: 'Georgia',
fontSize: 11),
)
],
);
}
/// Create series list with one series
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 100),
new LinearSales(1, 75),
new LinearSales(2, 25),
new LinearSales(3, 5),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,146 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart with example of a legend with customized position, justification,
/// desired max rows, and padding. These options are shown as an example of how
/// to use the customizations, they do not necessary have to be used together in
/// this way. Choosing [end] as the position does not require the justification
/// to also be [endDrawArea].
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example that shows how to build a datum legend that shows measure values.
///
/// Also shows the option to provide a custom measure formatter.
class DatumLegendWithMeasures extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DatumLegendWithMeasures(this.seriesList, {this.animate});
factory DatumLegendWithMeasures.withSampleData() {
return new DatumLegendWithMeasures(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DatumLegendWithMeasures.withRandomData() {
return new DatumLegendWithMeasures(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, int>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(2014, random.nextInt(100)),
new LinearSales(2015, random.nextInt(100)),
new LinearSales(2016, random.nextInt(100)),
new LinearSales(2017, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.PieChart(
seriesList,
animate: animate,
// Add the legend behavior to the chart to turn on legends.
// This example shows how to optionally show measure and provide a custom
// formatter.
behaviors: [
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// This is added in order to generate the image for the gallery to show
// an initial selection so that measure values are shown in the gallery.
new charts.InitialSelection(
selectedDataConfig: [
new charts.SeriesDatumConfig('Sales', 0),
],
),
// EXCLUDE_FROM_GALLERY_DOCS_END
new charts.DatumLegend(
// Positions for "start" and "end" will be left and right respectively
// for widgets with a build context that has directionality ltr.
// For rtl, "start" and "end" will be right and left respectively.
// Since this example has directionality of ltr, the legend is
// positioned on the right side of the chart.
position: charts.BehaviorPosition.end,
// By default, if the position of the chart is on the left or right of
// the chart, [horizontalFirst] is set to false. This means that the
// legend entries will grow as new rows first instead of a new column.
horizontalFirst: false,
// This defines the padding around each legend entry.
cellPadding: new EdgeInsets.only(right: 4.0, bottom: 4.0),
// Set [showMeasures] to true to display measures in series legend.
showMeasures: true,
// Configure the measure value to be shown by default in the legend.
legendDefaultMeasure: charts.LegendDefaultMeasure.firstValue,
// Optionally provide a measure formatter to format the measure value.
// If none is specified the value is formatted as a decimal.
measureFormatter: (num value) {
return value == null ? '-' : '${value}k';
},
),
],
);
}
/// Create series list with one series
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(2014, 100),
new LinearSales(2015, 75),
new LinearSales(2016, 25),
new LinearSales(2017, 5),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,188 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart with default hidden series legend example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class DefaultHiddenSeriesLegend extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DefaultHiddenSeriesLegend(this.seriesList, {this.animate});
factory DefaultHiddenSeriesLegend.withSampleData() {
return new DefaultHiddenSeriesLegend(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DefaultHiddenSeriesLegend.withRandomData() {
return new DefaultHiddenSeriesLegend(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tabletSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final otherSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
// Add the series legend behavior to the chart to turn on series legends.
// By default the legend will display above the chart.
behaviors: [
new charts.SeriesLegend(
// Configures the "Other" series to be hidden on first chart draw.
defaultHiddenSeries: ['Other'],
)
],
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final otherSalesData = [
new OrdinalSales('2014', 20),
new OrdinalSales('2015', 35),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 10),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,209 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart with custom symbol in legend example.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example custom renderer that renders [IconData].
///
/// This is used to show that legend symbols can be assigned a custom symbol.
class IconRenderer extends charts.CustomSymbolRenderer {
final IconData iconData;
IconRenderer(this.iconData);
@override
Widget build(BuildContext context, {Size size, Color color, bool enabled}) {
// Lighten the color if the symbol is not enabled
// Example: If user has tapped on a Series deselecting it.
if (!enabled) {
color = color.withOpacity(0.26);
}
return new SizedBox.fromSize(
size: size, child: new Icon(iconData, color: color, size: 12.0));
}
}
class LegendWithCustomSymbol extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
LegendWithCustomSymbol(this.seriesList, {this.animate});
factory LegendWithCustomSymbol.withSampleData() {
return new LegendWithCustomSymbol(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory LegendWithCustomSymbol.withRandomData() {
return new LegendWithCustomSymbol(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tabletSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final otherSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
// Add the legend behavior to the chart to turn on legends.
// By default the legend will display above the chart.
//
// To change the symbol used in the legend, set the renderer attribute of
// symbolRendererKey to a SymbolRenderer.
behaviors: [new charts.SeriesLegend()],
defaultRenderer: new charts.BarRendererConfig(
symbolRenderer: new IconRenderer(Icons.cloud)),
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final otherSalesData = [
new OrdinalSales('2014', 20),
new OrdinalSales('2015', 35),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 10),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
)
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,80 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'datum_legend_options.dart';
import 'datum_legend_with_measures.dart';
import 'default_hidden_series_legend.dart';
import 'legend_custom_symbol.dart';
import 'series_legend_options.dart';
import 'series_legend_with_measures.dart';
import 'simple_datum_legend.dart';
import 'simple_series_legend.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Series Legend',
subtitle: 'A series legend for a bar chart with default settings',
childBuilder: () => new SimpleSeriesLegend.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Series Legend Options',
subtitle:
'A series legend with custom positioning and spacing for a bar chart',
childBuilder: () => new LegendOptions.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Series Legend Custom Symbol',
subtitle: 'A series legend using a custom symbol renderer',
childBuilder: () => new LegendWithCustomSymbol.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Default Hidden Series Legend',
subtitle: 'A series legend showing a series hidden by default',
childBuilder: () => new DefaultHiddenSeriesLegend.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.insert_chart),
title: 'Series legend with measures',
subtitle: 'Series legend with measures and measure formatting',
childBuilder: () => new LegendWithMeasures.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Datum Legend',
subtitle: 'A datum legend for a pie chart with default settings',
childBuilder: () => new SimpleDatumLegend.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Datum Legend Options',
subtitle:
'A datum legend with custom positioning and spacing for a pie chart',
childBuilder: () => new DatumLegendOptions.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Datum legend with measures',
subtitle: 'Datum legend with measures and measure formatting',
childBuilder: () => new DatumLegendWithMeasures.withRandomData(),
),
];
}

View File

@@ -0,0 +1,215 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart with example of a legend with customized position, justification,
/// desired max rows, padding, and entry text styles. These options are shown as
/// an example of how to use the customizations, they do not necessary have to
/// be used together in this way. Choosing [end] as the position does not
/// require the justification to also be [endDrawArea].
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class LegendOptions extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
LegendOptions(this.seriesList, {this.animate});
factory LegendOptions.withSampleData() {
return new LegendOptions(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory LegendOptions.withRandomData() {
return new LegendOptions(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final otherSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
// Add the legend behavior to the chart to turn on legends.
// This example shows how to change the position and justification of
// the legend, in addition to altering the max rows and padding.
behaviors: [
new charts.SeriesLegend(
// Positions for "start" and "end" will be left and right respectively
// for widgets with a build context that has directionality ltr.
// For rtl, "start" and "end" will be right and left respectively.
// Since this example has directionality of ltr, the legend is
// positioned on the right side of the chart.
position: charts.BehaviorPosition.end,
// For a legend that is positioned on the left or right of the chart,
// setting the justification for [endDrawArea] is aligned to the
// bottom of the chart draw area.
outsideJustification: charts.OutsideJustification.endDrawArea,
// By default, if the position of the chart is on the left or right of
// the chart, [horizontalFirst] is set to false. This means that the
// legend entries will grow as new rows first instead of a new column.
horizontalFirst: false,
// By setting this value to 2, the legend entries will grow up to two
// rows before adding a new column.
desiredMaxRows: 2,
// This defines the padding around each legend entry.
cellPadding: new EdgeInsets.only(right: 4.0, bottom: 4.0),
// Render the legend entry text with custom styles.
entryTextStyle: charts.TextStyleSpec(
color: charts.MaterialPalette.purple.shadeDefault,
fontFamily: 'Georgia',
fontSize: 11),
)
],
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final otherSalesData = [
new OrdinalSales('2014', 20),
new OrdinalSales('2015', 35),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 10),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,228 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart with example of a legend with customized position, justification,
/// desired max rows, and padding. These options are shown as an example of how
/// to use the customizations, they do not necessary have to be used together in
/// this way. Choosing [end] as the position does not require the justification
/// to also be [endDrawArea].
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// Example that shows how to build a series legend that shows measure values
/// when a datum is selected.
///
/// Also shows the option to provide a custom measure formatter.
class LegendWithMeasures extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
LegendWithMeasures(this.seriesList, {this.animate});
factory LegendWithMeasures.withSampleData() {
return new LegendWithMeasures(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory LegendWithMeasures.withRandomData() {
return new LegendWithMeasures(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final otherSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
// Add the legend behavior to the chart to turn on legends.
// This example shows how to optionally show measure and provide a custom
// formatter.
behaviors: [
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// This is added in order to generate the image for the gallery to show
// an initial selection so that measure values are shown in the gallery.
new charts.InitialSelection(
selectedDataConfig: [
new charts.SeriesDatumConfig('Desktop', '2016'),
new charts.SeriesDatumConfig('Tablet', '2016'),
new charts.SeriesDatumConfig('Mobile', '2016'),
new charts.SeriesDatumConfig('Other', '2016'),
],
),
// EXCLUDE_FROM_GALLERY_DOCS_END
new charts.SeriesLegend(
// Positions for "start" and "end" will be left and right respectively
// for widgets with a build context that has directionality ltr.
// For rtl, "start" and "end" will be right and left respectively.
// Since this example has directionality of ltr, the legend is
// positioned on the right side of the chart.
position: charts.BehaviorPosition.end,
// By default, if the position of the chart is on the left or right of
// the chart, [horizontalFirst] is set to false. This means that the
// legend entries will grow as new rows first instead of a new column.
horizontalFirst: false,
// This defines the padding around each legend entry.
cellPadding: new EdgeInsets.only(right: 4.0, bottom: 4.0),
// Set show measures to true to display measures in series legend,
// when the datum is selected.
showMeasures: true,
// Optionally provide a measure formatter to format the measure value.
// If none is specified the value is formatted as a decimal.
measureFormatter: (num value) {
return value == null ? '-' : '${value}k';
},
),
],
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
// Purposely have a missing datum for 2016 to show the null measure format
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final otherSalesData = [
new OrdinalSales('2014', 20),
new OrdinalSales('2015', 35),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 10),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,104 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart with series legend example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class SimpleDatumLegend extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SimpleDatumLegend(this.seriesList, {this.animate});
factory SimpleDatumLegend.withSampleData() {
return new SimpleDatumLegend(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SimpleDatumLegend.withRandomData() {
return new SimpleDatumLegend(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, int>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.PieChart(
seriesList,
animate: animate,
// Add the series legend behavior to the chart to turn on series legends.
// By default the legend will display above the chart.
behaviors: [new charts.DatumLegend()],
);
}
/// Create series list with one series
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 100),
new LinearSales(1, 75),
new LinearSales(2, 25),
new LinearSales(3, 5),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,183 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Bar chart with series legend example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:flutter_web/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class SimpleSeriesLegend extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SimpleSeriesLegend(this.seriesList, {this.animate});
factory SimpleSeriesLegend.withSampleData() {
return new SimpleSeriesLegend(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SimpleSeriesLegend.withRandomData() {
return new SimpleSeriesLegend(_createRandomData());
}
/// Create random data.
static List<charts.Series<OrdinalSales, String>> _createRandomData() {
final random = new Random();
final desktopSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final tabletSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final mobileSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
final otherSalesData = [
new OrdinalSales('2014', random.nextInt(100)),
new OrdinalSales('2015', random.nextInt(100)),
new OrdinalSales('2016', random.nextInt(100)),
new OrdinalSales('2017', random.nextInt(100)),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.BarChart(
seriesList,
animate: animate,
barGroupingType: charts.BarGroupingType.grouped,
// Add the series legend behavior to the chart to turn on series legends.
// By default the legend will display above the chart.
behaviors: [new charts.SeriesLegend()],
);
}
/// Create series list with multiple series
static List<charts.Series<OrdinalSales, String>> _createSampleData() {
final desktopSalesData = [
new OrdinalSales('2014', 5),
new OrdinalSales('2015', 25),
new OrdinalSales('2016', 100),
new OrdinalSales('2017', 75),
];
final tabletSalesData = [
new OrdinalSales('2014', 25),
new OrdinalSales('2015', 50),
new OrdinalSales('2016', 10),
new OrdinalSales('2017', 20),
];
final mobileSalesData = [
new OrdinalSales('2014', 10),
new OrdinalSales('2015', 15),
new OrdinalSales('2016', 50),
new OrdinalSales('2017', 45),
];
final otherSalesData = [
new OrdinalSales('2014', 20),
new OrdinalSales('2015', 35),
new OrdinalSales('2016', 15),
new OrdinalSales('2017', 10),
];
return [
new charts.Series<OrdinalSales, String>(
id: 'Desktop',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: desktopSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Tablet',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: tabletSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Mobile',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: mobileSalesData,
),
new charts.Series<OrdinalSales, String>(
id: 'Other',
domainFn: (OrdinalSales sales, _) => sales.year,
measureFn: (OrdinalSales sales, _) => sales.sales,
data: otherSalesData,
),
];
}
}
/// Sample ordinal data type.
class OrdinalSales {
final String year;
final int sales;
OrdinalSales(this.year, this.sales);
}

View File

@@ -0,0 +1,101 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a line chart with pan and zoom enabled via
/// [Charts.PanAndZoomBehavior].
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class LineAnimationZoomChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
LineAnimationZoomChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory LineAnimationZoomChart.withSampleData() {
return new LineAnimationZoomChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory LineAnimationZoomChart.withRandomData() {
return new LineAnimationZoomChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = <LinearSales>[];
for (var i = 0; i < 100; i++) {
data.add(new LinearSales(i, random.nextInt(100)));
}
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList, animate: animate, behaviors: [
new charts.PanAndZoomBehavior(),
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,141 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Line chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class AreaAndLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
AreaAndLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory AreaAndLineChart.withSampleData() {
return new AreaAndLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory AreaAndLineChart.withRandomData() {
return new AreaAndLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final myFakeDesktopData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
var myFakeTabletData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customArea'),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList,
animate: animate,
customSeriesRenderers: [
new charts.LineRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customArea',
includeArea: true,
stacked: true),
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final myFakeDesktopData = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
var myFakeTabletData = [
new LinearSales(0, 10),
new LinearSales(1, 50),
new LinearSales(2, 200),
new LinearSales(3, 150),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
)
// Configure our custom bar target renderer for this series.
..setAttribute(charts.rendererIdKey, 'customArea'),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,162 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Dash pattern line chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
/// Example of a line chart rendered with dash patterns.
class DashPatternLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DashPatternLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory DashPatternLineChart.withSampleData() {
return new DashPatternLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DashPatternLineChart.withRandomData() {
return new DashPatternLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final myFakeDesktopData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
var myFakeTabletData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
var myFakeMobileData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
dashPatternFn: (_, __) => [2, 2],
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
dashPatternFn: (_, __) => [8, 3, 2, 3],
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList, animate: animate);
}
/// Create three series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final myFakeDesktopData = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
var myFakeTabletData = [
new LinearSales(0, 10),
new LinearSales(1, 50),
new LinearSales(2, 200),
new LinearSales(3, 150),
];
var myFakeMobileData = [
new LinearSales(0, 15),
new LinearSales(1, 75),
new LinearSales(2, 300),
new LinearSales(3, 225),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
dashPatternFn: (_, __) => [2, 2],
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
dashPatternFn: (_, __) => [8, 3, 2, 3],
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,124 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Line chart with line annotations example.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class LineLineAnnotationChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
LineLineAnnotationChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and line annotations.
///
/// The second annotation extends beyond the range of the series data,
/// demonstrating the effect of the [Charts.RangeAnnotation.extendAxis] flag.
/// This can be set to false to disable range extension.
factory LineLineAnnotationChart.withSampleData() {
return new LineLineAnnotationChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory LineLineAnnotationChart.withRandomData() {
return new LineLineAnnotationChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
// Fix one of the points to 100 so that the annotations are consistently
// placed.
new LinearSales(3, 100),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList, animate: animate, behaviors: [
new charts.RangeAnnotation([
new charts.LineAnnotationSegment(
1.0, charts.RangeAnnotationAxisType.domain,
startLabel: 'Domain 1'),
new charts.LineAnnotationSegment(
4, charts.RangeAnnotationAxisType.domain,
endLabel: 'Domain 2', color: charts.MaterialPalette.gray.shade200),
new charts.LineAnnotationSegment(
20, charts.RangeAnnotationAxisType.measure,
startLabel: 'Measure 1 Start',
endLabel: 'Measure 1 End',
color: charts.MaterialPalette.gray.shade300),
new charts.LineAnnotationSegment(
65, charts.RangeAnnotationAxisType.measure,
startLabel: 'Measure 2 Start',
endLabel: 'Measure 2 End',
color: charts.MaterialPalette.gray.shade400),
]),
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,113 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'animation_zoom.dart';
import 'area_and_line.dart';
import 'dash_pattern.dart';
import 'line_annotation.dart';
import 'points.dart';
import 'range_annotation.dart';
import 'range_annotation_margin.dart';
import 'segments.dart';
import 'simple.dart';
import 'simple_nulls.dart';
import 'stacked_area.dart';
import 'stacked_area_custom_color.dart';
import 'stacked_area_nulls.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Simple Line Chart',
subtitle: 'With a single series and default line point highlighter',
childBuilder: () => new SimpleLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Stacked Area Chart',
subtitle: 'Stacked area chart with three series',
childBuilder: () => new StackedAreaLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Stacked Area Custom Color Chart',
subtitle: 'Stacked area chart with custom area skirt color',
childBuilder: () => new StackedAreaCustomColorLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Area and Line Combo Chart',
subtitle: 'Combo chart with one line series and one area series',
childBuilder: () => new AreaAndLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Points Line Chart',
subtitle: 'Line chart with points on a single series',
childBuilder: () => new PointsLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Null Data Line Chart',
subtitle: 'With a single series and null measure values',
childBuilder: () => new SimpleNullsLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Stacked Area with Nulls Chart',
subtitle: 'Stacked area chart with three series and null measure values',
childBuilder: () => new StackedAreaNullsLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Dash Pattern Line Chart',
subtitle: 'Line chart with dash patterns',
childBuilder: () => new DashPatternLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Segments Line Chart',
subtitle: 'Line chart with changes of style for each line',
childBuilder: () => new SegmentsLineChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Line Annotation Line Chart',
subtitle: 'Line chart with line annotations',
childBuilder: () => new LineLineAnnotationChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Range Annotation Line Chart',
subtitle: 'Line chart with range annotations',
childBuilder: () => new LineRangeAnnotationChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Range Annotation Margin Labels Line Chart',
subtitle: 'Line chart with range annotations with labels in margins',
childBuilder: () => new LineRangeAnnotationMarginChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.show_chart),
title: 'Pan and Zoom Line Chart',
subtitle: 'Simple line chart pan and zoom behaviors enabled',
childBuilder: () => new LineAnimationZoomChart.withRandomData(),
),
];
}

View File

@@ -0,0 +1,103 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Line chart example
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class PointsLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
PointsLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory PointsLineChart.withSampleData() {
return new PointsLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory PointsLineChart.withRandomData() {
return new PointsLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList,
animate: animate,
defaultRenderer: new charts.LineRendererConfig(includePoints: true));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,124 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Line chart with range annotations example.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class LineRangeAnnotationChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
LineRangeAnnotationChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and range annotations.
///
/// The second annotation extends beyond the range of the series data,
/// demonstrating the effect of the [Charts.RangeAnnotation.extendAxis] flag.
/// This can be set to false to disable range extension.
factory LineRangeAnnotationChart.withSampleData() {
return new LineRangeAnnotationChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory LineRangeAnnotationChart.withRandomData() {
return new LineRangeAnnotationChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
// Fix one of the points to 100 so that the annotations are consistently
// placed.
new LinearSales(3, 100),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList, animate: animate, behaviors: [
new charts.RangeAnnotation([
new charts.RangeAnnotationSegment(
0.5, 1.0, charts.RangeAnnotationAxisType.domain,
startLabel: 'Domain 1'),
new charts.RangeAnnotationSegment(
2, 4, charts.RangeAnnotationAxisType.domain,
endLabel: 'Domain 2', color: charts.MaterialPalette.gray.shade200),
new charts.RangeAnnotationSegment(
15, 20, charts.RangeAnnotationAxisType.measure,
startLabel: 'Measure 1 Start',
endLabel: 'Measure 1 End',
color: charts.MaterialPalette.gray.shade300),
new charts.RangeAnnotationSegment(
35, 65, charts.RangeAnnotationAxisType.measure,
startLabel: 'Measure 2 Start',
endLabel: 'Measure 2 End',
color: charts.MaterialPalette.gray.shade400),
]),
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,141 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a line chart with range annotations configured to render labels
/// in the chart margin area.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class LineRangeAnnotationMarginChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
LineRangeAnnotationMarginChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and range annotations.
///
/// The second annotation extends beyond the range of the series data,
/// demonstrating the effect of the [Charts.RangeAnnotation.extendAxis] flag.
/// This can be set to false to disable range extension.
factory LineRangeAnnotationMarginChart.withSampleData() {
return new LineRangeAnnotationMarginChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory LineRangeAnnotationMarginChart.withRandomData() {
return new LineRangeAnnotationMarginChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
// Fix one of the points to 100 so that the annotations are consistently
// placed.
new LinearSales(3, 100),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList,
animate: animate,
// Allow enough space in the left and right chart margins for the
// annotations.
layoutConfig: new charts.LayoutConfig(
leftMarginSpec: new charts.MarginSpec.fixedPixel(60),
topMarginSpec: new charts.MarginSpec.fixedPixel(20),
rightMarginSpec: new charts.MarginSpec.fixedPixel(60),
bottomMarginSpec: new charts.MarginSpec.fixedPixel(20)),
behaviors: [
// Define one domain and two measure annotations configured to render
// labels in the chart margins.
new charts.RangeAnnotation([
new charts.RangeAnnotationSegment(
0.5, 1.0, charts.RangeAnnotationAxisType.domain,
startLabel: 'D1 Start',
endLabel: 'D1 End',
labelAnchor: charts.AnnotationLabelAnchor.end,
color: charts.MaterialPalette.gray.shade200,
// Override the default vertical direction for domain labels.
labelDirection: charts.AnnotationLabelDirection.horizontal),
new charts.RangeAnnotationSegment(
15, 20, charts.RangeAnnotationAxisType.measure,
startLabel: 'M1 Start',
endLabel: 'M1 End',
labelAnchor: charts.AnnotationLabelAnchor.end,
color: charts.MaterialPalette.gray.shade300),
new charts.RangeAnnotationSegment(
35, 65, charts.RangeAnnotationAxisType.measure,
startLabel: 'M2 Start',
endLabel: 'M2 End',
labelAnchor: charts.AnnotationLabelAnchor.start,
color: charts.MaterialPalette.gray.shade400),
], defaultLabelPosition: charts.AnnotationLabelPosition.margin),
]);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,233 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a stacked area chart with changing styles within each line.
///
/// Each series of data in this example contains different values for color,
/// dashPattern, or strokeWidthPx between each datum. The line and area skirt
/// will be rendered in segments, with the styling of the series changing when
/// these data attributes change.
///
/// Note that if a dashPattern or strokeWidth value is not found for a
/// particular datum, then the chart will fall back to use the value defined in
/// the [charts.LineRendererConfig]. This could be used, for example, to define
/// a default dash pattern for the series, with only a specific datum called out
/// with a different pattern.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SegmentsLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SegmentsLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory SegmentsLineChart.withSampleData() {
return new SegmentsLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SegmentsLineChart.withRandomData() {
return new SegmentsLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
// Series of data with static dash pattern and stroke width. The colorFn
// accessor will colorize each datum (for all three series).
final colorChangeData = [
new LinearSales(0, random.nextInt(100), null, 2.0),
new LinearSales(1, random.nextInt(100), null, 2.0),
new LinearSales(2, random.nextInt(100), null, 2.0),
new LinearSales(3, random.nextInt(100), null, 2.0),
new LinearSales(4, random.nextInt(100), null, 2.0),
new LinearSales(5, random.nextInt(100), null, 2.0),
new LinearSales(6, random.nextInt(100), null, 2.0),
];
// Series of data with changing color and dash pattern.
final dashPatternChangeData = [
new LinearSales(0, random.nextInt(100), [2, 2], 2.0),
new LinearSales(1, random.nextInt(100), [2, 2], 2.0),
new LinearSales(2, random.nextInt(100), [4, 4], 2.0),
new LinearSales(3, random.nextInt(100), [4, 4], 2.0),
new LinearSales(4, random.nextInt(100), [4, 4], 2.0),
new LinearSales(5, random.nextInt(100), [8, 3, 2, 3], 2.0),
new LinearSales(6, random.nextInt(100), [8, 3, 2, 3], 2.0),
];
// Series of data with changing color and stroke width.
final strokeWidthChangeData = [
new LinearSales(0, random.nextInt(100), null, 2.0),
new LinearSales(1, random.nextInt(100), null, 2.0),
new LinearSales(2, random.nextInt(100), null, 4.0),
new LinearSales(3, random.nextInt(100), null, 4.0),
new LinearSales(4, random.nextInt(100), null, 4.0),
new LinearSales(5, random.nextInt(100), null, 6.0),
new LinearSales(6, random.nextInt(100), null, 6.0),
];
// Generate 2 shades of each color so that we can style the line segments.
final blue = charts.MaterialPalette.blue.makeShades(2);
final red = charts.MaterialPalette.red.makeShades(2);
final green = charts.MaterialPalette.green.makeShades(2);
return [
new charts.Series<LinearSales, int>(
id: 'Color Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? blue[1] : blue[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: colorChangeData,
),
new charts.Series<LinearSales, int>(
id: 'Dash Pattern Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? red[1] : red[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: dashPatternChangeData,
),
new charts.Series<LinearSales, int>(
id: 'Stroke Width Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? green[1] : green[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: strokeWidthChangeData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList,
defaultRenderer:
new charts.LineRendererConfig(includeArea: true, stacked: true),
animate: animate);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
// Series of data with static dash pattern and stroke width. The colorFn
// accessor will colorize each datum (for all three series).
final colorChangeData = [
new LinearSales(0, 5, null, 2.0),
new LinearSales(1, 15, null, 2.0),
new LinearSales(2, 25, null, 2.0),
new LinearSales(3, 75, null, 2.0),
new LinearSales(4, 100, null, 2.0),
new LinearSales(5, 90, null, 2.0),
new LinearSales(6, 75, null, 2.0),
];
// Series of data with changing color and dash pattern.
final dashPatternChangeData = [
new LinearSales(0, 5, [2, 2], 2.0),
new LinearSales(1, 15, [2, 2], 2.0),
new LinearSales(2, 25, [4, 4], 2.0),
new LinearSales(3, 75, [4, 4], 2.0),
new LinearSales(4, 100, [4, 4], 2.0),
new LinearSales(5, 90, [8, 3, 2, 3], 2.0),
new LinearSales(6, 75, [8, 3, 2, 3], 2.0),
];
// Series of data with changing color and stroke width.
final strokeWidthChangeData = [
new LinearSales(0, 5, null, 2.0),
new LinearSales(1, 15, null, 2.0),
new LinearSales(2, 25, null, 4.0),
new LinearSales(3, 75, null, 4.0),
new LinearSales(4, 100, null, 4.0),
new LinearSales(5, 90, null, 6.0),
new LinearSales(6, 75, null, 6.0),
];
// Generate 2 shades of each color so that we can style the line segments.
final blue = charts.MaterialPalette.blue.makeShades(2);
final red = charts.MaterialPalette.red.makeShades(2);
final green = charts.MaterialPalette.green.makeShades(2);
return [
new charts.Series<LinearSales, int>(
id: 'Color Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? blue[1] : blue[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: colorChangeData,
),
new charts.Series<LinearSales, int>(
id: 'Dash Pattern Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? red[1] : red[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: dashPatternChangeData,
),
new charts.Series<LinearSales, int>(
id: 'Stroke Width Change',
// Light shade for even years, dark shade for odd.
colorFn: (LinearSales sales, _) =>
sales.year % 2 == 0 ? green[1] : green[0],
dashPatternFn: (LinearSales sales, _) => sales.dashPattern,
strokeWidthPxFn: (LinearSales sales, _) => sales.strokeWidthPx,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: strokeWidthChangeData,
),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
final List<int> dashPattern;
final double strokeWidthPx;
LinearSales(this.year, this.sales, this.dashPattern, this.strokeWidthPx);
}

View File

@@ -0,0 +1,101 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a simple line chart.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SimpleLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SimpleLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory SimpleLineChart.withSampleData() {
return new SimpleLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SimpleLineChart.withRandomData() {
return new SimpleLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList, animate: animate);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,179 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a line chart with null measure values.
///
/// Null values will be visible as gaps in lines and area skirts. Any data
/// points that exist between two nulls in a line will be rendered as an
/// isolated point, as seen in the green series.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class SimpleNullsLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
SimpleNullsLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory SimpleNullsLineChart.withSampleData() {
return new SimpleNullsLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory SimpleNullsLineChart.withRandomData() {
return new SimpleNullsLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final myFakeDesktopData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, null),
new LinearSales(3, random.nextInt(100)),
new LinearSales(4, random.nextInt(100)),
new LinearSales(5, random.nextInt(100)),
new LinearSales(6, random.nextInt(100)),
];
var myFakeTabletData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
new LinearSales(4, random.nextInt(100)),
new LinearSales(5, random.nextInt(100)),
new LinearSales(6, random.nextInt(100)),
];
var myFakeMobileData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, null),
new LinearSales(3, random.nextInt(100)),
new LinearSales(4, null),
new LinearSales(5, random.nextInt(100)),
new LinearSales(6, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList, animate: animate);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final myFakeDesktopData = [
new LinearSales(0, 5),
new LinearSales(1, 15),
new LinearSales(2, null),
new LinearSales(3, 75),
new LinearSales(4, 100),
new LinearSales(5, 90),
new LinearSales(6, 75),
];
final myFakeTabletData = [
new LinearSales(0, 10),
new LinearSales(1, 30),
new LinearSales(2, 50),
new LinearSales(3, 150),
new LinearSales(4, 200),
new LinearSales(5, 180),
new LinearSales(6, 150),
];
final myFakeMobileData = [
new LinearSales(0, 15),
new LinearSales(1, 45),
new LinearSales(2, null),
new LinearSales(3, 225),
new LinearSales(4, null),
new LinearSales(5, 270),
new LinearSales(6, 225),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,160 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a stacked area chart.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class StackedAreaLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
StackedAreaLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory StackedAreaLineChart.withSampleData() {
return new StackedAreaLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory StackedAreaLineChart.withRandomData() {
return new StackedAreaLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final myFakeDesktopData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
var myFakeTabletData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
var myFakeMobileData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList,
defaultRenderer:
new charts.LineRendererConfig(includeArea: true, stacked: true),
animate: animate);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final myFakeDesktopData = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
var myFakeTabletData = [
new LinearSales(0, 10),
new LinearSales(1, 50),
new LinearSales(2, 200),
new LinearSales(3, 150),
];
var myFakeMobileData = [
new LinearSales(0, 15),
new LinearSales(1, 75),
new LinearSales(2, 300),
new LinearSales(3, 225),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,175 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a stacked area chart with custom area colors.
///
/// By default, the area skirt for a chart will be drawn with the same color as
/// the line, but with a 10% opacity assigned to it. An area color function can
/// be provided to override this with any custom color.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class StackedAreaCustomColorLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
StackedAreaCustomColorLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory StackedAreaCustomColorLineChart.withSampleData() {
return new StackedAreaCustomColorLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory StackedAreaCustomColorLineChart.withRandomData() {
return new StackedAreaCustomColorLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final myFakeDesktopData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
var myFakeTabletData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
var myFakeMobileData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList,
defaultRenderer:
new charts.LineRendererConfig(includeArea: true, stacked: true),
animate: animate);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final myFakeDesktopData = [
new LinearSales(0, 5),
new LinearSales(1, 25),
new LinearSales(2, 100),
new LinearSales(3, 75),
];
var myFakeTabletData = [
new LinearSales(0, 10),
new LinearSales(1, 50),
new LinearSales(2, 200),
new LinearSales(3, 150),
];
var myFakeMobileData = [
new LinearSales(0, 15),
new LinearSales(1, 75),
new LinearSales(2, 300),
new LinearSales(3, 225),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
// colorFn specifies that the line will be blue.
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
// areaColorFn specifies that the area skirt will be light blue.
areaColorFn: (_, __) =>
charts.MaterialPalette.blue.shadeDefault.lighter,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
// colorFn specifies that the line will be red.
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
// areaColorFn specifies that the area skirt will be light red.
areaColorFn: (_, __) => charts.MaterialPalette.red.shadeDefault.lighter,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
// colorFn specifies that the line will be green.
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
// areaColorFn specifies that the area skirt will be light green.
areaColorFn: (_, __) =>
charts.MaterialPalette.green.shadeDefault.lighter,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,191 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Example of a stacked area chart with null measure values.
///
/// Null values will be visible as gaps in lines and area skirts. Any data
/// points that exist between two nulls in a line will be rendered as an
/// isolated point, as seen in the green series.
///
/// In a stacked area chart, no data above a null value in the stack will be
/// rendered. In this example, the null measure value at domain 2 in the Desktop
/// series will prevent any data from being rendered at domain 2 for every
/// series because it is at the bottom of the stack.
///
/// This will also result in an isolated point being rendered for the domain
/// value 3 in the Mobile series, because that series also contains a null at
/// domain 4.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class StackedAreaNullsLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
StackedAreaNullsLineChart(this.seriesList, {this.animate});
/// Creates a [LineChart] with sample data and no transition.
factory StackedAreaNullsLineChart.withSampleData() {
return new StackedAreaNullsLineChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory StackedAreaNullsLineChart.withRandomData() {
return new StackedAreaNullsLineChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, num>> _createRandomData() {
final random = new Random();
final myFakeDesktopData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, null),
new LinearSales(3, random.nextInt(100)),
new LinearSales(4, random.nextInt(100)),
new LinearSales(5, random.nextInt(100)),
new LinearSales(6, random.nextInt(100)),
];
var myFakeTabletData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
new LinearSales(4, random.nextInt(100)),
new LinearSales(5, random.nextInt(100)),
new LinearSales(6, random.nextInt(100)),
];
var myFakeMobileData = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
new LinearSales(4, null),
new LinearSales(5, random.nextInt(100)),
new LinearSales(6, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
),
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.LineChart(seriesList,
defaultRenderer:
new charts.LineRendererConfig(includeArea: true, stacked: true),
animate: animate);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final myFakeDesktopData = [
new LinearSales(0, 5),
new LinearSales(1, 15),
new LinearSales(2, null),
new LinearSales(3, 75),
new LinearSales(4, 100),
new LinearSales(5, 90),
new LinearSales(6, 75),
];
final myFakeTabletData = [
new LinearSales(0, 5),
new LinearSales(1, 15),
new LinearSales(2, 25),
new LinearSales(3, 75),
new LinearSales(4, 100),
new LinearSales(5, 90),
new LinearSales(6, 75),
];
final myFakeMobileData = [
new LinearSales(0, 5),
new LinearSales(1, 15),
new LinearSales(2, 25),
new LinearSales(3, 75),
new LinearSales(4, null),
new LinearSales(5, 90),
new LinearSales(6, 75),
];
return [
new charts.Series<LinearSales, int>(
id: 'Desktop',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeDesktopData,
),
new charts.Series<LinearSales, int>(
id: 'Tablet',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeTabletData,
),
new charts.Series<LinearSales, int>(
id: 'Mobile',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: myFakeMobileData,
),
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,54 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import 'app_config.dart';
import 'home.dart';
/// The main gallery app widget.
class GalleryApp extends StatefulWidget {
GalleryApp({Key key}) : super(key: key);
@override
GalleryAppState createState() => new GalleryAppState();
}
/// The main gallery app state.
///
/// Controls performance overlay, and instantiates a [Home] widget.
class GalleryAppState extends State<GalleryApp> {
// Initialize app settings from the default configuration.
bool _showPerformanceOverlay = defaultConfig.showPerformanceOverlay;
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: defaultConfig.appName,
theme: defaultConfig.theme,
showPerformanceOverlay: _showPerformanceOverlay,
home: new Home(
showPerformanceOverlay: _showPerformanceOverlay,
onShowPerformanceOverlayChanged: (bool value) {
setState(() {
_showPerformanceOverlay = value;
});
},
));
}
}
void main() {
runApp(new GalleryApp());
}

View File

@@ -0,0 +1,123 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Donut chart with labels example. This is a simple pie chart with a hole in
/// the middle.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class DonutAutoLabelChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DonutAutoLabelChart(this.seriesList, {this.animate});
/// Creates a [PieChart] with sample data and no transition.
factory DonutAutoLabelChart.withSampleData() {
return new DonutAutoLabelChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DonutAutoLabelChart.withRandomData() {
return new DonutAutoLabelChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, int>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
// Set a label accessor to control the text of the arc label.
labelAccessorFn: (LinearSales row, _) => '${row.year}: ${row.sales}',
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.PieChart(seriesList,
animate: animate,
// Configure the width of the pie slices to 60px. The remaining space in
// the chart will be left as a hole in the center.
//
// [ArcLabelDecorator] will automatically position the label inside the
// arc if the label will fit. If the label will not fit, it will draw
// outside of the arc with a leader line. Labels can always display
// inside or outside using [LabelPosition].
//
// Text style for inside / outside can be controlled independently by
// setting [insideLabelStyleSpec] and [outsideLabelStyleSpec].
//
// Example configuring different styles for inside/outside:
// new charts.ArcLabelDecorator(
// insideLabelStyleSpec: new charts.TextStyleSpec(...),
// outsideLabelStyleSpec: new charts.TextStyleSpec(...)),
defaultRenderer: new charts.ArcRendererConfig(
arcWidth: 60,
arcRendererDecorators: [new charts.ArcLabelDecorator()]));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 100),
new LinearSales(1, 75),
new LinearSales(2, 25),
new LinearSales(3, 5),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
// Set a label accessor to control the text of the arc label.
labelAccessorFn: (LinearSales row, _) => '${row.year}: ${row.sales}',
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,103 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Donut chart example. This is a simple pie chart with a hole in the middle.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class DonutPieChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
DonutPieChart(this.seriesList, {this.animate});
/// Creates a [PieChart] with sample data and no transition.
factory DonutPieChart.withSampleData() {
return new DonutPieChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory DonutPieChart.withRandomData() {
return new DonutPieChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, int>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.PieChart(seriesList,
animate: animate,
// Configure the width of the pie slices to 60px. The remaining space in
// the chart will be left as a hole in the center.
defaultRenderer: new charts.ArcRendererConfig(arcWidth: 60));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 100),
new LinearSales(1, 75),
new LinearSales(2, 25),
new LinearSales(3, 5),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,106 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Gauge chart example, where the data does not cover a full revolution in the
/// chart.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class GaugeChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
GaugeChart(this.seriesList, {this.animate});
/// Creates a [PieChart] with sample data and no transition.
factory GaugeChart.withSampleData() {
return new GaugeChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory GaugeChart.withRandomData() {
return new GaugeChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<GaugeSegment, String>> _createRandomData() {
final random = new Random();
final data = [
new GaugeSegment('Low', random.nextInt(100)),
new GaugeSegment('Acceptable', random.nextInt(100)),
new GaugeSegment('High', random.nextInt(100)),
new GaugeSegment('Highly Unusual', random.nextInt(100)),
];
return [
new charts.Series<GaugeSegment, String>(
id: 'Segments',
domainFn: (GaugeSegment segment, _) => segment.segment,
measureFn: (GaugeSegment segment, _) => segment.size,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.PieChart(seriesList,
animate: animate,
// Configure the width of the pie slices to 30px. The remaining space in
// the chart will be left as a hole in the center. Adjust the start
// angle and the arc length of the pie so it resembles a gauge.
defaultRenderer: new charts.ArcRendererConfig(
arcWidth: 30, startAngle: 4 / 5 * pi, arcLength: 7 / 5 * pi));
}
/// Create one series with sample hard coded data.
static List<charts.Series<GaugeSegment, String>> _createSampleData() {
final data = [
new GaugeSegment('Low', 75),
new GaugeSegment('Acceptable', 100),
new GaugeSegment('High', 50),
new GaugeSegment('Highly Unusual', 5),
];
return [
new charts.Series<GaugeSegment, String>(
id: 'Segments',
domainFn: (GaugeSegment segment, _) => segment.segment,
measureFn: (GaugeSegment segment, _) => segment.size,
data: data,
)
];
}
}
/// Sample data type.
class GaugeSegment {
final String segment;
final int size;
GaugeSegment(this.segment, this.size);
}

View File

@@ -0,0 +1,118 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Simple pie chart with outside labels example.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class PieOutsideLabelChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
PieOutsideLabelChart(this.seriesList, {this.animate});
/// Creates a [PieChart] with sample data and no transition.
factory PieOutsideLabelChart.withSampleData() {
return new PieOutsideLabelChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory PieOutsideLabelChart.withRandomData() {
return new PieOutsideLabelChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, int>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
// Set a label accessor to control the text of the arc label.
labelAccessorFn: (LinearSales row, _) => '${row.year}: ${row.sales}',
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
return new charts.PieChart(seriesList,
animate: animate,
// Add an [ArcLabelDecorator] configured to render labels outside of the
// arc with a leader line.
//
// Text style for inside / outside can be controlled independently by
// setting [insideLabelStyleSpec] and [outsideLabelStyleSpec].
//
// Example configuring different styles for inside/outside:
// new charts.ArcLabelDecorator(
// insideLabelStyleSpec: new charts.TextStyleSpec(...),
// outsideLabelStyleSpec: new charts.TextStyleSpec(...)),
defaultRenderer: new charts.ArcRendererConfig(arcRendererDecorators: [
new charts.ArcLabelDecorator(
labelPosition: charts.ArcLabelPosition.outside)
]));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 100),
new LinearSales(1, 75),
new LinearSales(2, 25),
new LinearSales(3, 5),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
// Set a label accessor to control the text of the arc label.
labelAccessorFn: (LinearSales row, _) => '${row.year}: ${row.sales}',
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,104 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Partial pie chart example, where the data does not cover a full revolution
/// in the chart.
// EXCLUDE_FROM_GALLERY_DOCS_START
import 'dart:math';
// EXCLUDE_FROM_GALLERY_DOCS_END
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_web/material.dart';
class PartialPieChart extends StatelessWidget {
final List<charts.Series> seriesList;
final bool animate;
PartialPieChart(this.seriesList, {this.animate});
/// Creates a [PieChart] with sample data and no transition.
factory PartialPieChart.withSampleData() {
return new PartialPieChart(
_createSampleData(),
// Disable animations for image tests.
animate: false,
);
}
// EXCLUDE_FROM_GALLERY_DOCS_START
// This section is excluded from being copied to the gallery.
// It is used for creating random series data to demonstrate animation in
// the example app only.
factory PartialPieChart.withRandomData() {
return new PartialPieChart(_createRandomData());
}
/// Create random data.
static List<charts.Series<LinearSales, int>> _createRandomData() {
final random = new Random();
final data = [
new LinearSales(0, random.nextInt(100)),
new LinearSales(1, random.nextInt(100)),
new LinearSales(2, random.nextInt(100)),
new LinearSales(3, random.nextInt(100)),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
// EXCLUDE_FROM_GALLERY_DOCS_END
@override
Widget build(BuildContext context) {
// Configure the pie to display the data across only 3/4 instead of the full
// revolution.
return new charts.PieChart(seriesList,
animate: animate,
defaultRenderer: new charts.ArcRendererConfig(arcLength: 3 / 2 * pi));
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData() {
final data = [
new LinearSales(0, 100),
new LinearSales(1, 75),
new LinearSales(2, 25),
new LinearSales(3, 5),
];
return [
new charts.Series<LinearSales, int>(
id: 'Sales',
domainFn: (LinearSales sales, _) => sales.year,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
}
/// Sample linear data type.
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}

View File

@@ -0,0 +1,65 @@
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
// for details.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter_web/material.dart';
import '../gallery_scaffold.dart';
import 'auto_label.dart';
import 'donut.dart';
import 'gauge.dart';
import 'simple.dart';
import 'outside_label.dart';
import 'partial_pie.dart';
List<GalleryScaffold> buildGallery() {
return [
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Simple Pie Chart',
subtitle: 'With a single series',
childBuilder: () => new SimplePieChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Outside Label Pie Chart',
subtitle: 'With a single series and labels outside the arcs',
childBuilder: () => new PieOutsideLabelChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Partial Pie Chart',
subtitle: 'That doesn\'t cover a full revolution',
childBuilder: () => new PartialPieChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Simple Donut Chart',
subtitle: 'With a single series and a hole in the middle',
childBuilder: () => new DonutPieChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Auto Label Donut Chart',
subtitle:
'With a single series, a hole in the middle, and auto-positioned labels',
childBuilder: () => new DonutAutoLabelChart.withRandomData(),
),
new GalleryScaffold(
listTileIcon: new Icon(Icons.pie_chart),
title: 'Gauge Chart',
subtitle: 'That doesn\'t cover a full revolution',
childBuilder: () => new GaugeChart.withRandomData(),
),
];
}

Some files were not shown because too many files have changed in this diff Show More