How to convert below code in scrollable view? - flutter

I'm trying to fit pie chart, bar graph and line graph in the same screen in scrollable view
I want to display multiple graphs in a single screen in scrollable view
I used flexible() widget that fitted the graph in a single screen then I tried ListView and SingleChildScrollView but it's not working
Below are the codes of whatever I tried
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:pie_chart/pie_chart.dart';
import 'DonutPieChart.dart';
class HomePage extends StatefulWidget {
final Widget child;
HomePage({Key key, this.child}) : super(key: key);
_HomePageState createState() => _HomePageState();
}
Map<String, double> dataMap = new Map();
class _HomePageState extends State<HomePage>{
List<charts.Series<Pollution, String>> _seriesData;
List<charts.Series<Electricity1, String>> _seriesPieData;
List<charts.Series<Vehicles,int>> _seriesLineData;
List<charts.Series<Electricity, String>>_seriesPieData1;
TabController _tabController;
ScrollController _scrollViewController;
int _counter = 0;
_generateData() {
var data1 = [
new Pollution('June',3),
new Pollution('July',1),
new Pollution('August',5),
];
var data2 = [
new Pollution('June', 1),
new Pollution('July',2),
new Pollution('August',4),
];
var data3 = [
new Pollution('June', 5),
new Pollution('July',3),
new Pollution('August',3),
];
var piedata = [
new Electricity1('Renewable Onsite', 8),
new Electricity1('Renewable Wheeled', 10),
new Electricity1('Purchased Grid', 15),
];
var piedata1 = [
new Electricity('Renewable', 18, Color(0xfffdbe19)),
new Electricity('Purchased Grid', 15, Color(0xff990099)),
];
var linedata = [
new Vehicles(2, 56),
new Vehicles(4, 55),
new Vehicles(6, 60),
new Vehicles(8, 61),
new Vehicles(10, 70),
];
var linedata1 = [
new Vehicles(2, 46),
new Vehicles(4, 45),
new Vehicles(6, 50),
new Vehicles(8, 51),
new Vehicles(10, 60),
];
var linedata2 = [
new Vehicles(2, 24),
new Vehicles(4, 25),
new Vehicles(6, 40),
new Vehicles(8, 45),
new Vehicles(10, 60),
];
final data = [
new LinearSales(0, 100),
new LinearSales(1, 75),
new LinearSales(2, 25),
new LinearSales(3, 5),
];
_seriesData.add(
charts.Series(
id:'LPG-Cooking',
domainFn: (Pollution pollution, _) => pollution.place,
measureFn: (Pollution pollution, _) => pollution.quantity,
data: data1,
),
);
_seriesData.add(
charts.Series(
id:'Diesel',
domainFn: (Pollution pollution, _) => pollution.place,
measureFn: (Pollution pollution, _) => pollution.quantity,
data: data2,
),
);
_seriesData.add(
charts.Series(
id:'LPG-lab',
domainFn: (Pollution pollution, _) => pollution.place,
measureFn: (Pollution pollution, _) => pollution.quantity,
data: data3,
),
);
_seriesPieData.add(
charts.Series(
id:'Pollution',
domainFn: (Electricity1 e, _) => e.emission,
measureFn: (Electricity1 e, _) => e.emission_value,
data: piedata,
// Set a label accessor to control the text of the arc label.
labelAccessorFn: (Electricity1 e, _) => '${e.emission}: ${e.emission_value}',
),
);
_seriesPieData1.add(
charts.Series(
id:'Pollution',
domainFn: (Electricity e, _) => e.emission,
measureFn: (Electricity e, _) => e.emission_value,
colorFn: (Electricity e, _) =>
charts.ColorUtil.fromDartColor(e.colorval),
data: piedata1,
// Set a label accessor to control the text of the arc label.
labelAccessorFn: (Electricity e, _) => '${e.emission}: ${e.emission_value}',
),
);
_seriesLineData.add(
charts.Series(
id: 'Two wheeler',
data: linedata,
domainFn: (Vehicles v, _) => v.month,
measureFn: (Vehicles v, _) => v.emissions,
),
);
_seriesLineData.add(
charts.Series(
colorFn: (__, _) => charts.ColorUtil.fromDartColor(Color(0xff0277BD)),
id: 'Three wheeler',
data: linedata1,
domainFn: (Vehicles v, _) => v.month,
measureFn: (Vehicles v, _) => v.emissions,
),
);
_seriesLineData.add(
charts.Series(
colorFn: (__, _) => charts.ColorUtil.fromDartColor(Color(0xff01579D)),
id: 'Four wheeler',
data: linedata2,
domainFn: (Vehicles v, _) => v.month,
measureFn: (Vehicles v, _) => v.emissions,
),
);
}
#override
void initState() {
// TODO: implement initState
super.initState();
_seriesData = List<charts.Series<Pollution, String>>();
_seriesPieData = List<charts.Series<Electricity1, String>>();
_seriesLineData = List<charts.Series<Vehicles,int>>();
_seriesPieData1= List<charts.Series<Electricity, String>>();
_generateData();
dataMap.putIfAbsent("Flutter", () => 5);
dataMap.putIfAbsent("React", () => 3);
dataMap.putIfAbsent("Xamarin", () => 2);
dataMap.putIfAbsent("Ionic", () => 2);
}
#override
void dispose() {
_tabController.dispose();
_scrollViewController.dispose();
super.dispose();
}
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
#override
Widget build(BuildContext context) {
var dpc = DonutPieChart.withSampleData();
return MaterialApp(
home: Scaffold(
body:Center(
child:ListView(
//child:Column(
//children: [
children: <Widget>[
SizedBox(height: 30.0,
child: Text(
'Direct Emissions by lpg-cooking, lpg-lab and diesel (in kg)',style: TextStyle(fontSize: 24.0,fontWeight: FontWeight.bold),),
),
Flexible( flex: 5,
child:
Card(
child: charts.BarChart(
_seriesData,
animate: true,
barGroupingType: charts.BarGroupingType.stacked,
behaviors: [new charts.SeriesLegend()],
animationDuration: Duration(seconds: 1),
),
),
),
SizedBox(height: 30.0,
child:Text(
'CO2 produced by electricity',style: TextStyle(fontSize: 24.0,fontWeight: FontWeight.bold),),
),
Flexible(
flex:5,
child:
Card(
child:Stack(
children:<Widget>[
Container(
//color: Colors.blue,
height: 300.0,
width: 300.0,
child: dpc,
),
Container(
// color: Colors.blue,
height: 300.0,
width: 300.0,
child: PieChart(dataMap: dataMap, showLegends: false,),
)
],
),
),
),
SizedBox(height: 30.0,
child:Text(
'CO2 in kg produced by vehicles',style: TextStyle(fontSize: 24.0,fontWeight: FontWeight.bold),),
),
Flexible(
flex:5,
child:
Card(
child: charts.LineChart(
_seriesLineData,
defaultRenderer: new charts.LineRendererConfig(
includeArea: true, stacked: true),
animate: true,
animationDuration: Duration(seconds: 1),
behaviors: [
new charts.SeriesLegend(),
new charts.ChartTitle('Months',
behaviorPosition: charts.BehaviorPosition.bottom,
titleOutsideJustification:charts.OutsideJustification.middleDrawArea),
]
),
),
),
],
),
),
),
);
}
}
class Pollution {
String place;
int quantity;
Pollution(this.place, this.quantity);
}
class Vehicles {
int month;
double emissions;
Vehicles(this.month, this.emissions);
}
class Electricity{
String emission;
double emission_value;
Color colorval;
Electricity(this.emission,this.emission_value,this.colorval);
}
class Electricity1{
String emission;
double emission_value;
Electricity1(this.emission,this.emission_value);
}
DonutPieChart.dart file
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
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,
);
}
#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);
}

