Настройка ширины или положения всплывающей подсказки в графике синхронизации Flutter

Мы интегрировали диаграммы Syncfusion в наше приложение Flutter. Когда пользователи нажимают на точки на графике, отображаются всплывающие подсказки. Однако текст в этих всплывающих подсказках часто бывает слишком длинным, из-за чего он обрезается или его становится трудно читать.

Есть ли способ настроить ширину всплывающей подсказки или отрегулировать ее положение, чтобы эффективно решить эту проблему?

Настройка ширины или положения всплывающей подсказки в графике синхронизации FlutterНастройка ширины или положения всплывающей подсказки в графике синхронизации Flutter
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я проанализировал ваш запрос и могу воспроизвести проблему, когда для всплывающей подсказки предоставляется более длинный текст с использованием свойства формата в TooltipBehavior. Это связано с тем, что всплывающая подсказка не отображалась в области графика. Чтобы решить эту проблему, я предлагаю вам использовать свойство builder в TooltipBehavior. Используя это, вы можете отображать содержимое всплывающей подсказки в области графика. Я поделился ссылкой на документацию руководства пользователя для вашего удобства.

Ссылка UG: https://help.syncfusion.com/flutter/cartesian-charts/tooltip#tooltip-template

Более того, я столкнулся с аналогичной проблемой при предоставлении более длинного значения x. Чтобы решить эту проблему и обеспечить пользовательский интерфейс всплывающей подсказки по умолчанию, я разработал виджет всплывающей подсказки компоновщика, который напоминает всплывающую подсказку по умолчанию. Я создал собственный визуализатор для серии, чтобы ограничить ширину всплывающей подсказки и получить цвет маркера всплывающей подсказки. Ниже я поделился фрагментом кода и снимком экрана для вашей справки.

import 'dart:math';

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

void main() {
  runApp(const WorkaroundSample());
}

class WorkaroundSample extends StatefulWidget {
  const WorkaroundSample({super.key});

  @override
  State<WorkaroundSample> createState() => _WorkaroundSampleState();
}

class _WorkaroundSampleState extends State<WorkaroundSample> {
  late List<ChartData> _chartData;
  late Size _seriesSize;
  late Color _seriesColor;

  Size measureText(String textValue, TextStyle textStyle, [int? angle]) {
    final TextPainter textPainter = TextPainter(
      textAlign: TextAlign.center,
      textDirection: TextDirection.ltr,
      text: TextSpan(text: textValue, style: textStyle),
    );
    textPainter.layout();
    return Size(textPainter.width, textPainter.height);
  }

  @override
  void initState() {
    _chartData = <ChartData>[
      ChartData(
          'themeData.textTheme.bodySmall!.copyWiththemeData.textTheme.bodySmall!.copyWith',
          10),
      ChartData(
          'themeData.textTheme.boySmall!.copyWiththemeData.textTheme.bodySmall!.copyWith',
          22),
      ChartData(
          'themeData.textTheme.bodySmall!.copyWiththemeData.textTheme.bodySmall!.copWith',
          13),
      ChartData(
          'themeData.txtTheme.bodySmall!.copyWiththemeData.textTheme.bodySmall!.copyith',
          34),
      ChartData(
          'themeData.textTheme.bodySmall!.copyWiththemeDa.textTheme.bodySmall!.copyWith',
          12),
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SfCartesianChart(
          primaryXAxis: const CategoryAxis(
            labelIntersectAction: AxisLabelIntersectAction.trim,
          ),
          tooltipBehavior: TooltipBehavior(
            enable: true,
            builder: (dynamic data, ChartPoint point, ChartSeries series,
                int pointIndex, int seriesIndex) {
              final ThemeData themeData = Theme.of(context);
              final TextStyle textStyle =
                  themeData.textTheme.bodySmall!.copyWith(
                color: themeData.colorScheme.onInverseSurface,
              );
              final TextStyle headerStyle =
                  textStyle.copyWith(fontWeight: FontWeight.bold);
              const String header =
                  "Robeco Sustainable Global Equities focus Fundamental (Global Stars)";
              final Size headerSize = measureText(header, headerStyle);
              final String text = '${point.x} : ${point.y}';
              final Size textSize = measureText(text, textStyle);
              const EdgeInsets tooltipInnerPadding = EdgeInsets.all(6);
              const EdgeInsets tooltipMarkerPadding = EdgeInsets.all(2.0);
              const double tooltipMarkerSize = 10.0;
              const EdgeInsetsDirectional tooltipItemSpacing =
                  EdgeInsetsDirectional.only(end: 3.0);

              double headerAlignedSize = max(headerSize.width, textSize.width);
              double dividerWidth = headerAlignedSize;
              if (headerAlignedSize >= _seriesSize.width) {
                headerAlignedSize =
                    _seriesSize.width - tooltipInnerPadding.horizontal;
                dividerWidth = headerAlignedSize;
              } else {
                dividerWidth +=
                    tooltipMarkerSize + tooltipMarkerPadding.horizontal;
              }

              dividerWidth = min(dividerWidth, _seriesSize.width);
              final double xTextSize = dividerWidth -
                  tooltipMarkerSize -
                  tooltipItemSpacing.horizontal -
                  tooltipMarkerPadding.horizontal -
                  tooltipInnerPadding.horizontal -
                  measureText(' : ${point.y}', textStyle).width;

              final bool hasHeader = header.isNotEmpty;
              Widget tooltip = Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  if (hasHeader)
                    SizedBox(
                      width: headerAlignedSize,
                      child: Center(child: Text(header, style: headerStyle)),
                    ),
                  if (hasHeader)
                    SizedBox(
                      width: dividerWidth,
                      child: Divider(
                        height: 10.0,
                        thickness: 0.5,
                        color: themeData.colorScheme.onInverseSurface,
                      ),
                    ),
                  if (text.isNotEmpty)
                    Row(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        Padding(
                          padding: tooltipItemSpacing,
                          child: Container(
                            padding: tooltipMarkerPadding,
                            width: tooltipMarkerSize,
                            height: tooltipMarkerSize,
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: _seriesColor,
                              border: Border.all(
                                color: Colors.white,
                                width: 1.0,
                              ),
                            ),
                          ),
                        ),
                        SizedBox(
                          width: xTextSize,
                          child: RichText(
                            overflow: TextOverflow.ellipsis,
                            text:
                                TextSpan(text: '${point.x}', style: textStyle),
                          ),
                        ),
                        Text(' : ${point.y}', style: textStyle),
                      ],
                    ),
                ],
              );

              return Padding(
                padding: tooltipInnerPadding,
                child: tooltip,
              );
            },
          ),
          series: [
            BubbleSeries<ChartData, String>(
              xValueMapper: (ChartData data, int index) => data.x,
              yValueMapper: (ChartData data, int index) => data.y,
              dataSource: _chartData,
              onCreateRenderer: (series) {
                return _BubbleSeriesRenderer(this);
              },
            ),
          ],
        ),
      ),
    );
  }
}

class _BubbleSeriesRenderer extends BubbleSeriesRenderer<ChartData, String> {
  _BubbleSeriesRenderer(this._state);

  final _WorkaroundSampleState _state;

  @override
  void customizeSegment(ChartSegment segment) {
    super.customizeSegment(segment);
    _state._seriesColor = segment.fillPaint.color;
  }

  @override
  void performLayout() {
    super.performLayout();
    _state._seriesSize = size;
  }
}

class ChartData {
  ChartData(
    this.x,
    this.y,
  );

  final String x;
  final num y;
}

Скриншот вывода:

Другие вопросы по теме