Marker and data label in Flutter Cartesian Charts (SfCartesianChart)

9 Oct 202324 minutes to read

Marker

Markers are used to provide information about the exact point location. You can add a shape to adorn each data point. Markers can be enabled by using the isVisible property of markerSettings. You can use the following properties to customize the appearance.

  • color - used to change the color of the marker shape.
  • borderWidth - used to change the stroke width of the marker shape.
  • borderColor - used to change the stroke color of the marker shape.
  • height - used to change the height of the marker shape.
  • width - used to change the width of the marker shape.
@override
    Widget build(BuildContext context) {
        final List<ChartData> chartData = [
            ChartData('USA', 6),
            ChartData('China', 11),
            ChartData('UK', 9),
            ChartData('Japan', 14),
            ChartData('France', 10),
        ];
        return Scaffold(
            body: Center(
                child: Container(
                    child: SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        series: <CartesianSeries>[
                            LineSeries<ChartData, String>(
                                dataSource: chartData,
                                xValueMapper: (ChartData data, _) => data.x,
                                yValueMapper: (ChartData data, _) => data.y,
                                // Renders the marker 
                                markerSettings: MarkerSettings(
                                    isVisible: true
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
      }

Marker

Customizing marker shapes

Markers can be assigned with different shapes using the shape property. By default, markers are rendered with DataMarkerType.circle shape. The available shapes of markers are listed below.

  • circle
  • rectangle
  • image
  • pentagon
  • verticalLine
  • horizontalLine
  • diamond
  • triangle
  • invertedTriangle
@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                child: Container(
                    child: SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        series: <CartesianSeries>[
                            LineSeries<ChartData, String>(
                                dataSource: chartData,
                                xValueMapper: (ChartData data, _) => data.x,
                                yValueMapper: (ChartData data, _) => data.y,
                                markerSettings: MarkerSettings(
                                    isVisible: true,
                                    // Marker shape is set to diamond
                                    shape: DataMarkerType.diamond
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
      }

Marker Shapes

Image marker

The markers can be rendered with desired image as shape. For this you have to specify the shape as DataMarkerType.image and provide the image using DataMarkerType.image property.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                child: Container(
                    child: SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        series: <CartesianSeries>[
                            LineSeries<ChartData, String>(
                                dataSource: chartData,
                                xValueMapper: (ChartData data, _) => data.x,
                                yValueMapper: (ChartData data, _) => data.y,
                                markerSettings: MarkerSettings(
                                    isVisible: true,
                                    shape: DataMarkerType.image,
                                    // Renders the image as marker
                                    image: const AssetImage('images/livechart.png')
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
      }

Image Marker

Data label

Data label can be added to a chart series by enabling the isVisible property in the dataLabelSettings. You can use the following properties to customize the appearance.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                child: Container(
                    child: SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        series: <CartesianSeries>[
                            LineSeries<ChartData, String>(
                                dataSource: chartData,
                                xValueMapper: (ChartData data, _) => data.x,
                                yValueMapper: (ChartData data, _) => data.y,
                                dataLabelSettings: DataLabelSettings(
                                    // Renders the data label
                                    isVisible: true
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
      }

DataLabel

Formatting label content

Data label considers the format used in the vertical axis by default. In the below code snippet, we have specified format to y-axis and you can see that the same format is applied to the data label.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                child: Container(
                    child: SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        primaryYAxis: NumericAxis(
                          // Applies currency format for y axis labels and also for data labels
                          numberFormat: NumberFormat.simpleCurrency()
                        ),
                        series: <CartesianSeries>[
                            LineSeries<ChartData, String>(
                                dataSource: chartData,
                                color: Colors.red,
                                xValueMapper: (ChartData data, _) => data.x,
                                yValueMapper: (ChartData data, _) => data.y,
                                dataLabelSettings: DataLabelSettings(
                                    isVisible: true
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
    }

DataLabel format

Import the following package to use label format in your package in your application, import "package:intl/intl.dart";.

Label position

The labelAlignment property is used to position the Cartesian chart type data labels at ChartDataLabelAlignment.top, ChartDataLabelAlignment.bottom, ChartDataLabelAlignment.auto, ChartDataLabelAlignment.outer and ChartDataLabelAlignment.middle position of the actual data point position. By default, labels are ChartDataLabelAlignment.auto positioned. You can move the labels horizontally and vertically using OffsetX and OffsetY properties respectively.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                child: Container(
                    child: SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        series: <CartesianSeries>[
                            AreaSeries<ChartData, String>(
                                dataSource: chartData,
                                xValueMapper: (ChartData data, _) => data.x,
                                yValueMapper: (ChartData data, _) => data.y,
                                dataLabelSettings: DataLabelSettings(
                                    isVisible: true,
                                    // Positioning the data label
                                    labelAlignment: ChartDataLabelAlignment.top
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
      }

Data label position

Apply series color

The useSeriesColor property is used to apply the series color to background color of the data labels. The default value of this property is false.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                child: Container(
                    child: SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        series: <CartesianSeries>[
                            AreaSeries<ChartData, String>(
                                dataSource: chartData,
                                xValueMapper: (ChartData data, _) => data.x,
                                yValueMapper: (ChartData data, _) => data.y,
                                dataLabelSettings: DataLabelSettings(
                                    isVisible: true,
                                    // Positioning the data label
                                    useSeriesColor: true,
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
      }

Series color

Point text mapping

The dataLabelMapper property is used to map the text from data source.

@override
    Widget build(BuildContext context) {
        final List<ChartData> chartData =[
        ChartData('Jan', 21),
        ChartData('Feb', 24),
        ChartData('Mar', 36),
        ChartData('Apr', 38),
        ChartData('May', 54),
        ChartData('Jun', 57),
        ChartData('Jul', 70)
     ];

        return Scaffold(
            body: Center(
                child: Container(
                    child:SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        series: <CartesianSeries>[
                            AreaSeries<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.x,
                                dataLabelSettings: DataLabelSettings(
                                    isVisible: true
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
    }

Data label mapper

Label template

You can customize the appearance of the data label with your own template using the builder property of dataLabelSettings.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                child: Container(
                    child:SfCartesianChart(
                        series: <CartesianSeries>[
                            AreaSeries<ChartData, String>(
                                dataSource: chartData,
                                xValueMapper: (ChartData data, _) => data.x,
                                yValueMapper: (ChartData data, _) => data.y,
                                dataLabelMapper: (ChartData data, _) => data.x,
                                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/bike.png')
                                        );
                                    }
                                )
                            )
                        ]
                    )
                )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final String x;
        final double? y;
      }

Label template

Hide data label for 0 value

Data label and its connector line in the Cartesian charts for the point value 0 can be hidden using the showZeroValue property. This defaults to true.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                    child:SfCartesianChart(
                        series: <CartesianSeries<ChartData,num>>[
                            SplineSeries<ChartData, num>(
                                dataLabelSettings: DataLabelSettings(
                                    showZeroValue: false, 
                                    isVisible: true
                                ),
                            )
                        ]
                    )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final num x;
        final double? y;
      }

hide_0_value

Data label padding

The offset property of dataLabelSettings can be used to add padding for the data label to move it in both vertically and horizontally direction from its position. It takes the logical pixel value for x and y values as input.

Note: This is not applicable for other widgets like Circular, Pyramid and Funnel charts.

Horizontal padding

In Horizontal padding, providing positive value for x moves the data label to right and negative value moves to left.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                    child:SfCartesianChart(
                        series: <CartesianSeries<ChartData,num>>[
                            SplineSeries<ChartData, num>(
                                dataLabelSettings: DataLabelSettings(
                                    isVisible: true,
                                    offset: Offset(30, 0),
                                ),
                            )
                        ]
                    )
            )
        );
    }

    class ChartData {
        ChartData(this.x, this.y);
        final num x;
        final double? y;
      }

Horizontal padding

Vertical padding

In Vertical padding, providing positive value for y moves the data label upwards and negative value moves downwards.

@override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                    child:SfCartesianChart(
                        series: <CartesianSeries<ChartData,num>>[
                            SplineSeries<ChartData, num>(
                                dataLabelSettings: DataLabelSettings(
                                    isVisible: true,
                                    offset: Offset(0, 30),
                                ),
                            )
                        ]
                    )
            )
        );
    }

     class ChartData {
        ChartData(this.x, this.y);
        final num x;
        final double? y;
      }

Vertical padding

Data label saturation color

If the user didn’t 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

Note: 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 topic for more details.