0

I have large sorted list of lists, where each sublist keeps elements of specific day. I’m trying to represent this data using SfCartesianChart with multiple charts, but in my case each day-list have random number of items.

One of results: result

And what I'm trying to display: expected

Also I would like to create 2-leveled label with number of column and day date. I've tried many approaches, but multiple ColumnSeries doesn't seem right to me... Here's my simplest version of code:

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

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

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final List<MyEvent> dayOne = <MyEvent>[
    MyEvent('2023-07-01T15.22', 11),
    MyEvent('2023-07-01T17.43', 10),
    MyEvent('2023-07-01T19.44', 16),
    MyEvent('2023-07-01T23.34', 13),
  ];

  final List<MyEvent> dayTwo = <MyEvent>[
    MyEvent('2023-12-23T08.13', 3),
    MyEvent('2023-12-23T19.55', 4),
  ];
  
  final List<MyEvent> dayThree = <MyEvent>[
    MyEvent('2023-12-27T06.04', 14),
    MyEvent('2023-12-27T10.13', 12),
    MyEvent('2023-12-27T11.46', 11),
  ];
  
  final List<MyEvent> dayFour = <MyEvent>[
    MyEvent('2023-12-31T06.04', 5),
  ];
  
  
  late List<List<MyEvent>> list = [dayOne,dayTwo, dayThree, dayFour];
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: SizedBox(
            height: 300.0,
            child: SfCartesianChart(
              primaryXAxis: CategoryAxis(
                axisLabelFormatter: (details){
                  return ChartAxisLabel(details.text.substring(8,10), const TextStyle(fontSize: 8.0));
                }
              ),
              
              primaryYAxis: NumericAxis(),
              series: List.generate(list.length, (index) {
                return ColumnSeries(
                     dataSource: list[index],
                     xValueMapper: (MyEvent event, i) => event.date,
                     yValueMapper: (MyEvent event, _) => event.value,
                   );
              }),
            ),
          ),
        ),
      ),
    );
  }
}
Dmitry
  • 1
  • 1
  • 3
  • Be aware that the SyncFusion products in the Dart/Flutter pub are *not* open source. They are released under a commercial license that may subject you or your organization to a financial liability, and might affect downstream re-users of your code. – Randal Schwartz May 25 '23 at 22:51
  • Don't they provide free use for sole devs with revenue less then 1kk? If my app gets stable income I'll gladly purchase the licence, charts are cool. – Dmitry May 31 '23 at 15:23
  • The problems are the threshold of five people, and non-transitivity to downstream projects. If you're in to open-source, it's a near-fatal taint in your code. – Randal Schwartz May 31 '23 at 15:28

1 Answers1

0

You can achieve your requirement by using two ColumnSeries in the SfCartesianChart. We have shared a code snippet, user guide documentation and SB link for your reference. Please let us know if you need any further assistance.

code snippet:

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

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

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
     final List<MyEvent> dayOne = <MyEvent>[
           MyEvent('Myanmar', 11),
           MyEvent('India', 10),
           MyEvent('Bangladesh', 16),
           MyEvent('Singapore', 13),
         ];

     final List<MyEvent> dayTwo = <MyEvent>[
          MyEvent('Poland', 3),
          MyEvent('Australia', 4),
    ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: SizedBox(
            height: 300.0,
            width: 300.0,
            child: SfCartesianChart(
              primaryXAxis: CategoryAxis(),
              primaryYAxis: NumericAxis(),
              series: <ColumnSeries<MyEvent, String>>[
                ColumnSeries(
                  dataSource: dayOne,
                  xValueMapper: (MyEvent list, _) => list.date,
                  yValueMapper: (MyEvent list, _) => list.value,
                ),
                ColumnSeries(
                  dataSource: dayTwo,
                  xValueMapper: (MyEvent list, _) => list.date,
                  yValueMapper: (MyEvent list, _) => list.value,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class MyEvent {
  MyEvent(this.date, this.value);
  final String date;
  final double value;
}

SB, https://flutter.syncfusion.com/#/cartesian-charts/axis-types/category/arranged-by-index

UG, https://help.syncfusion.com/flutter/cartesian-charts/axis-types#indexed-category-axis

Note:

By default, the datapoints in the CategoryAxis are arranged based on the x-values. However, in this code snippet, you can arrange the index based on the index value.

Regards,

Lokesh.

  • Hi! My list of days is dynamically editable by user. Lets add couple of days. So, the problem of this approach - ColumnSeries arranges elements according its index in series, so all the Events of dayOne placed at position 0 of a serie, Events of dayTwo - at 1, and so on... I've edited my code and images, thanks anyway Lokesh. – Dmitry May 31 '23 at 14:42