Flutter Pie Chart labelAccessorFn无法正常工作

时间:2019-03-18 12:57:19

标签: android dart flutter

注意:我使用此答案How to add label to pieChart flutter作为实现labelAccessorFn的参考。

我正在使用 charts_flutter 包在我的Flutter应用中显示图表,据我所知,我们使用labelAccessorFn在饼图中显示标签,但在我的情况下不起作用。

应用概述: 这是一个心情检查器应用程序,用户每天使用5种表情符号之一来选择心情,并在图表中显示表情符号与被选择天数的数据。

图表文件(labelAccessorFn在addChartData方法中定义):

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'];

数据库文件

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 个答案:

答案 0 :(得分:0)

您需要在ArcRendererConfig中定义一个arcRendererDecorator。示例:

    defaultRenderer: charts.ArcRendererConfig(
      arcRendererDecorators: [
       new charts.ArcLabelDecorator(
         labelPosition: charts.ArcLabelPosition.inside,
         insideLabelStyleSpec: new charts.TextStyleSpec(fontSize: 16, color: 
           charts.Color.fromHex(code: "#FFFFFF")))
     ]),