问题
Note: I used this answer How to add label to pieChart flutter as a reference to implement labelAccessorFn.
I am using charts_flutter package to display charts in my flutter app, as far as I know, we use labelAccessorFn to show labels in Pie Chart but it's not working in my case.
App Overview: It's a mood checker app where user chose its mood every day using one of 5 emojis and in charts, we display data of emoji vs num of days it's been chosen.
chart file(labelAccessorFn is defined in addChartData method):
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import '../models/mood_db.dart';
import 'dart:async';
class Mood {
String _emoji;
int _numOfDays; // this has to int bcz charts can't take future<int>
charts.Color _color;
Mood(this._emoji, this._numOfDays, this._color);
}
class MoodChart extends StatefulWidget {
@override
_MoodChartState createState() => _MoodChartState();
}
class _MoodChartState extends State<MoodChart> {
DatabaseHelper _databaseHelper = DatabaseHelper();
List<Mood> _data;
var isDataFilled;
List<charts.Series<Mood, String>> _chartData;
//returns a Future with a list of results.
Future<List<int>> numOfDaysFn(List<int> emojiID) async {
return Future.wait(emojiID.map((d) => _databaseHelper.numOfMoodDays(d)));
}
void initData(List<int> emojiIds, List<int> days) {
_chartData = List<charts.Series<Mood, String>>();
setState(() {
addData(days);
addChartData();
});
}
void addData(days) {
_data = <Mood>[
Mood(allMoods[0], days[0], charts.MaterialPalette.red.shadeDefault),
Mood(allMoods[1], days[1], charts.MaterialPalette.blue.shadeDefault),
Mood(allMoods[2], days[2], charts.MaterialPalette.gray.shadeDefault),
Mood(allMoods[3], days[3], charts.MaterialPalette.indigo.shadeDefault),
Mood(allMoods[4], days[4], charts.MaterialPalette.green.shadeDefault),
];
}
void addChartData() {
_chartData.add(charts.Series(
id: 'Mood',
data: _data,
colorFn: (Mood mood, _) => mood._color,
domainFn: (Mood mood, _) => mood._emoji,
measureFn: (Mood mood, _) => mood._numOfDays, //No longer a futures
// I don't know what's wrong with this:
labelAccessorFn: (Mood mood, _) => '${mood._emoji}'));
}
@override
void initState() {
super.initState();
var emojiID = [1, 2, 3, 4, 5];
numOfDaysFn(emojiID).then((days) {
initData(emojiID, days);
});
}
@override
Widget build(BuildContext context) {
if (_chartData != null) {
return ListView(
children: <Widget>[
Container(
height: 450,
child: Card(
elevation: 5.0,
child: charts.PieChart(_chartData,
animate: true,
defaultRenderer: charts.ArcRendererConfig(arcWidth: 120)),
),
),
],
);
} else {
return Center(child: CircularProgressIndicator()); //Added a loading icon
}
}
}
List allMoods = ['Disgusting', 'Bad', 'Ok', 'Good', 'Amazing'];
DataBase file:
import 'package:path/path.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:io';
import '../models/mood_model.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
bool dataFilled = false;
final String tableName = "moodTable";
final String colMoodId = "moodId";
final String colEmojiId = "emojiId";
final String colActId = "actId";
final String colMoodDay = "moodDay";
final String colMoodMonth = "moodMonth";
final String colMoodYear = "moodYear";
static Database _db;
Future<Database> get db async {
if (_db == null) {
return initDb();
}
return _db;
}
DatabaseHelper.internal();
Future<Database> initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "mood.db");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return ourDb;
}
void _onCreate(Database db, int version) async {
await db.execute(
"CREATE TABLE moodTable (moodId INTEGER PRIMARY KEY, emojiId INTEGER, actId INTEGER, moodDay INTEGER, moodMonth INTEGER, moodYear INTEGER)");
print("Table Created");
}
// insert
Future<int> saveMood(Mood mood) async {
// if (mood.moodDay == DateTime.now().day &&
// mood.moodMonth == DateTime.now().month &&
// mood.moodYear == DateTime.now().year) {
// var dbClient = await db;
// print('Updated');
// return await dbClient.update("$tableName", mood.toMap(),
// where: "$colMoodId = ?", whereArgs: [mood.moodID]);
// } else {
var dbClient = await this.db;
int result = await dbClient.insert("$tableName", mood.toMap());
dataFilled = true;
return result;
// }
}
// // update
// Future<int> updateMood(Mood mood) async {
// }
// to get number of mood days
Future<List<Map<String, dynamic>>> listOfMoods() async {
Database db = await this.db;
var result = await db.query(tableName, orderBy: '$colMoodId ASC');
return result;
}
Future<int> numOfMoodDays(int emojiID) async {
Database db = await this.db;
var result = await db.query(tableName,
orderBy: '$colMoodId ASC',
where: '$colEmojiId = ?',
whereArgs: [emojiID]);
return result.length;
}
Future<int> actData(int actID, int emojiID) async {
Database db = await this.db;
var result = await db.rawQuery(
'SELECT * FROM $tableName WHERE $colActId = $actID AND $colEmojiId = $emojiID ');
return result.length;
}
Future<bool> isDataFilled() async {
Database db = await this.db;
var result = await db.query(
tableName,
orderBy: '$colMoodId ASC',
);
if (result.length > 0) {
return true;
} else {
return false;
}
}
// close db
Future close() async {
var dbClient = await db;
return dbClient.close();
}
}
回答1:
You need to define a arcRendererDecorator in ArcRendererConfig. Example:
defaultRenderer: charts.ArcRendererConfig(
arcRendererDecorators: [
new charts.ArcLabelDecorator(
labelPosition: charts.ArcLabelPosition.inside,
insideLabelStyleSpec: new charts.TextStyleSpec(fontSize: 16, color:
charts.Color.fromHex(code: "#FFFFFF")))
]),
来源:https://stackoverflow.com/questions/55221941/flutter-pie-chart-labelaccessorfn-is-not-working