Open quynhnb2021 opened 1 month ago
@VijayakumarMariappan Hello, Did you check this bug?
Hi @quynhnb2021,
We have validated the issue and would like to inform you that the reported problem 'Charts get resetting to old or previous position' occurs because of calling setState in the onAxisLabelTapped and onTrackballPositionChanging callbacks, causes the chart to rebuild every time, resetting when the trackball is moved or the chart is panned. We recommend you to avoid using setState inside the chart callbacks while doing interactions.
We have achieved your requirement by implementing a CustomTrackballBehavior, where we override the onPaint method of the TrackballBehavior. This onPaint method allows us to draw custom axis labels with specific styling, such as custom colors and font sizes. By using the _CustomTrackballBehavior class, you can control the appearance and positioning of the axis labels and tooltips as per your needs. Please refer to the following code snippet.
Code snippet:
class _CustomTrackballBehavior extends TrackballBehavior {
@override
bool get enable => true;
@override
ActivationMode get activationMode => ActivationMode.singleTap;
@override
void onPaint(PaintingContext context, Offset offset,
SfChartThemeData chartThemeData, ThemeData themeData) {
super.onPaint(context, offset, chartThemeData, themeData);
if (chartPointInfo.isEmpty || parentBox == null) {
return;
}
final Rect plotAreaBounds = parentBox!.paintBounds;
final Offset position =
Offset(chartPointInfo[0].xPosition!, chartPointInfo[0].yPosition!);
_drawCustomAxisLabel(context.canvas, position, plotAreaBounds);
}
void _drawCustomAxisLabel(
Canvas canvas, Offset position, Rect plotAreaBounds) {
const TextStyle textStyle =
TextStyle(color: Colors.red, fontSize: 13, fontWeight: FontWeight.bold);
final Paint rectPaint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
final Offset tooltipPos = Offset(position.dx, plotAreaBounds.bottom);
final String label = chartPointInfo[0].header ?? '0';
final Size labelSize = measureText(label, textStyle);
final Rect rect = _calculateRect(labelSize, tooltipPos);
final Offset alignedPos = tooltipPos.translate(-rect.width / 2, 5);
final RRect tooltipRRect = RRect.fromRectAndRadius(
Rect.fromLTWH(alignedPos.dx, alignedPos.dy, rect.width, rect.height),
const Radius.circular(5),
);
canvas.drawRRect(tooltipRRect, rectPaint);
_drawText(canvas, label, _textPosition(tooltipRRect, labelSize), textStyle);
}
Rect _calculateRect(Size labelSize, Offset tooltipPos) {
const double padding = 5;
return Rect.fromLTWH(
tooltipPos.dx,
tooltipPos.dy,
labelSize.width + padding,
labelSize.height + padding,
);
}
Offset _textPosition(RRect tooltipRRect, Size labelSize) {
return Offset(
(tooltipRRect.left + tooltipRRect.width / 2) - labelSize.width / 2,
(tooltipRRect.top + tooltipRRect.height / 2) - labelSize.height / 2);
}
void _drawText(Canvas canvas, String text, Offset point, TextStyle style) {
final TextPainter textPainter = TextPainter(
text: TextSpan(text: text, style: style),
textAlign: TextAlign.center,
textDirection: TextDirection.ltr,
);
textPainter
..layout()
..paint(canvas, point);
}
}
Demo:
https://github.com/user-attachments/assets/171b31fd-ae14-4537-8e7e-f16431a0eac5
For more details, refer the following Knowledge Base link: KB : https://support.syncfusion.com/kb/article/16112/how-to-customize-the-trackball-in-flutter-cartesianchart
Regards, Baranibharathi P.
Hi @Baranibharathip ,
Thanks, it works! By the way, could you help me check how to use CustomTrackballBehavior to showByIndex in your example? I want to bold in red and display the tooltip and trackball on the first element of the chart without needing to tap on it.
Hi @quynhnb2021,
We have validated your query and would like to inform you that a custom trackball behavior, similar to the default trackball behavior, can be used. To achieve the requirement of displaying the trackball tooltip on the first element of the chart without the need to tap on it, you can use the showByIndex method of the TrackballBehavior to display the trackball at a specific data point. Please refer to the following code snippet.
Code snippet:
late TrackballBehavior trackballBehavior;
void initState() {
// Initialize the custom trackball behavior
trackballBehavior = _CustomTrackballBehavior();
// Show the trackball at the first data point (index 0) once the chart is built
WidgetsBinding.instance.addPostFrameCallback((_) {
trackballBehavior.showByIndex(0);
});
super.initState();
}
Demo:
https://github.com/user-attachments/assets/eb7a5a90-7c51-4c81-bf3f-f62770c08c60
For more details, refer to the following User Guide link: UG: https://help.syncfusion.com/flutter/cartesian-charts/trackball-crosshair#trackball
Also, we have attached sample for your reference.
Sample: GH_2124.zip
Regards, Baranibharathi P.
Bug description
When using SfCartesianChart in Flutter with horizontal scrolling enabled via ZoomPanBehavior and autoScrollingDelta, the chart experiences issues when trying to retrieve the index of the data points using the onTrackballPositionChanging callback. Specifically:
When panning to the rightmost data points, the chart glitches by snapping back to the initial position, preventing further horizontal scrolling. Trackball and tooltip do not appear even though TrackballBehavior is enabled. Additionally, I am trying to change the color of axis labels (to red) when the trackball is over a specific data point or when scrolling. However, the index from the onTrackballPositionChanging callback does not update properly, preventing the color change from happening.
Steps to reproduce
1: Create a SfCartesianChart with the following configuration: Enable horizontal panning with ZoomPanBehavior(enablePanning: true). Set auto-scrolling properties with autoScrollingDelta: 5 and autoScrollingMode: AutoScrollingMode.start. Add a TrackballBehavior with activationMode: ActivationMode.singleTap and enable: true. Implement the onTrackballPositionChanging callback to capture the index of the data point:
onTrackballPositionChanging: (trackballArgs) { setState(() { indexOfPoint = trackballArgs.chartPointInfo.dataPointIndex ?? 0; }); },
Use axisLabelFormatter to change the axis label color when the index matches the data point:axisLabelFormatter: (AxisLabelRenderDetails details) { return ChartAxisLabel( details.text, TextStyle( color: indexOfPoint == details.value ? Colors.red : Colors.black, ), ); },
2: Scroll horizontally to the rightmost data points.
3: Observe the following issues: The chart snaps back to the initial position, preventing continuous scrolling to the right. The trackball and tooltip are not displayed when tapping on the chart, even though the TrackballBehavior is enabled. The axis label color does not update based on the indexOfPoint due to improper index handling. This issue seems to be a conflict between ZoomPanBehavior and TrackballBehavior when horizontal scrolling is enabled with autoScrollingMode.
Code sample
Code sample
```dart [import 'dart:math'; import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override StateScreenshots or Video
Screenshots / Video demonstration
[Upload media here]https://github.com/user-attachments/assets/299f8bce-0c69-4f2a-85e1-a171b152a1de
Stack Traces
Stack Traces
```dart [Add the Stack Traces here] [demochart.zip](https://github.com/user-attachments/files/17345537/demochart.zip) ```On which target platforms have you observed this bug?
Android, iOS
Flutter Doctor output
Doctor output
```console [Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.24.3, on macOS 14.5 23F79 darwin-x64, locale en-VN) [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [✓] Xcode - develop for iOS and macOS (Xcode 15.0) [✓] Chrome - develop for the web [✓] Android Studio (version 2023.1) [✓] IntelliJ IDEA Ultimate Edition (version 2023.3.4) [✓] VS Code (version 1.93.1) [✓] Connected device (4 available) [✓] Network resources • No issues found!] ```