0

I am a new developer in flutter. I am developing a bar graph using syncfusion_flutter_charts in flutter. This is what I want to achieve in flutter. Expected Graph. And this is what I achieved after hours of struggle. Achieved Graph

You notice that in label the text is in superscripts format. I tried to achieve this but all effort in vain and moreover there is some padding before start of bar and y-labels are on the axis line. I did a lot research but I couldn't able to replicate these things. This is a university project and any help would be appreciated. This is my code.

  List<_ChartData> data= [];
int daysInMonth(DateTime date){
    var firstDayThisMonth = DateTime(date.year, date.month, date.day);
    var firstDayNextMonth = DateTime(firstDayThisMonth.year, firstDayThisMonth.month + 1, firstDayThisMonth.day);
    return firstDayNextMonth.difference(firstDayThisMonth).inDays;
  }
  List<String> months = <String>[ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  String ordinal(int number) {
    if(!(number >= 1 && number <= 100)) {
      throw Exception('Invalid number');
    }

    if(number >= 11 && number <= 13) {
      return 'th';
    }

    switch(number % 10) {
      case 1: return 'st';
      case 2: return 'nd';
      case 3: return 'rd';
      default: return 'th';
    }
  }
    for(int i=1;i<=daysInMonth(DateTime.now());i++){
      data.add(_ChartData('$i${ordinal(i)} ${months[DateTime.now().month-1]}', (Random().nextInt(11)+1).toDouble()));
    }

SizedBox(
  height: 25.h,
  child: SfCartesianChart(
      plotAreaBorderWidth: 0,

      primaryXAxis: CategoryAxis(
          isVisible: true,
          majorGridLines: const MajorGridLines(width: 0),
          interval: (daysInMonth(DateTime.now())+ ((daysInMonth(DateTime.now())-1) - 28))/2,
          labelAlignment: LabelAlignment.center,
        labelStyle: TextStyle(
            color: lightAxisGreyColor,
            fontSize: 10.sp,
        ),
          edgeLabelPlacement: EdgeLabelPlacement.shift,

          labelPlacement: LabelPlacement.onTicks,
        ),
      primaryYAxis: NumericAxis(
          minimum: 0, maximum: 12, interval: 12,
         labelPosition: ChartDataLabelPosition.outside,
          labelAlignment: LabelAlignment.end,
          rangePadding: ChartRangePadding.additional,
          labelStyle: TextStyle(
            color: blackBlueText,
            fontSize: 10.sp
          ),




          axisLine: const AxisLine(width: 0)),
      tooltipBehavior: TooltipBehavior(
        enable: true,
      ),
      series: <ChartSeries<_ChartData, String>>[
        ColumnSeries<_ChartData, String>(

            dataSource: data,
            xValueMapper: (_ChartData data, _) => data.x,
            yValueMapper: (_ChartData data, _) => data.y,
            name: 'Open Tasks',
            width: 1,
            spacing: 0.05,
            borderRadius: BorderRadius.only(topLeft: Radius.circular(0.25.w),topRight: Radius.circular(0.25.w)),
            color: colorPurple)
      ]),
)
Adriaan
  • 17,741
  • 7
  • 42
  • 75
  • Be aware that the SyncFusion products in the Dart/Flutter pub are *not* open source. They are released under a commercial license that may subject you or your organization to a financial liability, and might affect downstream re-users of your code. – Randal Schwartz Feb 24 '23 at 20:04

1 Answers1

0

I don't know if it's the way you want it, but at least I used Unicode.

And I made it by referring to your code.

this is result.

result.

I added the following part.

var re = RegExp(r'(%u(?<hexData>[0-9A-Fa-f]{4}))|.');

var th_sup = '%u1d57%u02b0';
var st_sup = '%u02e2%u1d57';
var nd_sup = '%u207f%u1d48';
var rd_sup = '%u02b3%u1d48';

convertedUnicodeStr(String sup) {
  var matches = re.allMatches(sup);
  var hexDatas = <int>[];
  for (var match in matches) {
    var hexData = match.namedGroup('hexData');
    if (hexData != null) {
    hexDatas.add(int.parse(hexData, radix: 16));
  } else {
    hexDatas += match.group(0)!.runes.toList();
  }
 }
 var decodedStr = String.fromCharCodes(hexDatas);
 return decodedStr;

}

and changed switch statement

switch (number % 10) {
  case 1:
    return convertedUnicodeStr(st_sup); // previous one : return 'st';
  case 2:
    return convertedUnicodeStr(nd_sup); // previous one : return 'nd';
  case 3:
    return convertedUnicodeStr(rd_sup); // previous one : return 'rd';
  default:
    return convertedUnicodeStr(th_sup); // previous one : return 'th';
}

All Codes

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

class _ChartData {
  final String x;
  final double y;

  _ChartData(this.x, this.y);
}

class ChartExample extends StatefulWidget {
  const ChartExample({Key? key}) : super(key: key);

  @override
  State<ChartExample> createState() => _ChartExampleState();
}

class _ChartExampleState extends State<ChartExample> {
  var re = RegExp(r'(%u(?<hexData>[0-9A-Fa-f]{4}))|.');
  var th_sup = '%u1d57%u02b0';
  var st_sup = '%u02e2%u1d57';
  var nd_sup = '%u207f%u1d48';
  var rd_sup = '%u02b3%u1d48';

  List<_ChartData> data = [];

  List<String> months = <String>[
    'Jan',
    'Feb',
    'Mar',
    'Apr',
    'May',
    'Jun',
    'Jul',
    'Aug',
    'Sep',
    'Oct',
    'Nov',
    'Dec'
  ];

  int daysInMonth(DateTime date) {
    var firstDayThisMonth = DateTime(date.year, date.month, date.day);
    var firstDayNextMonth = DateTime(firstDayThisMonth.year,
        firstDayThisMonth.month + 1, firstDayThisMonth.day);
    return firstDayNextMonth.difference(firstDayThisMonth).inDays;
  }

  String ordinal(int number) {
    if (!(number >= 1 && number <= 100)) {
      throw Exception('Invalid number');
    }

    if (number >= 11 && number <= 13) {
      return 'th';
    }

    switch (number % 10) {
      case 1:
        return convertedUnicodeStr(st_sup);
      case 2:
        return convertedUnicodeStr(nd_sup);
      case 3:
        return convertedUnicodeStr(rd_sup);
      default:
        // return 'th';
        return convertedUnicodeStr(th_sup);
    }
  }

  init() {
    for (int i = 1; i <= daysInMonth(DateTime.now()); i++) {
      data.add(_ChartData('$i${ordinal(i)} ${months[DateTime.now().month - 1]}',
          (Random().nextInt(11) + 1).toDouble()));
    }
  }

  convertedUnicodeStr(String sup) {
    var matches = re.allMatches(sup);
    var hexDatas = <int>[];
    for (var match in matches) {
      var hexData = match.namedGroup('hexData');
      if (hexData != null) {
        hexDatas.add(int.parse(hexData, radix: 16));
      } else {
        hexDatas += match.group(0)!.runes.toList();
      }
    }
    var decodedStr = String.fromCharCodes(hexDatas);
    return decodedStr;
  }

  @override
  void initState() {
    init();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SizedBox(
          height: 195,
          child: SfCartesianChart(
              plotAreaBorderWidth: 0,
              primaryXAxis: CategoryAxis(
                isVisible: true,
                majorGridLines: const MajorGridLines(width: 0),
                interval: (daysInMonth(DateTime.now()) +
                        ((daysInMonth(DateTime.now()) - 1) - 28)) /
                    2,
                labelAlignment: LabelAlignment.center,
                labelStyle: TextStyle(
                  color: Colors.green,
                  fontSize: 10,
                ),
                edgeLabelPlacement: EdgeLabelPlacement.shift,
                labelPlacement: LabelPlacement.onTicks,
              ),
              primaryYAxis: NumericAxis(
                  minimum: 0,
                  maximum: 12,
                  interval: 12,
                  labelPosition: ChartDataLabelPosition.outside,
                  labelAlignment: LabelAlignment.end,
                  rangePadding: ChartRangePadding.additional,
                  labelStyle: TextStyle(color: Colors.black, fontSize: 10),
                  axisLine: const AxisLine(width: 0)),
              tooltipBehavior: TooltipBehavior(
                enable: true,
              ),
              series: <ChartSeries<_ChartData, String>>[
                ColumnSeries<_ChartData, String>(
                    dataSource: data,
                    xValueMapper: (_ChartData data, _) => data.x,
                    yValueMapper: (_ChartData data, _) => data.y,
                    name: 'Open Tasks',
                    width: 1,
                    spacing: 0.05,
                    borderRadius: BorderRadius.only(
                        topLeft: Radius.circular(0.25),
                        topRight: Radius.circular(0.25)),
                    color: Colors.purple)
              ]),
        ),
      ),
    );
  }
}

Lastly, I think you'd better refer to this.

I don't know if this is the answer you want. But I hope it helps.

develover
  • 203
  • 2
  • 5