Related
I want to display a chart that retrieve from firebase firestore but its says that
The argument type 'Future<List<PieChartSectionData>>' can't be assigned to the parameter type 'List<PieChartSectionData>?' on the line sections: showingSections();
. Here are my codes,
children: <Widget>[
const SizedBox(height: 18),
Expanded(
child: AspectRatio(
aspectRatio: 1,
child: PieChart(
PieChartData(
pieTouchData: PieTouchData(
touchCallback:
(FlTouchEvent event,
pieTouchResponse) {},
),
borderData: FlBorderData(
//show: false,
),
sectionsSpace: 0,
centerSpaceRadius: 40,
sections: showingSections(), // this is the error //
),
),
),
),
Column(
mainAxisAlignment:
MainAxisAlignment.end,
crossAxisAlignment:
CrossAxisAlignment.start,
children: const <Widget>[
Indicator(
color: Colors.blue,
text: 'Fiest',
isSquare: true,
),
],
),
],
this is my function,
Future<List<PieChartSectionData>> showingSections() async {
int count = await subuhPrayedOnTime();
int count2 = await subuhPrayedLate();
double percentage1 = count * 0.4;
double percentage2 = count2 * 0.10;
return [
PieChartSectionData(
color: Colors.blueAccent,
value: percentage1,
title: '${percentage1.toStringAsFixed(0)}%',
radius: 60,
titleStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
//shadows: shadows,
),
),
PieChartSectionData(
color: Colors.blueAccent,
value: percentage2,
title: '${percentage2.toStringAsFixed(0)}%',
radius: 60,
titleStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
//shadows: shadows,
),
),
];
}
Try changing return type of the function from
Future<List<PieChartSectionData>> showingSections() async {
int count = await subuhPrayedOnTime();
int count2 = await subuhPrayedLate();
double percentage1 = count * 0.4;
double percentage2 = count2 * 0.10;
return [
PieChartSectionData(
color: Colors.blueAccent,
value: percentage1,
title: '${percentage1.toStringAsFixed(0)}%',
radius: 60,
titleStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
//shadows: shadows,
),
),
PieChartSectionData(
color: Colors.blueAccent,
value: percentage2,
title: '${percentage2.toStringAsFixed(0)}%',
radius: 60,
titleStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
//shadows: shadows,
),
),
];
}
To
List<PieChartSectionData> showingSections() async {
int count = await subuhPrayedOnTime();
int count2 = await subuhPrayedLate();
double percentage1 = count * 0.4;
double percentage2 = count2 * 0.10;
return [
PieChartSectionData(
color: Colors.blueAccent,
value: percentage1,
title: '${percentage1.toStringAsFixed(0)}%',
radius: 60,
titleStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
//shadows: shadows,
),
),
PieChartSectionData(
color: Colors.blueAccent,
value: percentage2,
title: '${percentage2.toStringAsFixed(0)}%',
radius: 60,
titleStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
//shadows: shadows,
),
),
];
}
showingSections is a future method, you need to await/FutureBuilder to fetch data.
For your case, create a future on state class[if stateFullWidget].
late final dFuture = showingSections();
and use like
Expanded(
child: FutureBuilder<List<PieChartSectionData>>(
future: dFuture,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data != null) {
return AspectRatio(
aspectRatio: 1,
child: PieChart(
PieChartData(
pieTouchData: PieTouchData(
touchCallback:
(FlTouchEvent event, pieTouchResponse) {},
),
borderData: FlBorderData(
//show: false,
),
sectionsSpace: 0,
centerSpaceRadius: 40,
sections: snapshot.data!, // this is the error //
),
),
);
}
return CircularProgressIndicator();
}),
),
Find more about FutureBuilder
I'm trying to create a line chart off the last 12 hours. I'd like the x-axis to read the labels as "12pm, 5am" respectively. The x-axis labels should only show star/end. When my code gets to this point it freezes the simulator with no errors.
sensorData has 12 objects in it and are stored as a DateTime. The times are hourly based.
final Color lineColor;
final List<SpatialGrowSensor> sensorData;
const SensorLineChart({
Key? key,
required this.sensorData,
required this.lineColor,
}) : super(key: key);
LineChartData sampleData1(List<SpatialGrowSensor> sensorData) {
return LineChartData(
lineTouchData: lineTouchData1(),
gridData: gridData(),
titlesData: titlesData1(),
borderData: borderData(),
lineBarsData: lineBarsData1(),
minY: 0,
maxY: 10,
);
}
LineTouchData lineTouchData1() => LineTouchData(
handleBuiltInTouches: true,
touchTooltipData: LineTouchTooltipData(
tooltipBgColor: Colors.blueGrey.withOpacity(0.8),
),
);
FlTitlesData titlesData1() => FlTitlesData(
bottomTitles: AxisTitles(
sideTitles: bottomTitles(),
),
rightTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
leftTitles: AxisTitles(
sideTitles: leftTitles(),
),
);
List<LineChartBarData> lineBarsData1() => [
lineChartBarData1_1(),
];
Widget leftTitleWidgets(double value, TitleMeta meta) {
const style = TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16,
);
return Text(value.toString(), style: style, textAlign: TextAlign.center);
}
SideTitles leftTitles() => SideTitles(
getTitlesWidget: leftTitleWidgets,
showTitles: true,
reservedSize: 32,
interval: 2,
);
Widget bottomTitleWidgets(double value, TitleMeta meta) {
const style = TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16,
);
// format datetime as '12pm'
String dateFormated = DateFormat('ha').format(DateTime.fromMillisecondsSinceEpoch(value.toInt(), isUtc: true));
Widget text = Text(dateFormated, style: style);
return SideTitleWidget(
axisSide: meta.axisSide,
space: 10,
child: text,
);
}
SideTitles bottomTitles() => SideTitles(
showTitles: true,
reservedSize: 32,
interval: 6,
getTitlesWidget: bottomTitleWidgets,
);
FlGridData gridData() => FlGridData(show: false);
FlBorderData borderData() => FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(color: Color(0xff4e4965), width: 4),
left: BorderSide(color: Colors.transparent),
right: BorderSide(color: Colors.transparent),
top: BorderSide(color: Colors.transparent),
),
);
LineChartBarData lineChartBarData1_1() {
final flSpotData = sensorData.map((sensor) {
return FlSpot(sensor.dateTime.millisecondsSinceEpoch.toDouble(), sensor.sensorValue);
}).toList();
return LineChartBarData(
isCurved: true,
color: lineColor,
barWidth: 4,
dotData: FlDotData(show: false),
belowBarData: BarAreaData(show: false),
preventCurveOverShooting: true,
spots: flSpotData,
);
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: HexColor('#0c110a'),
),
child: SizedBox(
height: 200,
child: Padding(
padding: const EdgeInsets.all(32.0),
child: LineChart(
sampleData1(sensorData),
),
),
),
),
);
}
}```
How to fix this error. Someone can help me?
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
AspectRatio(
aspectRatio: 1.70,
child: Container(
height: 250,
padding: EdgeInsets.all(20),
child: LineChart(
mainData(),
),
),
),
],
);
}
LineChartData mainData() {
return LineChartData(
gridData: FlGridData(
show: true,
drawVerticalLine: true,
getDrawingHorizontalLine: (value) {
return FlLine(
color: Color.fromRGBO(0, 0, 0, 0.3),
strokeWidth: 1,
);
},
getDrawingVerticalLine: (value) {
return FlLine(
color: Color.fromRGBO(0, 0, 0, 0.3),
strokeWidth: 1,
);
},
),
titlesData: FlTitlesData(
show: true,
bottomTitles: SideTitles(
showTitles: true,
reservedSize: 10,
rotateAngle: -90,
textStyle: const TextStyle(color: Color(0xff68737d),
fontWeight: FontWeight.bold, fontSize: 10),
getTitles: (value) { //ERROR textStyle
SideTitle's textStyle property changed to getTextStyles getter (it gives you the axis value, and you must return a TextStyle based on it), It helps you to have a different style for specific text, check it in 0.12.0. Therefore, try:
getTextStyles: (BuildContext context, double v) {
return TextStyle(color: Color(0xff68737d), fontWeight: FontWeight.bold, fontSize: 10);
},
After flutter update the textStyle is changed to getTextStyles. Try below code, hope its help to you. Refer SideTitles
SideTitles(
showTitles: true,
reservedSize: 10,
rotateAngle: -90,
getTextStyles: (BuildContext context, double v) {
return TextStyle(color: Color.red,
fontWeight: FontWeight.bold,
fontSize: 15,
);
},
),
Currently building my first app. Getting data from firebase. Purpose is to hopefully get more people to get the COVID vaccine in Kenya.
Explanation of the code below: A user will use the search function to search for a specific county, then all vaccination posts in that county will show up with the relevant data. There are also 2 buttons, yes and no. Users can vote to let other users know if a vaccination post is still administering vaccines or not. Also, when button is pressed, they should get disabled.
I have a list that buttonPressed that when called, x number of "true" is added depending on the number of vaccination posts available. They are linked together using their index's.
Problem is after adding the buttons, I am getting an "Out of Memory" error.
Without the buttons, it runs as intended. Buttons are important because some vaccination posts are still operational while others are not.
Question:
1 - How can I get passed "Out of Memory" error?
Code:
import 'package:colour/colour.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
// import 'package:shared_preferences/shared_preferences.dart';
class VaccineCenterList extends StatefulWidget {
const VaccineCenterList({key}) : super(key: key);
static const String idScreen = "VaccineCenterList";
#override
_VaccineCenterListState createState() => _VaccineCenterListState();
}
class _VaccineCenterListState extends State<VaccineCenterList> {
List<bool> buttonPressed = [];
buttonControls(numOfDrivers) {
print(numOfDrivers);
while (numOfDrivers > 0) {
buttonPressed.add(true);
}
print(buttonPressed);
}
#override
void initState() {
super.initState();
print("I'm in the vaccine list search screen");
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
backgroundColor: Colors.grey[100],
centerTitle: true,
elevation: 0,
iconTheme: const IconThemeData(
color: Colors.black,
),
title: Text(
"Pamoja",
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 35,
),
),
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: SingleChildScrollView(
child: Column(
children: [
Container(
// textfield
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: hospitalCountyEditingController,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.words,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
style: BorderStyle.solid,
width: 1,
),
),
labelText: "Search County",
labelStyle: const TextStyle(
fontSize: 14.0,
color: Colors.blueGrey,
),
hintStyle: GoogleFonts.lexendMega(
color: Colors.grey,
fontSize: 10,
),
),
style: GoogleFonts.lexendMega(
fontSize: 14,
color: Colors.black,
),
),
),
ElevatedButton(
// search button
onPressed: () {
setState(() {
FocusScope.of(context).requestFocus(
FocusNode(),
);
driverList.clear();
if (hospitalCountyEditingController.text == "" ||
hospitalCountyEditingController.text == " ") {
isTrueOrFalse = "False";
} else {
isTrueOrFalse = "True";
}
});
getHospitalDetails();
},
child: Text(
"Search",
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
),
),
),
SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height,
// height: 50,
// color: Colors.black,
child: Padding(
padding: const EdgeInsets.only(
right: 12.0,
left: 12.0,
bottom: 12.0,
),
child: driverList.isEmpty
? Center(
// child: CircularProgressIndicator(),
child: (isTrueOrFalse == "True")
? const CircularProgressIndicator()
: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Search for one of the counties below",
style:
GoogleFonts.lexendMega()),
),
Text(
"Nairobi, Baringo, Busia, Bomet, Bungoma, Elgeyo Marakwet, Embu, Garissa, Homa Bay, Isiolo, Kajiado, Kakamega, Kericho, Kiambu, Kilifi, Kirinyaga, Kisii, Kisumu, Kitui, Kwale, Laikipia, Lamu, Machakos, Makueni, Mandera, Marsabit, Meru, Migori, Mombasa, Muranga, Nakuru, Nandi, Narok, Nyamira, Nyandarua, Nyeri, Samburu, Siaya County, Taita Taveta, Tana River County, Tharaka Nithi, Trans Nzoia, Turkana, Uasin Gishu, Vihiga, Wajir, West Pokot",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
),
),
],
),
)
: ListView.builder(
itemCount: driverList.length,
itemBuilder: (context, index) {
buttonControls(driverList.length);
final Hospitals hospitals = driverList[index];
final String hospitalLocaiton =
hospitals.location;
final String hospitalPhone = hospitals.phone;
final String hospitalName = hospitals.name;
positiveCount = hospitals.positiveCount;
negativeCount = hospitals.negativeCount;
final int setpercentage =
calculatePositivePercentage(
positiveCount, negativeCount);
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 0,
child: ExpansionTile(
title: Text(
hospitalName.toUpperCase(),
style: GoogleFonts.lexendMega(),
textAlign: TextAlign.center,
),
children: [
Column(
children: [
Container(
child: (hospitalPhone
.isNotEmpty)
? ElevatedButton(
onPressed: () {
Clipboard.setData(
ClipboardData(
text:
hospitalPhone,
),
);
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.green,
content: Text(
"Number Copied",
textAlign:
TextAlign
.center,
),
),
);
},
child: Text(
hospitalPhone,
textAlign:
TextAlign.center,
style: GoogleFonts
.lexendMega(
fontSize: 13),
),
style: ElevatedButton
.styleFrom(
elevation: 0,
),
)
: const Text(""),
),
const SizedBox(
height: 5,
),
hospitalLocaiton.isNotEmpty
? Container(
padding:
const EdgeInsets.all(
8),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
),
borderRadius:
BorderRadius
.circular(10),
),
child: Text(
hospitalLocaiton,
textAlign:
TextAlign.center,
style: GoogleFonts
.lexendMega(
fontSize: 12,
),
),
)
: Text(
hospitalLocaiton,
textAlign:
TextAlign.center,
style: GoogleFonts
.lexendMega(
fontSize: 12,
),
),
const SizedBox(
height: 10,
),
Text(
"$setpercentage% (percent) of voters say this hospital administer vaccines.",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
fontSize: 12,
color: Colors.deepPurple[400],
),
),
const SizedBox(
height: 10,
),
const Divider(
// thickness: 1,
indent: 20,
endIndent: 20,
color: Colors.black87,
),
const SizedBox(
height: 10,
),
Text(
"Does this Hospital administer Vaccines?\n(To help the public, please vote only if you know.)",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
// Container(
// child: (positiveCount == 0)
// ? Text("Votes: $positiveCount")
// : Text("Votes: " +
// positiveCount.toString()),
// ),
Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceEvenly,
children: [
ElevatedButton(
onPressed:
buttonPressed[index]
? () {
positiveIncrement(
hospitalName,
index);
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.redAccent,
content:
Text(
"Voted",
textAlign:
TextAlign.center,
),
),
);
}
: null,
child: Text(
"Yes",
style: GoogleFonts
.lexendMega(),
),
style: ElevatedButton
.styleFrom(
primary:
Colour("#87D68D"),
),
),
ElevatedButton(
onPressed:
buttonPressed[index]
? () {
negativeIncrement(
hospitalName,
index);
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.redAccent,
content:
Text(
"Voted",
textAlign:
TextAlign.center,
),
),
);
}
: null,
child: Text(
"No",
style: GoogleFonts
.lexendMega(),
),
style: ElevatedButton
.styleFrom(
primary:
Colour("#E3655B"),
),
),
],
),
// const SizedBox(
// height: 10,
// ),
// Text(
// "Total No. of Votes: ",
// style:
// GoogleFonts.lexendMega(
// fontSize: 12),
// ),
const SizedBox(
height: 10,
),
Text(
"1 - To vote, tap once\n2 - To Undo vote, tap and hold",
style:
GoogleFonts.lexendMega(
fontSize: 12,
),
textAlign: TextAlign.start,
),
const SizedBox(
height: 10,
),
],
),
],
),
],
),
),
);
},
),
),
),
// SizedBox(height: 40),
],
),
),
],
),
),
),
);
}
}
class Hospitals {
final String name;
final String phone;
final String location;
// final String county;
final int positiveCount;
final int negativeCount;
// final int intPercentage;
// final int totalVotes;
Hospitals({
required this.name,
required this.phone,
required this.location,
// required this.county,
required this.positiveCount,
required this.negativeCount,
// required this.intPercentage,
// required this.totalVotes,
});
static Hospitals fromJson(Map<String, dynamic> json) {
return Hospitals(
name: json['HospitalName'],
phone: json['HospitalPhone'],
// county: json['county'],
location: json['HospitalAddres'],
positiveCount: json['poitiveCount'],
negativeCount: json['negativeCount'],
// intPercentage: json['intPercentage'],
// totalVotes: json['totalVotes']
);
}
}
buttonControls(numOfDrivers) {
print(numOfDrivers);
while (numOfDrivers > 0) {
buttonPressed.add(true);
}
print(buttonPressed);
}
numOfDrivers reference doesn't change over time, because it's a function parameter. Whenever you call buttonControls with numOfDrivers > 0, you get OutOfMemory.
Ask another question. It's a general problem, not related to OutOfMemory statement in title.
I'm Using fl_chart: ^0.12.2 for add PIE chart in to the my app. But i'm unable to add add image on very section
I want something similar to this
Working demo is modification of PieChartSample2
official example https://github.com/imaNNeoFighT/fl_chart/blob/master/example/lib/pie_chart/samples/pie_chart_sample2.dart
You can in PieChartSectionData use badgeWidget and set badgePositionPercentageOffset
/// If [badgeWidget] is not null, it draws a widget at the middle of section,
/// by default it draws the widget at the middle of section, but you can change the
/// [badgePositionPercentageOffset] to have your desire design,
/// the value works the same way as [titlePositionPercentageOffset].
code snippet
List<PieChartSectionData> showingSections() {
return List.generate(4, (i) {
...
final double widgetSize = isTouched ? 55 : 40;
switch (i) {
case 0:
return PieChartSectionData(
color: const Color(0xff0293ee),
value: 40,
title: '40%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/ophthalmology-svgrepo-com.svg',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
case 1:
return PieChartSectionData(
color: const Color(0xfff8b250),
...
working demo
full code of modified PieChartSample2
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'indicator.dart';
class _Badge extends StatelessWidget {
final String svgAsset;
final double size;
final Color borderColor;
const _Badge(
this.svgAsset, {
Key key,
#required this.size,
#required this.borderColor,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: PieChart.defaultDuration,
width: size,
height: size,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
border: Border.all(
color: borderColor,
width: 2,
),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black.withOpacity(.5),
offset: const Offset(3, 3),
blurRadius: 3,
),
],
),
padding: EdgeInsets.all(size * .15),
child: Center(
child: kIsWeb
? Image.network(svgAsset, fit: BoxFit.contain)
: SvgPicture.asset(
svgAsset,
fit: BoxFit.contain,
),
),
);
}
}
class PieChartSample2 extends StatefulWidget {
#override
State<StatefulWidget> createState() => PieChart2State();
}
class PieChart2State extends State {
int touchedIndex;
#override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1.3,
child: Card(
color: Colors.white,
child: Row(
children: <Widget>[
const SizedBox(
height: 18,
),
Expanded(
child: AspectRatio(
aspectRatio: 1,
child: PieChart(
PieChartData(
pieTouchData:
PieTouchData(touchCallback: (pieTouchResponse) {
setState(() {
if (pieTouchResponse.touchInput is FlLongPressEnd ||
pieTouchResponse.touchInput is FlPanEnd) {
touchedIndex = -1;
} else {
touchedIndex = pieTouchResponse.touchedSectionIndex;
}
});
}),
borderData: FlBorderData(
show: false,
),
sectionsSpace: 0,
centerSpaceRadius: 40,
sections: showingSections()),
),
),
),
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[
Indicator(
color: Color(0xff0293ee),
text: 'First',
isSquare: true,
),
SizedBox(
height: 4,
),
Indicator(
color: Color(0xfff8b250),
text: 'Second',
isSquare: true,
),
SizedBox(
height: 4,
),
Indicator(
color: Color(0xff845bef),
text: 'Third',
isSquare: true,
),
SizedBox(
height: 4,
),
Indicator(
color: Color(0xff13d38e),
text: 'Fourth',
isSquare: true,
),
SizedBox(
height: 18,
),
],
),
const SizedBox(
width: 28,
),
],
),
),
);
}
List<PieChartSectionData> showingSections() {
return List.generate(4, (i) {
final isTouched = i == touchedIndex;
final double fontSize = isTouched ? 25 : 16;
final double radius = isTouched ? 60 : 50;
final double widgetSize = isTouched ? 55 : 40;
switch (i) {
case 0:
return PieChartSectionData(
color: const Color(0xff0293ee),
value: 40,
title: '40%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/ophthalmology-svgrepo-com.svg',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
case 1:
return PieChartSectionData(
color: const Color(0xfff8b250),
value: 30,
title: '30%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/ophthalmology-svgrepo-com.svg',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
case 2:
return PieChartSectionData(
color: const Color(0xff845bef),
value: 15,
title: '15%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/ophthalmology-svgrepo-com.svg',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
case 3:
return PieChartSectionData(
color: const Color(0xff13d38e),
value: 15,
title: '15%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/ophthalmology-svgrepo-com.svg',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
default:
return null;
}
});
}
}
full code for png
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'indicator.dart';
class _Badge extends StatelessWidget {
final String svgAsset;
final double size;
final Color borderColor;
const _Badge(
this.svgAsset, {
Key key,
#required this.size,
#required this.borderColor,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: PieChart.defaultDuration,
width: size,
height: size,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
border: Border.all(
color: borderColor,
width: 2,
),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black.withOpacity(.5),
offset: const Offset(3, 3),
blurRadius: 3,
),
],
),
padding: EdgeInsets.all(size * .15),
child: Center(
child: kIsWeb
? Image.network(svgAsset, fit: BoxFit.contain)
: Image.asset(svgAsset, fit: BoxFit.contain) /*SvgPicture.asset(
svgAsset,
fit: BoxFit.contain,
)*/,
),
);
}
}
class PieChartSample2 extends StatefulWidget {
#override
State<StatefulWidget> createState() => PieChart2State();
}
class PieChart2State extends State {
int touchedIndex;
#override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1.3,
child: Card(
color: Colors.white,
child: Row(
children: <Widget>[
const SizedBox(
height: 18,
),
Expanded(
child: AspectRatio(
aspectRatio: 1,
child: PieChart(
PieChartData(
pieTouchData:
PieTouchData(touchCallback: (pieTouchResponse) {
setState(() {
if (pieTouchResponse.touchInput is FlLongPressEnd ||
pieTouchResponse.touchInput is FlPanEnd) {
touchedIndex = -1;
} else {
touchedIndex = pieTouchResponse.touchedSectionIndex;
}
});
}),
borderData: FlBorderData(
show: false,
),
sectionsSpace: 0,
centerSpaceRadius: 40,
sections: showingSections()),
),
),
),
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[
Indicator(
color: Color(0xff0293ee),
text: 'First',
isSquare: true,
),
SizedBox(
height: 4,
),
Indicator(
color: Color(0xfff8b250),
text: 'Second',
isSquare: true,
),
SizedBox(
height: 4,
),
Indicator(
color: Color(0xff845bef),
text: 'Third',
isSquare: true,
),
SizedBox(
height: 4,
),
Indicator(
color: Color(0xff13d38e),
text: 'Fourth',
isSquare: true,
),
SizedBox(
height: 18,
),
],
),
const SizedBox(
width: 28,
),
],
),
),
);
}
List<PieChartSectionData> showingSections() {
return List.generate(4, (i) {
final isTouched = i == touchedIndex;
final double fontSize = isTouched ? 25 : 16;
final double radius = isTouched ? 60 : 50;
final double widgetSize = isTouched ? 55 : 40;
switch (i) {
case 0:
return PieChartSectionData(
color: const Color(0xff0293ee),
value: 40,
title: '40%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/test.png',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
case 1:
return PieChartSectionData(
color: const Color(0xfff8b250),
value: 30,
title: '30%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/test.png',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
case 2:
return PieChartSectionData(
color: const Color(0xff845bef),
value: 15,
title: '15%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/test.png',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
case 3:
return PieChartSectionData(
color: const Color(0xff13d38e),
value: 15,
title: '15%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
badgeWidget: _Badge(
'assets/test.png',
size: widgetSize,
borderColor: const Color(0xff0293ee),
),
badgePositionPercentageOffset: .50,
);
default:
return null;
}
});
}
}