Try using ListView
A scrollable list of widgets arranged linearly.
return MaterialApp(
home: Scaffold(
body:Center(
child:
// Column(
// children: [
ListView(
children: <Widget>[
SizedBox(height: 30.0,
child: Text(
'Direct Emissions by lpg-cooking, lpg-lab and diesel (in kg)',style: TextStyle(fontSize: 24.0,fontWeight: FontWeight.bold),),
),
Flexible( flex: 5,
child:
Card(
child: charts.BarChart(
_seriesData,
animate: true,
barGroupingType: charts.BarGroupingType.stacked,
behaviors: [new charts.SeriesLegend()],
animationDuration: Duration(seconds: 1),
),
),
),
SizedBox(height: 30.0,
child:Text(
'CO2 produced by electricity',style: TextStyle(fontSize: 24.0,fontWeight: FontWeight.bold),),
),
Flexible(
flex:5,
child:
Card(
child:Stack(
children:<Widget>[
Container(
//color: Colors.blue,
height: 300.0,
width: 300.0,
child: dpc,
),
Container(
// color: Colors.blue,
height: 300.0,
width: 300.0,
child: PieChart(dataMap: dataMap, showLegends: false,),
)
],
),
),
),
SizedBox(height: 30.0,
child:Text(
'CO2 in kg produced by vehicles',style: TextStyle(fontSize: 24.0,fontWeight: FontWeight.bold),),
),
Flexible(
flex:5,
child:
Card(
child: charts.LineChart(
_seriesLineData,
defaultRenderer: new charts.LineRendererConfig(
includeArea: true, stacked: true),
animate: true,
animationDuration: Duration(seconds: 1),
behaviors: [
new charts.SeriesLegend(),
new charts.ChartTitle('Months',
behaviorPosition: charts.BehaviorPosition.bottom,
titleOutsideJustification:charts.OutsideJustification.middleDrawArea),
]
),
),
),
],
),
),
),
);

