0

I have 2 line series in SfCartesianChart. where year is on x-axis and population is on Y axis. each series indicates a country. I added animation duration (20 sec) in chart so that it will give more visual effect of population change over the last 10 years.

I want to show country name (legend) on last datapoint of series , so that it will be more readable when animation is in progress. A sort of: Running snake (lines) having its name on its head (last datapint)

Dharman
  • 30,962
  • 25
  • 85
  • 135
Djai
  • 188
  • 10

1 Answers1

0

Your requirement can be achieved using the annotation feature. We have created a sample for rendering a text at the last point, since the text moves out of the chart area, we have set a visible range for the x-axis to overcome this. We have attached the code snippet below for your reference, we hope it will help you to achieve your scenario.

code snippet:

import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: UpdatedScroll(),
    );
  }
}

class UpdatedScroll extends StatefulWidget {
  const UpdatedScroll({Key? key}) : super(key: key);
  @override
  _UpdatedScrollState createState() => _UpdatedScrollState();
}

class _UpdatedScrollState extends State<UpdatedScroll> {
  _UpdatedScrollState() {
    timer = Timer.periodic(const Duration(seconds: 21), _updateDataSource);
  }
  List<ChartData> chartDataLine = [];
  @override
  void initState() {
    chartDataLine = <ChartData>[
      ChartData(DateTime(2001), 10, 40),
      ChartData(DateTime(2002), 50, 40),
      ChartData(DateTime(2003), 20, 10)
    ];
    super.initState();
  }

  Timer? timer;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: SizedBox(
          child: Stack(
            children: [
              SfCartesianChart(
                onActualRangeChanged: (ActualRangeChangedArgs args) {
                  if (args.axisName == 'primaryXAxis') {
                    args.visibleMax = DateTime(chartDataLine.last.x.year + 1);
                  }
                },
                annotations: <CartesianChartAnnotation>[
                  CartesianChartAnnotation(
                    widget: Container(
                        decoration: const BoxDecoration(
                          borderRadius: BorderRadius.all(Radius.circular(5)),
                          color: Colors.black87,
                        ),
                        height: 20,
                        width: 50,
                        child: const Center(
                            child: Text('China',
                                style: TextStyle(color: Colors.white)))),
                    coordinateUnit: CoordinateUnit.point,
                    x: DateTime(chartDataLine.last.x.year),
                    y: chartDataLine.last.y,
                  ),
                  CartesianChartAnnotation(
                      widget: Container(
                          decoration: const BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(5)),
                            color: Colors.black87,
                          ),
                          height: 20,
                          width: 50,
                          child: const Center(
                              child: Text(
                            'Japan',
                            style: TextStyle(color: Colors.white),
                          ))),
                      coordinateUnit: CoordinateUnit.point,
                      x: DateTime(chartDataLine.last.x.year),
                      y: chartDataLine.last.y1)
                ],
                primaryXAxis:
                    DateTimeAxis(intervalType: DateTimeIntervalType.years),
                series: <ChartSeries<ChartData, DateTime>>[
                  LineSeries(
                    animationDuration: 20000,
                    dataSource: chartDataLine,
                    xValueMapper: (ChartData data, _) => data.x,
                    yValueMapper: (ChartData data, _) => data.y,
                  ),
                  LineSeries(
                    animationDuration: 20000,
                    dataSource: chartDataLine,
                    xValueMapper: (ChartData data, _) => data.x,
                    yValueMapper: (ChartData data, _) => data.y1,
                  ),
                ],
              ),
            ],
          ),
        ));
  }

  void _updateDataSource(Timer timer) {
    chartDataLine.add(ChartData(DateTime(chartDataLine.last.x.year + 1),
        getRandomInt(50, 100), getRandomInt(50, 100)));
    if (chartDataLine.length > 10) {
      chartDataLine.removeAt(0);
    }
    setState(() {});
  }

  int getRandomInt(int min, int max) {
    final Random random = Random();
    return min + random.nextInt(max - min);
  }
}

class ChartData {
  ChartData(this.x, this.y, [this.y1]);
  final DateTime x;
  final int y;
  final int? y1;
}

UG: https://help.syncfusion.com/flutter/cartesian-charts/annotations

yuva
  • 436
  • 4
  • 9
  • This is the only workaround as of now for my requirement. I repeat word workaround. I raised request for line chart race chart and bar chart race chart to syncfusion here : https://www.syncfusion.com/feedback/32379 Please upvote for this requirement whoever need it. – Djai Feb 08 '22 at 12:31