Format & localize date labels in charts_flutter time series chart

2,432

The solution from Shruti Gupta is not complete. You have to use a custom dateTimeFactory to really localized date.

So create your own DateTimeFactory

import 'package:charts_common/common.dart' as common show DateTimeFactory;

/// A class to localize the date
class LocalizedTimeFactory implements common.DateTimeFactory {
  final Locale locale;

  const LocalizedTimeFactory(this.locale);

  DateTime createDateTimeFromMilliSecondsSinceEpoch(
      int millisecondsSinceEpoch) {
    return DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
  }

  DateTime createDateTime(int year,
      [int month = 1,
        int day = 1,
        int hour = 0,
        int minute = 0,
        int second = 0,
        int millisecond = 0,
        int microsecond = 0]) {
    return DateTime(
        year, month, day, hour, minute, second, millisecond, microsecond);
  }

  /// Returns a [DateFormat].
  DateFormat createDateFormat(String pattern) {
    return DateFormat(pattern, locale.languageCode);
  }
}

Then you need to add a tickFormatterSpec so your custom dateTimeFactory is taken into account and fill dateTimeFactory field:

charts.TimeSeriesChart(data.seriesPressure(context),
     defaultRenderer: charts.LineRendererConfig(includeArea: true, strokeWidthPx: 1),
     animate: false,
     domainAxis: new charts.DateTimeAxisSpec(
        tickFormatterSpec: charts.AutoDateTimeTickFormatterSpec(
            hour: new charts.TimeFormatterSpec(format: "Hm", transitionFormat: "Hm"),
        ),
     ),
     dateTimeFactory: LocalizedTimeFactory(Localizations.localeOf(context)),
     primaryMeasureAxis: charts.NumericAxisSpec(
         tickProviderSpec: charts.BasicNumericTickProviderSpec(zeroBound: false))
     ),

Your remaining task is to better configure tickFormatterSpec. Play with day, hour and minute fields, also with format and transition format until you reach what you want. I was not able unfortunately to duplicate the display when there is not tickFormatterSpec...

Share:
2,432
Angel Todorov
Author by

Angel Todorov

Updated on December 09, 2022

Comments

  • Angel Todorov
    Angel Todorov over 1 year

    I have following time series in charts_flutter:

    charts.Series<DatumPoint, DateTime>(
            id: 'Series',
            colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
            domainFn: (DatumPoint point, _) => point.date,
            measureFn: (DatumPoint point, _) => point.value,
            data: p,
          )
    

    and this is how my TimeSeriesChart has been created:

    @override
      Widget build(BuildContext context) {
        return charts.TimeSeriesChart(
          widget.seriesList,
          animate: widget.animate,
          selectionModels: [
            charts.SelectionModelConfig(
              type: charts.SelectionModelType.info,
              changedListener: _onSelectionChanged,
            )
          ],
          domainAxis: charts.EndPointsTimeAxisSpec(),
          behaviors: [
            charts.LinePointHighlighter(
                showHorizontalFollowLine:
                    charts.LinePointHighlighterFollowLineType.none,
                showVerticalFollowLine:
                    charts.LinePointHighlighterFollowLineType.nearest,
                dashPattern: [1, 1]),
            charts.SelectNearest(
              eventTrigger: charts.SelectionTrigger.tapAndDrag,
            ),
          ],
        );
      }
    }
    

    I would like to format start & end ticker on domain Axis using localize DateTime format e.g. DateFormat.yMMMd(Localizations.localeOf(context).languageCode).format(date)

    How can I achieve this?