wrap your Column inside a SingleChildScrollView and use Containers with the desired height instead of Flexible.
Don't forget to set mainAxisSize: MainAxisSize.min to your Column.
#override
Widget build(BuildContext context) {
var dpc = DonutPieChart.withSampleData();
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 30.0,
child: Text(
'Direct Emissions by lpg-cooking, lpg-lab and diesel (in kg)',
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
),
Container(
height: 300,
child: charts.BarChart(
_seriesData,
animate: true,
barGroupingType: charts.BarGroupingType.stacked,
behaviors: [charts.SeriesLegend()],
animationDuration: Duration(seconds: 1),
),
),
SizedBox(
height: 30.0,
child: Text(
'CO2 produced by electricity',
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
),
Container(
height: 300,
width: 300,
child: Card(
child: Stack(
children: <Widget>[
Container(child: dpc),
Container(child: dpc),
],
),
),
),
SizedBox(
height: 30.0,
child: Text(
'CO2 in kg produced by vehicles',
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
),
Container(
height: 300,
child: charts.LineChart(_seriesLineData,
defaultRenderer: charts.LineRendererConfig(
includeArea: true, stacked: true),
animate: true,
animationDuration: Duration(seconds: 1),
behaviors: [
charts.SeriesLegend(),
charts.ChartTitle('Months',
behaviorPosition: charts.BehaviorPosition.bottom,
titleOutsideJustification:
charts.OutsideJustification.middleDrawArea),
]),
),
],
),
),
),
),
);
}

Related

How to change the size of the text in a Pie Chart in flutter?

I have a donut graphic but the texts are too small and I have not been able to make them bigger. it is a "PieChart" chart. I have my data segmented into A, B, C, D, E, F. I need to change text size, I am using a tablet size device and that is why the graph should look large, however the texts do not change size and I do not know how to achieve that my code is as follows:
_RegZonesCircularTabletState createState() => _RegZonesCircularTabletState();
}
class GradesData {
final String gradeSymbol;
final int numberOfStudents;
final charts.Color color;
GradesData(this.gradeSymbol, this.numberOfStudents, this.color);
}
#override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
}
class _RegZonesCircularTabletState extends State<RegZonesCircularTablet> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
centerTitle: true,
title: Text("Región o Zona"),
),drawer: LateralMenu(),
body: ListView(children: <Widget> [
Container(
height: 750,
child:new charts.PieChart(
_getSeriesData(),
animate: true,
defaultRenderer: new charts.ArcRendererConfig(
arcWidth: 200,//ancho de la dona
arcRendererDecorators: [new charts.ArcLabelDecorator(),]
),
),
),
],),
floatingActionButton:Container(
height: 110.0,
width: 110.0,
child: FloatingActionButton(
onPressed: () {
// Add your onPressed code here!
},
child: const Icon(Icons.calendar_today,size: 50),
backgroundColor: Colors.black,
elevation: 5.0,
) ,)
);
}
}
final data = [
GradesData('A', 190,charts.MaterialPalette.indigo.shadeDefault),
GradesData('B', 230,charts.MaterialPalette.purple.shadeDefault),
GradesData('C', 150,charts.MaterialPalette.cyan.shadeDefault),
GradesData('D', 73,charts.MaterialPalette.lime.shadeDefault),
GradesData('E', 31,charts.MaterialPalette.teal.shadeDefault),
GradesData('Fail', 13,charts.MaterialPalette.gray.shadeDefault),
];
_getSeriesData() {
List<charts.Series<GradesData, String>> series = [
charts.Series(
id: "Grades",
data: data,
labelAccessorFn: (GradesData row, _) => '${row.gradeSymbol}: ${row.numberOfStudents}',
domainFn: (GradesData grades, _) => grades.gradeSymbol,
measureFn: (GradesData grades, _) => grades.numberOfStudents,
colorFn: (GradesData grades, _) => grades.color,
)
];
return series;
}
The chart is for tablet
Thanks, I'm a beginner, sorry for the trouble
Using the below code while creating charts.Series, we can manage the text style of the chart
charts.Series<MyModel, String>(
//....
outsideLabelStyleAccessorFn: (_, __) => const charts.TextStyleSpec(
fontSize: 16,
color: charts.MaterialPalette.black,
fontFamily: 'MyFont'
),
insideLabelStyleAccessorFn: (_, __) => const charts.TextStyleSpec(
fontSize: 16,
color: charts.MaterialPalette.white,
fontFamily: 'MyFont'
),
);
And don't forget to add this in PieChart widget
defaultRenderer: charts.ArcRendererConfig(
arcRendererDecorators: [charts.ArcLabelDecorator()],
),

