Мы интегрировали диаграммы Syncfusion в наше приложение Flutter. Когда пользователи нажимают на точки на графике, отображаются всплывающие подсказки. Однако текст в этих всплывающих подсказках часто бывает слишком длинным, из-за чего он обрезается или его становится трудно читать.
Есть ли способ настроить ширину всплывающей подсказки или отрегулировать ее положение, чтобы эффективно решить эту проблему?
Я проанализировал ваш запрос и могу воспроизвести проблему, когда для всплывающей подсказки предоставляется более длинный текст с использованием свойства формата в 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;
}
Скриншот вывода: