Text Overflow issue on Horizontal Bar Chart Y Axis

Hello Team, 

We've integrated Syncfusion Charts into our Flutter app. Here on horizontal Bar chart, on X Axis since the text is quite large facing overflow issue on Y Axis. Below attached screenshot and code for your reference.

played around with labelIntersectAction: AxisLabelIntersectAction.wrap, this attribute but it didn't worked. 

Screenshot 2024-07-08 at 5.47.35 PM.jpg


SfCartesianChart(
primaryXAxis: CategoryAxis(
majorGridLines: const MajorGridLines(width: 0),
maximumLabelWidth: 70,
),
primaryYAxis: NumericAxis(
majorGridLines: const MajorGridLines(width: 1),
numberFormat: intl.NumberFormat.compact(),
labelFormat: '{value}${widget.barChartData.labelYFormat ?? ''}',
title: AxisTitle(text: widget.barChartData.yAxisName),
),
series: _getDefaultBarSeries(),
trackballBehavior: TrackballBehavior(
enable: true,
builder: (data, details) {
final ThemeData themeData = Theme.of(context);

final TextStyle textStyle =
themeData.textTheme.bodyMedium!.copyWith(
color: Colors.white,
);

final TextStyle headerStyle = textStyle;
final barChartData =
widget.barChartData.barChartValues[details.pointIndex ?? 0];
final header = "Name: ${barChartData.x}";

final Size headerSize =
AppConstants.measureText(context, header, headerStyle);

final String text = 'Value: ${barChartData.y}%';

final Size textSize =
AppConstants.measureText(context, text, textStyle);

const EdgeInsets tooltipInnerPadding = EdgeInsets.all(6);

const EdgeInsets tooltipMarkerPadding = EdgeInsets.all(2.0);

const double tooltipMarkerSize = 10.0;

double headerAlignedSize = max(headerSize.width, textSize.width);

double dividerWidth = headerAlignedSize;

if (headerAlignedSize >= 300) {
headerAlignedSize = 300 - tooltipInnerPadding.horizontal;

dividerWidth = headerAlignedSize;
} else {
dividerWidth +=
tooltipMarkerSize + tooltipMarkerPadding.horizontal;
}

dividerWidth = min(dividerWidth, 300);

Widget tooltip = Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
width: headerAlignedSize,
child: Center(child: Text(header, style: headerStyle)),
),
const SizedBox(
height: 5,
),
Text(
text,
style: textStyle,
),
],
);

return Container(
decoration: BoxDecoration(
color: AppColors.blueishGreyColor,
borderRadius: BorderRadius.circular(5),
),
child: Padding(
padding: tooltipInnerPadding,
child: tooltip,
),
);
},
markerSettings: const TrackballMarkerSettings(
markerVisibility: TrackballVisibilityMode.visible,
height: 10,
width: 10,
borderWidth: 2,
),
activationMode: ActivationMode.singleTap,
tooltipSettings: const InteractiveTooltip(
canShowMarker: true,
color: AppColors.cardColor,
textStyle: TextStyle(
color: Colors.white,
),
connectorLineColor: AppColors.cardColor,
borderColor: AppColors.cardColor,
),
shouldAlwaysShow: false,
lineColor: Colors.grey,
),
)


List<BarSeries<HorizontalBarChartValue, String>> _getDefaultBarSeries() {
return <BarSeries<HorizontalBarChartValue, String>>[
BarSeries<HorizontalBarChartValue, String>(
dataSource: widget.barChartData.barChartValues,
xValueMapper: (HorizontalBarChartValue sales, _) => sales.x as String,
yValueMapper: (HorizontalBarChartValue sales, _) => sales.y,
color: widget.barChartData.barColor,
width: 0.35,
),
];
}