Need to use Isolates to speed up file processing in my app

What the app does:
Tapping on the FAB will:
Create a single pdf with multiple pages or multiple png files. (the latter is selected as default, can be changed with a boolean in the parameter)
The function will return a list of Files.
What is the problem:
When there are more than 4 pages, the main isolate (app) will start to lag, and if more than 2 digits quantity the app will crash. I am trying to speed up the processing and hopefully prevent crashes.
What I have tried:
Learning how to spawn an isolate but I still get a lot of errors here and there.
Using an Isolate is very low-level programming and there are very few resources for it.
Some things may not make sense it's because this is a stripped-down version of a larger code. But everything should be working, in this example, it can either create pdf or png files, I prefer png files which is the one that consumes the most time.
For complete code https://github.com/fenchai23/pdf_isolate_test.git
This is an example of Isolates from the author of the pdf package for isolates but it is very simple and not what I am trying to do.
This is the complete main.dart file:
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Pdf Isolate Test'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List _invoice = [
{
'qty': '1',
'code': '27274-7J125 SET',
'desc': 'A/A NIS PATHFINDER NEW 2015 - 2PC ALMERA 27275-1N605',
'invt': '615',
'codealt': 'AC2503 SET',
'descalt': '',
'group': '10.FILTRO A/A',
'price': '5.53',
'disc1': '4.42',
'globalPrice': '5.53',
'total': '5.53'
},
{
'qty': '1',
'code': '27274-EA000 SET',
'desc':
'A/A NIS FRONTIER VQ40 YD25 PATHFIADER D40 VITARRA J20 27274-EL00A 27277-4JA0A',
'invt': '1018',
'codealt': 'AC2507SET',
'descalt': '27277-4JA0A' 'GRAN VITARRA J20',
'group': '10.FILTRO A/A',
'price': '4.25',
'disc1': '3.40',
'globalPrice': '4.25',
'total': '4.25'
}
];
static Future<List<File>> generateInvoice(Map args) async {
print('creating pdf');
final String _cartSubTotal = '1.00';
final String _cartTotal = '1.01';
final String _cartItbms = '7.00%';
final DateTime _startTime = DateTime.now();
final String dateTimeStamp = DateTime.now().toString();
PdfImage _logo;
List<Product> products = [];
final List customRecordData = args['customRecordData'];
final String customClientName = args['customClientName'];
final String customClientDirection = args['customClientDirection'];
final String customClientSeller = args['customClientSeller'];
final bool isPdf = args['isPdf'];
for (final k in customRecordData) {
Product productsHolder = Product(
k['qty'],
k['code'],
k['desc'],
k['globalPrice'],
k['total'],
);
products.add(productsHolder);
}
final pw.Document pdf = pw.Document();
_logo = PdfImage.file(pdf.document,
bytes: (await rootBundle.load('assets/icons/appIcon.png'))
.buffer
.asUint8List());
pw.Widget _pdfHeader(pw.Context context) {
return pw.Column(
children: [
pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Expanded(
child: pw.Column(
children: [
pw.Container(height: 2),
pw.Container(
decoration: pw.BoxDecoration(
borderRadius: 2,
border:
pw.BoxBorder(color: PdfColors.blue, width: 2)),
padding: const pw.EdgeInsets.only(
left: 10, top: 5, bottom: 5, right: 10),
alignment: pw.Alignment.centerLeft,
height: 60,
child: pw.DefaultTextStyle(
style: pw.TextStyle(
color: PdfColors.black,
fontSize: 10,
),
child: pw.Column(
mainAxisSize: pw.MainAxisSize.min,
crossAxisAlignment: pw.CrossAxisAlignment.start,
mainAxisAlignment: pw.MainAxisAlignment.spaceEvenly,
children: [
pw.Text('Cliente: $customClientName', maxLines: 1),
pw.Text('Dir: $customClientDirection',
maxLines: 1),
pw.Text('Vend: $customClientSeller', maxLines: 1),
],
),
),
),
],
),
),
pw.Expanded(
child: pw.Column(
mainAxisSize: pw.MainAxisSize.min,
children: [
pw.Container(
alignment: pw.Alignment.topRight,
padding: const pw.EdgeInsets.only(bottom: 8, left: 30),
height: 72,
child: pw.Image(_logo),
),
],
),
),
],
),
if (context.pageNumber > 1) pw.SizedBox(height: 20),
],
);
}
pw.Widget _contentTable(pw.Context context) {
const tableHeaders = ['CANT', 'CODIGO', 'DESCRIPCION', 'PRECIO', 'TOTAL'];
return pw.Table.fromTextArray(
context: context,
border: null,
cellAlignment: pw.Alignment.centerLeft,
headerDecoration: pw.BoxDecoration(
borderRadius: 2,
color: PdfColors.blue,
),
headerHeight: 25,
cellHeight: 25,
cellAlignments: {
0: pw.Alignment.center,
1: pw.Alignment.centerLeft,
2: pw.Alignment.centerLeft,
3: pw.Alignment.center,
4: pw.Alignment.centerRight,
},
headerStyle: pw.TextStyle(
color: PdfColors.white,
fontSize: 10,
fontWeight: pw.FontWeight.bold,
),
cellStyle: const pw.TextStyle(
color: PdfColors.black,
fontSize: 10,
),
rowDecoration: pw.BoxDecoration(
border: pw.BoxBorder(
bottom: true,
color: PdfColors.grey,
width: .5,
),
),
headers: List<String>.generate(
tableHeaders.length,
(col) => tableHeaders[col],
),
data: List<List<String>>.generate(
products.length,
(row) => List<String>.generate(
tableHeaders.length,
(col) => products[row].getIndex(col),
),
),
);
}
pw.Widget _contentFooter(pw.Context context) {
return pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Expanded(
flex: 2,
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'',
style: pw.TextStyle(
color: PdfColors.black,
fontWeight: pw.FontWeight.bold,
),
),
pw.Container(
margin: const pw.EdgeInsets.only(top: 20, bottom: 8),
child: pw.Text(
'',
style: pw.TextStyle(
color: PdfColors.black,
fontWeight: pw.FontWeight.bold,
),
),
),
pw.Text(
'',
style: const pw.TextStyle(
fontSize: 8,
lineSpacing: 5,
color: PdfColors.black,
),
),
],
),
),
pw.Expanded(
flex: 1,
child: pw.DefaultTextStyle(
style: const pw.TextStyle(
fontSize: 10,
color: PdfColors.black,
),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Text('Sub Total:'),
pw.Text(_cartSubTotal),
],
),
pw.SizedBox(height: 5),
pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Text('I.T.B.M.S:'),
pw.Text(_cartItbms),
],
),
pw.Divider(color: PdfColors.black),
pw.DefaultTextStyle(
style: pw.TextStyle(
color: PdfColors.black,
fontSize: 14,
fontWeight: pw.FontWeight.bold,
),
child: pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Text('Total:'),
pw.Text(_cartTotal),
],
),
),
],
),
),
),
],
);
}
pw.Widget _pdfFooter(pw.Context context) {
return pw.DefaultTextStyle(
style: pw.Theme.of(context).defaultTextStyle.copyWith(
color: PdfColors.grey,
),
child: pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Container(
child: pw.Text(dateTimeStamp),
margin: const pw.EdgeInsets.only(top: 1.0 * PdfPageFormat.cm),
),
pw.Container(
alignment: pw.Alignment.centerRight,
margin: const pw.EdgeInsets.only(top: 1.0 * PdfPageFormat.cm),
child: pw.Text(
'Página ${context.pageNumber} de ${context.pagesCount}',
),
),
],
),
);
}
// Here is where PDF (Invoice) is created
pdf.addPage(
pw.MultiPage(
pageTheme: pw.PageTheme(
buildBackground: (pw.Context context) => pw.FullPage(
ignoreMargins: true,
child: pw.Container(
color: PdfColors.white,
),
),
pageFormat: PdfPageFormat.letter.copyWith(
marginBottom: 1.5 * PdfPageFormat.cm,
marginTop: 1.5 * PdfPageFormat.cm,
marginLeft: 1 * PdfPageFormat.cm,
marginRight: 1 * PdfPageFormat.cm,
),
),
header: _pdfHeader,
footer: _pdfFooter,
build: (pw.Context context) => <pw.Widget>[
pw.Padding(
padding: pw.EdgeInsets.only(bottom: 12.0),
),
_contentTable(context),
pw.Padding(
padding: pw.EdgeInsets.only(bottom: 12.0),
),
_contentFooter(context),
],
),
);
final output = await getTemporaryDirectory();
final timef = dateTimeStamp;
// get a safe name for filenames
final safeClientName =
customClientName.replaceAll(RegExp("[\\\\/:*?\"<>|]"), '');
final String fileName = '$timef--$customClientSeller--$safeClientName';
File file;
var imageList = List<File>();
var pagesToPrint;
pagesToPrint = await Printing.raster(pdf.save()).length;
if (!isPdf) {
int pageIndex = 1;
await for (var page in Printing.raster(pdf.save(), dpi: 300)) {
final image = await page.toPng();
final String pageQty =
(pagesToPrint > 1) ? '$pageIndex-$pagesToPrint' : '1-1';
file = File("${output.path}/$fileName--$pageQty.png");
await file.writeAsBytes(image);
imageList.add(file);
pageIndex++;
}
} else {
file = File("${output.path}/$fileName.pdf");
await file.writeAsBytes(pdf.save());
imageList.add(file);
}
print('done creating pdf');
final int elapsedTime = DateTime.now().difference(_startTime).inSeconds;
print('time elapsed: $elapsedTime seconds');
return imageList;
}
#override
void initState() {
final tempInvoice = [];
for (final Map k in _invoice) {
print(k);
tempInvoice.add(k);
}
for (int i = 1; i <= 100; i++) {
_invoice.addAll(tempInvoice);
}
print(_invoice);
print(_invoice.length);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(),
SizedBox(
height: 20,
),
Text('If animation lags then we know isolate failed.')
],
))),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await getTemporaryDirectory()
..delete(recursive: true);
var result = await compute(generateInvoice, {
'customRecordData': _invoice,
'customClientName': 'Obama',
'customClientDirection': 'USA',
'customClientSeller': '1',
'isPdf': false,
});
print(result);
},
child: Icon(Icons.picture_as_pdf),
),
);
}
}
class Product {
const Product(
this.qty,
this.code,
this.desc,
this.price,
this.total,
);
final String qty;
final String code;
final String desc;
final String price;
final String total;
String getIndex(int index) {
switch (index) {
case 0:
return qty;
case 1:
return truncateWithEllipsis(25, code.trim());
case 2:
return truncateWithEllipsis(50, desc.trim());
case 3:
return price;
case 4:
return total;
}
return '';
}
}
String truncateWithEllipsis(int cutoff, String myString) {
return (myString.length <= cutoff)
? myString
: '${myString.substring(0, cutoff)}...';
}
While the app runs fine, when I try to run the compute code it gives me this error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
I have tried giving main() async and also WidgetsFlutterBinding.ensureInitialized();
but it continues to call the same error.
btw this is the part that takes the most time.
if (!isPdf) {
int pageIndex = 1;
await for (var page in Printing.raster(pdf.save(), dpi: 300)) {
final image = await page.toPng();
final String pageQty =
(pagesToPrint > 1) ? '$pageIndex-$pagesToPrint' : '1-1';
file = File("${output.path}/$fileName--$pageQty.png");
await file.writeAsBytes(image);
imageList.add(file);
pageIndex++;
}
} else {
file = File("${output.path}/$fileName.pdf");
await file.writeAsBytes(pdf.save());
imageList.add(file);
}
Maybe I haven't seen it but where do you spawn your Isolate?
I could be a little bit tricky to generate your on Isolate, but Flutter have a great workaround and it's called the compute function. Give it a try! Compute Flutter API
Or try this page it helped me to get a good view over this function. Compute with Flutter
Maybe good to know is that Dart is a single threaded language, that means you can run your code in background on a second thread and in the main thread you can show a loading indicator. Workaround is to generate more threads or to vectorize your code.Dart vectorize
Tom

