Series customization in Flutter Cartesian Charts (SfCartesianChart)

21 Apr 2021 / 24 minutes to read

Animation

SfCartesianChart 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 property. You can disable the animation by setting this property to 0.

  • 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
                                )
                            ]
                        )
                    )
                )
            );
        }

    Dynamic series animation

    SfCartesianChart 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 property’s value in the series. If this property’s value is 0, then the animation will not be performed.

  • dart
  • @override
        Widget build(BuildContext context) {
            ChartSeriesController? _chartSeriesController1, _chartSeriesController2;
            return Column(children: <Widget>[
            Container(
                child: SfCartesianChart(
                primaryXAxis: CategoryAxis(),
                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'),
                    ))
                ],
                ),
            )
            ]);
        }

    Dynamic series animation

    See Also

    Transpose the series

    The isTransposed property of CartesianSeries 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.

  • 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,
                                )
                            ]
                        )
                    )
                )
            );
        }

    Transposed chart

    Color palette

    The palette 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.

  • 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.y2
                                ),
                                ColumnSeries<ChartData, String>(
                                    dataSource: chartData,
                                    xValueMapper: (ChartData data, _) => data.x,
                                    yValueMapper: (ChartData data, _) => data.y3
                                )
                            ]
                        )
                    )
                )
            );
        }

    Palette

    Color mapping for data points

    The pointColorMapper property is used to map the color field from the data source.

  • 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;
        }

    Point color mapping

    Gradient fill

    The gradient 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 to transform the applied gradient colors.

  • 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)
                            ]
                        )
                    )
                )
            );
        }

    Gradient color

    See Also

    NOTE

    : 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 alone.

    Gradient stroke

    The borderGradient property is used to define the gradient color for the border of the applicable series.

    If the properties of both borderColor and borderGradient are defined then borderGradient is considered.

  • 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
                                                ]
                                    ),
                                )
                            ]
                        )
                    )
                )
            );
        }

    stroke_gradient

    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 property in series, you can decide the action taken for empty points. Available modes are gap, zero, drop and average. Default mode of the empty point is gap.

  • 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
                                    )
                                )      
                            ]
                        )
                    )
                )
            );
        }

    Empty points

    Empty point customization

    Specific color for empty point can be set by color property in emptyPointSettings. The borderWidth property is used to change the stroke width of the empty point and borderColor is used to change the stroke color of the empty point.

  • 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
                                    )
                                )
                            ]
                        )
                    )
                )
            );
        }

    Empty points customization

    Sorting

    The chart’s data source can be sorted using the sortingOrder and sortFieldValueMapper properties of series. The sortingOrder property determines whether the data points in the sequence should be sorted in ascending or descending order. The data points will be rendered in the specified order if sortingOrder is set to none. The sortFieldValueMapper specifies the field in the data source, which is considered for sorting the data points.

  • 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
                                )
                            ]
                        )
                    )
                )
            );
        }

    Sorting

    See Also