Latest source merged from Syncfusion

This commit is contained in:
buildautomation 2021-10-01 11:17:05 +05:30
Родитель 97c07e66e6
Коммит c60b1d1517
113 изменённых файлов: 22358 добавлений и 232 удалений

Просмотреть файл

@ -0,0 +1,182 @@
---
layout: post
title: Customizations in Flutter Date Range Picker widget | Syncfusion
description: Learn here all about Customizations features of Syncfusion Flutter Date Range Picker (SfDateRangePicker) widget and more.
platform: Flutter
control: SfDateRangePicker
documentation: ug
---
# Customizations in Flutter Date Range Picker (SfDateRangePicker)
You can customize the month and year cells, month format, and selection cells in [Flutter Date Range Picker](https://www.syncfusion.com/flutter-widgets/flutter-daterangepicker) (SfDateRangePicker).
## Month cell customization
You can customize the calendar month view by using the `monthCellStyle` of `SfDateRangePicker`.
**Current month dates** – You can customize the current month date's text style and background of the `DateRangePicker` by using the [textStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/textStyle.html) and [cellDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/cellDecoration.html) properties of [DateRangePickerMonthCellStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle-class.html)
**Today date** – You can customize the today date text style and background of the `DateRangePicker` by using the [todayTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/todayTextStyle.html) and [todayCellDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/todayCellDecoration.html).
**Leading dates** – You can hide the leading dates by using the [showTrailingAndLeadingDates](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthViewSettings/showTrailingAndLeadingDates.html) property in the [DateRangePickerMonthViewSettings](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthViewSettings-class.html) class. You can also customize the leading month dates text style and background of the `DateRangePicker` by using the [leadingDatesTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/leadingDatesTextStyle.html) and [leadingDatesDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/leadingDatesDecoration.html).
**Trailing dates** - You can hide the trailing dates by using `showTrailingAndLeadingDates` dates property in `DateRangePickerMonthViewSettings` class. You can also customize the trailing month dates text style and background of the `DateRangePicker` by using the [trailingDatesTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/trailingDatesTextStyle.html) and [trailingDatesDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/trailingDatesDecoration.html).
**Blackout Dates** - You can customize the blackout dates text style and background of the `DateRangePicker` by using the [blackoutDateTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/blackoutDateTextStyle.html) and [blackoutDatesDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/blackoutDatesDecoration.html).
**Disabled dates** – Disable dates text style and background of the `minDate` and `maxDate` in the `DateRangePicker`, and the dates which are disabled by the `selectableDayPredicate` callback are customized by using [disableDatesTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/disabledDatesTextStyle.html) and [disableDatesDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/disabledDatesDecoration.html).
**Special Dates** – You can add special dates to the `DateRangePicker` by using [specialDates](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthViewSettings/specialDates.html) property, and you can also customize the special dates text style and background by using the [specialDatesTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/specialDatesTextStyle.html) and [specialDatesDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/specialDatesDecoration.html).
**Weekend Dates** – You can change weekend dates to `DateRangePicker` by using the [weekendDays](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthViewSettings/weekendDays.html) property, and you can also customize the weekend dates text style and background by using the [weekendDatesTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/weekendTextStyle.html) and [weekendDatesDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/weekendDatesDecoration.html).
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
monthViewSettings:DateRangePickerMonthViewSettings(blackoutDates:[DateTime(2020, 03, 26)],
weekendDays: [7,6],
specialDates:[DateTime(2020, 03, 20),DateTime(2020, 03, 16),DateTime(2020,03,17)],
showTrailingAndLeadingDates: true),
monthCellStyle: DateRangePickerMonthCellStyle(
blackoutDatesDecoration: BoxDecoration(
color: Colors.red,
border: Border.all(color: const Color(0xFFF44436), width: 1),
shape: BoxShape.circle),
weekendDatesDecoration: BoxDecoration(
color: const Color(0xFFDFDFDF),
border: Border.all(color: const Color(0xFFB6B6B6), width: 1),
shape: BoxShape.circle),
specialDatesDecoration: BoxDecoration(
color: Colors.green,
border: Border.all(color: const Color(0xFF2B732F), width: 1),
shape: BoxShape.circle),
blackoutDateTextStyle: TextStyle(color: Colors.white, decoration: TextDecoration.lineThrough),
specialDatesTextStyle: const TextStyle(color: Colors.white),
),
)
);
}
{% endhighlight %}
{% endtabs %}
![Customizations Date Range Picker](images/customizations/customizations.png)
## Month format
You can customize the month format of the `DateRangePicker` using the [monthFormat](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/monthFormat.html) property.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
monthFormat: 'MMM',
),
);
}
{% endhighlight %}
{% endtabs %}
![Month cell customization Date Range Picker](images/customizations/monthcell_customization.png)
## Selection cell customization
You can also customize the date range picker section by using the `monthCellStyle` of `SfDateRangePicker`.
**Selection date text style** – Selected date text style can be customized using the [selectionTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/selectionTextStyle.html) property of `SfDateRangePicker` that is applicable for `selectionMode` is `single` and `multiple`, it is also applicable to start and end of the selected range text style in the `single` and `multi-range` selection.
**Selection color** – Selected date background color can be customized using the [selectionColor](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/selectionColor.html) property of `SfDateRangePicker` that is applicable for `single` and `multiple` selections.
**Range selection text style** – Range selection date text style can be customized using the [rangeTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/rangeTextStyle.html) property that is applicable when `selectionMode` is `range` or `multi-range`.
**Range selection color** - Range selection color text style can be customized using the [startRangeSelectionColor](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/startRangeSelectionColor.html), [endRangeSelectionColor](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/endRangeSelectionColor.html) , [rangeSelectionColor](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/rangeSelectionColor.html) properties that is applicable when `selectionMode` is in `range` or `multi-range`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
selectionMode: DateRangePickerSelectionMode.range,
selectionTextStyle: const TextStyle(color: Colors.white),
selectionColor: Colors.blue,
startRangeSelectionColor: Colors.purple,
endRangeSelectionColor: Colors.purple,
rangeSelectionColor: Colors.purpleAccent,
rangeTextStyle: const TextStyle(color: Colors.white, fontSize: 20),
));
}
{% endhighlight %}
{% endtabs %}
![Month Selection cell customization Date Range Picker](images/customizations/monthcell_selection_customization.png)
## Year cell customization
You can customize the calendar `year`, `decade`, and `century` view by using the `yearCellStyle` of `SfDateRangePicker`.
**Current year** – You can customize current month dates text style and background of the `DateRangePicker` by using the [textStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/textStyle.html) and [cellDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/cellDecoration.html) properties of [DateRangePickerYearCellStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerYearCellStyle-class.html)
**Disabled dates** – Disable dates text style and background of the `minDate` and `maxDate` in the `DateRangePicker`, and the dates which are disabled by the `selectableDayPredicate` callback are customized by using [disableDatesTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/disabledDatesTextStyle.html) and [disableDatesDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/disabledDatesDecoration.html).
**Leading dates** – You can also customize the leading month dates text style and background of the `DateRangePicker` by using the [leadingDatesTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/leadingDatesTextStyle.html) and [leadingDatesDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/leadingDatesDecoration.html).
**Today date** – You can customize the today date text style and background of the `DateRangePicker` by using the [todayTextStyle](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/todayTextStyle.html) and [todayCellDecoration](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthCellStyle/todayCellDecoration.html).
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
selectionMode: DateRangePickerSelectionMode.range,
yearCellStyle: DateRangePickerYearCellStyle(
disabledDatesDecoration:BoxDecoration(
color: const Color(0xFFDFDFDF),
border: Border.all(color: const Color(0xFFB6B6B6), width: 1),
shape: BoxShape.circle),
disabledDatesTextStyle: const TextStyle(color: Colors.black),
leadingDatesDecoration:BoxDecoration(
color: const Color(0xFFDFDFDF),
border: Border.all(color: const Color(0xFFB6B6B6), width: 1),
shape: BoxShape.circle),
leadingDatesTextStyle: const TextStyle(color: Colors.black),
textStyle: const TextStyle(color: Colors.blue),
todayCellDecoration: BoxDecoration(
color: const Color(0xFFDFDFDF),
border: Border.all(color: const Color(0xFFB6B6B6), width: 1),
shape: BoxShape.circle),
todayTextStyle: const TextStyle(color: Colors.purple),
)
),
);
}
{% endhighlight %}
{% endtabs %}
![Year cell customization Date Range Picker](images/customizations/yearcell_customization.png)
## See also
* [How to customize the month cell of the Flutter date range picker (SfDateRangePicker)?](https://www.syncfusion.com/kb/11307/how-to-customize-the-month-cell-of-the-flutter-date-range-picker-sfdaterangepicker)
* [How to style the current month date cell in the Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12190/how-to-style-the-current-month-date-cell-in-the-flutter-date-range-picker-sfdaterangepicker)
* [How to change the week end dates in the Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12182/how-to-change-the-week-end-dates-in-the-flutter-date-range-picker-sfdaterangepicker)
* [How to change the month format in the Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12169/how-to-change-the-month-format-in-the-flutter-date-range-picker-sfdaterangepicker)
* [How to customize the selected range cells in the Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12148/how-to-customize-the-selected-range-cells-in-the-flutter-date-range-picker)
* [How to add the indicator in the month cells of the date range picker (SfDateRangePicker), when the Flutter event calendar (SfCalendar) has an appointments?](https://www.syncfusion.com/kb/12119/how-to-add-the-indicator-in-the-month-cells-of-the-date-range-picker-sfdaterangepicker-when)
* [How to add custom fonts in Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12212/how-to-add-custom-fonts-in-flutter-date-range-picker-sfdaterangepicker)
* [How to style the year, decade, century views in the Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12321/how-to-style-the-year-decade-century-views-in-the-flutter-date-range-picker)
* [How to customize the special dates using builder in the Flutter date picker](https://www.syncfusion.com/kb/12374/how-to-customize-the-special-dates-using-builder-in-the-flutter-date-picker)

Просмотреть файл

@ -0,0 +1,125 @@
---
layout: post
title: Date Restrictions in Flutter Date Range Picker widget | Syncfusion
description: Learn here all about Date restrictions feature of Syncfusion Flutter Date Range Picker (SfDateRangePicker) widget and more.
platform: flutter
control: SfDateRangePicker
documentation: ug
---
# Date Restrictions in Flutter Date Range Picker (SfDateRangePicker)
## Minimum display date
The [minDate](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/minDate.html) will restrict `backward` date navigations features, and cannot swipe the control using the touch gesture beyond the min date range in all views.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
minDate: DateTime(2020, 03, 05, 10 , 0, 0),
)
);
}
{% endhighlight %}
{% endtabs %}
## Maximum display date
The [maxDate](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/maxDate.html) will restrict `forward` date navigations features, and cannot swipe the control using the touch gesture beyond the max date range in all views.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
maxDate: DateTime(2020, 03, 25, 10 , 0, 0),
)
);
}
{% endhighlight %}
{% endtabs %}
![Min_Max Date Date Range Picker](images/date-restrictions/min_max_date.png)
## Enable and disable past dates
The `DateRangePicker` allows you to enable or disable the past dates from today's date in `MonthView`. This can be achieved by changing the [enablePastDates](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/enablePastDates.html) property. By default, the value of this property is set to true.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
enablePastDates : false,
)
);
}
{% endhighlight %}
{% endtabs %}
![Enable and disable past dates Range Picker](images/date-restrictions/enable_diasable_pastdates.png)
## Blackout Dates
In `DateRangePicker`, [blackoutDates](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthViewSettings/blackoutDates.html) refer to the disabled dates that restrict the user from selecting it. These dates will be marked with Strikethrough.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.year,
monthViewSettings: DateRangePickerMonthViewSettings(blackoutDates:[DateTime(2020, 03, 18), DateTime(2020, 03, 19)]),
)
);
}
{% endhighlight %}
{% endtabs %}
## SelectableDayPredicate
[selectableDayPredicate]() callback allows certain days for selection. Only the days that `selectableDayPredicate` returns `true` will be selectable in the date range picker.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(body: SafeArea(child: Card(child: SfDateRangePicker(
selectableDayPredicate: (DateTime dateTime) {
if (dateTime == DateTime(2021, 9, 5)) {
return false;
}
return true;
},
))));
}
{% endhighlight %}
{% endtabs %}
>**NOTE**
* Applicable for year, decade and century views only when the `allowViewNavigation` set as false.
* This callback is not applicable when the `navigationMode` set as `DateRangePickerNavigationMode.scroll`.
![selectable day predicate Range Picker](images/date-restrictions/selectableDayPredicate.jpg)
## See also
* [How to enable or disable the past dates in the Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12168/how-to-enable-or-disable-the-past-dates-in-the-flutter-date-range-picker-sfdaterangepicker)
* [How to add active dates in the Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12075/how-to-add-active-dates-in-the-flutter-date-range-picker-sfdaterangepicker)
* [How to restrict date range picker within the date limit in Flutter date range picker (SfDateRangePicker)?](https://www.syncfusion.com/kb/11329/how-to-restrict-date-range-picker-within-the-date-limit-in-flutter-date-range-picker)
* [How to update blackout dates using onViewChanged callback in the Flutter date picker](https://www.syncfusion.com/kb/12372/how-to-update-blackout-dates-using-onviewchanged-callback-in-the-flutter-date-picker)

Просмотреть файл

@ -1,30 +1,37 @@
---
layout: post
title: "Flutter date range picker widget | Syncfusion"
description: Getting started with the Syncfusion flutter date range picker with four built-in configurable views modes.
title: Getting started with Flutter Date Range Picker widget | Syncfusion
description: Learn here about getting started with Syncfusion Flutter Date Range Picker (SfDateRangePicker) widget, its elements, and more.
platform: flutter
control: SfDateRangePicker
documentation: ug
---
# Getting Started with Flutter Date Range Picker (SfDateRangePicker)
This section explains the steps required to add the date picker range widget. This section covers only basic features needed to get started with Syncfusion date range picker widget.
# Getting started with Flutter Date Range Picker (SfDateRangePicker)
This section explains the steps required to add the [date range picker](https://www.syncfusion.com/flutter-widgets/flutter-daterangepicker) widget. This section covers only basic features needed to get started with Syncfusion date range picker widget.
## Add flutter calendar to an application
To get start quickly with our Flutter date range picker widget, you can check on this video.
<style>#flutterDateRangePickerVideoTutorial{width : 90% !important; height: 300px !important }</style>
<iframe id='flutterDateRangePickerVideoTutorial' src='https://www.youtube.com/embed/3TyuUVExuPs'></iframe>
## Add Flutter Date Range Picker to an application
Create a simple project using the instructions given in the [Getting Started with your first Flutter app](https://flutter.dev/docs/get-started/test-drive?tab=vscode#create-app) documentation.
**Add dependency**
Add the Syncfusion flutter date picker range dependency to your pubspec.yaml file.
Add the Syncfusion Flutter date range picker dependency to your `pubspec.yaml` file.
{% highlight dart %}
dependencies:
syncfusion_flutter_datepicker: ^17.4.39-beta
syncfusion_flutter_datepicker: ^xx.x.xx
{% endhighlight %}
N> Here **xx.x.xx** denotes the current version of [`Syncfusion Flutter Date Picker`](https://pub.dev/packages/syncfusion_flutter_datepicker/versions) package.
**Get packages**
Run the following command to get the required packages.
@ -49,7 +56,7 @@ import 'package:syncfusion_flutter_datepicker/datepicker.dart';
## Initialize date range picker
After importing the package, initialize the date range picker widget as a child of any widget. Here, the date picker range widget is added as a child of the scaffold widget.
After importing the package, initialize the date range picker widget as a child of any widget. Here, the date range picker widget is added as a child of the scaffold widget.
{% tabs %}
{% highlight Dart %}
@ -58,17 +65,18 @@ After importing the package, initialize the date range picker widget as a child
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SfDateRangePicker(),
child: SfDateRangePicker(),
));
}
{% endhighlight %}
{% endtabs %}
![Initialize Date Range Picker](images/getting-started/initialize.png)
## Change different views
## Multiple picker views
The SfDateRangePicker widget provides four different types of views to display. It can be assigned to the widget constructor by using the [view](https://pub.dev/documentation/syncfusion_flutter_daterangepicker/latest/daterangepicker/SfDateRangePicker/view.html) property. Default view of the widget is month view. By default the current date will be displayed initially for all the date range picker views.
The [SfDateRangePicker](https://www.syncfusion.com/flutter-widgets/flutter-daterangepicker) widget provides four different types of views to display. It can be assigned to the widget constructor by using the [view](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/view.html) property. Default view of the widget is month view. By default the current date will be displayed initially for all the date range picker views.
{% tabs %}
{% highlight Dart %}
@ -77,16 +85,19 @@ The SfDateRangePicker widget provides four different types of views to display.
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.year,
));
view: DateRangePickerView.year,
)
);
}
{% endhighlight %}
{% endtabs %}
![Multiple picker views Date Range Picker](images/getting-started/year-view.png)
## Change first day of week
The DateRangePicker widget will be rendered with Sunday as the first day of the week, but you can customize it to any day by using the [firstDayOfWeek](https://pub.dev/documentation/syncfusion_flutter_daterangepicker/latest/daterangepicker/SfDateRangePicker/firstDayOfWeek.html) property.
The DateRangePicker widget will be rendered with Sunday as the first day of the week, but you can customize it to any day by using the [firstDayOfWeek](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/DateRangePickerMonthViewSettings/firstDayOfWeek.html) property.
{% tabs %}
{% highlight Dart %}
@ -94,43 +105,107 @@ The DateRangePicker widget will be rendered with Sunday as the first day of the
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
firstDayOfWeek: 1,
));
body: SfDateRangePicker(
view: DateRangePickerView.month,
monthViewSettings: DateRangePickerMonthViewSettings(firstDayOfWeek: 1),
)
);
}
{% endhighlight %}
{% endtabs %}
## Date selection
The DateRangePicker supports selecting single, multiple, and range of dates. It also supports programmatic selection.
The [DateRangePicker](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker-class.html) supports selecting single, multiple, and range of dates. It also supports programmatic selection.
The selected date or range details can be obtained using the `onSelectionChanged` callback of datepicker. The callback will return the `DateRangePickerSelectionChangedArgs` which contains the selected date or range details.
The selected date or range details can be obtained using the [onSelectionChanged](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/onSelectionChanged.html) callback of date range picker. The callback will return the `DateRangePickerSelectionChangedArgs` which contains the selected date or range details.
{% tabs %}
{% highlight Dart %}
void _onSelectionChanged(DateRangePickerSelectionChangedArgs args) {
final dynamic value = args;
// TODO: implement your code here
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfDateRangePicker(
onSelectionChanged: _onSelectionChanged,
selectionMode: DateRangePickerSelectionMode.range,
return MaterialApp(
home: Scaffold(
body: Container(
child: SfDateRangePicker(
onSelectionChanged: _onSelectionChanged,
selectionMode: DateRangePickerSelectionMode.range,
),
),
),
),
);
);
}
{% endhighlight %}
{% endtabs %}
![Date selection Date Range Picker](images/getting-started/range-selection.png)
## Action buttons
You can display action buttons at the bottom of the date range picker by using the [showActionButtons](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker/showActionButtons.html) property of `SfDateRangePicker`. It allows to confirm or cancel the selection values of [SfDateRangePicker](https://pub.dev/documentation/syncfusion_flutter_datepicker/latest/datepicker/SfDateRangePicker-class.html).
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: TextButton(
child: Text('Show picker'),
onPressed: () {
showDialog<Widget>(
context: context,
builder: (BuildContext context) {
return SfDateRangePicker(
showActionButtons: true,
onSubmit: (Object value) {
Navigator.pop(context);
},
onCancel: () {
Navigator.pop(context);
},
);
});
},
));
}
{% endhighlight %}
{% endtabs %}
![showActionButtons](images/getting-started/confirm_and_cancel_buttons.png)
## Today button
The today button can be displayed at the bottom of the date range picker by using the [showTodayButton]() property of the `DateRangePicker`. It easily moves to the current date of the picker view.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDateRangePicker(
view: DateRangePickerView.month,
showTodayButton: true,
)
);
}
{% endhighlight %}
{% endtabs %}
![todayButton](images/getting-started/todayButton.jpg)
## See also
* [How to apply theming in Flutter date range picker (SfDateRangePicker)?](https://www.syncfusion.com/kb/11898/how-to-apply-theming-in-flutter-date-range-picker-sfdaterangepicker)
* [How to change the first day of week in the Flutter date range picker (SfDateRangePicker)](https://www.syncfusion.com/kb/12221/how-to-change-the-first-day-of-week-in-the-flutter-date-range-picker-sfdaterangepicker)
* [How to confirm or cancel the selection in the Flutter Date Range Picker](https://www.syncfusion.com/kb/12546/how-to-confirm-or-cancel-the-selection-in-the-flutter-date-range-picker)

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Двоичные данные
Flutter/DateRangePicker/images/getting-started/todayButton.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 25 KiB

Просмотреть файл

@ -0,0 +1,17 @@
---
title: Essential Studio for Flutter Weekly Nuget Release Release Notes
description: Essential Studio for Flutter Weekly Nuget Release Release Notes
platform: flutter
documentation: ug
---
# Essential Studio for Flutter Release Notes
{% include release-info.html date="August 31, 2021" version="v19.2.0.59" %}
{% directory path: _includes/release-notes/v19.2.0.59 %}
{% include {{file.url}} %}
{% enddirectory %}

Просмотреть файл

@ -0,0 +1,17 @@
---
title: Essential Studio for Flutter 2021 volume 3 Main Release Notes
description: Essential Studio for Flutter 2021 volume 3 Main Release Notes
platform: flutter
documentation: ug
---
# Essential Studio for Flutter Release Notes
{% include release-info.html date="September 30, 2021" version="v19.3.0.43" %}
{% directory path: _includes/release-notes/v19.3.0.43 %}
{% include {{file.url}} %}
{% enddirectory %}

Просмотреть файл

@ -0,0 +1,148 @@
---
layout: post
title: Appointment resizing in Flutter Event Calendar widget | Syncfusion
description: Learn here all about appointment resizing feature of Syncfusion Flutter Event Calendar (SfCalendar) widget and more.
platform: flutter
control: SfCalendar
documentation: ug
---
# Appointment Resize in Flutter Event Calendar (SfCalendar)
You can quickly change an appointments start and end times by resizing the appointment.
## Allow Appointment resize
[allowAppointmentResize]() property allows to reschedule the appointment by resizing the appointment in desktop platforms.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowAppointmentResize: true),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![appointment_resizing](images/appointments/appointment_resize.gif)
>**NOTE**
* It is not applicable for mobile platforms.
## onAppointmentResizeStart
[onAppointmentResizeStart]() callback was called whenever the appointment starts to resizing in SfCalendar. The [AppointmentResizeStartDetails]() arguments contains the resizing appointment, and resource details.
[appointment]() - Get the resizing appointment details.
[resource]() - Get the resource details.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowAppointmentResize: true,
onAppointmentResizeStart: resizeStart,
),
),
),
);
}
void resizeStart(AppointmentResizeStartDetails appointmentResizeStartDetails) {
dynamic appointment = appointmentResizeStartDetails.appointment;
CalendarResource? resource = appointmentResizeStartDetails.resource;
}
{% endhighlight %}
{% endtabs %}
## onAppointmentResizeUpdate
[onAppointmentResizeUpdate]() callback was called whenever the appointment resizing in SfCalendar. The [AppointmentResizeUpdateDetails]() arguments contains the resizing appointment, resizing time, resizing offset and resource details.
[appointment]() - Get the resize appointment.
[resizingTime]() - Get the resize appointment time.
[Resizing offset]() - Get the offset value.
[Resource details]() - Get the resource details.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowAppointmentResize: true,
onAppointmentResizeUpdate: resizeUpdate,
),
),
),
);
}
void resizeUpdate(AppointmentResizeUpdateDetails appointmentResizeUpdateDetails) {
dynamic appointment = appointmentResizeUpdateDetails.appointment;
DateTime? resizingTime = appointmentResizeUpdateDetails.resizingTime;
Offset? resizingOffset = appointmentResizeUpdateDetails.resizingOffset;
CalendarResource? resourceDetails = appointmentResizeUpdateDetails.resource;
}
{% endhighlight %}
{% endtabs %}
## onAppointmentResizeEnd
[onAppointmentResizeEnd]() callback was called whenever the appointment resizing end in the SfCalendar. The [AppointmentResizeEndDetails]() arguments contains the resized appointment, start time, end time and resource details.
[appointment]() - Get the resized appointment details.
[startTime]() - Get the start time.
[endTime]() - Get the end time.
[resource]() - Get the resource details.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowAppointmentResize: true,
onAppointmentResizeEnd: resizeEnd,
),
),
),
);
}
void resizeEnd(AppointmentResizeEndDetails appointmentResizeEndDetails) {
dynamic appointment = appointmentResizeEndDetails.appointment;
DateTime? startTime = appointmentResizeEndDetails.startTime;
DateTime? endTime = appointmentResizeEndDetails.endTime;
CalendarResource? resourceDetails = appointmentResizeEndDetails.resource;
}
{% endhighlight %}
{% endtabs %}

Просмотреть файл

@ -1,13 +1,13 @@
---
layout: post
title: Appointments | events in Syncfusion Flutter Calendar | Scheduler
description: Learn how to plan, configure and manage all day, recurrence and spanning appointments in Syncfusion Flutter Calendar.
title: Appointments in Flutter Event Calendar widget | Syncfusion
description: Learn here all about Appointments feature of Syncfusion Flutter Event Calendar (SfCalendar) widget and more.
platform: flutter
control: SfCalendar
documentation: ug
---
# Appointments
# Appointments in Flutter Event Calendar (SfCalendar)
SfCalendar widget has a built-in capability to handle the appointment arrangement internally based on the [CalendarDataSource](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/CalendarDataSource-class.html). [Appointment](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/Appointment-class.html) is a class, which holds the details about the appointment to be rendered in calendar.
@ -82,37 +82,37 @@ class MeetingDataSource extends CalendarDataSource {
@override
DateTime getStartTime(int index) {
return appointments[index].from;
return appointments![index].from;
}
@override
DateTime getEndTime(int index) {
return appointments[index].to;
return appointments![index].to;
}
@override
bool isAllDay(int index) {
return appointments[index].isAllDay;
return appointments![index].isAllDay;
}
@override
String getSubject(int index) {
return appointments[index].eventName;
return appointments![index].eventName;
}
@override
String getStartTimeZone(int index) {
return appointments[index].startTimeZone;
return appointments![index].startTimeZone;
}
@override
String getEndTimeZone(int index) {
return appointments[index].endTimeZone;
return appointments![index].endTimeZone;
}
@override
Color getColor(int index) {
return appointments[index].background;
return appointments![index].background;
}
}
@ -138,7 +138,7 @@ You can create a custom class `Meeting` with mandatory fields `from`, and `to`.
{% highlight Dart %}
class Meeting {
Meeting({this.eventName, this.from, this.to, this.background, this.isAllDay});
Meeting({this.eventName = '', required this.from, required this.to, required this.background, this.isAllDay = false});
String eventName;
DateTime from;
@ -162,37 +162,37 @@ class MeetingDataSource extends CalendarDataSource {
@override
DateTime getStartTime(int index) {
return appointments[index].from;
return appointments![index].from;
}
@override
DateTime getEndTime(int index) {
return appointments[index].to;
return appointments![index].to;
}
@override
bool isAllDay(int index) {
return appointments[index].isAllDay;
return appointments![index].isAllDay;
}
@override
String getSubject(int index) {
return appointments[index].eventName;
return appointments![index].eventName;
}
@override
String getStartTimeZone(int index) {
return appointments[index].startTimeZone;
return appointments![index].startTimeZone;
}
@override
String getEndTimeZone(int index) {
return appointments[index].endTimeZone;
return appointments![index].endTimeZone;
}
@override
Color getColor(int index) {
return appointments[index].background;
return appointments![index].background;
}
}
@ -233,6 +233,63 @@ MeetingDataSource _getCalendarDataSource() {
{% endhighlight %}
{% endtabs %}
## Get the business object data
The event data can be achieved in the custom business object type by overriding the [convertAppointmentToObject()]() method from the `CalendarDataSource`.
{% tabs %}
{% highlight Dart %}
class _DataSource extends CalendarDataSource<_Meeting> {
_DataSource(List<_Meeting> source) {
appointments = source;
}
@override
DateTime getStartTime(int index) {
return appointments![index].from as DateTime;
}
@override
DateTime getEndTime(int index) {
return appointments![index].to as DateTime;
}
@override
String getSubject(int index) {
return appointments![index].content as String;
}
@override
Color getColor(int index) {
return appointments![index].background as Color;
}
@override
Meeting convertAppointmentToObject(
_Meeting customData, Appointment appointment) {
return Meeting(
from: appointment.startTime,
to: appointment.endTime,
content: appointment.subject,
background: appointment.color,
isAllDay: appointment.isAllDay);
}
}
class Meeting {
Meeting({this.content = '', required this.from, required this.to, required this.background, this.isAllDay = false});
String content;
DateTime from;
DateTime to;
Color background;
bool isAllDay;
}
{% endhighlight %}
{% endtabs %}
## Spanned appointments
Spanned Appointment is an appointment, which lasts more than 24 hours. It does not block out time slots in SfCalendar, it will render in `All-Day appointment panel` exclusively.
@ -297,11 +354,11 @@ The `recurrenceRule` is a string value (RRULE) that contains the details of the
| FREQ | Maintains the Repeat type value of the appointment. (Example: Daily, Weekly, Monthly, Yearly, Every week day) Example: FREQ=DAILY;INTERVAL=1 |
| INTERVAL | Maintains the interval value of the appointments. For example, when you create the daily appointment at an interval of 2, the appointments are rendered on the days Monday, Wednesday and Friday. (creates the appointment on all days by leaving the interval of one day gap) Example: FREQ=DAILY;INTERVAL=1 |
| COUNT | It holds the appointments count value. For example, when the recurrence appointment count value is 10, it means 10 appointments are created in the recurrence series. Example: FREQ=DAILY;INTERVAL=1;COUNT=10 |
| UNTIL | This property is used to store the recurrence end date value. For example, when you set the end date of appointment as 6/30/2020, the UNTIL property holds the end date value when the recurrence actually ends. Example: FREQ=DAILY;INTERVAL=1;UNTIL=8/25/2020 |
| UNTIL | This property is used to store the recurrence end date value. For example, when you set the end date of appointment as 6/30/2020, the UNTIL property holds the end date value when the recurrence actually ends. Example: FREQ=DAILY;INTERVAL=1;UNTIL=20200827T183000Z |
| BYDAY | It holds the “DAY” values of an appointment to render.For example, when you create the weekly appointment, select the day(s) from the day options (Monday/Tuesday/Wednesday/Thursday/Friday/Saturday/Sunday). When Monday is selected, the first two letters of the selected day “MO” is stored in the “BYDAY” property. When you select multiple days, the values are separated by commas. Example: FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE;COUNT=10 |
| BYMONTHDAY | This property is used to store the date value of the Month while creating the Month recurrence appointment. For example, when you create a Monthly recurrence appointment in the date 3, it means the BYMONTHDAY holds the value 3 and creates the appointment on 3rd day of every month. Example: FREQ=MONTHLY;BYMONTHDAY=3;INTERVAL=1;COUNT=10 |
| BYMONTH | This property is used to store the index value of the selected Month while creating the yearly appointments. For example, when you create the yearly appointment in the Month June, it means the index value for June month is 6 and it is stored in the BYMONTH field. The appointment is created on every 6th month of a year. Example: FREQ=YEARLY;BYMONTHDAY=16;BYMONTH=6;INTERVAL=1;COUNT=10 |
| BYSETPOS | This property is used to store the index value of the week. For example, when you create the monthly appointment in second week of the month, the index value of the second week (2) is stored in BYSETPOS. Example: FREQ=MONTHLY;BYDAY=MO;BYSETPOS=2;UNTIL=8/11/2020 |
| BYSETPOS | This property is used to store the index value of the week. For example, when you create the monthly appointment in second week of the month, the index value of the second week (2) is stored in BYSETPOS. Example: FREQ=MONTHLY;BYDAY=MO;BYSETPOS=2;UNTIL=20200810T183000Z . If the property value is set to -1 and -2, the appointment will be added to the last week and second last week of the month.|
### Adding recurrence appointment
@ -357,11 +414,11 @@ For creating custom recurrence appointment, you need to create a custom class `M
class Meeting {
Meeting(
{this.eventName,
this.from,
this.to,
this.background,
this.isAllDay,
{this.eventName = '',
required this.from,
required this.to,
required this.background,
this.isAllDay = false,
this.recurrenceRule});
String eventName;
@ -369,7 +426,7 @@ class Meeting {
DateTime to;
Color background;
bool isAllDay;
String recurrenceRule;
String? recurrenceRule;
}
{% endhighlight %}
@ -387,32 +444,32 @@ class MeetingDataSource extends CalendarDataSource {
@override
DateTime getStartTime(int index) {
return appointments[index].from;
return appointments![index].from;
}
@override
DateTime getEndTime(int index) {
return appointments[index].to;
return appointments![index].to;
}
@override
bool isAllDay(int index) {
return appointments[index].isAllDay;
return appointments![index].isAllDay;
}
@override
String getSubject(int index) {
return appointments[index].eventName;
return appointments![index].eventName;
}
@override
Color getColor(int index) {
return appointments[index].background;
return appointments![index].background;
}
@override
String getRecurrenceRule(int index) {
return appointments[index].recurrenceRule;
return appointments![index].recurrenceRule;
}
}
@ -457,41 +514,41 @@ class MeetingDataSource extends CalendarDataSource {
@override
DateTime getStartTime(int index) {
return appointments[index].from;
return appointments![index].from;
}
@override
DateTime getEndTime(int index) {
return appointments[index].to;
return appointments![index].to;
}
@override
bool isAllDay(int index) {
return appointments[index].isAllDay;
return appointments![index].isAllDay;
}
@override
String getSubject(int index) {
return appointments[index].eventName;
return appointments![index].eventName;
}
@override
Color getColor(int index) {
return appointments[index].background;
return appointments![index].background;
}
@override
String getRecurrenceRule(int index) {
return appointments[index].recurrenceRule;
return appointments![index].recurrenceRule;
}
}
class Meeting {
Meeting({this.eventName,
this.from,
this.to,
this.background,
this.isAllDay,
Meeting({this.eventName = '',
required this.from,
required this.to,
required this.background,
this.isAllDay = false,
this.recurrenceRule});
String eventName;
@ -499,7 +556,7 @@ class Meeting {
DateTime to;
Color background;
bool isAllDay;
String recurrenceRule;
String? recurrenceRule;
}
{% endhighlight %}
@ -624,16 +681,16 @@ To add the exception dates in the recurrence series of custom appointment, add t
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
),
),
),
),
);
);
}
MeetingDataSource _getCalendarDataSource() {
@ -659,47 +716,47 @@ class MeetingDataSource extends CalendarDataSource {
@override
DateTime getStartTime(int index) {
return appointments[index].from;
return appointments![index].from;
}
@override
DateTime getEndTime(int index) {
return appointments[index].to;
return appointments![index].to;
}
@override
bool isAllDay(int index) {
return appointments[index].isAllDay;
return appointments![index].isAllDay;
}
@override
String getSubject(int index) {
return appointments[index].eventName;
return appointments![index].eventName;
}
@override
Color getColor(int index) {
return appointments[index].background;
return appointments![index].background;
}
@override
String getRecurrenceRule(int index) {
return appointments[index].recurrenceRule;
return appointments![index].recurrenceRule;
}
@override
List<DateTime> getRecurrenceExceptionDates(int index) {
return appointments[index].exceptionDates;
return appointments![index].exceptionDates;
}
}
class Meeting {
Meeting(
{this.eventName,
this.from,
this.to,
this.background,
this.isAllDay,
{this.eventName = '',
required this.from,
required this.to,
required this.background,
this.isAllDay = false,
this.recurrenceRule,
this.exceptionDates});
@ -708,8 +765,8 @@ class Meeting {
DateTime to;
Color background;
bool isAllDay;
String recurrenceRule;
List<DateTime> exceptionDates;
String? recurrenceRule;
List<DateTime>? exceptionDates;
}
{% endhighlight %}
@ -718,8 +775,67 @@ class Meeting {
>**NOTE**
* Exception dates should be Universal Time Coordinates (UTC) time zone.
### Add exception appointment to the recurrence series
Add an exception appointment that is changed or modified occurrence of the recurrence pattern appointment to the `dateSource` of the `SfCalendar`. To add a changed occurrence, ensure to set the [RecurrenceId](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/Appointment/recurrenceId.html) of that occurrence, and add the date of that occurrence to the [RecurrenceExceptionDates](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/Appointment/recurrenceExceptionDates.html) of recurrence pattern appointment. The `RecurrenceId` of the changed occurrence should hold the exact recurrence pattern appointment [Id](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/Appointment/id.html). We can get the type of appointment from the [appointmentType](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/Appointment/appointmentType.html) property.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getDataSource(),
),
),
),
);
}
AppointmentDataSource _getDataSource() {
final List<Appointment> appointments = <Appointment>[];
final DateTime exceptionDate = DateTime(2021, 04, 20);
final Appointment recurrenceAppointment = Appointment(
startTime: DateTime(2021, 04, 12, 10),
endTime: DateTime(2021, 04, 12, 12),
subject: 'Scrum meeting',
id: '01',
recurrenceRule: 'FREQ=DAILY;INTERVAL=1;COUNT=10',
color: Colors.purple,
recurrenceExceptionDates: <DateTime>[exceptionDate],
);
appointments.add(recurrenceAppointment);
final Appointment exceptionAppointment = Appointment(
startTime: exceptionDate.add(const Duration(hours: 14)),
endTime: exceptionDate.add(const Duration(hours: 15)),
subject: 'Meeting',
id: '02',
color: Colors.pinkAccent,
recurrenceId: recurrenceAppointment.id);
appointments.add(exceptionAppointment);
return AppointmentDataSource(appointments);
}
{% endhighlight %}
{% endtabs %}
![Recurrence Series in Flutter Calendar](images/appointments/flutter-calendar-recurrence-series.png)
>**NOTE**
* The RecurrenceId of the changed occurrence should hold the exact recurrence pattern appointment Id.
* The exception appointment should be a normal appointment, and should not be created as recurring appointment, since its occurrence is from recurrence pattern.
* The exception recurrence appointment does not have the RecurrenceRule, so for an exception appointment, it will be reset to empty.
## Appearance customization
Calendar appointment text style can be customized by using the [appointmentTextStyle](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/appointmentTextStyle.html) property of calendar.
The Calendar appointment text style can be customized by using the [appointmentTextStyle](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/appointmentTextStyle.html) property of the calendar.
{% tabs %}
{% highlight Dart %}
@ -747,3 +863,162 @@ Widget build(BuildContext context) {
{% endtabs %}
![Appearance customization](images/appointments/appearance-customization.png)
## Appointment time format
You can customize the displaying time format in the appointment widget in the month agenda view and schedule view of calendar by specifying the [appointmentTimeTextFormat](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/appointmentTimeTextFormat.html) property of the SfCalendar.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return SfCalendar(
view: CalendarView.month,
dataSource: _calendarDataSource,
appointmentTimeTextFormat: 'HH:mm',
monthViewSettings: MonthViewSettings(
showAgenda: true
),
);
}
{% endhighlight %}
{% endtabs %}
![Appointment time format](images/appointments/appointment_time_format.png)
## Appointment helper
### Get visible appointments
You can get the list of visible appointments by using the [getVisibleAppointments](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/CalendarDataSource/getVisibleAppointments.html) method available in the Calendar data source.
{% tabs %}
{% highlight Dart %}
@override
initState() {
_calendarController = CalendarController();
_dataSource = _getCalendarDataSource();
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SfCalendar(
view: CalendarView.month,
controller: _calendarController,
dataSource: _dataSource,
onViewChanged: (ViewChangedDetails details) {
List<DateTime> dates = details.visibleDates;
String calendarTimeZone = '';
List<Object> appointment = _dataSource.getVisibleAppointments(
dates[0], calendarTimeZone,
dates[(details.visibleDates.length) - 1]);
},
),
),
);
}
}
{% endhighlight %}
{% endtabs %}
>**NOTE**
* The `startTime` specifies the starting date from which the appointments should be obtained.
### Get occurrence appointment
Gets an occurrence at the specified date within a series of recurring appointments by using the [getOccurrenceAppointment](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/CalendarDataSource/getOccurrenceAppointment.html).
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SfCalendar(
view: CalendarView.month,
controller: _calendarController,
dataSource: _dataSource,
onTap: (CalendarTapDetails details) {
final DateTime? date = details.date;
final Appointment? occurrenceAppointment =
_dataSource.getOccurrenceAppointment(recurrenceApp, date!, '');
},
),
),
);
}
{% endhighlight %}
{% endtabs %}
>**NOTE**
* If there is no appointment occurring on the date specified, null is returned.
* The `patternAppointment` is required for the start appointment in a recurrence series, from which the occurrence appointments are cloned with the pattern appointment characteristics.
* The `date` is required for the occurrence appointment.
### Get pattern appointment
Gets the pattern appointment for the specified occurrence by using the [getPatternAppointment](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/CalendarDataSource/getPatternAppointment.html).
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SfCalendar(
view: CalendarView.month,
controller: _calendarController,
dataSource: _dataSource,
onTap: (CalendarTapDetails details) {
if (details.appointments!.isNotEmpty &&
details.appointments != null) {
final dynamic occurrenceAppointment = details.appointments![0];
final Appointment? patternAppointment =
_dataSource.getPatternAppointment(occurrenceAppointment, '')
as Appointment?;
}
},
),
),
);
}
{% endhighlight %}
{% endtabs %}
>**NOTE**
* The `occurrenceAppointment` is necessary in order to receive the Pattern appointment.
## See also
* [How to design and configure your appointment editor in event calendar widget Flutter](https://www.syncfusion.com/kb/11204/how-to-design-and-configure-your-appointment-editor-in-event-calendar-widget-flutter)
* [How to get appointment details from the OnTap event of the Flutter event calendar](https://www.syncfusion.com/kb/10999/how-to-get-appointment-details-from-the-ontap-event-of-the-flutter-event-calendar)
* [How to style the appointment in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12162/how-to-style-the-appointment-in-the-flutter-event-calendar-sfcalendar)
* [How to exclude the dates from recurrence appointments in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12161/how-to-exclude-the-dates-from-recurrence-appointments-in-the-flutter-event-calendar)
* [How to add recurring appointments until the specified date in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12158/how-to-add-recurring-appointments-until-the-specified-date-in-the-flutter-event-calendar)
* [How to add the appointments to the Fire base database using appointment editor in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12110/how-to-add-the-appointments-to-the-firebase-database-using-appointment-editor-in-the)
* [How to work with the Fire base database and the Flutter event calendar (SfCalendar) for appointments](https://www.syncfusion.com/kb/12067/how-to-work-with-the-firebase-database-and-the-flutter-event-calendar-sfcalendar-for)
* [How to add google calendar events to the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12116/how-to-add-google-calendar-events-to-the-flutter-event-calendar-sfcalendar)
* [How to add additional attributes in events in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12209/how-to-add-additional-attributes-in-events-in-the-flutter-event-calendar-sfcalendar)
* [How to add the appointments using the onTap callback in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12300/how-to-add-the-appointments-using-the-ontap-callback-in-the-flutter-calendar)
* [How to set the arbitrary height to appointments in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12279/how-to-set-the-arbitrary-height-to-appointments-in-the-flutter-event-calendar-sfcalendar)
* [How to get the recurrence date collection in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12344/how-to-get-the-recurrence-date-collection-in-the-flutter-event-calendar-sfcalendar)
* [How to get the recurrence properties from RRULE in the Flutter calendar](https://www.syncfusion.com/kb/12370/how-to-get-the-recurrence-properties-from-rrule-in-the-flutter-calendar)
* [How to update blackout dates using onViewChanged callback in the Flutter calendar](https://www.syncfusion.com/kb/12368/how-to-update-blackout-dates-using-onviewchanged-callback-in-the-flutter-calendar)
* [How to use navigation drawer for view switching in the Flutter calendar](https://www.syncfusion.com/kb/12361/how-to-use-navigation-drawer-for-view-switching-in-the-flutter-calendar)
* [How to show the tapped appointment details on another page in the Flutter event calendar](https://www.syncfusion.com/kb/12358/how-to-show-the-tapped-appointment-details-on-another-page-in-the-flutter-event-calendar)
* [How to load appointments On-Demand in Flutter Calendar](https://www.syncfusion.com/kb/12658/how-to-load-appointments-on-demand-in-flutter-calendar)
* [How to load the google calendar events to the Flutter Calendar (SfCalendar) in iOS](https://www.syncfusion.com/kb/12647/how-to-load-the-google-calendar-events-to-the-flutter-calendar-sfcalendar-in-ios)
* [How to perform the CRUD operations in Flutter Calendar using Fire base database](https://www.syncfusion.com/kb/12623/how-to-perform-the-crud-operations-in-flutter-calendar-using-firebase-database)
* [How to add the appointments to Fire store Database using Flutter Calendar](https://www.syncfusion.com/kb/12616/how-to-add-the-appointments-to-firestore-database-using-flutter-calendar)
* [How to perform the CRUD operations in Flutter Calendar using Fire store database](https://www.syncfusion.com/kb/12661/how-to-perform-the-crud-operations-in-flutter-calendar-using-firestore-database)

Просмотреть файл

@ -0,0 +1,295 @@
---
layout: post
title: Drag and drop in Flutter Event Calendar widget | Syncfusion
description: Learn here all about Drag and drop feature of Syncfusion Flutter Event Calendar (SfCalendar) widget and more.
platform: flutter
control: SfCalendar
documentation: ug
---
# Appointment Drag and Drop in Flutter Event Calendar (SfCalendar)
Easily reschedule an appointment by dragging it from one time slot or month cell and dropping it into a different time slot or month cell.
## Allow Drag and Drop
To perform drag-and-drop operations within the calendar, enable the [allowDragAndDrop]() property of SfCalendar.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![drag_and_drop](images/appointments/dragdrop.gif)
>**NOTE**
* It is not applicable for month view in mobile platform.
## onDragStart
[onDragStart]() callback was called whenever the appointment starts to drag in the SfCalendar. The [AppointmentDragStartDetails]() arguments contains the dragging appointment and associated resource details.
[appointment]() - Get the dragged appointment details.
[Resource]() - Get the resource details.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true,
onDragStart: dragStart,
),
),
),
);
}
void dragStart(AppointmentDragStartDetails appointmentDragStartDetails) {
dynamic appointment = appointmentDragStartDetails.appointment;
CalendarResource? resource = appointmentDragStartDetails.resource;
}
{% endhighlight %}
{% endtabs %}
## onDragUpdate
[onDragUpdate]() callback was called whenever the appointment is dragging in the SfCalendar. The [AppointmentDragUpdateDetails]() arguments contains the dragging appointment, dragging time, dragging offset, source resource and target resource details.
[appointment]() - Get the dragged appointment details.
[draggingTime]() - Get the resource details.
[draggingPosition]() - Get the drag position.
[sourceResource]() - Get the source resource details.
[targetResource]() - Get the resource details.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true,
onDragUpdate: dragUpdate,
),
),
),
);
}
void dragUpdate(AppointmentDragUpdateDetails appointmentDragUpdateDetails) {
dynamic appointment = appointmentDragUpdateDetails.appointment;
DateTime? draggingTime = appointmentDragUpdateDetails.draggingTime;
Offset? draggingOffset = appointmentDragUpdateDetails.draggingPosition;
CalendarResource? sourceResource = appointmentDragUpdateDetails.sourceResource;
CalendarResource? targetResource = appointmentDragUpdateDetails.targetResource;
}
{% endhighlight %}
{% endtabs %}
## onDragEnd
[onDragEnd]() callback called when the dragging appointment is dropped in the SfCalendar. The [AppointmentDragEndDetails]() arguments contains the dropped appointment, dropping time, source and target resource details.
[appointment]() - Get the dragged appointment details.
[droppingTime]() - Get the resource details.
[sourceResource]() - Get the resource details.
[targetResource]() - Get the target resource details.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true,
onDragEnd: dragEnd,
),
),
),
);
}
void dragEnd(AppointmentDragEndDetails appointmentDragEndDetails) {
dynamic appointment = appointmentDragEndDetails.appointment!;
CalendarResource? sourceResource = appointmentDragEndDetails.sourceResource;
CalendarResource? targetResource = appointmentDragEndDetails.targetResource;
DateTime? droppingTime = appointmentDragEndDetails.droppingTime;
}
{% endhighlight %}
{% endtabs %}
## Disabling navigation when dragging appointment
You can restrict the navigation to the next/previous view when the dragging appointment reaches the start/end point of the current view in calendar by using the [allowNavigation]() property of `DragDropSettings`. Default value of `allowNavigation` property is true.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true,
dragAndDropSettings: DragAndDropSettings(allowNavigation: true),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
## Disabling scroll when dragging appointment
You can restrict the timeslot views auto scroll when the appointment reaches the start/end point of the view port in the timeslot views of calendar by using the [allowScroll]() property of [DragDropSettings]().
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true,
dragAndDropSettings: DragAndDropSettings(allowScroll: true),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
## Time indicator
[showTimeIndicator]() - This property handles whether to show the time indicator or not, which shows the dragging appointment current time position in time ruler. Default value of the [ShowTimeIndicator]() property is true.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true,
dragAndDropSettings: DragAndDropSettings(showTimeIndicator: true),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
## Customize appearance of dragging Time Indicator
Using [timeIndicatorStyle]() property you can customize the text style of the time indicator. Also using [indicatorTimeFormat]() property you can customize the indicator time format.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true,
dragAndDropSettings: DragAndDropSettings(
indicatorTimeFormat: 'hh:mm',
showTimeIndicator: true,
timeIndicatorStyle: TextStyle(
backgroundColor: Color(0xFFCEE5D0),
color: Colors.black,
fontSize: 15,
),
),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![drag_and_drop_indicator_customization](images/appointments/dragtime_customization.gif)
## View Navigation Delay
Using [autoNavigateDelay]() property you can handle the navigation time when navigating to next/previous view while dragging the appointment.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
allowDragAndDrop: true,
dragAndDropSettings:
DragAndDropSettings(autoNavigateDelay: Duration(seconds: 1)),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}

Просмотреть файл

@ -1,30 +1,39 @@
---
layout: post
title: Flutter calendar widget to schedule & manage events | Syncfusion
description: Getting started with the Syncfusion flutter calendar widget to schedule an event with seven built-in configurable views modes.
title: Getting started with Flutter Event Calendar widget | Syncfusion
description: Learn here about getting started with Syncfusion Event Calendar (SfCalendar) widget, its elements, and more.
platform: flutter
control: SfCalendar
documentation: ug
---
# Getting Started
# Getting started with Flutter Event Calendar (SfCalendar)
This section explains the steps required to add the calendar widget and populate appointments to the calendar widget. This section covers only basic features needed to get started with Syncfusion calendar widget.
## Add flutter calendar to an application
To get start quickly with our [Flutter event calendar widget](https://www.syncfusion.com/flutter-widgets/flutter-calendar), you can check on this video.
<style>#flutterEventCalendarVideoTutorial{width : 90% !important; height: 300px !important }</style>
<iframe id='flutterEventCalendarVideoTutorial' src='https://www.youtube.com/embed/3OROjbAQS8Y'></iframe>
N> You can also explore our [Flutter Calendar example](https://flutter.syncfusion.com/#/event-calendar/getting-started) to know how to render and configure the Flutter Examples.
## Add Flutter calendar to an application
Create a simple project using the instructions given in the [Getting Started with your first Flutter app](https://flutter.dev/docs/get-started/test-drive?tab=vscode#create-app) documentation.
**Add dependency**
Add the Syncfusion flutter calendar dependency to your pubspec.yaml file.
Add the Syncfusion Flutter calendar dependency to your pubspec.yaml file.
{% highlight dart %}
dependencies:
syncfusion_flutter_calendar: ^17.4.39-beta
syncfusion_flutter_calendar: ^xx.x.xx
{% endhighlight %}
N> Here **xx.x.xx** denotes the current version of [`Syncfusion Flutter Calendar`](https://pub.dev/packages/syncfusion_flutter_calendar/versions) package.
**Get packages**
Run the following command to get the required packages.
@ -98,7 +107,7 @@ You can also map custom appointment data to our calendar.
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfCalendar(
body: SfCalendar(
view: CalendarView.month,
dataSource: MeetingDataSource(_getDataSource()),
monthViewSettings: MonthViewSettings(
@ -107,7 +116,7 @@ Widget build(BuildContext context) {
}
List<Meeting> _getDataSource() {
meetings = <Meeting>[];
final List<Meeting> meetings = <Meeting>[];
final DateTime today = DateTime.now();
final DateTime startTime =
DateTime(today.year, today.month, today.day, 9, 0, 0);
@ -117,34 +126,35 @@ List<Meeting> _getDataSource() {
return meetings;
}
class MeetingDataSource extends CalendarDataSource {
MeetingDataSource(List<Meeting> source){
MeetingDataSource(List<Meeting> source) {
appointments = source;
}
@override
DateTime getStartTime(int index) {
return appointments[index].from;
return appointments![index].from;
}
@override
DateTime getEndTime(int index) {
return appointments[index].to;
return appointments![index].to;
}
@override
String getSubject(int index) {
return appointments[index].eventName;
return appointments![index].eventName;
}
@override
Color getColor(int index) {
return appointments[index].background;
return appointments![index].background;
}
@override
bool isAllDay(int index) {
return appointments[index].isAllDay;
return appointments![index].isAllDay;
}
}
@ -345,4 +355,146 @@ Widget build(BuildContext context) {
![Background color](images/getting-started/calendar-background-color.png)
You can get the complete getting started sample from [here](https://github.com/SyncfusionExamples/flutter-calendar).
## Navigation arrow
Using the [showNavigationArrow](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/showNavigationArrow.html) property of the `SfCalendar`, you can navigate to the next or previous views of the calendar without swiping.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.month,
showNavigationArrow: true,
),
);
}
{% endhighlight %}
{% endtabs %}
![Show Navigation Arrow](images/getting-started/show-navigation-arrow.jpg)
>**NOTE**
* The `showNavigationArrow` property is not applicable when the `view` is set to `CalendarView.schedule`.
## Cell end padding
You can customize the padding of appointment view end to make touch position for timeslot and month cell by using the [cellEndPadding](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/cellEndPadding.html) property in the calendar, which allows you to tap the calendar cell when the cell has appointments.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SfCalendar(
view: CalendarView.month,
cellEndPadding: 5,
dataSource: _getCalendarDataSource(),
monthViewSettings: MonthViewSettings(
appointmentDisplayMode:
MonthAppointmentDisplayMode.appointment),
)),
);
}
{% endhighlight %}
{% endtabs %}
![Cell end padding](images/getting-started/cell-end-padding.png)
## Current time indicator
You can display the current time indicator in all timeslot views of SfCalendar by using the [showCurrentTimeIndicator](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/showCurrentTimeIndicator.html) property and you can also customize the color of current time indicator by using the [todayHighlightColor](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/todayHighlightColor.html) property.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.day,
showCurrentTimeIndicator: true,
),
);
}
{% endhighlight %}
{% endtabs %}
![showCurrentTimeIndicator](images/getting-started/current-time-indicator.png)
## Week number
Display the Week number of the year in all views except schedule view of the `SfCalendar` by setting the [showWeekNumber](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/showWeekNumber.html) property as true and by default it is false. Week numbers will be displayed based on the ISO standard.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SfCalendar(
view: CalendarView.month,
showWeekNumber: true,
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Week Number in Flutter Calendar](images\getting-started\flutter-calendar-week-number.png)
## Week number appearance
Customize the Week number text style of the calendar by using the [WeekNumberStyle](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/WeekNumberStyle-class.html) property. Allows to customize the [textStyle](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/WeekNumberStyle/textStyle.html) and the [backgroundColor](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/WeekNumberStyle/backgroundColor.html) in the Week number of the calendar.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SfCalendar(
view: CalendarView.month,
showWeekNumber: true,
weekNumberStyle: const WeekNumberStyle(
backgroundColor: Colors.pink,
textStyle: TextStyle(color: Colors.white, fontSize: 15),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Week Number Appearance in Flutter Calendar](images\getting-started\flutter-calendar-week-number-appearance.png)
Get the complete "getting started" sample from [here](https://github.com/SyncfusionExamples/flutter-calendar).
## See also
* [How to switch between views of the event calendar in Flutter?](https://www.syncfusion.com/kb/10944/how-to-switch-between-views-of-the-event-calendar-in-flutter)
* [How to update event calendar (SfCalendar) DisplayDate using showDatePicker in flutter](https://www.syncfusion.com/kb/11010/how-to-update-event-calendar-sfcalendar-displaydate-using-showdatepicker-in-flutter)
* [How can we move to specific time while switching from month to day view in Flutter event calendar](https://www.syncfusion.com/kb/10943/how-can-we-move-to-specific-time-while-switching-from-month-to-day-view-in-flutter-event)
* [How to customize the cell border in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12118/how-to-customize-the-cell-border-in-the-flutter-event-calendar-sfcalendar)
* [How to apply theming in Flutter event calendar (SfCalendar)?](https://www.syncfusion.com/kb/11899/how-to-apply-theming-in-flutter-event-calendar-sfcalendar)
* [How to add an image as background in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12243/how-to-add-an-image-as-background-in-the-flutter-event-calendar-sfcalendar)
* [How to change the first day of week in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12222/how-to-change-the-first-day-of-week-in-the-flutter-event-calendar-sfcalendar)
* [How to interact with event calendar cell when appointments loaded in the Flutter (SfCalendar)](https://www.syncfusion.com/kb/12218/how-to-interact-with-event-calendar-cell-when-appointments-loaded-in-the-flutter-sfcalendar)
* [How to customize the selection using decoration in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12245/how-to-customize-the-selection-using-decoration-in-the-flutter-event-calendar-sfcalendar)
* [How to navigate to the previous or next views using navigation arrows in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12247/how-to-navigate-to-the-previous-or-next-views-using-navigation-arrows-in-the-flutter-event)
* [How to customize the current day color in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12336/how-to-customize-the-current-day-color-in-the-flutter-event-calendar-sfcalendar)
* [How to show a particular week in a day view of Flutter event calendar(SfCalendar)](https://www.syncfusion.com/kb/12310/how-to-show-a-particular-week-in-a-day-view-of-flutter-event-calendarsfcalendar)
* [How to customize the selection using decoration in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12245/how-to-customize-the-selection-using-decoration-in-the-flutter-event-calendar-sfcalendar)
* [How to format the view header day and date in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12339/how-to-format-the-view-header-day-and-date-in-the-flutter-event-calendar-sfcalendar)

Двоичные данные
Flutter/calendar/images/appointments/appointment_resize.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 262 KiB

Двоичные данные
Flutter/calendar/images/appointments/dragdrop.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 442 KiB

Двоичные данные
Flutter/calendar/images/appointments/dragtime_customization.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 499 KiB

Двоичные данные
Flutter/calendar/images/getting-started/alldayPanelColor.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 29 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 71 KiB

Просмотреть файл

@ -1,35 +1,43 @@
---
layout: post
title: Overview of Syncfusion Flutter calendar | Scheduler
description: Learn the key features of Syncfusion Flutter Calendar (SfCalendar) widget and more details | Scheduler.
title: About Flutter Event Calendar widget | Syncfusion | Scheduler
description: Learn here all about introduction of Syncfusion Flutter Event Calendar (SfCalendar) widget, its features, and more.
platform: flutter
control: SfCalendar
documentation: ug
---
# Overview
# Flutter Event Calendar (SfCalendar) Overview
The Syncfusion Flutter Calendar library was written natively in Dart and has seven types of built-in configurable view modes that provide basic functionality for scheduling, managing, and representing appointments efficiently. The Calendar Widget exposes a clean and convenient user interface for custom working days and hours and basic calendar operations such as date navigation and selection.
The Syncfusion Flutter Calendar library was written natively in Dart and has nine types of built-in configurable view modes that provide basic functionality for scheduling, managing, and representing appointments efficiently. The Calendar Widget exposes a clean and convenient user interface for custom working days and hours and basic calendar operations such as date navigation and selection.
![Calendar overview](images/overview/calendar_overview.png)
## Key features
* **Multiple calendar views**: A wide range of built-in view modes are available: day, week, workweek, month, timeline day, timeline week, timeline workweek. The control allows you to conveniently customize every view with unique, view-specific options.
![Multiple calendar views](images/overview/multiple_calenda_views.png)
* **Multiple calendar views**: A wide range of built-in view modes are available: day, week, workweek, month, schedule, timeline day, timeline week, timeline workweek. The control allows you to conveniently customize every view with unique, view-specific options.
![Multiple calendar views](images/overview/multiple_calendar_views.png)
* **Appointments**: Appointments contain information on events scheduled at specific times. In addition to default appointments, users can use their own collections to connect a business entity to an appointment by mapping their fields, such as start time, end time, subject, notes, and recurrence.
![Calendar appointments](images/overview/appointments_events.png)
* **Recurring appointments**: Easily configure recurring events to be repeated on a daily, weekly, monthly, or yearly basis with optimized recurrence options. You can also skip or change the occurrence of a recurring appointment.
![Recurring appointments](images/overview/recurring_events.jpg)
* **Time zone**: Regardless of the time zone in your device, Calendar supports setting any required time zone for the control itself, as well as individual events.
![Calendar timezone](images/overview/timezone.png)
* **Schedule view**: Show a list of scheduled appointments grouped by week, between set minimum and maximum dates, with the schedule view. You can customize everything from the date and time formats to the styling of each header.
![Schedule view](images/overview/Schedule_view.png)
* **Timeline month view**: Display appointments across the multiple days of a month on a horizontal axis where each column represents a single day.
![Timeline month view](images/overview/timeline-month.png)
* **Resource view**: Display the appointments of each resource in a discrete timeline view to enhance viewability.
![Resource view](images/overview/resource-view.png)
* **Special time regions**: Disable interactions and selections for specific time ranges. This is useful when you want to block user interaction during holidays or another special events and to highlight those time slots.
![Calendar time regions](images/overview/Special_region.png)
* **Flexible working days**: Customize the work days in a workweek so that the remaining days will be hidden from view.
@ -38,18 +46,19 @@ The Syncfusion Flutter Calendar library was written natively in Dart and has sev
* **First day of the week**: Customize the first day of the week as needed. The default is Sunday.
![First day of week](images/overview/First_day_of_week.png)
* **Blackout dates**: Disable any date in a month and timeline month view of a calendar to make it inactive. You can easily prevent the selection of weekends by disabling them.
![Blackout dates](images/overview/blackout_dates.png)
* **Hide leading and trailing dates**: Hide the next month and previous month dates in the calendar to enhance the appearance.
![Hide leading trailing dates](images/overview/hide-leading-trailing-dates.png)
* **Month agenda view**: Display appointments in a list as shown in the following month view by clicking on a day.
![Month agenda view](images/overview/Month_agenda_view.png)
* **Appearance customization**: Provide a uniform and consistent look with Calendars flexible appearance and format.
![Appearance customization](images/overview/Appearance_customization.png)
* **Custom start and end hours**: Display the event calendar timeslot views with specific time durations by hiding the unwanted hours.
* **Web layout**: The web layout improved for a better experience, and now, the mouse hovering effect has been applied to all the calendar elements.

Просмотреть файл

@ -0,0 +1,545 @@
---
layout: post
title: Timeslot views in Flutter Event Calendar widget | Syncfusion
description: Learn here all about timeslot views feature of Syncfusion Flutter Event Calendar (SfCalendar) widget and more.
platform: flutter
control: SfCalendar
documentation: ug
---
# Timeslot views in Flutter Event Calendar (SfCalendar)
[Flutter Calendar](https://www.syncfusion.com/flutter-widgets/flutter-calendar) has six built-in time slot views used to display date, and the views will display based on the current day by default. Appointments on a specific day will be arranged in respective timeslots based on its duration.
* **Day view:** Displays a single day.
* **Week view:** Views all days of a week.
* **Work week view:** Views only working days of a week. By default, Saturday and Sunday are the non-working days. You can customize it with any days of a week.
* **Timeline day view:** Displays the single day in horizontal time axis.
* **Timeline week view:** Displays the days of a week in horizontal time axis. You can see the past or future dates by scrolling to right or left.
* **Timeline work week view:** Views only working days of a week in horizontal axis. By default, Saturday and Sunday are the non-working days. You can customize it with any days of a week.
* **Timeline month:** Display appointments across multiple days of a month on a horizontal axis where each column represents a single day.
## Change time interval
You can customize the interval of timeslots in all the timeslots view by using the [timeInterval](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/timeInterval.html) property of [TimeSlotViewSettings](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings-class.html/).
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.week,
timeSlotViewSettings:
TimeSlotViewSettings(timeInterval: Duration(hours: 2)),
),
);
}
{% endhighlight %}
{% endtabs %}
![Change time interval](images/timeslot-views/time-interval.png)
>**NOTE**
* If you modify the timeInterval value (in minutes), you need to change the time labels format by setting the timeFormat value to `hh:mm`. By default, timeFormat value is `h a`.
## Change time interval height
You can customize the time interval height of the day, week, and workweek view by using the [timeIntervalHeight](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/timeIntervalHeight.html) property of `TimeSlotViewSettings`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.week,
timeSlotViewSettings: TimeSlotViewSettings(
timeIntervalHeight: 100,
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Change time interval height](images/timeslot-views/time-interval-height.png)
## Change time interval width
You can customize the time interval width of the timeline day, timeline week, timeline work week, and timeline month view by using the [timeIntervalWidth](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/timeIntervalWidth.html) property of `TimeSlotViewSettings`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.timelineDay,
timeSlotViewSettings: TimeSlotViewSettings(
timeIntervalWidth: 100,
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Change time interval width](images/timeslot-views/time-interval-width.png)
## Flexible working days and working hours
The default values for [startHour](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/startHour.html) and [endHour](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/endHour.html) are 0 and 24 to show all the time slots in time slot views. You can to set the `startHour` and `endHour` properties of `timeSlotViewSettings` to show only the required time duration for users. You can set `startHour` and `endHour` in time duration to show the required time duration in minutes.
You can also customize the nonworking days of a week by using the [nonWorkingDays](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/nonWorkingDays.html) property of `timeSlotViewSettings` to show only the required days for the users.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfCalendar(
view: CalendarView.workWeek,
timeSlotViewSettings: TimeSlotViewSettings(
startHour: 9,
endHour: 16,
nonWorkingDays: <int>[DateTime.friday, DateTime.saturday]),
));
}
{% endhighlight %}
{% endtabs %}
![Flexible working days and working hours](images/timeslot-views/starthour-endhour.png)
>**NOTE**
* The `nonWorkingDays` property will applicable only for `workWeek` and `timelineWorkWeek` views only, and not applicable for the remaining views.
* Calendar Appointments UI, which does not fall within the `startHour` and `endHour` will not be visible and if it falls partially, it will be clipped.
* No need to specify the decimal point values for `startHour` and `endHour`, if you dont want to set the minutes.
* The number of time slots will be calculated based on total minutes of a day and time interval (total minutes of a day ((start hour - end hour) * 60) / time interval).
* If custom timeInterval is given, then the number of time slots calculated based on the given TimeInterval should result in integer value (total minutes % timeInterval = 0), otherwise next immediate time interval that result in integer value when divide total minutes of a day will be considered. For example, if timeInterval=2 Hours 15 minutes and total minutes = 1440 (24 Hours per day), then timeInterval will be changed to 144 (1440%144=0) by considering (total minutes % timeInterval = 0), it will return integer value for time slots rendering.
* If the custom `startHour` and `endHour` are given, then the number of time slots calculated based on given `startHour` and `endHour` should result in integer value, otherwise next immediate `timeInterval` will be considered until the result is integer value. For example, if `startHour` is 9 (09:00AM), `endHour` is 18.25 (06:15 PM), `timeInterval` is 30 minutes, and total minutes = 555 ((18.25-9)*60), then the timeInterval will be changed to 37 minutes (555%37=0) by considering (total minutes % timeInterval = 0). it will return integer value for time slots rendering.
## Special time regions
You can restrict the user interaction such as selection and highlights specific regions of time in the timeslot views by adding the [specialRegions](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/SfCalendar/specialRegions.html) property of `SfCalendar`. You need to set the [startTime](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/startTime.html) and [endTime](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/endTime.html) properties of [TimeRegion](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion-class.html) to create a `specialTimeRegion`, you can use the [timeZone](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/timeZone.html) property to set the specific timezone for start and end time of `specialTimeRegion`. The `specialTimeRegion` will display the text or icon on it that set to the [text](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/text.html) or [iconData](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/iconData.html) property of `TimeRegion`.
![Special time region in Flutter event calendar](images/timeslot-views/Special_region.png)
>**NOTE**
* If time region has both the text and icon then it will draw icon only.
* The `TimeRegion` not applicable, when the calendar view is set to `timelineMonth`.
### Selection restriction in timeslots
You can enable or disable the touch interaction of `TimeRegion` using the [enablePointerInteraction](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/enablePointerInteraction.html) property of `TimeRegion`. By default, its value is true.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.week,
specialRegions: _getTimeRegions(),
),
);
}
List<TimeRegion> _getTimeRegions() {
final List<TimeRegion> regions = <TimeRegion>[];
regions.add(TimeRegion(
startTime: DateTime.now(),
endTime: DateTime.now().add(Duration(hours: 1)),
enablePointerInteraction: false,
color: Colors.grey.withOpacity(0.2),
text: 'Break'));
return regions;
}
{% endhighlight %}
{% endtabs %}
![Special time region touch restriction](images/timeslot-views/Special_region_touch_restriction.png)
>**NOTE**
This property only restricts the interaction on region and it does not restrict the following:
* Programmatic selection (if the user updates the selected date value dynamically)
* Does not clear the selection when the user selects the region and dynamically change
the `enablePointerInteraction` property to false
* It does not restrict appointment interaction when the appointment placed
in the region
* It does not restrict the appointment rendering on a region, when appointments are loaded from data services or adding programmatically.
### Recurring time region
The recurring time region on a daily, weekly, monthly, or yearly interval. The recurring special time regions can be created by setting the [recurrenceRule](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/recurrenceRule.html) property in `TimeRegion`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.week,
specialRegions: _getTimeRegions(),
),
);
}
List<TimeRegion> _getTimeRegions() {
final List<TimeRegion> regions = <TimeRegion>[];
regions.add(TimeRegion(
startTime: DateTime.now(),
endTime: DateTime.now().add(Duration(hours: 1)),
enablePointerInteraction: false,
recurrenceRule: 'FREQ=DAILY;INTERVAL=1',
textStyle: TextStyle(color: Colors.black45, fontSize: 15),
color: Colors.grey.withOpacity(0.2),
text: 'Break'));
return regions;
}
{% endhighlight %}
{% endtabs %}
![Special time region recurrence](images/timeslot-views/Special_region_recurrence.png)
You can refer to [here](https://help.syncfusion.com/flutter/calendar/appointments#recurrence-rule) to know more about the recurrence rule.
### Recurrence exception dates
You can delete any of occurrence that is an exception from the recurrence pattern time region by using the [recurrenceExceptionDates](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/recurrenceExceptionDates.html) property of `TimeRegion`. The deleted occurrence date will be considered as a recurrence exception date.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.week,
specialRegions: _getTimeRegions(),
),
);
}
List<TimeRegion> _getTimeRegions() {
final List<TimeRegion> regions = <TimeRegion>[];
regions.add(TimeRegion(
startTime: DateTime.now(),
endTime: DateTime.now().add(Duration(hours: 1)),
enablePointerInteraction: false,
recurrenceRule: 'FREQ=DAILY;INTERVAL=1',
textStyle: TextStyle(color: Colors.black45, fontSize: 15),
color: Colors.grey.withOpacity(0.2),
recurrenceExceptionDates: [DateTime.now().add(Duration(days: 2))],
text: 'Break'));
return regions;
}
{% endhighlight %}
{% endtabs %}
![Special time region recurrence exception](images/timeslot-views/Special_region_recurrence_exception.png)
### Special time region customization
The `specialTimeRegion` background color can be customized by using the [color](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/color.html) and [textStyle](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeRegion/textStyle.html) properties of `TimeRegion` that is used to customize the text style for the `text` and `iconData` of the `specialTimeRegion`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.week,
specialRegions: _getTimeRegions(),
),
);
}
List<TimeRegion> _getTimeRegions() {
final List<TimeRegion> regions = <TimeRegion>[];
regions.add(TimeRegion(
startTime: DateTime.now(),
endTime: DateTime.now().add(Duration(hours: 1)),
enablePointerInteraction: false,
textStyle: TextStyle(color: Colors.red, fontSize: 15),
color: Color.fromRGBO(255, 236, 179, 1.0),
iconData: Icons.group));
return regions;
}
{% endhighlight %}
{% endtabs %}
![Special time region customization](images/timeslot-views/Special_region_customization.jpg)
## Full screen calendar
The calendar time interval height and width can be adjusted based on the screen height by changing the value of the `timeIntervalHeight` and `timeIntervalWidth` property to -1. It will auto fit the screen height and width.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCalendar(
view: CalendarView.week,
timeSlotViewSettings: TimeSlotViewSettings(
timeIntervalHeight: -1,
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Full screen calendar](images/timeslot-views/time-interval-height-1.png)
## Change time ruler size
You can customize the size of the time ruler view where the labels mentioning the time are placed by using the [timeRulerSize](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/timeRulerSize.html) property of `TimeSlotViewSettings`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
timeSlotViewSettings: TimeSlotViewSettings(timeRulerSize: 100),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Change time ruler size](images/timeslot-views/time-ruler-size.png)
## Minimum appointment duration
The [minimumAppointmentDuration](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/minimumAppointmentDuration.html) property in timeSlotViewSettings is to set an arbitrary height to appointments when it has minimum duration, in timeslot views, so that the subject can be readable.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
dataSource: _getCalendarDataSource(),
timeSlotViewSettings: TimeSlotViewSettings(
minimumAppointmentDuration: Duration(minutes: 30)),
),
),
),
);
}
_AppointmentDataSource _getCalendarDataSource() {
List<Appointment> appointments = <Appointment>[];
appointments.add(Appointment(
startTime: DateTime.now(),
endTime: DateTime.now().add(Duration(minutes: 10)),
subject: 'Meeting',
color: Colors.blue,
startTimeZone: '',
endTimeZone: '',
));
return _AppointmentDataSource(appointments);
}
class _AppointmentDataSource extends CalendarDataSource {
_AppointmentDataSource(List<Appointment> source) {
appointments = source;
}
}
{% endhighlight %}
{% endtabs %}
![Minimum appointment duration](images/timeslot-views/minimum-appointment-height.png)
>**NOTE**
* `minimumAppointmentDuration` value will be set, when an appointment duration value lesser than `minimumAppointmentDuration`.
* Appointment duration value will be set, when the appointment duration value greater than `minimumAppointmentDuration`.
* `timeInterval` value will be set, when `minimumAppointmentDuration` greater than `timeInterval` with lesser appointment duration.
* All day Appointment does not support `minimumAppointmentDuration`.
* The `minimumAppointmentDuration` property not applicable when the calendar view is set to `timelineMonth`.
## Timeline appointment height
You can customize the height of appointment in timeline views using the [timelineAppointmentHeight](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/timelineAppointmentHeight.html) property of `TimeSlotViewSettings`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.timelineWeek,
timeSlotViewSettings:
TimeSlotViewSettings(timelineAppointmentHeight: 100),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Timeline appointment height](images/timeslot-views/timeline-appointment-height.png)
## View header text formatting
You can customize the date and day format of SfCalendar ViewHeader by using the [dateFormat](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/dateFormat.html) and [dayFormat](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/dayFormat.html) properties of `TimeSlotViewSettings`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
timeSlotViewSettings:
TimeSlotViewSettings(dateFormat: 'd', dayFormat: 'EEE'),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![View header text formatting](images/timeslot-views/viewheader-text-format.png)
## Time text formatting
You can customize the format for the labels mentioning the time, by setting the [timeFormat](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/timeFormat.html) property of `timeSlotViewSettings` in calendar.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
timeSlotViewSettings: TimeSlotViewSettings(
timeInterval: Duration(minutes: 30), timeFormat: 'h:mm'),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Time text formatting](images/timeslot-views/time-text-format.png)
## Time text appearance
You can customize the text style for the labels mentioning the time, by setting the [timeTextStyle](https://pub.dev/documentation/syncfusion_flutter_calendar/latest/calendar/TimeSlotViewSettings/timeTextStyle.html) property of `timeSlotViewSettings` in calendar.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
timeSlotViewSettings: TimeSlotViewSettings(
timeTextStyle: TextStyle(
fontWeight: FontWeight.w500,
fontStyle: FontStyle.italic,
fontSize: 15,
color: Colors.blue,
)),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Time text appearance](images/timeslot-views/time-text-appearance.png)
## All day panel background color
All day panel background color can be customized by using the [allDayPanelColor]() property of `timeSlotViewSettings` in the calendar.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: SfCalendar(
view: CalendarView.week,
timeSlotViewSettings:
TimeSlotViewSettings(allDayPanelColor: Colors.green),
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Allday panel Background color](images/getting-started/alldayPanelColor.jpg)
## See also
* [Time label customization in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/11008/how-to-customize-the-time-label-in-the-flutter-event-calendar-sfcalendar)
* [How to customize the timeline appointment height in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12147/how-to-customize-the-timeline-appointment-height-in-the-flutter-event-calendar-sfcalendar)
* [How to format the date and time in timeline views in the Flutter event calendar (SfCalendar)?](https://www.syncfusion.com/kb/11997/how-to-format-the-date-and-time-in-timeline-views-in-the-flutter-event-calendar-sfcalendar)
* [How to use multiple recurrence rule (RRule) in special region using Flutter event calendar (SfCalendar)?](https://www.syncfusion.com/kb/11730/how-to-use-multiple-recurrence-rule-rrule-in-special-region-using-flutter-event-calendar)
* [How to add a special region dynamically using onTap, onViewChanged callbacks of the Flutter event calendar (SfCalendar)?](https://www.syncfusion.com/kb/11729/how-to-add-a-special-region-dynamically-using-ontap-onviewchanged-callbacks-of-the-fluttter)
* [How to highlight the weekends in Flutter event calendar (SfCalendar)?](https://www.syncfusion.com/kb/11712/how-to-highlight-the-weekends-in-flutter-event-calendar-sfcalendar)
* [How to highlight the working and non-working hours in the Flutter event calendar (SfCalendar)?](https://www.syncfusion.com/kb/11711/how-to-highlight-the-working-and-non-working-hours-in-the-flutter-event-calendar-sfcalendar)
* [How to highlight the lunch hours in the Flutter event calendar (SfCalendar)?](https://www.syncfusion.com/kb/11710/how-to-highlight-the-lunch-hours-in-the-flutter-event-calendar-sfcalendar)
* [How to autofit the calendar to screen height in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12231/how-to-autofit-the-calendar-to-screen-height-in-the-flutter-event-calendar-sfcalendar)
* [How to change the time interval width and height in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12322/how-to-change-the-time-interval-width-and-height-in-the-flutter-event-calendar-sfcalendar)
* [How to format the view header day and date in the Flutter event calendar (SfCalendar)](https://www.syncfusion.com/kb/12339/how-to-format-the-view-header-day-and-date-in-the-flutter-event-calendar-sfcalendar)

Просмотреть файл

@ -0,0 +1,396 @@
---
layout: post
title: Annotation in Flutter Cartesian Charts widget | Syncfusion
description: Learn here all about Annotation feature of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Annotation in Flutter Cartesian Charts (SfCartesianChart)
Chart supports annotations which allows you to mark the specific area of interest in the chart area. You can add the custom widgets using this annotations feature as depicted below.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
annotations: <CartesianChartAnnotation>[
CartesianChartAnnotation(
widget:
Container(
child: const Text('Annotation')
),
coordinateUnit: CoordinateUnit.point,
x: 'USA',
y: 20
)
]
)
)
)
)
);
}
{% endhighlight %}
![Annotation](images/annotation/default_annotation.jpg)
## Positioning the annotation
The [`x`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/x.html) and [`y`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/y.html) values can be specified with axis units or pixel units or percentage units, and these can be identified by using [`coordinateUnit`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/coordinateUnit.html) property. When logicalPixel is specified, the annotation will be placed with respect to pixel values whereas point is specified, then the annotation will be placed with respect to series point values.
**Positioning based on coordinateUnit as point**
To position the annotation based on axis, set the [`x`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/x.html) and [`y`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/y.html) properties based on axis range values, and set the [`coordinateUnit`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/coordinateUnit.html) value as [`point`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/coordinateUnit.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
annotations: <CartesianChartAnnotation>[
CartesianChartAnnotation(
widget: Container(
child: const Text('Text')
),
coordinateUnit: CoordinateUnit.point,
x: 20, // x position of annotation
y: 40 // y position of annotation
)
]
)
)
)
)
);
}
{% endhighlight %}
**Positioning based on coordinateUnit as pixels**
To position the annotation based on the pixel values, set the [`CoordinateUnit`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/coordinateUnit.html) value as [`logicalPixel`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/coordinateUnit.html), and the pixel values in [`x`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/x.html) and [`y`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/y.html) properties of annotation as shown in the following code snippet.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
annotations: <CartesianChartAnnotation>[
CartesianChartAnnotation(
widget: Container(
child: const Text('Text')
),
// Coordinate unit type
coordinateUnit: CoordinateUnit.logicalPixel,
x: 150,
y: 200
)
]
)
)
)
)
);
}
{% endhighlight %}
![Positioning based on coordinateUnit as pixels](images/annotation/annotation_pixel.jpg)
**Positioning based on coordinateUnit as percentage**
To position the annotation based on the percentage values, set the [`CoordinateUnit`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/coordinateUnit.html) value as [`percentage`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/coordinateUnit.html), and the percentage values in [`x`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/x.html) and [`y`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/y.html) properties of annotation as shown in the following code snippet.
{% highlight dart %}
@override
Widget build(BuildContext context) {
const List<ChartData> chartData = [
ChartData('IND', 24),
ChartData('AUS', 20),
ChartData('USA', 27),
ChartData('DEU', 57),
ChartData('ITA', 30),
ChartData('UK', 41),
];
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(interval: 1),
annotations: const <CartesianChartAnnotation>[
CartesianChartAnnotation(
coordinateUnit: CoordinateUnit.percentage,
region: AnnotationRegion.plotArea,
widget: Text('Annotation With Percentage',
style: TextStyle(
fontSize: 14,
)),
x: '50%',
y: '50%'
)
],
series: <ChartSeries<ChartData, String>>[
ColumnSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y)
]
),
)
);
}
class ChartData {
const ChartData(this.x, this.y);
final String x;
final int y;
}
{% endhighlight %}
![Positioning based on coordinateUnit as percentage](images/annotation/percentage.png)
**Positioning based on region**
Annotations can be placed with respect to either [`AnnotationRegion.plotArea`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AnnotationRegion-class.html) or [`AnnotationRegion.chart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AnnotationRegion-class.html) using [`region`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/region.html) property.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
annotations: <CartesianChartAnnotation>[
CartesianChartAnnotation(
widget: Container(
child: const Text('Text')
),
region: AnnotationRegion.chartArea,
coordinateUnit: CoordinateUnit.logicalPixel,
x: 150,
y: 200
)
]
)
)
)
)
);
}
{% endhighlight %}
## Alignment of annotation
[`CartesianChartAnnotation`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation-class.html) can be aligned to center, near and far using the [`horizontalAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/horizontalAlignment.html) and [`verticalAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/verticalAlignment.html) properties of annotation.
The following code example demonstrates how to set the [`horizontalAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/horizontalAlignment.html) for annotation
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
annotations: <CartesianChartAnnotation>[
CartesianChartAnnotation(
widget: Container(
child: const Text('Text')
),
region: AnnotationRegion.chartArea,
coordinateUnit: CoordinateUnit.logicalPixel,
x: 150,
y: 200,
HorizontalAlignment: HorizontalAlignment.near,
)
]
)
)
)
)
);
}
{% endhighlight %}
## Adding multiple annotation
You can add multiple annotations to the Chart by adding multiple widgets to the [`annotations`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation-class.html) property. as depicted in below code snippet.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
annotations: <CartesianChartAnnotation>[
// first annotation
CartesianChartAnnotation(
child: Container(child: const Text('High')),
coordinateUnit: CoordinateUnit.logicalPixel,
x: 90,
y: 200),
// second annotation
CartesianChartAnnotation(
child: Container(child: const Text('Low')),
coordinateUnit: CoordinateUnit.logicalPixel,
x: 170,
y: 200)
],
)
)
)
),
);
}
{% endhighlight %}
![Multiple annotation](images/annotation/multiple_annotation_pixel.jpg)
## Adding annotation for multiple axes
When there are multiple axes in the chart, annotation can be added for a particular axis by using the [`xAxisName`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/xAxisName.html) and [`yAxisName`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianChartAnnotation/yAxisName.html ) properties. It is shown in the below code snippet.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData(10, 17, 132),
ChartData(20, 34, 134),
ChartData(30, 24, 124),
ChartData(40, 30, 130),
ChartData(50, 10, 110)
];
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
annotations: <CartesianChartAnnotation>[
CartesianChartAnnotation(
widget: Container(child: const Text('Low')),
coordinateUnit: CoordinateUnit.point,
x: 15,
y: 50
),
CartesianChartAnnotation(
widget: Container(child: const Text('High')),
coordinateUnit: CoordinateUnit.point,
x: 35,
y: 130,
yAxisName: 'YAxis' // Refers to the additional axis
)
],
primaryYAxis: NumericAxis(minimum: 0, maximum: 80),
axes: <ChartAxis>[
NumericAxis(name: 'YAxis', opposedPosition: true)
],
series: <CartesianSeries>[
ColumnSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y
),
ColumnSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y2,
yAxisName: 'YAxis'
)
]
)
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y, this.y2);
final double x;
final double y;
final double y2;
}
{% endhighlight %}
![Multiple axis annotation](images/annotation/annotation_axis.jpg)
## Chart with watermark
Chart supports watermark which allows you to mark the specific area of interest in the chart area. You can add the custom widgets and watermarks using this annotations feature as depicted below.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
annotations: <CartesianChartAnnotation>[
CartesianChartAnnotation(
child: Container(
child: const Text(
'€ - \$ ',
style: TextStyle(
color: Color.fromRGBO(216, 225, 227, 1),
fontWeight: FontWeight.bold,
fontSize: 80),
),
),
coordinateUnit: CoordinateUnit.point,
region: AnnotationRegion.chart,
x: 3,
y: 38,
)
]
)
)
)
)
);
}
{% endhighlight %}
![Chart with Watermark](images/annotation/watermark.png)
N> `chartData` in the above code snippets is a class type list and holds the data for binding to the chart series. Refer [Bind data source](https://help.syncfusion.com/flutter/cartesian-charts/getting-started#bind-data-source) topic for more details.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Просмотреть файл

@ -0,0 +1,302 @@
---
layout: post
title: Error bar chart in Flutter Cartesian Charts widget | Syncfusion
description: Learn here all about error bar chart of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Error bar chart in Flutter Cartesian Charts (SfCartesianChart)
Error bars are graphical representations of the variability of data and used on graphs to indicate the error or uncertainty in a reported measurement.
To render an error bar chart, create an instance of `ErrorBarSeries`, and add it to the [`series`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/XyDataSeries-class.html) collection property of [`SfCartesianChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart/SfCartesianChart.html). The following properties can be used to customize the appearance:
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/color.html) - changes the stroke width of the line.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/opacity.html) - controls the transparency of the chart series.
* [`width`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/width.html) - changes the stroke width of the line.
* [`dashArray`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/dashArray.html) - renders error bar with dashes.
* [`pointColorMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/pointColorMapper.html)- maps the individual colors to the data point.
[`Marker`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MarkerSettings/MarkerSettings.html), [`data label`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings-class.html), [`trendline`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline-class.html), [`Technical indicators`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators-class.html), and other user interaction features are not applicable for error bar series. And events like [`onPointTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/onPointTap.html), [`onPointDoubleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/onPointDoubleTap.html) and [`onPointLongPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/onPointLongPress.html) are not applicable for this series.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final dynamic chartData = [
ChartData(1, 24),
ChartData(2, 20),
ChartData(3, 35),
ChartData(4, 27),
ChartData(5, 30),
ChartData(6, 41),
ChartData(7, 26)
];
return Scaffold(
body: SfCartesianChart(
series: <ChartSeries<ChartData, int>>[
ErrorBarSeries<ChartData, int>(
width: 3.0,
opacity: 0.7,
color: Color.fromRGBO(246, 114, 128, 1),
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
)
],
)
);
}
class ChartData {
ChartData(this.x, this.y);
final int x;
final int y;
}
{% endhighlight %}
![Error bar](cartesian-chart-types-images/error_bar_color.png)
## Type
The `type` property is used to define the error bar type value. The default value of this property is `fixed`, and other values are `custom`, `percentage`, `standardDeviation` and `standardError`.
You can customize the error bar depending on the error value by setting the values for `horizontalErrorValue` and `verticalErrorValue` for all types except `custom`.
* `horizontalErrorValue` - This property horizontally depicts the error value in positive and negative directions. The default value of `horizontalErrorValue` is `1`.
* `verticalErrorValue` - This property vertically depicts the error value in positive and negative directions. The default value of `verticalErrorValue` is `3`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final dynamic chartData = [
ChartData(1, 24),
ChartData(2, 20),
ChartData(3, 35),
ChartData(4, 27),
ChartData(5, 30),
ChartData(6, 41),
ChartData(7, 26)
];
return Scaffold(
body: SfCartesianChart(
series: <ChartSeries<ChartData, int>>[
ErrorBarSeries<ChartData, int>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
width: 1.5,
type: ErrorBarType.standardError
)
],
)
);
}
class ChartData {
ChartData(this.x, this.y);
final int x;
final int y;
}
{% endhighlight %}
![Error bar type](cartesian-chart-types-images/error_bar_type.png)
### Custom type
For `custom` type, you can customize the error bar depending on the error value by setting the values for `horizontalPositiveErrorValue`, `horizontalNegativeErrorValue`, `verticalPositiveErrorValue` and `verticalNegativeErrorValue`.
* `horizontalPositiveErrorValue` - This property horizontally depicts the error value in positive direction. The default value of `horizontalPositiveErrorValue` is `1`.
* `horizontalNegativeErrorValue` - This property horizontally depicts the error value in negative direction. The default value of `horizontalNegativeErrorValue` is `1`.
* `verticalPositiveErrorValue` - This property vertically depicts the error value in positive direction. The default value of `verticalPositiveErrorValue` is `3`.
* `verticalNegativeErrorValue` - This property vertically depicts the error value in negative direction. The default value of `verticalNegativeErrorValue` is `3`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final dynamic chartData = [
ChartData(1, 24),
ChartData(2, 20),
ChartData(3, 35),
ChartData(4, 27),
ChartData(5, 30),
ChartData(6, 41),
ChartData(7, 26)
];
return Scaffold(
body: SfCartesianChart(
series: <ChartSeries<ChartData, int>>[
ErrorBarSeries<ChartData, int>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
width: 1.5,
type: ErrorBarType.custom,
mode: RenderingMode.both,
verticalPositiveErrorValue: 5,
verticalNegativeErrorValue: 2,
horizontalPositiveErrorValue: 0.2,
horizontalNegativeErrorValue: 0.5
)
],
)
);
}
class ChartData {
ChartData(this.x, this.y);
final int x;
final int y;
}
{% endhighlight %}
![Error bar custom type](cartesian-chart-types-images/error_bar_custom_type.png)
## Mode
The error bar `mode` specifies whether the error bar should be drawn `horizontally`, `vertically`, or `both` ways. Use the `mode` option to switch the error bar mode. The default value of the `mode` is `RenderingMode.vertical`. You can use the following properties to customize the `mode`,
* `vertical` - This property displays vertical error value only.
* `horizontal` - This property displays horizontal error value only.
* `both` - This property displays both vertical and horizontal error values.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final dynamic chartData = [
ChartData(1, 24),
ChartData(2, 20),
ChartData(3, 35),
ChartData(4, 27),
ChartData(5, 30),
ChartData(6, 41),
ChartData(7, 26)
];
return Scaffold(
body: SfCartesianChart(
series: <ChartSeries<ChartData, int>>[
ErrorBarSeries<ChartData, int>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
width: 1.5,
mode:RenderingMode.both,
verticalErrorValue:2,
horizontalErrorValue:0.2
)
],
)
);
}
class ChartData {
ChartData(this.x, this.y);
final int x;
final int y;
}
{% endhighlight %}
![Error bar mode](cartesian-chart-types-images/error_bar_mode.jpg)
## Direction
Using the `direction` option, you can alter the error bar direction to `plus`, `minus`, or `both` sides. The default value of the `direction` is `Direction.both`. You can use the following properties to customize the `direction`,
* `both` - Used to set error value in positive and negative directions.
* `minus` - Used to set error value in a negative direction.
* `plus` - Used to set error value in a positive direction.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final dynamic chartData = [
ChartData(1, 24),
ChartData(2, 20),
ChartData(3, 35),
ChartData(4, 27),
ChartData(5, 30),
ChartData(6, 41),
ChartData(7, 26)
];
return Scaffold(
body: SfCartesianChart(
series: <ChartSeries<ChartData, int>>[
ErrorBarSeries<ChartData, int>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
width: 1.5,
direction: Direction.minus
)
],
)
);
}
class ChartData {
ChartData(this.x, this.y);
final int x;
final int y;
}
{% endhighlight %}
![Error bar direction](cartesian-chart-types-images/error_bar_direction.jpg)
## Cap length
The `capLength` property is used to customize the length of the error bar's cap. The default value is `10`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final dynamic chartData = [
ChartData(1, 24),
ChartData(2, 20),
ChartData(3, 35),
ChartData(4, 27),
ChartData(5, 30),
ChartData(6, 41),
ChartData(7, 26)
];
return Scaffold(
body: SfCartesianChart(
series: <ChartSeries<ChartData, int>>[
ErrorBarSeries<ChartData, int>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
width: 1.5,
capLength: 20.0
)
],
)
);
}
class ChartData {
ChartData(this.x, this.y);
final int x;
final int y;
}
{% endhighlight %}
![Error bar cap length](cartesian-chart-types-images/error_bar_caplength.png)

Просмотреть файл

@ -0,0 +1,247 @@
---
layout: post
title: Chart Types in Flutter Cartesian Charts widget | Syncfusion
description: Learn here all about available chart types of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Chart Types in Flutter Cartesian Charts (SfCartesianChart)
This page helps to navigate to the Chart types available in the Syncfusion Flutter Cartesian Charts widgets.
<table>
<tr>
<td>
Line Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/line-chart">Link</a>
</td>
</tr>
<tr>
<td>
Fast line Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/fast-line-chart">Link</a>
</td>
</tr>
<tr>
<td>
Area Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/area-chart">Link</a>
</td>
</tr>
<tr>
<td>
Spline Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/spline-chart">Link</a>
</td>
</tr>
<tr>
<td>
Column Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/column-chart">Link</a>
</td>
</tr>
<tr>
<td>
Bar Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/bar-chart">Link</a>
</td>
</tr>
<tr>
<td>
Bubble Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/bubble-chart">Link</a>
</td>
</tr>
<tr>
<td>
Scatter Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/scatter-chart">Link</a>
</td>
</tr>
<tr>
<td>
Step line Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/step-line-chart">Link</a>
</td>
</tr>
<tr>
<td>
Range column Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/range-column-chart">Link</a>
</td>
</tr>
<tr>
<td>
Range area Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/range-area-chart">Link</a>
</td>
</tr>
<tr>
<td>
Spline area Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/spline-area-chart">Link</a>
</td>
</tr>
<tr>
<td>
Spline range area Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/spline-range-area-chart">Link</a>
</td>
</tr>
<tr>
<td>
Step area Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/step-area-chart">Link</a>
</td>
</tr>
<tr>
<td>
Histogram Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/histogram-chart">Link</a>
</td>
</tr>
<tr>
<td>
Stacked line Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/stacked-line-chart">Link</a>
</td>
</tr>
<tr>
<td>
Stacked area Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/stacked-area-chart">Link</a>
</td>
</tr>
<tr>
<td>
Stacked column Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/stacked-column-chart">Link</a>
</td>
</tr>
<tr>
<td>
Stacked bar Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/stacked-bar-chart">Link</a>
</td>
</tr>
<tr>
<td>
Stacked area 100 Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/stacked-area-100-chart">Link</a>
</td>
</tr>
<tr>
<td>
Stacked column 100 Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/stacked-column-100-chart">Link</a>
</td>
</tr>
<tr>
<td>
Stacked bar 100 Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/stacked-bar-100-chart">Link</a>
</td>
</tr>
<tr>
<td>
Stacked line 100 Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/stacked-line-100-chart">Link</a>
</td>
</tr>
<tr>
<td>
HiLo Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/hilo-chart">Link</a>
</td>
</tr>
<tr>
<td>
OHLC Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/ohlc-chart">Link</a>
</td>
</tr>
<tr>
<td>
Candle Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/candle-chart">Link</a>
</td>
</tr>
<tr>
<td>
Box and Whisker Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/box-and-whisker-chart">Link</a>
</td>
</tr>
<tr>
<td>
Waterfall Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/waterfall-chart">Link</a>
</td>
</tr>
<tr>
<td>
Error bar Chart
</td>
<td>
<a href="https://help.syncfusion.com/flutter/cartesian-charts/chart-types/error-bar-chart">Link</a>
</td>
</tr>
</table>

Двоичные данные
Flutter/cartesian-charts/images/annotation/percentage.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 43 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 275 KiB

Двоичные данные
Flutter/cartesian-charts/images/cartesian-customization/shader.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 19 KiB

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,673 @@
---
layout: post
title: Series customization in Flutter Cartesian Charts widget | Syncfusion
description: Learn here all about Series customization of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Series customization in Flutter Cartesian Charts (SfCartesianChart)
## Animation
[`SfCartesianChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart-class.html) provides animation support for the series. Series will be animated while rendering. Animation is enabled by default, you can also control the duration of the animation using [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/animationDuration.html) property. You can disable the animation by setting this property to 0.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
series: <CartesianSeries>[
ColumnSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
// Duration of series animation
animationDuration: 1000
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y);
final String x;
final double? y;
}
{% endhighlight %}
### Dynamic series animation
[`SfCartesianChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart-class.html) also provides dynamic animation support for the series.
If you wish to perform the initial rendering animation again in the existing series, this method should be called. On calling this method, this particular series will be animated again based on the [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartSeries/animationDuration.html) property's value in the series. If this property's value is 0, then the animation will not be performed.
{% highlight dart %}
@override
Widget build(BuildContext context) {
ChartSeriesController? _chartSeriesController1, _chartSeriesController2;
return Column(children: <Widget>[
Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
axes: <ChartAxis>[
NumericAxis(
numberFormat: NumberFormat.compact(),
majorGridLines: const MajorGridLines(width: 0),
opposedPosition: true,
name: 'yAxis1',
interval: 1000,
minimum: 0,
maximum: 7000)
],
series: <ChartSeries<_ChartSampleData, String>>[
ColumnSeries<_ChartSampleData, String>(
animationDuration: 2000,
onRendererCreated: (ChartSeriesController controller) {
_chartSeriesController1 = controller;
},
dataSource: chartData,
xValueMapper: (_ChartSampleData sales, _) => sales.x,
yValueMapper: (_ChartSampleData sales, _) => sales.y,
name: 'Unit Sold'),
LineSeries<_ChartSampleData, String>(
animationDuration: 4500,
dataSource: chartData,
onRendererCreated: (ChartSeriesController controller) {
_chartSeriesController2 = controller;
},
xValueMapper: (_ChartSampleData sales, _) => sales.x,
yValueMapper: (_ChartSampleData sales, _) =>
sales.secondSeriesYValue,
yAxisName: 'yAxis1',
markerSettings: MarkerSettings(isVisible: true),
name: 'Total Transaction')
],
)),
Container(
child: Row(
children: [
Container(
child: RaisedButton(
color: Colors.grey[400],
onPressed: () {
_chartSeriesController2?.animate();
},
child: Text('Line'),
)),
Container(
child: RaisedButton(
color: Colors.grey[400],
onPressed: () {
_chartSeriesController1?.animate();
},
child: Text('Column'),
))
],
),
)
]);
}
class _ChartSampleData{
_ChartSampleData(this.x, this.y, this.secondSeriesYValue);
final String x;
final double? y;
final double? secondSeriesYValue;
}
{% endhighlight %}
![Dynamic series animation](images/cartesian-customization/dynamicanimation.gif)
## Animation delay
The `animationDelay` property is used to specify the delay duration of the series animation. This takes milliseconds value as input. By default, the series will get animated for the specified duration. If `animationDelay` is specified, then the series will begin to animate after the specified duration.
Defaults to `0` for all the series except `ErrorBarSeries`. The default value for the `ErrorBarSeries` is `1500`.
>**NOTE**
* The animation delay is applicable for series, trendline, and indicators.
{% highlight dart %}
import 'package:intl/intl.dart';
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = <ChartData>[
ChartData(x: 'Jan', yValue1: 45, yValue2: 1000),
ChartData(x: 'Feb', yValue1: 100, yValue2: 3000),
ChartData(x: 'March', yValue1: 25, yValue2: 1000),
ChartData(x: 'April', yValue1: 100, yValue2: 7000),
ChartData(x: 'May', yValue1: 85, yValue2: 5000),
ChartData(x: 'June', yValue1: 140, yValue2: 7000)
];
return Column(children: <Widget>[
Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
axes: <ChartAxis>[
NumericAxis(
numberFormat: NumberFormat.compact(),
majorGridLines: const MajorGridLines(width: 0),
opposedPosition: true,
name: 'yAxis1',
interval: 1000,
minimum: 0,
maximum: 7000)
],
series: <ChartSeries<ChartData, String>>[
ColumnSeries<ChartData, String>(
animationDuration: 2000,
dataSource: chartData,
xValueMapper: (ChartData sales, _) => sales.x,
yValueMapper: (ChartData sales, _) => sales.yValue1,
name: 'Unit Sold'),
LineSeries<ChartData, String>(
animationDuration: 4500,
animationDelay: 2000,
dataSource: chartData,
xValueMapper: (ChartData sales, _) => sales.x,
yValueMapper: (ChartData sales, _) => sales.yValue2,
yAxisName: 'yAxis1',
markerSettings: MarkerSettings(isVisible: true),
name: 'Total Transaction')
],)),
]);
}
class ChartData {
ChartData({this.x, this.yValue1, this.yValue2});
final String? x;
final double? yValue1;
final double? yValue2;
}
{% endhighlight %}
![Animation Delay](images/cartesian-customization/animationDelay.gif)
#### See Also
* [Create dynamic animated series on addition of data points in the series](https://www.syncfusion.com/kb/12290/how-to-create-flutter-animated-charts-using-the-charts-widget-sfcartesianchart).
* [Dynamically animate chart using public methods](https://www.syncfusion.com/kb/12205/how-to-animate-the-chart-series-dynamically-using-the-public-method-sfcartesianchart).
## Transpose the series
The [`isTransposed`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart/isTransposed.html) property of [`CartesianSeries`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries-class.html) is used to transpose the horizontal and vertical axes, to view the data in a different perspective. Using this feature, you can render vertical charts.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
// Transpose the chart
isTransposed: true,
primaryXAxis: CategoryAxis(),
series: <CartesianSeries>[
SplineSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y)'
final String x;
final double? y;
}
{% endhighlight %}
![Transposed chart](images/cartesian-customization/transposes.jpg)
## Color palette
The [`palette`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart/palette.html) property is used to define the colors for the series available in chart. By default, a set of 10 colors are predefined for applying it to the series. If the colors specified in the series are less than the number of series, than the remaining series are filled with the specified palette colors rotationally.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
// Palette colors
palette: <Color>[
Colors.teal,
Colors.orange,
Colors.brown
],
series: <CartesianSeries>[
ColumnSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y
),
ColumnSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y1
),
ColumnSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y2
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y, this.y1, this.y2);
final String x;
final double? y;
final double? y1;
final double? y2;
}
{% endhighlight %}
![Palette](images/cartesian-customization/palettee.jpg)
## Color mapping for data points
The [`pointColorMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/pointColorMapper.html) property is used to map the color field from the data source.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('Germany', 118, Colors.teal),
ChartData('Russia', 123, Colors.orange),
ChartData('Norway', 107, Colors.brown),
ChartData('USA', 87, Colors.deepOrange)
];
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
series: <CartesianSeries>[
ColumnSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
// Map color for each data points from the data source
pointColorMapper: (ChartData data, _) => data.color
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y, this.color);
final String x;
final double? y;
final Color? color;
}
{% endhighlight %}
![Point color mapping](images/cartesian-customization/colormapping.jpg)
## Gradient fill
The [`gradient`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/gradient.html) property is used to define the gradient colors. The colors from this property are used for series. Also, you can use the transform property available in [`LinearGradient`](https://api.flutter.dev/flutter/painting/LinearGradient/LinearGradient.html) to transform the applied gradient colors.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<Color> color = <Color>[];
color.add(Colors.deepOrange[50]!);
color.add(Colors.deepOrange[200]!);
color.add(Colors.deepOrange);
final List<double> stops = <double>[];
stops.add(0.0);
stops.add(0.5);
stops.add(1.0);
final LinearGradient gradientColors =
LinearGradient(colors: color, stops: stops);
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
series: <CartesianSeries>[
SplineRangeAreaSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
// Applies gradient color
gradient: gradientColors)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y);
final double x;
final double? y;
}
{% endhighlight %}
![Gradient color](images/cartesian-customization/gradient.png)
#### See Also
* [Rotating the gradient applied to a chart in Cartesian charts](https://www.syncfusion.com/kb/12054/how-to-apply-and-rotate-gradient-in-the-chart-sfcartesainchart).
N>: The gradient is not applicable for spline, step line, candle, hilo, hilo open close, and line type charts. However, in line type gradient is applicable for [`FastLineSeries`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/FastLineSeries-class.html) alone.
### Gradient stroke
The [`borderGradient`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/borderGradient.html) property is used to define the gradient color for the border of the applicable series.
If the properties of both [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartSeries/borderColor.html) and [`borderGradient`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/borderGradient.html) are defined then [`borderGradient`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/borderGradient.html) is considered.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
series: <CartesianSeries>[
AreaSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
borderWidth: 4,
borderGradient: const LinearGradient(
colors: <Color>[
Color.fromRGBO(230, 0, 180, 1),
Color.fromRGBO(255, 200, 0, 1)
],
stops: <double>[
0.2,
0.9
]
),
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y);
final double x;
final double? y;
}
{% endhighlight %}
![stroke_gradient](images/cartesian-customization/stroke_gradient.png)
## Gradient based on values
The `onCreateShader` callback is used to fill the data points with the [`gradient`](https://api.flutter.dev/flutter/dart-ui/Gradient-class.html) and [`ImageShader`](https://api.flutter.dev/flutter/dart-ui/ImageShader-class.html). All the data points are together considered as a single segment and the shader is applied commonly.
Defaults to `null`.
{% highlight dart %}
/// Package import
import 'dart:ui' as ui;
@override
Widget build(BuildContext context) {
const List<ChartData> chartData = <ChartData>[
ChartData('Jan', 35.53),
ChartData('Feb', 46.06),
ChartData('Mar', 46.06),
ChartData('Apr', 50.86),
ChartData('May', 60.89),
ChartData('Jun', 70.27),
ChartData('Jul', 75.65),
ChartData('Aug', 74.70),
ChartData('Sep', 65.91),
ChartData('Oct', 54.28),
ChartData('Nov', 46.33),
ChartData('Dec', 35.71),
];
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
series: <ChartSeries<ChartData, String>>[
AreaSeries<ChartData, String>(
dataSource: chartData,
onCreateShader: (ShaderDetails details) {
return ui.Gradient.linear(details.rect.bottomLeft,
details.rect.bottomRight, const <Color>[
Color.fromRGBO(116, 182, 194, 1),
Color.fromRGBO(75, 189, 138, 1),
Color.fromRGBO(75, 189, 138, 1),
Color.fromRGBO(255, 186, 83, 1),
Color.fromRGBO(255, 186, 83, 1),
Color.fromRGBO(194, 110, 21, 1),
Color.fromRGBO(194, 110, 21, 1),
Color.fromRGBO(116, 182, 194, 1),
], <double>[
0.1,
0.1,
0.4,
0.4,
0.7,
0.7,
0.9,
0.9
]);
},
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y)])
)
);
}
}
class ChartData {
const ChartData(this.x, this.y);
final String x;
final double y;
}
{% endhighlight %}
![Shader](images/cartesian-customization/shader.png)
## Empty points
The data points that has null value are considered as empty points. Empty data points are ignored and not plotted in the chart. By using [`emptyPointSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/emptyPointSettings.html) property in series, you can decide the action taken for empty points. Available [`modes`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html) are [`gap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html), [`zero`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html), [`drop`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html) and [`average`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html). Default mode of the empty point is [`gap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData(1, 112),
ChartData(2, null),
ChartData(3, 107),
ChartData(4, 87)
];
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
series: <CartesianSeries>[
ColumnSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
emptyPointSettings: EmptyPointSettings(
// Mode of empty point
mode: EmptyPointMode.average
)
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y);
final double x;
final double? y;
}
{% endhighlight %}
![Empty points](images/cartesian-customization/emptyPoint.jpg)
### Empty point customization
Specific color for empty point can be set by [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/color.html) property in [`emptyPointSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/emptyPointSettings.html). The [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/borderWidth.html) property is used to change the stroke width of the empty point and [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/borderColor.html) is used to change the stroke color of the empty point.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData(1, 112),
ChartData(2, null),
ChartData(3, 107),
ChartData(4, 87)
];
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
series: <CartesianSeries>[
ColumnSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
borderColor: Colors.blue,
borderWidth: 5,
emptyPointSettings: EmptyPointSettings(
mode: EmptyPointMode.average,
color: Colors.red,
borderColor: Colors.black,
borderWidth: 2
)
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y);
final double x;
final double? y;
}
{% endhighlight %}
![Empty points customization](images/cartesian-customization/emptyPointcustomization.jpg)
## Sorting
The charts data source can be sorted using the [`sortingOrder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/sortingOrder.html) and [`sortFieldValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/sortFieldValueMapper.html) properties of series. The [`sortingOrder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/sortingOrder.html) property determines whether the data points in the sequence should be sorted in [`ascending`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SortingOrder-class.html) or [`descending`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SortingOrder-class.html) order. The data points will be rendered in the specified order if [`sortingOrder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/sortingOrder.html) is set to [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SortingOrder-class.html). The [`sortFieldValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/sortFieldValueMapper.html) specifies the field in the data source, which is considered for sorting the data points.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('USA', 112),
ChartData('China', 97),
ChartData('Japan', 107),
ChartData('Africa', 87),
];
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
series: <CartesianSeries>[
ColumnSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
sortingOrder: SortingOrder.descending,
// Sorting based on the specified field
sortFieldValueMapper: (ChartData data, _) => data.x
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y);
final String x;
final double? y;
}
{% endhighlight %}
![Sorting](images/cartesian-customization/sortings.jpg)
#### See Also
* [Rendering a chart using JSON data retrieved from a fire base](https://www.syncfusion.com/kb/11883/how-to-render-chart-using-json-data-stored-in-firebase-database-sfcartesianchart).
N> `chartData` in the above code snippets is a class type list and holds the data for binding to the chart series. Refer [Bind data source](https://help.syncfusion.com/flutter/cartesian-charts/getting-started#bind-data-source) topic for more details.

Просмотреть файл

@ -0,0 +1,644 @@
---
layout: post
title: Technical indicators in Flutter Cartesian Charts widget | Syncfusion
description: Learn here all about Technical indicators feature of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Technical indicators in Flutter Cartesian Charts (SfCartesianChart)
The different types of technical indicators available in chart are follows:
* [`Accumulation distribution indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AccumulationDistributionIndicator-class.html) - AD
* [`Average true range indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AtrIndicator-class.html) - ATR
* [`Bollinger band indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/BollingerBandIndicator-class.html)
* [`Exponential moving average indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmaIndicator-class.html) - EMA
* [`Moving average convergence divergence`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MacdIndicator-class.html) - MACD
* [`Momentum indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MomentumIndicator-class.html)
* [`Relative strength index indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RsiIndicator-class.html) - RSI
* [`Simple moving average indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SmaIndicator-class.html) - SMA
* [`Stochastic indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/StochasticIndicator-class.html)
* [`Triangular moving average indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TmaIndicator-class.html) - TMA
## Adding Technical indicator into Chart
To render any indicator, add it to the [`TechnicalIndicators`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators-class.html) collection using the indicators in [`SfCartesianChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart-class.html).The following properties can be used to customize the appearance:
* [`isVisible`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/isVisible.html) - To check the visibility of the indicator.
* [`period`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/period.html)- Used to indicates the moving average period.
* [`signalLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/signalLineColor.html)- Used to defines the color for the respective indicator line.
* [`signalLineWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/signalLineWidth.html) - Used to change the signal line width.
* [`seriesName`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/seriesName.html) - Used to bind the data source of chart series to technical indicators, including x and y axis.
* [`xAxisName`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xAxisName.html),[`yAxisName`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/yAxisName.html) - Used to set the x and y axes
* [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/animationDuration.html) - To control the duration of animation.
* `animationDelay` - Used to specify the delay duration of the indicator animation. This takes a millisecond value as input. By default, the indicator will get animated for the specified duration. If `animationDelay` is specified, then the indicator will begin to animate after the specified duration.
* [`dataSource`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/dataSource.html) - Directly bind the values such as [`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html),[`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html),[`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html),[`openValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/openValueMapper.html),[`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)
* [`isVisibleInLegend`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/isVisibleInLegend.html),[`legendItemText`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/legendItemText.html),[`legendIconType`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/legendIconType.html) - Used to change the legend visibility,text and Icon type
* [`name`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/name.html) - Used to define the label for corresponding indicators.
* [`dashArray`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/dashArray.html) - Used to render the indicators with dashes.
N>: If you giving series and indicator in the chart, you can add the same [`seriesName`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/seriesName.html) to the series and indicator, otherwise you can directly bind the [`dataSource`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/dataSource.html) to the [`indicators`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart/indicators.html) property.
## Indicator Types
### Accumulation distribution indicator (AD)
Accumulation distribution indicator is a volume-based indicator designed to measure the accumulative flow of money into and out of a security. It requires [`volumeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AccumulationDistributionIndicator/volumeValueMapper.html) property additionally with the data source to calculate the signal line.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<ChartData,DateTime>>[AccumulationDistributionIndicator<ChartData, DateTime>(
seriesName: 'HiloOpenClose')],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(
dataSource: ChartData,
xValueMapper: (ChartData sales, _) => sales.x,
lowValueMapper: (ChartData sales, _) => sales.low,
highValueMapper: (ChartData sales, _) => sales.high,
openValueMapper: (ChartData sales, _) => sales.open,
closeValueMapper: (ChartData sales, _) => sales.close,
name: 'HiloOpenClose'),
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![ADIndicator](images/technical-indicators/ad.jpg)
### Average true range indicator(ATR)
ATR indicator is a technical analysis volatility indicator. This indicator does not indicate the price trend. simply the degree of price volatility. The average true range is an N-day smoothed moving average (SMMA) of the true range values.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators:
<TechnicalIndicators<dynamic, dynamic>>[
AtrIndicator<dynamic, dynamic>(
period: 3,
seriesName: 'HiloOpenClose')],
series: <CartesianSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(
name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![ATRIndicator](images/technical-indicators/atr.jpg)
### Bollinger band Indicator
This indicator also has [`upperLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/BollingerBandIndicator/upperLineColor.html) and [`lowerLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/BollingerBandIndicator/lowerLineColor.html) properties that can be used to define the brushes for the indicator lines.
Also, we can specify standard deviation values for the BollingerBand indicator using [`standardDeviation`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/BollingerBandIndicator/standardDeviation.html) property.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<dynamic, dynamic>[ BollingerBandIndicator<dynamic, dynamic>(
period: 3,
seriesName: 'HiloOpenClose')],
series: <CartesianSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![BollingerBand](images/technical-indicators/bollinger.jpg)
### Exponential moving average indicator (EMA)
An EMA indicator is a simple, arithmetic moving average that is calculated by adding the closing price for the number of time periods and dividing the total value by the number of periods.
It also has a [`valueField`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmaIndicator/valueField.html) property. Based on this property Indicator will render.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<dynamic, dynamic>>[
EmaIndicator<dynamic, dynamic>(
seriesName: 'HiloOpenClose',
valueField: 'high',)],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(
name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![EMAIndicator](images/technical-indicators/ema.jpg)
### Moving average convergence divergence (MACD)
This is mostly using indicator having [`shortPeriod`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MacdIndicator/shortPeriod.html) and [`longPeriod`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MacdIndicator/longPeriod.html) for defining the motion of the indicator.
Also you can draw `Line`, `Histogram` MACD or `Both` types using the [`macdType`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MacdIndicator/macdType.html) property,
The [`macdLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MacdIndicator/macdLineColor.html) property is used to define the color for the MACD line and the [`histogramNegativeColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MacdIndicator/histogramNegativeColor.html) and [`histogramPositiveColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MacdIndicator/histogramPositiveColor.html) property is used to define the color for the MACD histogram.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<dynamic, dynamic>>[
MacdIndicator<dynamic, dynamic>(
longPeriod: 5,
shortPeriod: 2,
seriesName: 'HiloOpenClose')],
series: <CartesianSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(
name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![MACDIndicator](images/technical-indicators/macd.jpg)
### Momentum Indicator
This indicator also has a centerline. The [`centerLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MomentumIndicator/centerLineColor.html) and [`centerLineWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MomentumIndicator/centerLineWidth.html) properties are used to define center line.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<dynamic, dynamic>>[
MomentumIndicator<dynamic, dynamic>(
period: 3,
seriesName: 'HiloOpenClose',)],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![MomentumIndicator](images/technical-indicators/momentum.jpg)
### Relative strength index Indicator(RSI)
The RSI indicator has an additional two lines other than the signal line.They indicate the [`overBought`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RsiIndicator/overbought.html) and [`overSold`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RsiIndicator/oversold.html) region.
The [`upperLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RsiIndicator/upperLineColor.html) property is used to define the color for the line that indicates [`overBought`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RsiIndicator/overbought.html) region, and the [`lowerLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RsiIndicator/lowerLineColor.html) property is used to define the color for the line that indicates [`overSold`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RsiIndicator/oversold.html) region.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<dynamic, dynamic>>[
RsiIndicator<dynamic, dynamic>(
period: 3,
seriesName: 'HiloOpenClose',
overbought: 70,
oversold: 30)],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![RSIIndicator](images/technical-indicators/rsi.jpg)
### Simple moving average indicator(SMA)
The [`Simple moving average indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SmaIndicator-class.html) is similar to [`Exponential moving average indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmaIndicator-class.html) and this can be defined using the following code examples.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<dynamic, dynamic>>[
SmaIndicator<dynamic, dynamic>(
seriesName: 'HiloOpenClose',
valueField: 'close')],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(
name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![SMAIndicator](images/technical-indicators/sma.jpg)
### Stochastic indicator
This indicator is used to measure the range and momentum of price movements. It contains [`kPeriod`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/StochasticIndicator/kPeriod.html) and [`dPeriod`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/StochasticIndicator/dPeriod.html) property defining the k percentage and d percentage respectively.
In this indicator [`upperLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/StochasticIndicator/upperLineColor.html),[`lowerLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/StochasticIndicator/lowerLineColor.html) and [`periodLineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/StochasticIndicator/periodLineColor.html) property are used to define the color for the Stochastic indicator lines.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<dynamic, dynamic>>[
StochasticIndicator<dynamic, dynamic>(
seriesName: 'HiloOpenClose',,
kPeriod: 2,
dPeriod: 3)],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![StochasticIndicator](images/technical-indicators/stochastic.jpg)
### Triangular moving average indicator (TMA)
A TMA indicator is simply a double-smoothed simple moving average of data calculated over a period where the middle portion of the data has more weight.
Refer the following example,
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
legend: Legend(isVisible: true),
indicators: <TechnicalIndicators<dynamic, dynamic>>[
TmaIndicator<ChartData, dynamic>(
seriesName: 'HiloOpenClose',
valueField: 'low')],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(
name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![TMAIndicator](images/technical-indicators/tma.jpg)
## Legend for technical indicators
Legend provides information about the series rendered in the chart. Legend for the indicator is rendered along with the series legend when the legend is set to be visible. Also when the [ `name` ](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/name.html) property is given to an indicator, the legend name is changed based on the indicator name.[`legendItemText`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/legendItemText.html) can also be provided for changing the name of the legend. In default rendering the [`legendIconType`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/legendIconType.html) will be a horizontal line.
The following code example can define the legend.
{% highlight dart %}
@override
Widget build(BuildContext context){
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
indicators: <TechnicalIndicators<dynamic, dynamic>>[
MomentumIndicator<dynamic, dynamic>(
seriesName: 'HiloOpenClose',
legendIconType: LegendIconType.diamond,
legendItemText: 'Indicator')],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(
name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![Legend](images/technical-indicators/legend.jpg)
Also refer [`technical indicators event`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/IndicatorRenderArgs-class.html) for customizing the tooltip further.
## Tooltip for technical indicators
The chart will display the segment information through the tooltip. It is used to show information about the segment when you tap on the segment. The technical indicator tooltip has the same [`ActivationMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/activationMode.html) that has been given in the [`TooltipBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior-class.html) of the series.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(enable: true, shared: true);
super.initState();
}
@override
Widget build(BuildContext context){
return Scaffold(
body: Center(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
tooltipBehavior: _tooltipBehavior,
indicators: <TechnicalIndicators<dynamic, dynamic>>[
ATRIndicator<dynamic, dynamic>(
seriesName: 'HiloOpenClose',
)
],
series: <ChartSeries<ChartData, DateTime>>[
HiloOpenCloseSeries<ChartData, DateTime>(
enableTooltip: true,
name: 'HiloOpenClose')
]
)
)
);
}
class ChartData {
ChartData(this.x, this.low, this.high, this.open, this.close);
final DateTime x;
final double? low;
final double? high;
final double? open;
final double? close;
}
{% endhighlight %}
![tooltip](images/technical-indicators/tooltip.jpg)
## Binding data source to indicators
In order to use [`TechnicalIndicators`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators-class.html) for line, area chart etc., you need to bind the data source of the chart to indicator's [`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`openValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/openValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html) respectively.
Refer the following example below
{% highlight dart %}
@override
Widget build(BuildContext context){
return Scaffold(
body: Center(
child: SfCartesianChart(
indicators: <TechnicalIndicators>[
MomentumIndicator<SalesData, num>(
period: 5,
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.x,
highValueMapper: (SalesData sales, _) => sales.high,
lowValueMapper: (SalesData sales, _) => sales.low,
openValueMapper: (SalesData sales, _) => sales.open,
closeValueMapper: (SalesData sales, _) => sales.close,
)
],
series: <ChartSeries<SalesData, num>>[
LineSeries<SalesData, num>(
color: Colors.purple,
dataSource: chartData,
xValueMapper: (SalesData1 sales, _) => sales.x,
yValueMapper: (SalesData1 sales, _) => sales.y,
)
]
)
)
);
}
class SalesData {
SalesData(this.x, this.low, this.high, this.open, this.close);
final num x;
final double? low;
final double? high;
final double? open;
final double? close;
}
class SalesData1{
SalesData1(this.x, this.y);
final num x;
final double y;
}
{% endhighlight %}
![Binding data source to Indicators](images/technical-indicators/indicator_binding.jpg)
#### See Also
* [Refer this link for technical indicators callback](https://help.syncfusion.com/flutter/cartesian-charts/callbacks#onrenderdetailsupdate).
_Note_ : Each indicators has their own number of value mappers available,
* [`Accumulation distribution indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AccumulationDistributionIndicator-class.html) (AD) - can be rendered with five value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html), [`volumeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AccumulationDistributionIndicator/volumeValueMapper.html)).
* [`Average true range indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AtrIndicator-class.html) (ATR) - can be rendered with four value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
* [`Bollinger band indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/BollingerBandIndicator-class.html) - can be rendered with two value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html) and [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
* [`Exponential moving average indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmaIndicator-class.html) (EMA) - can be rendered with five value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`openValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/openValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
* [`Moving average convergence divergence`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MacdIndicator-class.html) (MACD) - can be rendered with two value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html) and [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
* [`Momentum indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MomentumIndicator-class.html) - can be rendered with five value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`openValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/openValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
* [`Relative strength index indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RsiIndicator-class.html) (RSI) - can be rendered with four value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
* [`Simple moving average indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SmaIndicator-class.html) (SMA) - can be rendered with five value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`openValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/openValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
* [`Stochastic indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/StochasticIndicator-class.html) - can be rendered with five value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`openValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/openValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
* [`Triangular moving average indicator`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TmaIndicator-class.html) (TMA) - can be rendered with five value mappers ([`xValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/xValueMapper.html), [`lowValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/lowValueMapper.html), [`highValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/highValueMapper.html), [`openValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/openValueMapper.html), [`closeValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TechnicalIndicators/closeValueMapper.html)).
N> `chartData` in the above code snippets is a class type list and holds the data for binding to the chart series. Refer [Bind data source](https://help.syncfusion.com/flutter/cartesian-charts/getting-started#bind-data-source) topic for more details.

Просмотреть файл

@ -0,0 +1,268 @@
---
layout: post
title: Tooltip in Flutter Cartesian Charts widget | Syncfusion
description: Learn here all about Tooltip feature of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Tooltip in Flutter Cartesian Charts (SfCartesianChart)
Chart provides tooltip support for all the series. It is used to show information about the segment, when you tap on the segment. To enable the tooltip, you need to set [`enableTooltip`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CartesianSeries/enableTooltip.html) property as *true*.
The tooltip state will be preserved on the device's orientation change and on browser resize. For example, if the tooltip's ['duration'](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/duration.html) is set to 10,000ms, and when you change the orientation of your device from portrait to landscape after 5,000ms of tooltip display, the tooltip will be displayed for the next 5,000ms in landscape mode before disappearing.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState() {
_tooltipBehavior = TooltipBehavior(
enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
//Enables the tooltip for all the series
tooltipBehavior: _tooltipBehavior,
series: <CartesianSeries>[
LineSeries<ChartData, String>(
//Enables the tooltip for individual series
enableTooltip: true,
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y);
final String x;
final double? y;
}
{% endhighlight %}
![Tooltip](images/tooltip/default_tooltip.jpg)
#### See Also
* [Activate chart tooltip after the chart got rendered](https://www.syncfusion.com/kb/12223/how-to-activate-chart-tooltip-initially-after-the-chart-widget-got-rendered).
## Customizing the appearance
You can use the following properties to customize the tooltip appearance.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/color.html) - used to change the background color of tooltip.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/borderWidth.html) - used to change the stroke width of the tooltip.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/borderColor.html) - used to change the stroke color of the tooltip.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/opacity.html) - used to control the transparency of the tooltip.
* [`duration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/duration.html) - specifies the duration for displaying the tooltip that defaults to `3000`.
* [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/animationDuration.html) - specifies the duration for animating the tooltip that default to 350.
* [`elevation`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/elevation.html) - specifies the elevation of tooltip.
* [`canShowMarker`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/canShowMarker.html) - toggles the visibility of the marker in the tooltip.
* [`header`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/header.html) - specifies the header for tooltip. By default, the series name will be displayed in the header.
* [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) - formats the tooltip text. By default, the tooltip will be rendered with x and y-values. You can add prefix or suffix to x, y, and series name values in the tooltip by formatting them.
* [`shadowColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shadowColor.html) - specifies the color of the tooltip shadow.
* [`shouldAlwaysShow`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shouldAlwaysShow.html) - shows or hides the tooltip. By default, the tooltip will be hidden on touch. To avoid this, set this property to true.
* [`textAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/textAlignment.html) - alignment of the text in the tooltip.
* [`header`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/header.html) - header of the tooltip. By default, the series name will be displayed in the header.
* [`textStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/textStyle.html) - customizes the tooltip text.
* [`shared`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shared.html) - share the tooltip with same index points.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState() {
_tooltipBehavior = TooltipBehavior(
enable: true,
borderColor: Colors.red,
borderWidth: 5,
color: Colors.lightBlue
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
tooltipBehavior: _tooltipBehavior,
)
)
)
);
}
{% endhighlight %}
![Customized tooltip](images/tooltip/customized_tooltip.jpg)
## Label format
By default, x and y value will be displayed in the tooltip, and it can be customized using [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) property as depicted in the below code snippet. You can show the below values in the tooltip. Also you can add prefix or suffix to these values.
* X value - `point.x`
* Y value - `point.y`
* Bubble size - `point.size`
* Name of the series - `series.name`
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState() {
_tooltipBehavior = TooltipBehavior(
enable: true,
// Formatting the tooltip text
format: 'point.y%'
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
tooltipBehavior: _tooltipBehavior,
)
)
)
);
}
{% endhighlight %}
## Tooltip positioning
The tooltip can be made to display in the fixed location or at the pointer location itself using the `tooltipPosition` property. This defaults to `auto`.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState() {
_tooltipBehavior = TooltipBehavior(
enable: true,
tooltipPosition: TooltipPosition.pointer
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
tooltipBehavior: _tooltipBehavior,
)
)
)
);
}
{% endhighlight %}
![pointer tooltip](images/tooltip/tooltip_pointer.png)
## Tooltip template
You can customize the appearance of the tooltip with your own widget by using the [`builder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/builder.html) property of [`tooltipBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart/tooltipBehavior.html).
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState() {
_tooltipBehavior = TooltipBehavior(
enable: true,
// Templating the tooltip
builder: (dynamic data, dynamic point, dynamic series,
int pointIndex, int seriesIndex) {
return Container(
child: Text(
'PointIndex : ${pointIndex.toString()}'
)
);
}
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
tooltipBehavior: _tooltipBehavior,
)
)
)
);
}
{% endhighlight %}
![Tooltip template](images/tooltip/tooltip_template.jpg)
## Activation mode
The [`activationMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/activationMode.html) property is used to restrict the visibility of tooltip based on the touch actions. The default value of this property is [`ActivationMode.singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html).
The ActivationMode enum contains the following values:
* [`longPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - Activates tooltip only when performing the long press action.
* [`singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - Activates tooltip only when performing single tap action.
* [`doubleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - Activates tooltip only when performing double tap action.
* [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - Hides the visibility of tooltip when setting activation mode to none.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState() {
_tooltipBehavior = TooltipBehavior(
enable: true,
// Tooltip will be displayed on long press
activationMode: ActivationMode.longPress
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
tooltipBehavior: _tooltipBehavior,
)
)
)
);
}
{% endhighlight %}
Also refer [tooltip event](./events#ontooltiprender) for customizing the tooltip further.

Просмотреть файл

@ -0,0 +1,682 @@
---
layout: post
title: Trackball and Crosshair in Flutter Cartesian Charts | Syncfusion
description: Learn here all about Trackball and Crosshair feature of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Trackball and Crosshair in Flutter Cartesian Charts (SfCartesianChart)
## Trackball
Trackball feature displays the tooltip for the data points that are closer to the point where you touch on the chart area. This feature, especially, can be used instead of data label feature when you cannot show data labels for all data points due to space constraint. This feature can be enabled using [`enable`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/enable.html) property of [`trackballBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart/trackballBehavior.html). Trackball will be activated once you long-press anywhere on the chart area. Once it is activated, it will appear in the UI and move based on your touch movement until you stop touching on the chart.
The trackball state will be preserved on the device's orientation change and on browser resize. For example, if the trackball's ['hideDelay'](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/hideDelay.html) is set to 10,000ms, and when you change the orientation of your device from portrait to landscape after 5,000ms of trackball display, the trackball will be displayed for the next 5,000ms in landscape mode before disappearing.
You can use the following properties to customize the appearance of trackball tooltip.
* [`lineType`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/lineType.html) - specifies the type of trackball line. By default, vertical line will be displayed.
* [`lineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/lineColor.html) - specifies the color of the trackball line.
* [`lineWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/lineWidth.html) - specifies the stroke width of the trackball line.
* [`lineDashArray`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/lineDashArray.html)- used to render trackball line with dashes.
* [`shouldAlwaysShow`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/shouldAlwaysShow.html) - used to show the trackball even after the touch end.
* [`tooltipSettings.borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/borderWidth.html) - used to change the stroke width of the axis tooltip.
* [`tooltipSettings.borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/borderColor.html) - used to change the stroke color of the axis tooltip.
* [`tooltipSettings.arrowLength`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/arrowLength.html) - specifies the length of the tooltip arrow.
* [`tooltipSettings.arrowWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/arrowWidth.html) - specifies the width of the tooltip arrow.
* [`tooltipSettings.format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/format.html) - by default, axis value will be displayed in the tooltip, and it can be customized by adding desired text as prefix or suffix.
* [`tooltipSettings.textStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the text color, size, font family, fontStyle, and font weight.
* [`tooltipSettings.textStyle.color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the color of the tooltip text.
* [`tooltipSettings.textStyle.fontFamily`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the font family for tooltip text.
* [`tooltipSettings.textStyle.fontStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the font style for tooltip text.
* [`tooltipSettings.textStyle.fontSize`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the font size for tooltip text.
* [`hideDelay`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/hideDelay.html ) - used to specify disappear delay for trackball.
N> The above mentioned properties are only applicable for SfCartesian types of charts.
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
// Enables the trackball
enable: true,
tooltipSettings: InteractiveTooltip(
enable: true,
color: Colors.red
)
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
trackballBehavior: _trackballBehavior,
)
)
)
)
);
}
{% endhighlight %}
![Trackball](images/trackball-crosshair/default_trackball.jpg)
### Label display mode
The [`tooltipDisplayMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/tooltipDisplayMode.html) property is used to specify whether to display label for all the data points along the vertical line or display only single label. Following are the options you can set to this property,
* [`floatAllPoints`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballDisplayMode-class.html) - displays label for all the data points along the tracker line.
* [`nearestPoint`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballDisplayMode-class.html) - displays label for single data point that is nearer to the touch contact position.
* [`groupAllPoints`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballDisplayMode-class.html) - displays label for all the data points grouped and positioned at the top of the chart area.
* [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballDisplayMode-class.html) - doesn't display the label.
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
enable: true,
// Display mode of trackball tooltip
tooltipDisplayMode: TrackballDisplayMode.floatAllPoints
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
trackballBehavior: _trackballBehavior,
)
)
)
)
);
}
{% endhighlight %}
![Label display mode](images/trackball-crosshair/label_display_mode.jpg)
### Label alignment
The position of trackball tooltip can be changed using the [`tooltipAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/tooltipAlignment.html) property of [`trackballBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart/trackballBehavior.html). The following options are available in [`tooltipAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/tooltipAlignment.html).
* [`near`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html) - aligns the trackball tooltip to the top position of plot area.
* [`far`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html) - aligns the trackball tooltip to the bottom position of plot area.
* [`center`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html) - aligns the trackball tooltip to the center position of plot area.
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
enable: true,
tooltipAlignment: ChartAlignment.near,
tooltipDisplayMode: TrackballDisplayMode.groupAllPoints
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
trackballBehavior: _trackballBehavior,
)
)
)
)
);
}
{% endhighlight %}
![Label alignment](images/trackball-crosshair/label_alignment.jpg)
N> This is applicable only when the [`tooltipDisplayMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/tooltipDisplayMode.html) is set to [`groupAllPoints`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballDisplayMode-class.html).
### Label format
By default, axis value will be displayed in the tooltip, and it can be customized using [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) property by adding desired text as prefix or suffix.
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
enable: true,
tooltipSettings: InteractiveTooltip(
// Formatting trackball tooltip text
format: 'point.x : point.y%'
)
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
trackballBehavior: _trackballBehavior,
)
)
)
)
);
}
{% endhighlight %}
![Label format](images/trackball-crosshair/label_format.jpg)
### Activation mode
The [`activationMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/activationMode.html) property is used to restrict the visibility of trackball based on the touch actions. The default value of this property is [`ActivationMode.longPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html).
The ActivationMode enum contains the following values:
* [`longPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates trackball only when performing the long press action.
* [`singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates trackball only when performing single tap action.
* [`doubleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates trackball only when performing double tap action.
* [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - Hides the visibility of trackball when setting activation mode to none. It will be activated when calling the [`show`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/show.html) method.
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
enable: true,
// Displays the trackball on single tap
activationMode: ActivationMode.singleTap
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
trackballBehavior: _trackballBehavior,
)
)
)
)
);
}
{% endhighlight %}
### Trackball tooltip overlap
[`SfCartesianChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCartesianChart-class.html) provides support to avoid the overlapping of two or more tooltips of the trackball and no API is required for this feature as it will be done by default. For example, If we have 2 or more series data points rendered close to each other then, the trackball tooltips of each data point will not be overlap with each other.
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
trackballBehavior: _trackballBehavior,
<LineSeries<SalesData, DateTime>>[
LineSeries<SalesData, DateTime>(
dataSource: ChartData,
markerSettings: MarkerSettings(enable: true),
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales)
LineSeries<SalesData, DateTime>(
dataSource: ChartData1,
markerSettings: MarkerSettings(enable: true),
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales),
LineSeries<SalesData, DateTime>(
dataSource: ChartDat2,
markerSettings: MarkerSettings(enable: true),
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales),
LineSeries<SalesData, DateTime>(
dataSource: ChartData3,
markerSettings: MarkerSettings(enable: true),
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![Trackball tooltip overlap](images/trackball-crosshair/trackball_overlap.png)
### Trackball marker settings
Trackball markers are used to provide information about the exact point location. You can add a shape to adorn each data point when the trackball is visible. Trackball markers can be enabled by using the [`markerVisibility`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballMarkerSettings/markerVisibility.html) property of [`TrackballMarkerSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballMarkerSettings-class.html). The below [`markerVisibility`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballMarkerSettings/markerVisibility.html) property determines whether the trackball marker should be visible or not when the trackball is enabled in the chart
* [`TrackballVisibilityMode.auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballVisibilityMode-class.html) - If the [`isVisible`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MarkerSettings/isVisible.html) property in the series [`markerSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MarkerSettings-class.html) is set to true, then the trackball marker will also be displayed for that particular series, else it will not be displayed.
* [`TrackballVisibilityMode.visible`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballVisibilityMode-class.html) - Makes the trackball marker visible for all the series irrespective of considering the [`isVisible`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MarkerSettings/isVisible.html) property's value in the [`markerSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/MarkerSettings-class.html).
* [`TrackballVisibilityMode.hidden`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballVisibilityMode-class.html) - Hides the trackball marker for all the series.
Also refer, [marker customization](./marker-datalabel#Marker) for customizing the appearance of trackball marker.
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
enable: true,
markerSettings: TrackballMarkerSettings(
markerVisibility: TrackballVisibilityMode.visible)
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
trackballBehavior: _trackballBehavior,
<LineSeries<SalesData, DateTime>>[
LineSeries<SalesData, DateTime>(
dataSource: ChartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales)
LineSeries<SalesData, DateTime>(
dataSource: ChartData1,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales),
LineSeries<SalesData, DateTime>(
dataSource: ChartData2,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales),
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![Trackball marker](images/trackball-crosshair/trackball_marker.png)
#### See Also
* [Disable marker for a specific series in trackball](https://www.syncfusion.com/kb/12107/how-to-disable-the-trackball-marker-for-specific-series-in-cartesian-charts).
### Trackball tooltip template
You can customize the appearance of the trackball tooltip with your own widgets by using the [`builder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/builder.html) property of [`trackballBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior-class.html).
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
enable: true,
builder: (BuildContext context,
TrackballDetails trackballDetails) {
return Container(
height: 50,
width: 150,
decoration: BoxDecoration(
color: Color.fromRGBO(0, 8, 22, 0.75),
borderRadius:
BorderRadius.all(Radius.circular(6.0)),
),
child: Row(children: [
Padding(
padding: EdgeInsets.only(left: 5),
child: SizedBox(
child:
Image.asset('images/People_Circle16.png'),
height: 30,
width: 30,
)),
Center(
child: Container(
padding: EdgeInsets.only(top: 11, left: 7),
height: 40,
width: 100,
child: Text(
'${trackballDetails.point.x.toString()} : \$${trackballDetails.point.y.toString()}',
style: TextStyle(
fontSize: 13,
color: Color.fromRGBO(
255, 255, 255, 1)))))
]));
},
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
trackballBehavior: _trackballBehavior,
series: <CartesianChart<SalesData, String>>[
SplineSeries<SalesData, String>(
dataSource: ChartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final String year;
final double? sales;
}
{% endhighlight %}
![Trackball template](images/trackball-crosshair/trackball_template.jpg)
### Trackball grouping mode info
[TrackballGroupingModeInfo](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballGroupingModeInfo-class.html) is store the group mode details of trackball template.
The following properties are available in [`TrackballGroupingModeInfo`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballGroupingModeInfo-class.html):
* [`points`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballGroupingModeInfo/points.html) - it specifies the Cartesian chart points.
* [`currentPointIndices`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballGroupingModeInfo/currentPointIndices.html) - it specifies the current point indices.
* [`visibleSeriesIndices`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballGroupingModeInfo/visibleSeriesIndices.html) - it specifies the visible series indices.
* [`visibleSeriesList`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballGroupingModeInfo/visibleSeriesList.html) - it specifies the Cartesian visible series list.
### Trackball tooltip Marker
The [`canShowMarker`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/canShowMarker.html) is used to toggle the visibility of the marker in the trackball tooltip.
Markers are rendered with the series color and placed near the value in trackball tooltip to convey which value belongs to which series.
Trackball tooltip marker uses the same shape specified for the series marker. But trackball tooltip marker will render based on the value specified to this property irrespective of considering the series marker's visibility.
Defaults to `true`.
{% highlight dart %}
late TrackballBehavior _trackballBehavior;
@override
void initState(){
_trackballBehavior = TrackballBehavior(
enable: true,
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
trackballBehavior: _trackballBehavior,
series: <LineSeries<SalesData, String>>[
LineSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales),
LineSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales1),
LineSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales2),
LineSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales3),
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales, this,sales1, this.sales2, this.sales3);
final String year;
final double? sales;
final double? sales1;
final double? sales2;
final double? sales3;
}
{% endhighlight %}
![Trackball tooltip marker](images/trackball-crosshair/trackball_tooltip_marker.png)
#### See Also
* [Synchronize trackball with multiple charts in Cartesian charts](https://www.syncfusion.com/kb/11881/how-to-synchronize-trackball-in-multiple-charts-sfcartesianchart).
## Crosshair
Crosshair has a vertical and horizontal line to view the value of the axis.
Crosshair lines can be enabled by using [`enable`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/enable.html) property in the [`crosshairBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/CrosshairBehavior.html). Likewise tooltip label for an axis can be enabled by using [`enable`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/enable.html) property of [`interactiveTooltip`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAxis/interactiveTooltip.html) in the corresponding axis. The [`hideDelay`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/hideDelay.html) property can be used to specify a disappear delay for the crosshair.
The crosshair state will be preserved on the device's orientation change and on browser resize. For example, if the crosshair's ['hideDelay'](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/hideDelay.html) is set to 10,000ms, and when you change the orientation of your device from portrait to landscape after 5,000ms of crosshair display, the crosshair will be displayed for the next 5,000ms in landscape mode before disappearing.
N> The above mentioned properties are only applicable for SfCartesian types of charts.
{% highlight dart %}
late CrosshairBehavior _crosshairBehavior;
@override
void initState(){
_crosshairBehavior = CrosshairBehavior(
// Enables the crosshair
enable: true
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: NumericAxis(
interactiveTooltip: InteractiveTooltip(
// Enables the crosshair tooltip
enable: true
)
),
crosshairBehavior: _crosshairBehavior
)
)
)
)
);
}
{% endhighlight %}
![Crosshair](images/trackball-crosshair/default_crosshair.jpg)
### Track line customization
The appearance of the track line in crosshair can be customized using the following properties.
* [`lineType`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/lineType.html) - specifies the type of crosshair line.
* [`lineColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/lineColor.html) - specifies the color of the crosshair line.
* [`lineWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/lineWidth.html) - specifies the stroke width of the crosshair line.
* [`lineDashArray`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/lineDashArray.html) - used to render crosshair line with dashes.
* [`shouldAlwaysShow`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/shouldAlwaysShow.html) - enables or disables the crosshair. Defaults to `false`.
{% highlight dart %}
late CrosshairBehavior _crosshairBehavior;
@override
void initState(){
_crosshairBehavior = CrosshairBehavior(
enable: true,
lineColor: Colors.red,
lineDashArray: <double>[5,5],
lineWidth: 2,
lineType: CrosshairLineType.vertical
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
crosshairBehavior: _crosshairBehavior
)
)
)
)
);
}
{% endhighlight %}
![Customized trackline](images/trackball-crosshair/customized_trackline.jpg)
### Show axis tooltip
The axis tooltip can be enabled using [`enable`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/enable.html) property of [`interactiveTooltip`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAxis/interactiveTooltip.html). You can customize the appearance of axis tooltip using the following properties.
* [`enable`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/enable.html) - used to enable the axis tooltip.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/borderWidth.html) - used to change the stroke width of the axis tooltip.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/borderColor.html) - used to change the stroke color of the axis tooltip.
* [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/format.html) - by default, axis value will be displayed in the tooltip, and it can be customized by adding desired text as prefix or suffix.
* [`textStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the text color, size, font family, fontStyle, and font weight.
* [`textStyle.color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the color of the text.
* [`textStyle.fontFamily`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the font family for chart title.
* [`textStyle.fontStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the font style for the chart title.
* [`textStyle.fontSize`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the font size for the chart title.
### Activation mode
The [`activationMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrackballBehavior/activationMode.html) property is used to restrict the visibility of trackball based on the touch actions. The default value of this property is [`ActivationMode.longPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html).
The ActivationMode enum contains the following values:
* [`longPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates crosshair only when performing the long press action.
* [`singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates crosshair only when performing single tap action.
* [`doubleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates crosshair only when performing double tap action.
* [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - hides the visibility of crosshair when setting activation mode to none. It will be activated when calling the [`show`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/show.html) method.
{% highlight dart %}
late CrosshairBehavior _crosshairBehavior;
@override
void initState(){
_crosshairBehavior = CrosshairBehavior(
enable: true,
// Displays the crosshair on single tap
activationMode: ActivationMode.singleTap
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
crosshairBehavior: _crosshairBehavior
)
)
)
)
);
}
{% endhighlight %}
Also refer [crosshair](./events#oncrosshairpositionchanging) and [trackball](./events#ontrackballpositionchanging) events for customizing the crosshair and trackball further.
## See Also
* [Disabling trackball tooltip for particular series in Cartesian chart](https://www.syncfusion.com/kb/11638/how-to-disable-trackball-tooltip-for-particular-series-in-cartesian-charts-sfcartesianchart).
N> `chartData` in the above code snippets is a class type list and holds the data for binding to the chart series. Refer [Bind data source](https://help.syncfusion.com/flutter/cartesian-charts/getting-started#bind-data-source) topic for more details.

Просмотреть файл

@ -0,0 +1,517 @@
---
layout: post
title: Trendlines in Flutter Cartesian Charts widget | Syncfusion
description: Learn here all about Trendlines feature of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Trendlines in Flutter Cartesian Charts (SfCartesianChart)
Trendlines are used to show the direction and speed of price.
Trendlines can be generated for the Cartesian type series (Line, Column, Scatter, Area, Candle, HiLo, etc.) except bar type series. You can add more than one trendline to a series.
You can use the following properties to customize the behavior and appearance of trendlines.
* [`type`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrendlineType-class.html) - specifies the type of trendline that must be added to the series.
* [`isVisible`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/isVisible.html) - used to toggle the visibility of trendlines in a series.
* [`width`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/width.html) - used to determine the width of trendline.
* [`backwardForecast`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/backwardForecast.html) - used to specify the range of backward forecast for the trendline.
* [`forwardForecast`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/forwardForecast.html) - used to specify the range of forward forecast for the trendline.
* [`intercept`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/intercept.html) - used to provide the trendline intercept values
* [`period`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/period.html) - used to determine the starting point for the trendline.
* [`polynomialOrder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/polynomialOrder.html) -used to provide the polynomial order for polynomial type trendlines.
* [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/animationDuration.html) - used to animate the trendlines. By default, animationDuration has a value of 1500. When animationDuration is set to zero no animation takes place.
* `animationDelay` - Used to specify the delay duration of the trendline animation. This takes a millisecond value as input. By default, the trendline will get animated for the specified duration. If `animationDelay` is specified, then the trendline will begin to animate after the specified duration.
* [`dashArray`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/AxisLine/dashArray.html) - pattern of dashes and gaps used to stroke the trendline.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/opacity.html) - opacity of the trendline.
* [`valueField`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/valueField.html) - used to choose the valueField(low or high) to render the trendline. Defaults to `low`.
* [`isVisibleInLegend`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/isVisibleInLegend.html) - show/hides the legend for trendline.
* [`legendIconType`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/legendIconType.html) - specifies the type of legend icon for trendline
## Types of trendlines
Chart supports 6 types of trendlines.
### Linear
A linear trendline is a best fit straight line that is used with simpler data sets. To render a linear trendline, use trendline type as Linear.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.linear,
color: Colors.blue)
]
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![linear trendline](images/trendline/linear.png)
### Exponential
An exponential trendline is a curved line that is most useful when data values rise or fall at increasingly higher rates. You cannot create an exponential trendline if your data contains zero or negative values.
To render an exponential trendline, use trendline type as Exponential.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.exponential,
color: Colors.blue)
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![exponential trendline](images/trendline/exponential.png)
### Logarithmic
A logarithmic trendline is a best-fit curved line that is most useful when the rate of change in the data increases or decreases quickly and then levels out. A logarithmic trendline can use negative and/or positive values.
To render a logarithmic trendline, use trendline type as Logarithmic
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.logarithmic,
color: Colors.blue)
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![logarithmic trendline](images/trendline/logarithmic.png)
### Polynomial
A polynomial trendline is a curved line that is used when data fluctuates.
To render a polynomial trendline, use trendline type as Polynomial.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.polynomial,
color: Colors.blue)
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![polynomial trendline](images/trendline/polynomial.png)
### Power
A power trendline is a curved line that is best used with data sets that compare measurements that increase at a specific rate.
To render a power trendline, use trendline type as Power
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.power,
color: Colors.blue)
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![power trendline](images/trendline/power.png)
### Moving Average
A moving average trendline smoothen out fluctuations in data to show a pattern or trend more clearly.
To render a moving average trendline, use trendline type as MovingAverage
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.MovingAverage,
color: Colors.blue)
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![linear trendline](images/trendline/movingaverage.png)
## Forecasting
Trendline forecasting is the prediction of future/past situations.
Forward Forecasting and Backward Forecasting are the two types of forecasting.
### Forward Forecasting
The value set for forwardForecast is used to determine the distance moving towards the future trend.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.linear,
forwardForecast:10,
color: Colors.blue),
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![forward forecast](images/trendline/forwardforecast.png)
### Backward Forecasting
The value set for the backwardForecast is used to determine the past trends.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.linear,
backwardForecast:10,
color: Colors.blue)
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![forward forecast](images/trendline/backwardforecast.png)
## Legend for TrendLine
Legend for trendline gets rendered together with the series legend when the legend is set to be visible. Also when the [name](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/name.html) property is assigned to a trendline, the name of the legend is changed based on the name of the trendlines.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.linear,
name:'trendline-name',
legendIconType: LegendIconType.diamond,
color: Colors.blue)
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![forward forecast](images/trendline/legend.png)
## Markers
Data markers are used to provide information about the data points in the series. You can add a shape to adorn each data point.Trendlines support markers that can be enabled using the property [`markerSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/Trendline/markerSettings.html) .
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.linear,
name:'trendline-name',
markerSettings: MarkerSettings(isVisible:true),
color: Colors.blue)
],
),
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![backward forecast](images/trendline/marker.png)
## Tooltip for Trendline
Chart will display details about the points through tooltip, when user interaction is done over the point.Trendline Tooltip has the same [`ActivationMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/activationMode.html) that has been given in the [`TooltipBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior-class.html) of the series.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCartesianChart(
tooltipBehavior: _tooltipBehavior,
primaryXAxis: DateTimeAxis(),
series: <ChartSeries>[
// Renders spline chart
SplineSeries<SalesData, DateTime>(
dataSource: chartData,
trendlines:<Trendline>[
Trendline(
type: TrendlineType.linear,
name:'trendline-name',
enableTooltip: true,
markerSettings: MarkerSettings(isVisible:true),
color: Colors.blue)
],
)
]
)
)
)
);
}
class SalesData {
SalesData(this.year, this.sales);
final DateTime year;
final double? sales;
}
{% endhighlight %}
![tooltip](images/trendline/tooltip.png)
Also refer [`trendline event`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TrendlineRenderArgs-class.html) for customizing the tooltip further.
N> `chartData` in the above code snippets is a class type list and holds the data for binding to the chart series. Refer [Bind data source](https://help.syncfusion.com/flutter/cartesian-charts/getting-started#bind-data-source) topic for more details.

Просмотреть файл

@ -0,0 +1,334 @@
---
layout: post
title: Zooming and Panning in Flutter Cartesian Charts widget | Syncfusion
description: Learn here all about Zooming and Panning feature of Syncfusion Flutter Cartesian Charts (SfCartesianChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Zooming and Panning in Flutter Cartesian Charts (SfCartesianChart)
## Pinch zooming
Pinch zooming can be enabled by [`enablePinching`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/enablePinching.html) property and defaults to `false`. Pinching can be performed by moving two fingers over the chart.
{% highlight dart %}
late ZoomPanBehavior _zoomPanBehavior;
@override
void initState(){
_zoomPanBehavior = ZoomPanBehavior(
// Enables pinch zooming
enablePinching: true
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
height: 300,
width: 350,
child: SfCartesianChart(
zoomPanBehavior: _zoomPanBehavior
)
)
)
)
);
}
{% endhighlight %}
## Double tap zooming
Double tap zooming can be enabled using [`enableDoubleTapZooming`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/enableDoubleTapZooming.html) property. Defaults to `false`.
{% highlight dart %}
late ZoomPanBehavior _zoomPanBehavior;
@override
void initState(){
_zoomPanBehavior = ZoomPanBehavior(
// Performs zooming on double tap
enableDoubleTapZooming: true
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
height: 300,
width: 350,
child: SfCartesianChart(
zoomPanBehavior: _zoomPanBehavior
)
)
)
)
);
}
{% endhighlight %}
## Selection zooming
By specifying [`enableSelectionZooming`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/enableSelectionZooming.html) property to true, you can long press and drag to select a range on the chart to be zoomed in.
**Selection rectangle customization**
You can customize the selection rectangle using the below properties.
* [`selectionRectBorderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/selectionRectBorderWidth.html) - used to change the stroke width of the selection rectangle.
* [`selectionRectBorderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/selectionRectBorderColor.html) - used to change the stroke color of the selection rectangle.
* [`selectionRectColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/selectionRectColor.html) - used to change the background color of the selection rectangle.
{% highlight dart %}
late ZoomPanBehavior _zoomPanBehavior;
@override
void initState(){
_zoomPanBehavior = ZoomPanBehavior(
enableSelectionZooming: true,
selectionRectBorderColor: Colors.red,
selectionRectBorderWidth: 1,
selectionRectColor: Colors.grey
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
height: 300,
width: 350,
child: SfCartesianChart(
zoomPanBehavior: _zoomPanBehavior
)
)
)
)
);
}
{% endhighlight %}
![Selection Zooming](images/zooming-panning/before_zooming.jpg)
Following screenshot shows the zoomed area
![Selection Zooming](images/zooming-panning/after_zooming.jpg)
**Show axis tooltip**
The axis tooltip on selection zooming can be enabled using [`enable`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CrosshairBehavior/enable.html) property of [`InteractiveTooltip`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip-class.html). You can customize the appearance of axis tooltip using the following properties.
* [`enable`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/enable.html) - used to enable the axis tooltip.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/borderWidth.html) - used to change the stroke width of the axis tooltip.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/borderColor.html) - used to change the stroke color of the axis tooltip.
* [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/format.html) - by default, axis value will be displayed in the tooltip, and it can be customized by adding desired text as prefix or suffix.
* [`textStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/InteractiveTooltip/textStyle.html) - used to change the text color, size, font family, fontStyle, and font weight.
* [`textStyle.color`](https://api.flutter.dev/flutter/painting/TextStyle/color.html) - used to change the color of the text.
* [`textStyle.fontFamily`](https://api.flutter.dev/flutter/painting/TextStyle/fontFamily.html) - used to change the font family for chart title.
* [`textStyle.fontStyle`](https://api.flutter.dev/flutter/painting/TextStyle/fontStyle.html) - used to change the font style for the chart title.
* [`textStyle.fontSize`](https://api.flutter.dev/flutter/painting/TextStyle/fontSize.html) - used to change the font size for the chart title.
{% highlight dart %}
late ZoomPanBehavior _zoomPanBehavior;
@override
void initState(){
_zoomPanBehavior = ZoomPanBehavior(
enableDoubleTapZooming: true,
enablePinching: true,
// Enables the selection zooming
enableSelectionZooming: true
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: NumericAxis(
interactiveTooltip: InteractiveTooltip(
// Displays the x-axis tooltip
enable: true,
borderColor: Colors.red,
borderWidth: 2
)
),
primaryYAxis: NumericAxis(
interactiveTooltip: InteractiveTooltip(
// Displays the y-axis tooltip
enable: true,
borderColor: Colors.red,
borderWidth: 2
)
),
zoomPanBehavior: _zoomPanBehavior
)
)
)
)
);
}
{% endhighlight %}
## Mouse wheel zooming
The [enableMouseWheelZooming](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/enableMouseWheelZooming.html) can be performed by rolling the mouse wheel up or down. The place where the cursor is hovering gets zoomed in or out according to the mouse wheel rolling up or down.
{% highlight dart %}
late ZoomPanBehavior _zoomPanBehavior;
@override
void initState(){
_zoomPanBehavior = ZoomPanBehavior(
enableMouseWheelZooming : true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
height: 300,
width: 350,
child: SfCartesianChart(
zoomPanBehavior: _zoomPanBehavior
)
)
)
)
);
}
{% endhighlight %}
## Auto interval on zooming
The [`enableAutoIntervalOnZooming`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAxis/enableAutoIntervalOnZooming.html) property determines the update of axis interval based on the current visible range while zooming and panning the chart. Default value of this property is true. If this property is false, the nice interval will not be calculated for new range after zoom in and actual interval will be sustained.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
primaryXAxis: DateTimeAxis(
// Intervals will be fixed, not calculated automatically based on the visible range on zooming and panning
enableAutoIntervalOnZooming: false
)
)
)
)
)
);
}
{% endhighlight %}
## Maximum zoom level
The [`maximumZoomLevel`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/maximumZoomLevel.html) property defines the maximum zooming level. Zooming will be stopped after reaching this value. This defaults to `null`.
{% highlight dart %}
late ZoomPanBehavior _zoomPanBehavior;
@override
void initState(){
_zoomPanBehavior = ZoomPanBehavior(
maximumZoomLevel: 3);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
zoomPanBehavior: _zoomPanBehavior
)
)
)
)
);
}
{% endhighlight %}
## Panning
Panning can be performed on a zoomed axis. You can pan the zoomed chart with [`enablePanning`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomPanBehavior/enablePanning.html) property. Defaults to `false`.
If zoom mode is set to [`zoomMode.x`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomMode-class.html) means you can only pan to the horizontal direction, in case the [`zoomMode.y`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomMode-class.html) means you can pan only to the vertical direction and [`zoomMode.xy`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ZoomMode-class.html) means you can pan to both horizontal and vertical directions on the chart.
{% highlight dart %}
late ZoomPanBehavior _zoomPanBehavior;
@override
void initState(){
_zoomPanBehavior = ZoomPanBehavior(
enablePinching: true,
zoomMode: ZoomMode.x,
enablePanning: true,
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
child: SfCartesianChart(
zoomPanBehavior: _zoomPanBehavior
)
)
)
)
);
}
{% endhighlight %}
![Panning](images/zooming-panning/panning.gif)
Also refer [zooming](./callbacks#onzooming), [zoom start](./callbacks#onzoomstart) and [zoom end](./callbacks#onzoomend) events for customizing the zooming further.
## See Also
* [To Synchronize panning in multiple charts](https://www.syncfusion.com/kb/11533/how-to-synchronize-panning-in-multiple-charts-sfcartesianchart).

Просмотреть файл

@ -0,0 +1,635 @@
---
layout: post
title: Series customization in Flutter Circular Charts widget | Syncfusion
description: Learn here all about Series customization of Syncfusion Flutter Circular Charts (SfCircularChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Series customization in Flutter Circular Charts (SfCircularChart)
## Animation
[`SfCircularChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCircularChart-class.html) provides animation support for the series. Series will be animated while rendering. Animation is enabled by default, you can also control the duration of the animation using [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/animationDuration.html) property. You can disable the animation by setting 0 value to that property.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
series: <CircularSeries<ChartData,String>>[
// Render pie chart
PieSeries<ChartData, String>(
dataSource: chartData,
pointColorMapper:(ChartData data, _) => data.color,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
animationDuration: 1000
)
]
)
)
)
);
}
{% endhighlight %}
## Animation delay
The `animationDelay` property is used to specify the delay duration of the series animation. This takes milliseconds value as input. By default, the series will get animated for the specified duration. If `animationDelay` is specified, then the series will begin to animate after the specified duration. Defaults to `0`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
List<ChartData> data = [
ChartData('Jan', 35),
ChartData('Feb', 28),
ChartData('Mar', 38),
ChartData('Apr', 32),
ChartData('May', 40)
];
return Center(
child: SfCircularChart(
series: <CircularSeries<ChartData, String>>[
PieSeries<ChartData, String>(
dataSource: data,
animationDuration: 4500,
animationDelay: 2000,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
)
]
),
);
}
class ChartData {
ChartData(this.x, this.y);
final String x;
final double y;
}
{% endhighlight %}
## Color Palette
[`SfCircularChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCircularChart-class.html) provides support for color palette property called [`palette`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCircularChart/palette.html) for the data points in the chart series. If the series color is not specified, then the series will be rendered with appropriate palette color. Ten colors are available by default.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
palette: <Color>[Colors.amber, Colors.brown, Colors.green, Colors.redAccent, Colors.blueAccent, Colors.teal],
series: <CircularSeries<ChartData,String>>[
// Render pie chart
PieSeries<ChartData, String>(
dataSource: chartData,
pointColorMapper:(ChartData data, _) => data.color,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
)
]
)
)
)
);
}
{% endhighlight %}
![Color Palette](images/circular-customization/color_palette.jpg)
## Color mapping for data points
The [`pointColorMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/pointColorMapper.html) property is used to map the color field from the data source.
{% highlight dart %}
@override
Widget build(BuildContext context) {
static List<SalesData> chartData = <SalesData>[
SalesData('Rent', 1000,Colors.teal),
SalesData('Food', 2500,Colors.lightBlue),
SalesData('Savings', 760,Colors.brown),
SalesData('Tax', 1897,Colors.grey),
SalesData('Others', 2987,Colors.blueGrey)
];
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
primaryXAxis: CategoryAxis(),
series: <PieSeries<SalesData, String>>[
PieSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales,
//map Color for each dataPoint datasource.
pointColorMapper: (SalesData sales,_) => sales.color,
)
]
)
)
)
);
}
{% endhighlight %}
![mapcolor](images/circular-customization/color-mapping.jpg)
## Gradient and image shader
The [`onCreateShader`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCircularChart/onCreateShader.html) callback is used to fill the circular chart series data points with gradient and image shader. This callback is called once while rendering
the data points and legend.
N> All the data points of the circular chart are considered together as a single segment and the shader is applied commonly.
### Gradient fill
The data points of pie, doughnut and radial bar charts can be filled with three types of [`gradient`](https://api.flutter.dev/flutter/dart-ui/Gradient-class.html) such as [`linear`](https://api.flutter.dev/flutter/dart-ui/Gradient/Gradient.linear.html), [`sweep`](https://api.flutter.dev/flutter/dart-ui/Gradient/Gradient.sweep.html) and [`radial`](https://api.flutter.dev/flutter/dart-ui/Gradient/Gradient.radial.html). All the data points in the circular chart are together considered as a single segment and the shader is applied commonly.
#### Linear gradient
{% highlight dart %}
List<Color> colors = <Color>[
const Color.fromRGBO(75, 135, 185, 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)
];
List<double> stops = <double>[
0.2,
0.4,
0.6,
0.8,
1,
];
@override
Widget build(BuildContext context) {
return Container(
child: SfCircularChart(
onCreateShader: (ChartShaderDetails chartShaderDetails) {
return Gradient.linear(chartShaderDetails.outerRect.topRight,
chartShaderDetails.outerRect.centerLeft, colors, stops);
},
series: <CircularSeries<_SalesData, String>>[
PieSeries<_SalesData, String>(
dataSource: chartData,
xValueMapper: (_SalesData sales, _) => sales.year,
xValueMapper: (_SalesData sales, _) => sales.year,
)
]
));
}
{% endhighlight %}
![shader linear](images/circular-customization/pie_linear.jpg)
#### Sweep gradient
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCircularChart(
onCreateShader: (ChartShaderDetails chartShaderDetails) {
return Gradient.sweep(
chartShaderDetails.outerRect.center,
colors,
stops,
TileMode.clamp,
_degreeToRadian(0),
_degreeToRadian(360),
_resolveTransform(chartShaderDetails.outerRect, TextDirection.ltr)
);
},
series: <CircularSeries<_SalesData, String>>[
RadialBarSeries<_SalesData, String>(
dataSource: chartData,
xValueMapper: (_SalesData sales, _) => sales.year,
xValueMapper: (_SalesData sales, _) => sales.year,
)
]
));
}
// Rotate the sweep gradient according to the start angle
Float64List _resolveTransform(Rect bounds, TextDirection textDirection) {
final GradientTransform transform = GradientRotation(_degreeToRadian(-90));
return transform.transform(bounds, textDirection: textDirection)!.storage;
}
// Convert degree to radian
double _degreeToRadian(int deg) => deg * (3.141592653589793 / 180);
{% endhighlight %}
![shader sweep](images/circular-customization/radialbar_sweep.jpg)
#### Radial gradient
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Container(
child: SfCircularChart(
onCreateShader: (ChartShaderDetails chartShaderDetails) {
return Gradient.radial(
chartShaderDetails.outerRect.center,
chartShaderDetails.outerRect.right - chartShaderDetails.outerRect.center.dx,
colors,
stops
);
},
series: <CircularSeries<_SalesData, String>>[
DoughnutSeries<_SalesData, String>(
dataSource: chartData,
xValueMapper: (_SalesData sales, _) => sales.year,
xValueMapper: (_SalesData sales, _) => sales.year,
)
]
));
}
{% endhighlight %}
![shader radial](images/circular-customization/doughnut_radial.jpg)
### Image fill
The data points of pie, doughnut and radial bar charts can also be filled with image by returning [`ImageShader`](https://api.flutter.dev/flutter/dart-ui/ImageShader-class.html) with required parameters.
{% highlight dart %}
/// Package import
import 'dart:async';
import 'dart:ui' as ui;
ui.Image? image;
Future<void> getImage() async {
const ImageProvider imageProvider = AssetImage('assets/apple.png');
final Completer<ImageInfo> completer = Completer<ImageInfo>();
imageProvider.resolve(const ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info, bool _) {
completer.complete(info);
}));
final ImageInfo imageInfo = await completer.future;
image = imageInfo.image;
isLoadedImage = true;
}
@override
Widget build(BuildContext context) {
getImage();
return Container(
child: SfCircularChart(
onCreateShader: (ChartShaderDetails chartShaderDetails) {
return ImageShader(
ui.image!,
TileMode.mirror,
TileMode.mirror,
Matrix4.identity().scaled(0.4).storage
);
},
series: <CircularSeries<_SalesData, String>>[
PieSeries<_SalesData, String>(
dataSource: chartData,
xValueMapper: (_SalesData sales, _) => sales.year,
xValueMapper: (_SalesData sales, _) => sales.year,
)
]
));
}
{% endhighlight %}
![Image shader](images/circular-customization/pie_imageshader.jpg)
## Shader mapping for data points
The [`pointShaderMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/pointShaderMapper.html) property is used to map the shader field from the chart data source. You can map different [`gradient`](https://api.flutter.dev/flutter/dart-ui/Gradient-class.html) types and [`image shader`](https://api.flutter.dev/flutter/dart-ui/ImageShader-class.html) for individual data points using this mapper callback.
{% highlight dart %}
/// Package import
import 'dart:async';
import 'dart:ui' as ui;
ui.Image? image1;
ui.Image? image2;
ui.Image? image3;
ui.Image? image4;
// To get the images from asset folder
void getImage() async {
final Completer<ImageInfo> completer = Completer();
final ImageProvider imageProvider = AssetImage('images/apple.png');
imageProvider.resolve(const ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info, bool _) async {
completer.complete(info);
final ImageInfo imageInfo = await completer.future;
image1 = imageInfo.image;
}));
final Completer<ImageInfo> completer1 = Completer();
final ImageProvider imageProvider1 = AssetImage('images/orange.png');
imageProvider1.resolve(const ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info, bool _) async {
completer1.complete(info);
final ImageInfo imageInfo1 = await completer1.future;
image2 = imageInfo1.image;
}));
final Completer<ImageInfo> completer2 = Completer();
final ImageProvider imageProvider2 = AssetImage('images/pears.png');
imageProvider2.resolve(const ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info, bool _) async {
completer2.complete(info);
final ImageInfo imageInfo2 = await completer2.future;
image3 = imageInfo2.image;
}));
final Completer<ImageInfo> completer3 = Completer();
final ImageProvider imageProvider3 = AssetImage('images/other_fruits.png');
imageProvider3.resolve(const ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info, bool _) async {
completer3.complete(info);
final ImageInfo imageInfo4 = await completer3.future;
image4 = imageInfo4.image;
if (mounted) {
setState(() {});
}
}));
}
Widget? renderWidget;
@override
Widget build(BuildContext context) {
getImage();
if (image1 != null && image2 != null && image3 != null && image4 != null) {
renderWidget = SfCircularChart(
title: ChartTitle(text: 'Sales comparison of fruits in a shop'),
series: <PieSeries<_ChartShaderData, String>>[
PieSeries<_ChartShaderData, String>(
dataSource: <_ChartShaderData>[
_ChartShaderData(
'Apple',
25,
'25%',
ui.ImageShader(
image1!,
TileMode.repeated,
TileMode.repeated,
Matrix4.identity().scaled(0.5).storage,
),
),
_ChartShaderData(
'Orange',
35,
'35%',
ui.ImageShader(
image2!,
TileMode.repeated,
TileMode.repeated,
Matrix4.identity().scaled(0.6).storage,
),
),
_ChartShaderData(
'Pears',
22,
'22%',
ui.ImageShader(
image3!,
TileMode.repeated,
TileMode.repeated,
Matrix4.identity().scaled(0.6).storage,
),
),
_ChartShaderData(
'Others',
18,
'18%',
ui.ImageShader(
image4!,
TileMode.repeated,
TileMode.repeated,
Matrix4.identity().scaled(0.5).storage,
),
),
],
strokeColor: Colors.black.withOpacity(0.5),
strokeWidth: 1.5,
explodeAll: true,
explodeOffset: '3%',
explode: true,
xValueMapper: (_ChartShaderData data, _) => data.x,
yValueMapper: (_ChartShaderData data, _) => data.y,
dataLabelMapper: (_ChartShaderData data, _) => data.text,
// mapped the shader data from the chart's data source
pointShaderMapper: (_ChartShaderData data, _, Color color, Rect rect) => data.shader,
radius: '83%',
),
],
);
} else {
getImage();
renderWidget = Center(child: CircularProgressIndicator());
}
return Scaffold(
body: renderWidget!
);
}
class _ChartShaderData {
_ChartShaderData(this.x, this.y, this.text, this.shader);
final String x;
final num y;
final String text;
final Shader shader;
}
{% endhighlight %}
![Image pointshadermapper](images/circular-customization/pie_pointshadermapper.jpg)
## Point render mode
The [`pointRenderMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/pointRenderMode.html) property is used to define the painting mode for the data points. The data points in the pie and doughnut chart can be filled either with solid colors or with sweep gradient by using this property. This property is not applicable for [`RadialBarSeries`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/RadialBarSeries-class.html).
* If `PointRenderMode.segment` is specified, the data points are filled with solid colors from the palette or with the colors mentioned in [`pointColorMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/pointColorMapper.html) property.
* If `PointRenderMode.gradient` is specified, a sweep gradient is formed with the solid colors and fills the data points.
N> This property is applicable only if the [`onCreateShader`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCircularChart/onCreateShader.html) and [`pointShaderMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/pointShaderMapper.html) are null.
{% highlight dart %}
@override
Widget build(BuildContext context) {
getImage();
return Container(
child: SfCircularChart(
series: <CircularSeries<_SalesData, String>>[
PieSeries<_SalesData, String>(
dataSource: chartData,
// Sweep gradient will be formed with default palette colors.
pointRenderMode: PointRenderMode.gradient,
xValueMapper: (_SalesData sales, _) => sales.year,
xValueMapper: (_SalesData sales, _) => sales.year,
)
]
)
);
}
{% endhighlight %}
![Image pointshadermapper](images/circular-customization/pie_rendermode.jpg)
## Dynamic animation
[`SfCircularChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCircularChart-class.html) also provide the dynamic animation support for the series. The series can be dynamically added to the charts, it will animated by setting the timer value. when you set the [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/animationDuration.html) value to 0, the series won't be animated.
## Empty points
The data points that has null value are considered as empty points. Empty data points are ignored and not plotted in the chart. By using [`emptyPointSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/emptyPointSettings.html) property in series, you can decide the action taken for empty points. Available [`modes`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html) are [`gap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html), [`zero`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html), [`drop`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html) and [`average`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html). Default mode of the empty point is [`gap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('David', null),
ChartData('Steve', 38),
ChartData('Jack', 34),
ChartData('Others', 52)
];
return Scaffold(
body: Center(
child: SfCircularChart(
series: <CircularSeries<ChartData,String>>[
// Render pie chart
PieSeries<ChartData, String>(
dataSource: chartData,
dataLabelSettings: DataLabelSettings(isVisible:true),
emptyPointSettings:
EmptyPointSettings(mode: EmptyPointMode.average),
pointColorMapper:(ChartData data, _) => data.color,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,)
]
)
)
);
}
{% endhighlight %}
![Empty points](images/circular-customization/emptyPoints.jpg)
### Empty point customization
Specific color for empty point can be set by [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/color.html) property in [`emptyPointSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/emptyPointSettings.html). The [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/borderWidth.html) property is used to change the stroke width of the empty point and [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/borderColor.html) is used to change the stroke color of the empty point.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('David', null),
ChartData('Steve', 38),
ChartData('Jack', 34),
ChartData('Others', 52)
];
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
series: <CircularSeries<ChartData, String>>[
PieSeries<ChartData, String>(
dataSource: chartData,
dataLabelSettings: DataLabelSettings(isVisible: true),
emptyPointSettings: EmptyPointSettings(
mode: EmptyPointMode.average,
color: Colors.red,
borderColor: Colors.black,
borderWidth: 2),
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y)
]
)
)
)
);
}
{% endhighlight %}
![Empty points customization](images/circular-customization/emptyPointcustomization.jpg)
## Sorting
The charts data source can be sorted using the [`sortingOrder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/sortingOrder.html) and [`sortFieldValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/sortFieldValueMapper.html) properties of series. The [`sortingOrder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SortingOrder-class.html) property specifies the data points in the series can be sorted in [`ascending`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SortingOrder-class.html) or [`descending`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SortingOrder-class.html) order. The data points will be rendered in the specified order if [`sortingOrder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/sortingOrder.html) is set to [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SortingOrder-class.html). The [`sortFieldValueMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/sortFieldValueMapper.html) specifies the field in the data source, which is considered for sorting the data points.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('David', 25),
ChartData('Steve', 38),
ChartData('Jack', 34),
ChartData('Others', 52)
];
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
series: <CircularSeries<ChartData,String>>[
// Render pie chart
PieSeries<ChartData, String>(
dataSource: chartData,
dataLabelSettings: DataLabelSettings(isVisible:true),
sortingOrder: SortingOrder.ascending,
sortFieldValueMapper: (ChartData data, _) => data.x,
pointColorMapper:(ChartData data, _) => data.color,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
animationDuration: 1000
)]))));
}
{% endhighlight %}
![Sorting](images/circular-customization/sortings.jpg)
#### See Also
* [Creating a circular drilldown chart using SfCircular charts](https://www.syncfusion.com/kb/11640/how-to-drilldown-with-syncfusion-flutter-chart-widget-sfcircularchart)

Просмотреть файл

@ -0,0 +1,428 @@
---
layout: post
title: Data label in Flutter Circular Charts widget | Syncfusion
description: Learn here all about Data label feature of Syncfusion Flutter Circular Charts (SfCircularChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Data label in Flutter Circular Charts (SfCircularChart)
Data label can be added to a chart series by enabling the [`isVisible`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/isVisible.html) property in the [`dataLabelSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/dataLabelSettings.html). You can use the following properties to customize the appearance.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/color.html) - used to change the background color of the data label shape.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderWidth.html) - used to change the stroke width of the data label shape.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderColor.html) - used to change the stroke color of the data label shape.
* [`alignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/alignment.html) - aligns the data label text to [`near`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html), [`center`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html) and [`far`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html).
* [`textStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/textStyle.html) - used to change the data label text color, size, font family, font style, and font weight.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/color.html) - used to change the color of the data label.
* [`fontFamily`](https://api.flutter.dev/flutter/painting/TextStyle/fontFamily.html) - used to change the font family for the data label.
* [`fontStyle`](https://api.flutter.dev/flutter/painting/TextStyle/fontStyle.html) - used to change the font style for the data label.
* [`fontWeight`](https://api.flutter.dev/flutter/painting/TextStyle/fontWeight.html) - used to change the font weight for the data label.
* [`fontSize`](https://api.flutter.dev/flutter/painting/TextStyle/fontSize.html) - used to change the font size for the data label.
* [`margin`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/margin.html) - used to change the margin size for data labels.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/opacity.html) - used to control the transparency of the data label.
* [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelAlignment.html) - used to align the Circular data label positions. The available options to customize the positions are [`outer`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`top`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`bottom`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) and [`middle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html).
* [`borderRadius`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderRadius.html) - used to add the rounded corners to the data label shape.
* [`angle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/angle.html) - used to rotate the labels.
* [`offset`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/offset.html) - used to movethedata label vertically or horizontally from its position.
* [`showCumulativeValues`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/showCumulativeValues.html) - to show the cumulative values in stacked type series charts.
* [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) - action on data labels intersection. The intersecting data labels can be hidden.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
series: <CircularSeries>[
PieSeries<ChartData, double>(
dataSource: chartData,
pointColorMapper: (ChartData data, _) => data.color,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
// Renders the data label
isVisible: true
)
)
]
)
)
)
);
}
{% endhighlight %}
![DataLabel](images/datalabel/default_datalabel.jpg)
## Formatting label content
Data label considers the format used in the Circular series by default. In the below code snippet, we have specified format for the data label in the [`dataLabelMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/dataLabelMapper.html) and you can see that the same format is applied to the data label.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
series: <CircularSeries>[
PieSeries<ChartData, double>(
dataSource: [
// Bind data source
ChartData('Jan', 35, '35%'),
ChartData('Feb', 28, '28%'),
ChartData('Mar', 34, '34%'),
ChartData('Apr', 32, '32%'),
ChartData('May', 40, '40%')
],
color: Colors.red,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelMapper: (ChartData data, _) => data.text,
dataLabelSettings: DataLabelSettings(
isVisible: true
)
)
]
)
)
)
);
}
{% endhighlight %}
![DataLabel format](images/datalabel/datalabel_format.jpg)
## Positioning the labels
The [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) property is used to position the Circular chart type data labels at [`top`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`bottom`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`outer`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) and [`middle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) position of the actual data point position. By default, labels are [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) positioned. You can move the labels horizontally and vertically using OffsetX and OffsetY properties respectively.
The [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) property is used to place the circular series data labels either [`inside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html) or [`outside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html). By default the label of circular chart is placed [`inside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html) the series.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
series: <CircularSeries>[
PieSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
isVisible: true,
// Positioning the data label
labelPosition: ChartDataLabelPosition.outside
)
)
]
)
)
)
);
}
{% endhighlight %}
![Data label position](images/datalabel/datalabel_position.jpg)
N> The [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelAlignment.html) property is used to position the Cartesian chart labels whereas [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) property is used to position the circular chart labels.
## Smart labels
This feature is used to arrange the data labels smartly and avoid the intersection when there is overlapping of labels. The enum property called the [`shift`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html) in [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) is used to arrange the data labels smartly when labels get intersect. By default, the label intersection action property is [`shift`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html).
If the [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) is [`inside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) and the [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) is [`shift`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html), then the overlapped labels will shift to outside the slices and arrange smartly. If the [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) is [`inside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) and the [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) is [`hide`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html), then the overlapped labels will be hidden.
If the [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) is [`outside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) and the [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) is [`shift`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html), then the overlapped labels arrange smartly. If the [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) is [`outside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) and the [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) is [`hide`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html), then the overlapped labels will be hidden.
If the [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) is [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html), then the overlapped labels will be visible irrespective of [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html).
When the [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) is [`shift`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html), and if the data label goes out of the chart area, then the labels got trimmed and the tooltip is shown when clicking/tapping the data label. The values of the [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) are listed below.
* [`hide`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html) - hides the intersected data labels.
* [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html) - intersected data labels will be visible.
* [`shift`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/LabelIntersectAction-class.html) - smartly arranges the overlapped data labels.
N> The smart label positioning is applicable only for the pie and doughnut series.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = <ChartData>[
ChartData(x: 'USA', y: 46),
ChartData(x: 'Great Britain', y: 27),
ChartData(x: 'China', y: 26),
ChartData(x: 'Russia', y: 19),
ChartData(x: 'Germany', y: 17),
ChartData(x: 'Japan', y: 12),
ChartData(x: 'France', y: 10),
ChartData(x: 'Korea', y: 9),
ChartData(x: 'Italy', y: 8),
ChartData(x: 'Australia', y: 8),
ChartData(x: 'Netherlands', y: 8),
ChartData(x: 'Hungary', y: 8),
ChartData(x: 'Brazil', y: 7),
ChartData(x: 'Spain', y: 7),
ChartData(x: 'Kenya', y: 6),
ChartData(x: 'Jamaica', y: 6),
ChartData(x: 'Croatia', y: 5),
ChartData(x: 'Cuba', y: 5),
ChartData(x: 'New Zealand', y: 4)
];
return SfCircularChart(
series: <CircularSeries<ChartData, String>>[
PieSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelMapper: (ChartData data, _) => data.x,
radius: '60%',
dataLabelSettings: DataLabelSettings(
isVisible: true,
// Avoid labels intersection
labelIntersectAction: LabelIntersectAction.shift,
labelPosition: ChartDataLabelPosition.outside,
connectorLineSettings: ConnectorLineSettings(
type: ConnectorType.curve, length: '25%')
)
)
]);
}
class ChartData {
ChartData({this.x, this.y});
final String? x;
final num? y;
}
{% endhighlight %}
![Smart labels](images/datalabel/smart_datalabel.jpg)
## Apply series color
The [`useSeriesColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/useSeriesColor.html) property is used to apply the series color to background color of the data labels. The default value of this property is `false`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child:SfCircularChart(
series: <CircularSeries>[
PieSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelMapper: (ChartData data, _) => data.x,
dataLabelSettings: DataLabelSettings(
isVisible: true,
labelPosition: ChartDataLabelPosition.outside,
// Renders background rectangle and fills it with series color
useSeriesColor: true
)
)
]
)
)
)
);
}
{% endhighlight %}
![Series color](images/datalabel/use_series_color.jpg)
## Connector line
This feature is used to connect label and data point using a line. It is applicable only for [`Pie`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/PieSeries-class.html) and [`Doughnut`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DoughnutSeries-class.html) chart types. The [`connectorLineSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/connectorLineSettings.html) property can be used to customize the connector line.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorLineSettings/color.html) - used to change the color of the line
* [`width`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorLineSettings/width.html) - used to change the stroke thickness of the line
* [`length`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorLineSettings/length.html) - specifies the length of the connector line.
* [`type`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorLineSettings/type.html) - specifies the shape of connector line either [`curve`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorType-class.html) or [`line`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorType-class.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
series: <CircularSeries>[
PieSeries<ChartData, double>(
enableSmartLabels: true,
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
isVisible: true,
labelPosition: ChartDataLabelPosition.outside,
connectorLineSettings: ConnectorLineSettings(
// Type of the connector line
type: ConnectorType.curve
)
)
)
]
)
)
)
);
}
{% endhighlight %}
![Connector line](images/datalabel/connector_line.jpg)
## Point text mapping
The [`dataLabelMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/dataLabelMapper.html) property is used to map the text from data source.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('USA', 17, '17%'),
ChartData('China', 34, '34%'),
ChartData('Japan', 24, '24%'),
ChartData('Africa', 30, '30%'),
ChartData('UK', 10, '10%')
];
return Scaffold(
body: Center(
child: Container(
child:SfCircularChart(
series: <CircularSeries>[
PieSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
// Map the data label text for each point from the data source
dataLabelMapper: (ChartData data, _) => data.text,
dataLabelSettings: DataLabelSettings(
isVisible: true
)
)
]
)
)
)
);
}
class ChartData {
ChartData(this.x, this.y, this.text);
final String x;
final double y;
final String text;
}
{% endhighlight %}
![Data label mapper](images/datalabel/value_mapper.jpg)
## Templating the labels
You can customize the appearance of the data label with your own template using the [`builder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/builder.html) property of [`dataLabelSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/dataLabelSettings.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child:SfCircularChart(
series: <CircularSeries>[
PieSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelMapper: (ChartData data, _) => data.text,
dataLabelSettings: DataLabelSettings(
isVisible: true,
// Templating the data label
builder: (dynamic data, dynamic point, dynamic series, int pointIndex, int seriesIndex) {
return Container(
height: 30,
width: 30,
child: Image.asset('images/livechart.png')
);
}
)
)
]
)
)
)
);
}
{% endhighlight %}
![Label template](images/datalabel/datalabel_template.jpg)
## Hide data label for 0 value
Data label and its connector line in the Circular charts for the point value 0 can be hidden using the [`showZeroValue`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/showZeroValue.html) property. This defaults to `true`.
{% highlight dart %}
final List<SalesData> chartData = <SalesData>[
SalesData('Jan', 35),
SalesData('Feb', 28),
SalesData('March', 0),
SalesData('April', 32),
SalesData('May', 40)
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child:SfCircularChart(
series: <CircularSeries<SalesData, String>>[
PieSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.xValue,
yValueMapper: (SalesData sales, _) => sales.yValue,
dataLabelSettings: DataLabelSettings(
showZeroValue : false,
isVisible: true
)
)
],
)
)
)
);
}
{% endhighlight %}
![datalabel0value](images/datalabel/datalabel_0_value.png)
## Data label saturation color
If the user didnt provide text color to the data label, then by default, the saturation color is applied to the data label text. i.e., if the data points background color intensity is dark, then the data label will render in white color (#FFFFFF) and if the data points background color intensity is light, data label will render in black color (#000000).
![label_saturation](images/datalabel/circular_saturation.png)

Двоичные данные
Flutter/circular-charts/images/datalabel/smart_datalabel.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 44 KiB

Просмотреть файл

@ -0,0 +1,342 @@
---
layout: post
title: Methods in Flutter Circular Charts widget | Syncfusion
description: Learn here all about available Methods of Syncfusion Flutter Circular Charts (SfCircularChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Methods in Flutter Circular Charts (SfCircularChart)
## Methods in tooltipBehavior
### Show method in tooltipBehavior
The [`show`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/show.html) method is used to activate the tooltip at the specified x and y point values.
{% highlight dart %}
late SfCircularChart chart;
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData(10, 17),
ChartData(20, 34),
// Add the required data
];
chart = SfCircularChart(
tooltipBehavior: _tooltipBehavior,
series: <CircularSeries>[
ColumnSeries<ChartData, double>(
enableTooltip: true,
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y)
]
);
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
TextButton(
child: Text('Show'),
onPressed: show
),
Container(child: chart)
]
)
)
);
}
void show() {
_tooltipBehavior.show(10, 17);
}
{% endhighlight %}
### showByIndex method in tooltipBehavior
The [`showByIndex`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/showByIndex.html) method is used to display the tooltip at the specified series and point index.
The below mentioned arguments are given to the [`showByIndex`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/showByIndex.html) method:
[`seriesIndex`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipArgs/seriesIndex.html) - index of the series for which the pointIndex is specified.
[`pointIndex`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipArgs/pointIndex.html) - index of the point for which the tooltip should be shown.
{% highlight dart %}
late SfCircularChart chart;
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData(10, 17),
ChartData(20, 34),
// Add the required data
];
chart = SfCircularChart(
tooltipBehavior: _tooltipBehavior,
series: <CircularSeries>[
ColumnSeries<ChartData, double>(
enableTooltip: true,
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y)
]
);
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
TextButton(
child: Text('Show'),
onPressed:(){
_tooltipBehavior.showByIndex(0,1);
}
),
Container(child: chart)
]
)
)
);
}
{% endhighlight %}
### showByPixel method in tooltipBehavior
The [`showByPixel`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/showByPixel.html) method is used to display the tooltip at the specified x and y-positions.
x & y - logical pixel values to position the tooltip.
{% highlight dart %}
late SfCircularChart chart;
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData(10, 17),
ChartData(20, 34),
// Add the required data
];
chart = SfCircularChart(
tooltipBehavior: _tooltipBehavior,
series: <CircularSeries>[
ColumnSeries<ChartData, double>(
enableTooltip: true,
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y)
]
);
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
TextButton(
child: Text('Show'),
onPressed:(){
_tooltipBehavior.showByPixel(230.0,470.0);
}
),
Container(child: chart)
]
)
)
);
}
{% endhighlight %}
### Hide method in tooltipBehavior
The [`hide`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/hide.html) method is used to hide the displaying tooltip programmatically.
{% highlight dart %}
late SfCircularChart chart;
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData(10, 17),
ChartData(20, 34)
// Add the required data
];
chart = SfCircularChart(
tooltipBehavior: _tooltipBehavior,
series: <CircularSeries>[
ColumnSeries<ChartData, double>(
enableTooltip: true,
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y)
]
);
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
TextButton(
child: Text('Hide'),
onPressed: hide
),
Container(child: chart)
]
)
)
);
}
void hide(){
_tooltipBehavior.hide();
}
{% endhighlight %}
## Methods in selectionBehavior
### SelectDataPoints method in selectionBehavior
The [`selectDataPoints`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SelectionBehavior/selectDataPoints.html) method is used to select the data point programmatically. The required arguments are listed below.
* `pointIndex` - index of the point which needs to be selected.
* `seriesIndex` - index of the series for which the pointIndex is specified and this is an optional parameter. By default it will be considered as 0.
N> The [`enableMultiSelection`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCircularChart/enableMultiSelection.html) is also applicable for this but, it is based on the API values specified in the chart.
{% highlight dart %}
late SfCircularChart chart;
late SelectionBehavior _selectionBehavior;
@override
void initState(){
_selectionBehavior = SelectionBehavior(enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData(10, 17),
ChartData(20, 34)
// Add the required data
];
chart = SfCircularChart(
series: <CircularSeries>[
PieSeries<ChartData, double>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
selectionBehavior: _selectionBehavior
)
]
);
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
TextButton(
child: Text('Select'),
onPressed: select
),
Container(child: chart)
]
)
)
);
}
void select() {
_selectionBehavior.selectDataPoints(1, 0);
}
{% endhighlight %}
## PixelToPoint
Converts logical pixel value to the data point value.
The `pixelToPoint` method takes logical pixel value as input and returns a chart data point.
N> The method will return the center value of the segment.
{% highlight dart %}
//Initialize the series controller
CircularSeriesController? seriesController;
@override
Widget build(BuildContext context) {
return Container(
child: SfCircularChart(
series: <PieSeries<ChartData, String>>[
PieSeries<ChartData, String>(
onRendererCreated: (CircularSeriesController controller) {
seriesController = controller;
},
)
],
onChartTouchInteractionUp: (ChartTouchInteractionArgs args) {
final Offset value = Offset(args.position.dx, args.position.dy);
ChartPoint<dynamic>? chartpoint = seriesController?.pixelToPoint(value);
}
)
);
}
class ChartData{
ChartData(this.x, this.y);
final String x;
final double y;
}
{% endhighlight %}

Просмотреть файл

@ -0,0 +1,257 @@
---
layout: post
title: Tooltip in Flutter Circular Charts widget | Syncfusion
description: Learn here all about Tooltip feature of Syncfusion Flutter Circular Charts (SfCircularChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Tooltip in Flutter Circular Charts (SfCircularChart)
Chart provides tooltip support for all the series. It is used to show information about the segment, when you tap on the segment. To enable the tooltip, you need to set [`enableTooltip`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/CircularSeries/enableTooltip.html) property as `true`.
The tooltip state will be preserved on the device's orientation change and on browser resize. For example, if the tooltip's [`duration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/duration.html) is set to 10,000ms, and when you change the orientation of your device from portrait to landscape after 5,000ms of tooltip display, the tooltip will be displayed for the next 5,000ms in landscape mode before disappearing.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
//Enables the tooltip for all the series
tooltipBehavior: _tooltipBehavior,
series: <CircularSeries>[
PieSeries<ChartData, double>(
//Enables the tooltip for individual series
enableTooltip: true,
)
]
)
)
)
);
}
{% endhighlight %}
![Tooltip](images/tooltip/default_tooltip.jpg)
## Customizing the appearance
You can use the following properties to customize the tooltip appearance.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/color.html) - used to change the background color of tooltip.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/borderWidth.html) - used to change the stroke width of the tooltip.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/borderColor.html) - used to change the stroke color of the tooltip.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/opacity.html) - used to control the transparency of the tooltip.
* [`duration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/duration.html) - specifies the duration for displaying the tooltip that defaults to `3000`.
* [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/animationDuration.html) - specifies the duration for animating the tooltip that default to 350.
* [`elevation`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/elevation.html) - specifies the elevation of tooltip.
* [`canShowMarker`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/canShowMarker.html) - toggles the visibility of the marker in the tooltip.
* [`header`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/header.html) - specifies the header for tooltip. By default, the series name will be displayed in the header.
* [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) - formats the tooltip text. By default, the tooltip will be rendered with x and y-values. You can add prefix or suffix to x, y, and series name values in the tooltip by formatting them.
* [`shadowColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shadowColor.html) - specifies the color of the tooltip shadow.
* [`shouldAlwaysShow`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shouldAlwaysShow.html) - used to shows or hides the tooltip.
* [`textAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/textAlignment.html) - alignment of the text in the tooltip.
* [`decimalPlaces`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/decimalPlaces.html) - used to specify the number decimals to be displayed in tooltip text.
* [`shared`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shared.html) - used to share the tooltip with same index points.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
borderColor: Colors.red,
borderWidth: 5,
color: Colors.lightBlue);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![Customized tooltip](images/tooltip/customized_tooltip.jpg)
## Label format
By default, x and y value will be displayed in the tooltip, and it can be customized using [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) property as depicted in the below code snippet. You can show the below values in the tooltip. Also you can add prefix or suffix to these values.
* X value - `point.x`
* Y value - `point.y`
* Bubble size - `point.size`
* Name of the series - `series.name`
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Formatting the tooltip text
format: 'point.y%'
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircualrChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
## Tooltip positioning
The tooltip can be made to display in the fixed location or at the pointer location itself using the `tooltipPosition` property. This defaults to `auto`.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
tooltipPosition: TooltipPosition.pointer
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![pointer tooltip](images/tooltip/tooltip_pointer.jpg)
## Tooltip template
You can customize the appearance of the tooltip with your own widget by using the [`builder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/builder.html) property of [`tooltipBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfCircularChart/tooltipBehavior.html).
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Templating the tooltip
builder: (dynamic data, dynamic point, dynamic series,
int pointIndex, int seriesIndex) {
return Container(
child: Text(
'PointIndex : ${SeriesIndex.toString()}'
)
);
}
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![Tooltip template](images/tooltip/tooltip_template.jpg)
## Activation mode
The [`activationMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/activationMode.html) property is used to restrict the visibility of tooltip based on the touch actions. The default value of this property is [`ActivationMode.singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html).
The ActivationMode enum contains the following values:
* [`longPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing the long press action.
* [`singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing single tap action.
* [`doubleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing double tap action.
* [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - hides the visibility of tooltip when setting activation mode to none.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Tooltip will be displayed on long press
activationMode: ActivationMode.longPress
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfCircularChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
Also refer [tooltip event](./events#ontooltiprender) for customizing the tooltip further.

Просмотреть файл

@ -0,0 +1,514 @@
---
layout: post
title: Column in Flutter DataGrid | DataTable | Syncfusion
description: Learn here all about how to add columns to Syncfusion Flutter DataGrid (SfDataGrid) control and more.
platform: flutter
control: SfDataGrid
documentation: ug
---
# Column Types in Flutter DataGrid (SfDataGrid)
[SfDataGrid](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid-class.html) provides support for load any type of widget in each column.
## GridColumn
GridColumn is a class that provides base functionalities for all the column types in `SfDataGrid`.
### Mapping column to a property
Column can be bound to a property in data object using [GridColumn.columnName](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/GridColumn/columnName.html) property. [label](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/GridColumn/label.html) is used to display the required widget in a column header.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(source: _employeeDataSource, columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
)))
]));
}
{% endhighlight %}
{% endtabs %}
### Hiding a column
[GridColumn.visible](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/GridColumn/visible.html) property can be used to set a column as hidden. The default value of the `visible` property is true.
>**NOTE**
Set the `visible` property to `false` instead of setting column width as `0` to hide a column.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(source: _employeeDataSource, columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'designation',
visible: false,
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
)))
]));
}
{% endhighlight %}
{% endtabs %}
### Set manual width for column
`SfDataGrid` allows you to customize the width of each [GridColumn](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/GridColumn-class.html) in the [SfDataGrid.Columns](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/columns.html) collection. To customize column width, use the [GridColumn.width](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/GridColumn/width.html) property. By default, this property will not be assigned any value. The GridColumn renders in view based on the value of the [defaultColumnWidth](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/defaultColumnWidth.html) property.
>**NOTE**
Set the `visible` property to `false` instead of setting column width as `0` to hide a column.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(source: _employeeDataSource, columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
width: 100.0,
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
)))
]));
}
{% endhighlight %}
{% endtabs %}
## Checkbox column
By setting the `showCheckboxColumn` property to `true`, you can select or deselect individual rows using checkboxes in each row. The checkbox column will be added as first column.
The selection is applied to row only if you set the [SfDataGrid.selectionMode](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/selectionMode.html) property other than `none`.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(
source: _employeeDataSource,
showCheckboxColumn: true,
selectionMode: SelectionMode.multiple,
columns: [
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
))),
]));
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid show checkbox column](images/column-types/flutter-datagrid-show-checkbox-column.png)
### Show text in header cell
You can display widgets along with the checkbox in the header cell by adding widget to the `SfDataGrid.checkboxColumnSettings.label` property.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(
source: _employeeDataSource,
showCheckboxColumn: true,
checkboxColumnSettings: DataGridCheckboxColumnSettings(
label: Text('Selector'), width: 100),
selectionMode: SelectionMode.multiple,
columns: [
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
))),
]));
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid shows text in checkbox column header](images/column-types/flutter-datagrid-shows-text-in-checkbox-column-header.png)
### Disable the checkbox in the header cell
By default, checkBox gets displayed in the header cell. By disabling the `SfDataGrid.checkboxColumnSettings.showCheckboxOnHeader` property, checkBox can be disappeared in the header cell.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(
source: _employeeDataSource,
showCheckboxColumn: true,
checkboxColumnSettings:
DataGridCheckboxColumnSettings(showCheckboxOnHeader: false),
selectionMode: SelectionMode.multiple,
columns: [
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
))),
]));
}
{% endhighlight %}
{% endtabs %}
![checkbox is disabled in checkbox column header in flutter datagrid](images/column-types/checkbox-is-disabled-in-checkbox-column-header-in-flutter-datagrid.png)
### Change the background color of checkbox column
The background color of the checkbox column can be customized by using the `SfDataGrid.checkboxColumnSettings.backgroundColor` property.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(
source: _employeeDataSource,
showCheckboxColumn: true,
checkboxColumnSettings:
DataGridCheckboxColumnSettings(backgroundColor: Colors.yellow),
selectionMode: SelectionMode.multiple,
columns: [
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
))),
]));
}
{% endhighlight %}
{% endtabs %}
![background color in checkbox column in flutter datagrid](images/column-types/background-color-in-checkbox-column-in-flutter-datagrid.png)
### Get checked items
You can get the checked items by using the [DataGridController.selectedRows](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataGridController/selectedRows.html) property. Because, the selection and checkbox's checked state are the same.
{% tabs %}
{% highlight Dart %}
final DataGridController _dataGridController = DataGridController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: [
TextButton(
child: Text('Get Checked Items Information'),
onPressed: () {
//Index of the checked item
var _selectedIndex = _dataGridController.selectedIndex;
//CheckedRow
var _selectedRow = _dataGridController.selectedRow;
//Collection of checkedRows
var _selectedRows = _dataGridController.selectedRows;
print(_selectedIndex);
print(_selectedRow);
print(_selectedRows);
}),
Expanded(
child: SfDataGrid(
source: _employeeDataSource,
showCheckboxColumn: true,
controller: _dataGridController,
selectionMode: SelectionMode.multiple,
columns: [
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
))),
]))
]));
}
{% endhighlight %}
{% endtabs %}
### Limitations
The following are the limitations of GridCheckboxColumn:
* Checkbox column does not support data operations such as sorting.
* Checkbox column does not support to add the stacked headers along with other columns.
* Checkbox column will be excluded in exporting operations.

Просмотреть файл

@ -0,0 +1,477 @@
---
layout: post
title: Columns Resizing in Flutter DataGrid | Syncfusion | DataTable
description: Learn here all about how to resize a column in Syncfusion Flutter DataGrid (SfDataGrid) widget and more.
platform: flutter
control: SfDataGrid
documentation: ug
---
# Columns Resizing in Flutter DataGrid (SfDataGrid)
The [SfDataGrid](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid-class.html) provides support to resize the columns by dragging the right end of the column header. The column resizing can be enabled by setting the `SfDataGrid.allowColumnsResizing` property to `true`.
`SfDataGrid` does not automatically resize the columns when you perform column resizing. You should maintain the column width collection at the application level and set the column width of the corresponding column using the `SfDataGrid.onColumnResizeUpdate` callback.
The column resizing indicator comes to view based on the platform. In web and desktop platforms, the indicator appears when you hover over the right end of the column and drag it. In mobile platforms, the indicator comes into view when you long-press the corresponding column header.
> **NOTE:**
Column resizing considers the [GridColumn.minimumWidth](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/GridColumn/minimumWidth.html) and [GridColumn.maximumWidth](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/GridColumn/maximumWidth.html) properties.
{% tabs %}
{% highlight Dart %}
late Map<String, double> columnWidths = {
'id': double.nan,
'name': double.nan,
'designation': double.nan,
'salary': double.nan
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: _employeeDataSource,
allowColumnsResizing: true,
onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
setState(() {
columnWidths[details.column.columnName] = details.width;
});
return true;
},
columns: <GridColumn>[
GridColumn(
width: columnWidths['id']!,
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
width: columnWidths['name']!,
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
width: columnWidths['designation']!,
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
width: columnWidths['salary']!,
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid shows column resizing with onResize mode](images/columns-resizing/flutter-datagrid-resizing-onResize.gif)
## Column resizing modes
By default, the columns are resized by dragging the right end of the columns. `SfDataGrid` provided the two modes to perform the column resizing:
* `onResize`: The resizing indicator is moved based on the dragging gesture. `onColumnResizeUpdate` callback is called when a column is resized.
* `onResizeEnd`: The resizing indicator is moved based on the dragging gesture. `onColumnResizeUpdate` callback is called when you release the pointer.
The following example demonstrates how to resize a column by setting the `SfDataGrid.columnResizeMode` property to `onResizeEnd`.
{% tabs %}
{% highlight Dart %}
late Map<String, double> columnWidths = {
'id': double.nan,
'name': double.nan,
'designation': double.nan,
'salary': double.nan
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: _employeeDataSource,
allowColumnsResizing: true,
columnResizeMode: ColumnResizeMode.onResizeEnd,
onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
setState(() {
columnWidths[details.column.columnName] = details.width;
});
return true;
},
columns: <GridColumn>[
GridColumn(
width: columnWidths['id']!,
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
width: columnWidths['name']!,
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
width: columnWidths['designation']!,
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
width: columnWidths['salary']!,
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid shows column resizing with onResizeEnd mode](images/columns-resizing/flutter-datagrid-resizing-onResizeEnd.gif)
## Callbacks
The following callbacks are called when you perform the column resizing:
* `onColumnResizeStart`: Called when column resizing is started. In Mobile platforms, it will be called when the resizing indicator appears after you long-press the corresponding column header. In Web and Windows platforms, it will be called when you click and drag the right end of the columns.
* `onColumnResizeUpdate`: Called when a column is being resized. Typically, you should set the column width here.
* `onColumnResizeEnd`: Called when a column resizing is ended. Typically, this will be called when you release the pointer.
{% tabs %}
{% highlight Dart %}
late Map<String, double> columnWidths = {
'id': double.nan,
'name': double.nan,
'designation': double.nan,
'salary': double.nan
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: _employeeDataSource,
allowColumnsResizing: true,
onColumnResizeStart: (ColumnResizeStartDetails details) {
return true;
},
onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
setState(() {
columnWidths[details.column.columnName] = details.width;
});
return true;
},
onColumnResizeEnd: (ColumnResizeEndDetails details) {
print('Column resizing is ended for the ${details.column.columnName}');
},
columns: <GridColumn>[
GridColumn(
width: columnWidths['id']!,
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
width: columnWidths['name']!,
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
width: columnWidths['designation']!,
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
width: columnWidths['salary']!,
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
{% endhighlight %}
{% endtabs %}
## Disable resizing for a particular column
To disable resizing for a particular column, use the `SfDataGrid.onColumnResizeStart` callback and return `false` to the corresponding column. Return `true` for all other columns.
{% tabs %}
{% highlight Dart %}
late Map<String, double> columnWidths = {
'id': double.nan,
'name': double.nan,
'designation': double.nan,
'salary': double.nan
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: _employeeDataSource,
allowColumnsResizing: true,
onColumnResizeStart: (ColumnResizeStartDetails details) {
// Disable resizing for the `id` column.
if (details.column.columnName == 'id') {
return false;
}
return true;
},
onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
setState(() {
columnWidths[details.column.columnName] = details.width;
});
return true;
},
columns: <GridColumn>[
GridColumn(
width: columnWidths['id']!,
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
width: columnWidths['name']!,
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
width: columnWidths['designation']!,
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
width: columnWidths['salary']!,
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
{% endhighlight %}
{% endtabs %}
## Prevent column from being hidden on resizing
To prevent a column from being hidden while resizing, use the `GridColumn.minimumWidth` property to set the columns minimum width. The column will not be resized below the minimum width.
{% tabs %}
{% highlight Dart %}
late Map<String, double> columnWidths = {
'id': double.nan,
'name': double.nan,
'designation': double.nan,
'salary': double.nan
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: _employeeDataSource,
allowColumnsResizing: true,
onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
setState(() {
columnWidths[details.column.columnName] = details.width;
});
return true;
},
columns: <GridColumn>[
GridColumn(
width: columnWidths['id']!,
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
width: columnWidths['name']!,
minimumWidth: 30.0,
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
width: columnWidths['designation']!,
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
width: columnWidths['salary']!,
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
{% endhighlight %}
{% endtabs %}
## Customize indicator appearance
The column resizing indicator color and its width can be customized by using the `SfDataGridThemeData.columnResizeIndicatorColor` and `SfDataGridThemeData.columnResizeIndicatorStrokeWidth` properties.
{% tabs %}
{% highlight Dart %}
late Map<String, double> columnWidths = {
'id': double.nan,
'name': double.nan,
'designation': double.nan,
'salary': double.nan
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGridTheme(
data: SfDataGridThemeData(
columnResizeIndicatorColor: Colors.orange,
columnResizeIndicatorStrokeWidth: 2.0,
),
child: SfDataGrid(
source: _employeeDataSource,
allowColumnsResizing: true,
onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
setState(() {
columnWidths[details.column.columnName] = details.width;
});
return true;
},
columns: <GridColumn>[
GridColumn(
width: columnWidths['id']!,
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
width: columnWidths['name']!,
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
width: columnWidths['designation']!,
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
width: columnWidths['salary']!,
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
),
);
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid shows column resizing with onResize mode](images/columns-resizing/flutter-datagrid-resizing-indicator-customization.png)

Просмотреть файл

@ -0,0 +1,416 @@
---
layout: post
title: Export Flutter DataGrid to Excel | Flutter DataTable | Syncfusion
description: Learn here all about how to export the Syncfusion Flutter DataGrid (SfDataGrid) into the Excel and more.
platform: flutter
control: SfDataGrid
documentation: ug
---
# Export to Excel in Flutter DataGrid (SfDataGrid)
The [SfDataGrid](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid-class.html) provides support to export the content to the Excel with several customization options.
**Add dependency**
The following dependencies must be added to your pubspec.yaml file for exporting to the Excel.
{% highlight dart %}
dependencies:
syncfusion_flutter_datagrid_export: ^xx.x.xx
{% endhighlight %}
>**NOTE:** Here, **xx.x.xx** denotes the current version of `Syncfusion Flutter DataGrid Export` package.
**Import package**
Import the following package in your Dart code.
{% tabs %}
{% highlight Dart %}
import 'package:syncfusion_flutter_datagrid_export/export.dart';
import 'package:syncfusion_flutter_xlsio/xlsio.dart';
{% endhighlight %}
{% endtabs %}
You can export the `SfDataGrid` to the Excel by using the following extension methods present in the `SfDataGridState` class.
* `exportToExcelWorkbook`
* `exportToExcelWorksheet`
**Add GlobalKey for the DataGrid**
Create the [GlobalKey](https://api.flutter.dev/flutter/widgets/GlobalKey-class.html) using the [SfDataGridState](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGridState-class.html) class. Exporting related methods are available in the `SfDataGridState` class.
Set the created `GlobalKey` to the `SfDataGrid`.
{% tabs %}
{% highlight Dart %}
final GlobalKey<SfDataGridState> key = GlobalKey<SfDataGridState>();
{% endhighlight %}
{% endtabs %}
The following code illustrates how to create and export a `SfDataGrid` to the Excel using the global key.
{% tabs %}
{% highlight Dart %}
final GlobalKey<SfDataGridState> key = GlobalKey<SfDataGridState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'Syncfusion Flutter DataGrid Export',
overflow: TextOverflow.ellipsis,
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 50.0,
width: 150.0,
padding: const EdgeInsets.all(10.0),
child: MaterialButton(
color: Colors.blue,
child: const Center(
child: Text(
'Export to Excel',
style: TextStyle(color: Colors.white),
)),
onPressed: () async {
final Workbook workbook =
key.currentState!.exportToExcelWorkbook();
final List<int> bytes = workbook.saveAsStream();
workbook.dispose();
await helper.saveAndLaunchFile(bytes, 'DataGrid.xlsx');
}),
),
Expanded(
child: SfDataGrid(
key: key,
source: employeeDataSource,
columns: <GridColumn>[
GridColumn(
columnName: 'ID',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text(
'ID',
))),
GridColumn(
columnName: 'Name',
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.center,
child: const Text('Name'))),
GridColumn(
columnName: 'Designation',
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.center,
child: const Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'Salary',
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.center,
child: const Text('Salary'))),
],
),
),
],
),
);
}
{% endhighlight %}
{% endtabs %}
## Export DataGrid to Excel workbook
You can export the data to [Excel Workbook](https://pub.dev/documentation/syncfusion_flutter_xlsio/latest/xlsio/Workbook-class.html) by using the `exportToExcelWorkbook` method from the `key.currentState` of the DataGrid.
{% tabs %}
{% highlight Dart %}
final Workbook workbook = key.currentState!.exportToExcelWorkbook();
final List<int> bytes = workbook.saveAsStream();
File('DataGrid.xlsx').writeAsBytes(bytes, flush: true);
{% endhighlight %}
{% endtabs %}
## Export DataGrid to Excel sheet
You can export the data to [Excel Worksheet](https://pub.dev/documentation/syncfusion_flutter_xlsio/latest/xlsio/Worksheet-class.html) by using the `exportToExcelWorksheet` method from `key.currentState` of the DataGrid.
{% tabs %}
{% highlight Dart %}
final Workbook workbook = Workbook();
final Worksheet worksheet = workbook.worksheets[0];
key.currentState!.exportToExcelWorksheet(worksheet);
final List<int> bytes = workbook.saveAsStream();
File('DataGrid.xlsx').writeAsBytes(bytes, flush: true);
{% endhighlight %}
{% endtabs %}
## Exporting options
### Exclude columns when exporting
By default, all the columns in the `SfDataGrid` is exported to Excel. To exclude certain columns when exporting to Excel, add those column names to the `excludeColumns` parameter.
{% tabs %}
{% highlight Dart %}
Workbook workbook = key.currentState!
.exportToExcelWorkbook(excludeColumns: ['Name']);
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
![excel shows the grid with exclude columns](images/export-to-excel/flutter-datagrid-excel-export-exclude-columns.png)
### Exclude table summaries when exporting
By default, table summaries in `SfDataGrid` is exported to Excel. You can set `exportTableSummaries` parameter as `false` to export the `SfDataGrid` without table summaries.
{% tabs %}
{% highlight Dart %}
Workbook workbook = key.currentState!
.exportToExcelWorkbook(exportTableSummaries: false);
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
### Exclude stacked headers when exporting
By default, stacked headers in `SfDataGrid` is exported to Excel. You can set `exportStackedHeaders` parameter as `false` to export the `SfDataGrid` without stacked headers.
{% tabs %}
{% highlight Dart %}
Workbook workbook = key.currentState!
.exportToExcelWorkbook(exportStackedHeaders: false);
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
### Change start row and column index when exporting
By default, the DataGrid is exported from (0,0) index in Excel sheet. You can export the data from specific row and column index in Excel worksheet by setting the `startColumnIndex` and `startRowIndex` properties.
{% tabs %}
{% highlight Dart %}
Workbook workbook = key.currentState!
.exportToExcelWorkbook(startRowIndex: 3, startColumnIndex: 2);
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
## Export the selected rows to Excel
By default, the entire grid is exported to Excel. You can export selected rows only by passing `dataGridController.selectedRows` to `rows` parameter in `exportToExcelWorksheet` and `exportToExcelWorkbook` methods.
{% tabs %}
{% highlight Dart %}
Workbook workbook = key.currentState!
.exportToExcelWorkbook(rows: dataGridController.selectedRows);
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
## Row height and column width customization
By default, [SfDataGrid.rowHeight](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/rowHeight.html) and [SfDataGrid.defaultColumnWidth](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/defaultColumnWidth.html) properties will be set to the cells in the Excel sheet. To customize the row height and column width in Excel, you can use the `defaultRowHeight` and `defaultColumnWidth` properties. But these properties are only applicable when the `exportRowHeight` and `exportColumnWidth` properties are `false`.
If the `exportRowHeight` and `exportColumnWidth` properties are `true`, the `SfDataGrid.headerRowHeight` and `SfDataGrid.rowHeight` properties are considered for row heights in Excel and the actual width of the column is considered for columns in Excel.
{% tabs %}
{% highlight Dart %}
Workbook workbook = key.currentState!.exportToExcelWorkbook(
exportRowHeight: false,
exportColumnWidth: false,
defaultRowHeight: 35,
defaultColumnWidth: 120);
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
## Styling cells based on the cell type in Excel
You can customize the cell styles based on cell type using `cellExport` parameter which is a callback in `exportToExcelWorkbook` and `exportToExcelWorksheet` methods.
{% tabs %}
{% highlight Dart %}
final Workbook workbook = key.currentState!.exportToExcelWorkbook(
cellExport: (DataGridCellExcelExportDetails details) {
if (details.cellType == DataGridExportCellType.columnHeader) {
details.excelRange.cellStyle.backColor = '#42A5F5';
} else if (details.cellType == DataGridExportCellType.row) {
details.excelRange.cellStyle.backColor = '#FFA726';
}
});
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
![excel shows the cell styling](images/export-to-excel/flutter-datagrid-excel-export-styling.png)
## Cell customization when exporting
### Customize cell values while exporting
The cell value can be customized while exporting to Excel by directly setting the cell value of a cell to the `excelRange.value` property available in the argument of `cellExport` callback.
{% tabs %}
{% highlight Dart %}
final Workbook workbook = key.currentState!.exportToExcelWorkbook(
cellExport: (DataGridCellExcelExportDetails details) {
if (details.cellType == DataGridExportCellType.row &&
details.cellValue == 'Project Lead') {
details.excelRange.value = 'Lead';
}
});
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
![excel shows the cell customization](images/export-to-excel/flutter-datagrid-excel-export-cell-customization.png)
### Customize the cells based on column
You can customize the column style based on the column name when exporting to Excel by using the `cellExport` parameter.
{% tabs %}
{% highlight Dart %}
final Workbook workbook = key.currentState!.exportToExcelWorkbook(
cellExport: (DataGridCellExcelExportDetails details) {
if (details.cellType == DataGridExportCellType.row &&
details.columnName == 'Name') {
details.excelRange.cellStyle
..bold = true
..fontColor = '#F44336';
}
});
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}
## Customize Exporting Behavior
You can customize the exporting behavior by overriding the available methods in `DataGridToExcelConverter` class and setting the instance of custom excel converter to the `converter` parameter in `exportToExcelWorksheet` or `exportToExcelWorkbook` method.
{% tabs %}
{% highlight Dart %}
class CustomDataGridToExcelConverter extends DataGridToExcelConverter {
@override
void exportColumnHeader(SfDataGrid dataGrid, GridColumn column,
String columnName, Worksheet worksheet) {
// TODO: Add your requirements in exportColumnHeader
super.exportColumnHeader(dataGrid, column, columnName, worksheet);
}
@override
void exportColumnHeaders(SfDataGrid dataGrid, Worksheet worksheet) {
// TODO: Add your requirements in exportColumnHeaders
super.exportColumnHeaders(dataGrid, worksheet);
}
@override
void exportRow(SfDataGrid dataGrid, DataGridRow row, GridColumn column,
Worksheet worksheet) {
// TODO: Add your requirements in exportRow
super.exportRow(dataGrid, row, column, worksheet);
}
@override
void exportRows(
SfDataGrid dataGrid, List<DataGridRow> rows, Worksheet worksheet) {
// TODO: Add your requirements in exportRows
super.exportRows(dataGrid, rows, worksheet);
}
@override
void exportStackedHeaderRow(SfDataGrid dataGrid,
StackedHeaderRow stackedHeaderRow, Worksheet worksheet) {
// TODO: Add your requirements in exportStackedHeaderRow
super.exportStackedHeaderRow(dataGrid, stackedHeaderRow, worksheet);
}
@override
void exportStackedHeaderRows(SfDataGrid dataGrid, Worksheet worksheet) {
// TODO: Add your requirements in exportStackedHeaderRows
super.exportStackedHeaderRows(dataGrid, worksheet);
}
@override
void exportTableSummaryRow(SfDataGrid dataGrid,
GridTableSummaryRow summaryRow, Worksheet worksheet) {
// TODO: Add your requirements in exportTableSummaryRow
super.exportTableSummaryRow(dataGrid, summaryRow, worksheet);
}
@override
void exportTableSummaryRows(SfDataGrid dataGrid,
GridTableSummaryRowPosition position, Worksheet worksheet) {
// TODO: Add your requirements in exportTableSummaryRows
super.exportTableSummaryRows(dataGrid, position, worksheet);
}
@override
Object? getCellValue(DataGridRow row, GridColumn column) {
// TODO: Add your requirements in getCellValue
super.getCellValue(row, column);
}
}
{% endhighlight %}
{% endtabs %}
The following code snippet illustrates how to create an instance of `CustomDataGridToExcelConverter` class and setting the instance to `converter` parameter in `exportToExcelWorksheet` or `exportToExcelWorkbook` method.
{% tabs %}
{% highlight Dart %}
CustomDataGridToExcelConverter converter = CustomDataGridToExcelConverter();
Workbook workbook = key.currentState!.exportToExcelWorkbook(converter: converter);
final List<int> bytes = workbook.saveAsStream();
{% endhighlight %}
{% endtabs %}

Просмотреть файл

@ -0,0 +1,432 @@
---
layout: post
title: Export Flutter DataGrid to PDF | Flutter DataTable | Syncfusion
description: Learn here all about how to export the Syncfusion Flutter DataGrid (SfDataGrid) into PDF Document and more.
platform: flutter
control: SfDataGrid
documentation: ug
---
# Export Flutter DataGrid to PDF (SfDataGrid)
The [SfDataGrid](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid-class.html) provides support to export the content to PDF document with several customization options.
**Add dependency**
The following dependencies must be added to your pubspec.yaml file for exporting to PDF.
{% highlight dart %}
dependencies:
syncfusion_flutter_datagrid_export: ^xx.x.xx
{% endhighlight %}
>**NOTE** Here, **xx.x.xx** denotes the current version of `Syncfusion Flutter DataGrid Export` package.
**Import package**
Import the following package in your Dart code.
{% tabs %}
{% highlight Dart %}
import 'package:syncfusion_flutter_datagrid_export/export.dart';
import 'package:syncfusion_flutter_pdf/pdf.dart';
{% endhighlight %}
{% endtabs %}
You can export the `SfDataGrid` to PDF by using the following extension methods present in the `SfDataGridState` class:
* `exportToPdfDocument`
* `exportToPdfGrid`
**Add GlobalKey for the DataGrid**
Create the [GlobalKey](https://api.flutter.dev/flutter/widgets/GlobalKey-class.html) using the [SfDataGridState](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGridState-class.html) class. Exporting related methods are available via `SfDataGridState` class.
Set the created `GlobalKey` to the `SfDataGrid`.
{% tabs %}
{% highlight Dart %}
final GlobalKey<SfDataGridState> key = GlobalKey<SfDataGridState>();
{% endhighlight %}
{% endtabs %}
The following code illustrates how to create and display a `SfDataGrid` using the global key.
{% tabs %}
{% highlight Dart %}
GlobalKey<SfDataGridState> key = GlobalKey<SfDataGridState>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
ElevatedButton(
child: Text('Export To Pdf'),
onPressed: () {
PdfDocument document = key.currentState!.exportToPdfDocument()
final List<int> bytes = document.save();
}),
Expanded(
child: SfDataGrid(
source: _employeeDataSource,
columns: [
GridColumn(
columnName: 'ID',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'Name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'Designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Designation',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'Salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Salary',
overflow: TextOverflow.ellipsis,
))),
],
),
),
],
),
);
}
{% endhighlight %}
{% endtabs %}
## Export DataGrid to PDF document
You can export the data to [PdfDocument](https://pub.dev/documentation/syncfusion_flutter_pdf/latest/pdf/PdfDocument-class.html) by using the `exportToPdfDocument` method from `key.currentState` of the DataGrid.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument();
final List<int> bytes = document.save();
File('DataGrid.pdf').writeAsBytes(bytes);
{% endhighlight %}
{% endtabs %}
## Export DataGrid to PDF Grid
You can export the data to [PdfGrid](https://pub.dev/documentation/syncfusion_flutter_pdf/latest/pdf/PdfGrid-class.html) by using the `exportToPdfGrid` method from `key.currentState` of the DataGrid.
{% tabs %}
{% highlight Dart %}
PdfDocument document = PdfDocument();
PdfPage pdfPage = document.pages.add();
PdfGrid pdfGrid = key.currentState!.exportToPdfGrid();
pdfGrid.draw(
page: pdfPage,
bounds: Rect.fromLTWH(0, 0, 0, 0),
);
final List<int> bytes = document.save();
File('DataGrid.pdf').writeAsBytes(bytes);
{% endhighlight %}
{% endtabs %}
## Exporting options
### Exclude columns when exporting
By default, all the columns in the SfDataGrid are exported to PDF. To exclude some particular columns while exporting to PDF, add those column names to the `excludeColumns` parameter.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument( excludeColumns: ['Name']);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
![pdf document shows grid with exclude column ](images/export-to-pdf/flutter-datagrid-pdf-exclude-column.png)
### Disable column headers on each page
You can disable the column headers on each page by setting the `canRepeatHeaders` parameter as `false`.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(canRepeatHeaders: false);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
### Export all columns in one page
You can fit all the columns in one page by setting the `fitAllColumnsInOnePage` parameter as `true`.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(fitAllColumnsInOnePage: true);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
### Exclude table summaries when exporting
By default, table summaries in `SfDataGrid` are exported to PDF. Set the `exportTableSummaries` parameter as `false` to export the `SfDataGrid` without table summaries.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(exportTableSummaries: false);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
### Exclude stacked headers when exporting
By default, stacked headers in `SfDataGrid` are exported to PDF. Set the `exportStackedHeaders` parameter as `false` to export the `SfDataGrid` without stacked headers.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(exportStackedHeaders: false);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
### Auto-size column widths in PDF
In order, to export the actual column width from `SfDataGrid` instead of the auto column width, set the `autoColumnWidth` parameter as `false`.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(autoColumnWidth: false);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
>**NOTE**
If you disabled the `autoColumnWidth`, then you must set `fitAllColumnsInOnePage` as false. Then only, the overflowing columns are drawn in next page. Because `fitAllColumnsInOnePage` has topmost priority.
## Change the orientation of the PDF document
You can change the orientation of a page in PDF document by using the `PdfDocument.pageSettings.orientation` property.
To change the page orientation, you need to export the `SfDataGrid` to `PdfGrid` using the `exportToPdfGrid` method and draw the exported `PdfGrid` into a `PdfDocument`.
{% tabs %}
{% highlight Dart %}
PdfDocument document = PdfDocument();
document.pageSettings.orientation = PdfPageOrientation.landscape;
PdfPage pdfPage = document.pages.add();
PdfGrid pdfGrid = key.currentState!.exportToPdfGrid();
pdfGrid.draw(
page: pdfPage,
bounds: Rect.fromLTWH(0, 0, 0, 0));
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
## Export the selected rows to PDF
By default, entire grid is exported to PDF. You can export selected rows only by passing the `dataGridController.selectedRows` to `rows` parameter in `exportToPdfDocument` and `exportToPdfGrid` methods.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(rows: dataGridController.selectedRows,);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
## Setting header and footer in PDF document
`SfDataGrid` provides a way to display additional content at the top (Header) and bottom (Footer) of the PDF page while exporting to PDF. This can be achieved by using `headerFooterExport` parameter in `exportToPdfDocument` or `exportToPdfGrid` methods.
Setting the `PdfPageTemplateElement` to `headerFooterExport.pdfDocumentTemplate.top` loads the content at the top of the page, while setting the `PdfPageTemplateElement` to `headerFooterExport.pdfDocumentTemplate.bottom` loads the content at the bottom of the page.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(
headerFooterExport: (DataGridPdfHeaderFooterExportDetails headerFooterExport) {
final double width = headerFooterExport.pdfPage.getClientSize().width;
final PdfPageTemplateElement header = PdfPageTemplateElement(Rect.fromLTWH(0, 0, width, 65));
header.graphics.drawString(
'Company Details',
PdfStandardFont(PdfFontFamily.helvetica, 13, style: PdfFontStyle.bold),
bounds: const Rect.fromLTWH(0, 25, 200, 60),
);
headerFooterExport.pdfDocumentTemplate.top = header;
},
);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
![pdf document shows the document header](images/export-to-pdf/flutter-datagrid-pdf-document-header.png)
## Styling cells based on cell type in PDF
You can customize the cell styles based on cell type using the `cellExport` parameter, which is a callback in `exportToPdfDocument` or `exportToPdfGrid` methods.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(cellExport: (details) {
if (details.cellType == DataGridExportCellType.columnHeader) {
details.pdfCell.style.backgroundBrush = PdfBrushes.pink;
}
if (details.cellType == DataGridExportCellType.row) {
details.pdfCell.style.backgroundBrush = PdfBrushes.lightCyan;
}
});
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
![pdf document show the cell styles](images/export-to-pdf/flutter-datagrid-pdf-cell-styles.png)
## Cell customization when exporting
### Customize cell values while exporting
The cell value can be customized while exporting to PDF by directly setting the cell value of a cell in `PdfGrid` via `PdfCell` property available in argument of `cellExport` callback.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(cellExport: (details) {
if (details.cellType == DataGridExportCellType.row &&
details.columnName == 'Designation') {
if (details.cellValue == 'Project Lead') {
details.pdfCell.value = 'Lead';
}
}
});
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
![pdf document shows the cell customization](images/export-to-pdf/flutter-datagrid-pdf-cell-customization.png)
### Customize the Cells based on Column Name
You can customize the column style based on the column name while exporting to PDF by using the `cellExport` parameter.
{% tabs %}
{% highlight Dart %}
PdfDocument document = key.currentState!.exportToPdfDocument(cellExport: (details) {
if (details.cellType == DataGridExportCellType.row && details.columnName == 'Customer Name') {
details.pdfCell.style.textBrush = PdfBrushes.red;
}
}
);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}
## Customize Exporting Behavior
You can customize the exporting behavior by overriding the available methods in `DataGridToPdfConverter` class and setting the instance of custom pdf converter to `converter` parameter in `exportToPdfDocument` or `exportToPdfGrid` method.
{% tabs %}
{% highlight Dart %}
class CustomDataGridToPdfConverter extends DataGridToPdfConverter {
@override
void exportColumnHeader(SfDataGrid dataGrid, GridColumn column,
String columnName, PdfGrid pdfGrid) {
// TODO: Add your requirements column header
super.exportColumnHeader(dataGrid, column, columnName, pdfGrid);
}
@override
void exportColumnHeaders(
SfDataGrid dataGrid, List<GridColumn> columns, PdfGrid pdfGrid) {
// TODO: Add your requirements column headers
super.exportColumnHeaders(dataGrid, columns, pdfGrid);
}
@override
void exportRows(
List<GridColumn> columns, List<DataGridRow> rows, PdfGrid pdfGrid) {
// TODO: Add your requirements in exportRows
super.exportRows(columns, rows, pdfGrid);
}
@override
void exportRow(List<GridColumn> columns, DataGridRow row, PdfGrid pdfGrid) {
// TODO: Add your requirements in exportRow
super.exportRow(columns, row, pdfGrid);
}
}
{% endhighlight %}
{% endtabs %}
The following code sample illustrates how to create an instance of `CustomDataGridToPdfConverter` class and setting the instance to `converter` parameter in `exportToPdfDocument` or `exportToPdfGrid` method.
{% tabs %}
{% highlight Dart %}
CustomDataGridToPdfConverter customDataGridToPdfConverter = CustomDataGridToPdfConverter();
PdfDocument document = key.currentState!.exportToPdfDocument(converter: customDataGridToPdfConverter);
final List<int> bytes = document.save();
{% endhighlight %}
{% endtabs %}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 40 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 480 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 435 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 36 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 36 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 34 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 28 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 30 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 28 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 17 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 15 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 17 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 17 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 46 KiB

864
Flutter/datagrid/paging.md Normal file
Просмотреть файл

@ -0,0 +1,864 @@
---
layout: post
title: Paging in Flutter DataGrid | DataPager | Syncfusion
description: Learn here all about paging feature and how to customize its apperance in Syncfusion Flutter DataGrid (SfDataGrid) widget and more.
platform: flutter
control: SfDataGrid
documentation: ug
---
# Paging in Flutter DataGrid (SfDataGrid)
The datagrid interactively supports the manipulation of data using [SfDataPager](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager-class.html) control. This provides support to load data in segments when dealing with large volumes of data. `SfDataPager` can be placed above or below based on the requirement to easily manage data paging.
The datagrid performs paging of data using the `SfDataPager`. To enable paging, follow below procedure
* Create a new `SfDataPager` widget, and set the [SfDataGrid.DataGridSource](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataGridSource-class.html) to the [SfDataPager.delegate](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/delegate.html) property.
* Set the number of pages required to be displayed in data pager by setting the [SfDataPager.pageCount](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/pageCount.html) property.
* Set the number of buttons that should be displayed in view by setting the [SfDataPager.visibleItemsCount](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/visibleItemsCount.html) property.
* You can load the data for a specific page in `handlePageChange` method. This method is called for every page navigation from data pager.
N> The `SfDataPager.visibleItemsCount` property default value is 5.
The following code example illustrates using `SfDataPager` with the datagrid control:
{% tabs %}
{% highlight Dart %}
import 'package:intl/intl.dart';
final int _rowsPerPage = 15;
final double _dataPagerHeight = 60.0;
List<OrderInfo> _orders = [];
List<OrderInfo> _paginatedOrders = [];
final OrderInfoDataSource _orderInfoDataSource = OrderInfoDataSource();
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraint) {
return Column(children: [
SizedBox(
height: constraint.maxHeight - _dataPagerHeight,
width: constraint.maxWidth,
child: _buildDataGrid(constraint)),
Container(
height: _dataPagerHeight,
child: SfDataPager(
delegate: _orderInfoDataSource,
pageCount: _orders.length / _rowsPerPage,
direction: Axis.horizontal,
))
]);
});
}
Widget _buildDataGrid(BoxConstraints constraint) {
return SfDataGrid(
source: _orderInfoDataSource,
columnWidthMode: ColumnWidthMode.fill,
columns: <GridColumn>[
GridColumn(
columnName: 'orderID',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Order ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'customerID',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Customer Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Order Date',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'freight',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Freight',
overflow: TextOverflow.ellipsis,
)))
]);
}
class OrderInfoDataSource extends DataGridSource {
OrderInfoDataSource() {
_paginatedOrders = _orders.getRange(0, 19).toList(growable: false);
buildPaginatedDataGridRows();
}
List<DataGridRow> dataGridRows = [];
@override
List<DataGridRow> get rows => dataGridRows;
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((dataGridCell) {
if (dataGridCell.columnName == 'orderID') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
dataGridCell.value.toString(),
overflow: TextOverflow.ellipsis,
),
);
} else if (dataGridCell.columnName == 'customerID') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
dataGridCell.value.toString(),
overflow: TextOverflow.ellipsis,
));
} else if (dataGridCell.columnName == 'orderDate') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
DateFormat.yMd().format(dataGridCell.value).toString(),
overflow: TextOverflow.ellipsis,
));
} else {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
NumberFormat.currency(locale: 'en_US', symbol: '\$')
.format(dataGridCell.value)
.toString(),
overflow: TextOverflow.ellipsis,
));
}
}).toList());
}
@override
Future<bool> handlePageChange(int oldPageIndex, int newPageIndex) async {
int startIndex = newPageIndex * _rowsPerPage;
int endIndex = startIndex + _rowsPerPage;
if (startIndex < _orders.length && endIndex <= _orders.length) {
_paginatedOrders =
_orders.getRange(startIndex, endIndex).toList(growable: false);
buildPaginatedDataGridRows();
notifyListeners();
} else {
_paginatedOrders = [];
}
return true;
}
void buildPaginatedDataGridRows() {
dataGridRows = _paginatedOrders.map<DataGridRow>((dataGridRow) {
return DataGridRow(cells: [
DataGridCell(columnName: 'orderID', value: dataGridRow.orderID),
DataGridCell(columnName: 'customerID', value: dataGridRow.customerID),
DataGridCell(columnName: 'orderDate', value: dataGridRow.orderDate),
DataGridCell(columnName: 'freight', value: dataGridRow.freight),
]);
}).toList(growable: false);
}
}
{% endhighlight %}
{% endtabs %}
![flutter datapager with datagrid](images/paging/flutter-datapager.png)
## Callbacks
The SfDataPager provides [onPageNavigationStart](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/onPageNavigationStart.html) and [onPageNavigationEnd](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/onPageNavigationEnd.html) callbacks to listen the page navigation in widget level.
Typically, these callbacks are used to show and hide loading indicator.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(body: LayoutBuilder(builder: (context, constraints) {
return Row(children: [
Column(children: [
SizedBox(
height: constraints.maxHeight - 60,
width: constraints.maxWidth,
child: _buildDataGrid(constraints)),
Container(
height: 60,
width: constraints.maxWidth,
child: SfDataPager(
pageCount: _orders.length / _rowsPerPage,
direction: Axis.horizontal,
onPageNavigationStart: (int pageIndex) {
//You can do your customization
},
delegate: _orderInfoDataSource,
onPageNavigationEnd: (int pageIndex) {
//You can do your customization
}))
])
]);
}));
}
{% endhighlight %}
{% endtabs %}
## Asynchronous data loading
You can load the data asynchronously to the `SfDataPager` by overriding the `handlePageChange` method and await the method while loading the data.
You can use `onPageNavigationStart` and `onPageNavigationEnd` callbacks to show and hide the loading indicator when navigating between pages.
In the below example, we have set await for 2000ms and displayed the loading indicator until 2000ms.
{% tabs %}
{% highlight Dart %}
import 'package:intl/intl.dart';
bool showLoadingIndicator = true;
@override
Widget build(BuildContext context) {
return Scaffold(body: LayoutBuilder(builder: (context, constraints) {
return Row(children: [
Column(children: [
SizedBox(
height: constraints.maxHeight - 60,
width: constraints.maxWidth,
child: _buildStack(constraints)),
Container(
height: 60,
width: constraints.maxWidth,
child: SfDataPager(
pageCount: _orders.length / _rowsPerPage,
direction: Axis.horizontal,
onPageNavigationStart: (int pageIndex) {
setState(() {
showLoadingIndicator = true;
});
},
delegate: _orderInfoDataSource,
onPageNavigationEnd: (int pageIndex) {
setState(() {
showLoadingIndicator = false;
});
}))
])
]);
}));
}
Widget _buildStack(BoxConstraints constraints) {
List<Widget> _getChildren() {
final List<Widget> stackChildren = [];
stackChildren.add(_buildDataGrid(constraints));
if (showLoadingIndicator) {
stackChildren.add(Container(
color: Colors.black12,
width: constraints.maxWidth,
height: constraints.maxHeight,
child: Align(
alignment: Alignment.center,
child: CircularProgressIndicator(
strokeWidth: 3,
))));
}
return stackChildren;
}
return Stack(
children: _getChildren(),
);
}
class OrderInfoDataSource extends DataGridSource {
OrderInfoDataSource() {
_paginatedOrders = _orders.getRange(0, 19).toList(growable: false);
buildPaginatedDataGridRows();
}
List<DataGridRow> dataGridRows = [];
@override
List<DataGridRow> get rows => dataGridRows;
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((dataGridCell) {
if (dataGridCell.columnName == 'orderID') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
dataGridCell.value.toString(),
overflow: TextOverflow.ellipsis,
),
);
} else if (dataGridCell.columnName == 'customerID') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
dataGridCell.value.toString(),
overflow: TextOverflow.ellipsis,
));
} else if (dataGridCell.columnName == 'orderDate') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
DateFormat.yMd().format(dataGridCell.value).toString(),
overflow: TextOverflow.ellipsis,
));
} else {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
NumberFormat.currency(locale: 'en_US', symbol: '\$')
.format(dataGridCell.value)
.toString(),
overflow: TextOverflow.ellipsis,
));
}
}).toList());
}
@override
Future<bool> handlePageChange(int oldPageIndex, int newPageIndex) async {
int startIndex = newPageIndex * _rowsPerPage;
int endIndex = startIndex + _rowsPerPage;
if (startIndex < _orders.length && endIndex <= _orders.length) {
await Future.delayed(Duration(milliseconds: 2000));
_paginatedOrders =
_orders.getRange(startIndex, endIndex).toList(growable: false);
buildPaginatedDataGridRows();
notifyListeners();
} else {
_paginatedOrders = [];
}
return true;
}
void buildPaginatedDataGridRows() {
dataGridRows = _paginatedOrders.map<DataGridRow>((dataGridRow) {
return DataGridRow(cells: [
DataGridCell(columnName: 'orderID', value: dataGridRow.orderID),
DataGridCell(columnName: 'customerID', value: dataGridRow.customerID),
DataGridCell(columnName: 'orderDate', value: dataGridRow.orderDate),
DataGridCell(columnName: 'freight', value: dataGridRow.freight),
]);
}).toList(growable: false);
}
}
{% endhighlight %}
{% endtabs %}
![flutter datapager with asynchronous loading](images/paging/flutter-datapager-asynchronous-loading.gif)
>**NOTE**
Download demo application from [GitHub](https://github.com/SyncfusionExamples/how-to-show-loading-indicator-on-loading-page-in-flutter-datatable).
## Programmatic page navigation
The `SfDataPager` provides the support to navigate between the pages programmatically using [controller](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataGridController-class.html) with following options,
* [nextPage](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataPagerController/nextPage.html)
* [previousPage](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataPagerController/previousPage.html)
* [LastPage](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataPagerController/lastPage.html)
* [firstPage](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataPagerController/firstPage.html)
The following code example shows how to navigate the previous page programmatically,
{% tabs %}
{% highlight Dart %}
DataPagerController _controller = DataPagerController();
@override
Widget build(BuildContext context) {
return Scaffold(body: LayoutBuilder(builder: (context, constraint) {
return Column(children: [
MaterialButton(
onPressed: () {
_controller.previousPage();
},
child: Text('Move Previous page'),
),
SizedBox(
height: constraint.maxHeight - 120,
width: constraint.maxWidth,
child: _buildDataGrid(constraint)),
Container(
height: 60,
child: Align(
alignment: Alignment.center,
child: SfDataPager(
delegate: _orderInfoDataSource,
initialPageIndex: 2,
controller: _controller,
pageCount: _orders.length / _rowsPerPage,
direction: Axis.horizontal,
)))
]);
}));
}
{% endhighlight %}
{% endtabs %}
## Orientation
`SfDataPager` allows you to arrange the child elements either horizontally or vertically. This can be achieved by using the [direction](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/direction.html) Property. `direction` is an Enum type.
<table>
<tr>
<th>
Enum
</th>
<th>
Description</th>
</tr>
<tr>
<td>
horizontal
</td>
<td>
This is the default enum value for direction. Arranges all the navigation buttons and numeric buttons horizontally.{{'![flutter datapager in horizontal direction](images/paging/flutter-datapager-direction-horizontal.png)'|markdownify}}
</td>
</tr>
<tr>
<td>
vertical
</td>
<td>
Arranges all the navigation buttons and numeric buttons vertically by setting Axis.vertical to direction property.{{'![flutter datapager in vertical direction](images/paging/flutter-datapager-direction-vertical.png)'|markdownify}}
</td>
</tr>
</table>
## Appearance
SfDataPager allows to customize the appearance of the data pager using the [SfDataPagerThemeData](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfDataPagerThemeData-class.html) in [SfDataPagerTheme](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfDataPagerTheme-class.html). The `SfDataPager` should be wrapped inside the `SfDataPagerTheme`.
Import the following class from the [syncfusion_flutter_core](https://pub.dev/packages/syncfusion_flutter_core) package.
{% tabs %}
{% highlight Dart %}
import 'package:syncfusion_flutter_core/theme.dart';
{% endhighlight %}
{% endtabs %}
The following code example illustrates using `SfDataPagerThemeData` with the data pager control
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataPagerTheme(
data: SfDataPagerThemeData(
itemColor: Colors.white,
selectedItemColor: Colors.lightGreen,
itemBorderRadius: BorderRadius.circular(5),
backgroundColor: Colors.teal,
),
child: SfDataPager(
delegate: _orderInfoDataSource,
pageCount: _orders.length / _rowsPerPage,
direction: Axis.horizontal,
),
),
);
}
{% endhighlight %}
{% endtabs %}
![flutter datapager with customization](images/paging/flutter-datapager-customization.png)
### Set the padding between page items
The padding between the page items including navigation page items such as first, last, previous and next can be changed by using the `itemPadding` property.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataPager(
itemPadding: EdgeInsets.all(8.0),
pageCount: 5,
delegate: employeeDataSource,
),
);
}
{% endhighlight %}
{% endtabs %}
N> The default value of `SfDataPager.itemPadding` is 5.0.
### Set the height and width for the page items
The default width and height of the page items are 50 and 50, respectively. For changing page number items size, use the `itemWidth` and `itemHeight` properties; for changing navigation items size such as first, last, previous, and next, use the `navigationItemHeight` and `navigationItemWidth` properties.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: Center(
child: SfDataPagerTheme(
data: SfDataPagerThemeData(
itemBorderWidth: 0.5,
itemBorderColor: Colors.grey.shade400,
itemBorderRadius: BorderRadius.circular(5),
),
child: SfDataPager(
pageCount: 5,
visibleItemsCount: 2,
itemWidth: 70,
itemHeight: 55,
navigationItemWidth: 70,
navigationItemHeight: 55,
delegate: employeeDataSource,
),
)));
}
{% endhighlight %}
{% endtabs %}
![flutter datapager with page button resizing](images/paging/flutter-datapager-page-item-resizing.png)
### Hide certain navigation page items
To hide the certain navigation page items, use the following properties:
* `firstPageItemVisible`
* `lastPageItemVisible`
* `nextPageItemVisible`
* `previousPageItemVisible`
N> Default value of all properties is true.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataPagerTheme(
data: SfDataPagerThemeData(
itemBorderWidth: 0.5,
itemBorderColor: Colors.grey.shade400,
itemBorderRadius: BorderRadius.circular(5),
selectedItemColor: Colors.indigo.shade500),
child: SfDataPager(
firstPageItemVisible: false,
lastPageItemVisible: false,
pageCount: 5,
visibleItemsCount: 3,
navigationItemWidth: 100,
delegate: employeeDataSource,
pageItemBuilder: (String itemName) {
if (itemName == 'Next') {
return Center(
child: Text('Next'),
);
}
if (itemName == 'Previous') {
return Center(
child: Text('Previous'),
);
}
},
itemPadding: EdgeInsets.all(8.0),
),
));
}
{% endhighlight %}
{% endtabs %}
![flutter datapager with page button resizing](images/paging/flutter_datagrid_resize_page_button.png)
## Change the number of visible items (buttons) in view
You can change the number of visible items i.e. page buttons in view by using the [SfDataPager.visibleItemsCount](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/visibleItemsCount.html).
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter DataGrid Sample'),
),
body: LayoutBuilder(builder: (context, constraint) {
return Column(
children: [
SizedBox(
height: constraint.maxHeight - _dataPagerHeight,
width: constraint.maxWidth,
child: _buildDataGrid(constraint)),
Container(
height: _dataPagerHeight,
child: SfDataPager(
visibleItemsCount: 1,
delegate: _orderInfoDataSource,
pageCount: _orders.length / _rowsPerPage,
direction: Axis.horizontal,
),
)
],
);
}));
}
{% endhighlight %}
{% endtabs %}
## Load any widget in page button
You can load any widget to page button by using [SfDataPager.pageItemBuilder](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/pageItemBuilder.html).
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter DataGrid Sample'),
),
body: LayoutBuilder(builder: (context, constraint) {
return Column(children: [
SizedBox(
height: constraint.maxHeight - _dataPagerHeight,
width: constraint.maxWidth,
child: _buildDataGrid(constraint)),
Container(
height: _dataPagerHeight,
child: SfDataPagerTheme(
data: SfDataPagerThemeData(
itemBorderColor: Colors.blue,
itemBorderWidth: 1,
backgroundColor: Colors.transparent,
itemBorderRadius: BorderRadius.circular(0),
),
child: SfDataPager(
pageItemBuilder: (String value) {
return Container(
child: Text(
value,
style: TextStyle(
fontSize: 10, fontWeight: FontWeight.w700),
));
},
delegate: _orderInfoDataSource,
pageCount: _orders.length / _rowsPerPage,
direction: Axis.horizontal,
)))
]);
}));
}
{% endhighlight %}
{% endtabs %}
## Sort all the rows instead of rows available in a page
By default, the rows on a page are sorted. To sort all the rows available for paging, do not override the `handlePageChange` method in the `DataGridSource` class. The DataGrid will automatically split the rows required for each page based on the `SfDataPager.pageCount`, i.e. the divided value of the `DataGridRows.rows` and `SfDataPager.pageCount`.
If you want to specifically maintain the rows required for a page, you can use the [SfDataGrid.rowsPerPage]() property. However, make sure that you do not override the `handlePageChange` method in the `DataGridSource` class at the sample level.
{% tabs %}
{% highlight Dart %}
final int _rowsPerPage = 15;
final double _dataPagerHeight = 60.0;
List<OrderInfo> _orders = [];
@override
Widget build(BuildContext context) {
return Scaffold(body: LayoutBuilder(builder: (context, constraint) {
return Column(children: [
SizedBox(
height: constraint.maxHeight - _dataPagerHeight,
width: constraint.maxWidth,
child: _buildDataGrid(constraint)),
Container(
height: _dataPagerHeight,
child: SfDataPager(
delegate: _orderInfoDataSource,
pageCount: (_orders.length / _rowsPerPage).ceil().toDouble(),
direction: Axis.horizontal,
))
]);
}));
}
Widget _buildDataGrid(BoxConstraints constraint) {
return SfDataGrid(
source: _orderInfoDataSource,
columnWidthMode: ColumnWidthMode.fill,
rowsPerPage: _rowsPerPage,
allowSorting: true,
columns: <GridColumn>[
GridColumn(
columnName: 'orderID',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Order ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'customerID',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Customer Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Order Date',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'freight',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Freight',
overflow: TextOverflow.ellipsis,
)))
]);
}
class OrderInfoDataSource extends DataGridSource {
OrderInfoDataSource() {
buildDataGridRows();
}
List<DataGridRow> dataGridRows = [];
@override
List<DataGridRow> get rows => dataGridRows;
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((dataGridCell) {
if (dataGridCell.columnName == 'orderID') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
dataGridCell.value.toString(),
overflow: TextOverflow.ellipsis,
),
);
} else if (dataGridCell.columnName == 'customerID') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
dataGridCell.value.toString(),
overflow: TextOverflow.ellipsis,
));
} else if (dataGridCell.columnName == 'orderDate') {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
DateFormat.yMd().format(dataGridCell.value).toString(),
overflow: TextOverflow.ellipsis,
));
} else {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
NumberFormat.currency(locale: 'en_US', symbol: '\$')
.format(dataGridCell.value)
.toString(),
overflow: TextOverflow.ellipsis,
));
}
}).toList());
}
void buildDataGridRows() {
dataGridRows = _orders.map<DataGridRow>((dataGridRow) {
return DataGridRow(cells: [
DataGridCell(columnName: 'orderID', value: dataGridRow.orderID),
DataGridCell(columnName: 'customerID', value: dataGridRow.customerID),
DataGridCell(columnName: 'orderDate', value: dataGridRow.orderDate),
DataGridCell(columnName: 'freight', value: dataGridRow.freight),
]);
}).toList(growable: false);
}
}
{% endhighlight %}
{% endtabs %}
![sorting applied for all the rows in flutter datagrid paging](images/paging/sorting-applied-for-all-the-rows-in-flutter-datagrid-paging.gif)

Просмотреть файл

@ -0,0 +1,746 @@
---
layout: post
title: Summaries feature in Flutter DataGrid | DataTable | Syncfusion
description: Learn here all about how to add summary rows to the Syncfusion Flutter DataGrid (SfDataGrid) widget and more.
platform: flutter
control: SfDataGrid
documentation: ug
---
# Summaries in Flutter DataGrid (SfDataGrid)
## Table summary
The `SfDataGrid` provides built-in support to display concise information about the rows by using the table summary rows. The table summary value is calculated based on all the rows in the `DataGridSource.rows` property. You can add a table summary row to the DataGrid by adding the `GridTableSummaryRow` to the `SfDataGrid.tableSummaryRows` collection.
DataGrid does not automatically display the summary values. To display the summary value, you need to override the `buildTableSummaryCellWidget` method in the `DataGridSource` class. The calculated summary value is passed as a parameter to the `DataGridSource.buildTableSummaryCellWidget` method. So, you need to return the required widget with the summary value.
### Display table summary for row
The summary information can be displayed in a row by setting the `GridTableSummaryRow.showSummaryInRow` property to `true` and defining the summary columns. The `GridTableSummaryRow.title` content will be displayed in the corresponding row. You must define the `GridTableSummaryRow.title` based on the `GridSummaryColumn.name` property to customize the summary value.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: employeeDataSource,
tableSummaryRows: [
GridTableSummaryRow(
showSummaryInRow: true,
title: 'Total Salary: {Sum} for 20 employees',
columns: [
GridSummaryColumn(
name: 'Sum',
columnName: 'salary',
summaryType: GridSummaryType.sum)
],
position: GridTableSummaryRowPosition.bottom)
],
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Job Title',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
class EmployeeDataSource extends DataGridSource {
EmployeeDataSource({required List<Employee> employeeData}) {
_employeeData = employeeData
.map<DataGridRow>((e) => DataGridRow(cells: [
DataGridCell<int>(columnName: 'id', value: e.id),
DataGridCell<String>(columnName: 'name', value: e.name),
DataGridCell<String>(
columnName: 'designation', value: e.designation),
DataGridCell<int>(columnName: 'salary', value: e.salary),
]))
.toList();
}
List<DataGridRow> _employeeData = [];
@override
List<DataGridRow> get rows => _employeeData;
@override
Widget? buildTableSummaryCellWidget(
GridTableSummaryRow summaryRow,
GridSummaryColumn? summaryColumn,
RowColumnIndex rowColumnIndex,
String summaryValue) {
return Container(
padding: EdgeInsets.all(15.0),
child: Text(summaryValue),
);
}
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((e) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: Text(e.value.toString()),
);
}).toList());
}
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid displays table summary column in row](images/summaries/flutter-datagrid-summary-column-in-row.png)
### Display table summary for column
The summary information can be displayed in a column by setting the `GridTableSummaryRow.showSummaryInRow` property to `false`. You can define summary columns to the `GridTableSummaryRow` by adding the `GridSummaryColumn` to the `GridTableSummaryRow.summaryColumns` collection. The `GridSummaryColumn` contains the following required properties:
* **`name`**: Defines the corresponding column name for the summary calculation. This should be the same value as the `GridColumn.columnName` property.
* **`columnName`**: Defines the corresponding column name for the summary calculation.
* **`summaryType`**: Defines the summary calculation type.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: employeeDataSource,
tableSummaryRows: [
GridTableSummaryRow(
showSummaryInRow: false,
columns: [
GridSummaryColumn(
name: 'Sum',
columnName: 'salary',
summaryType: GridSummaryType.sum)
],
position: GridTableSummaryRowPosition.bottom)
],
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Job Title',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
class EmployeeDataSource extends DataGridSource {
EmployeeDataSource({required List<Employee> employeeData}) {
_employeeData = employeeData
.map<DataGridRow>((e) => DataGridRow(cells: [
DataGridCell<int>(columnName: 'id', value: e.id),
DataGridCell<String>(columnName: 'name', value: e.name),
DataGridCell<String>(
columnName: 'designation', value: e.designation),
DataGridCell<int>(columnName: 'salary', value: e.salary),
]))
.toList();
}
List<DataGridRow> _employeeData = [];
@override
List<DataGridRow> get rows => _employeeData;
@override
Widget? buildTableSummaryCellWidget(
GridTableSummaryRow summaryRow,
GridSummaryColumn? summaryColumn,
RowColumnIndex rowColumnIndex,
String summaryValue) {
return Container(
padding: EdgeInsets.all(15.0),
child: Text(summaryValue),
);
}
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((e) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: Text(e.value.toString()),
);
}).toList());
}
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid displays table summary column in column](images/summaries/flutter-datagrid-summary-column-in-column.png)
### Positioning table summary row
The table summary row can be shown at either top or bottom position by using the `GridTableSummaryRow.position` property.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: employeeDataSource,
tableSummaryRows: [
GridTableSummaryRow(
showSummaryInRow: false,
columns: [
GridSummaryColumn(
name: 'Sum',
columnName: 'salary',
summaryType: GridSummaryType.sum)
],
position: GridTableSummaryRowPosition.top),
GridTableSummaryRow(
showSummaryInRow: true,
title: 'Total Salary: {Sum} for 20 employees',
columns: [
GridSummaryColumn(
name: 'Sum',
columnName: 'salary',
summaryType: GridSummaryType.sum)
],
position: GridTableSummaryRowPosition.bottom)
],
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Job Title',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
class EmployeeDataSource extends DataGridSource {
EmployeeDataSource({required List<Employee> employeeData}) {
_employeeData = employeeData
.map<DataGridRow>((e) => DataGridRow(cells: [
DataGridCell<int>(columnName: 'id', value: e.id),
DataGridCell<String>(columnName: 'name', value: e.name),
DataGridCell<String>(
columnName: 'designation', value: e.designation),
DataGridCell<int>(columnName: 'salary', value: e.salary),
]))
.toList();
}
List<DataGridRow> _employeeData = [];
@override
List<DataGridRow> get rows => _employeeData;
@override
Widget? buildTableSummaryCellWidget(
GridTableSummaryRow summaryRow,
GridSummaryColumn? summaryColumn,
RowColumnIndex rowColumnIndex,
String summaryValue) {
return Container(
padding: EdgeInsets.all(15.0),
child: Text(summaryValue),
);
}
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((e) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: Text(e.value.toString()),
);
}).toList());
}
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid shows positioning of table summary column](images/summaries/flutter-datagrid-position-of-summary-column.png)
### Summary calculation types
The following calculation types are supported for the summary calculation:
* **`Sum`**: Calculate the sum of a column
* **`Average`**: Calculate the average of a column.
* **`Count`**: Calculate the total of rows in `SfDataGrid`.
* **`Maximum`**: Calculate the maximum value in a column.
* **`Minimum`**: Calculate the minimum value in a column.
### Display table summary row with title
The SfDataGrid supports to display columns summary value along with the title by defining the `GridTableSummaryRow.title` and `GridTableSummaryRow.titleColumnCount` properties along with the summary columns. Showing a column summary with the title can be supported, only if the `GridSummaryRow.showSummaryInRow` is `false`. The `GridTableSummaryRow.titleColumnCount` property defines that how long the title should be spanned in the corresponding summary row.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: employeeDataSource,
tableSummaryRows: [
GridTableSummaryRow(
showSummaryInRow: false,
title: 'Total Employee Count: {Count}',
titleColumnSpan: 3,
columns: [
GridSummaryColumn(
name: 'Count',
columnName: 'id',
summaryType: GridSummaryType.count),
GridSummaryColumn(
name: 'Sum',
columnName: 'salary',
summaryType: GridSummaryType.sum)
],
position: GridTableSummaryRowPosition.bottom),
],
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Job Title',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
class EmployeeDataSource extends DataGridSource {
EmployeeDataSource({required List<Employee> employeeData}) {
_employeeData = employeeData
.map<DataGridRow>((e) => DataGridRow(cells: [
DataGridCell<int>(columnName: 'id', value: e.id),
DataGridCell<String>(columnName: 'name', value: e.name),
DataGridCell<String>(
columnName: 'designation', value: e.designation),
DataGridCell<int>(columnName: 'salary', value: e.salary),
]))
.toList();
}
List<DataGridRow> _employeeData = [];
@override
List<DataGridRow> get rows => _employeeData;
@override
Widget? buildTableSummaryCellWidget(
GridTableSummaryRow summaryRow,
GridSummaryColumn? summaryColumn,
RowColumnIndex rowColumnIndex,
String summaryValue) {
return Container(
padding: EdgeInsets.all(15.0),
child: Text(summaryValue),
);
}
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((e) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: Text(e.value.toString()),
);
}).toList());
}
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid shows table summary column along with title](images/summaries/flutter-datagrid-summary-column-with-title.png)
### Set background color for the table summary row
The background color of the table summary row can be customized by using the `GridTableSummaryRow.color` property.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: employeeDataSource,
tableSummaryRows: [
GridTableSummaryRow(
color: Colors.indigo,
showSummaryInRow: true,
title: 'Minimum Salary: {Minimum} for 20 employees',
columns: [
GridSummaryColumn(
name: 'Minimum',
columnName: 'salary',
summaryType: GridSummaryType.minimum)
],
position: GridTableSummaryRowPosition.bottom),
],
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Job Title',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
class EmployeeDataSource extends DataGridSource {
EmployeeDataSource({required List<Employee> employeeData}) {
_employeeData = employeeData
.map<DataGridRow>((e) => DataGridRow(cells: [
DataGridCell<int>(columnName: 'id', value: e.id),
DataGridCell<String>(columnName: 'name', value: e.name),
DataGridCell<String>(
columnName: 'designation', value: e.designation),
DataGridCell<int>(columnName: 'salary', value: e.salary),
]))
.toList();
}
List<DataGridRow> _employeeData = [];
@override
List<DataGridRow> get rows => _employeeData;
@override
Widget? buildTableSummaryCellWidget(
GridTableSummaryRow summaryRow,
GridSummaryColumn? summaryColumn,
RowColumnIndex rowColumnIndex,
String summaryValue) {
return Container(
padding: EdgeInsets.all(15.0),
child: Text(
summaryValue,
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
),
);
}
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((e) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: Text(e.value.toString()),
);
}).toList());
}
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid shows customization of table summary row](images/summaries/flutter-datagrid-summary-row-customization.png)
### Customize table summary calculation
You can write the custom logic for the summary calculation by overriding the `calculateSummaryValue` method from the `DataGridSource` class. The `summaryColumn` parameter will be null for the summary cells in the spanned summary columns.
The following example demonstrates how to customize the summary calculation to find the standard deviation for all employees' salaries.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: SfDataGrid(
source: employeeDataSource,
tableSummaryRows: [
GridTableSummaryRow(
showSummaryInRow: true,
title: 'Standard Deviation: {Deviation}',
columns: [
GridSummaryColumn(
name: 'Deviation',
columnName: 'salary',
summaryType: GridSummaryType.sum)
],
position: GridTableSummaryRowPosition.bottom),
],
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Name'))),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Job Title',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Salary'))),
],
),
);
}
class EmployeeDataSource extends DataGridSource {
EmployeeDataSource({required List<Employee> employeeData}) {
_employeeData = employeeData
.map<DataGridRow>((e) => DataGridRow(cells: [
DataGridCell<int>(columnName: 'id', value: e.id),
DataGridCell<String>(columnName: 'name', value: e.name),
DataGridCell<String>(
columnName: 'designation', value: e.designation),
DataGridCell<int>(columnName: 'salary', value: e.salary),
]))
.toList();
}
List<DataGridRow> _employeeData = [];
@override
List<DataGridRow> get rows => _employeeData;
@override
String calculateSummaryValue(GridTableSummaryRow summaryRow,
GridSummaryColumn? summaryColumn, RowColumnIndex rowColumnIndex) {
List<int> getCellValues(GridSummaryColumn summaryColumn) {
final List<int> values = <int>[];
for (final DataGridRow row in rows) {
final DataGridCell? cell = row.getCells().firstWhereOrNull(
(DataGridCell element) =>
element.columnName == summaryColumn.columnName);
if (cell != null && cell.value != null) {
values.add(cell.value);
}
}
return values;
}
String? title = summaryRow.title;
if (title != null) {
if (summaryRow.showSummaryInRow && summaryRow.columns.isNotEmpty) {
for (final GridSummaryColumn summaryColumn in summaryRow.columns) {
if (title!.contains(summaryColumn.name)) {
double deviation = 0;
final List<int> values = getCellValues(summaryColumn);
if (values.isNotEmpty) {
int sum = values.reduce((value, element) =>
value + pow(element - values.average, 2).toInt());
deviation = sqrt((sum) / (values.length - 1));
}
title = title.replaceAll(
'{${summaryColumn.name}}', deviation.toString());
}
}
}
}
return title ?? '';
}
@override
Widget? buildTableSummaryCellWidget(
GridTableSummaryRow summaryRow,
GridSummaryColumn? summaryColumn,
RowColumnIndex rowColumnIndex,
String summaryValue) {
return Container(
padding: EdgeInsets.all(15.0),
child: Text(summaryValue),
);
}
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((e) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: Text(e.value.toString()),
);
}).toList());
}
}
{% endhighlight %}
{% endtabs %}
![flutter datagrid shows custom logic for table summary column](images/summaries/flutter-datagrid-summary-column-custom-logic.png)

Просмотреть файл

@ -0,0 +1,168 @@
---
layout: post
title: Data label in Flutter Funnel Chart widget | Syncfusion
description: Learn here all about Data label feature of Syncfusion Flutter Funnel Chart (SfFunnelChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Data label in Flutter Funnel Chart (SfFunnelChart)
Data label can be added to a chart series by enabling the [`isVisible`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/isVisible.html) option in the [`dataLabelSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/FunnelSeries/dataLabelSettings.html). You can use the following properties to customize the appearance.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/color.html) - used to change the background color of the data label shape.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderWidth.html) - used to change the stroke width of the data label shape.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderColor.html) - used to change the stroke color of the data label shape.
* [`alignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/alignment.html) - aligns the data label text to [`near`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html), [`center`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html) and [`far`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html).
* [`textStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/textStyle.html) - used to change the data label text color, size, font family, font style, and font weight.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/color.html) - used to change the color of the data label.
* [`fontFamily`](https://api.flutter.dev/flutter/painting/TextStyle/fontFamily.html) - used to change the font family for the data label.
* [`fontStyle`](https://api.flutter.dev/flutter/painting/TextStyle/fontStyle.html) - used to change the font style for the data label.
* [`fontWeight`](https://api.flutter.dev/flutter/painting/TextStyle/fontWeight.html) - used to change the font weight for the data label.
* [`fontSize`](https://api.flutter.dev/flutter/painting/TextStyle/fontSize.html) - used to change the font size for the data label.
* [`margin`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/margin.html) - used to change the margin size for data labels.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/opacity.html) - used to control the transparency of the data label.
* [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelAlignment.html) - used to align the Funnel data label positions. The available options to customize the positions are [`outer`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`top`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`bottom`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) and [`middle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html).
* [`borderRadius`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderRadius.html) - used to add the rounded corners to the data label shape.
* [`angle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/angle.html) - used to rotate the labels.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
series: FunnelSeries<SalesData, String>(
dataSource: chartData,
pointColorMapper: (SalesData data, _) => data.color,
xValueMapper: (SalesData data, _) => data.x,
yValueMapper: (SalesData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
// Renders the data label
isVisible: true
)
)
)
)
)
);
}
{% endhighlight %}
![DataLabel](images/datalabel/default_datalabel.png)
## Positioning the labels
The [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) property is used to position the Funnel chart type data labels at [`top`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`bottom`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`outer`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) and [`middle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) position of the actual data point position. By default, labels are [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) positioned. You can move the labels horizontally and vertically using OffsetX and OffsetY properties respectively.
The [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) property is used to place the Funnel series data labels either [`inside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html) or [`outside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html). By default the label of Funnel chart is placed [`inside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html) the series.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
series: FunnelSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData data, _) => data.x,
yValueMapper: (SalesData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
isVisible: true,
// Positioning the data label
labelPosition: ChartDataLabelPosition.outside
)
)
)
)
)
);
}
{% endhighlight %}
![Data label position](images/datalabel/datalabel_position.png)
N> The [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelAlignment.html) property is used to position the Funnel chart labels whereas [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) property is used to position the Funnel chart labels.
## Apply series color
The [`useSeriesColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/useSeriesColor.html) property is used to apply the series color to background color of the data labels. The default value of this property is `false`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
series: FunnelSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData data, _) => data.x,
yValueMapper: (SalesData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
isVisible: true,
// Positioning the data label
labelPosition: ChartDataLabelPosition.outside,
// Renders background rectangle and fills it with series color
useSeriesColor: true
)
)
)
)
)
);
}
{% endhighlight %}
![Series color](images/datalabel/use_series_color.png)
## Hide data label for 0 value
Data label and its connector line in the Funnel charts for the point value 0 can be hidden using the [`showZeroValue`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/showZeroValue.html) property. This defaults to `true`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:SfFunnelChart(
series: FunnelSeries<SalesData, num>(
dataSource: [
SalesData(11, 35),
SalesData(12, 28),
SalesData(13, 0),
SalesData(14, 32),
SalesData(15, 40)
],
xValueMapper: (SalesData sales, _) => sales.xValue,
yValueMapper: (SalesData sales, _) => sales.yValue,
dataLabelSettings: DataLabelSettings(
showZeroValue: false,
isVisible: true
),
)
)
)
);
}
{% endhighlight %}
![hide_0_value](images/datalabel/dataLabel_0_value.png)
## Data label saturation color
If the user didnt provide text color to the data label, then by default, the saturation color is applied to the data label text. i.e., if the data points background color intensity is dark, then the data label will render in white color (#FFFFFF) and if the data points background color intensity is light, data label will render in black color (#000000).
![label_saturation](images/datalabel/funnel_saturation.png)

Просмотреть файл

@ -0,0 +1,53 @@
---
layout: post
title: Methods in Flutter Funnel Chart widget | Syncfusion
description: Learn here all about available methods of Syncfusion Flutter Funnel Chart(SfFunnelChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Methods in Flutter Funnel Chart (SfFunnelChart)
## PixelToPoint
Converts logical pixel value to the data point value.
The `pixelToPoint` method takes logical pixel value as input and returns a chart data point.
N> The method will return the center value of the segment.
{% highlight dart %}
//Initialize the series controller
FunnelSeriesController? seriesController;
@override
Widget build(BuildContext context) {
return Container(
child: SfFunnelChart(
onChartTouchInteractionDown: (ChartTouchInteractionArgs args) {
final Offset value = Offset(args.position.dx, args.position.dy);
final PointInfo<dynamic>? chartpoint = seriesController?.pixelToPoint(value);
},
series: FunnelSeries<ChartData, String>(
dataSource: data,
onRendererCreated: (FunnelSeriesController funnelSeriesController) {
seriesController = funnelSeriesController;
},
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y
)
),
);
}
class ChartData{
ChartData(this.x, this.y);
final String x;
final double y;
}
{% endhighlight %}

Просмотреть файл

@ -0,0 +1,181 @@
---
layout: post
title: Series customization in Flutter Funnel Chart widget | Syncfusion
description: Learn here all about Series customization feature of Syncfusion Flutter Funnel Chart (SfFunnelChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Series customization in Flutter Funnel Chart (SfFunnelChart)
## Animation
[`SfFunnelChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfFunnelChart-class.html) provides animation support for the series. Series will be animated while rendering. Animation is enabled by default, you can also control the duration of the animation using [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/FunnelSeries/animationDuration.html) property. You can disable the animation by setting 0 value to that property.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
series:FunnelSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
animationDuration: 1000,
)
)
)
)
);
}
{% endhighlight %}
## Animation delay
The `animationDelay` property is used to specify the delay duration of the series animation. This takes milliseconds value as input. By default, the series will get animated for the specified duration. If `animationDelay` is specified, then the series will begin to animate after the specified duration. Defaults to `0`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
List<ChartData> data = [
ChartData('Jan', 35),
ChartData('Feb', 28),
ChartData('Mar', 38),
ChartData('Apr', 32),
ChartData('May', 40)
];
return Center(
child: SfFunnelChart(
series: FunnelSeries<ChartData, String>(
dataSource: data,
animationDuration: 4500,
animationDelay: 2000,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
)
),
);
}
class ChartData {
ChartData(this.x, this.y);
final String x;
final double y;
}
{% endhighlight %}
## Empty points
The data points that has null value are considered as empty points. Empty data points are ignored and not plotted in the chart. By using [`emptyPointSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/FunnelSeries/emptyPointSettings.html) property in series, you can decide the action taken for empty points. Available [`modes`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html) are [`gap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html), [`zero`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html), [`drop`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html) and [`average`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html). Default mode of the empty point is [`gap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('David', null),
ChartData('Steve', 38),
ChartData('Jack', 34),
ChartData('Others', 52)
];
return Scaffold(
body: Center(
child: SfFunnelChart(
series:FunnelSeries<ChartData, String>(
dataSource: chartData,
dataLabelSettings: DataLabelSettings(isVisible:true),
emptyPointSettings: EmptyPointSettings(mode: EmptyPointMode.average),
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y
)
)
)
);
}
{% endhighlight %}
![Empty points](images/Funnel-customization/emptyPoints.png)
### Empty point customization
Specific color for empty point can be set by [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/color.html) property in [`emptyPointSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/FunnelSeries/emptyPointSettings.html). The [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/borderWidth.html) property is used to change the stroke width of the empty point and [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/borderColor.html) is used to change the stroke color of the empty point.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('David', null),
ChartData('Steve', 38),
ChartData('Jack', 34),
ChartData('Others', 52)
];
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
series:FunnelSeries<ChartData, String>(
dataSource: chartData,
dataLabelSettings: DataLabelSettings(isVisible:true),
emptyPointSettings: EmptyPointSettings(mode: EmptyPointMode.average,
color: Colors.red,
borderColor: Colors.black,
borderWidth: 2),
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y
)
)
)
)
);
}
{% endhighlight %}
![Empty points customization](images/Funnel-customization/emptyPointcustomization.png)
## Color mapping for data points
The [`pointColorMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/FunnelSeries/pointColorMapper.html) property is used to map the color field from the data source.
{% highlight dart %}
@override
Widget build(BuildContext context) {
static dynamic chartData = <SalesData>[
SalesData('Rent', 1000,Colors.teal),
SalesData('Food', 2500,Colors.lightBlue),
SalesData('Savings', 760,Colors.brown),
SalesData('Tax', 1897,Colors.grey),
SalesData('Others', 2987,Colors.blueGrey)
];
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
series:FunnelSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
//map Color for each dataPoint datasource.
pointColorMapper: (ChartData sales,_) => sales.color,
)
)
)
)
);
}
{% endhighlight %}
![mapcolor](images/Funnel-customization/color-mapping.png)

Просмотреть файл

@ -0,0 +1,254 @@
---
layout: post
title: Tooltip in Flutter Funnel Chart widget | Syncfusion
description: Learn here all about Tooltip feature of Syncfusion Flutter Funnel Chart (SfFunnelChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Tooltip in Flutter Funnel Chart (SfFunnelChart)
Chart provides tooltip support for all the series. It is used to show information about the segment, when you tap on the segment. To enable the tooltip, you need to set [`enableTooltip`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartSeries/enableTooltip.html) property as `true`.
The tooltip state will be preserved on the device's orientation change and on browser resize. For example, if the tooltip's [`duration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/duration.html) is set to 10,000ms, and when you change the orientation of your device from portrait to landscape after 5,000ms of tooltip display, the tooltip will be displayed for the next 5,000ms in landscape mode before disappearing.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
tooltipBehavior: _tooltipBehavior,
series: FunnelSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales
)
)
)
)
);
}
{% endhighlight %}
![Tooltip](images/tooltip/default_tooltip.png)
## Customizing the appearance
You can use the following properties to customize the tooltip appearance.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/color.html) - used to change the background color of tooltip.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/borderWidth.html) - used to change the stroke width of the tooltip.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/borderColor.html) - used to change the stroke color of the tooltip.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/opacity.html) - used to control the transparency of the tooltip.
* [`duration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/duration.html) - specifies the duration for displaying the tooltip that defaults to `3000`.
* [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/animationDuration.html) - specifies the duration for animating the tooltip that default to 350.
* [`elevation`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/elevation.html) - specifies the elevation of tooltip.
* [`canShowMarker`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/canShowMarker.html) - toggles the visibility of the marker in the tooltip.
* [`header`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/header.html) - specifies the header for tooltip. By default, the series name will be displayed in the header.
* [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) - formats the tooltip text. By default, the tooltip will be rendered with x and y-values. You can add prefix or suffix to x, y, and series name values in the tooltip by formatting them.
* [`shadowColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shadowColor.html) - specifies the color of the tooltip shadow.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
borderColor: Colors.red,
borderWidth: 2,
color: Colors.lightBlue
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 350,
width: 350,
child: SfFunnelChart(
tooltipBehavior: _tooltipBehavior,
)
)
)
);
}
{% endhighlight %}
![Customized tooltip](images/tooltip/customized_tooltip.png)
## Label format
By default, x and y value will be displayed in the tooltip, and it can be customized using [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) property as depicted in the below code snippet. You can show the below values in the tooltip. Also you can add prefix or suffix to these values.
* X value - `point.x`
* Y value - `point.y`
* Bubble size - `point.size`
* Name of the series - `series.name`
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Formatting the tooltip text
format: 'point.y%'
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![tooltip format](images/tooltip/tooltip_format.png)
## Tooltip positioning
The tooltip can be made to display in the fixed location or at the pointer location itself using the `tooltipPosition` property. This defaults to `auto`.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
tooltipPosition: TooltipPosition.pointer
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![pointer tooltip](images/tooltip/tooltip_pointer.png)
## Tooltip template
You can customize the appearance of the tooltip with your own widget by using the [`builder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/builder.html) property of [`tooltipBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfFunnelChart/tooltipBehavior.html).
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Templating the tooltip
builder: (dynamic data, dynamic point, dynamic series,
int pointIndex, int seriesIndex) {
return Container(
child: Text(
'Point Y : ${point.y.toString()}'
)
);
}
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![Tooltip template](images/tooltip/tooltip_template.png)
## Activation mode
The [`activationMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/activationMode.html) property is used to restrict the visibility of tooltip based on the touch actions. The default value of this property is [`ActivationMode.singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html).
The ActivationMode enum contains the following values:
* [`longPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing the long press action.
* [`singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing single tap action.
* [`doubleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing double tap action.
* [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - hides the visibility of tooltip when setting activation mode to none.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Tooltip will be displayed on long press
activationMode: ActivationMode.longPress
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfFunnelChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
Also refer [tooltip event](./events#ontooltiprender) for customizing the tooltip further.

Просмотреть файл

@ -0,0 +1,360 @@
---
layout: post
title: Axis in Flutter Linear Gauge widget | Syncfusion
description: Learn here all about adding and customizing Axis of Syncfusion Flutter Linear Gauge (SfLinearGauge) widget and more.
platform: Flutter
control: SfLinearGauge
documentation: ug
---
# Axis in Flutter Linear Gauge (SfLinearGauge)
The Linear Gauge axis is a scale where a set of values can be plotted. An axis can be customized by changing the thickness, color and edge styles. Axis elements such as labels and ticks can also be easily customized and you can also inverse the axis.
## Default axis
By default axis will have the [`minimum`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/minimum.html) axis value as 0 and the [`maximum`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/maximum.html) axis value as 100. Without any changes the default axis of the Linear Gauge will be displayed as follows.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge()
),
),
);
}
{% endhighlight %}
![Initialize linear gauge for axis](images/getting-started/default_linear_gauge.png)
## Customize minimum and maximum axis values
The [`minimum`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/minimum.html) and [`maximum`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/maximum.html) properties of a Linear Gauge can be used to customize the axis values. In the below code snippet the axis is customized to have the [`minimum`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/minimum.html) value of -50 to [`maximum`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/maximum.html) value of 50. The axis values are displayed by the labels. Customizing these label styles are further explained in next topics.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(minimum: -50, maximum: 50)
),
),
);
}
{% endhighlight %}
![Update linear gauge for axis scale](images/axis/minmax_axis_linear_gauge.png)
## Customize axis track style
The linear axis track can be customized using the [`axisTrackStyle`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/axisTrackStyle.html) property. The [`axisTrackStyle`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/axisTrackStyle.html) has the following properties.
* [`thickness`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/thickness.html) – Customizes the thickness of the axis track.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/color.html) – Customizes the color of the axis track with a solid color.
* [`gradient`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/gradient.html) - Customizes the color of the axis track with a gradient.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/borderWidth.html) - Customizes the border width of the axis track.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/borderColor.html) - Customizes the border color of the axis track.
The following code sample demonstrates how to customize the [`thickness`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/thickness.html) and [`color`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/color.html) properties.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(
axisTrackStyle: LinearAxisTrackStyle(thickness: 15)
),
),
),
);
}
{% endhighlight %}
![Change axis track thickness in linear gauge](images/axis/axis_thickness.png)
## Apply solid color
The below code snippet sets solid colors to the axis track.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(
axisTrackStyle: LinearAxisTrackStyle(color: Colors.blue))
),
),
);
}
{% endhighlight %}
![Apply color to axis in linear guage](images/axis/axis_solid_color.png)
## Apply gradient
The [`color`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/color.html) property of [`axisTrackStyle`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/LinearAxisTrackStyle.html) allows to set a solid color, while the [`gradient`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/gradient.html) property of [`axisTrackStyle`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/LinearAxisTrackStyle.html) allows to apply linear-gradient to axis track.
The following code sample sets solid colors to the axis track.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
child: SfLinearGauge(
axisTrackStyle: LinearAxisTrackStyle(
gradient: LinearGradient(
colors: [Colors.purple, Colors.blue],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
stops: [0.1, 0.5],
tileMode: TileMode.clamp
)
)
),
),
),
),
);
}
{% endhighlight %}
![Apply color to axis in linear guage](images/axis/axis_gradient.png)
## Customize borders
The [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/borderColor.html) and [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/borderWidth.html) properties of [`axisTrackStyle`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/LinearAxisTrackStyle.html) allow you to set a border to the axis track.
The below code snippet sets a border to the axis track.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(
axisTrackStyle: LinearAxisTrackStyle(
// Sets axis thickness for the better visibility of border
thickness: 15,
// Hides axis axis color for the better visibility of border
color: Colors.transparent,
//Sets the border color
borderColor: Colors.blueGrey,
//Sets the border width
borderWidth: 2))
),
),
);
}
{% endhighlight %}
![Customize axis track border](images/axis/axis_border.png)
## Customize corners
The [`edgeStyle`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/edgeStyle.html) property of [`axisTrackStyle`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearAxisTrackStyle/LinearAxisTrackStyle.html) specifies the corner type for the axis track. The corners can be customized with `bothFlat`, `bothCurve`, `startCurve`, and `endCurve` options. The default value of this property is `bothFlat`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(
axisTrackStyle: LinearAxisTrackStyle(
thickness: 20, edgeStyle: LinearEdgeStyle.bothCurve))
),
),
);
}
{% endhighlight %}
![Change axis track edge style](images/axis/axis_corner_style.png)
## Inverse the axis
The direction of linear gauge axis can be customized by the [`isAxisInversed`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/isAxisInversed.html) property.
When the [`isAxisInversed`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/isAxisInversed.html) property is true, the axis can be placed in an inverse direction. The default value of the [`isAxisInversed`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/isAxisInversed.html) property is false.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(isAxisInversed: true)
),
),
);
}
{% endhighlight %}
You can see that the axis values are displayed from 100 to 0 as the axis track is inversed.
![Inverse linear gauge for axis](images/axis/axis_inversed.png)
## Extend the axis
The axis track can be extended by the [`axisTrackExtent`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/axisTrackExtent.html) property. This will extend the axis track in both ends. The following code sample demonstrates this.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.white,
home: Scaffold(
body: Center(
child: child: SfLinearGauge(maximum: 50, axisTrackExtent: 50),
),
),
);
}
{% endhighlight %}
![Extend linear gauge axis tack](images/axis/extend_axis.png)
## Change axis track visibility
You can hide the axis track by setting the [`showAxisTrack`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/showAxisTrack.html) property to false. The default value of this property is true.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(showAxisTrack: false)
),
),
);
}
{% endhighlight %}
![Hide linear gauge axis track](images/axis/hide_axis_track.png)
## Customize axis values
Linear gauge allows you to display a set of values along with a custom axis based on your business logic by using the [`onGenerateLabels`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/onGenerateLabels.html) and [`valueToFactorCallback`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/valueToFactorCallback.html) callbacks.
{% highlight dart %}
double pointerValue = 50.0;
// To return the label value based on interval
double _calculateLabelValue(num value) {
if (value == 0) {
return 0;
} else if (value == 1) {
return 2;
} else if (value == 2) {
return 5;
} else if (value == 3) {
return 10;
} else if (value == 4) {
return 20;
} else if (value == 5) {
return 30;
} else if (value == 6) {
return 50;
} else if (value == 7) {
return 100;
} else {
return 150;
}
}
Widget _getLinearGauge() {
return Container(
child: SfLinearGauge(
minimum: 0,
maximum: 150.0,
interval: 18.75,
animateAxis: true,
animateRange: true,
labelPosition: LinearLabelPosition.outside,
tickPosition: LinearElementPosition.outside,
valueToFactorCallback: (value) {
if (value >= 0 && value <= 2) {
return (value * 0.125) / 2;
} else if (value > 2 && value <= 5) {
return (((value - 2) * 0.125) / (5 - 2)) + (1 * 0.125);
} else if (value > 5 && value <= 10) {
return (((value - 5) * 0.125) / (10 - 5)) + (2 * 0.125);
} else if (value > 10 && value <= 20) {
return (((value - 10) * 0.125) / (20 - 10)) + (3 * 0.125);
} else if (value > 20 && value <= 30) {
return (((value - 20) * 0.125) / (30 - 20)) + (4 * 0.125);
} else if (value > 30 && value <= 50) {
return (((value - 30) * 0.125) / (50 - 30)) + (5 * 0.125);
} else if (value > 50 && value <= 100) {
return (((value - 50) * 0.125) / (100 - 50)) + (6 * 0.125);
} else if (value > 100 && value <= 150) {
return (((value - 100) * 0.125) / (150 - 100)) + (7 * 0.125);
} else {
return 1;
}
},
onGenerateLabels: () {
final List<LinearAxisLabel> _visibleLabels = <LinearAxisLabel>[];
for (num i = 0; i < 9; i++) {
final double _value = _calculateLabelValue(i);
final LinearAxisLabel label = LinearAxisLabel(
text: _value.toInt().toString(),
value: (i * 18.75).toDouble());
_visibleLabels.add(label);
}
return _visibleLabels;
},
markerPointers: [
LinearShapePointer(
value: pointerValue,
onChanged: (value) =>
{
setState(() => {pointerValue = value})
},
color: Color(0xff06589C),
width: 24,
position: LinearElementPosition.cross,
shapeType: LinearShapePointerType.triangle,
height: 16)
],
),
margin: EdgeInsets.all(10));
}
{% endhighlight %}
![Custom axis track](images/axis/custom_axis.png)

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 78 KiB

Двоичные данные
Flutter/linear-gauge/images/shape-pointer/free-drag-behavior.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 88 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 64 KiB

Двоичные данные
Flutter/linear-gauge/images/widget-pointer/free-drag-behavior.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 64 KiB

Просмотреть файл

@ -0,0 +1,168 @@
---
layout: post
title: Interaction in Flutter Linear Gauge widget | Syncfusion
description: Learn here all about the interactions in Syncfusion Flutter Linear Gauge (SfLinearGauge) widget and more
platform: Flutter
control: SfLinearGauge
documentation: ug
---
# Interaction in Flutter Linear Gauge (SfLinearGauge)
The shape and widget marker pointers in a Linear Gauge can be moved from one value to another by swiping or drag gestures.
## Interaction with marker pointers
The `onChanged` callback is used to change the value of the marker pointer at run-time.
The following code sample demonstrates how to update simple marker pointer value based on swipe or drag gestures.
{% highlight dart %}
double shapePointerValue = 25;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(
markerPointers: [
LinearShapePointer(
value: shapePointerValue,
//Changes the value of shape pointer based on interaction
onChanged: (value) {
setState(() {
shapePointerValue = value;
});
},
color: Colors.blue[800]),
],
),
),
),
);
}
{% endhighlight %}
![Simple pointer interaction in linear gauge](images/interaction/simple_interaction.gif)
The following code sample demonstrates how to update multiple marker pointer values based on swipe or drag gesture.
{% highlight dart %}
double shapePointerValue = 85;
double barPointerValue = 85;
double widgetPointerValue = 26;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
children: [
SfLinearGauge(
barPointers: [LinearBarPointer(value: shapePointerValue)],
markerPointers: [
LinearShapePointer(
value: shapePointerValue,
onChanged: (value) {
setState(() {
shapePointerValue = value;
});
},
color: Colors.blue[800]
),
],
),
SizedBox(height: 30),
SfLinearGauge(
barPointers: [LinearBarPointer(value: barPointerValue)],
markerPointers: [
LinearWidgetPointer(
position: LinearElementPosition.outside,
value: barPointerValue,
onChanged: (value) {
setState(() {
barPointerValue = value;
});
},
child: Container(
height: 20,
width: 20,
decoration: BoxDecoration(
color: Colors.orange[500], shape: BoxShape.circle)
),
),
],
),
SizedBox(height: 25),
SfLinearGauge(
axisTrackStyle: LinearAxisTrackStyle(
thickness: 10
),
markerPointers: [
LinearShapePointer(
value: widgetPointerValue,
shapeType: LinearShapePointerType.invertedTriangle,
position: LinearElementPosition.cross,
onChanged: (value) {
setState(() {
widgetPointerValue = value;
});
},
color: widgetPointerValue < 40
? Colors.green
: widgetPointerValue < 80
? Colors.orange
: Colors.red
),
LinearWidgetPointer(
value: widgetPointerValue,
onChanged: (value) {
setState(() {
widgetPointerValue = value;
});
},
child: Container(
width: 55,
height: 45,
child: Center(
child: Text(
widgetPointerValue.toStringAsFixed(0),
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20,
color: widgetPointerValue < 40
? Colors.green
: widgetPointerValue < 80
? Colors.orange
: Colors.red
),
),
),
),
position: LinearElementPosition.outside,
),
],
ranges: [
LinearGaugeRange(
endValue: widgetPointerValue,
color: widgetPointerValue < 40
? Colors.green
: widgetPointerValue < 80
? Colors.orange
: Colors.red,
position: LinearElementPosition.cross)
],
),
],
mainAxisAlignment: MainAxisAlignment.center
)),
)
);
{% endhighlight %}
![Shape pointer interaction in linear gauge](images/interaction/interaction.gif)

Просмотреть файл

@ -0,0 +1,350 @@
---
layout: post
title: Shape Marker Pointer in Flutter Linear Gauge widget | Syncfusion
description: Learn here all about adding and customizing Shape Marker Pointer of Syncfusion Flutter Linear Gauge (SfLinearGauge) widget and more.
platform: Flutter
control: SfLinearGauge
documentation: ug
---
# Shape Marker Pointer in Flutter Linear Gauge (SfLinearGauge)
The [`LinearShapePointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer-class.html) in [`SfLinearGauge`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge-class.html) have the following pre-defined shapes to mark a specific value. The default shape pointer is `invertedTriangle`.
1. `Triangle`
2. `Inverted Triangle`
3. `Circle`
4. `Diamond`
5. `Rectangle`
The following is the default appearance of default shape pointer.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(
markerPointers: [LinearShapePointer(value: 50)]
),
),
),
);
}
{% endhighlight %}
![Initialize linear gauge for shape pointer](images/shape-pointer/default_shape_pointer.png)
## Change the size
The size of the marker pointer can be changed by the [`height`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/height.html) and [`width`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/width.html) properties of [`LinearShapePointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer-class.html). The following code sample demonstrates how to change the size of a shape pointer.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.white,
home: Scaffold(
body: Center(
child: SfLinearGauge(markerPointers: [
LinearShapePointer(value: 50, height: 25, width: 25)
]),
),
),
);
}
{% endhighlight %}
![Set size of linear gauge shape pointer](images/shape-pointer/shape_pointer_size.png)
## Customize color
The color of the shape pointer can be changed by the [`color`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/color.html) property. The following code example demonstrates the same.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.white,
home: Scaffold(
body: Center(
child: SfLinearGauge(markerPointers: [
LinearShapePointer(value: 50, color: Colors.redAccent)
]),
),
),
);
{% endhighlight %}
![Change shape pointer color](images/shape-pointer/shape_pointer_color.png)
## Customize the border
The border can be customized by the [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/borderColor.html) and [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/borderWidth.html) properties of the [`LinearShapePointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer-class.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.white,
home: Scaffold(
body: Center(
child: SfLinearGauge(markerPointers: [
LinearShapePointer(
value: 50, borderColor: Colors.redAccent, borderWidth: 2)
]),
),
),
);
}
{% endhighlight %}
![Customize shape pointer border](images/shape-pointer/shape_border.png)
## Customize the elevation
The elevation can be customized by the [`elevation`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/elevation.html) and [`elevationColor`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/elevationColor.html) properties.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.white,
home: Scaffold(
body: Center(
child: Container(
color: Colors.white,
child: SfLinearGauge(markerPointers: [
LinearShapePointer(
value: 50,
shapeType: LinearShapePointerType.circle,
elevation: 5,
elevationColor: Colors.blueGrey)
]),
),
),
),
);
}
{% endhighlight %}
![Change shape pointer elevation](images/shape-pointer/pointer_elevation.png)
## Change marker alignment
The marker pointer alignment can be changed by the [`markerAlignment`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/markerAlignment.html) property of [`LinearShapePointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer-class.html).The available marker pointer alignments are `start`, `end`, and `center`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(axisTrackExtent: 30, markerPointers: [
LinearShapePointer(
value: 0, markerAlignment: LinearMarkerAlignment.start)
]),
),
),
);
}
{% endhighlight %}
![Change shape pointer alignment](images/shape-pointer/shape_marker_alignment.png)
## Customize position
By default, the shape pointer is positioned `outside` the axis. This position can be changed by the [`position`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/position.html) property of a [`LinearShapePointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer-class.html). It is possible to position the shape pointer `inside`, `cross`, or `outside` the axis. The following code sample demonstrates how to change the shape pointer position to inside the axis.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(markerPointers: [
LinearShapePointer(
value: 55,
shapeType: LinearShapePointerType.triangle,
position: LinearElementPosition.inside)
]),
),
),
);
}
{% endhighlight %}
![Change shape pointer position](images/shape-pointer/shape_pointer_position.png)
## Customize offset
In addition to position the shape pointer, it is also possible to change the offset of the shape pointer. The [`offset`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/offset.html) is the distance from the axis and it cannot be negative and The cross positioned elements will not get affected by the [`offset`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/offset.html) value. The following code sample demonstrates how to change the [`offset`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer/offset.html) value of the shape pointer.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(markerPointers: [
LinearShapePointer(
value: 50,
offset: 25,
shapeType: LinearShapePointerType.triangle,
position: LinearElementPosition.inside)
]),
),
),
);
}
{% endhighlight %}
![Customize linear gauge bar pointer offset](images/shape-pointer/shape_pointer_offset.png)
## Drag behavior
You can drag the pointers freely to any position when adding multiple pointers by setting the `dragBehavior` property to `LinearMarkerDragBehavior.free`.
The `LinearMarkerDragBehavior.constrained` can be used to limit the active pointer dragging beyond the other pointers.
### Free
{% highlight dart %}
double _firstPointer = 30;
double _secondPointer = 70;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfLinearGauge(
markerPointers: [
LinearShapePointer(
value: _firstPointer,
height: 25,
width: 25,
shapeType: LinearShapePointerType.invertedTriangle,
dragBehavior: LinearMarkerDragBehavior.free,
onChanged: (double newValue) {
setState(() {
_firstPointer = newValue;
});
},
),
LinearShapePointer(
value: _secondPointer,
height: 25,
width: 25,
shapeType: LinearShapePointerType.invertedTriangle,
dragBehavior: LinearMarkerDragBehavior.free,
onChanged: (double newValue) {
setState(() {
_secondPointer = newValue;
});
},
),
],
),
);
}
{% endhighlight %}
![Pointers drag behavior](images/shape-pointer/free-drag-behavior.gif)
### Constrained
{% highlight dart %}
double _firstPointer = 30;
double _secondPointer = 70;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfLinearGauge(
markerPointers: [
LinearShapePointer(
value: _firstPointer,
height: 25,
width: 25,
shapeType: LinearShapePointerType.invertedTriangle,
dragBehavior: LinearMarkerDragBehavior.constrained,
onChanged: (double newValue) {
setState(() {
_firstPointer = newValue;
});
},
),
LinearShapePointer(
value: _secondPointer,
height: 25,
width: 25,
shapeType: LinearShapePointerType.invertedTriangle,
dragBehavior: LinearMarkerDragBehavior.constrained,
onChanged: (double newValue) {
setState(() {
_secondPointer = newValue;
});
},
),
],
),
);
}
{% endhighlight %}
![Pointers drag behavior](images/shape-pointer/constraint-drag-behavior.gif)
## Handle onChangeStart, onChanged, and onChangeEnd callbacks
The [`LinearShapePointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearShapePointer-class.html) provides the `onChangeStart`, `onChanged`, and `onChangeEnd` callbacks. The `onChangeStart` callback will be called when the user start dragging the pointer, the `onChanged` callback will be called when dragging the pointer and the `onChangeEnd` callback will be called when the user stops the pointer dragging.
{% highlight dart %}
double _value = 50;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfLinearGauge(
markerPointers: [
LinearShapePointer(
value: _value,
onChangeStart: (double newValue) {
_value = newValue;
},
onChanged: (double newValue) {
setState(() {
_value = newValue;
});
},
onChangeEnd: (double newValue) {
_value = newValue;
},
shapeType: LinearShapePointerType.invertedTriangle,
),
],
),
);
}
{% endhighlight %}

Просмотреть файл

@ -0,0 +1,247 @@
---
layout: post
title: Widget Marker Pointer in Flutter Linear Gauge widget | Syncfusion
description: Learn here all about adding and customizing Widget Marker Pointer of Syncfusion Flutter Linear Gauge (SfLinearGauge) widget and more.
platform: Flutter
control: SfLinearGauge
documentation: ug
---
# Widget Marker Pointer in Flutter Linear Gauge (SfLinearGauge)
The [`LinearWidgetPointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearWidgetPointer/LinearWidgetPointer.html) in [`SfLinearGauge`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/SfLinearGauge/SfLinearGauge.html) allows to use any Flutter widget as marker pointer. The following code sample uses a [`container`](https://api.flutter.dev/flutter/widgets/Container-class.html) as marker widget.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(markerPointers: [
LinearWidgetPointer(
value: 50,
child: Container(height: 14, width: 14, color: Colors.redAccent),
),
]),
),
),
);
}
{% endhighlight %}
![Initialize linear gauge for widget pointer](images/widget-pointer/default_widget_pointer.png)
## Change marker alignment
The widget marker pointer's alignment can be changed by the [`markerAlignment`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearWidgetPointer/markerAlignment.html) property of [`LinearWidgetPointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearWidgetPointer-class.html). The available marker positions are `start`, `end`, and `center`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(axisTrackExtent: 30, markerPointers: [
LinearWidgetPointer(
value: 0,
markerAlignment: LinearMarkerAlignment.center,
child:
Container(height: 14, width: 14, color: Colors.redAccent)),
]),
),
),
);
}
{% endhighlight %}
![Customize size of widget pointer](images/widget-pointer/widget_alignment.png)
## Change the position
By default, the shape pointer is positioned `outside` the axis. This position can be changed by the [`position`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearWidgetPointer/position.html) property of a [`LinearWidgetPointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearWidgetPointer/position.html). It is possible to position the shape pointer `inside`, `cross`, or `outside` the axis. The following code sample demonstrates how to change the shape pointer position to `inside` the axis.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(markerPointers: [
LinearWidgetPointer(
value: 55,
position: LinearElementPosition.inside,
child: Container(height: 14, width: 14, color: Colors.redAccent),
),
]),
),
),
);
}
{% endhighlight %}
![Change widget pointer position](images/widget-pointer/widget_pointer_position.png)
## Change the offset
In addition to position the widget marker pointer, it is also possible to change the offset of the shape pointer. The [`offset`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearWidgetPointer/offset.html) is the distance from the axis and it cannot be negative. The cross positioned elements will not get affected by the [`offset`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearWidgetPointer/offset.html) value. The following code sample demonstrates how to change the offset value of the shape pointer.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfLinearGauge(markerPointers: [
LinearWidgetPointer(
value: 50,
offset: 25,
position: LinearElementPosition.inside,
child: Container(
height: 14,
width: 14,
color: Colors.redAccent
),
),
]),
),
),
);
}
{% endhighlight %}
![Customize linear gauge bar pointer offset](images/widget-pointer/widget_pointer_offset.png)
## Drag behavior
You can drag the pointers freely to any position when adding multiple pointers by setting the `dragBehavior` property to `LinearMarkerDragBehavior.free`.
The `LinearMarkerDragBehavior.constrained` can be used to limit the active pointer dragging beyond the other pointers.
### Free
{% highlight dart %}
double _firstPointer = 30;
double _secondPointer = 70;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfLinearGauge(
markerPointers: [
LinearWidgetPointer(
value: _firstPointer,
dragBehavior: LinearMarkerDragBehavior.free,
onChanged: (double newValue) {
setState(() {
_firstPointer = newValue;
});
},
position: LinearElementPosition.outside,
child: Icon(Icons.location_pin, color: Colors.blue, size: 30),
),
LinearWidgetPointer(
value: _secondPointer,
position: LinearElementPosition.outside,
dragBehavior: LinearMarkerDragBehavior.free,
onChanged: (double newValue) {
setState(() {
_secondPointer = newValue;
});
},
child: Icon(Icons.location_pin, color: Colors.red, size: 30),
),
],
),
);
}
{% endhighlight %}
![Pointers drag behavior](images/widget-pointer/free-drag-behavior.gif)
### Constrained
{% highlight dart %}
double _firstPointer = 30;
double _secondPointer = 70;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfLinearGauge(
markerPointers: [
LinearWidgetPointer(
value: _firstPointer,
dragBehavior: LinearMarkerDragBehavior.constrained,
onChanged: (double newValue) {
setState(() {
_firstPointer = newValue;
});
},
position: LinearElementPosition.outside,
child: Icon(Icons.location_pin, color: Colors.blue, size: 30),
),
LinearWidgetPointer(
value: _secondPointer,
position: LinearElementPosition.outside,
dragBehavior: LinearMarkerDragBehavior.constrained,
onChanged: (double newValue) {
setState(() {
_secondPointer = newValue;
});
},
child: Icon(Icons.location_pin, color: Colors.red, size: 30),
),
],
),
);
}
{% endhighlight %}
![Pointers drag behavior](images/widget-pointer/constraint-drag-behavior.gif)
## Handle onChangeStart, onChanged, and onChangeEnd callbacks
The [`LinearWidgetPointer`](https://pub.dev/documentation/syncfusion_flutter_gauges/latest/gauges/LinearWidgetPointer-class.html) provides the `onChangeStart`, `onChanged`, and `onChangeEnd` callbacks. The `onChangeStart` callback will be called when the user start dragging the pointer, the `onChanged` callback will be called when dragging the pointer and the `onChangeEnd` callback will be called when the user stops the pointer dragging.
{% highlight dart %}
double _value = 50;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfLinearGauge(
markerPointers: [
LinearWidgetPointer(
value: _value,
onChangeStart: (double newValue) {
_value = newValue;
},
onChanged: (double newValue) {
setState(() {
_value = newValue;
});
},
onChangeEnd: (double newValue) {
_value = newValue;
},
child: Container(height: 14, width: 14, color: Colors.redAccent),
),
],
),
);
}
{% endhighlight %}

Двоичные данные
Flutter/maps/images/line-layer/line_stroke_cap.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 21 KiB

Двоичные данные
Flutter/maps/images/markers/fit_bounds.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 54 KiB

Двоичные данные
Flutter/maps/images/markers/marker_customization.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 38 KiB

Двоичные данные
Flutter/maps/images/polyline-layer/polyline-stroke-cap.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 23 KiB

999
Flutter/maps/markers.md Normal file
Просмотреть файл

@ -0,0 +1,999 @@
---
layout: post
title: Markers in Flutter Maps widget | Syncfusion
description: Learn here all about the Markers feature of Syncfusion Flutter Maps (SfMaps) widget to customize its appearance including text, icon and more.
platform: Flutter
control: SfMaps
documentation: ug
---
# Markers in Flutter Maps (SfMaps)
Markers can be used to denote the locations. It is possible to use the built-in symbols or display a custom widget at a specific latitude and longitude on a map.
## Adding markers
### Shape layer
You can show markers at any position on the map by providing latitude and longitude position to the [`MapMarker`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker-class.html), which is the widget returns from the [`markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html) property.
The [`markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html) callback will be called number of times equal to the value specified in the [`initialMarkersCount`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/initialMarkersCount.html) property. The default value of the [`initialMarkersCount`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/initialMarkersCount.html) property is `null`.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeSource _dataSource;
@override
void initState() {
_data = const <Model>[
Model('Brazil', -14.235004, -51.92528),
Model('Germany', 51.16569, 10.451526),
Model('Australia', -25.274398, 133.775136),
Model('India', 20.593684, 78.96288),
Model('Russia', 61.52401, 105.318756)
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
dataCount: _data.length,
primaryValueMapper: (index) => _data[index].country,
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: _dataSource,
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
iconColor: Colors.blue,
);
},
),
],
),
)),
);
}
class Model {
const Model(this.country, this.latitude, this.longitude);
final String country;
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
![default marker](images/markers/default_marker.png)
N>
* Refer the [`markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html), for returning the [`MapMarker`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker-class.html).
* Refer the [`controller`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer/controller.html), for dynamically updating the markers.
### Tile layer
You can show markers at any position on the map by providing latitude and longitude position to the [`MapMarker`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker-class.html), which is the widget returns from the [`MapTileLayer.markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html) property.
The [`markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html) callback will be called number of times equal to the value specified in the [`initialMarkersCount`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/initialMarkersCount.html) property. The default value of the [`initialMarkersCount`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/initialMarkersCount.html) property is `null`.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
@override
void initState() {
_data = const <Model>[
Model('Brazil', -14.235004, -51.92528),
Model('Germany', 51.16569, 10.451526),
Model('Australia', -25.274398, 133.775136),
Model('India', 20.593684, 78.96288),
Model('Russia', 61.52401, 105.318756)
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfMaps(
layers: <MapLayer>[
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
iconColor: Colors.blue,
);
},
),
],
),
),
);
}
class Model {
const Model(this.country, this.latitude, this.longitude);
final String country;
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
![Tile layer marker](images/markers/tile_layer_marker.png)
N>
* Refer the [`markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html), for returning the [`MapMarker`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker-class.html).
* Refer the [`controller`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/controller.html) for dynamically updating the markers.
## Appearance customization
You can customize the built-in markers appearance using the [`iconType`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/iconType.html), [`iconColor`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/iconColor.html), [`iconStrokeColor`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/iconStrokeColor.html), [`iconStrokeWidth`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/iconStrokeWidth.html), and [`size`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/size.html) properties of the [`MapMarker`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker-class.html).
* **Alignment** - You can change the position of the marker from the given coordinate using the `alignment` property. The default value is `Alignment.center`. The available alignment options are `topLeft`, `topRight`, `topCenter`, `centerLeft`, `center`, `centerRight`, `bottomLeft`, `bottomCenter`, `bottomRight`.
* **Offset** - You can adjust the marker position from the given coordinate using the `offset` property. The default value of the `offset` property is `Offset.zero`.
N>
* The default value of the [`iconType`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/iconType.html) is `MapIconType.circle`.
* The default value of the [`iconStrokeWidth`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/iconStrokeWidth.html) is `1.0`.
* The default value of the [`iconColor`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/iconColor.html) is `Colors.blue`.
* The default value of the [`size`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker/size.html) is `Size(14.0, 14.0)`.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeSource _dataSource;
@override
void initState() {
_data = <Model>[
Model(-14.235004, -51.92528),
Model(51.16569, 10.451526),
Model(-25.274398, 133.775136),
Model(20.593684, 78.96288),
Model(61.52401, 105.318756)
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: _dataSource,
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
iconType: MapIconType.triangle,
size: Size(18, 18),
alignment: Alignment.center,
offset: Offset(0, 9),
iconColor: Colors.green[200],
iconStrokeColor: Colors.green[900],
iconStrokeWidth: 2,
);
},
),
],
),
)),
);
}
class Model {
Model(this.latitude, this.longitude);
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
![marker customization](images/markers/marker_customization.png)
## Adding custom markers
You can show custom marker using the `child` property of the [`MapMarker`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapMarker-class.html) which returns from the [`markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html).
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late List<Widget> _iconsList;
late MapShapeSource _dataSource;
@override
void initState() {
_data = <Model>[
Model(-14.235004, -51.92528),
Model(51.16569, 10.451526),
Model(-25.274398, 133.775136),
Model(20.593684, 78.96288),
Model(61.52401, 105.318756)
];
_iconsList = <Widget>[
Icon(Icons.add_location),
Icon(Icons.airplanemode_active),
Icon(Icons.add_alarm),
Icon(Icons.accessibility_new),
Icon(Icons.account_balance)
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: _dataSource,
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
child: _iconsList[index],
);
},
),
],
),
)),
);
}
class Model {
Model(this.latitude, this.longitude);
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
![custom marker](images/markers/custom_marker.png)
## Adding markers dynamically
You can add markers dynamically using the [`insertMarker`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayerController/insertMarker.html) method. The [`markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html) will be called for the respective index once [`insertMarker`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayerController/insertMarker.html) method is called. The [`controller`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer/controller.html) property of [`MapShapeLayer`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer-class.html) has to be set with the new instance of [`MapShapeLayerController`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayerController-class.html).
Marker will be inserted at the given index if the index value is less than or equal to the current available index and the marker will be added as a last item if the index value is greater than the current available index.
N> You can get the current markers count from [`MapShapeLayerController.markersCount`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayerController/markersCount.html).
### For shape layer
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeLayerController _controller;
late MapShapeSource _dataSource;
late Random random;
@override
void initState() {
_data = <Model>[
Model(-14.235004, -51.92528),
Model(51.16569, 10.451526),
Model(-25.274398, 133.775136),
Model(20.593684, 78.96288),
Model(61.52401, 105.318756)
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
_controller = MapShapeLayerController();
random = Random();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 350,
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
children: [
SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: _dataSource,
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
child: Icon(Icons.add_location),
);
},
controller: _controller,
),
],
),
ElevatedButton(
child: Text('Add marker'),
onPressed: () {
_data.add(Model(-180 + random.nextInt(360).toDouble(),
-55 + random.nextInt(139).toDouble()));
_controller.insertMarker(5);
},
),
],
),
),
)),
);
}
class Model {
Model(this.latitude, this.longitude);
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
### For Tile layer
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapTileLayerController _controller;
late Random random;
@override
void initState() {
_data = <Model>[
Model(-14.235004, -51.92528),
Model(51.16569, 10.451526),
Model(-25.274398, 133.775136),
Model(20.593684, 78.96288),
Model(61.52401, 105.318756)
];
_controller = MapTileLayerController();
random = Random();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 350,
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
children: [
SfMaps(
layers: <MapLayer>[
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
child: Icon(Icons.add_location),
);
},
controller: _controller,
),
],
),
ElevatedButton(
child: Text('Add marker'),
onPressed: () {
_data.add(Model(-180 + random.nextInt(360).toDouble(),
-55 + random.nextInt(139).toDouble()));
_controller.insertMarker(5);
},
),
],
),
),
)),
);
}
class Model {
Model(this.latitude, this.longitude);
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
![Add markers dynamically](images/markers/add-markers.gif)
## Updating the existing markers
You can update multiple markers at a same time by passing indices to the [`updateMarkers`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayerController/updateMarkers.html) method in the [`MapShapeLayerController`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayerController-class.html). The [`markerBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html) will be called again for the respective indices once [`updateMarkers`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayerController/updateMarkers.html) method is called.
N>
* You can get the current markers count from [`MapShapeLayerController.markersCount`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayerController/markersCount.html).
* You can refer this [`snippet`](https://help.syncfusion.com/flutter/maps/markers#for-tile-layer) to update the markers dynamically for tile layer.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeLayerController _controller;
late Widget _markerWidget;
late MapShapeSource _dataSource;
@override
void initState() {
_data = <Model>[
Model(-14.235004, -51.92528),
Model(51.16569, 10.451526),
Model(-25.274398, 133.775136),
Model(20.593684, 78.96288),
Model(61.52401, 105.318756)
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
_controller = MapShapeLayerController();
_markerWidget = Icon(Icons.add_location);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 350,
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
children: [
SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: _dataSource,
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index){
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
child: _markerWidget,
);
},
controller: _controller,
),
],
),
ElevatedButton(
child: Text('Update marker'),
onPressed: () {
List<int> updateList = <int>[1, 2];
_markerWidget = Icon(Icons.people);
_controller.updateMarkers(updateList);
},
),
],
),
),
)
),
);
}
class Model {
Model(this.latitude, this.longitude);
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
![Update markers dynamically](images/markers/update-markers.gif)
## Deleting a marker
You can remove marker at any index using the [`removeMarkerAt`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayerController/removeMarkerAt.html) method.
N>
* You can get the current markers count from [`MapShapeLayerController.markersCount`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayerController/markersCount.html).
* You can refer this [`snippet`](https://help.syncfusion.com/flutter/maps/markers#for-tile-layer) to update the markers dynamically for tile layer.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeLayerController _controller;
late MapShapeSource _dataSource;
@override
void initState() {
_data = <Model>[
Model(-14.235004, -51.92528),
Model(51.16569, 10.451526),
Model(-25.274398, 133.775136),
Model(20.593684, 78.96288),
Model(61.52401, 105.318756)
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
_controller = MapShapeLayerController();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 350,
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
children: [
SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: _dataSource,
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index){
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
child: Icon(Icons.add_location),
);
},
controller: _controller,
),
],
),
ElevatedButton(
child: Text('Remove marker'),
onPressed: () {
_controller.removeMarkerAt(4);
},
),
],
),
),
)
),
);
}
class Model {
Model(this.latitude, this.longitude);
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
## Clearing the markers
You can clear all markers using the [`clearMarkers`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayerController/clearMarkers.html) method.
N>
* You can get the current markers count from [`MapShapeLayerController.markersCount`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayerController/markersCount.html).
* You can refer this [`snippet`](https://help.syncfusion.com/flutter/maps/markers#for-tile-layer) to update the markers dynamically for tile layer.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeLayerController _controller;
late MapShapeSource _dataSource;
@override
void initState() {
_data = <Model>[
Model(-14.235004, -51.92528),
Model(51.16569, 10.451526),
Model(-25.274398, 133.775136),
Model(20.593684, 78.96288),
Model(61.52401, 105.318756)
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
_controller = MapShapeLayerController();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 350,
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
children: [
SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: _dataSource,
initialMarkersCount: 5,
markerBuilder: (BuildContext context, int index){
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
child: Icon(Icons.add_location),
);
},
controller: _controller,
),
],
),
ElevatedButton(
child: Text('Clear marker'),
onPressed: () {
_controller.clearMarkers();
},
),
],
),
),
)
),
);
}
class Model {
Model(this.latitude, this.longitude);
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
## Marker controller
You can position the marker at the tapped position by converting touch pixel point into coordinates using the [`pixelToLatLng`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayerController/pixelToLatLng.html) method of [`MapTileLayerController`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayerController-class.html) in the [`MapTileLayer`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer-class.html) and the [`MapShapeLayerController`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayerController-class.html) in the [`MapShapeLayer`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer-class.html).
N> It is applicable for both tile layer and shape layer.
### Shape layer
{% tabs %}
{% highlight Dart %}
late MapLatLng _markerPosition;
late _CustomZoomPanBehavior _mapZoomPanBehavior;
late MapShapeLayerController _controller;
late MapShapeSource _mapSource;
@override
void initState() {
_controller = MapShapeLayerController();
_mapZoomPanBehavior = _CustomZoomPanBehavior()
..zoomLevel = 1
..onTap = updateMarkerChange;
_mapSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
void updateMarkerChange(Offset position) {
_markerPosition = _controller.pixelToLatLng(position);
/// Removed [MapShapeLayer.initialMarkersCount] property and updated
/// markers only when the user taps.
if (_controller.markersCount > 0) {
_controller.clearMarkers();
}
_controller.insertMarker(0);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 400,
width: 400,
child: MapShapeLayer(
source: _mapSource,
zoomPanBehavior: _mapZoomPanBehavior,
controller: _controller,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _markerPosition.latitude,
longitude: _markerPosition.longitude,
child: Icon(
Icons.location_on,
color: Colors.red,
size: 20,
),
);
},
),
),
),
);
}
class _CustomZoomPanBehavior extends MapZoomPanBehavior {
_CustomZoomPanBehavior();
late MapTapCallback onTap;
@override
void handleEvent(PointerEvent event) {
if (event is PointerUpEvent) {
onTap(event.localPosition);
}
super.handleEvent(event);
}
}
typedef MapTapCallback = void Function(Offset position);
{% endhighlight %}
{% endtabs %}
### Tile layer
{% tabs %}
{% highlight Dart %}
late MapLatLng _markerPosition;
late _CustomZoomPanBehavior _mapZoomPanBehavior;
late MapTileLayerController _controller;
@override
void initState() {
_controller = MapTileLayerController();
_mapZoomPanBehavior = _CustomZoomPanBehavior()
..onTap = updateMarkerChange;
super.initState();
}
void updateMarkerChange(Offset position) {
_markerPosition = _controller.pixelToLatLng(position);
/// Removed [MapTileLayer.initialMarkersCount] property and updated
/// markers only when the user taps.
if (_controller.markersCount > 0) {
_controller.clearMarkers();
}
_controller.insertMarker(0);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 400,
width: 400,
child: MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
zoomPanBehavior: _mapZoomPanBehavior,
controller: _controller,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _markerPosition.latitude,
longitude: _markerPosition.longitude,
child: Icon(
Icons.location_on,
color: Colors.red,
size: 20,
));
},
),
),
),
);
}
class _CustomZoomPanBehavior extends MapZoomPanBehavior {
_CustomZoomPanBehavior();
late MapTapCallback onTap;
@override
void handleEvent(PointerEvent event) {
if (event is PointerUpEvent) {
onTap(event.localPosition);
}
super.handleEvent(event);
}
}
typedef MapTapCallback = void Function(Offset position);
{% endhighlight %}
{% endtabs %}
![Position marker at tapped position](images/markers/marker-at-tapped-position.gif)
## Zoom markers to fit bounds
You can visualize a specific area on the map by specifying the northeast and southwest coordinate points to the `initialLatLngBounds` property in the `MapTileLayer` and `MapShapeLayer`. It renders the map by calculating the center coordinate and zoom level depending on the `initialLatLngBounds` value.
The `initialLatLngBounds` property can be set at load time alone. You can use the `latLngBounds` property of [`MapZoomPanBehavior`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapZoomPanBehavior-class.html) to dynamically update the map bounds.
{% tabs %}
{% highlight Dart %}
late List<_TouristPlaceDetails> _touristPlaces;
late MapZoomPanBehavior _zoomPanBehavior;
bool _canFitMarkers = false;
@override
void initState() {
_zoomPanBehavior = MapZoomPanBehavior();
_touristPlaces = <_TouristPlaceDetails>[
const _TouristPlaceDetails(
MapLatLng(-25.6953, -54.4367), 'Iguazu Falls, Argentina'),
const _TouristPlaceDetails(MapLatLng(-50.9423, -73.4068),
'Torres del Paine National Park, Patagonia, Chile'),
const _TouristPlaceDetails(
MapLatLng(-15.9254, -69.3354), 'Lake Titicaca, Bolivia'),
const _TouristPlaceDetails(
MapLatLng(-13.1631, -72.5450), 'Machu Picchu, Peru'),
const _TouristPlaceDetails(
MapLatLng(-0.1862504, -78.5706247), 'The Amazon via Quito, Ecuador'),
const _TouristPlaceDetails(
MapLatLng(5.9701, -62.5362), 'Angel Falls, Venezuela'),
const _TouristPlaceDetails(
MapLatLng(-14.0875, -75.7626), 'Huacachina, Peru'),
const _TouristPlaceDetails(
MapLatLng(-22.7953, -67.8361), 'Laguna Verde, Bolivia'),
const _TouristPlaceDetails(
MapLatLng(-50.5025092, -73.1997346), 'Perito Moreno, Venezuela'),
const _TouristPlaceDetails(
MapLatLng(-22.9068, -43.1729), 'Rio de Janeiro, Brazil'),
const _TouristPlaceDetails(
MapLatLng(5.1765, -59.4808), 'Kaieteur Falls, Guyana'),
const _TouristPlaceDetails(
MapLatLng(-33.4489, -70.6693), 'Santiago, Chile'),
const _TouristPlaceDetails(
MapLatLng(4.7110, -74.0721), 'Bogota, Colombia'),
const _TouristPlaceDetails(
MapLatLng(-1.3928, -78.4269), 'Banos, Ecuador'),
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SfMaps(
layers: <MapLayer>[
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
zoomPanBehavior: _zoomPanBehavior,
initialMarkersCount: _touristPlaces.length,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _touristPlaces[index].latLng.latitude,
longitude: _touristPlaces[index].latLng.longitude,
child: const Icon(
Icons.location_on,
color: Colors.red,
size: 20,
),
);
},
),
],
),
SizedBox(height: 10),
Container(
width: 300,
padding: EdgeInsets.zero,
child: CheckboxListTile(
activeColor: Colors.blue,
value: _canFitMarkers,
title: Text('Zoom marker to fit bounds'),
onChanged: (bool? value) {
_canFitMarkers = value!;
setState(() {
if (_canFitMarkers) {
// South America bounds.
_zoomPanBehavior.latLngBounds = const MapLatLngBounds(
MapLatLng(12.434375, -34.80546874999999),
MapLatLng(-55.891699218750006, -91.654150390625));
} else {
// World bounds.
_zoomPanBehavior.latLngBounds = const MapLatLngBounds(
MapLatLng(-90.0, -180.0), MapLatLng(90.0, 180.0));
}
});
},
),
),
],
),
);
}
class _TouristPlaceDetails {
const _TouristPlaceDetails(this.latLng, this.place);
final MapLatLng latLng;
final String place;
}
{% endhighlight %}
{% endtabs %}
![Zoom markers to fit bounds](images/markers/fit_bounds.jpg)

622
Flutter/maps/tooltip.md Normal file
Просмотреть файл

@ -0,0 +1,622 @@
---
layout: post
title: Tooltip in Flutter Maps widget | Syncfusion
description: Learn here all about adding the Tooltip feature of Syncfusion Flutter Maps (SfMaps) widget and more.
platform: Flutter
control: SfMaps
documentation: ug
---
# Tooltip in Flutter Maps (SfMaps)
Tooltip is used to indicate the shape, bubble, marker information during the tap, or click interaction. This section helps to learn about how to show tooltip for the shapes, bubbles, and markers in the maps and customize them.
## Tooltip for the shapes
It is used to clearly indicate the shape information on the tap or click. To show tooltip for the shape, return a widget in [`MapShapeLayer.shapeTooltipBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer/shapeTooltipBuilder.html). This widget will then be wrapped in the builtin shape which comes with the nose at the bottom.
The [`MapShapeLayer.shapeTooltipBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer/shapeTooltipBuilder.html) will be called with the corresponding index every time when you interacts with the shapes i.e., while tapping in touch devices and hover enter in the mouse enabled devices.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeSource _shapeSource;
@override
void initState() {
super.initState();
_data = <Model>[
Model('Asia', 50, '44,579,000 sq. km.'),
Model('Africa', 54, '30,370,000 sq. km.'),
Model('Europe', 51, '10,180,000 sq. km.'),
Model('North America', 23, '24,709,000 sq. km.'),
Model('South America', 12, '17,840,000 sq. km.'),
Model('Australia', 14, '8,600,000 sq. km.'),
];
_shapeSource = MapShapeSource.asset(
"assets/world_map.json",
shapeDataField: "continent",
dataCount: _data.length,
primaryValueMapper: (int index) => _data[index].continent,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: [
MapShapeLayer(
source: _shapeSource,
shapeTooltipBuilder: (BuildContext context, int index) {
return Container(
width: 180,
padding: const EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Stack(
children: [
Center(
child: Text(
_data[index].continent,
style: TextStyle(
color: Colors.white,
fontSize: Theme.of(context)
.textTheme
.bodyText2!
.fontSize),
),
),
const Icon(
Icons.map,
color: Colors.white,
size: 16,
),
],
),
const Divider(
color: Colors.white,
height: 10,
thickness: 1.2,
),
Text(
'Area : ' + _data[index].area,
style: TextStyle(
color: Colors.white,
fontSize:
Theme.of(context).textTheme.bodyText2!.fontSize),
),
],
),
);
},
tooltipSettings: const MapTooltipSettings(
color: Colors.blue,
strokeColor: Color.fromRGBO(252, 187, 15, 1),
strokeWidth: 1.5),
),
],
),
),
);
}
class Model {
const Model(this.continent, this.countriesCount, this.area);
final String continent;
final double countriesCount;
final String area;
}
{% endhighlight %}
{% endtabs %}
![Maps shape tooltip builder](images/tooltip/shape_tooltip_builder.png)
N>
* Refer the [`MapTooltipSettings`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings-class.html), for customizing the tooltip.
## Tooltip for the bubbles
It is used to clearly indicate the bubble information on the tap or click. To show tooltip for the bubble, return a widget in [MapShapeLayer.bubbleTooltipBuilder](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer/bubbleTooltipBuilder.html). This widget will then be wrapped in the builtin shape which comes with the nose at the bottom.
The [MapShapeLayer.bubbleTooltipBuilder](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer/bubbleTooltipBuilder.html) will be called with the corresponding index every time when you interacts with the bubbles i.e., while tapping in touch devices and hover enter in the mouse enabled devices.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeSource _shapeSource;
@override
void initState() {
super.initState();
_data = <Model>[
Model('Asia', 50, '44,579,000 sq. km.'),
Model('Africa', 54, '30,370,000 sq. km.'),
Model('Europe', 51, '10,180,000 sq. km.'),
Model('North America', 23, '24,709,000 sq. km.'),
Model('South America', 12, '17,840,000 sq. km.'),
Model('Australia', 14, '8,600,000 sq. km.'),
];
_shapeSource = MapShapeSource.asset(
"assets/world_map.json",
shapeDataField: "continent",
dataCount: _data.length,
primaryValueMapper: (int index) => _data[index].continent,
bubbleSizeMapper: (int index) => _data[index].countriesCount,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: [
MapShapeLayer(
source: _shapeSource,
bubbleTooltipBuilder: (BuildContext context, int index) {
return Container(
width: 150,
padding: const EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Stack(
children: [
Center(
child: Text(
_data[index].continent,
style: TextStyle(
color: Colors.white,
fontSize: Theme.of(context)
.textTheme
.bodyText2!
.fontSize),
),
),
const Icon(
Icons.flag,
color: Colors.white,
size: 16,
),
],
),
const Divider(
color: Colors.white,
height: 10,
thickness: 1.2,
),
Text(
'Total Countries : ' +
_data[index].countriesCount.toInt().toString(),
style: TextStyle(
color: Colors.white,
fontSize:
Theme.of(context).textTheme.bodyText2!.fontSize),
),
],
),
);
},
bubbleSettings: const MapBubbleSettings(
minRadius: 15,
maxRadius: 35,
),
tooltipSettings: const MapTooltipSettings(
color: Color.fromRGBO(98, 0, 238, 1),
strokeColor: Color.fromRGBO(252, 187, 15, 1),
strokeWidth: 1.5),
),
],
),
),
);
}
class Model {
const Model(this.continent, this.countriesCount, this.area);
final String continent;
final double countriesCount;
final String area;
}
{% endhighlight %}
{% endtabs %}
![Maps bubble tooltip builder](images/tooltip/bubble_tooltip_builder.png)
N>
* Refer the [`MapTooltipSettings`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings-class.html), for customizing the tooltip.
## Tooltip for the markers
It is used to clearly indicate the marker information on the tap or click. To show tooltip for the marker, return a widget in [MapLayer.markerTooltipBuilder](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerTooltipBuilder.html). This widget will then be wrapped in the builtin shape which comes with the nose at the bottom.
The [MapLayer.markerTooltipBuilder](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerTooltipBuilder.html) will be called with the corresponding index every time when you interacts with the markers i.e., while tapping in touch devices and hover enter in the mouse enabled devices.
{% tabs %}
{% highlight Dart %}
late List<WorldWonderModel> _data;
late MapShapeSource _shapeSource;
@override
void initState() {
super.initState();
_data = <WorldWonderModel>[
WorldWonderModel(
place: 'Chichen Itza',
country: 'Mexico',
latitude: 20.6843,
longitude: -88.5678),
WorldWonderModel(
place: 'Machu Picchu',
country: 'Peru',
latitude: -13.1631,
longitude: -72.5450),
WorldWonderModel(
place: 'Christ the Redeemer',
country: 'Brazil',
latitude: -22.9519,
longitude: -43.2105),
WorldWonderModel(
place: 'Colosseum',
country: 'Rome',
latitude: 41.8902,
longitude: 12.4922),
WorldWonderModel(
place: 'Petra',
country: 'Jordan',
latitude: 30.3285,
longitude: 35.4444),
WorldWonderModel(
place: 'Taj Mahal',
country: 'India',
latitude: 27.1751,
longitude: 78.0421),
WorldWonderModel(
place: 'Great Wall of China',
country: 'China',
latitude: 40.4319,
longitude: 116.5704)
];
_shapeSource = MapShapeSource.asset(
"assets/world_map.json",
shapeDataField: "country",
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: [
MapShapeLayer(
source: _shapeSource,
initialMarkersCount: _data.length,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _data[index].latitude,
longitude: _data[index].longitude,
child: const Icon(
Icons.location_on,
color: Colors.red,
),
);
},
markerTooltipBuilder: (BuildContext context, int index) {
return Container(
width: 150,
padding: const EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Stack(
children: [
Center(
child: Text(
_data[index].country,
style: TextStyle(
color: Colors.white,
fontSize: Theme.of(context)
.textTheme
.bodyText2!
.fontSize),
),
),
const Icon(
Icons.tour,
color: Colors.white,
size: 16,
),
],
),
const Divider(
color: Colors.white,
height: 10,
thickness: 1.2,
),
Text(
_data[index].place,
style: TextStyle(
color: Colors.white,
fontSize:
Theme.of(context).textTheme.bodyText2!.fontSize),
),
],
),
);
},
tooltipSettings: const MapTooltipSettings(
color: Colors.red,
strokeColor: Colors.black,
strokeWidth: 1.5),
),
],
),
),
);
}
class WorldWonderModel {
const WorldWonderModel(
{required this.place,
required this.country,
required this.latitude,
required this.longitude});
final String place;
final String country;
final double latitude;
final double longitude;
}
{% endhighlight %}
{% endtabs %}
![Maps marker tooltip builder](images/tooltip/marker_tooltip_builder.png)
N>
* Refer the [`MapTooltipSettings`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings-class.html), for customizing the tooltip.
## Appearance customization
You can customize the below appearances of the tooltip.
* **Background color** - Change the background color of the tooltip in the maps using the [`MapTooltipSettings.color`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/color.html) property.
* **Stroke color** - Change the stroke color of the tooltip in the maps using the [`MapTooltipSettings.strokeColor`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/strokeColor.html) property.
* **Stroke width** - Change the stroke width of the tooltip in the maps using the [`MapTooltipSettings.strokeWidth`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/strokeWidth.html) property.
* **Visibility** - Change the duration of the tooltip visibility using the `hideDelay` property. The default value of the `hideDelay` property is 3. By default, tooltip will hide automatically after 3 seconds of inactivity for mobile platforms. Also, you can increase or decrease the tooltip duration or show tooltip always by setting `double.infinity` to the `hideDelay` property.
N> For mobile platforms, the `hideDelay` option is supported. When you hover over the shape, bubble, or marker on the web or desktop, a tooltip will appear. When you remove hover from the shape, it will disappear.
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeSource _shapeSource;
@override
void initState() {
super.initState();
_data = <Model>[
Model('Asia', 50, '44,579,000 sq. km.'),
Model('Africa', 54, '30,370,000 sq. km.'),
Model('Europe', 51, '10,180,000 sq. km.'),
Model('North America', 23, '24,709,000 sq. km.'),
Model('South America', 12, '17,840,000 sq. km.'),
Model('Australia', 14, '8,600,000 sq. km.'),
];
_shapeSource = MapShapeSource.asset(
"assets/world_map.json",
shapeDataField: "continent",
dataCount: _data.length,
primaryValueMapper: (int index) => _data[index].continent,
bubbleSizeMapper: (int index) => _data[index].countriesCount,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: [
MapShapeLayer(
source: _shapeSource,
shapeTooltipBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(7),
child: Text(
'Continent : ' +
_data[index].continent +
'\nArea : ' +
_data[index].area,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontStyle: FontStyle.italic,
fontFamily: 'Times',
hideDelay: 10,
),
),
);
},
bubbleTooltipBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(7),
child: Text(
'Continent : ' +
_data[index].continent +
'\nTotal Countries : ' +
_data[index].countriesCount.toStringAsFixed(0),
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontStyle: FontStyle.italic,
fontFamily: 'Times',
),
),
);
},
tooltipSettings: const MapTooltipSettings(
color: const Color.fromRGBO(98, 0, 238, 1),
strokeColor: const Color.fromRGBO(252, 187, 15, 1),
strokeWidth: 3,
),
),
],
),
),
);
}
class Model {
const Model(this.continent, this.countriesCount, this.area);
final String continent;
final double countriesCount;
final String area;
}
{% endhighlight %}
{% endtabs %}
<b>Using SfMapsTheme</b>
You can customize the below appearance of the tooltip using [`SfMapsTheme`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfMapsTheme-class.html).
* **Background color** - Change the background color of the tooltip in the maps using the [`SfMapsThemeData.tooltipColor`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfMapsThemeData/tooltipColor.html) property.
* **Stroke color** - Change the stroke color of the tooltip in the maps using the [`SfMapsThemeData.tooltipStrokeColor`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfMapsThemeData/tooltipStrokeColor.html) property.
* **Stroke width** - Change the stroke width of the tooltip in the maps using the [`SfMapsThemeData.tooltipStrokeWidth`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfMapsThemeData/tooltipStrokeWidth.html) property.
* **Border radius** - Change the appearance of the tooltip borders in the maps using the [`SfMapsThemeData.tooltipBorderRadius`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfMapsThemeData/tooltipBorderRadius.html) property.
N> You must import the `theme.dart` library from the [`Core`](https://pub.dev/packages/syncfusion_flutter_core) package to use [`SfMapsTheme`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfMapsTheme-class.html).
{% tabs %}
{% highlight Dart %}
late List<Model> _data;
late MapShapeSource _shapeSource;
@override
void initState() {
super.initState();
_data = <Model>[
Model('Asia', 50, '44,579,000 sq. km.'),
Model('Africa', 54, '30,370,000 sq. km.'),
Model('Europe', 51, '10,180,000 sq. km.'),
Model('North America', 23, '24,709,000 sq. km.'),
Model('South America', 12, '17,840,000 sq. km.'),
Model('Australia', 14, '8,600,000 sq. km.'),
];
_shapeSource = MapShapeSource.asset(
"assets/world_map.json",
shapeDataField: "continent",
dataCount: _data.length,
primaryValueMapper: (int index) => _data[index].continent,
bubbleSizeMapper: (int index) => _data[index].countriesCount,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMapsTheme(
data: SfMapsThemeData(
tooltipColor: const Color.fromRGBO(98, 0, 238, 1),
tooltipStrokeColor: const Color.fromRGBO(252, 187, 15, 1),
tooltipStrokeWidth: 3,
tooltipBorderRadius: const BorderRadiusDirectional.only(
topStart: Radius.circular(20),
bottomEnd: Radius.circular(20),
),
),
child: SfMaps(
layers: [
MapShapeLayer(
source: _shapeSource,
shapeTooltipBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(7),
child: Text(
'Continent : ' +
_data[index].continent +
'\nArea : ' +
_data[index].area,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontStyle: FontStyle.italic,
fontFamily: 'Times',
),
),
);
},
bubbleTooltipBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(7),
child: Text(
'Continent : ' +
_data[index].continent +
'\nTotal Countries : ' +
_data[index].countriesCount.toStringAsFixed(0),
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontStyle: FontStyle.italic,
fontFamily: 'Times',
),
),
);
},
),
],
),
),
),
);
}
class Model {
const Model(this.continent, this.countriesCount, this.area);
final String continent;
final double countriesCount;
final String area;
}
{% endhighlight %}
{% endtabs %}
![Maps tooltip appearance customization](images/tooltip/tooltip_textStyle.png)
N>
* Refer the [MapShapeLayer.shapeTooltipBuilder](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer/shapeTooltipBuilder.html), for enabling tooltip for the shapes.
* Refer the [MapShapeLayer.bubbleTooltipBuilder](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer/bubbleTooltipBuilder.html), for enabling tooltip for the bubbles.
* Refer the [MapLayer.markerTooltipBuilder](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerTooltipBuilder.html), for enabling tooltip for the markers.

Просмотреть файл

@ -0,0 +1,730 @@
---
layout: post
title: Lines in Flutter Maps widget | Syncfusion
description: Learn here all about adding the Line Layer feature of Syncfusion Flutter Maps (SfMaps) widget and more.
platform: Flutter
control: SfMaps
documentation: ug
---
# Lines in Flutter Maps (SfMaps)
Line layer is a sublayer that renders a group of [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) on [`MapShapeLayer`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer-class.html) and [`MapTileLayer`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer-class.html). This section helps to learn about how to add the lines and customize them.
## Adding lines
The [`lines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/lines.html) is a collection of [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html). Every single [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) connects two location coordinates through a straight line. The start coordinate is set to [`MapLine.from`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine/from.html) property and the end coordinate is set to [`MapLine.to`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine/to.html) property.
N> It is applicable for both the tile layer and shape layer.
<b>In the shape layer</b>
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751)),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
);
}).toSet(),
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to);
final MapLatLng from;
final MapLatLng to;
}
{% endhighlight %}
{% endtabs %}
<b>In the tile layer</b>
{% tabs %}
{% highlight Dart %}
late List<DataModel> data;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751)),
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
);
}).toSet(),
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to);
final MapLatLng from;
final MapLatLng to;
}
{% endhighlight %}
{% endtabs %}
![Default line shape](../images/line-layer/default_line_shape.png)
## Color
You can apply the same color for all [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) in the [`lines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/lines.html) collection using the [`MapLineLayer.color`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/color.html) property. Alternatively, you can apply different colors to each [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) in the [`lines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/lines.html) collection using the individual [`MapLine.color`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine/color.html) property.
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468), Colors.redAccent),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152), Colors.deepPurpleAccent),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188), Colors.blueAccent),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751), Colors.teal),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
color: data[index].color,
);
}).toSet(),
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to, this.color);
final MapLatLng from;
final MapLatLng to;
final Color color;
}
{% endhighlight %}
{% endtabs %}
![Line shape color](../images/line-layer/line_shape_color.png)
## Width
You can apply the same width for all [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) in the [`lines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/lines.html) collection using the [`MapLineLayer.width`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/width.html) property. Alternatively, you can apply different width to each [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) in the [`lines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/lines.html) collection using the individual [`MapLine.width`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine/width.html) property. The default value of the [`MapLineLayer.width`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/width.html) property is `2`.
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468), 2),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152), 4),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188), 5),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751), 6),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
width: data[index].width,
);
}).toSet(),
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to, this.width);
final MapLatLng from;
final MapLatLng to;
final double width;
}
{% endhighlight %}
{% endtabs %}
![Line shape width](../images/line-layer/line_shape_width.png)
## Stroke cap
You can apply the same stroke cap for all [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) in the [`lines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/lines.html) collection using the `MapLineLayer.strokeCap` property. Alternatively, you can apply different stroke cap to each [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) in the [`lines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/lines.html) collection using the individual `MapLine.strokeCap` property. The default value of the `MapLineLayer.strokeCap` property is `StrokeCap.butt`. The available values are `butt`, `round`, and `square`.
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468), 3),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152), 4),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188), 6),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751), 7),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
width: data[index].width,
strokeCap: StrokeCap.round,
);
}).toSet(),
),
],
),
],
),
);
}
class DataModel {
DataModel(this.from, this.to, this.width);
final MapLatLng from;
final MapLatLng to;
final double width;
}
{% endhighlight %}
{% endtabs %}
![Line stroke cap](../images/line-layer/line_stroke_cap.png)
## Dash array
You can apply dash support for the line using the [`MapLine.dashArray`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine/dashArray.html) property.
A sequence of dash and gap will be rendered based on the values in this list. Once all values of the list is rendered, it will be repeated again till the end of the line.
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751)),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
dashArray: [8, 4, 2, 4],
);
}).toSet(),
color: Colors.blue,
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to);
final MapLatLng from;
final MapLatLng to;
}
{% endhighlight %}
{% endtabs %}
![Line shape dash array](../images/line-layer/line_shape_dash_array.png)
## Animation
You can apply animation for the [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) using the [`MapLineLayer.animation`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLineLayer/animation.html) property and able to customize the animation flow, curve and duration.
By default, there will not be any animation.
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
late AnimationController animationController;
late Animation animation;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751)),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
animationController = AnimationController(
duration: Duration(seconds: 3),
vsync: this,
);
animation = CurvedAnimation(
parent: animationController,
curve: Curves.easeInOut,
);
animationController.forward(from: 0);
super.initState();
}
@override
void dispose() {
animationController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
);
}).toSet(),
color: Colors.blue,
animation: animation,
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to);
final MapLatLng from;
final MapLatLng to;
}
{% endhighlight %}
{% endtabs %}
![Line shape animation](../images/line-layer/line_shape_animation.gif)
## Tap
You can use the [`onTap`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine/onTap.html) callback to get a notification if the particular [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) is tapped. You can also customize the tapped [`MapLine`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLine-class.html) based on the index passed in the callback as shown in the below code snippet.
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
late int selectedIndex;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751)),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
selectedIndex = -1;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
color: selectedIndex == index ? Colors.pink : Colors.blue,
onTap: () {
setState(() {
selectedIndex = index;
});
});
}).toSet(),
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to);
final MapLatLng from;
final MapLatLng to;
}
{% endhighlight %}
{% endtabs %}
![Line shape onTap](../images/line-layer/line_shape_onTap.gif)
## Tooltip
You can show additional information about the line drawn using the [`tooltipBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapSublayer/tooltipBuilder.html) property.
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
late Random random;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751)),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
random = Random();
super.initState();
}
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final TextStyle textStyle = themeData.textTheme.caption!
.copyWith(color: themeData.colorScheme.surface);
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
);
}).toSet(),
tooltipBuilder: (BuildContext context, int index) {
return Container(
padding: EdgeInsets.only(left: 5, top: 5),
height: 40,
width: 100,
child: Column(
children: [
Row(
children: [
Text('Flight : ', style: textStyle),
Text('Air India', style: textStyle),
],
),
Row(
children: [
Text('Depart : ', style: textStyle),
Text(random.nextInt(12).toString() + 'AM', style: textStyle),
],
),
],
),
);
},
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to);
final MapLatLng from;
final MapLatLng to;
}
{% endhighlight %}
{% endtabs %}
![Line shape tooltip](../images/line-layer/line_shape_tooltip.png)
## Tooltip customization
You can customize the appearance of the tooltip.
* Background color - Change the background color of the tooltip in the maps using the [`MapTooltipSettings.color`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/color.html) property.
* Stroke color - Change the stroke color of the tooltip in the maps using the [`MapTooltipSettings.strokeColor`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/strokeColor.html) property.
* Stroke width - Change the stroke width of the tooltip in the maps using the [`MapTooltipSettings.strokeWidth`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/strokeWidth.html) property.
{% tabs %}
{% highlight Dart %}
late MapShapeSource dataSource;
late List<DataModel> data;
late Random random;
@override
void initState() {
data = <DataModel>[
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(56.1304, -106.3468)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-9.1900, -75.0152)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(61.5240, 105.3188)),
DataModel(MapLatLng(28.7041, 77.1025), MapLatLng(-25.2744, 133.7751)),
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
random = Random();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(10),
child: SfMaps(layers: [
MapShapeLayer(
source: dataSource,
tooltipSettings: const MapTooltipSettings(
color: Colors.white,
strokeWidth: 2,
strokeColor: Colors.black,
),
sublayers: [
MapLineLayer(
lines: List<MapLine>.generate(data.length, (int index) {
return MapLine(
from: data[index].from,
to: data[index].to,
);
}).toSet(),
tooltipBuilder: (BuildContext context, int index) {
return Container(
padding: EdgeInsets.only(left: 5, top: 5),
height: 40,
width: 100,
child: Column(
children: [
Row(
children: [
Text('Flight : '),
Text('Air India'),
],
),
Row(
children: [
Text('Depart : '),
Text(random.nextInt(12).toString() + 'AM'),
],
),
],
),
);
},
),
],
),
]),
),
);
}
class DataModel {
DataModel(this.from, this.to);
final MapLatLng from;
final MapLatLng to;
}
{% endhighlight %}
{% endtabs %}
![Line shape tooltip customization](../images/line-layer/line_shape_tooltip_customization.png)

Просмотреть файл

@ -0,0 +1,891 @@
---
layout: post
title: Adding Polylines in Flutter Maps widget | Syncfusion
description: Learn here all about adding the Polylines feature of Syncfusion Flutter Maps (SfMaps) widget and more.
platform: Flutter
control: SfMaps
documentation: ug
---
# Polylines in Flutter Maps (SfMaps)
Polyline layer is a sublayer that renders a group of [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) on [`MapShapeLayer`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapShapeLayer-class.html) and [`MapTileLayer`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer-class.html). This section helps to learn about how to add the polylines and customize them.
## Adding polylines
The [`polylines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/polylines.html) is a collection of [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html). Every single [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) connects multiple coordinates through a [`points`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline/points.html) property.
N> It is applicable for both the tile layer and shape layer.
<b>In the shape layer</b>
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<List<MapLatLng>> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <List<MapLatLng>>[polyline];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 2,
focalLatLng: MapLatLng(20.3173, 78.7139),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index],
);
},
).toSet(),
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points);
final List<MapLatLng> points;
}
{% endhighlight %}
{% endtabs %}
<b>In the tile layer</b>
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<List<MapLatLng>> polylines;
late MapZoomPanBehavior zoomPanBehavior;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <List<MapLatLng>>[polyline];
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 5,
focalLatLng: MapLatLng(20.3173, 78.7139),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index],
);
},
).toSet(),
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points);
final List<MapLatLng> points;
}
{% endhighlight %}
{% endtabs %}
![Default polyline shape](../images/polyline-layer/default-polyline-shape.png)
## Color
You can apply the same color for all [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) in the [`polylines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/polylines.html) collection using the [`MapPolylineLayer.color`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/color.html) property. Alternatively, you can apply different colors to each [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) in the [`polylines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/polylines.html) collection using the individual [`MapPolyline.color`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline/color.html) property.
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<PolylineModel> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <PolylineModel>[
PolylineModel(polyline, Colors.purple),
];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 1,
focalLatLng: MapLatLng(20.3173, 78.7139),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index].points,
color: polylines[index].color,
);
},
).toSet(),
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points, this.color);
final List<MapLatLng> points;
final Color color;
}
{% endhighlight %}
{% endtabs %}
![Polyline color](../images/polyline-layer/polyline-color.png)
## Width
You can apply the same width for all [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) in the [`polylines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/polylines.html) collection using the [`MapPolylineLayer.width`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/width.html) property. Alternatively, you can apply different width to each [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) in the [`polylines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/polylines.html) collection using the individual [`MapPolyline.width`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline/width.html) property. The default value of the [`MapPolylineLayer.width`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/width.html) property is `2`.
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<PolylineModel> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <PolylineModel>[
PolylineModel(polyline, 3),
];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 2,
focalLatLng: MapLatLng(20.3173, 78.7139),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index].points,
width: polylines[index].width,
);
},
).toSet(),
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points, this.width);
final List<MapLatLng> points;
final double width;
}
{% endhighlight %}
{% endtabs %}
![Polyline width](../images/polyline-layer/polyline-width.png)
## Stroke cap
You can apply the same stroke cap for all [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) in the [`polylines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/polylines.html) collection using the `MapPolylineLayer.strokeCap` property. Alternatively, you can apply different stroke cap to each [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) in the [`polylines`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/polylines.html) collection using the individual `MapPolyline.strokeCap` property. The default value of the `MapPolylineLayer.strokeCap` property is `StrokeCap.butt`. The available values are `butt`, `round`, and `square`.
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<PolylineModel> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <PolylineModel>[
PolylineModel(polyline, 5),
];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
focalLatLng: MapLatLng(20.3173, 78.7139),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index].points,
width: polylines[index].width,
strokeCap: StrokeCap.round,
);
},
).toSet(),
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points, this.width);
final List<MapLatLng> points;
final double width;
}
{% endhighlight %}
{% endtabs %}
![Polyline stroke cap](../images/polyline-layer/polyline-stroke-cap.png)
## Dash array
You can apply dash support for the polyline using the [`MapPolyline.dashArray`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline/dashArray.html) property.
A sequence of dash and gap will be rendered based on the values in this list. Once all values of the list is rendered, it will be repeated again till the end of the polyline.
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<PolylineModel> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <PolylineModel>[
PolylineModel(polyline),
];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 2,
focalLatLng: MapLatLng(18.3173, 77.7139),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index].points,
dashArray: [8, 4, 2, 4],
);
},
).toSet(),
color: Colors.blue,
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points);
final List<MapLatLng> points;
}
{% endhighlight %}
{% endtabs %}
![Polyline dash array](../images/polyline-layer/polyline-dash-array.png)
## Animation
You can apply animation for the [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) using the [`MapPolylineLayer.animation`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolylineLayer/animation.html) property and able to customize the animation flow, curve and duration.
By default, there will not be any animation.
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<PolylineModel> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
late AnimationController animationController;
late Animation animation;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <PolylineModel>[
PolylineModel(polyline),
];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 2,
focalLatLng: MapLatLng(19.3173, 76.7139),
);
animationController = AnimationController(
duration: Duration(seconds: 3),
vsync: this,
);
animation = CurvedAnimation(
parent: animationController,
curve: Curves.easeInOut,
);
animationController.forward(from: 0);
super.initState();
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index].points,
);
},
).toSet(),
color: Colors.blue,
animation: animation,
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points);
final List<MapLatLng> points;
}
{% endhighlight %}
{% endtabs %}
![Polyline animation](../images/polyline-layer/polyline-animation.gif)
## Tap
You can use the [`onTap`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline/onTap.html) callback to get a notification if the particular [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) is tapped. You can also customize the tapped [`MapPolyline`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapPolyline-class.html) based on the index passed in the callback as shown in the below code snippet.
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<PolylineModel> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
late int selectedIndex;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <PolylineModel>[
PolylineModel(polyline),
];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 2,
focalLatLng: MapLatLng(19.3173, 76.7139),
);
selectedIndex = -1;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index].points,
color: selectedIndex == index ? Colors.pink: Colors.blue,
onTap: () {
setState(() {
selectedIndex = index;
});
}
);
},
).toSet(),
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points);
final List<MapLatLng> points;
}
{% endhighlight %}
{% endtabs %}
![Polyline tap support](../images/polyline-layer/polyline-tap-support.gif)
## Tooltip
You can show additional information about the polyline drawn using the [`tooltipBuilder`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapSublayer/tooltipBuilder.html) property.
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<PolylineModel> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
late Random random;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <PolylineModel>[
PolylineModel(polyline),
];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 2,
focalLatLng: MapLatLng(19.3173, 76.7139),
);
random = Random();
super.initState();
}
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final TextStyle textStyle = themeData.textTheme.caption!
.copyWith(color: themeData.colorScheme.surface);
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index].points,
);
},
).toSet(),
tooltipBuilder: (BuildContext context, int index) {
return Container(
padding: EdgeInsets.only(left: 15, top: 10),
width: 150,
height: 50,
child: Column(
children: [
Row(
children: [
Text('Order item : ', style: textStyle),
Text('Pizza', style: textStyle),
],
),
Row(
children: [
Text('Time left : ', style: textStyle),
Text(random.nextInt(30).toString() + ' mins',
style: textStyle),
],
),
],
),
);
},
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points);
final List<MapLatLng> points;
}
{% endhighlight %}
{% endtabs %}
![Polyline tooltip support](../images/polyline-layer/polyline-tooltip.png)
## Tooltip customization
You can customize the appearance of the tooltip.
* Background color - Change the background color of the tooltip in the maps using the [`MapTooltipSettings.color`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/color.html) property.
* Stroke color - Change the stroke color of the tooltip in the maps using the [`MapTooltipSettings.strokeColor`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/strokeColor.html) property.
* Stroke width - Change the stroke width of the tooltip in the maps using the [`MapTooltipSettings.strokeWidth`](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTooltipSettings/strokeWidth.html) property.
{% tabs %}
{% highlight Dart %}
late List<MapLatLng> polyline;
late List<PolylineModel> polylines;
late MapShapeSource dataSource;
late MapZoomPanBehavior zoomPanBehavior;
late Random random;
@override
void initState() {
polyline = <MapLatLng>[
MapLatLng(13.0827, 80.2707),
MapLatLng(13.1746, 79.6117),
MapLatLng(13.6373, 79.5037),
MapLatLng(14.4673, 78.8242),
MapLatLng(14.9091, 78.0092),
MapLatLng(16.2160, 77.3566),
MapLatLng(17.1557, 76.8697),
MapLatLng(18.0975, 75.4249),
MapLatLng(18.5204, 73.8567),
MapLatLng(19.0760, 72.8777),
];
polylines = <PolylineModel>[
PolylineModel(polyline),
];
dataSource = MapShapeSource.asset(
'assets/india.json',
shapeDataField: 'name',
);
zoomPanBehavior = MapZoomPanBehavior(
zoomLevel: 3,
focalLatLng: MapLatLng(15.3173, 76.7139),
);
random = Random();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: dataSource,
tooltipSettings: MapTooltipSettings(
color: Colors.white,
strokeWidth: 2,
strokeColor: Colors.black,
),
sublayers: [
MapPolylineLayer(
polylines: List<MapPolyline>.generate(
polylines.length,
(int index) {
return MapPolyline(
points: polylines[index].points,
);
},
).toSet(),
tooltipBuilder: (BuildContext context, int index) {
return Container(
padding: EdgeInsets.only(left: 15, top: 10),
width: 150,
height: 50,
child: Column(
children: [
Row(
children: [
Text('Order item : ',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Pizza'),
],
),
Row(
children: [
Text('Time left : ',
style: TextStyle(fontWeight: FontWeight.bold)),
Text(random.nextInt(30).toString() + ' mins'),
],
),
],
),
);
},
),
],
zoomPanBehavior: zoomPanBehavior,
),
],
),
);
}
class PolylineModel {
PolylineModel(this.points);
final List<MapLatLng> points;
}
{% endhighlight %}
{% endtabs %}
![Polyline tooltip customization](../images/polyline-layer/polyline-tooltip- customization.png)

Просмотреть файл

@ -0,0 +1,129 @@
---
layout: post
title: Accessibility in Flutter PDF Viewer widget | Syncfusion
description: Learn here all about the accessibility feature of the Syncfusion Flutter PDF Viewer (SfPdfViewer) widget and more.
platform: Flutter
control: SfPdfViewer
documentation: ug
---
# Accessibility in Flutter PDF Viewer (SfPdfViewer)
## Screen reader
The [`SfPdfViewer`](https://pub.dev/documentation/syncfusion_flutter_pdfviewer/latest/pdfviewer/SfPdfViewer-class.html) can be accessed by the screen readers by wrapping the [`SfPdfViewer`](https://pub.dev/documentation/syncfusion_flutter_pdfviewer/latest/pdfviewer/SfPdfViewer-class.html) widget to the [`Semantics`](https://api.flutter.dev/flutter/widgets/Semantics-class.html) widget.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Semantics(
label: 'Syncfusion Flutter PDF Viewer',
child:
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf'),
),
);
}
{% endhighlight %}
{% endtabs %}
## Sufficient contrast
The `SfPdfViewer` [theming](https://help.syncfusion.com/flutter/themes) support provides a consistent and standardized appearance, as well as the ability to set the colors for all UI elements.
The following APIs allow you to customize the colors of the following elements:
* [searchTextHighlightColor](https://help.syncfusion.com/flutter/pdf-viewer/text-search#customize-the-search-text-highlight-color)
* [selectionColor and selectionHandleColor](https://help.syncfusion.com/flutter/pdf-viewer/text-selection#customize-the-text-selection-and-its-handle-color)
## Large fonts
The font size of the [`SfPdfViewer`](https://pub.dev/documentation/syncfusion_flutter_pdfviewer/latest/pdfviewer/SfPdfViewer-class.html) will be automatically scaled based on the device settings.
Also, you can change the font size of the [`SfPdfViewer`](https://pub.dev/documentation/syncfusion_flutter_pdfviewer/latest/pdfviewer/SfPdfViewer-class.html) elements using the following APIs:
* [`Pagination dialog style`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfPdfViewerThemeData/paginationDialogStyle.html)
* [`Bookmark view style`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfPdfViewerThemeData/bookmarkViewStyle.html)
* [`Scroll head style`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfPdfViewerThemeData/scrollHeadStyle.html)
* [`Scroll status style`](https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfPdfViewerThemeData/scrollStatusStyle.html)
## Keyboard navigation
The `SfPdfViewer` supports the following keyboard interactions:
<table>
<tr>
<tr>
<th style="text-align:left" colspan="1">Action</th>
<th>Windows</th>
<th>Macintosh</th>
</tr>
<tr>
</tr>
<tr>
<th style="text-align:left" colspan="3">Shortcuts for page navigation</th>
</tr>
<tr>
<td>Navigate to the first page</td>
<td>Home</td>
<td>Function+Left arrow</td>
</tr>
<tr>
<td>Navigate to the last page</td>
<td>End</td>
<td>Function+Right arrow</td>
</tr>
<tr>
<td>Navigate to the previous page</td>
<td>Left arrow</td>
<td>Left arrow</td>
</tr>
<tr>
<td>Navigate to the next page</td>
<td>Right arrow</td>
<td>Right arrow</td>
</tr>
<tr>
<th style="text-align:left" colspan="3">Shortcuts for Zooming</th>
</tr>
<tr>
<td>Perform zoom in operation</td>
<td>CONTROL + =</td>
<td>COMMAND + =</td>
</tr>
<tr>
</tr>
<tr>
<td>Perform zoom out operation</td>
<td>CONTROL + -</td>
<td>COMMAND + -</td>
</tr>
<tr>
<td>Retain the zoom level to 1</td>
<td>CONTROL + 0</td>
<td>COMMAND + 0</td>
</tr>
<tr>
<th style="text-align:left" colspan="3">Shortcut for Text Search</th>
</tr>
<tr>
<td>Open the search toolbar</td>
<td>CONTROL + F</td>
<td>COMMAND + F</td>
</tr>
<tr>
<th style="text-align:left" colspan="3">Shortcut for Text Selection</th>
</tr>
<tr>
<td>Copy the selected text</td>
<td>CONTROL + C</td>
<td>COMMAND + C</td>
</tr>
</table>
## Easier touch targets
The [`SfPdfViewer`](https://pub.dev/documentation/syncfusion_flutter_pdfviewer/latest/pdfviewer/SfPdfViewer-class.html) has touch target of 48 * 48, as per the standard for all the elements.

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 483 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 475 KiB

Просмотреть файл

@ -0,0 +1,108 @@
---
layout: post
title: Page layout and Scrolling options in Flutter PDF Viewer | Syncfusion
description: Learn here all about Page layout and Scrolling options feature of Syncfusion Flutter PDF Viewer (SfPdfViewer) widget and more.
platform: Flutter
control: SfPdfViewer
documentation: ug
---
# Page layout and Scrolling options in Flutter PDF Viewer (SfPdfViewer)
Page layout modes describe how the PDF page is displayed and, scrolling options describe the direction in which the PDF pages can be scrolled in [SfPdfViewer](https://pub.dev/documentation/syncfusion_flutter_pdfviewer/latest/pdfviewer/SfPdfViewer-class.html).
## Page layout modes
The [SfPdfViewer](https://pub.dev/documentation/syncfusion_flutter_pdfviewer/latest/pdfviewer/SfPdfViewer-class.html) supports the following page layout modes:
* Continuous page layout mode
* Single page layout mode
N> For now, only `Horizontal` scrolling is supported in `Single page layout mode`.
### Continuous page layout mode
By default, the `continuous` page layout mode is enabled, which scrolls the PDF pages vertically and horizontally. To enable the `continuous` page layout mode in `SfPdfViewer`, use the following code sample.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
pageLayoutMode: PdfPageLayoutMode.continuous)));
}
{% endhighlight %}
{% endtabs %}
### Single page layout mode
In `Single` page layout mode, PDFs will be displayed page by page horizontally. To enable the `Single` page layout mode in `SfPdfViewer`, use the following code sample.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
pageLayoutMode: PdfPageLayoutMode.single)));
}
{% endhighlight %}
{% endtabs %}
![Single page layout mode](images/page-layout-and-scroll-direction/page-by-page.gif)
## Scrolling options
The [SfPdfViewer](https://pub.dev/documentation/syncfusion_flutter_pdfviewer/latest/pdfviewer/SfPdfViewer-class.html) supports the following scrolling options:
* Vertical scrolling
* Horizontal scrolling
### Vertical scrolling
By default, `Vertical` scrolling is enabled, which moves the PDF pages from up to down. To enable the `Vertical` scrolling in `SfPdfViewer`, use the following code sample.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
scrollDirection: PdfScrollDirection.vertical)));
}
{% endhighlight %}
{% endtabs %}
### Horizontal scrolling
In `Horizontal` scrolling, PDF pages can be scrolled from left to right. To enable the `Horizontal` scrolling in `SfPdfViewer`, use the following code sample.
{% tabs %}
{% highlight Dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
scrollDirection: PdfScrollDirection.horizontal)));
}
{% endhighlight %}
{% endtabs %}
![Horizontal scrolling](images/page-layout-and-scroll-direction/horizontal-scrolling.gif)

Просмотреть файл

@ -0,0 +1,249 @@
---
layout: post
title: Data label in Flutter Pyramid Chart widget | Syncfusion
description: Learn here all about Data label feature of Syncfusion Flutter Pyramid Chart (SfPyramidChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Data label in Flutter Pyramid Chart (SfPyramidChart)
Data label can be added to a chart series by enabling the [`isVisible`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/isVisible.html) option in the [`dataLabelSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/PyramidSeries/dataLabelSettings.html). You can use the following properties to customize the appearance.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/color.html) - used to change the background color of the data label shape.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderWidth.html) - used to change the stroke width of the data label shape.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderColor.html) - used to change the stroke color of the data label shape.
* [`alignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/alignment.html) - aligns the data label text to [`near`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html), [`center`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html) and [`far`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartAlignment-class.html).
* [`textStyle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/textStyle.html) - used to change the data label text color, size, font family, font style, and font weight.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/color.html) - used to change the color of the data label.
* [`fontFamily`](https://api.flutter.dev/flutter/painting/TextStyle/fontFamily.html) - used to change the font family for the data label.
* [`fontStyle`](https://api.flutter.dev/flutter/painting/TextStyle/fontStyle.html) - used to change the font style for the data label.
* [`fontWeight`](https://api.flutter.dev/flutter/painting/TextStyle/fontWeight.html) - used to change the font weight for the data label.
* [`fontSize`](https://api.flutter.dev/flutter/painting/TextStyle/fontSize.html) - used to change the font size for the data label.
* [`margin`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/margin.html) - used to change the margin size for data labels.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/opacity.html) - used to control the transparency of the data label.
* [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelAlignment.html) - used to align the Pyramid data label positions. The available options to customize the positions are [`outer`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`top`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`bottom`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) and [`middle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html).
* [`borderRadius`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/borderRadius.html) - used to add the rounded corners to the data label shape.
* [`angle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/angle.html) - used to rotate the labels.
* [`offset`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/offset.html) - used to movethedata label vertically or horizontally from its position.
* [`showCumulativeValues`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/showCumulativeValues.html) - to show the cumulative values in stacked type series charts.
* [`labelIntersectAction`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelIntersectAction.html) - action on data labels intersection. The intersecting data labels can be hidden.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
series: PyramidSeries<SalesData, String>(
dataSource: chartData,
pointColorMapper: (SalesData data, _) => data.color,
xValueMapper: (SalesData data, _) => data.x,
yValueMapper: (SalesData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
// Renders the data label
isVisible: true
)
)
)
)
)
);
}
{% endhighlight %}
![DataLabel](images/datalabel/default_datalabel.png)
## Connector line
This feature is used to connect label and data point using a line. It can be enabled for [`PyramidSeries`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/PyramidSeries-class.html) chart type. The [`connectorLineSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/connectorLineSettings.html) property used to customize the connector line.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorLineSettings/color.html) - used to change the color of the line
* [`width`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorLineSettings/width.html) - used to change the stroke thickness of the line
* [`length`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorLineSettings/length.html) - specifies the length of the connector line.
* [`type`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorLineSettings/type.html) - specifies the shape of connector line either [`curve`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorType-class.html) or [`line`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ConnectorType-class.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
series: <PyramidSeries>[
PyramidSeries<ChartData, double>(
enableSmartLabels: true,
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
isVisible: true,
labelPosition: ChartDataLabelPosition.outside,
connectorLineSettings: ConnectorLineSettings(
// Type of the connector line
type: ConnectorType.curve
)
)
)
]
)
)
)
);
}
{% endhighlight %}
## Positioning the labels
The [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) property is used to position the Pyramid chart type data labels at [`top`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`bottom`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html), [`outer`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) and [`middle`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) position of the actual data point position. By default, labels are [`auto`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelAlignment-class.html) positioned. You can move the labels horizontally and vertically using OffsetX and OffsetY properties respectively.
The [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) property is used to place the Pyramid series data labels either [`inside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html) or [`outside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html). By default the label of Pyramid chart is placed [`inside`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartDataLabelPosition-class.html) the series.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
series: PyramidSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData data, _) => data.x,
yValueMapper: (SalesData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
isVisible: true,
// Positioning the data label
labelPosition: ChartDataLabelPosition.outside
)
)
)
)
)
);
}
{% endhighlight %}
![Data label position](images/datalabel/datalabel_position.png)
N> The [`labelAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelAlignment.html) property is used to position the Cartesian chart labels whereas [`labelPosition`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/labelPosition.html) property is used to position the Pyramid chart labels.
## Apply series color
The [`useSeriesColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/useSeriesColor.html) property is used to apply the series color to background color of the data labels. The default value of this property is `false`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
series: PyramidSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData data, _) => data.x,
yValueMapper: (SalesData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
isVisible: true,
// Positioning the data label
labelPosition: ChartDataLabelPosition.outside,
// Renders background rectangle and fills it with series color
useSeriesColor: true
)
)
)
)
)
);
}
{% endhighlight %}
![Series color](images/datalabel/use_series_color.png)
## Templating the labels
You can customize the appearance of the data label with your own template using the [`builder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/builder.html) property of [`dataLabelSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/PyramidSeries/dataLabelSettings.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
series: PyramidSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData data, _) => data.x,
yValueMapper: (SalesData data, _) => data.y,
dataLabelSettings: DataLabelSettings(
isVisible: true,
// Templating the data label
builder: (dynamic data, dynamic point, dynamic series, int pointIndex, int seriesIndex) {
return Container(
height: 30,
width: 30,
child: Image.asset('images/livechart.png')
);
}
)
)
)
)
)
);
}
{% endhighlight %}
![Label template](images/datalabel/datalabel_template.png)
## Hide data label for 0 value
Data label and its connector line in the Pyramid charts for the point value 0 can be hidden using the [`showZeroValue`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/DataLabelSettings/showZeroValue.html) property. This defaults to `true`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:SfPyramidChart(
series: PyramidSeries<SalesData, num>(
dataSource: [
SalesData(11, 35),
SalesData(12, 28),
SalesData(13, 0),
SalesData(14, 32),
SalesData(15, 40)
],
xValueMapper: (SalesData sales, _) => sales.xValue,
yValueMapper: (SalesData sales, _) => sales.yValue,
dataLabelSettings: DataLabelSettings(
showZeroValue: false,
isVisible: true
),
)
)
)
);
}
{% endhighlight %}
![hide_0_value](images/datalabel/dataLabel_0_value.png)
### Data label saturation color
If the user didnt provide text color to the data label, then by default, the saturation color is applied to the data label text. i.e., if the data points background color intensity is dark, then the data label will render in white color (#FFFFFF) and if the data points background color intensity is light, data label will render in black color (#000000).
![label_saturation](images/datalabel/pyramid_saturation.png)

Просмотреть файл

@ -0,0 +1,53 @@
---
layout: post
title: Methods in Flutter Pyramid Chart widget | Syncfusion
description: Learn here all about available methods of Syncfusion Flutter Pyramid Chart(SfPyramidChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Methods in Flutter Pyramid Chart (SfPyramidChart)
## PixelToPoint
Converts logical pixel value to the data point value.
The `pixelToPoint` method takes logical pixel value as input and returns a chart data point.
N> The method will return the center value of the segment.
{% highlight dart %}
//Initialize the series controller
PyramidSeriesController? seriesController;
@override
Widget build(BuildContext context) {
return Container(
child: SfPyramidChart(
onChartTouchInteractionDown: (ChartTouchInteractionArgs args) {
final Offset value = Offset(args.position.dx, args.position.dy);
final PointInfo<dynamic>? chartpoint = seriesController?.pixelToPoint(value);
},
series: PyramidSeries<ChartData, String>(
dataSource: data,
onRendererCreated: (PyramidSeriesController pyramidSeriesController) {
seriesController = pyramidSeriesController;
},
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y
)
),
);
}
class ChartData{
ChartData(this.x, this.y);
final String x;
final double y;
}
{% endhighlight %}

Просмотреть файл

@ -0,0 +1,181 @@
---
layout: post
title: Series customization in Flutter Pyramid Chart widget | Syncfusion
description: Learn here all about Series customization of Syncfusion Flutter Pyramid Chart (SfPyramidChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Series customization in Flutter Pyramid Chart (SfPyramidChart)
## Animation
[`SfPyramidChart`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfPyramidChart-class.html) provides animation support for the series. Series will be animated while rendering. Animation is enabled by default, you can also control the duration of the animation using [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/PyramidSeries/animationDuration.html) property. You can disable the animation by setting 0 value to that property.
{% highlight dart %}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
series:PyramidSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
animationDuration: 1000,
)
)
)
)
);
}
{% endhighlight %}
## Animation delay
The `animationDelay` property is used to specify the delay duration of the series animation. This takes milliseconds value as input. By default, the series will get animated for the specified duration. If `animationDelay` is specified, then the series will begin to animate after the specified duration. Defaults to `0`.
{% highlight dart %}
@override
Widget build(BuildContext context) {
List<ChartData> data = [
ChartData('Jan', 35),
ChartData('Feb', 28),
ChartData('Mar', 38),
ChartData('Apr', 32),
ChartData('May', 40)
];
return Center(
child: SfPyramidChart(
series: PyramidSeries<ChartData, String>(
dataSource: data,
animationDuration: 4500,
animationDelay: 2000,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
)
),
);
}
class ChartData {
ChartData(this.x, this.y);
final String x;
final double y;
}
{% endhighlight %}
## Empty points
The data points that has null value are considered as empty points. Empty data points are ignored and not plotted in the chart. By using [`emptyPointSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/PyramidSeries/emptyPointSettings.html) property in series, you can decide the action taken for empty points. Available [`modes`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html) are [`gap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html), [`zero`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html), [`drop`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html) and [`average`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html). Default mode of the empty point is [`gap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointMode-class.html).
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('David', null),
ChartData('Steve', 38),
ChartData('Jack', 34),
ChartData('Others', 52)
];
return Scaffold(
body: Center(
child: SfPyramidChart(
series:PyramidSeries<ChartData, String>(
dataSource: chartData,
dataLabelSettings: DataLabelSettings(isVisible:true),
emptyPointSettings: EmptyPointSettings(mode: EmptyPointMode.average),
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y
)
)
)
);
}
{% endhighlight %}
![Empty points](images/Pyramid-customization/emptyPoints.png)
### Empty point customization
Specific color for empty point can be set by [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/color.html) property in [`emptyPointSettings`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/PyramidSeries/emptyPointSettings.html). The [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/borderWidth.html) property is used to change the stroke width of the empty point and [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/EmptyPointSettings/borderColor.html) is used to change the stroke color of the empty point.
{% highlight dart %}
@override
Widget build(BuildContext context) {
final List<ChartData> chartData = [
ChartData('David', null),
ChartData('Steve', 38),
ChartData('Jack', 34),
ChartData('Others', 52)
];
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
series:PyramidSeries<ChartData, String>(
dataSource: chartData,
dataLabelSettings: DataLabelSettings(isVisible:true),
emptyPointSettings: EmptyPointSettings(mode: EmptyPointMode.average,
color: Colors.red,
borderColor: Colors.black,
borderWidth: 2),
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y
)
)
)
)
);
}
{% endhighlight %}
![Empty points customization](images/Pyramid-customization/emptyPointcustomization.png)
## Color mapping for data points
The [`pointColorMapper`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/PyramidSeries/pointColorMapper.html) property is used to map the color field from the data source.
{% highlight dart %}
@override
Widget build(BuildContext context) {
static List<SalesData> chartData = <ChartData>[
ChartData('Rent', 1000,Colors.teal),
ChartData('Food', 2500,Colors.lightBlue),
ChartData('Savings', 760,Colors.brown),
ChartData('Tax', 1897,Colors.grey),
ChartData('Others', 2987,Colors.blueGrey)
];
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
series:PyramidSeries<ChartData, String>(
dataSource: chartData,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
//map Color for each dataPoint datasource.
pointColorMapper: (ChartData sales,_) => sales.color,
)
)
)
)
);
}
{% endhighlight %}
![mapcolor](images/Pyramid-customization/color-mapping.png)

Просмотреть файл

@ -0,0 +1,259 @@
---
layout: post
title: Tooltip in Flutter Pyramid Chart widget | Syncfusion
description: Learn here all about Tooltip feature of Syncfusion Flutter Pyramid Chart (SfPyramidChart) widget and more.
platform: flutter
control: Chart
documentation: ug
---
# Tooltip in Flutter Pyramid Chart (SfPyramidChart)
Chart provides tooltip support for all the series. It is used to show information about the segment, when you tap on the segment. To enable the tooltip, you need to set [`enableTooltip`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ChartSeries/enableTooltip.html) property as `true`.
The tooltip state will be preserved on the device's orientation change and on browser resize. For example, if the tooltip's [`duration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/duration.html) is set to 10,000ms, and when you change the orientation of your device from portrait to landscape after 5,000ms of tooltip display, the tooltip will be displayed for the next 5,000ms in landscape mode before disappearing.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(enable: true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
tooltipBehavior: _tooltipBehavior,
series: PyramidSeries<SalesData, String>(
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales
)
)
)
)
);
}
{% endhighlight %}
![Tooltip](images/tooltip/default_tooltip.png)
## Customizing the appearance
You can use the following properties to customize the tooltip appearance.
* [`color`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/color.html) - used to change the background color of tooltip.
* [`borderWidth`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/borderWidth.html) - used to change the stroke width of the tooltip.
* [`borderColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/borderColor.html) - used to change the stroke color of the tooltip.
* [`opacity`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/opacity.html) - used to control the transparency of the tooltip.
* [`duration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/duration.html) - specifies the duration for displaying the tooltip that defaults to `3000`.
* [`animationDuration`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/animationDuration.html) - specifies the duration for animating the tooltip that default to `350`.
* [`elevation`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/elevation.html) - specifies the elevation of tooltip.
* [`canShowMarker`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/canShowMarker.html) - toggles the visibility of the marker in the tooltip.
* [`header`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/header.html) - specifies the header for tooltip. By default, the series name will be displayed in the header.
* [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) - formats the tooltip text. By default, the tooltip will be rendered with x and y-values. You can add prefix or suffix to x, y, and series name values in the tooltip by formatting them.
* [`shadowColor`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shadowColor.html) - specifies the color of the tooltip shadow.
* [`shouldAlwaysShow`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shouldAlwaysShow.html) - used to shows or hides the tooltip.
* [`textAlignment`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/textAlignment.html) - alignment of the text in the tooltip.
* [`decimalPlaces`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/decimalPlaces.html) - used to specify the number decimals to be displayed in tooltip text.
* [`shared`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/shared.html) - used to share the tooltip with same index points.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
borderColor: Colors.red,
borderWidth: 2,
color: Colors.lightBlue
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 350,
width: 350,
child: SfPyramidChart(
tooltipBehavior: _tooltipBehavior,
)
)
)
);
}
{% endhighlight %}
![Customized tooltip](images/tooltip/customized_tooltip.png)
## Label format
By default, x and y value will be displayed in the tooltip, and it can be customized using [`format`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/format.html) property as depicted in the below code snippet. You can show the below values in the tooltip. Also you can add prefix or suffix to these values.
* X value - `point.x`
* Y value - `point.y`
* Bubble size - `point.size`
* Name of the series - `series.name`
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Formatting the tooltip text
format: 'point.y%'
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![tooltip format](images/tooltip/tooltip_format.png)
## Tooltip positioning
The tooltip can be made to display in the fixed location or at the pointer location itself using the `tooltipPosition` property. This defaults to `auto`.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
tooltipPosition: TooltipPosition.pointer
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![pointer tooltip](images/tooltip/tooltip_pointer.png)
## Tooltip template
You can customize the appearance of the tooltip with your own widget by using the [`builder`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/builder.html) property of [`tooltipBehavior`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/SfPyramidChart/tooltipBehavior.html).
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Templating the tooltip
builder: (dynamic data, dynamic point, dynamic series,
int pointIndex, int seriesIndex) {
return Container(
child: Text(
'Point Y : ${point.y.toString()}'
)
);
}
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
![Tooltip template](images/tooltip/tooltip_template.png)
## Activation mode
The [`activationMode`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/TooltipBehavior/activationMode.html) property is used to restrict the visibility of tooltip based on the touch actions. The default value of this property is [`ActivationMode.singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html).
The ActivationMode enum contains the following values:
* [`longPress`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing the long press action.
* [`singleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing single tap action.
* [`doubleTap`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - activates tooltip only when performing double tap action.
* [`none`](https://pub.dev/documentation/syncfusion_flutter_charts/latest/charts/ActivationMode-class.html) - hides the visibility of tooltip when setting activation mode to none.
{% highlight dart %}
late TooltipBehavior _tooltipBehavior;
@override
void initState(){
_tooltipBehavior = TooltipBehavior(
enable: true,
// Tooltip will be displayed on long press
activationMode: ActivationMode.longPress
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfPyramidChart(
tooltipBehavior: _tooltipBehavior
)
)
)
);
}
{% endhighlight %}
Also refer [tooltip event](./events#ontooltiprender) for customizing the tooltip further.

Просмотреть файл

@ -1,30 +1,37 @@
---
layout: post
title: Getting Started for Syncfusion Flutter Range Selector | Syncfusion
description: This section explains the steps required to add the range selector widget and its elements such as numeric and date values, ticks, labels and tooltips.
platform: flutter
title: Getting started with Flutter Range Selector widget | Syncfusion
description: Learn here about getting started with Syncfusion Flutter Range Selector (SfRangeSelector) widget, its elements, and more.
platform: Flutter
control: SfRangeSelector
documentation: ug
---
# Getting Started for Range Selector
# Getting started with Flutter Range Selector (SfRangeSelector)
This section explains the steps required to add the range selector widget and its elements such as numeric and date values, ticks, labels and tooltips. This section covers only basic features needed to know to get started with Syncfusion range selector.
## Add flutter range selector to an application
To get start quickly with our Flutter Range Selector widget, you can check on this video.
<style>#FlutterRangeSelectorVideoTutorial{width : 90% !important; height: 300px !important }</style>
<iframe id='FlutterRangeSelectorVideoTutorial' src='https://www.youtube.com/embed/WX1IvK5R0q0'></iframe>
## Add Flutter range selector to an application
Create a simple project using the instructions given in the [Getting Started with your first Flutter app](https://flutter.dev/docs/get-started/test-drive?tab=vscode#create-app) documentation.
**Add dependency**
Add the Syncfusion flutter range selector dependency to your pubspec.yaml file.
Add the Syncfusion Flutter range selector dependency to your pubspec.yaml file.
{% highlight dart %}
dependencies:
syncfusion_flutter_sliders: ^18.1.0.36-beta
syncfusion_flutter_sliders: ^xx.x.xx
{% endhighlight %}
N> Here **xx.x.xx** denotes the current version of [`Syncfusion Flutter Sliders`](https://pub.dev/packages/syncfusion_flutter_sliders/versions) package.
**Get packages**
Run the following command to get the required packages.
@ -49,7 +56,9 @@ import 'package:syncfusion_flutter_sliders/sliders.dart';
## Initialize range selector
After importing the package, initialize the range selector widget as a child of any widget. Here, the range slider widget is added as a child of the Container widget. The default value of the `min` and `max` property of the SfRangeSlider is 0.0 and 1.0 respectively. So, the `initialValues` property must be given within the range. You can add any kind of widget as a child of range selector. Here, [Chart](https://help.syncfusion.com/flutter/chart/getting-started) widget is added as a child.
After importing the package, initialize the range selector widget as a child of any widget. Here, the range selector widget is added as a child of the Container widget. The default value of the [`min`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/min.html) and [`max`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/max.html) properties of the SfRangeSelector is 0.0 and 1.0 respectively. So, the [`initialValues`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) property must be given within the range. You can add any kind of widget as a child of range selector. Here, [Chart](https://www.syncfusion.com/flutter-widgets/flutter-charts) widget is added as a child.
I> You need to set the [`controller`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/controller.html) property to update range selector thumb values dynamically. Refer this [`link`](https://help.syncfusion.com/flutter/range-selector/range-controller) for setting controller property. The [initialValues](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) property can be used to set values at load time.
{% tabs %}
{% highlight Dart %}
@ -82,8 +91,8 @@ Widget build(BuildContext context) {
series: <SplineAreaSeries<Data, DateTime>>[
SplineAreaSeries<Data, DateTime>(
dataSource: _chartData,
xValueMapper: (Data sales, _) => sales.x,
yValueMapper: (Data sales, _) => sales.y)
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
height: 250,
@ -93,14 +102,8 @@ Widget build(BuildContext context) {
);
}
{% endhighlight %}
{% endtabs %}
{% tabs %}
{% highlight Dart %}
class Data {
Data({this.x, this.y});
Data({required this.x, required this.y});
final DateTime x;
final double y;
}
@ -110,30 +113,36 @@ class Data {
![Default range selector](images/getting-started/default-range-selector.png)
## Add tick with numeric labels
## Handle range change
Add the range selector with ticks, numeric labels, minimum and maximum values to restrict the slider range.
The [`onChanged`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/onChanged.html) callback is called when the user is selecting the new values.
N> The label type like numeric or date time can be determined based on the `min` and `max` properties.
I> You need to set the [`controller`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/controller.html) property to update range selector thumb values dynamically. Refer this [`link`](https://help.syncfusion.com/flutter/range-selector/range-controller) for setting controller property. The [initialValues](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) property can be used to set values at load time.
{% tabs %}
{% highlight Dart %}
final double _min = 10;
final double _max = 90;
final SfRangeValues _initialValues = SfRangeValues(40.0, 60.0);
final SfRangeValues _initialValues = SfRangeValues(0.3, 0.7);
final List<Data> _chartData = <Data>[
Data(x: DateTime(2003, 01, 01), y: 3.4),
Data(x: DateTime(2004, 01, 01), y: 2.8),
Data(x: DateTime(2005, 01, 01), y: 1.6),
Data(x: DateTime(2006, 01, 01), y: 2.3),
Data(x: DateTime(2007, 01, 01), y: 2.5),
Data(x: DateTime(2008, 01, 01), y: 2.9),
Data(x: DateTime(2009, 01, 01), y: 3.8),
Data(x: DateTime(2010, 01, 01), y: 2.0),
];
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: SfRangeSelector(
min: _min,
max: _max,
initialValues: _initialValues,
interval: 10,
showLabels: true,
showTicks: true,
onChanged: (SfRangeValues values) {
},
child: Container(
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
@ -143,8 +152,8 @@ Widget build(BuildContext context) {
series: <SplineAreaSeries<Data, DateTime>>[
SplineAreaSeries<Data, DateTime>(
dataSource: _chartData,
xValueMapper: (Data sales, _) => sales.x,
yValueMapper: (Data sales, _) => sales.y)
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
height: 250,
@ -154,61 +163,294 @@ Widget build(BuildContext context) {
);
}
class Data {
Data({required this.x, required this.y});
final DateTime x;
final double y;
}
{% endhighlight %}
{% endtabs %}
## Set numeric range
You can show numeric values in the range selector by setting `double` values to the [`min`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/min.html), [`max`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/max.html) and [`initialValues`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) properties.
I> You need to set the [`controller`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/controller.html) property to update range selector thumb values dynamically. Refer this [`link`](https://help.syncfusion.com/flutter/range-selector/range-controller) for setting controller property. The [initialValues](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) property can be used to set values at load time.
{% tabs %}
{% highlight Dart %}
final double _min = 2.0;
final double _max = 10.0;
SfRangeValues _initialValues = SfRangeValues(4.0, 8.0);
final List<Data> _chartData = <Data>[
Data(x:2.0, y: 2.2),
Data(x:3.0, y: 3.4),
Data(x:4.0, y: 2.8),
Data(x:5.0, y: 1.6),
Data(x:6.0, y: 2.3),
Data(x:7.0, y: 2.5),
Data(x:8.0, y: 2.9),
Data(x:9.0, y: 3.8),
Data(x:10.0, y: 3.7),
];
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: SfRangeSelector(
min: _min,
max: _max,
initialValues: _initialValues,
interval: 2,
showLabels: true,
child: Container(
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis: NumericAxis(
isVisible: false,),
primaryYAxis: NumericAxis(isVisible: false, maximum: 4),
series: <SplineAreaSeries<Data, double>>[
SplineAreaSeries<Data, double>(
dataSource: _chartData,
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
height: 250,
),
),
),
);
}
class Data {
Data({required this.x, required this.y});
final double x;
final double y;
}
{% endhighlight %}
{% endtabs %}
![Numeric range selector](images/getting-started/numeric-range-selector.png)
## Add tick with date labels
## Set date range
Add range selector with ticks and date labels.
You can show date values in the range selector by setting `DateTime` values to the [`min`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/min.html), [`max`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/max.html) and [`initialValues`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) properties.
N> You must import the 'package:intl/intl.dart' show DateFormat` package to add the date format in the range selector.
N> You must import [`intl`](https://pub.dev/packages/intl) package for formatting date range selector using the [`DateFormat`](https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html) class.
I> You need to set the [`controller`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/controller.html) property to update range selector thumb values dynamically. Refer this [`link`](https://help.syncfusion.com/flutter/range-selector/range-controller) for setting controller property. The [initialValues](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) property can be used to set values at load time.
{% tabs %}
{% highlight Dart %}
final DateTime _dateTimeMin = DateTime(2003, 01, 01);
final DateTime _dateTimeMax = DateTime(2010, 01, 01);
final SfRangeValues _dateTimeValues = SfRangeValues(DateTime(2005, 01, 01), DateTime(2008, 01, 01));
final DateTime _min = DateTime(2002, 01, 01);
final DateTime _max = DateTime(2010, 01, 01);
SfRangeValues _values = SfRangeValues(DateTime(2004, 01, 01), DateTime(2008, 01, 01));
final List<Data> _chartData = <Data>[
Data(x: DateTime(2002, 01, 01), y: 2.2),
Data(x: DateTime(2003, 01, 01), y: 3.4),
Data(x: DateTime(2004, 01, 01), y: 2.8),
Data(x: DateTime(2005, 01, 01), y: 1.6),
Data(x: DateTime(2006, 01, 01), y: 2.3),
Data(x: DateTime(2007, 01, 01), y: 2.5),
Data(x: DateTime(2008, 01, 01), y: 2.9),
Data(x: DateTime(2009, 01, 01), y: 3.8),
Data(x: DateTime(2010, 01, 01), y: 3.7),
];
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: SfRangeSelector(
min: _dateTimeMin,
max: _dateTimeMax,
initialValues: _dateTimeValues,
labelPlacement: LabelPlacement.betweenTicks,
dateIntervalType: DateIntervalType.months,
interval: 12,
dateFormat: DateFormat.y(),
showLabels: true,
showTicks: true,
child: Container(
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis: DateTimeAxis(
minimum: dateTimeMin,
maximum: dateTimeMax,
isVisible: false,),
primaryYAxis: NumericAxis(isVisible: false, maximum: 4),
series: <SplineAreaSeries<Data, DateTime>>[
SplineAreaSeries<Data, DateTime>(
dataSource: chartData,
xValueMapper: (Data sales, _) => sales.x,
yValueMapper: (Data sales, _) => sales.y)
],
),
height: 250,
),
),
),
);
min: _min,
max: _max,
showLabels: true,
interval: 2,
dateFormat: DateFormat.y(),
dateIntervalType: DateIntervalType.years,
initialValues: _values,
child: Container(
height: 130,
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis: DateTimeAxis(
minimum: _min,
maximum: _max,
isVisible: false),
primaryYAxis: NumericAxis(isVisible: false),
plotAreaBorderWidth: 0,
series: <SplineAreaSeries<Data, DateTime>>[
SplineAreaSeries<Data, DateTime>(
color: Color.fromARGB(255, 126, 184, 253),
dataSource: _chartData,
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
),
),
),
);
}
class Data {
Data({required this.x, required this.y});
final DateTime x;
final double y;
}
{% endhighlight %}
{% endtabs %}
![Date time range selector](images/getting-started/date-time-range-selector.png)
## Enable ticks
You can enable ticks in the range selector using the [`showTicks`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/showTicks.html) property.
I> You need to set the [`controller`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/controller.html) property to update range selector thumb values dynamically. Refer this [`link`](https://help.syncfusion.com/flutter/range-selector/range-controller) for setting controller property. The [initialValues](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) property can be used to set values at load time.
{% tabs %}
{% highlight Dart %}
final double _min = 2.0;
final double _max = 10.0;
SfRangeValues _initialValues = SfRangeValues(4.0, 8.0);
final List<Data> _chartData = <Data>[
Data(x:2.0, y: 2.2),
Data(x:3.0, y: 3.4),
Data(x:4.0, y: 2.8),
Data(x:5.0, y: 1.6),
Data(x:6.0, y: 2.3),
Data(x:7.0, y: 2.5),
Data(x:8.0, y: 2.9),
Data(x:9.0, y: 3.8),
Data(x:10.0, y: 3.7),
];
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: SfRangeSelector(
min: _min,
max: _max,
initialValues: _initialValues,
interval: 1,
showLabels: true,
showTicks: true,
child: Container(
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis: NumericAxis(
isVisible: false,),
primaryYAxis: NumericAxis(isVisible: false, maximum: 4),
series: <SplineAreaSeries<Data, double>>[
SplineAreaSeries<Data, double>(
dataSource: _chartData,
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
height: 250,
),
),
),
);
}
class Data {
Data({required this.x, required this.y});
final double x;
final double y;
}
{% endhighlight %}
{% endtabs %}
![Show ticks in range selector](images/getting-started/range-selector_with_ticks.png)
## Add prefix/suffix to labels
You can add prefix or suffix to the labels using the [`numberFormat`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/numberFormat.html) or [`dateFormat`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/dateFormat.html) properties.
N> The format type (numeric or date) of the range selector is determined based on the values specified in [`min`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/min.html), [`max`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/max.html) and [`initialValues`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/initialValues.html) properties.
I> You must import [`intl`](https://pub.dev/packages/intl) package for formatting date range selector using the [`DateFormat`](https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html) class and for formatting numeric range selector using the [`NumberFormat`](https://pub.dev/documentation/intl/latest/intl/NumberFormat-class.html) class.
{% tabs %}
{% highlight Dart %}
final double _min = 2.0;
final double _max = 10.0;
SfRangeValues _initialValues = SfRangeValues(4.5, 8.5);
final List<Data> _chartData = <Data>[
Data(x:2.0, y: 2.2),
Data(x:3.0, y: 3.4),
Data(x:4.0, y: 2.8),
Data(x:5.0, y: 1.6),
Data(x:6.0, y: 2.3),
Data(x:7.0, y: 2.5),
Data(x:8.0, y: 2.9),
Data(x:9.0, y: 3.8),
Data(x:10.0, y: 3.7),
];
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: SfRangeSelector(
min: _min,
max: _max,
initialValues: _initialValues,
interval: 1,
showLabels: true,
showTicks: true,
numberFormat: NumberFormat("\$"),
child: Container(
height: 130,
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis: NumericAxis(
isVisible: false,
minimum: _min,
maximum: _max,
),
primaryYAxis: NumericAxis(isVisible: false, maximum: 4),
plotAreaBorderWidth: 0,
plotAreaBackgroundColor: Colors.transparent,
series: <ColumnSeries<Data, double>>[
ColumnSeries<Data, double>(
dataSource: _chartData,
color: Color.fromARGB(255, 126, 184, 253),
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
),
),
),
);
}
class Data {
Data({required this.x, required this.y});
final double x;
final double y;
}
{% endhighlight %}
{% endtabs %}
![Format labels in range selector](images/getting-started/range-selector_with_formatted_label.png)

Просмотреть файл

@ -1,23 +1,23 @@
---
layout: post
title: Overview of Syncfusion Flutter Range Selector
description: Syncfusion flutter range selector provides a rich set of features such as support for numeric and date values, ticks, labels and tooltips.
platform: flutter
title: About Flutter Range Selector widget | Syncfusion
description: Learn here all about the introduction of Syncfusion Flutter Range Selector (SfRangeSelector) widget, its features, and more.
platform: Flutter
control: SfRangeSelector
documentation: ug
---
# Overview of Range Selector
# Flutter range selector (SfRangeSelector) Overview
Syncfusion flutter range selector provides a rich set of features such as support for numeric and date values, ticks, labels and tooltips.
Syncfusion Flutter Range Selector is a highly interactive UI widget for selecting a smaller range from a larger data set. It provides a rich set of features such as numeric and date values, labels, ticks, dividers, and tooltips. It also supports adding any type of widget as content.
![Range selector overview](images/overview/range-selector-overview.png)
## Features
* **Child support** - Add a child of any type inside the range selector. It is also possible to add [Charts](https://help.syncfusion.com/flutter/chart/getting-started) widget. With the built-in integrations, the range selector is smart enough to handle features like segment selection and zooming in the chart based on the selected range in the range selector. Similar to the range slider, it also supports both numeric and date values.
* **Child support** - Add a child of any type inside the range selector. It is also possible to add [Charts](https://www.syncfusion.com/flutter-widgets/flutter-charts) widget. With the built-in integrations, the range selector is smart enough to handle features like segment selection and zooming in the chart based on the selected range in the range selector. Similar to the range slider, it also supports both numeric and date values.
* **Numeric and date support** - Provides functionality for selecting numeric and date ranges. For the date range, support is provided up to the seconds interval.
* **Labels** - Render labels for the date and numeric ranges with the option to customize their format based on your requirements.
* **Ticks and divisors** - Provides the option to show ticks and divisors based on the interval. Also enables minor ticks to indicate the values between each interval. These options present the selected range in a more intuitive way for end users.
* **Ticks and dividers** - Provides the option to show ticks and dividers based on the interval. Also enables minor ticks to indicate the values between each interval. These options present the selected range in a more intuitive way for end users.
* **Highly customizable** - In addition to the rich set of built-in features, fully customize the control in a much simpler way using the wide range of provided options.
* **Tooltips** - Render tooltips to show the selected range clearly. It is also possible to customize the format of the text shown in the tooltip.

Просмотреть файл

@ -0,0 +1,484 @@
---
layout: post
title: Custom shapes in Flutter Range Selector widget | Syncfusion
description: Learn here all about adding the custom shapes in Syncfusion Flutter Range Selector (SfRangeSelector) widget and more.
platform: Flutter
control: SfRangeSelector
documentation: ug
---
# Shapes in Flutter Range Selector (SfRangeSelector)
This section helps to learn about how to customize the shapes of the range selector elements.
## Track shape
You can change the size and shape of the track using the [`trackShape`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/trackShape.html) property in the `SfRangeSelector`.
* getPreferredSize() - Returns the size based on the values passed to it.
* paint() - Used to change the track shape.
N>
* You must use the `thumbCenter` and `currentValue` parameters of paint override method for customizing slider track.
* You must use the `startThumbCenter`, `endThumbCenter`, and `currentValues` parameters of paint override method for customizing range slider and range selector track.
{% tabs %}
{% highlight Dart %}
double _min = 2.0;
double _max = 10.0;
SfRangeValues _values = SfRangeValues(3.0, 8.0);
final List<Data> chartData = <Data>[
Data(x: 2.0, y: 2.2),
Data(x: 3.0, y: 3.4),
Data(x: 4.0, y: 2.8),
Data(x: 5.0, y: 1.6),
Data(x: 6.0, y: 2.3),
Data(x: 7.0, y: 2.5),
Data(x: 8.0, y: 2.9),
Data(x: 9.0, y: 3.8),
Data(x: 10.0, y: 3.7),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfRangeSelectorTheme(
data: SfRangeSelectorThemeData(
activeTrackHeight: 10,
inactiveTrackHeight: 10,
),
child: SfRangeSelector(
min: 0.0,
max: 10.0,
initialValues: _values,
trackShape: _TrackShape(),
child: Container(
height: 130,
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis:
NumericAxis(minimum: _min, maximum: _max, isVisible: false),
primaryYAxis: NumericAxis(isVisible: false),
plotAreaBorderWidth: 0,
series: <SplineAreaSeries<Data, double>>[
SplineAreaSeries<Data, double>(
color: Color.fromARGB(255, 126, 184, 253),
dataSource: chartData,
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
),
),
),
),
);
}
class Data {
Data({required this.x, required this.y});
final double x;
final double y;
}
class _TrackShape extends SfTrackShape {
void paint(PaintingContext context, Offset offset, Offset? thumbCenter,
Offset? startThumbCenter, Offset? endThumbCenter,
{required RenderBox parentBox,
required SfSliderThemeData themeData,
SfRangeValues? currentValues,
dynamic currentValue,
required Animation<double> enableAnimation,
required Paint? inactivePaint,
required Paint? activePaint,
required TextDirection textDirection}) {
Paint paint = Paint()
..color = themeData.activeTrackColor!
..style = PaintingStyle.stroke
..strokeWidth = 1;
super.paint(context, offset, thumbCenter, startThumbCenter, endThumbCenter,
parentBox: parentBox,
themeData: themeData,
enableAnimation: enableAnimation,
inactivePaint: inactivePaint,
activePaint: paint,
textDirection: textDirection);
}
}
{% endhighlight %}
{% endtabs %}
![Track shape](images/shapes/track-shape.png)
## Thumb shape
You can change the size and shape of the thumb using the [`thumbShape`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/thumbShape.html) property in the `SfRangeSelector`.
* getPreferredSize() - Returns the size based on the values passed to it.
* paint() - Used to change the thumb shape.
N>
* You must use the `currentValue` parameter of paint override method for customizing slider thumb.
* You must use the `currentValues` parameter of paint override method for customizing range slider and range selector thumbs.
{% tabs %}
{% highlight Dart %}
double _min = 2.0;
double _max = 10.0;
SfRangeValues _values = SfRangeValues(4.0, 8.0);
final List<Data> chartData = <Data>[
Data(x: 2.0, y: 2.2),
Data(x: 3.0, y: 3.4),
Data(x: 4.0, y: 2.8),
Data(x: 5.0, y: 1.6),
Data(x: 6.0, y: 2.3),
Data(x: 7.0, y: 2.5),
Data(x: 8.0, y: 2.9),
Data(x: 9.0, y: 3.8),
Data(x: 10.0, y: 3.7),
];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfRangeSelectorTheme(
data: SfRangeSelectorThemeData(overlayColor: Colors.transparent),
child: SfRangeSelector(
min: _min,
max: _max,
initialValues: _values,
thumbShape: _SfThumbShape(),
child: Container(
height: 130,
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis: NumericAxis(
minimum: _min, maximum: _max, isVisible: false),
primaryYAxis: NumericAxis(isVisible: false),
plotAreaBorderWidth: 0,
series: <SplineAreaSeries<Data, double>>[
SplineAreaSeries<Data, double>(
color: Color.fromARGB(255, 126, 184, 253),
dataSource: chartData,
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
),
),
),
),
),
);
}
class Data {
Data({required this.x, required this.y});
final double x;
final double y;
}
class _SfThumbShape extends SfThumbShape {
@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}) {
final Path path = Path();
path.moveTo(center.dx, center.dy);
path.lineTo(center.dx + 10, center.dy - 15);
path.lineTo(center.dx - 10, center.dy - 15);
path.close();
context.canvas.drawPath(
path,
Paint()
..color = themeData.activeTrackColor!
..style = PaintingStyle.fill
..strokeWidth = 2);
}
}
{% endhighlight %}
{% endtabs %}
![Thumb shape](images/shapes/thumb-shape.png)
## Divider shape
You can change the size and shape of the divider using the `dividerShape` property in the `SfRangeSelector`.
* getPreferredSize() - Returns the size based on the values passed to it.
* paint() - Used to change the divider shape.
N>
* You must use the `thumbCenter` and `currentValue` parameters of paint override method for customizing slider divider.
* You must use the `startThumbCenter`, `endThumbCenter`, and `currentValues` parameters of paint override method for customizing range slider and range selector divider.
{% tabs %}
{% highlight Dart %}
double _min = 2.0;
double _max = 10.0;
SfRangeValues _values = SfRangeValues(4.0, 8.0);
final List<Data> chartData = <Data>[
Data(x: 2.0, y: 2.2),
Data(x: 3.0, y: 3.4),
Data(x: 4.0, y: 2.8),
Data(x: 5.0, y: 1.6),
Data(x: 6.0, y: 2.3),
Data(x: 7.0, y: 2.5),
Data(x: 8.0, y: 2.9),
Data(x: 9.0, y: 3.8),
Data(x: 10.0, y: 3.7),
];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfRangeSelector(
min: _min,
max: _max,
initialValues: _values,
interval: 1,
showDividers: true,
dividerShape: _DividerShape(),
child: Container(
height: 130,
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis:
NumericAxis(minimum: _min, maximum: _max, isVisible: false),
primaryYAxis: NumericAxis(isVisible: false),
plotAreaBorderWidth: 0,
series: <SplineAreaSeries<Data, double>>[
SplineAreaSeries<Data, double>(
color: Color.fromARGB(255, 126, 184, 253),
dataSource: chartData,
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
),
),
),
),
);
}
class Data {
Data({required this.x, required this.y});
final double x;
final double y;
}
class _DividerShape extends SfDividerShape {
@override
void paint(PaintingContext context, Offset center, Offset? thumbCenter,
Offset? startThumbCenter, Offset? endThumbCenter,
{required RenderBox parentBox,
required SfSliderThemeData themeData,
SfRangeValues? currentValues,
dynamic currentValue,
required Paint? paint,
required Animation<double> enableAnimation,
required TextDirection textDirection}) {
final bool isActive =
center.dx >= startThumbCenter!.dx && center.dx <= endThumbCenter!.dx;
context.canvas.drawRect(
Rect.fromCenter(center: center, width: 5.0, height: 10.0),
Paint()
..isAntiAlias = true
..style = PaintingStyle.fill
..color = isActive ? Colors.white : themeData.activeTrackColor!);
}
}
{% endhighlight %}
{% endtabs %}
![Divider shape](images/shapes/divider-shape.png)
## Major and minor ticks shapes
You can change the size and shape of the major and minor ticks using the [`tickShape`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/tickShape.html) and [`minorTickShape`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSelector/minorTickShape.html) properties in the `SfRangeSelector`.
* getPreferredSize() - Returns the size based on the values passed to it.
* paint() - Used to change the ticks shape.
N>
* You must use the `thumbCenter` and `currentValue` parameters of paint override method for customizing slider ticks.
* You must use the `startThumbCenter`, `endThumbCenter`, and `currentValues` parameters of paint override method for customizing range slider and range selector ticks.
{% tabs %}
{% highlight Dart %}
double _min = 2.0;
double _max = 10.0;
SfRangeValues _values = SfRangeValues(4.0, 8.0);
final List<Data> chartData = <Data>[
Data(x: 2.0, y: 2.2),
Data(x: 3.0, y: 3.4),
Data(x: 4.0, y: 2.8),
Data(x: 5.0, y: 1.6),
Data(x: 6.0, y: 2.3),
Data(x: 7.0, y: 2.5),
Data(x: 8.0, y: 2.9),
Data(x: 9.0, y: 3.8),
Data(x: 10.0, y: 3.7),
];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfRangeSelector(
min: _min,
max: _max,
initialValues: _values,
interval: 1,
showTicks: true,
minorTicksPerInterval: 3,
tickShape: _TickShape(),
minorTickShape: _MinorTickShape(),
child: Container(
height: 130,
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis:
NumericAxis(minimum: _min, maximum: _max, isVisible: false),
primaryYAxis: NumericAxis(isVisible: false),
plotAreaBorderWidth: 0,
series: <SplineAreaSeries<Data, double>>[
SplineAreaSeries<Data, double>(
color: Color.fromARGB(255, 126, 184, 253),
dataSource: chartData,
xValueMapper: (Data sales, int index) => sales.x,
yValueMapper: (Data sales, int index) => sales.y)
],
),
),
),
),
),
);
}
class Data {
Data({required this.x, required this.y});
final double x;
final double y;
}
class _TickShape extends SfTickShape {
@override
void paint(PaintingContext context, Offset offset, Offset? thumbCenter,
Offset? startThumbCenter, Offset? endThumbCenter,
{required RenderBox parentBox,
required SfSliderThemeData themeData,
SfRangeValues? currentValues,
dynamic currentValue,
required Animation<double> enableAnimation,
required TextDirection textDirection}) {
final Size tickSize = getPreferredSize(themeData);
final bool isTickRightOfThumb = endThumbCenter == null
? offset.dx > thumbCenter!.dx
: offset.dx < startThumbCenter!.dx || offset.dx > endThumbCenter.dx;
final Color begin = isTickRightOfThumb
? themeData.disabledInactiveTickColor
: themeData.disabledActiveTickColor;
final Color end = isTickRightOfThumb
? themeData.inactiveTickColor
: themeData.activeTickColor;
final Paint paint = Paint()
..isAntiAlias = true
..strokeWidth = tickSize.width
..color = ColorTween(begin: begin, end: end).evaluate(enableAnimation)!;
context.canvas.drawLine(
offset, Offset(offset.dx, offset.dy + tickSize.height), paint);
context.canvas.drawLine(
Offset(
offset.dx,
offset.dy -
2 -
math.max(themeData.activeTrackHeight,
themeData.inactiveTrackHeight)),
Offset(
offset.dx,
offset.dy -
2 -
math.max(themeData.activeTrackHeight,
themeData.inactiveTrackHeight) -
tickSize.height),
paint);
}
}
class _MinorTickShape extends SfTickShape {
@override
void paint(PaintingContext context, Offset offset, Offset? thumbCenter,
Offset? startThumbCenter, Offset? endThumbCenter,
{required RenderBox parentBox,
required SfSliderThemeData themeData,
SfRangeValues? currentValues,
dynamic currentValue,
required Animation<double> enableAnimation,
required TextDirection textDirection}) {
final Size minorTickSize = getPreferredSize(themeData);
final bool isMinorTickRightOfThumb = endThumbCenter == null
? offset.dx > thumbCenter!.dx
: offset.dx < startThumbCenter!.dx || offset.dx > endThumbCenter.dx;
final Color begin = isMinorTickRightOfThumb
? themeData.disabledInactiveMinorTickColor
: themeData.disabledActiveMinorTickColor;
final Color end = isMinorTickRightOfThumb
? themeData.inactiveMinorTickColor
: themeData.activeMinorTickColor;
final Paint paint = Paint()
..isAntiAlias = true
..strokeWidth = minorTickSize.width
..color = ColorTween(begin: begin, end: end).evaluate(enableAnimation)!;
context.canvas.drawLine(
offset, Offset(offset.dx, offset.dy + minorTickSize.height), paint);
context.canvas.drawLine(
Offset(
offset.dx,
offset.dy -
2 -
math.max(themeData.activeTrackHeight,
themeData.inactiveTrackHeight)),
Offset(
offset.dx,
offset.dy -
2 -
math.max(themeData.activeTrackHeight,
themeData.inactiveTrackHeight) -
minorTickSize.height),
paint);
}
}
{% endhighlight %}
{% endtabs %}
![Ticks shape](images/shapes/ticks-shape.png)

Просмотреть файл

@ -0,0 +1,137 @@
---
layout: post
title: Drag modes in Flutter Range Slider widget | Syncfusion
description: Learn here all about adding the multiple drag modes in Syncfusion Flutter Range Slider (SfRangeSlider) widget and more.
platform: Flutter
control: SfRangeSlider
documentation: ug
---
# Drag modes in Flutter Range Slider (SfRangeSlider)
## On thumb
When `dragMode` is set to `SliderDragMode.onThumb`, only individual thumb can be moved by dragging it. The nearest thumb will move to the touch position if interaction is done anywhere other than the thumb. The default value of the `dragMode` property is `SliderDragMode.onThumb`.
{% tabs %}
{% highlight Dart %}
SfRangeValues _values = SfRangeValues(DateTime(2014, 01, 01), DateTime(2016, 01, 01));
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 400,
width: 400,
child: SfRangeSlider(
min: DateTime(2010, 01, 01),
max: DateTime(2020, 01, 01),
dragMode: SliderDragMode.onThumb,
showLabels: true,
showTicks: true,
interval: 2,
dateIntervalType: DateIntervalType.years,
dateFormat: DateFormat.y(),
values: _values,
enableTooltip: true,
onChanged: (SfRangeValues newValues) {
setState(() {
_values = newValues;
});
},
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Drag mode on thumb](images/drag-mode/range-slider-drag-mode-on-thumb.gif)
## Between thumbs
When `dragMode` is set to `SliderDragMode.betweenThumbs`, both the thumbs can be moved at the same time by dragging in the area between start and end thumbs. The range between the start and end thumb will always be the same. Hence, it is not possible to move the individual thumb.
N> It is applicable for both horizontal and vertical range slider.
{% tabs %}
{% highlight Dart %}
SfRangeValues _values = SfRangeValues(DateTime(2012, 01, 01), DateTime(2016, 01, 01));
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 400,
width: 400,
child: SfRangeSlider(
min: DateTime(2010, 01, 01),
max: DateTime(2020, 01, 01),
dragMode: SliderDragMode.betweenThumbs,
showLabels: true,
showTicks: true,
interval: 2,
dateIntervalType: DateIntervalType.years,
dateFormat: DateFormat.y(),
values: _values,
enableTooltip: true,
onChanged: (SfRangeValues newValues) {
setState(() {
_values = newValues;
});
},
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Drag mode between thumb](images/drag-mode/range-slider-drag-mode-between-thumb.gif)
## Both thumbs
When `dragMode` is set to `SliderDragMode.both`, individual thumb can be moved by dragging it, and also both the thumbs can be moved at the same time by dragging in the area between start and end thumbs.
N> It is applicable for both horizontal and vertical range slider.
{% tabs %}
{% highlight Dart %}
SfRangeValues _values = SfRangeValues(DateTime(2014, 01, 01), DateTime(2016, 01, 01));
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 400,
width: 400,
child: SfRangeSlider(
min: DateTime(2010, 01, 01),
max: DateTime(2020, 01, 01),
dragMode: SliderDragMode.both,
showLabels: true,
showTicks: true,
interval: 2,
dateIntervalType: DateIntervalType.years,
dateFormat: DateFormat.y(),
values: _values,
enableTooltip: true,
onChanged: (SfRangeValues newValues) {
setState(() {
_values = newValues;
});
},
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Drag mode both thumb](images/drag-mode/range-slider-drag-mode-both.gif)

Просмотреть файл

@ -1,30 +1,37 @@
---
layout: post
title: Getting Started for Syncfusion Flutter Range Slider | Syncfusion
description: This section explains the steps required to add the range slider widget and its elements such as numeric and date values, ticks, labels and tooltips
platform: flutter
title: Getting started with Flutter Range Slider widget | Syncfusion
description: Learn here about getting started with Syncfusion Flutter Range Slider (SfRangeSlider) widget, its elements, and more.
platform: Flutter
control: SfRangeSlider
documentation: ug
---
# Getting Started for Range Slider
This section explains the steps required to add the range slider widget and ts elements such as numeric and date values, ticks, labels and tooltips. This section covers only basic features needed to know to get started with Syncfusion range slider.
# Getting started with Flutter Range Slider (SfRangeSlider)
This section explains the steps required to add the range slider widget and its elements such as numeric and date values, ticks, labels and tooltips. This section covers only basic features needed to know to get started with Syncfusion range slider.
## Add flutter range slider to an application
To get start quickly with our Flutter Range Slider widget, you can check on this video.
<style>#FlutterRangeSliderVideoTutorial{width : 90% !important; height: 300px !important }</style>
<iframe id='FlutterRangeSliderVideoTutorial' src='https://www.youtube.com/embed/ndF9XToq4rI'></iframe>
## Add Flutter range slider to an application
Create a simple project using the instructions given in the [Getting Started with your first Flutter app](https://flutter.dev/docs/get-started/test-drive?tab=vscode#create-app) documentation.
**Add dependency**
Add the Syncfusion flutter range slider dependency to your pubspec.yaml file.
Add the Syncfusion Flutter range slider dependency to your pubspec.yaml file.
{% highlight dart %}
dependencies:
syncfusion_flutter_sliders: ^18.1.0.36-beta
syncfusion_flutter_sliders: ^xx.x.xx
{% endhighlight %}
N> Here **xx.x.xx** denotes the current version of [`Syncfusion Flutter Sliders`](https://pub.dev/packages/syncfusion_flutter_sliders/versions) package.
**Get packages**
Run the following command to get the required packages.
@ -49,9 +56,11 @@ import 'package:syncfusion_flutter_sliders/sliders.dart';
## Initialize range slider
After importing the package, initialize the range slider widget as a child of any widget. Here, the range slider widget is added as a child of the Container widget. The default value of the `min` and `max` property of the SfRangeSlider is 0.0 and 1.0 respectively. So, the `values` property must be given within the range.
After importing the package, initialize the range slider widget as a child of any widget. Here, the range slider widget is added as a child of the Container widget. The default value of the [`min`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/min.html) and [`max`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/max.html) properties of the [`SfRangeSlider`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider-class.html) is 0.0 and 1.0 respectively. So, the [`values`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/values.html) property must be given within the range.
N> You must update the `values` property inside the `setState` function for the movement of the thumb in the range slider.
N> The range slider passes the new values to the [`onChanged`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/onChanged.html) callback but does not change its state until the parent widget rebuilds the range slider with new values.
### Horizontal
{% tabs %}
{% highlight Dart %}
@ -83,11 +92,271 @@ Widget build(BuildContext context) {
![Default range slider](images/getting-started/default_range_slider.png)
## Add tick with numeric labels
### Vertical
Add the range slider with ticks, numeric labels, minimum and maximum values to restrict the slider range.
{% tabs %}
{% highlight Dart %}
N> The label type like numeric or date time can be determined based on the `min` and `max` properties.
SfRangeValues _values = const SfRangeValues(0.3, 0.7);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
child: SfRangeSlider.vertical(
values: _values,
onChanged: (dynamic values){
setState(() {
_values = values;
});
},
)
)
)
)
);
}
{% endhighlight %}
{% endtabs %}
![Default range slider](images/getting-started/vertical_default_range_slider.png)
## Handle range change
The [`onChanged`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/onChanged.html) callback is used to get the current value of the range slider when the user selects a value through interaction.
N> The range slider passes the new values to the callback but does not change its state until the parent widget rebuilds the range slider with new values.
### Horizontal
{% tabs %}
{% highlight Dart %}
SfRangeValues _values = SfRangeValues(3.0, 7.0);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfRangeSlider(
min: 0.0,
max: 10.0,
values: _values,
onChanged: (SfRangeValues newValues) {
setState(() {
_values = newValues;
});
},
)
)
)
);
}
{% endhighlight %}
{% endtabs %}
![Handle range slider](images/getting-started/handle-range-slider-state.png)
### Vertical
{% tabs %}
{% highlight Dart %}
SfRangeValues _values = SfRangeValues(3.0, 7.0);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SfRangeSlider.vertical(
min: 0.0,
max: 10.0,
values: _values,
onChanged: (SfRangeValues newValues) {
setState(() {
_values = newValues;
});
},
)
)
)
);
}
{% endhighlight %}
{% endtabs %}
![Handle range slider](images/getting-started/vertical-handle-range-slider-state.png)
## Set numeric range
You can show numeric values in the range slider by setting `double` values to the [`min`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/min.html), [`max`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/max.html) and [`values`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/values.html) properties.
### Horizontal
{% tabs %}
{% highlight Dart %}
final double _min = 0;
final double _max = 100;
SfRangeValues _values = const SfRangeValues(40.0, 60.0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfRangeSlider(
min: _min,
max: _max,
values: _values,
interval: 20,
showLabels: true,
onChanged: (SfRangeValues value) {
setState(() {
_values = value;
});
},
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Numeric range slider](images/getting-started/numeric_range_slider.png)
### Vertical
{% tabs %}
{% highlight Dart %}
final double _min = 0;
final double _max = 100;
SfRangeValues _values = const SfRangeValues(40.0, 60.0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfRangeSlider.vertical(
min: _min,
max: _max,
values: _values,
interval: 20,
showLabels: true,
onChanged: (SfRangeValues value) {
setState(() {
_values = value;
});
},
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Numeric range slider](images/getting-started/vertical_numeric_range_slider.png)
## Set date range
You can show date values in the range slider by setting `DateTime` values to the [`min`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/min.html), [`max`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/max.html) and [`values`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/values.html) properties.
N> You must import [`intl`](https://pub.dev/packages/intl) package for formatting date range slider using the [`DateFormat`](https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html) class.
### Horizontal
{% tabs %}
{% highlight Dart %}
DateTime _min = DateTime(2008, 01, 01);
DateTime _max = DateTime(2018, 01, 01);
SfRangeValues _values = SfRangeValues(DateTime(2012, 01, 01), DateTime(2014, 01, 01));
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfRangeSlider(
min: _min,
max: _max,
values: _values,
interval: 2,
showLabels: true,
dateIntervalType: DateIntervalType.years,
dateFormat: DateFormat.y(),
onChanged: (SfRangeValues value) {
setState(() {
_values = value;
});
},
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![DateTime range slider](images/getting-started/date_range_slider.png)
### Vertical
{% tabs %}
{% highlight Dart %}
DateTime _min = DateTime(2008, 01, 01);
DateTime _max = DateTime(2018, 01, 01);
SfRangeValues _values = SfRangeValues(DateTime(2012, 01, 01), DateTime(2014, 01, 01));
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfRangeSlider.vertical(
min: _min,
max: _max,
values: _values,
interval: 2,
showLabels: true,
dateIntervalType: DateIntervalType.years,
dateFormat: DateFormat.y(),
onChanged: (SfRangeValues value) {
setState(() {
_values = value;
});
},
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![DateTime range slider](images/getting-started/vertical_date_range_slider.png)
## Enable ticks
You can enable ticks in the range slider using the [`showTicks`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/showTicks.html) property.
### Horizontal
{% tabs %}
{% highlight Dart %}
@ -108,7 +377,6 @@ Widget build(BuildContext context) {
interval: 20,
showTicks: true,
showLabels: true,
minorTicksPerInterval: 1,
onChanged: (SfRangeValues value) {
setState(() {
_values = value;
@ -123,20 +391,131 @@ Widget build(BuildContext context) {
{% endhighlight %}
{% endtabs %}
![Numeric range slider](images/getting-started/numeric_range_slider.png)
![Numeric range slider](images/getting-started/range_slider_with_tick.png)
## Add tick with date labels
Add the range slider with ticks and date labels.
N> You must import the 'package:intl/intl.dart' show DateFormat` package to add the date format in the range slider.
### Vertical
{% tabs %}
{% highlight Dart %}
DateTime _min = DateTime(2008, 01, 01);
DateTime _max = DateTime(2018, 01, 01);
SfRangeValues _values = SfRangeValues(DateTime(2012, 01, 01), DateTime(2014, 01, 01));
final double _min = 0;
final double _max = 100;
SfRangeValues _values = const SfRangeValues(40.0, 60.0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfRangeSlider.vertical(
min: _min,
max: _max,
values: _values,
interval: 20,
showTicks: true,
showLabels: true,
onChanged: (SfRangeValues value) {
setState(() {
_values = value;
});
},
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Numeric range slider](images/getting-started/vertical_range_slider_with_tick.png)
## Inverse the horizontal range slider
You can invert the horizontal range slider by wrapping the range slider to the [`Directionality`](https://api.flutter.dev/flutter/widgets/Directionality-class.html) widget by setting [`textDirection`](https://api.flutter.dev/flutter/widgets/Directionality/textDirection.html) property to `TextDirection.rtl`.
{% tabs %}
{% highlight Dart %}
SfRangeValues _values = SfRangeValues(20.0, 60.0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Directionality(
textDirection: TextDirection.rtl,
child: SfRangeSlider(
min: 0,
max: 100,
values: _values,
interval: 20,
showTicks: true,
showLabels: true,
onChanged: (SfRangeValues newValues) {
setState(() {
_values = newValues;
});
},
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Inversed horizontal range slider](images/getting-started/inversed_horizontal_range_slider.png)
## Inverse the vertical range slider
You can invert the vertical range slider using the `isInversed` property. The default value of the `isInversed` property is `false`.
{% tabs %}
{% highlight Dart %}
SfRangeValues _values = SfRangeValues(20.0, 60.0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfRangeSlider.vertical(
min: 0,
max: 100,
values: _values,
interval: 20,
isInversed: true,
showTicks: true,
showLabels: true,
onChanged: (SfRangeValues newValues) {
setState(() {
_values = newValues;
});
},
),
);
}
{% endhighlight %}
{% endtabs %}
![Inversed vertical range slider](images/getting-started/inversed_vertical_range_slider.png)
## Add prefix/suffix to labels
You can add prefix or suffix to the labels using the [`numberFormat`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/numberFormat.html) or [`dateFormat`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/dateFormat.html) properties.
N> The format type (numeric or date) of the range slider is determined based on the values specified in [`min`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/min.html), [`max`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/max.html) and [`values`](https://pub.dev/documentation/syncfusion_flutter_sliders/latest/sliders/SfRangeSlider/values.html) properties.
I> You must import [`intl`](https://pub.dev/packages/intl) package for formatting date range slider using the [`DateFormat`](https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html) class and for formatting numeric range slider using the [`NumberFormat`](https://pub.dev/documentation/intl/latest/intl/NumberFormat-class.html) class.
### Horizontal
{% tabs %}
{% highlight Dart %}
final double _min = 0;
final double _max = 100;
SfRangeValues _values = const SfRangeValues(40.0, 60.0);
@override
Widget build(BuildContext context) {
@ -147,12 +526,10 @@ Widget build(BuildContext context) {
min: _min,
max: _max,
values: _values,
interval: 2,
interval: 20,
showTicks: true,
showLabels: true,
minorTicksPerInterval: 1,
dateIntervalType: DateIntervalType.years,
dateFormat: DateFormat.y(),
numberFormat: NumberFormat("\$"),
onChanged: (SfRangeValues value) {
setState(() {
_values = value;
@ -167,4 +544,42 @@ Widget build(BuildContext context) {
{% endhighlight %}
{% endtabs %}
![DateTime range slider](images/getting-started/date_range_slider.png)
![Format label](images/getting-started/slider_with_formatted_label.png)
### Vertical
{% tabs %}
{% highlight Dart %}
final double _min = 0;
final double _max = 100;
SfRangeValues _values = const SfRangeValues(40.0, 60.0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: SfRangeSlider.vertical(
min: _min,
max: _max,
values: _values,
interval: 20,
showTicks: true,
showLabels: true,
numberFormat: NumberFormat("\$"),
onChanged: (SfRangeValues value) {
setState(() {
_values = value;
});
},
),
),
),
);
}
{% endhighlight %}
{% endtabs %}
![Format label](images/getting-started/vertical_slider_with_formatted_label.png)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше