Flutter charts looks great but I can't find a good doc for it. I have a few questions based on what I want to achieve:
Questions are also in the code as comments (and I have added some of my understanding for some parameters in case it helps beginners like me)
- Question 1: The Theme from the MaterialApp doesn't cascade naturally to the children Widgets...why?
- Question 2: I want to limit the grid to a value of 5 so thought that viewport 0,5 would help but it completely messes the scatterplot - why?
- Question 3: How can Datum be named individually on the scatterplot?
- Question 4: I tried to do the green arcs that delimit some areas but using the code in the example gallery doesn't work (I am using the line example as opposed to an arc one as a pure copy but it doesn't work anyway) - I could use a datum with transparent fill color but I would need to be able to cut it...
- Question 5: how can I name axes?
and the code:
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//populating data by calling the setSeries function
var seriesList = setSeries();
return new MaterialApp(
title: 'Material Title',
//question 1: This doesn't seem to be passed to the underlying widgets - Why? calling Theme.of all the time would be the weird
theme: new ThemeData(
primarySwatch: Colors.green,
),
home:
ListView(
children: [
//Added that to see text outside the plot widget
Text('A scatter plot'),
//plot would not display when not put in a SizedBox - I assume it is because ListView doesn't give constraints
SizedBox(
height: 300.0,
//Only height is required
//width: 200.0,
child: charts.ScatterPlotChart(
//Providing the data needed (see below to look at the data)
seriesList,
animate: false,
//Adds the legend based on the data in the Series in field "id" or "displayName"
//It also adds "dots" in the graph itself to show series...it is confusing as they look like data points
//behaviors: [charts.SeriesLegend()],
/* Goes with question 4: This doesn't work at all and doesn't compile - I wanted an arc but even trying a line like in the gallery example doesn't work
customSeriesRenderers: [
new charts.LineRendererConfig(
// ID used to link series to this renderer.
customRendererId: 'customArc',
// 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)
],
*/
primaryMeasureAxis: charts.NumericAxisSpec(
tickProviderSpec: charts.BasicNumericTickProviderSpec(
//Ticks are the ones inside the plotting area, excluding the min and max axis values
desiredTickCount: 3,
),
//Question 2: Data point values are to be 0-5, so I expected viewport with a max of 5 to "crop" the display showing up to 5 only
//but it actually gets the widget to diplay outside its SizedBox + shows data twice with / without format
//Almost like an offset - how does this work? (chand to (0,6) and it looks nicer...but not what I want)
viewport: charts.NumericExtents(0, 5),
),
domainAxis: charts.NumericAxisSpec(
tickProviderSpec: charts.BasicNumericTickProviderSpec(
desiredTickCount: 3,
),
viewport: charts.NumericExtents(0, 5),
),
),
),
],
),
);
}
//For beginners like me:
//Series is defined in the doc as Series, so my stating Series means that T=PlotPoint, D=num
//...so domainFn (the abscissa) is of type num now...
//had I done Series domainFn would have taken ints only as abscissa values (i.e. 1.3 would be converted into 1)
List> setSeries() {
var dataOne = [
PlotPoint(1.0,1.5,10,'a','circle',
charts.MaterialPalette.pink.shadeDefault,
charts.MaterialPalette.green.shadeDefault,
10.0),
PlotPoint(2.3,2.3,15,'b','rect',
charts.MaterialPalette.pink.shadeDefault,
charts.MaterialPalette.green.shadeDefault,
5.0),
PlotPoint(4.7, 3.8, 5, 'c', 'rect',
null,
charts.MaterialPalette.green.shadeDefault,
null),
PlotPoint(5,5,10,'d','circle',
charts.MaterialPalette.yellow.shadeDefault,
charts.MaterialPalette.green.shadeDefault,
5.0),
];
var dataTwo = [
PlotPoint(4,4,60,'other','circle',
charts.MaterialPalette.transparent,
charts.MaterialPalette.blue.shadeDefault,
2.0),
];
var dataThree = [
PlotPoint(4,5,1,'limit','circle',
charts.MaterialPalette.transparent,
charts.MaterialPalette.purple.shadeDefault,
2.0),
PlotPoint(5,4,1,'limit','circle',
charts.MaterialPalette.transparent,
charts.MaterialPalette.purple.shadeDefault,
2.0),
];
return [
//First series in List - matching type expectation
charts.Series(
//Name of the series
id: 'one',
//the data to use which should be of type here PlotPoint
data: dataOne,
//The X / abscissa
domainFn: (PlotPoint pData, _) => pData.x,
//The Y / Ordinate
measureFn: (PlotPoint pData, _) => pData.y,
//Used in the Legend instead of the "id" value
displayName: 'a',
//Color of the stroke
colorFn: (PlotPoint pData, _) => pData.strokeColor,
//XXX - Must work for LineChart only
dashPatternFn: (PlotPoint pData, _) => [1, 5],
//Defines the lowest a Datum has been (to be used when showing a data point along with a range) -> pass data like the current value
//domainLowerBoundFn: (PlotPoint pData, _) => pData.lowestValueForAGivenPlotPoint,
//Defines the highest a Datum has been (to be used when showing a data point along with a range) -> pass data like the current value
//domainUpperBoundFn: ,
//Color to use to fill the data point
fillColorFn: (PlotPoint pData, _) => pData.fillColor,
//XXX never used
//fillPatternFn: ,
//Question 3: how can I show the name of the datum on the graph?
labelAccessorFn: (PlotPoint pData, _) => pData.label,
//XXX - No idea
//insideLabelStyleAccessorFn: ,
//XXX - No idea
//outsideLabelStyleAccessorFn: ,
//Defines the lowest a Datum has been (to be used when showing a data point along with a range) -> pass data like the current value
//measureLowerBoundFn: ,
//Defines the highest a Datum has been (to be used when showing a data point along with a range) -> pass data like the current value
//measureUpperBoundFn: ,
//XXX - No idea
//measureOffsetFn: ,
//XXX - No idea
//overlaySeries: false,
//The radius of the itemt to plot in pixel
radiusPxFn: (PlotPoint pData, _) => pData.radius,
//XXX - No idea
//seriesCategory: ,
//Stroke width
strokeWidthPxFn: (PlotPoint pData, _) => pData.strokeWidth,
),
//Created 2 series as points within the same serie are not shown when overlapping...so created 2
charts.Series(
id: 'two',
data: dataTwo,
domainFn: (PlotPoint pData, _) => pData.x,
measureFn: (PlotPoint pData, _) => pData.y,
displayName: 'b',
colorFn: (PlotPoint pData, _) => pData.strokeColor,
fillColorFn: (PlotPoint pData, _) => pData.fillColor,
labelAccessorFn: (PlotPoint pData, _) => pData.label,
radiusPxFn: (PlotPoint pData, _) => pData.radius,
strokeWidthPxFn: (PlotPoint pData, _) => pData.strokeWidth,
),
charts.Series(
id: 'three',
data: dataThree,
domainFn: (PlotPoint pData, _) => pData.x,
measureFn: (PlotPoint pData, _) => pData.y,
displayName: 'c',
colorFn: (PlotPoint pData, _) => pData.strokeColor,
fillColorFn: (PlotPoint pData, _) => pData.fillColor,
labelAccessorFn: (PlotPoint pData, _) => pData.label,
radiusPxFn: (PlotPoint pData, _) => pData.radius,
strokeWidthPxFn: (PlotPoint pData, _) => pData.strokeWidth,
)
//Question 4: wanted to use this to mark that Serie and create an arc to define areas...example in library doesn't work
//..setAttribute(charts.rendererIdKey, 'customArc')
,
];
}
}
class PlotPoint {
num _x;
num _y;
num _radius;
String _label;
String _shape;
charts.Color _fillColor;
charts.Color _strokeColor;
double _strokeWidth;
PlotPoint(this._x, this._y, this._radius, this._label, this._shape,
this._fillColor, this._strokeColor, this._strokeWidth);
num get x => _x;
num get y => _y;
num get radius => _radius;
String get label => _label;
String get shape => _shape;
charts.Color get fillColor => _fillColor;
charts.Color get strokeColor => _strokeColor;
double get strokeWidth => _strokeWidth;
}