How To Create Custom Line Chart in Flutter?

I just want to line chart in my flutter application like below image.
Here is my code but the result output is normal. i am using charts_flutter: ^0.9.0 packages.
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_screenutil/screenutil.dart';
import 'data/sale_data.dart';
class LineChart extends StatelessWidget {
// Defining the data
final data = [
new SalesData(1, 7),
new SalesData(2, 19),
new SalesData(3, 6),
new SalesData(4, 3),
new SalesData(5, 10),
new SalesData(6, 21),
new SalesData(7, 3),
new SalesData(8, 10),
new SalesData(9, 5),
new SalesData(10, 15),
new SalesData(11, 8),
new SalesData(12, 12),
new SalesData(13, 6),
new SalesData(14, 18),
new SalesData(15, 4),
new SalesData(16, 8),
new SalesData(17, 3),
new SalesData(18, 12),
new SalesData(19, 7),
new SalesData(20, 3),
new SalesData(21, 8),
new SalesData(22, 12),
new SalesData(23, 6),
new SalesData(24, 18),
new SalesData(25, 4),
new SalesData(26, 8),
new SalesData(27, 3),
new SalesData(28, 12),
new SalesData(29, 7),
new SalesData(30, 3),
new SalesData(31, 8),
new SalesData(32, 12),
new SalesData(33, 6),
new SalesData(34, 18),
new SalesData(35, 4),
new SalesData(36, 8),
new SalesData(37, 3),
new SalesData(38, 12),
new SalesData(39, 7),
new SalesData(40, 3),
];
_getSeriesData() {
List<charts.Series<SalesData, int>> series = [
charts.Series(
//dot color is fillcolorfn
fillColorFn: (SalesData series, _) =>
charts.MaterialPalette.green.shadeDefault,
//seriesColor: charts.ColorUtil.fromDartColor(Colors.red),
id: "Sales",
data: data,
patternColorFn: (SalesData series, _) => charts.MaterialPalette.white,
// areaColorFn: ((SalesData series, _) => charts.MaterialPalette.black),
domainUpperBoundFn: (SalesData series, _) => series.domainUpper,
domainLowerBoundFn: (SalesData series, _) => series.domainLower,
measureUpperBoundFn: (SalesData series, _) => series.measureUpper,
measureLowerBoundFn: (SalesData series, _) => series.measureLower,
domainFn: (SalesData series, _) => series.year,
measureFn: (SalesData series, _) => series.sales,
colorFn: (SalesData series, _) =>
charts.MaterialPalette.red.shadeDefault),
];
return series;
}
#override
Widget build(BuildContext context) {
return Container(
height: ScreenUtil().setHeight(800),
child: Card(
color: Colors.white,
child: Padding(
padding: EdgeInsets.only(
left: ScreenUtil().setWidth(20),
right: ScreenUtil().setWidth(20),
),
child: Column(
children: <Widget>[
// Text(
// "Sales of a company over the years",
// style: TextStyle(fontWeight: FontWeight.bold),
// ),
// SizedBox(
// height: 20,
// ),
Padding(
padding: EdgeInsets.only(
top: ScreenUtil().setWidth(20),
),
child: Align(
alignment: Alignment.centerRight,
child: Container(
alignment: Alignment.topRight,
color: Colors.white,
height: ScreenUtil().setHeight(50),
width: ScreenUtil().setWidth(100),
child: Text("hello"),
),
),
),
Expanded(
child: new charts.LineChart(
_getSeriesData(),
animate: true,
// domainAxis: new charts.NumericAxisSpec(
// // Set the initial viewport by providing a new AxisSpec with the
// // desired viewport, in NumericExtents.
// viewport: new charts.NumericExtents(0.0, 40.0)),
),
)
],
),
),
),
);
}
}
my output image is below
I've checked the two images that you've shared and the only difference that I can see seems to only be different colors used on those charts. You can try using fl_chart plugin to see if it fits your use case. With fl_chart, it allows you to modify the charts color as detailed on the docs.