///Chart sample data
class HorizontalBarChartValue {
/// Holds the datapoint values like x, y, etc.,
HorizontalBarChartValue({
this.x,
this.y,
this.xValue,
this.yValue,
});

/// Holds x value of the datapoint
final dynamic x;

/// Holds y value of the datapoint
final num? y;

/// Holds x value of the datapoint
final dynamic xValue;

/// Holds y value of the datapoint
final num? yValue;
}



3 Replies

PS Preethika Selvam Syncfusion Team July 9, 2024 01:54 PM UTC

Hi AS TFOCO,


We have analyzed your query and found that you have used a maximumLabelWidth and labelIntersectAction properties in primaryXAxis of BarSeries. When using the maximumLabelWidth and labelIntersectAction, the maximumLabelWidth takes priority so the axis label within the maximumLabelWidth will visible others will trim, this is a default behavior. And regarding the labelIntersectAction property AxisLabelIntersectAction is only works when the adjacent label get collide with each other. We have shared a output with and without maximumLabelWidth along with AxisLabelIntersectAction.wrap and UG documentation for your reference.


Output Screenshot:



UG Links:

https://help.syncfusion.com/flutter/cartesian-charts/axis-customization#axis-label-width-customization
https://help.syncfusion.com/flutter/cartesian-charts/axis-customization#smart-axis-labels


If you still face the any issue, we kindly request you to try replicating the reported issue in the test sample attached below. Please revert to us so that we can assist you in a better way.


Regards,

Preethika Selvam.


Attachment: fr189219_1426056b.zip


AT AS TFOCO July 11, 2024 10:13 AM UTC

Hello Preethika,

Thank you for the valuable reply. Is there any way to apply max width and if there text overflow making the text overflow to next lines, by applying maxLines.

I tried the solution which you mentioned but the output takes almost half the whole screen width which looks little

weird.

Screenshot 2024-07-11 at 3.19.04 PM.png


Is there any possible way to make the graph looks some what like this. if there is text overflow.

Screenshot 2024-07-11 at 3.23.57 PM.jpg




LP Lokesh Palani Syncfusion Team July 12, 2024 01:39 PM UTC

Hi,


We have validated your query and the attached screenshot. You can achieve your requirement by using the axisLabelFormatter callback in the CategoryAxis. This allows you to display the axis label text on the next line when the text is too long. You can measure the width of the axis label text using the measureText function. In the axisLabelFormatter callback, you can get the text width with the measureText function and if the text exceeds the maximum width of the label, it will split and move to the next line based on the given size in the axisLabelWidth. We have shared a code snippet, screenshot, user guide documentation link, and sample for your reference below. Please let us know if you have any further needs.


UG Link for AxisLabelFormatter callback to customize the Axis label text in the Axis: https://help.syncfusion.com/flutter/cartesian-charts/callbacks#axislabelformatter


Code Snippet:


  double measureText(String text, TextStyle style) {

    final TextPainter textPainter = TextPainter(

      text: TextSpan(text: text, style: style),

      textDirection: TextDirection.ltr,

    )..layout(minWidth: 0, maxWidth: double.infinity);

    return textPainter.size.width;

  }

 

  double axisLabelWidth = 150;

 

     primaryXAxis: CategoryAxis(

              majorGridLines: const MajorGridLines(width: 0),

              axisLabelFormatter: (AxisLabelRenderDetails details) {

String text = details.text;

double maxWidth = axisLabelWidth;

final double textSize = measureText(text, details.textStyle);

 

if (textSize > maxWidth) {

final words = text.split(' ');

text = '';

String line = '';

 

for (final word in words) {

final newLine = line.isEmpty ? word : '$line $word';

final newSize = measureText(newLine, details.textStyle);

 

if (newSize > maxWidth) {

text += (text.isEmpty ? '' : '') + line;

line = word;

                    } else {

line = newLine;

                    }

                  }

text += (text.isEmpty ? '' : '') + line;

                }

 

return ChartAxisLabel(text, details.textStyle);

              },

            ),


Screenshot:



Regards,

Lokesh P.


Attachment: barchart_3535271a_64811021.zip

Loader.
Up arrow icon