Grouping Date Axis
Hello,
I have chart that display Month Year as shown below
Would It be possible for sfCartesianChart to group month within a year as screenshot below
Best regards
Sao
Hi Sao,
We have analyzed your query, you can achieve your requirement with help of the multiLevelLabels property in the primaryXAxis. Here, you can use DateTimeAxis as primaryXAxis and use the multiLevelLabels property to show the specific year in the chart as per the following code snippet.
|
SfCartesianChart( primaryXAxis: DateTimeAxis( intervalType: DateTimeIntervalType.months, dateFormat: DateFormat.MMM(), minimum: DateTime(2021, 01), maximum: DateTime(2023, 12), interval: 02, labelAlignment: LabelAlignment.end, multiLevelLabels: [ DateTimeMultiLevelLabel( start: DateTime(2021, 01), end: DateTime(2021, 12), level: 0, text: '2021', ), DateTimeMultiLevelLabel( start: DateTime(2021, 12), end: DateTime(2022, 12), level: 0, text: '2022', ), DateTimeMultiLevelLabel( start: DateTime(2022, 12), end: DateTime(2023, 12), level: 0, text: '2023', ), ], multiLevelLabelStyle: const MultiLevelLabelStyle( borderColor: Colors.grey, borderType: MultiLevelBorderType.rectangle, borderWidth: 2, textStyle: TextStyle( color: Colors.red, fontSize: 12, ), ), ), primaryYAxis: NumericAxis(), series: <CartesianSeries<ChartSampleData, DateTime>>[ ColumnSeries( dataSource: data, xValueMapper: (ChartSampleData sales, int index) => sales.x, yValueMapper: (ChartSampleData sales, int index) => sales.y, ) ], ), |
Snapshot:
Also shared the sample below for your reference.
Regards,
Hari Hara Sudhan. K
Attachment: 183290_1ab576ca.zip
Dear Hari Hara Sudhan. K,
Thank you for provide me the solution, However, if the chart is connected to data dynamically, how can we assign the
multiLevelLabels: []?
Thank you.
Sao
Hi Sao,
We are currently working on the workaround sample to provide the best possible solution from our end and will share further details within one business day on July 11, 2023. We appreciate your patience until then.
Regards,
Hari Hara Sudhan. K
Hi Sao,
We have analyzed your query and to update the multilevel labels dynamically you can use public method updateDataSource using ChartSeriesController and onActualRangeChanged callback. In SfCartesianChart, the multilevel labels will be rendered at the given position at load time itself, so while updating the data points dynamically, the visible minimum and visible maximum of the DateTimeAxis will be changed and thus the multilevel labels will be visible.
For example, here we have rendered the 5 segments with the data points for the 2021 at load time itself. But the multilevel labels for all the 2021, 2022, and 2023 will be rendered and the multilevel label for 2021 will be visible on the screen. While we update the data points dynamically, actual range of the DateTimeAxis changes and thus the multilevel label for the respective data points will be visible on the screen.
Modify the below shared code snippet based on your requirement to achieve the expected output.
|
class _UsagePatternChartState extends State<UsagePatternChart> { ValueNotifier<bool> isRangeExists = ValueNotifier(false); late ChartSeriesController _chartSeriesController; late List<ChartSampleData> data; late Random random; int count = 10;
@override void initState() { data = [ ChartSampleData(DateTime(2021, 01, 01), 60), ChartSampleData(DateTime(2021, 03, 01), 50), ChartSampleData(DateTime(2021, 06, 01), 20), ChartSampleData(DateTime(2021, 09, 01), 80), ChartSampleData(DateTime(2021, 12, 01), 60), ]; random = Random(); super.initState(); }
@override Widget build(BuildContext context) { return Scaffold( body: Center( child: SfCartesianChart( onActualRangeChanged: (ActualRangeChangedArgs rangeChangedArgs) { if (rangeChangedArgs.orientation == AxisOrientation.horizontal) { if (rangeChangedArgs.actualMax > DateTime(2023, 12).millisecondsSinceEpoch) { isRangeExists.value = true; } } }, primaryXAxis: DateTimeAxis( intervalType: DateTimeIntervalType.months, dateFormat: DateFormat.MMM(), interval: 02, multiLevelLabels: [ DateTimeMultiLevelLabel( start: DateTime(2021, 01), end: DateTime(2021, 12), level: 02, text: '2021', ), DateTimeMultiLevelLabel( start: DateTime(2022, 01), end: DateTime(2022, 12), level: 02, text: '2022', ), DateTimeMultiLevelLabel( start: DateTime(2023, 01), end: DateTime(2023, 12), level: 02, text: '2023', ), ], multiLevelLabelStyle: const MultiLevelLabelStyle( borderColor: Colors.grey, borderType: MultiLevelBorderType.rectangle, borderWidth: 2, textStyle: TextStyle( color: Colors.red, fontSize: 12, ), ), ), primaryYAxis: NumericAxis(), series: <CartesianSeries<ChartSampleData, DateTime>>[ ColumnSeries( dataSource: data, xValueMapper: (ChartSampleData sales, int index) => sales.x, yValueMapper: (ChartSampleData sales, int index) => sales.y, onRendererCreated: (ChartSeriesController controller) { _chartSeriesController = controller; }, ), ], ), ), floatingActionButton: Padding( padding: const EdgeInsets.only(left: 20.0, top: 20), child: Align( alignment: Alignment.topLeft, child: ValueListenableBuilder( valueListenable: isRangeExists, builder: (context, value, child) { return FloatingActionButton.small( onPressed: () { if (!isRangeExists.value) { addData(); _chartSeriesController.updateDataSource(addedDataIndex: data.length - 1); } }, child: const Icon(Icons.add), ); }, ), ), ), ); }
void addData() { data.add( ChartSampleData( DateTime(2022, 03).add( Duration(days: count), ), random.nextInt(100), ), ); count = count + 60; } } |
Also attached the recording below for your reference and if you have further queries, please get back to us.
Regards,
Hari Hara Sudhan. K
Attachment: 183290_ce3395cd.zip
- 4 Replies
- 2 Participants
-
SA Sao
- Jul 5, 2023 04:19 AM UTC
- Jul 13, 2023 01:09 PM UTC