Flutter-unable to set coordinates in line charts?

i'm facing issues in line charts. i'm fetching x and y data from sq lite database. and it should set
in line chart.when activity started chart showing blank. but only click on chart value is setting in
chart.
i'm using charts_flutter dart package for implementation.
where i did the mistake. any solutions.
Future graph_initialize() {
Future<List<Map>> noteListFuture1 = dbHelper.get_lactation_curve("${widget.value.tag}");//fetching data from databse
noteListFuture1.then((noteList) {
for(int i=0;i<noteList.length;i++){
print(noteList[i]["Days"].toString()+","+noteList[i]["Milk_Yield"].toString());
milking_data.add( new Sales(noteList[i]["Days"], noteList[i]["Milk_Yield"]));
}
_serieslineData.add(charts.Series(
colorFn: (__, _) => charts.ColorUtil.fromDartColor(Colors.red),
id: 'lac',
data: milking_data,// here data is setting
domainFn: (Sales sales, _) => sales.yearval,
measureFn: (Sales sales, _) => sales.salesval));
setState(() {
});
});}
#override
void initState() {
super.initState();
_serieslineData = List<charts.Series<Sales, int>>();
graph_initialize();//function call
}
Widget show_chart(){
return Padding(
padding: EdgeInsets.all(8),
child: Container(
height: 300,
child: Column(
children: <Widget>[
Text('Lactation Curve',
style: TextStyle(fontSize: 16, fontFamily: 'Montserrat',fontWeight: FontWeight.bold)),
Expanded(
child: charts.LineChart(_serieslineData,
animate: false,
domainAxis: charts.NumericAxisSpec(
tickProviderSpec:
new charts.BasicNumericTickProviderSpec(
desiredTickCount: 11,
),
viewport: charts.NumericExtents(
0,
300,
)),
animationDuration: Duration(seconds: 3),
behaviors: [
charts.ChartTitle('Milk Yield',
behaviorPosition: charts.BehaviorPosition.start),
charts.ChartTitle('Days in Milk',
behaviorPosition: charts.BehaviorPosition.bottom),
charts.ChartTitle(
'',
),
charts.ChartTitle(' ')
])),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[label(Colors.red,'Lac'),
label(Colors.lightBlueAccent,'Milk(kg)'),
label(Colors.amber,'A.I'),
label(Colors.green,'Pregnant'),
label(Colors.blueGrey,'Vaccination'),
label(Colors.black,'Treatment'),
],
),
)
],
),
),
);
}
You need a bool loading or isLoading to control because chart data is not ready yet
and when loading == true return CircularProgressIndicator() or Container()
bool loading = false;
Future graph_initialize() {
loading = true;
Future<List<Map>> noteListFuture1 = dbHelper.get_lactation_curve("${widget.value.tag}");//fetching data from databse
noteListFuture1.then((noteList) {
for(int i=0;i<noteList.length;i++){
print(noteList[i]["Days"].toString()+","+noteList[i]["Milk_Yield"].toString());
milking_data.add( new Sales(noteList[i]["Days"], noteList[i]["Milk_Yield"]));
}
_serieslineData.add(charts.Series(
colorFn: (__, _) => charts.ColorUtil.fromDartColor(Colors.red),
id: 'lac',
data: milking_data,// here data is setting
domainFn: (Sales sales, _) => sales.yearval,
measureFn: (Sales sales, _) => sales.salesval));
setState(() {
loading = false;
});
});}
Expanded(
child: loading? CircularProgressIndicator() : charts.LineChart(_serieslineData,
animate: false,
domainAxis: charts.NumericAxisSpec(
tickProviderSpec:

Navigate from and to the Donut chart gets blank using charts_flutter in flutter

I am using the donut chart using the package charts_flutter V0.8.1. But when I navigate to the next screen and get back to the previous page(Donut page) chart gets blank. Scenario: Once I can see the next screen I pressed the back button. FYI I am using the Donut chart sample code.https://google.github.io/charts/flutter/example/pie_charts/donut
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: new DonutPieChart()
));
}
class DonutPieChart extends StatefulWidget {
#override
_DonutPieChartState createState() => new _DonutPieChartState();
}
class _DonutPieChartState extends State<DonutPieChart> {
List<charts.Series<Task, String>> _seriesPieData;
#override
void initState() {
super.initState();
_seriesPieData = List<charts.Series<Task, String>>();
_generateData();
}
_generateData() {
var piedata = [
new Task('T01', 35, Color(0xff3366cc)),
new Task('T02', 8, Color(0xff990099)),
new Task('T03', 10, Color(0xff109618)),
];
_seriesPieData.add(
charts.Series(
domainFn: (Task task, _) => task.task,
measureFn: (Task task, _) => task.taskvalue,
colorFn: (Task task, _) =>
charts.ColorUtil.fromDartColor(task.colorval),
id: 'Sample',
data: piedata,
labelAccessorFn: (Task row, _) => '${row.taskvalue}',
),
);
}
#override
Widget build(BuildContext _context) {
return Scaffold(
appBar: AppBar(
title: Text('Donut chart'),
),
body: GestureDetector(
onTap: () {
Navigator.of(_context).push(new MaterialPageRoute<bool>(
builder: (BuildContext context) => NextScreen()));
},
child: Column(
children: <Widget>[
Expanded(
child: Container(
alignment: Alignment.center,
height: 230,
width: 280,
child: charts.PieChart(_seriesPieData,
animate: true,
animationDuration: Duration(seconds: 1),
defaultInteractions: false,
behaviors: [
new charts.DatumLegend(
outsideJustification:
charts.OutsideJustification.endDrawArea,
horizontalFirst: false,
desiredMaxRows: 3,
cellPadding: new EdgeInsets.only(
left: 8, right: 4.0, bottom: 4.0),
entryTextStyle: charts.TextStyleSpec(
color: charts.Color.fromHex(code: "#000000"),
fontFamily: 'Georgia',
fontSize: 15),
)
],
defaultRenderer: new charts.ArcRendererConfig(
arcWidth: 30,
strokeWidthPx: 0,
arcRendererDecorators: [
new charts.ArcLabelDecorator(
insideLabelStyleSpec: new charts.TextStyleSpec(
fontSize: 16,
color:
charts.Color.fromHex(code: "#000000")),
labelPosition: charts.ArcLabelPosition.inside)
])),
),
),
],
),
));
}
}
class Task {
String task;
double taskvalue;
Color colorval;
Task(this.task, this.taskvalue, this.colorval);
}
class NextScreen extends StatefulWidget {
#override
_NextScreenState createState() => new _NextScreenState();
}
class _NextScreenState extends State<NextScreen> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: Text(' ')),
);
}
}