如何使用charts_flutter包在Flutter中显示工具提示

6
我正在使用 https://pub.dev/packages/charts_flutter 在我的应用程序中创建图表。我想在对PointsLineChart上的点进行按压时显示提示信息。

有什么办法可以显示提示信息吗?

3个回答

10

我为此苦苦挣扎了一个小时,最终在一个GitHub问题中找到了解决方案。我稍微修改了一下代码,以将被点击的值显示为工具提示。

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart';
import 'package:charts_flutter/src/text_element.dart';
import 'package:charts_flutter/src/text_style.dart' as style;

class Chart extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LineChart(
      _createSampleData(),
      behaviors: [
        LinePointHighlighter(
          symbolRenderer: CustomCircleSymbolRenderer()  // add this line in behaviours
        )
      ],
      selectionModels: [
        SelectionModelConfig(
          changedListener: (SelectionModel model) {
            if(model.hasDatumSelection){
              final value = model.selectedSeries[0].measureFn(model.selectedDatum[0].index);
              CustomCircleSymbolRenderer.value = value;  // paints the tapped value 
             }
          }
        )
      ],
    );
  }

  List<Series<LinearSales, int>> _createSampleData() {
    final data = [
      new LinearSales(0, 5),
      new LinearSales(1, 25),
      new LinearSales(2, 100),
      new LinearSales(3, 75),
    ];
    return [
      new Series<LinearSales, int>(
        id: 'Sales',
        colorFn: (_, __) => MaterialPalette.blue.shadeDefault,
        domainFn: (LinearSales sales, _) => sales.year,
        measureFn: (LinearSales sales, _) => sales.sales,
        data: data,
      )
    ];
  }
}

class CustomCircleSymbolRenderer extends CircleSymbolRenderer {
static String value;
  @override
  void paint(ChartCanvas canvas, Rectangle<num> bounds, {List<int> dashPattern, Color fillColor, Color strokeColor, double strokeWidthPx}) {
    super.paint(canvas, bounds, dashPattern: dashPattern, fillColor: fillColor, strokeColor: strokeColor, strokeWidthPx: strokeWidthPx);
    canvas.drawRect(
      Rectangle(bounds.left - 5, bounds.top - 30, bounds.width + 10, bounds.height + 10),
      fill: Color.white
    );
    var textStyle = style.TextStyle();
    textStyle.color = Color.black;
    textStyle.fontSize = 15;
    canvas.drawText(
      TextElement("$value", style: textStyle),
        (bounds.left).round(),
        (bounds.top - 28).round()
    );
  }
}
class LinearSales {
  final int year;
  final int sales;
  LinearSales(this.year, this.sales);
}

6

使用空值安全和更新版本的绘画重写方法,更新了@mahesh-jamdade解决方案的版本。

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart';
import 'package:charts_flutter/src/text_element.dart' as charts_text;
import 'package:charts_flutter/src/text_style.dart' as style;

class Chart extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LineChart(
      _createSampleData(),
      behaviors: [
        LinePointHighlighter(
          symbolRenderer: CustomCircleSymbolRenderer()  // add this line in behaviours
        )
      ],
      selectionModels: [
        SelectionModelConfig(
          changedListener: (SelectionModel model) {
            if(model.hasDatumSelection){
              final value = model.selectedSeries[0].measureFn(model.selectedDatum[0].index);
              CustomCircleSymbolRenderer.value = value.toString();  // paints the tapped value 
             }
          }
        )
      ],
    );
  }

  List<Series<LinearSales, int>> _createSampleData() {
    final data = [
      new LinearSales(0, 5),
      new LinearSales(1, 25),
      new LinearSales(2, 100),
      new LinearSales(3, 75),
    ];
    return [
      new Series<LinearSales, int>(
        id: 'Sales',
        colorFn: (_, __) => MaterialPalette.blue.shadeDefault,
        domainFn: (LinearSales sales, _) => sales.year,
        measureFn: (LinearSales sales, _) => sales.sales,
        data: data,
      )
    ];
  }
}

