Syncfusion stacked bar chart

90 Views Asked by At

i am trying to make a pyramid population in flutter dart. i try a tricky way by using stacked bar chart while i make one series data in 'negative' (actually it's a positive number) is there any way to make axis value and data label looks positive (while actually it's a negative number). Or there is another way to create Pyramid Population with Synfusion chart in fultter dart?

what i'm expecting: enter image description here

1

There are 1 best solutions below

2
Lavanya A On BEST ANSWER

The tornado chart a specialized type of the barseries in Charts. The requirement can be achieved by setting the enableSideBySideSeriesPlacement to false and removing the negative sign in the axisLabelFormatter and onDataLabelRender callbacks.

Output:

Tornado chart

Added code snippet below for your reference.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

void main() {
  return runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      debugShowCheckedModeBanner: false,
      home: _MyHomePage(),
    );
  }
}

class _MyHomePage extends StatefulWidget {
  // ignore: prefer_const_constructors_in_immutables
  _MyHomePage({Key? key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<_MyHomePage> {
  List<_SalesData>? data;

  @override
  void initState() {
    super.initState();
    data = [
      _SalesData('0-4', -70.12, 67.12),
      _SalesData('5-9', -75.23, 71.23),
      _SalesData('10-14', -77.34, 72.44),
      _SalesData('15-19', -77.15, 72.11),
      _SalesData('20-24', -82.63, 75.22),
      _SalesData('25-29', -80.75, 74.45),
      _SalesData('30-34', -79.21, 75.67),
      _SalesData('35-39', -73.50, 73.78),
      _SalesData('40-44', -67.65, 70.12),
      _SalesData('45-49', -65.33, 70.32),
      _SalesData('50-54', -60.44, 63.54),
      _SalesData('55-59', -54.67, 55.63),
      _SalesData('60-64', -42.87, 43.71),
      _SalesData('65-69', -34.98, 33.87),
      _SalesData('70-74', -21.12, 21.66),
      _SalesData('75+', -18.11, 21.22),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SfCartesianChart(
        title: const ChartTitle(text: 'Piramida Penduduk Kabupaten Cilacap'),
        legend: const Legend(isVisible: true, position: LegendPosition.bottom),
        enableSideBySideSeriesPlacement: false,
        primaryXAxis:
            const CategoryAxis(majorGridLines: MajorGridLines(width: 0)),
        primaryYAxis: NumericAxis(
          majorGridLines: const MajorGridLines(width: 0),
          axisLabelFormatter: (AxisLabelRenderDetails args) {
            if (args.value < 0) {
              return ChartAxisLabel(
                  args.value.abs().toString().replaceAll(RegExp(r'[-.]0'), ''),
                  args.textStyle);
            }
            return ChartAxisLabel(args.text, args.textStyle);
          },
        ),
        onDataLabelRender: (dataLabelArgs) {
          if (dataLabelArgs.text != null) {
            double? yValue = double.tryParse(dataLabelArgs.text!);

            if (yValue != null && yValue < 0) {
              dataLabelArgs.text =
                  yValue.abs().toString().replaceAll(RegExp(r'[-.]0'), '');
            }
          }
        },
        series: <CartesianSeries<_SalesData, String>>[
          BarSeries<_SalesData, String>(
            dataSource: data,
            xValueMapper: (_SalesData sales, _) => sales.x,
            yValueMapper: (_SalesData sales, _) => sales.y1,
            name: 'Laki-Laki',
            dataLabelSettings: const DataLabelSettings(
              isVisible: true,
              labelAlignment: ChartDataLabelAlignment.middle,
            ),
          ),
          BarSeries<_SalesData, String>(
            dataSource: data,
            xValueMapper: (_SalesData sales, _) => sales.x,
            yValueMapper: (_SalesData sales, _) => sales.y2,
            name: 'Prempuan',
            dataLabelSettings: const DataLabelSettings(
                isVisible: true,
                labelAlignment: ChartDataLabelAlignment.middle),
          ),
        ],
      ),
    );
  }
}

class _SalesData {
  _SalesData(this.x, this.y1, this.y2);

  final String x;
  final double? y1;
  final double? y2;
}