In this article, we explain how to apply the different gradients to each column in our Flutter SfCartesianChart feature tour page. In the SfCartesianChart widget we can apply different gradient to each column by using the onCreateRenderer callback. Here we need to create a custom column series renderer and return that in onCreateRenderer callback instead of the default renderer. The following steps explain how to apply the different gradients to each column in ColumnSeries . Step 1: Initialize the _chartData variable which holds the data source for the chart. late List<_ChartData> chartData; @override void initState() { chartData = <_ChartData>[ _ChartData('Jan', 35), _ChartData('Feb', 28), _ChartData('Mar', 34), _ChartData('Apr', 32), _ChartData('May', 40) ]; super.initState(); } class _ChartData { _ChartData(this.year, this.sales); final String year; final double sales; } Step 2: Create a class _ColumnCustomPainter which is extended from ColumnSegment. In this class based on the index, we will be painting the columns with the required gradient color. So, get the current segment index and store it internally for further process as in the below code. class _ColumnCustomPainter<T, D> extends ColumnSegment<T, D> { @override int get currentSegmentIndex => super.currentSegmentIndex; } Step 3: Initialize the gradientList variable which holds gradients for each column. Override the onPaint method from ColumnSegment, and set the gradient to the shader property using the createShader method of the gradient. class _ColumnCustomPainter<T, D> extends ColumnSegment<T, D> { @override int get currentSegmentIndex => super.currentSegmentIndex; @override void onPaint(Canvas canvas) { final List<LinearGradient> gradientList = <LinearGradient>[ const LinearGradient( colors: <Color>[Colors.cyan, Colors.greenAccent], stops: <double>[0.2, 0.9] ), const LinearGradient( colors: <Color>[Colors.pink, Colors.purpleAccent], stops: <double>[0.2, 0.9] ), const LinearGradient( colors: <Color>[Colors.deepPurple, Colors.blue], stops: <double>[0.2, 0.9] ), const LinearGradient( colors: <Color>[Colors.deepOrange, Colors.amber], stops: <double>[0.2, 0.9] ), const LinearGradient( colors: <Color>[Colors.blue, Colors.cyanAccent], stops: <double>[0.2, 0.9] ) ]; fillPaint!.shader = gradientList[currentSegmentIndex].createShader(segmentRect.outerRect); super.onPaint(canvas); } } Step 4: Create a class _customColumnSeriesRenderer which is extended from ColumnSeriesRenderer and in the createSegment method return the _ColumnCustomPainter, so that the column series will get paint based on the fill applied in _ColumnCustomPainter class. class _CustomColumnSeriesRenderer<T, D> extends ColumnSeriesRenderer<T, D> { _CustomColumnSeriesRenderer(); @override ColumnSegment<T, D> createSegment() { return _ColumnCustomPainter<T, D>(); }}Step 5: Now create the SfCartesianChart widget with the ColumnSeries, assign the chartData to the dataSource property, and map the x, y values to xValueMapper, yValueMapper properties respectively. In the onCreateRenderer callback, return the _CustomColumnSeriesRenderer. SfCartesianChart( primaryXAxis: CategoryAxis(), series: <ColumnSeries<_ChartData, String>>[ ColumnSeries<_ChartData, String>( dataSource: chartData, onCreateRenderer: (ChartSeries<_ChartData, String> series) { return _CustomColumnSeriesRenderer(); }, xValueMapper: (_ChartData data, _) => data.year, yValueMapper: (_ChartData data, _) => data.sales, ) ] ) Now the column series will render with different gradients to each column points as in below image. View the sample in GitHub.ConclusionI hope you enjoyed learning about ow apply different gradients to each column in Flutter SfCartesianChart.You can refer to our Flutter CartesianChart feature tour page to know about its other groundbreaking feature representations. You can also explore our documentation to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In this article, we explain how to export the pie chart as an image using the Flutter circular chart. The SfCircularChart widget provides an option to export the chart as an image. The following steps explain how to accomplish this exporting functionality. Step 1: Initialize the variable _chartData which stores the data source and initialize the variable _circularChartKey which stores the global key of rendering the circular chart. This key is used to convert the chart into an image. late GlobalKey<SfCircularChartState> _circularChartKey; late List<ChartSampleData> _chartData; @override void initState() { _circularChartKey = GlobalKey(); _chartData = < ChartSampleData >[ ChartSampleData ('Jan', 12), ChartSampleData ('Feb', 28), ChartSampleData ('Mar', 35), ChartSampleData ('Apr', 47), ChartSampleData ('Jun', 56), ChartSampleData ('Jul', 70), ]; super.initState(); } class ChartSampleData { ChartSampleData ({this.x, this.y}); final String? x; final num? y; } Step 2: Now create the SfCircularChart widget with the PieSeries and assign the _chartData to the dataSource property and map the x, y values to xValueMapper, yValueMapper properties respectively. And also assign the _circularChartKey to the key property. SfCircularChart( key: _circularChartKey, series: <CircularSeries< ChartSampleData, String>>[ PieSeries< ChartSampleData, String>( dataSource: _chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y ) ], ) Step 3: Import the dart files dart:typed_data and dart.ui files to use the Uint8List, ByteData. import 'dart:typed_data'; import 'dart:ui' as ui; Step 4: Create a separate method called _renderCircularImage in which we have converted the rendered circular chart to Image by using the toImage method. Then using this Image, convert it into a byte array using toByteData method. Further creates the Uint8List from the byte array which was shown on the new page. Future<void> _renderCircularImage() async { final ui.Image? data = await _circularChartKey.currentState!.toImage(pixelRatio : 3.0); final ByteData? bytes = await data!.toByteData(format : ui.ImageByteFormat.png); final Uint8List imageBytes = bytes!.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes); await Navigator.of(context).push<dynamic>( MaterialPageRoute<dynamic>( builder: (BuildContext context) { return Scaffold( body:Image.memory(imageBytes) ); }, ), ); } Step 5: Add the TextButton widget and call the _renderCircularImage method to render the chart image on a new page. @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ SfCircularChart( key: _circularChartKey, series: <CircularSeries<ChartSampleData, String>>[ PieSeries<ChartSampleData, String>( dataSource: _chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y, ) ] ), TextButton( child: Text('Export as image'), onPressed: () { _renderCircularImage(); }, ) ] ); } Now if we tap the TextButton the exported image of the circular chart will render on the new page. View the sample in GitHub.
In this article, we explain how to use SVG image in the cartesian chart tooltip by using the Flutter Cartesian Chart. In the SfCartesianChart widget, we can render the SVG image in the cartesian chart tooltip by using the builder property of TooltipBehavior. The following steps explain how to achieve this, Step 1: To access SVG images, add the flutter_svg dependency to the pubspec file. Also, ensure that the SVG image has been added to the project and is referred to the pubspec's assets. dependencies: flutter_svg: ^1.0.3 flutter: assets: - assets/ Step 2: Initialize the _chartData variable in the initState method, which contains the chart's data source. And access the SVG image from the asset folder using the SvgPicture.asset. Find the code below to accomplish this. import 'package:flutter_svg/svg.dart'; late List<_ChartData> _chartData; late TooltipBehavior _tooltipBehavior; @override void initState() { _chartData = <_ChartData>[ _ChartData('Jan', 35), _ChartData('Feb', 28), _ChartData('Mar', 34), _ChartData('Apr', 32), _ChartData('May', 40) ]; _tooltipBehavior = TooltipBehavior( enable: true, builder: (dynamic data, dynamic point, dynamic series, int pointIndex, int seriesIndex) { return SizedBox( child: SvgPicture.asset('assets/circle.svg') ); } ); super.initState(); } class _ChartData { _ChartData(this.year, this.sales); final String year; final double sales; } Step 3: Now create the SfCartesianChart widget with the ColumnSeries and initialize the required properties. And also assign the _tooltipBehavior to the tooltipBehavior property. @override Widget build(BuildContext context) { return SfCartesianChart( tooltipBehavior: _tooltipBehavior, primaryXAxis: CategoryAxis(), series: <ColumnSeries<_ChartData, String>>[ ColumnSeries<_ChartData, String>( dataSource: _chartData, xValueMapper: (_ChartData data, _) => data.year, yValueMapper: (_ChartData data, _) => data.sales ) ] ); } Now the cartesian chart tooltip will render with the SVG image. View the sample in GitHub.ConclusionI hope you enjoyed learning about how to use SVG image in Flutter Cartesian Chart tooltip.You can refer to our Flutter Cartesian Chart feature tour page to know about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications. You can also explore our Flutter Cartesian Chart example to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In this article, we explain how to export the cartesian chart as a PDF using the Flutter cartesian chart. The SfCartesianChart widget provides an option to export the chart in PDF format. The following steps explain how to accomplish this exporting functionality. Step 1: To access the path from mobile and other platforms, add the path_provider package as a dependency in the application. And add syncfusion_flutter_pdf package as a dependency to create and access PDF files. path_provider: ^2.0.9 syncfusion_flutter_charts: ^20.1.48 syncfusion_flutter_pdf: ^20.1.48-beta Step 2: It is necessary to include the platform-specific file generating codes to save the file as a PDF document. So, we have created two dart files (save_file_mobile and save_file_web) to save and launch the file on different platforms. On that two dart files, we have provided the common method called saveAndLaunchFile to save the exported content as a file. To download the PDF file in the web platform, we should add AnchorElement from dart:html in this save_file_web file. save_file_web.dart import 'dart:async'; import 'dart:convert'; import 'dart:html'; class FileSaveHelper { static Future<void> saveAndLaunchFile( List<int> bytes, String fileName) async { AnchorElement( href: 'data:application/octet-stream;charset=utf-16le;base64,${base64.encode(bytes)}') ..setAttribute('download', fileName) ..click(); } } To download the PDF file on the mobile and other platforms, we use this save_file_mobile file. save_file_mobile.dart import 'dart:io'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; class FileSaveHelper { static const MethodChannel _platformCall = MethodChannel('launchFile'); static Future<void> saveAndLaunchFile( List<int> bytes, String fileName) async { String? path; if (Platform.isAndroid || Platform.isIOS || Platform.isLinux || Platform.isWindows) { final Directory directory = await getApplicationSupportDirectory(); path = directory.path; } else { path = await PathProviderPlatform.instance.getApplicationSupportPath(); } final File file = File(Platform.isWindows ? '$path\\$fileName' : '$path/$fileName'); await file.writeAsBytes(bytes, flush: true); if (Platform.isAndroid || Platform.isIOS) { final Map<String, String> argument = <String, String> { 'file_path': '$path/$fileName' }; try { final Future<Map<String, String>?> result = _platformCall.invokeMethod('viewPdf', argument); } catch (e) { throw Exception(e); } } else if (Platform.isWindows) { await Process.run('start', <String>['$path\\$fileName'], runInShell: true); } else if (Platform.isMacOS) { await Process.run('open', <String>['$path/$fileName'], runInShell: true); } else if (Platform.isLinux) { await Process.run('xdg-open', <String>['$path/$fileName'], runInShell: true); } } } Step 3: Initialize the variable _chartData which stores the data source and initialize the variable _cartesianChartKey which stores the global key of rendering the cartesian chart. This key is used to convert the chart into an image and we will use that image to create a PDF file. And create the SfCartesianChart widget with the necessary properties. //Add the necessary imports import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import '../save_file_mobile.dart' if (dart.library.html) '../save_file_web.dart'; import 'dart:async'; import 'package:syncfusion_flutter_charts/charts.dart'; import 'package:syncfusion_flutter_pdf/pdf.dart'; late GlobalKey<SfCartesianChartState> _cartesianChartKey; late List<ChartSampleData> _chartData; @override void initState() { _cartesianChartKey = GlobalKey(); _chartData = < ChartSampleData >[ ChartSampleData ('Jan', 12), ChartSampleData ('Feb', 28), ChartSampleData ('Mar', 35), ChartSampleData ('Apr', 27), ChartSampleData ('Jun', 42), ChartSampleData ('Jul', 33) ]; super.initState(); } @override Widget build(BuildContext context) { return SfCartesianChart( key: _cartesianChartKey, primaryXAxis: CategoryAxis(), series: <ColumnSeries< ChartSampleData, String>>[ ColumnSeries< ChartSampleData, String>( dataSource: _chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y ) ] ) } class ChartSampleData { ChartSampleData ({this.x, this.y}); final String? x; final num? y; } Step 4: Create a separate method called _renderPdf where we export the chart as a PDF. Added a snack bar to notify the chart is exported as a PDF document. Future<void> _ renderPdf () async { final ui.Image data = await _ cartesianChartKey.currentState!.toImage(pixelRatio : 3.0); final ByteData? bytes = await data.toByteData(format : ui.ImageByteFormat.png); final Uint8List imageBytes = bytes!.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes); final PdfBitmap bitmap = PdfBitmap(imageBytes); final PdfDocument document = PdfDocument(); document.pageSettings.size = Size(bitmap.width.toDouble(), bitmap.height.toDouble()); final PdfPage page = document.pages.add(); final Size pageSize = page.getClientSize(); page.graphics.drawImage(bitmap, Rect.fromLTWH(0, 0, pageSize.width, pageSize.height)); await FileSaveHelper.saveAndLaunchFile(document.save(), 'cartesian_chart.pdf'); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(5)) ), duration: Duration(milliseconds: 200), content: Text('Chart has been exported as PDF document.'), ) ); Step 5: Add the TextButton widget and call the _renderPdf method to convert the rendered chart as PDF. @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ SfCartesianChart( key: _ cartesianChartKey, primaryXAxis: CategoryAxis(), series: <ColumnSeries<ChartSampleData, String>>[ ColumnSeries<ChartSampleData, String>( dataSource: _chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y, ) ] ), TextButton( child: const Text('Export as PDF), onPressed: () { _renderPdf(); }, ) ] ); } Now if we tap the TextButton ,the exported PDF of the cartesian chart will be downloaded. View the sample in GitHub.
In this article, we explain how to localize the default texts in Flutter cartesian chart. The SfCartesianChart widget provides localization support, based on the current locale the build-in text for legend and tooltips are translated automatically. You can use the either in-build texts or customized texts. The following step explain how to use in-build text in the SfCartesianChart widget. Step 1: Add syncfusion_flutter_charts and syncfusion_localizations packages in pubspec file and also add the necessary imports. We can change the locale of the flutter charts using the locale property of MaterialApp widget. Add SfGlobalLocalizations.delegate in the localizationsDelegate and add the supported locales, so based on this we can render the application. Create the SfCartesianChart widget with the necessary properties. Add the tooltipBehavior and legend to ensure the localization changes. import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; /// To use the default localized text values. import 'package:syncfusion_localizations/syncfusion_localizations.dart'; late List<ChartData> _chartData; late TooltipBehavior _tooltipBehavior; Locale? _locale; String? currentLocale = 'en'; List<String> localeList = ['en', 'es'].toList(); @override void initState() { _chartData = <ChartData>[ ChartData(1, 23), ChartData(2, 24), ChartData(3, 32), ChartData(4, 36), ChartData(5, 27) ]; _locale = const Locale('en'); _tooltipBehavior = TooltipBehavior(enable: true); super.initState(); } @override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, //Add our delegate here to use the localized texts of our widgets SfGlobalLocalizations.delegate ], supportedLocales: const [ Locale('en'), Locale('es'), ], Locale: _locale, home: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ const Text('Locale:'), Radio<String>( value: 'en', groupValue: currentLocale, onChanged: (String? value) { setState(() { currentLocale = value; _onLocaleChanged(value!); }); }, ), const Text('en'), Container( padding: const EdgeInsets.only(left: 5), child: Radio<String>( value: 'es', groupValue: currentLocale, onChanged: (String? value) { setState(() { currentLocale = value; _onLocaleChanged(value!); }); }, ), ), const Text('es') ], ), SfCartesianChart( legend: Legend(isVisible: true), tooltipBehavior: TooltipBehavior(enable: true), series: <ColumnSeries<ChartData, double>>[ ColumnSeries<ChartData, double>( dataSource: _chartData, xValueMapper: (ChartData data, _) => data.x, yValueMapper: (ChartData data, _) => data.y ), ] ), ] ); void _onLocaleChanged(String changedLocale) { if (changedLocale == 'en') { _locale = const Locale('en'); } else { _locale = const Locale('es'); } } } class ChartData { ChartData(this.x, this.y); final double x; final double y; } The above codes render the legend with default en language and tooltip header values as default localized texts as below. The following steps explains how to use customized values. Step 1: To use the customized localized values, first create the localization.dart file in the lib folder. Then create a class for the culture from SfLocalizations class and override the required field values as needed. import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_core/localizations.dart'; class SfLocalizationEs extends SfLocalizations { SfLocalizationEs(); /// Need to add other overridden fields here. @override /// Customized the chart widget field only here. String get series => 'Customized string’; } Step 2: Add the delegate class for custom text in the localization.dart file. class SfLocalizationEsDelegate extends LocalizationsDelegate<SfLocalizations> { const SfLocalizationEsDelegate(); @override bool isSupported(Locale locale) => locale.languageCode == 'es'; @override Future<SfLocalizations> load(Locale locale) { return SynchronousFuture<SfLocalizations>(SfLocalizationEs()); } @override bool shouldReload(LocalizationsDelegate<SfLocalizations> old) => true; } Step 3: Call the delegate class in localizationsDelegate of MaterialApp widget instead of using SfGlobalLocalizations.delegate to override the localized values in the main.dart file. //import other required packages //import the newly created localization file here import 'localization.dart'; MaterialApp( localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, SfLocalizationEsDelegate() ], supportedLocales: const [ Locale('en'), Locale('es'), ], locale: const Locale('es'), home: SfCartesianChart( /// Need to add necessary properties for charts here. ) ); The above codes render the chart with custom texts in SfCartesianChart widget. View the sample in GitHub.
In this article, we explain how to apply point color to the tracker in the radial bar series by using the Flutter circular chart. The SfCircularChart widget supports for RadialBarseries, here we can apply different colors to each tracker of the radial bar using the pointColorMapper, trackOpacity, and useSeriesColor properties from RadialBarseries. The following steps explain how to apply point color to the trackers in the radial bar series. Step 1: Initialize the chartData variable which holds the data source for the chart. Here add the color for each data point. late List<ChartData> chartData; @override void initState() { chartData = <ChartData>[ ChartData(1, 11, const Color.fromRGBO(248, 177, 149, 1.0)), ChartData(2, 12, const Color.fromRGBO(246, 114, 128, 1.0)), ChartData(3, 13, const Color.fromRGBO(61, 205, 171, 1.0)), ChartData(4, 14, const Color.fromRGBO(1, 174, 190, 1.0)), ]; super.initState(); } class ChartData { ChartData(this.x, this.y, this.color); final int x; final int y; final Color color; } Step 2: Create the SfCircularChart widget with the RadialBarseries and initialize the required properties. To apply the point’s color to the tracker, set useSeriesColor as true and map the color from chartData to pointColorMapper property. Set opacity for the tracker using the trackOpacity property. @override Widget build(BuildContext context) { return SfCircularChart( series: <RadialBarSeries<ChartData, int>>[ RadialBarSeries<ChartData, int>( dataSource: chartData, useSeriesColor: true, trackOpacity: 0.3, gap: ‘6%’, xValueMapper: (ChartData data, _) => data.x, yValueMapper: (ChartData data, _) => data.y, pointColorMapper: (ChartData data, _) => data.color ) ] ); } Now the radial bar series will render with different colors on each tracker. View the sample in GitHub. ConclusionI hope you enjoyed learning how to apply point color to the tracker in the radial bar series (SfCircularChart).You can refer to our Flutter Circular Chart feature tour page to know about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications. You can also explore our Flutter Circular Chart example to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In this article, we explain how to calculate the value axis range based on the visible data points in Flutter Cartesian chart. In the SfCartesianChart widget, we can control the range of the value axis by using the anchorRangeToVisiblePoints property. It is applicable for value axes only. If we set anchorRangeToVisiblePoints as false, the y axis range is calculated for the overall data points available in the data source. If we set anchorRangeToVisiblePoints as true, the value axis range will be calculated for the data points available in the viewport. By default, the anchorRangeToVisiblePoints is true. The following steps explain how to represent the y axis range by considering the visible data points on panning in the SfCartesianChart widget. Step 1: Initialize the chartData variable which holds the data source for the chart. late List<_ChartData> chartData; @override void initState() { chartData = <_ChartData>[ _ChartData(1, 10), _ChartData(2, 20), _ChartData(3, 30), _ChartData(4, 40), _ChartData(5, 50), _ChartData(6, 60), _ChartData(7, 70), _ChartData(8, 80), _ChartData(9, 90), _ChartData(10, 100) ]; super.initState(); } class _ChartData { _ChartData(this.x, this.y); final int x; final int y; } Step 2: Now create the SfCartesianChart widget with the ColumnSeries and assign the chartData to the dataSource property and map the x, y values to xValueMapper, yValueMapper properties respectively. SfCartesianChart( series: <ColumnSeries<_ChartData, int>>[ ColumnSeries<_ChartData, int>( dataSource: chartData, xValueMapper: (_ChartData data, _) => data.x, yValueMapper: (_ChartData data, _) => data.y ), ], ) Step 3: Set initialVisibleMinimum and initialVisibleMaximum for the x-axis. Enable the panning and set zoomMode as ZoomMode.x in zoompanBehavior. late ZoomPanBehavior _zoomPanBehavior; @override void initState() { _zoomPanBehavior = ZoomPanBehavior( enablePanning: true, zoomMode: ZoomMode.x ); super.initState(); } SfCartesianChart( primaryXAxis: NumericAxis( initialVisibleMinimum: 2, initialVisibleMaximum: 6, ), primaryYAxis: NumericAxis( anchorRangeToVisiblePoints: true ), zoomPanBehavior: _zoomPanBehavior, series: <ColumnSeries<ChartData, int>>[ ColumnSeries<ChartData, int>( dataSource: chartData, xValueMapper: (ChartData data, _) => data.x, yValueMapper: (ChartData data, _) => data.y ), ] ) On panning the chart, depending on the y-value the y-axis range can be changed as shown in the below image.
In this article we explain how to render a line at the specific value using the Flutter SfCartesianChart widget. Our Flutter Cartesian chart provides an option to render a line at a specific value using the plot band feature. The following steps explains how to add plot band feature in both x and y axes to add a line. Render a line in x-axis Step 1: Declare and initialize the required data source for the chart. final List<ChartSampleData> chartData = <ChartSampleData>[ ChartSampleData(x: 'Jan', y: 23), ChartSampleData(x: 'Feb', y: 24), ChartSampleData(x: 'Mar', y: 23), ChartSampleData(x: 'Apr', y: 22), ChartSampleData(x: 'May', y: 21), ChartSampleData(x: 'Jun', y: 27), ChartSampleData(x: 'Jul', y: 33), ChartSampleData(x: 'Aug', y: 36), ChartSampleData(x: 'Sep', y: 23), ChartSampleData(x: 'Oct', y: 25), ChartSampleData(x: 'Nov', y: 22) ]; Step 2: Then initialize the SfCartesianChart widget and then initialize the axes with other required properties. SfCartesianChart( primaryXAxis: CategoryAxis(), primaryYAxis: NumericAxis(), series: <LineSeries<ChartSampleData, String>>[ LineSeries<ChartSampleData, String>( dataSource: chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y) ], ) Step 3: Then add the plotBands property to the primaryXAxis and set the start and end value of the plot band as same value.Here we have used the category axis as primaryXAxis, so you need to specify the index value in the start and end properties SfCartesianChart( primaryXAxis: CategoryAxis( plotBands: <PlotBand>[ PlotBand( start: 7, end: 7, //Specify the width for the line borderWidth: 2, //Specify the color for the line borderColor: Colors.black, //Specify the dash array for the line dashArray: const <double>[4, 5]) ]), primaryYAxis: NumericAxis(), series: <LineSeries<ChartSampleData, String>>[ LineSeries<ChartSampleData, String>( dataSource: chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y) ], ) Render a line in y-axis Step 1: Declare and initialize the required data source for the chart. final List<ChartSampleData> chartData = <ChartSampleData>[ ChartSampleData(x: 'Jan', y: 23), ChartSampleData(x: 'Feb', y: 24), ChartSampleData(x: 'Mar', y: 23), ChartSampleData(x: 'Apr', y: 22), ChartSampleData(x: 'May', y: 21), ChartSampleData(x: 'Jun', y: 27), ChartSampleData(x: 'Jul', y: 33), ChartSampleData(x: 'Aug', y: 36), ChartSampleData(x: 'Sep', y: 23), ChartSampleData(x: 'Oct', y: 25), ChartSampleData(x: 'Nov', y: 22) ]; Step 2: Then initialize the SfCartesianChart widget and then initialize the axes with other required properties. SfCartesianChart( primaryXAxis: CategoryAxis(), primaryYAxis: NumericAxis(), series: <LineSeries<ChartSampleData, String>>[ LineSeries<ChartSampleData, String>( dataSource: chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y) ], ) Step 3: Then add the plotBands property to the primaryXAxis and set the start and end value of the plot band as same value.Here we have used the category axis as primaryXA, so you need to specify the index value in the start and end properties. SfCartesianChart( primaryXAxis: CategoryAxis(), primaryYAxis: NumericAxis( plotBands: <PlotBand>[ PlotBand( start: 36, end: 36, //Specify the width for the line borderWidth: 2, //Specify the color for the line borderColor: Colors.black, //Specify the dash array for the line dashArray: const <double>[4, 5]) ]), series: <LineSeries<ChartSampleData, String>> [ LineSeries<ChartSampleData, String> ( dataSource: chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y) ], ) View the sample in GitHubConclusionI hope you enjoyed learning how to render a line at a specific value in Flutter CartesianChart.You can refer to our Flutter Cartesian Chart feature tour page to know about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications. You can also explore our Flutter Cartesian Chart example to understand how to present and manipulate data.For current customers, you can check out our WinForms components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our WinForms Edit control and other WinForms components.If you have any queries or require clarifications, please let us know in comments below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In this article, we explain how to render a customized column chart using the Flutter cartesian chart. The SfCartesianChart widget has the onCreateRenderer callback in the series, using this you can customize the rendering of the series. The following steps explain how to render customized ColumnSeries in the SfCartesianChart widget. Step 1: Create a renderer class _CustomColumnSeriesRenderer extends from ColumnSeriesRenderer, In the createSegment override method, return the customized column segments. Here we have returned the _ColumnCustomPainter class. class _CustomColumnSeriesRenderer<T, D> extends ColumnSeriesRenderer<T, D> { _CustomColumnSeriesRenderer(); @override ColumnSegment<T, D> createSegment() { return _ColumnCustomPainter(); } } Step 2: Then create a class _ColumnCustomPainter extends from ColumnSegment, inside this class you can access series properties such as animationFactor, currentSegmentIndex, fillPaint, points, segmentRect, strokePaint, and the methods below, calculateSegmentPoint for calculating the segment bound. getFillPaint for getting the fill color of the current segment. getStrokePaint for getting the border color of the current series. onPaint for rendering a column series. Inside this class declare the list of color values that is used to apply color while rendering the column segment, then get the currentSegmentIndex which is used to apply the color based on the index value and the getFillPaint method to apply the color, painting style to the current segment. class _ColumnCustomPainter<T, D> extends ColumnSegment<T, D> { List<Color> colorList = <Color>[ const Color.fromRGBO(53, 92, 125, 1), const Color.fromRGBO(192, 108, 132, 1), const Color.fromRGBO(246, 114, 128, 1), const Color.fromRGBO(248, 177, 149, 1), const Color.fromRGBO(116, 180, 155, 1) ]; @override int get currentSegmentIndex => super.currentSegmentIndex; @override Paint getFillPaint() { final Paint customerFillPaint = Paint(); customerFillPaint.isAntiAlias = false; customerFillPaint.color = colorList[currentSegmentIndex]; customerFillPaint.style = PaintingStyle.fill; return customerFillPaint; } } Step 3: Declare the override method onPaint inside the _ColumnCustomPainter class, using this you can draw the customized column. In this method, we have created a custom path using the column segment value and drawn with the help of canvas. @override void onPaint(Canvas canvas) { double x, y; x = segmentRect!.center.dx; y = segmentRect!.top; double width = 0; const double height = 20; width = segmentRect!.width; final Paint paint = Paint(); paint.color = getFillPaint().color; paint.style = PaintingStyle.fill; final Path path = Path(); final double factor = segmentRect!.height * (1 - animationFactor); path.moveTo(x - width / 2, y + factor + height); path.lineTo(x, (segmentRect!.top + factor + height) - height); path.lineTo(x + width / 2, y + factor + height); path.lineTo(x + width / 2, segmentRect!.bottom + factor); path.lineTo(x - width / 2, segmentRect!.bottom + factor); path.close(); canvas.drawPath(path, paint); } Step 4: Now create the SfCartesianChart widget with ColumnSeries and use the onCreateRenderer callback to return the _CustomColumnSeriesRenderer class. SfCartesianChart( series: <ColumnSeries<ChartSampleData, String>>[ ColumnSeries<ChartSampleData, String>( onCreateRenderer: (ChartSeries<ChartSampleData, String> series) { return _CustomColumnSeriesRenderer(); }, // Other required properties ) ], ) Thus, the customized column series rendering is achieved by onCreateRenderer callback in the series by returning the series renderer. View the sample in GitHub
In this article, we have described how to integrate Syncfusion® Flutter chart in Flutter windows. Step 1: Create a new Flutter application project using the instructions given in the Getting Started with your first Flutter app documentation. Step 2: Add the following code in your pubspec.yaml file to install the Syncfusion® Flutter chart package in your application. It will be automatically downloaded from the pub once you trigger the flutter pub get comment or click the Get packages option from the Visual Studio code. dependencies: syncfusion_flutter_charts: ^19.4.52 Step 3: Add the following code in lib/main.dart file to create a simple line chart. 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: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { // ignore: prefer_const_constructors_in_immutables MyHomePage({Key? key}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { late TooltipBehavior _tooltipBehavior; @override void initState() { _tooltipBehavior = TooltipBehavior(enable: true); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Syncfusion Flutter chart'), ), body: SfCartesianChart( primaryXAxis: CategoryAxis(), // Chart title title: ChartTitle(text: 'Half yearly sales analysis'), // Enable legend legend: Legend(isVisible: true), // Enable tooltip tooltipBehavior: _tooltipBehavior, series: <LineSeries<SalesData, String>>[ LineSeries<SalesData, String>( dataSource: <SalesData>[ SalesData('Jan', 35), SalesData('Feb', 28), SalesData('Mar', 34), SalesData('Apr', 32), SalesData('May', 40) ], xValueMapper: (SalesData sales, _) => sales.year, yValueMapper: (SalesData sales, _) => sales.sales, // Enable data label dataLabelSettings: DataLabelSettings(isVisible: true)) ])); } } class SalesData { SalesData(this.year, this.sales); final String year; final double sales; } Step 4: Run the application on windows using the flutter run -d windows command. Thus, the SfCartesianChart widget is rendered on windows desktop application and can be found in below screenshot. With Flutter SDK v2.10.0 or higher, no need to enable desktop support on windows, it is enabled by default. For more information on building windows desktop application, find the user guide here.
In Flutter Maps, you can dynamically update the markers by following these steps. Step 1: Add Syncfusion® Flutter Maps package to your dependencies in the pubspec.yaml file and initialize the Maps with the necessary properties. Please refer to this documentation for initializing the tile layer with markers. late List<Model> _data; late MapTileLayerController _controller; @override void initState() { _data = <Model>[ Model(-14.235004, -51.92528, Icon(Icons.location_on_sharp)), Model(51.16569, 10.451526, Icon(Icons.location_on_sharp)), Model(-25.274398, 133.775136, Icon(Icons.location_on_sharp)), Model(61.52401, 105.318756, Icon(Icons.location_on_sharp)) ]; _controller = MapTileLayerController(); super.initState(); } Step 2: Next, set the MapTileLayerController to the MapTileLayer.controller property, which is used for adding, removing, deleting, updating the markers collection, and converting pixel points to latitude and longitude. Note:For MapShapeLayer, set the MapShapeLayerController to the MapShapeLayer.controller property to update the markers dynamically. Step 3: To add a marker in the existing marker collections, pass the index of the marker to be added in _controller.insertMarker() method. This method will call the MapTileLayer.markerBuilder() callback again, for the last added index. To update the existing markers, pass the list of indices that needs to be updated in the _controller.updateMarkers() method. This method will call the MapTileLayer.markerBuilder() callback again, for the given indices. To remove a marker from a specific index, pass the respective index in the _controller.removeMarkerAt() method. After removing the existing markers, the collection will be re-updated automatically. To clear the entire markers, you can use the _controller.clearMarkers() method. This will remove entire marker collections from maps. @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ SfMaps( layers: <MapLayer>[ MapTileLayer( urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png", initialFocalLatLng: MapLatLng(36.27662812847283, 40.76405763626096), initialMarkersCount: _data.length, markerBuilder: (BuildContext context, int index) { return MapMarker( latitude: _data[index].latitude, longitude: _data[index].longitude, child: _data[index].icon, ); }, controller: _controller, ), ], ), Wrap( spacing: 10, children: [ ElevatedButton( child: Text('Add'), onPressed: () { _data.add(Model(20.593684, 78.96288, Icon(Icons.add_location))); int length = _data.length; if (length > 1) { _controller.insertMarker(_data.length - 1); } else { _controller.insertMarker(0); } }, ), ElevatedButton( child: Text('Update'), onPressed: () { int length = _data.length; if (length > 0) { _data[length - 1].icon = Icon(Icons.edit_location); _controller.updateMarkers([length - 1]); } }, ), ElevatedButton( child: Text('Remove'), onPressed: () { int index = _data.length - 1; if (index > 0) { _data.removeAt(index); _controller.removeMarkerAt(index); } }, ), ElevatedButton( child: Text('Clear'), onPressed: () { _data.clear(); _controller.clearMarkers(); }, ), ], ), ], ), ); } class Model { Model(this.latitude, this.longitude, this.icon); final double latitude; final double longitude; Icon icon; } Thus, using the Syncfusion® Flutter Maps, we have dynamically updated the marker collections. Output Check the following links for more features in Syncfusion® Flutter Maps: https://www.syncfusion.com/flutter-widgets/flutter-maps https://help.syncfusion.com/flutter/maps/overview https://pub.dev/packages/syncfusion_flutter_maps Live samples https://flutter.syncfusion.com/#/maps/tile-layer/osm https://play.google.com/store/apps/details?id=com.syncfusion.flutter.examples https://apps.apple.com/us/app/syncfusion-flutter-ui-widgets/id1475231341 ConclusionI hope you enjoyed learning about how to update the markers dynamically using Flutter Maps.You can refer to our Flutter Maps feature tour page to know about its other groundbreaking feature representations. You can also explore our Flutter Maps documentation to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In this article, we explain how to format the date-time values of the axis label in the Flutter cartesian chart. The SfCartesianChart widget has the DateTimeAxis support, and in this we have dateFormat property and axisLabelFormatter callback, using these you can customize the date-time axis label format. The following steps explains formatting the axis labels. Step 1: Initialize the data source. late List<SeriesData> chartData; @override void initState() { chartData = <SeriesData>[ SeriesData(DateTime(2022, 02, 01), 20), SeriesData(DateTime(2022, 02, 02), 10), SeriesData(DateTime(2022, 02, 03), 20), SeriesData(DateTime(2022, 02, 04), 30), SeriesData(DateTime(2022, 02, 05), 20), SeriesData(DateTime(2022, 02, 06), 30), SeriesData(DateTime(2022, 02, 07), 10), SeriesData(DateTime(2022, 02, 08), 20), SeriesData(DateTime(2022, 02, 09), 10), SeriesData(DateTime(2022, 02, 10), 30) ]; super.initState(); } class SeriesData { SeriesData(this.x, this.y); final DateTime x; final num y; } Step 2: Initialize the SfCartesianChart widget with required properties and bind the data source to the series. SfCartesianChart( primaryXAxis: DateTimeAxis(), series: <LineSeries<SeriesData, DateTime>>[ LineSeries( dataSource: chartData, xValueMapper: (SeriesData sales, _) => sales.x, yValueMapper: (SeriesData sales, _) => sales.y, ) ], ) Step 3: Using the dateFormat property in the primaryXAxis, specify the required date format to customize the axis labels and import the following intl package. Here we have used yMd format. To know more on the available date formats, find the formats here. import 'package:intl/intl.dart'; primaryXAxis: DateTimeAxis( dateFormat: DateFormat.yMd(), ) Thus, the date time axis with the formatted axis labels is achieved by dateFormat property in DateTimeAxis. Step 4: Also you can customize the axis label format using the axisLabelFormatter callback, here you can return the customized text and text style property using the ChartAxisLabel class. primaryXAxis: DateTimeAxis( axisLabelFormatter: (axisLabelRenderArgs) { final String text = DateFormat('EEEE').format( DateTime.fromMillisecondsSinceEpoch( axisLabelRenderArgs.value.toInt())); const TextStyle style = TextStyle(color: Colors.teal, fontWeight: FontWeight.bold); return ChartAxisLabel(text, style); }, ) Using axisLabelFormatter callback achieved the following axis label format. View sample in the GitHub.
In this article, we explain how to export the cartesian chart as an image using the Flutter Cartesian chart. The SfCartesianChart widget provides an option to export the chart as an image. The following steps explain how to accomplish this exporting functionality. Step 1: Initialize the variable _chartData which stores the data source and initialize the variable _cartesianChartKey which stores the global key of the SfCartesianChart widget. This key is used to convert the chart into an image. late GlobalKey<SfCartesianChartState> _cartesianChartKey; late List<ChartSampleData> _chartData; @override void initState() { _cartesianChartKey = GlobalKey(); _chartData = < ChartSampleData >[ ChartSampleData ('Jan', 12), ChartSampleData ('Feb', 28), ChartSampleData ('Mar', 35), ChartSampleData ('Apr', 27), ChartSampleData ('Jun', 42), ChartSampleData ('Jul', 33) ]; super.initState(); } class ChartSampleData { ChartSampleData ({this.x, this.y}); final String? x; final num? y; } Step 2: Now create the SfCartesianChart widget with the ColumnSeries and assign the _chartData to the dataSource property and map the x, y values to xValueMapper, yValueMapper properties respectively. And also assign the _cartesianChartKey to the key property. Assign CategoryAxis for primaryXAxis because we are using strings as x values here. SfCartesianChart( key: _cartesianChartKey, primaryXAxis: CategoryAxis(), series: <ColumnSeries< ChartSampleData, String>>[ ColumnSeries< ChartSampleData, String>( dataSource: _chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y ) ], ) Step 3: Import the dart files dart:typed_data and dart.ui files to use the Uint8List, ByteData. import 'dart:typed_data'; import 'dart:ui' as ui; Step 4: Create a separate method called _renderChartAsImage in which we have converted the rendered cartesian chart to Image by using the toImage method. Then using this Image, converted it into a byte array using toByteData method. Further creates the Uint8List from the byte array which was shown on the new page. Future<void> _renderChartAsImage() async { final ui.Image data = await _ cartesianChartKey.currentState!.toImage(pixelRatio : 3.0); final ByteData? bytes = await data.toByteData(format : ui.ImageByteFormat.png); final Uint8List imageBytes = bytes!.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes); await Navigator.of(context).push<dynamic>( MaterialPageRoute<dynamic>( builder: (BuildContext context) { return Scaffold( body:Image.memory(imageBytes) ); }, ), ); } Step 5: Add the TextButton widget and call the _renderChartAsImage method to render the chart image on a new page. @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ SfCartesianChart( key: _ cartesianChartKey, primaryXAxis: CategoryAxis(), series: <ColumnSeries<ChartSampleData, String>>[ ColumnSeries<ChartSampleData, String>( dataSource: _chartData, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y, ) ] ), TextButton( child: const Text('Export as image'), onPressed: () { _renderChartAsImage (); }, ) ] ); } Now, if we tapped the TextButton, the exported image of the cartesian chart will render on the new page. View the sample in GitHub.ConclusionI hope you enjoyed learning about how to export Cartesian Chart as an image (SfCartesianChart).You can refer to our Flutter CartesianChart feature tour page to know about its other groundbreaking feature representations. You can also explore our Flutter CartesianChart documentation to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In this article we will explain how to render the Flutter chart using the data stored in the Firestore. Refer the following link for creating project in the Firestore database. https://firebase.google.com/docs/firestore/quickstart Refer the following link for configured Firestore project with created Flutter sample https://firebase.google.com/docs/flutter/setup?platform=android#register-app Step 1: Add the required packages in the pubspec.yaml file. syncfusion_flutter_chart: ^19.1.59 firebase_core: ^1.1.1 cloud_firestore: ^2.1.0 Step 2: Import the required packages. import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; Step 3: In initState() , fetch the data from Firestore by mapping the Firestore doc values to data source values in Flutter Chart by using snapShotValue.docs. //Holds the data source of chart List<_ChartData> chartData = <_ChartData>[]; @override void initState() { getDataFromFireStore().then((results) { SchedulerBinding.instance!.addPostFrameCallback((timeStamp) { setState(() {}); }); }); super.initState(); } Future<void> getDataFromFireStore() async { var snapShotsValue = await FirebaseFirestore.instance.collection("chartData").get(); List<_ChartData> list = snapShotsValue.docs .map((e) => _ChartData(x: DateTime.fromMillisecondsSinceEpoch( e.data()['x'].millisecondsSinceEpoch) , y: e.data()['y'])) .toList(); setState(() { chartData = list; }); } // Class for chart data source, this can be modified based on the data in Firestore class _ChartData { _ChartData({this.x, this.y}); final DateTime? x; final int? y; } Step 4: Then assign the populated values to dataSource property of the SfCartesianChart widget. SfCartesianChart( primaryXAxis: DateTimeAxis(), primaryYAxis: NumericAxis(), series: <LineSeries<_ChartData, DateTime>>[ LineSeries<_ChartData, DateTime>( dataSource: chartData, xValueMapper: (_ChartData data, _) => data.x, yValueMapper: (_ChartData data, _) => data.y), ]) Thus, the chart is rendered with data from the Firestore. Image for the data in the Firestore and the chart rendered with the respective data is below. View the sample in GitHubConclusionI hope you enjoyed learning about how to render the Flutter chart using the data in Firestore.You can refer to our Flutter Cartesian Chart feature tour page to know about its other groundbreaking feature representations,documentation and how to quickly get started for configuration specifications. You can also explore our Flutter Cartesian Chart example to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In this article we explain how to show the tapped point value in the center of the doughnut chart using the Flutter circular chart. The SfCircularChart widget supports for annotations which is used to display the custom widget in the circular chart. In default the annotation gets positioned at center of the circular chart and you can get the tapped point information using the onPointTap callback. Follow the below steps to show tapped point information. Step 1: Initialize the data source for chart and tappedValue variable with empty string. late List<SeriesData> chartData; String tappedValue = ''; @override void initState() { chartData = <SeriesData>[ SeriesData('Mon', 10), SeriesData('Tue', 20), SeriesData('Wed', 30), SeriesData('Thus', 40), SeriesData('Fri', 50), SeriesData('Sat', 60), SeriesData('Sun', 70), ]; super.initState(); } class SeriesData { SeriesData(this.x, this.y); final String x; final num y; } Step 2: Initialize the SfCircularChart widget with DoughnutSeries and bind the data source to the series. SfCircularChart( series: <CircularSeries<SeriesData, String>>[ DoughnutSeries( dataSource: chartData, xValueMapper: (SeriesData data, _) => data.x, yValueMapper: (SeriesData data, _) => data.y) ], ) Step 3: Then assign the annotations property with the text widget, for that text widget assign the tappedValue variable. Then using the onPointTap callback get the tapped point information, assign it to the tappedValue variable and call the setState to reflect the changes in the chart. SfCircularChart( annotations: [ CircularChartAnnotation( widget: Text( tappedValue, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), )) ], series: <CircularSeries<SeriesData, String>>[ DoughnutSeries( onPointTap: (pointInteractionDetails) { tappedValue = pointInteractionDetails .dataPoints![pointInteractionDetails.pointIndex!].y .toString(); setState(() {}); }, ], ) Thus, the showing the tapped point value at the center of the doughnut chart is achieved by the help of annotations property and onPointTap callback. View the sample in GitHub
In this article, we explain how to jitter the data points of the scatter series using Flutter Cartesian chart. The SfCartesianChart widget has a ScatterSeries support and when number y-values are assigned to same x-value, then plotting the scatter series will look clumsy in appearance. This can be avoided by adding jittering effect for the rendering points. In the following steps explain how to jitter the data points of the ScatterSeries in the SfCartesianChart widget. Step 1: Initialize the chartData variable that holds the data source. late List<SampleData> chartData; Step 2: Now create the SfCartesianChart widget with the ScatterSeries, assign the chartData to the dataSource property and initialize chart with other required properties. SfCartesianChart( primaryYAxis: NumericAxis(interval: 10), primaryXAxis: NumericAxis(interval: 2, minimum: 0, maximum: 11), series: <ScatterSeries<SampleData, num>>[ ScatterSeries( markerSettings: const MarkerSettings(width: 5, height: 5), dataSource: chartData, xValueMapper: (SampleData data, _) => data.x, yValueMapper: (SampleData data, _) => data.y) ], ) Step 3: Then create a getData method for generating jitter data. In this method, we have applied a formula which can be found in below code snippet to find the jitter value for x-values. List<SampleData> getData() { final List<SampleData> data = []; for (int i = 1; i <= 10; i++) { for (int j = 0; j < 25; j++) { //Formula to find the jitter value final double jitterValue = (Random().nextDouble() - 0.5) * 0.3; data.add(SampleData( i + jitterValue, getRandomData(1, 40) + Random().nextDouble())); } } return data; } int getRandomData(int min, int max) { return min + Random().nextInt(max - min); } @override void initState() { chartData = getData(); super.initState(); } Thus, the scatter series with the jitter data point is achieved. View the sample in GitHub.
In this article, we explain how to a render multi-colored line chart using Flutter Cartesian chart.In SfCartesianChart widget using the pointColorMapper property, you can map the color from the data source to each point. Follow the below steps, to accomplish this. Step 1: Initialize the chartData variable which holds the data source for the chart. Here provides the color to each point. late List<_ChartData> chartData; @override void initState() { chartData = <_ChartData>[ _ChartData(DateTime(1925), 415, const Color.fromRGBO(248, 184, 131, 1)), _ChartData(DateTime(1926), 408, const Color.fromRGBO(248, 184, 131, 1)), _ChartData(DateTime(1927), 415, const Color.fromRGBO(248, 184, 131, 1)), _ChartData(DateTime(1928), 350, const Color.fromRGBO(248, 184, 131, 1)), _ChartData(DateTime(1929), 375, const Color.fromRGBO(248, 184, 131, 1)), _ChartData(DateTime(1930), 500, const Color.fromRGBO(248, 184, 131, 1)), _ChartData(DateTime(1931), 390, const Color.fromRGBO(229, 101, 144, 1)), _ChartData(DateTime(1932), 450, const Color.fromRGBO(229, 101, 144, 1)), _ChartData(DateTime(1933), 440, const Color.fromRGBO(229, 101, 144, 1)), _ChartData(DateTime(1934), 350, const Color.fromRGBO(229, 101, 144, 1)), _ChartData(DateTime(1935), 400, const Color.fromRGBO(229, 101, 144, 1)), _ChartData(DateTime(1936), 365, const Color.fromRGBO(53, 124, 210, 1)), _ChartData(DateTime(1937), 490, const Color.fromRGBO(53, 124, 210, 1)), _ChartData(DateTime(1938), 400, const Color.fromRGBO(53, 124, 210, 1)), _ChartData(DateTime(1939), 520, const Color.fromRGBO(53, 124, 210, 1)), _ChartData(DateTime(1940), 510, const Color.fromRGBO(53, 124, 210, 1)), _ChartData(DateTime(1941), 395, const Color.fromRGBO(0, 189, 174, 1)), _ChartData(DateTime(1942), 380, const Color.fromRGBO(0, 189, 174, 1)), _ChartData(DateTime(1943), 404, const Color.fromRGBO(0, 189, 174, 1)), _ChartData(DateTime(1944), 400, const Color.fromRGBO(0, 189, 174, 1)), _ChartData(DateTime(1945), 500, const Color.fromRGBO(0, 189, 174, 1)) ]; super.initState(); } class _ChartData { _ChartData(this.x, this.y, [this.lineColor]); final DateTime x; final double y; final Color? lineColor; } Step 2: Now create the SfCartesianChart widget with the LineSeries and assign the chartData to the dataSource property and map the x, y values to xValueMapper, yValueMapper properties respectively. SfCartesianChart( primaryXAxis: DateTimeAxis(), primaryYAxis: NumericAxis(), series: <LineSeries<_ChartData, DateTime>>[ LineSeries<_ChartData, DateTime>( dataSource: chartData, xValueMapper: (_ChartData sales, _) => sales.x, yValueMapper: (_ChartData sales, _) => sales.y, width: 2) ], ) Step 3: Then map the color values in the data source to the pointColorMapper property. It will map the respective color to the respective points. SfCartesianChart( series: <LineSeries<_ChartData, DateTime>>[ LineSeries<_ChartData, DateTime>( // The property used to apply the color to each data. pointColorMapper: (_ChartData sales, _) => sales.lineColor, // Other required properties. ) ], ) Thus, the line series with the multi-colored is achieved with the help of pointColorMapper property in the LineSeries. View the sample in GitHub. ConclusionI hope you enjoyed learning about how to render multi-colored line chart using Flutter Cartesian chart. You can refer to our Flutter CartesianChart feature tour page to know about its other groundbreaking feature representations. You can also explore our Flutter CartesianChart documentation to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In this article, we explain how to rotate the legend in the chart using the Flutter cartesian chart. To achieve the below transposed look chart, the legend needs to be rotated. The SfCartesianChart widget provides option to use the custom widgets as legend using the legendItemBuilder property. So, you can wrap the required widgets using the RotatedBox widget and return it using the legendItemBuilder property. In the RotatedBox widget using the quarterTurns property, you can rotate the child widget. Here the default legend can’t be rotated. The following steps explain how to rotate the legend in the SfCartesianChart widget. Step 1: Initialize the variable chartData which holds the data source, then assign the value at the initState. late List<ChartSampleData> chartData; @override void initState() { chartData = <ChartSampleData>[ ChartSampleData( x: 'Germany', y: 128, secondSeriesYValue: 129, thirdSeriesYValue: 101), ChartSampleData( x: 'Russia', y: 123, secondSeriesYValue: 92, thirdSeriesYValue: 93), ChartSampleData( x: 'Norway', y: 107, secondSeriesYValue: 106, thirdSeriesYValue: 90), ChartSampleData( x: 'USA', y: 87, secondSeriesYValue: 95, thirdSeriesYValue: 71), ]; super.initState(); } Step 2: Now create the SfCartesianChart widget with the ColumnSeries and assign the chartData to the dataSource property and map the x, y values to xValueMapper and yValueMapper properties respectively. Use the isTransposed property to transpose the vertical and horizontal axes i,e using this you can render vertical chart. SfCartesianChart( isTransposed: true, primaryXAxis: CategoryAxis(), series: <ColumnSeries<ChartSampleData, String>>[ ColumnSeries<ChartSampleData, String>( dataSource: chartData, color: const Color.fromRGBO(252, 216, 20, 1), xValueMapper: (ChartSampleData sales, _) => sales.x, yValueMapper: (ChartSampleData sales, _) => sales.y, name: 'Gold'), ColumnSeries<ChartSampleData, String>( dataSource: chartData, color: const Color.fromRGBO(169, 169, 169, 1), xValueMapper: (ChartSampleData sales, _) => sales.x as String, yValueMapper: (ChartSampleData sales, _) => sales.secondSeriesYValue, name: 'Silver'), ColumnSeries<ChartSampleData, String>( dataSource: chartData, color: const Color.fromRGBO(205, 127, 50, 1), xValueMapper: (ChartSampleData sales, _) => sales.x as String, yValueMapper: (ChartSampleData sales, _) => sales.thirdSeriesYValue, name: 'Bronze') ], ) Step 3: Declare the legend property in the SfCartesianChart, enable it by setting true to the isVisible property in the legend. Then return the custom widget wrapped with the RotatedBox widget in the legendItemBuilder property. Then specify the quarterTurns property of RotatedBox widget. SfCartesianChart( // Other required properties legend: Legend( isVisible: true, legendItemBuilder: (String name, dynamic series, dynamic point, int index) { return RotatedBox( quarterTurns: 1, child: SizedBox( width: 87, child: Row(children: <Widget>[ SizedBox( child: Icon( Icons.bar_chart, color: series.color, )), const SizedBox( width: 1, ), Text(series.name), ])), ); }), ) Thus, the rotated view for legend in the cartesian chart is achieved by the help of legendItemBuilder and RotatedBox widget. View the sample in the GitHub.
In Flutter CartesianChart has support to achieve sliding view port functionality. You can achieve this by using the selectDataPoints public method, method, visibleMinimum, visibleMaximum, and onPlotAreaSwipe callback available in the chart widget. The following steps explain how to maintain the selected data point is in the centre of the viewport in both dragging the chart towards the end and selecting the data points manually and you change this as per your requirement.Step 1: Declare the series variables for storing axis visible minimum and maximum, data source, selection behaviour, selected point index, and other required variables as in the following code sample. late List<OrdinalData> chartData; // Initializing with visible minimum and visible maximum as 1 and 5 respectively. double axisVisibleMin = 1, axisVisibleMax = 5; late SelectionBehavior selectionBehavior; // create instance for axis controller NumericAxisController? axisController; int? selectedPointIndex; bool isLoad = false; Step 2: Initialize the data, and selection behavior in the init state of the widget as like below. @override void initState() { //Initialize the data source to the chart chartData = <OrdinalData>[ OrdinalData(0, 5), OrdinalData(1, 25), OrdinalData(2, 100), OrdinalData(3, 75), OrdinalData(4, 33), OrdinalData(5, 80), … ]; // Enabling selection behavior selectionBehavior = SelectionBehavior(enable: true); super.initState(); } Step 3: In the onSelectionChanged call back event, set the selected point index with the help of event’s arguments when the selection is performed. We can set the view port index if the selection is done manually by touching the points or else set the point index to perform selection while swiping to the selectedPointIndex variable. Using this variable, set the initialVisibleMinimum and initialVisibleMaximum values by subtracting and adding the two indexes from left and right respectively to show the selected point in the centre. onSelectionChanged: (args) { // While manually selecting the points. if (!isLoad) { selectedPointIndex = args.viewportPointIndex; } // While swiping the point gets selected. else { selectedPointIndex = args.pointIndex; } //Setting visible minimum and visible maximum to maintain the selected point in the center of viewport axisVisibleMin = selectedPointIndex! - 2.toDouble(); axisVisibleMax = selectedPointIndex! + 2.toDouble(); }, Step 4: Define the performSwipe method which is used to perform the swiping based on the swipe direction and also selection of the centre point in the viewport is handled as shown in the following code snippet. void performSwipe(ChartSwipeDirection direction) { // Executes when swiping the chart from right to left if (direction == ChartSwipeDirection.end && (axisVisibleMax + 5.toDouble()) < chartData.length) { isLoad = true; // set the visible minimum and visible maximum to maintain the selected point in the center of the viewport. axisVisibleMin = axisVisibleMin + 5.toDouble(); axisVisibleMax = axisVisibleMax + 5.toDouble(); // To update the visible maximum and visible minimum dynamically by using axis controller. axisController!.visibleMinimum = axisVisibleMin; axisController!.visibleMaximum = axisVisibleMax; // To execute after chart redrawn with new visible minimum and maximum, we used delay for 1 second Future.delayed(const Duration(milliseconds: 1000), () { // Public method used to select the data point dynamically selectionBehavior.selectDataPoints((axisVisibleMin.toInt()) + 2); }); } // Executes when swiping the chart from left to right else if (direction == ChartSwipeDirection.start && (axisVisibleMin - 5.toDouble()) >= 0) { setState(() { axisVisibleMin = axisVisibleMin - 5.toDouble(); axisVisibleMax = axisVisibleMax - 5.toDouble(); axisController!.visibleMinimum = axisVisibleMin; axisController!.visibleMaximum = axisVisibleMax; Future.delayed(const Duration(milliseconds: 1000), () { selectionBehavior.selectDataPoints((axisVisibleMin.toInt()) + 2); }); }); } } } Step 4: Assign the performSwipe method to the onPlotAreaSwipe callback in the chart and axisController value in onRendererCreated callback in the axis. SfCartesianChart( primaryXAxis: NumericAxis( initialVisibleMaximum: axisVisibleMax; initialVisibleMinimum: axisVisibleMin; // set value for axis controller. onRendererCreated(NumericAxisController controller){ axisController = controller; } ) onPlotAreaSwipe: (ChartSwipeDirection direction) => performSwipe(direction), ) Thus, the sliding viewport is achieved by selecting the data manually also by dragging the chart towards the end or start using the SfCartesianchart widget. View the sample in GitHubConclusionI hope you enjoyed learning about how to achieve viewport functionality using Flutter Cartesian Chart.You can refer to our Flutter Cartesian Chart feature tour page to know about its other groundbreaking feature representations. You can also explore our documentation to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you
In the Flutter Event Calendar, load the google calendar events to the Flutter calendar in iOS platform. STEP 1: Add the required packages in the dependencies of Pubspec.yaml. dependencies: flutter: sdk: flutter syncfusion_flutter_calendar: ^18.3.40 intl: ^0.16.0 google_sign_in: ^4.4.6 googleapis_auth: ^0.2.11+1 googleapis: ^0.54.0 cupertino_icons: ^0.1.2 STEP 2: Create a project in firebase and configure the created sample to the firebase project. Kindly refer the following link. https://firebase.google.com/docs/flutter/setup?platform=android#create-firebase-project STEP 3: As per the steps in the above link configure the firebase with the created sample and add the iOS bundle ID (Take a bundle ID from project.pbxproj file of the Runner.xcodeproj folder in iOS project). Register the app with firebase and download the GoogleService-Info.plist. STEP 4: In the Project settings of the Firebase project, add the Project name and the Support email. Then Enable the Google Sign in and click Save in the Authentication tab. STEP 4: Import the Firebase package and add the following lines in the AppDelegate. STEP 5: Add the following lines in the Podfile. STEP 6: Open the Runner folder in XCode of the project then drag and drop the GoogleService-Info.plist file into that folder. STEP 7: Call the GoogleSignIn method to authenticate Google users. final GoogleSignIn _googleSignIn = GoogleSignIn( clientId: 'OAuth Client ID', scopes: <String>[ googleAPI.CalendarApi.CalendarScope, ], ); STEP 8: Google provides googleAPI.Event class which holds the details about the google events. Use these API’s in override methods. class GoogleDataSource extends CalendarDataSource { GoogleDataSource({List<googleAPI.Event> events}) { this.appointments = events; } @override DateTime getStartTime(int index) { final googleAPI.Event event = appointments[index]; return event.start.date ?? event.start.dateTime.toLocal(); } @override bool isAllDay(int index) { return appointments[index].start.date != null; } @override DateTime getEndTime(int index) { final googleAPI.Event event = appointments[index]; return event.endTimeUnspecified != null && event.endTimeUnspecified ? (event.start.date ?? event.start.dateTime.toLocal()) : (event.end.date != null ? event.end.date.add(Duration(days: -1)) : event.end.dateTime.toLocal()); } @override String getLocation(int index) { return appointments[index].location; } @override String getNotes(int index) { return appointments[index].description; } @override String getSubject(int index) { final googleAPI.Event event = appointments[index]; return event.summary == null || event.summary.isEmpty ? 'No Title' : event.summary; } } STEP 9: To load the google events, create async method named as getGoogleEventsData() and get the data from google calendar using googleAPI.Event. Find the following code snippet for the same. Future<List<googleAPI.Event>> getGoogleEventsData() async { final GoogleSignInAccount googleUser = await _googleSignIn.signIn(); final GoogleAPIClient httpClient = GoogleAPIClient(await googleUser.authHeaders); final googleAPI.CalendarApi calendarAPI = googleAPI.CalendarApi(httpClient); final googleAPI.Events calEvents = await calendarAPI.events.list( "primary", ); Final List<googleAPI.Event> appointments = <googleAPI.Event>[]; if (calEvents != null && calEvents.items != null) { for (int i = 0; i < calEvents.items.length; i++) { final googleAPI.Event event = calEvents.items[i]; if (event.start == null) { continue; } appointments.add(event); } } return appointments; } STEP 10: Using the FutureBuilder widget, display the google calendar data. Based on the Snapshot.data, load that google calendar events to the Flutter calendar. child: FutureBuilder( future: getGoogleEventsData(), builder: (BuildContext context, AsyncSnapshot snapshot) { return Container( child: Stack( children: [ Container( child: SfCalendar( view: CalendarView.month, dataSource: GoogleDataSource(events: snapshot.data), monthViewSettings: MonthViewSettings( appointmentDisplayMode: MonthAppointmentDisplayMode.appointment), ), ), snapshot.data != null ? Container() : Center( child: CircularProgressIndicator(), ) ], )); }, ), View sample in GitHub
In Flutter Range Slider, you can add a label for the current value by following these steps. Step 1: Add the Syncfusion® Flutter Sliders package to your dependencies in the pubspec.yaml file. Step 2: Initialize the SfRangeSlider widget as a child of any widget. Now, set the values for the SfRangeSlider.min and SfRangeSlider.max properties. The values of the SfRangeSlider.values property should be between the min and max values. You can customize the thumb using the SfRangeSlider.thumbShape property of SfRangeSlider. SfRangeValues _values = SfRangeValues(1500.0, 3000.0); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: SfRangeSlider( min: 0, max: 5000, stepSize: 10, thumbShape: _CustomThumb( textScaleFactor: MediaQuery.of(context).textScaleFactor, values: _values), values: _values, onChanged: (dynamic newValue) { setState(() { _values = newValue; }); }, ), ); } Step 3: To customize the thumb, extend the SfThumbShape class to create a custom shape. Override the paint method and draw a shape that you want. After drawing a thumb shape in the paint, you can convert the current values to the string and layout the text using TextPainter class, as shown in the following code sample. class _CustomThumb extends SfThumbShape { _CustomThumb({required this.textScaleFactor, required this.values}) : _textSpan = TextSpan(), _textPainter = TextPainter(); final double textScaleFactor; final SfRangeValues values; TextPainter _textPainter; TextSpan _textSpan; final double verticalSpacing = 5.0; @override Size getPreferredSize(SfSliderThemeData themeData) { _textSpan = TextSpan(text: values.start.toInt().toString()); _textPainter ..text = _textSpan ..textDirection = TextDirection.ltr ..textScaleFactor = textScaleFactor ..layout(); // Considered label height along with thumb radius to avoid the // label get overlapping with adjacent widget. return Size(themeData.thumbRadius * 2, (themeData.thumbRadius + _textPainter.height + verticalSpacing) * 2); } @override void paint(PaintingContext context, Offset center, {required RenderBox parentBox, required RenderBox? child, required SfSliderThemeData themeData, SfRangeValues? currentValues, dynamic currentValue, required Paint? paint, required Animation<double> enableAnimation, required TextDirection textDirection, required SfThumb? thumb}) { paint ??= Paint()..color = themeData.thumbColor!; context.canvas.drawCircle(center, themeData.thumbRadius, paint); String text = currentValues!.end.toInt().toString(); if (thumb != null) { text = (thumb == SfThumb.start ? currentValues.start : currentValues.end) .toInt() .toString(); } _textSpan = TextSpan( text: text, style: TextStyle(color: Colors.black), ); _textPainter ..text = _textSpan ..textDirection = textDirection ..textScaleFactor = textScaleFactor ..layout() ..paint( context.canvas, // To show the label below the thumb, we had added it with thumb radius // and constant vertical spacing. Offset(center.dx - _textPainter.width / 2, center.dy + verticalSpacing + themeData.thumbRadius), ); } } Output Check the following links for more features in Syncfusion® Flutter Sliders: Syncfusion® Flutter Sliders product page User guide documentation for Sliders pub.dev Live samples Android iOS Web Windows Linux ConclusionI hope you enjoyed learning about how to add label for current value in Flutter Range Slider.You can refer to our Flutter Range Slider feature tour page to know about its other groundbreaking feature representations. You can also explore our Flutter Range Slider documentation to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In the Flutter Calendar, add the appointment data to the Firestore database and show the added data to SfCalendar.Refer the following link for creating project in the Firestore database.https://firebase.google.com/docs/firestore/quickstartRefer the following link for configured Firestore project with created Flutter samplehttps://firebase.google.com/docs/flutter/setup?platform=android#register-app STEP 1: Add the required packages. syncfusion_flutter_calendar: ^19.1.59 firebase_core: ^1.1.1 cloud_firestore: ^2.1.0 STEP 2: Initialize the default values for the calendar. List<Color> _colorCollection = <Color>[]; MeetingDataSource? events; final List<String> options = <String>['Add', 'Delete', 'Update']; final databaseReference = FirebaseFirestore.instance; STEP 3: In initState() , populate the appointments data from Firestore to Flutter Calendar by mapping the Firestore doc values to appointment values in Flutter Calendar by using snapShotValue.docs. @override void initState() { _initializeEventColor(); getDataFromFireStore().then((results) { SchedulerBinding.instance!.addPostFrameCallback((timeStamp) { setState(() {}); }); }); super.initState(); } Future<void> getDataFromFireStore() async { var snapShotsValue = await databaseReference .collection("CalendarAppointmentCollection") .get(); final Random random = new Random(); List<Meeting> list = snapShotsValue.docs .map((e) => Meeting( eventName: e.data()['Subject'], from: DateFormat('dd/MM/yyyy HH:mm:ss').parse(e.data()['StartTime']), to: DateFormat('dd/MM/yyyy HH:mm:ss').parse(e.data()['EndTime']), background: _colorCollection[random.nextInt(9)], isAllDay: false)) .toList(); setState(() { events = MeetingDataSource(list); }); } STEP 4: For adding the appointment data to Firestore, kindly use the set() to add appointment document, delete() to remove the appointment from document, update() will update the changes the appointment changes. leading: PopupMenuButton<String>( icon: Icon(Icons.settings), itemBuilder: (BuildContext context) => options.map((String choice) { return PopupMenuItem<String>( value: choice, child: Text(choice), ); }).toList(), onSelected: (String value) { if (value == 'Add') { databaseReference .collection("CalendarAppointmentCollection") .doc("1") .set({ 'Subject': 'Mastering Flutter', 'StartTime': '07/04/2020 08:00:00', 'EndTime': '07/04/2020 09:00:00' }); } else if (value == "Delete") { try { databaseReference .collection('CalendarAppointmentCollection') .doc('1') .delete(); } catch (e) {} } else if (value == "Update") { try { databaseReference .collection('CalendarAppointmentCollection') .doc('1') .update({'Subject': 'Meeting'}); } catch (e) {} } }, ) STEP 5: Assign the events to the dataSource property of the calendar. body: SfCalendar( view: CalendarView.month, initialDisplayDate: DateTime(2020, 4, 5, 9, 0, 0), dataSource: events, monthViewSettings: MonthViewSettings( showAgenda: true, ), ) View sample in GitHub ConclusionI hope you enjoyed learning about how to add appointments to Firestore Database using Flutter Calendar.You can refer to our Flutter Calender feature tour page to know about its other groundbreaking feature representations. You can also explore our Flutter Calendar documentation to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
You can create time table by adding appointments for particular days of week by using onViewChanged callback in Flutter Calendar. In initState(), set the default values for calendar. CalendarDataSource _dataSource = _DataSource(<Appointment>[]); List<String> _subjectCollection = <String>[]; List<DateTime> _startTimeCollection = <DateTime>[]; List<DateTime> _endTimeCollection = <DateTime>[]; List<Color> _colorCollection = <Color>[]; List<TimeRegion> _specialTimeRegion = <TimeRegion>[]; @override void initState() { _getSubjectCollection(); _getStartTimeCollection(); _getEndTimeCollection(); _getColorCollection(); super.initState(); } Using the onViewchanged callback, checks whether the visible date weekday is not falls in weekend to add appointments for week days. void viewChanged(ViewChangedDetails viewChangedDetails) { List<DateTime> visibleDates = viewChangedDetails.visibleDates; List<TimeRegion> _timeRegion = <TimeRegion>[]; List<Appointment> appointments = <Appointment>[]; _dataSource.appointments!.clear(); for (int i = 0; i < visibleDates.length; i++) { if (visibleDates[i].weekday == 6 || visibleDates[i].weekday == 7) { continue; } _timeRegion.add(TimeRegion( startTime: DateTime(visibleDates[i].year, visibleDates[i].month, visibleDates[i].day, 13, 0, 0), endTime: DateTime(visibleDates[i].year, visibleDates[i].month, visibleDates[i].day, 14, 0, 0), text: 'Break', enablePointerInteraction: false)); SchedulerBinding.instance!.addPostFrameCallback((timeStamp) { setState(() { _specialTimeRegion = _timeRegion; }); }); for (int j = 0; j < _startTimeCollection.length; j++) { DateTime startTime = new DateTime( visibleDates[i].year, visibleDates[i].month, visibleDates[i].day, _startTimeCollection[j].hour, _startTimeCollection[j].minute, _startTimeCollection[j].second); DateTime endTime = new DateTime( visibleDates[i].year, visibleDates[i].month, visibleDates[i].day, _endTimeCollection[j].hour, _endTimeCollection[j].minute, _endTimeCollection[j].second); Random random = Random(); appointments.add(Appointment( startTime: startTime, endTime: endTime, subject: _subjectCollection[random.nextInt(9)], color: _colorCollection[random.nextInt(9)])); } } for (int i = 0; i < appointments.length; i++) { _dataSource.appointments!.add(appointments[i]); } _dataSource.notifyListeners( CalendarDataSourceAction.reset, _dataSource.appointments!); } Then assign the _dataSource to dataSource property of the calendar. child: SfCalendar( dataSource: _dataSource, view: CalendarView.week, allowedViews: [ CalendarView.day, CalendarView.week, CalendarView.workWeek, CalendarView.month, CalendarView.timelineDay, CalendarView.timelineWeek, CalendarView.timelineWorkWeek, CalendarView.timelineMonth, CalendarView.schedule ], onViewChanged: viewChanged, specialRegions: _specialTimeRegion, ), View sample in GitHub
Flutter Calendar allows you to access the local database using SQLite. You can go through the following steps to load the offline data to calendar events. STEP 1: Add the required packages in the dependencies of pubspec.yaml. syncfusion_flutter_calendar: 18.4.39 sqflite: ^1.3.2+3 path_provider: ^1.6.27 intl: ^0.16.0 http: "0.11.3+17" date_format: ^1.0.8 connectivity: ^0.3.0 STEP 2: Add the database_helper.dart and create the database using the DatabaseHelper instance. static final table = 'flutter_calendar_events'; static final columnId = '_id'; static final columnName = 'name'; static final columnStart = 'start'; static final columnEnd = 'end'; // make this a singleton class DatabaseHelper._privateConstructor(); static final DatabaseHelper instance = DatabaseHelper._privateConstructor(); // only have a single app-wide reference to the database static Database _database; Future<Database> get database async { if (_database != null) return _database; // lazily instantiate the db the first time it is accessed _database = await _initDatabase(); return _database; } _initDatabase() async { Directory documentsDirectory = await getApplicationDocumentsDirectory(); String path = join(documentsDirectory.path,”flutter_calendar_database.db”); return await openDatabase(path, version: _databaseVersion, onCreate: _onCreate); } STEP 3: Create the database table using Create Table query. // SQL code to create the database table Future _onCreate(Database db, int version) async { await db.execute(''' CREATE TABLE $table ( $columnId INTEGER PRIMARY KEY, $columnName TEXT NOT NULL, $columnStart TEXT NOT NULL, $columnEnd TEXT NOT NULL ) '''); } STEP 4: Add the helper methods for add, remove, update operations. Future<int> insert(Map<String, dynamic> row) async { Database db = await instance.database; return await db.insert(table, row); } // All of the rows are returned as a list of maps, where each map is // a key-value list of columns. Future<List<Map<String, dynamic>>> queryAllRows() async { Database db = await instance.database; return await db.query(table); } // All of the methods (insert, query, update, delete) can also be done using // raw SQL commands. This method uses a raw query to give the row count. Future<int> queryRowCount() async { Database db = await instance.database; return Sqflite.firstIntValue(await db.rawQuery('SELECT COUNT(*) FROM $table')); } // We are assuming here that the id column in the map is set. The other // column values will be used to update the row. Future<int> update(Map<String, dynamic> row) async { Database db = await instance.database; int id = row[columnId]; return await db.update(table, row, where: '$columnId = ?', whereArgs: [id]); } // Deletes the row specified by the id. The number of affected rows is // returned. This should be 1 as long as the row exists. Future<int> delete(int id) async { Database db = await instance.database; return await db.delete(table, where: '$columnId = ?', whereArgs: [id]); } Future<List> getAllRecords(String dbTable) async { var dbClient = await instance.database; var result = await dbClient.rawQuery("SELECT * FROM $dbTable"); return result.toList(); } STEP 5: In initState(), set the default values for Calendar. DatabaseHelper dbHelper = DatabaseHelper.instance; List<Color> _colorCollection; List<String> _views; @override void initState() { _initializeEventColor(); _views = <String>[ 'Insert', 'Query', 'Update', 'Delete', ]; super.initState(); } STEP 6: Using the FutureBuilder widget get the values from the database. If the Snapshot.hasData contains data, then, you can load that database data to the Flutter calendar events. appBar: AppBar( title: Text('SQL data'), leading: PopupMenuButton<String>( icon: Icon(Icons.calendar_today), itemBuilder: (BuildContext context) => _views.map((String choice) { return PopupMenuItem<String>( value: choice, child: Text(choice), ); }).toList(), onSelected: (String value) { setState(() { if (value == 'Insert') { _insert(); } else if (value == 'Query') { _query(); } else if (value == 'Update') { _update(); } else { _delete(); } }); }, )), body: FutureBuilder<List>( future: dbHelper.getAllRecords("flutter_calendar_events"), builder: (context, snapshot) { List<Appointment> collection = <Appointment>[]; if (snapshot.data != null) { return ListView.builder( itemCount: 1, itemExtent: 550, itemBuilder: (context, int position) { var item = snapshot.data[position]; Random random = new Random(); for (int i = 0; i < snapshot.data.length; i++) { collection.add( Appointment( subject: item.row[1], startTime: _convertDateFromString(item.row[2]), endTime: _convertDateFromString(item.row[3]), color: _colorCollection[random.nextInt(9)], ), ); } return SfCalendar( view: CalendarView.month, initialDisplayDate: DateTime(2021, 1, 4, 9, 0, 0), monthViewSettings: MonthViewSettings(showAgenda: true), dataSource: _getCalendarDataSource(collection), ); }, ); } else { return CircularProgressIndicator(); } })); void _initializeEventColor() { // ignore: deprecated_member_use _colorCollection = List<Color>(); _colorCollection.add(const Color(0xFF0F8644)); _colorCollection.add(const Color(0xFF8B1FA9)); _colorCollection.add(const Color(0xFFD20100)); _colorCollection.add(const Color(0xFFFC571D)); _colorCollection.add(const Color(0xFF36B37B)); _colorCollection.add(const Color(0xFF01A1EF)); _colorCollection.add(const Color(0xFF3D4FB5)); _colorCollection.add(const Color(0xFFE47C73)); _colorCollection.add(const Color(0xFF636363)); _colorCollection.add(const Color(0xFF0A8043)); } View sample in GitHub ConclusionI hope you enjoyed learning about how to load data from offline SQLite database to Flutter Calendar.You can refer to our Flutter Calender feature tour page to know about its other groundbreaking feature representations. You can also explore our Flutter Calendar documentation to understand how to create and manipulate data.For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!
In Flutter, override the Material app locale with different locale by using the Localization.override constructor. The SfCalendar and SfDateRangePicker control is present in the Column widget. Place the SfCalendar in the Localization.override constructor in which the inherited locale (defined in Material app locale) or LocalizationsDelegate for child has been overridden with English language for SfCalendar and SfDateRangePicker has Material app locale. import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; import 'package:syncfusion_flutter_datepicker/datepicker.dart'; void main() => runApp(LocalizationSupport()); class LocalizationSupport extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: [ const Locale('en'), const Locale('zh'), const Locale('he'), const Locale('ru'), const Locale('fr', 'BE'), const Locale('fr', 'CA'), const Locale('ja'), const Locale('de'), const Locale('hi'), const Locale('ar'), ], locale: const Locale('zh'), debugShowCheckedModeBanner: false, home: CustomStringLocale(), ); } } class CustomStringLocale extends StatefulWidget { @override State<StatefulWidget> createState() => ScheduleExample(); } class ScheduleExample extends State<CustomStringLocale> { @override Widget build(BuildContext context) { return (Scaffold( body: Column( children: [ Localizations.override( context: context, locale: Locale('en'), child: Expanded(child: SfCalendar()), ), SfDateRangePicker() ], ), )); } } View sample in GitHub