class CustomCircleSymbolRenderer extends CircleSymbolRenderer {
static String value;
  @override
  void paint(ChartCanvas canvas, Rectangle<num> bounds, {List<int>? dashPattern,
      Color? fillColor,
      FillPatternType? fillPattern,
      Color? strokeColor,
      double? strokeWidthPx}) {
    super.paint(canvas, bounds,
        dashPattern: dashPattern,
        fillColor: fillColor,
        fillPattern: fillPattern,
        strokeColor: strokeColor,
        strokeWidthPx: strokeWidthPx);
    canvas.drawRect(
      Rectangle(bounds.left - 5, bounds.top - 30, bounds.width + 10, bounds.height + 10),
      fill: Color.white
    );
    var textStyle = style.TextStyle();
    textStyle.color = Color.black;
    textStyle.fontSize = 15;
    canvas.drawText(
      charts_text.TextElement("$value", style: textStyle),
        (bounds.left).round(),
        (bounds.top - 28).round()
    );
  }
}
class LinearSales {
  final int year;
  final int sales;
  LinearSales(this.year, this.sales);
}


嘿 @Eagle。听起来很有趣。在我的情况下出现了一个错误。你知道它是什么意思吗?... - David L
1
'CustomCircleSymbolRenderer.paint' ('void Function(ChartCanvas, Rectangle<num>, {List<int>? dashPattern, Color? fillColor, FillPatternType? fillPattern, Color? strokeColor, double? strokeWidthPx}) (where Color is defined in xxx/painting.dart)') isn't a valid override of 'CircleSymbolRenderer.paint' ('void Function(ChartCanvas, Rectangle<num>, {List<int>? dashPattern, Color? fillColor, FillPatternType? fillPattern, Color? strokeColor, double? strokeWidthPx}) (where Color is defined in xxx/charts_common-0.12.0/lib/src/common/color.dart)'). - David L
嗯...我解决了。因为我使用了import 'package:charts_flutter/flutter.dart' as charts;,所以我在颜色变量的定义中包含了charts.Color?... - David L

3

使用上述代码时出现了一些错误,修改后的正确版本代码如下:

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart';
// import 'package:charts_flutter/src/chart_canvas.dart' as eos;
import 'package:charts_flutter/src/text_element.dart' as TextElement;
import 'package:charts_flutter/src/text_style.dart' as style;

class Chart extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LineChart(
      _createSampleData(),
      behaviors: [
        LinePointHighlighter(
          symbolRenderer: CustomCircleSymbolRenderer()
        )
      ],
      selectionModels: [
        SelectionModelConfig(
          changedListener: (SelectionModel model) {
            if(model.hasDatumSelection)
              print(model.selectedSeries[0].measureFn(model.selectedDatum[0].index));
          }
        )
      ],
    );
  }

  List<Series<LinearSales, int>> _createSampleData() {
    final data = [
      new LinearSales(0, 5),
      new LinearSales(1, 25),
      new LinearSales(2, 100),
      new LinearSales(3, 75),
    ];
    return [
      new Series<LinearSales, int>(
        id: 'Sales',
        colorFn: (_, __) => MaterialPalette.blue.shadeDefault,
        domainFn: (LinearSales sales, _) => sales.year,
        measureFn: (LinearSales sales, _) => sales.sales,
        data: data,
      )
    ];
  }
}

class CustomCircleSymbolRenderer extends CircleSymbolRenderer {

  @override
  void paint(ChartCanvas canvas, Rectangle<num> bounds, {List<int> dashPattern, Color fillColor, FillPatternType fillPattern, Color strokeColor, double strokeWidthPx}) {
    super.paint(canvas, bounds, dashPattern: dashPattern, fillColor: fillColor,fillPattern: fillPattern, strokeColor: strokeColor, strokeWidthPx: strokeWidthPx);
    canvas.drawRect(
      Rectangle(bounds.left - 5, bounds.top - 30, bounds.width + 10, bounds.height + 10),
      fill: Color.white
    );
    var textStyle = style.TextStyle();
    textStyle.color = Color.black;
    textStyle.fontSize = 15;
    canvas.drawText(

      TextElement.TextElement("1", style: textStyle),
        (bounds.left).round(),
        (bounds.top - 28).round()
    );
  }
}
class LinearSales {
  final int year;
  final int sales;
  LinearSales(this.year, this.sales);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接