0

我正在使用 Flutter 中的 SyncFusion Charts 创建一个实时图表。将在该图表中显示的折线图的数量取决于运行时,因此我创建了一个方法,该方法将动态添加LineSeries<DataForGraph, double>List<ChartSeries>whereDataForGraph是一个包含图表中使用的时间和值的类。现在,由于每个LineSeries都需要一个单独的控制器(因为不同的折线图将同时具有不同的值),我创建了一个late List<ChartSeriesController> chartSeriesControllerList包含 ChartSeriesController 对象的数量,具体取决于运行时要显示的图形数量。但是,颤振给了我这个错误:

E/flutter ( 3535): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: LateInitializationError: Field '_chartSeriesController@50005135' has not been initialized.
E/flutter ( 3535): #0      _LiveChartState.updateDataSource (package:scan_tabview/widgets/live_chart.dart:189:7)
E/flutter ( 3535): <asynchronous suspension>

我的DataForGraph班级:

class DataForGraph {
  final double time;
  final double value;
  DataForGraph(this.time, this.value);
}

我确实尝试在声明期间对其进行初始化,但是ChartSeriesController()构造函数接受了一个seriesRenderer我不知道如何(以及是否)获取的参数。如何创建多个ChartSeriesControllers?

4

1 回答 1

0

我们怀疑您没有像下面的代码片段那样在 onRendererCreated 回调中分配控制器值,这是导致延迟初始化错误的原因。

LineSeries<_ChartData, int>(
  onRendererCreated: (ChartSeriesController controller) {
    chartSeriesController = controller;
  },
 // Other required properties.
)

我们已经创建了 ChartSeriesController 列表,并为每个系列动态更新了列表,以便它能够正常工作,我们附上了下面的示例代码片段供您参考。

import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:syncfusion_flutter_core/core.dart';

void main() {
  return runApp(ChartApp());
}

class ChartApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Chart Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: LiveLineChart(),
    );
  }
}

class LiveLineChart extends StatefulWidget {
  /// Creates the realtime line chart sample.
  const LiveLineChart({Key? key}) : super(key: key);

  @override
  _LiveLineChartState createState() => _LiveLineChartState();
}

/// State class of the realtime line chart.
class _LiveLineChartState extends State<LiveLineChart> {
  _LiveLineChartState() {
    timer = Timer.periodic(const Duration(milliseconds: 100), (_timer) {
      for (int i = 0; i < 4; i++) {
        _updateDataSource(_timer, chartData[i] as List<_ChartData>,
            chartSeriesController![i]);
      }
    });
  }

  Timer? timer;
  int seriesCount = 2;

  List<List<dynamic>> chartData = [];
  List<_ChartData> chartData1 = [];
  List<_ChartData> chartData2 = [];
  List<_ChartData> chartData3 = [];
  List<_ChartData> chartData4 = [];
  late int count;
  ChartSeriesController? _chartSeriesController1;
  ChartSeriesController? _chartSeriesController2;
  ChartSeriesController? _chartSeriesController3;
  ChartSeriesController? _chartSeriesController4;
  List<dynamic>? chartSeriesController = [];

  @override
  void dispose() {
    timer?.cancel();
    chartData[0].clear();
    chartData[1].clear();
    chartData[2].clear();
    chartData[3].clear();
    super.dispose();
  }

  @override
  void initState() {
    count = 19;
    chartSeriesController = <dynamic>[
      _chartSeriesController1,
      _chartSeriesController2,
      _chartSeriesController3,
      _chartSeriesController4
    ];
    chartData = <List<dynamic>>[chartData1, chartData2, chartData3, chartData4];
    chartData[0] = <_ChartData>[
      _ChartData(0, 42),
    ];
    chartData[1] = <_ChartData>[
      _ChartData(0, 42),
    ];
    chartData[2] = <_ChartData>[
      _ChartData(0, 42),
    ];
    chartData[3] = <_ChartData>[
      _ChartData(0, 42),
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(), body: _buildLiveLineChart());
  }

  /// Returns the realtime Cartesian line chart.
  SfCartesianChart _buildLiveLineChart() {
    return SfCartesianChart(
        plotAreaBorderWidth: 0,
        primaryXAxis:
            NumericAxis(majorGridLines: const MajorGridLines(width: 0)),
        primaryYAxis: NumericAxis(
            axisLine: const AxisLine(width: 0),
            majorTickLines: const MajorTickLines(size: 0)),
        series: getLineSeries());
  }

  List<LineSeries<_ChartData, num>> getLineSeries() {
    List<LineSeries<_ChartData, num>> lineSeries = [];
    for (int i = 0; i < 4; i++) {
      lineSeries.add(LineSeries<_ChartData, int>(
        onRendererCreated: (ChartSeriesController controller) {
          chartSeriesController![i] = controller;
        },
        dataSource: chartData[i] as List<_ChartData>,
        xValueMapper: (_ChartData sales, _) => sales.country,
        yValueMapper: (_ChartData sales, _) => sales.sales,
        animationDuration: 0,
      ));
    }
    return lineSeries;
  }

  ///Continously updating the data source based on timer
  void _updateDataSource(Timer timer, List<_ChartData> chartData,
      ChartSeriesController _chartSeriesController) {
    chartData.add(_ChartData(count, _getRandomInt(10, 100)));
    if (chartData.length == 20) {
      chartData.removeAt(0);
      _chartSeriesController.updateDataSource(
        addedDataIndexes: <int>[chartData.length - 1],
        removedDataIndexes: <int>[0],
      );
    } else {
      _chartSeriesController.updateDataSource(
        addedDataIndexes: <int>[chartData.length - 1],
      );
    }
    count = count + 1;
  }

  ///Get the random data
  int _getRandomInt(int min, int max) {
    final Random _random = Random();
    return min + _random.nextInt(max - min);
  }
}

/// Private calss for storing the chart series data points.
class _ChartData {
  _ChartData(this.country, this.sales);
  final int country;
  final num sales;
}
于 2022-02-21T04:53:35.577 回答