Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Setting domain axis viewport has no effect in TimeSeriesChart #287

Open
vpavliuk opened this issue Jul 2, 2019 · 4 comments
Open

Setting domain axis viewport has no effect in TimeSeriesChart #287

vpavliuk opened this issue Jul 2, 2019 · 4 comments

Comments

@vpavliuk
Copy link

vpavliuk commented Jul 2, 2019

Chart embraces the whole data range despite the time axis viewport being configured to display only one day. In the below snippet the line that sets the viewport for domain axis has no effect.

charts_flutter package version: 0.6.0

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

class TimeSeriesBarChart extends StatelessWidget
{
  factory TimeSeriesBarChart.withSampleData()
  {
    return TimeSeriesBarChart(ChartDataPoint.samplePoints(10));
  }

  TimeSeriesBarChart(this.data);

  final List<ChartDataPoint> data;

  @override
  Widget build(BuildContext context)
  {
    final timeSeries = charts.Series<ChartDataPoint, DateTime>(
      id: 'TimeSeries',
      colorFn: (_, __) => charts.Color.black,
      domainFn: (ChartDataPoint datum, _) => datum.time,
      measureFn: (ChartDataPoint datum, _) => datum.value,
      data: data,
    );

    final now = DateTime.now();

    return charts.TimeSeriesChart(
      [timeSeries],
      defaultRenderer: charts.BarRendererConfig(),
      domainAxis: charts.DateTimeAxisSpec(
        viewport: charts.DateTimeExtents(start: now, end: now.add(Duration(days: 1))),
      ),
    );
  }
}

class ChartDataPoint
{
  static List<ChartDataPoint> samplePoints(int count)
  {
    List<ChartDataPoint> points = [];
    final random = Random();
    final now = DateTime.now();
    for (int i = 0; i < count; i++)
    {
      points.add(
        ChartDataPoint(
          value: random.nextInt(100),
          time: now.add(Duration(days: i)),
        )
      );
    }

    return points;
  }

  const ChartDataPoint({this.value, this.time});

  final int value;
  final DateTime time;
}
@matthewlloyd
Copy link

This is because of the autoViewport setting in the Axis class (charts_common/lib/src/chart/cartesian/axis/axis.dart). You have to set axis.autoViewport = false in the DateTimeAxisSpec.configure method. This also allows the PanAndZoomBehavior to operate correctly.

@symons63
Copy link

symons63 commented Aug 16, 2019

This is because of the autoViewport setting in the Axis class (charts_common/lib/src/chart/cartesian/axis/axis.dart). You have to set axis.autoViewport = false in the DateTimeAxisSpec.configure method. This also allows the PanAndZoomBehavior to operate correctly.

You're right. So, to fix that, the workaround is to create a class which extends DateTimeAxisSpec of charts_flutter and override the configure method like that :

class DateTimeAxisSpecWorkaround extends DateTimeAxisSpec {

  const DateTimeAxisSpecWorkaround ({
    RenderSpec<DateTime> renderSpec,
    DateTimeTickProviderSpec tickProviderSpec,
    DateTimeTickFormatterSpec tickFormatterSpec,
    bool showAxisLine,
  }) : super(
            renderSpec: renderSpec,
            tickProviderSpec: tickProviderSpec,
            tickFormatterSpec: tickFormatterSpec,
            showAxisLine: showAxisLine);

  @override
  configure(Axis<DateTime> axis, ChartContext context,
      GraphicsFactory graphicsFactory) {
    super.configure(axis, context, graphicsFactory);
    axis.autoViewport = false;
  }
}

Thank you so much. You saved my day !

@bobosette
Copy link

This is because of the autoViewport setting in the Axis class (charts_common/lib/src/chart/cartesian/axis/axis.dart). You have to set axis.autoViewport = false in the DateTimeAxisSpec.configure method. This also allows the PanAndZoomBehavior to operate correctly.

Thank u very much. I struggled tow weeks on this issue. U saved my life

@JasonEdinburgh
Copy link

For any others that find this thread. I had to also pass a viewport as follows. HTH

class DateTimeAxisSpecWorkaround extends charts.DateTimeAxisSpec {
  const DateTimeAxisSpecWorkaround(
      {charts.RenderSpec<DateTime> renderSpec,
      charts.DateTimeTickProviderSpec tickProviderSpec,
      charts.DateTimeTickFormatterSpec tickFormatterSpec,
      bool showAxisLine,
      viewport})
      : super(
            renderSpec: renderSpec,
            tickProviderSpec: tickProviderSpec,
            tickFormatterSpec: tickFormatterSpec,
            showAxisLine: showAxisLine,
            viewport: viewport);

  @override
  configure(charts.Axis<DateTime> axis, charts.ChartContext context, charts.GraphicsFactory graphicsFactory) {
    super.configure(axis, context, graphicsFactory);
    axis.autoViewport = false;
  }
}

I then use it like this
return new charts.TimeSeriesChart(seriesList,
                            animate: true,
                            defaultRenderer: new charts.BarRendererConfig<DateTime>(cornerStrategy: charts.ConstCornerStrategy(2)),
                            // It is recommended that default interactions be turned off if using bar
                            // renderer, because the line point highlighter is the default for time
                            // series chart.
                            defaultInteractions: false,
                            // If default interactions were removed, optionally add select nearest
                            // and the domain highlighter that are typical for bar charts.

                            behaviors: [new charts.SelectNearest(), new charts.DomainHighlighter()],
                            primaryMeasureAxis: charts.AxisSpec(),
                            domainAxis: DateTimeAxisSpecWorkaround(
                              viewport: charts.DateTimeExtents(start: DateTime.now().subtract(Duration(minutes: 10)), end: DateTime.now()),
                            ));

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants