5

我一直在使用 Flutter 图表的在线图库(https://google.github.io/charts/flutter/gallery.html),但我正在努力为 x 和 y 轴值添加标题。

有人可以帮助我或告诉我如何将标签添加到图表中吗?

4

3 回答 3

9

它可能使用behaviors属性,检查代码

 var chart = charts.LineChart(seriesList,
        behaviors: [
          new charts.ChartTitle('Dimension',
              behaviorPosition: charts.BehaviorPosition.bottom,
              titleStyleSpec: chartsCommon.TextStyleSpec(fontSize: 11),
              titleOutsideJustification:
              charts.OutsideJustification.middleDrawArea),
          new charts.ChartTitle('Dose, mg',
              behaviorPosition: charts.BehaviorPosition.start,
              titleStyleSpec: chartsCommon.TextStyleSpec(fontSize: 11),
              titleOutsideJustification:
              charts.OutsideJustification.middleDrawArea)
        ],
        defaultRenderer: new charts.LineRendererConfig(includePoints: true));

来源https://google.github.io/charts/flutter/example/behaviors/chart_title

于 2018-12-10T14:00:53.940 回答
0

您可以通过使用行注释迭代列表数据并创建一个新的 LineAnnotationSegment 数组的行为来做到这一点,但您应该注意,当下一个时间点非常接近时,某些标题可能会重叠。

final data = [
      LinearPrices(DateTime(2020, 9, 19), 5),
      LinearPrices(DateTime(2020, 9, 26), 15),
      LinearPrices(DateTime(2020, 10, 3), 20),
      LinearPrices(DateTime(2020, 10, 10), 17),
    ];
  @override
  Widget build(BuildContext context) {
    return  charts.TimeSeriesChart(seriesList, animate: false, behaviors: [
           charts.RangeAnnotation( data.map((e) => charts.LineAnnotationSegment(
            e.timestamp, charts.RangeAnnotationAxisType.domain,
            middleLabel: '\$${e.price}')).toList()),
    ]);
  }

不过,您可以在用户单击该行时使用回调进行绘制,方法是在底部绘制自定义文本或使用如下行为作为自定义标签:

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

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

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    final data = [
      LinearPrices(DateTime(2020, 9, 19), 5),
      LinearPrices(DateTime(2020, 9, 26), 15),
      LinearPrices(DateTime(2020, 10, 3), 20),
      LinearPrices(DateTime(2020, 10, 10), 17),
    ];
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(
        title: Text('Chart'),
      ),
      body: ChartPricesItem(data),
    ));
  }
}

class ChartPricesItem extends StatefulWidget {
  final List<LinearPrices> data;
  ChartPricesItem(this.data);

  static List<charts.Series<LinearPrices, DateTime>> _createSeries(
      List<LinearPrices> data) {
    return [
      charts.Series<LinearPrices, DateTime>(
        id: 'Prices',
        colorFn: (_, __) => charts.MaterialPalette.deepOrange.shadeDefault,
        domainFn: (LinearPrices sales, _) => sales.timestamp,
        measureFn: (LinearPrices sales, _) => sales.price,
        data: data,
      )
    ];
  }

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

class _ChartPricesItemState extends State<ChartPricesItem> {
  DateTime _time;
  double _price;
  // Listens to the underlying selection changes, and updates the information relevant
  void _onSelectionChanged(charts.SelectionModel model) {
    final selectedDatum = model.selectedDatum;

    DateTime time;
    double price;

    // We get the model that updated with a list of [SeriesDatum] which is
    // simply a pair of series & datum.
    if (selectedDatum.isNotEmpty) {
      time = selectedDatum.first.datum.timestamp;
      price = selectedDatum.first.datum.price;
    }

    // Request a build.
    setState(() {
      _time = time;
      _price = price;
    });
  }

  @override
  Widget build(BuildContext context) {
    final simpleCurrencyFormatter =
        charts.BasicNumericTickFormatterSpec.fromNumberFormat(
            NumberFormat.compactSimpleCurrency());
    var behaviors;
    // Check if the user click over the line.
    if (_time != null && _price != null) {
      behaviors = [
        charts.RangeAnnotation([
          charts.LineAnnotationSegment(
            _time,
            charts.RangeAnnotationAxisType.domain,
            labelDirection: charts.AnnotationLabelDirection.horizontal,
            labelPosition: charts.AnnotationLabelPosition.margin,
            labelStyleSpec:
                charts.TextStyleSpec(fontWeight: FontWeight.bold.toString()),
            middleLabel: '\$$_price',
          ),
        ]),
      ];
    }

    var chart = charts.TimeSeriesChart(
      ChartPricesItem._createSeries(widget.data),
      animate: false,
      // Include timeline points in line
      defaultRenderer: charts.LineRendererConfig(includePoints: true),
      selectionModels: [
        charts.SelectionModelConfig(
          type: charts.SelectionModelType.info,
          changedListener: _onSelectionChanged,
        )
      ],
      // This is the part where you paint label when you click over the line.
      behaviors: behaviors,
      // Sets up a currency formatter for the measure axis.
      primaryMeasureAxis: charts.NumericAxisSpec(
          tickFormatterSpec: simpleCurrencyFormatter,
          tickProviderSpec:
              charts.BasicNumericTickProviderSpec(zeroBound: false)),

      /// Customizes the date tick formatter. It will print the day of month
      /// as the default format, but include the month and year if it
      /// transitions to a new month.
      ///
      /// minute, hour, day, month, and year are all provided by default and
      /// you can override them following this pattern.
      domainAxis: charts.DateTimeAxisSpec(
          tickFormatterSpec: charts.AutoDateTimeTickFormatterSpec(
              day: charts.TimeFormatterSpec(
                  format: 'd', transitionFormat: 'dd/MM/yyyy'),
              minute: charts.TimeFormatterSpec(
                  format: 'mm', transitionFormat: 'dd/MM/yyyy HH:mm'))),
    );
    var chartWidget = Padding(
      padding: EdgeInsets.all(16),
      child: SizedBox(
        height: 200.0,
        child: chart,
      ),
    );
    final children = <Widget>[chartWidget];
    // If there is a selection, then include the details.
    if (_time != null) {
      children.add(Padding(
          padding: EdgeInsets.only(top: 4.0),
          child: Text(DateFormat('dd/MM/yyyy hh:mm').format(_time),
              style: Theme.of(context).textTheme.bodyText1)));
    }
    return SingleChildScrollView(
      child: Column(
        children: <Widget>[
          const SizedBox(height: 8),
          Text("Product Prices", style: Theme.of(context).textTheme.headline5),
          Column(children: children),
        ],
      ),
    );
  }
}

/// Sample linear data type.
class LinearPrices {
  final DateTime timestamp;
  final double price;

  LinearPrices(this.timestamp, this.price);
}

这是结果:

图表

于 2021-03-25T17:00:38.213 回答
0

使用“行为”列表设置图表标题

Widget build(BuildContext context) { return new charts.LineChart( seriesList, animate: animate,

  behaviors: [
    new charts.ChartTitle('Top title text',
        subTitle: 'Top sub-title text',
        behaviorPosition: charts.BehaviorPosition.top,
        titleOutsideJustification: charts.OutsideJustification.start,
       
        innerPadding: 18),
    new charts.ChartTitle('Bottom title text',
        behaviorPosition: charts.BehaviorPosition.bottom,
        titleOutsideJustification:
            charts.OutsideJustification.middleDrawArea),
    new charts.ChartTitle('Start title',
        behaviorPosition: charts.BehaviorPosition.start,
        titleOutsideJustification:
            charts.OutsideJustification.middleDrawArea),
    new charts.ChartTitle('End title',
        behaviorPosition: charts.BehaviorPosition.end,
        titleOutsideJustification:
            charts.OutsideJustification.middleDrawArea),
  ],
);

}

于 2021-05-08T11:23:57.357 回答