after realtime data update i want to show trackball by using trackballBehavior.show it is not working it returns null in crosshair.dart file at 240

import 'dart:async';
import 'dart:math';

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

class Chart extends StatefulWidget {
const Chart({Key? key}) : super(key: key);

@override
_chartState createState() => _chartState();
}

class _chartState extends State<Chart> {
int? x = 10;
int? y = 15;
Timer? timer;
int index = 0;
@override
void dispose() {
timer!.cancel();
super.dispose();
}

TooltipBehavior? _tooltipBehavior;
List<Widget> stackList = [];

ChartSeriesController? _controller;
late TrackballBehavior _trackballBehavior;
late CrosshairBehavior _crosshairBehavior;
@override
void initState() {
super.initState();
_trackballBehavior = trackballBehavior();
// _tooltipBehavior = tooltipBehavior();
_crosshairBehavior = crosshairBehavior();
timer = Timer.periodic(const Duration(seconds: 3), (_timer) {
updateData().then((value) {
print(index);
pri
_trackballBehavior.show(
chartCustomData[index].x,
chartCustomData[index].y!.toDouble(),
);

_crosshairBehavior.show(
chartCustomData[index].x,
chartCustomData[index].y!.toDouble(),
);
});
// if (_crosshairBehavior != null) {
// _crosshairBehavior.showByIndex(index);
// }
});
}

CrosshairBehavior crosshairBehavior() {
return CrosshairBehavior(
activationMode: ActivationMode.singleTap,
enable: true,
shouldAlwaysShow: true,
lineType: CrosshairLineType.horizontal,
);
}

TooltipBehavior tooltipBehavior() {
return TooltipBehavior(
canShowMarker: true,
animationDuration: 0,
activationMode: ActivationMode.singleTap,
shouldAlwaysShow: true,
elevation: 6,
duration: 1,
format: 'tool tip header',
tooltipPosition: TooltipPosition.auto,
color: Colors.indigoAccent,
enable: true,
builder: (data, point, series, pointIndex, seriesIndex) {
print(
'---- tool tip ${data}, ${point}, ${series}, ${pointIndex}, ${seriesIndex}');
return Card(
child: Text('Data${chartCustomData[pointIndex].y}'),
);
},
);
}

TrackballBehavior trackballBehavior() {
return TrackballBehavior(
enable: true,
lineColor: Colors.cyan,
// shouldAlwaysShow: true,
activationMode: ActivationMode.singleTap,
lineType: TrackballLineType.horizontal,
hideDelay: 10,
shouldAlwaysShow: true,
tooltipDisplayMode: TrackballDisplayMode.groupAllPoints,
// lineDashArray: const [1.7],
// tooltipDisplayMode: TrackballDisplayMode.floatAllPoints,
// tooltipAlignment: ChartAlignment.near,
// lineWidth: 2,
// tooltipSettings: const InteractiveTooltip(
// enable: true,
// color: Colors.cyan,
// ),
// builder: (context, trackballDetails) {
// // print(trackballDetails.point!.currentPoint);
// latLong.add(
// Position(
// x: trackballDetails.point!.x.toDouble(),
// y: trackballDetails.point!.y.toDouble(),
// ),
// );
// return Card(
// color: Colors.white,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(
// 16,
// ),
// ),
// child: Padding(
// padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4),
// child: Text(
// 'x ${trackballDetails.point!.x.toDouble()}\n y ${trackballDetails.point!.y.toDouble()}',
// ),
// ),
// );
// },
);
}

List<Position> latLong = [];

void onController(ChartSeriesController controller) {
_controller = controller;
}

@override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
return WillPopScope(
onWillPop: () async {
timer!.cancel();
return true;
},
child: Scaffold(
body: SafeArea(
child: SizedBox(
height: height,
width: width,
child: SingleChildScrollView(
child: Column(
children: [
// Image.network(
// 'https://scraapynew.mrmmbs.com/public/en/uploaded_images/' +
// temp
// .replaceAll('\[', '')
// .replaceAll('\]', '')
// .replaceAll('\"', '')
// .replaceAll('\\', '')
// .split(',')
// .first,
// height: 30,
// width: 30,
// ),
SizedBox(
height: height / 2,
width: width,
child: Row(
children: [
Expanded(
child: SfCartesianChart(
title: ChartTitle(text: 'My Trade'),
trackballBehavior: _trackballBehavior,
// onMarkerRender: (markerArgs) {},
primaryXAxis: NumericAxis(
tickPosition: TickPosition.outside,
isVisible: true,
autoScrollingMode: AutoScrollingMode.start,
interactiveTooltip: const InteractiveTooltip(
enable: true,
canShowMarker: true,
),
),

crosshairBehavior: _crosshairBehavior,

// onTooltipRender: (TooltipArgs args) {
// args.text = 'Customized Text';
//
// print(
// '----- ${args.locationX} ${args.locationY}');
// },
series: <LineSeries<ChartSampleData, num>>[
LineSeries<ChartSampleData, num>(
animationDelay: 0,
isVisible: true,
/* markerSettings: const MarkerSettings(
isVisible: true,
shape: DataMarkerType.circle,
color: Colors.amber,
height: 5,
width: 5,
borderColor: Colors.orangeAccent,
),*/
animationDuration: 0,
enableTooltip: true, opacity: 1,
onRendererCreated: onController,
dataSource: chartCustomData,
xValueMapper: (ChartSampleData data, _) =>
data.x,
yValueMapper: (ChartSampleData data, _) =>
data.y,
// dataLabelSettings: DataLabelSettings(
// connectorLineSettings: ConnectorLineSettings(
// type: ConnectorType.curve,
// color: Colors.cyan,
// ),
// ),
),
],
),
),
SizedBox(
width: width / 5,
height: height / 2,
child: Stack(
children: [
...stackList,
],
),
)
],
),
),

ElevatedButton(
onPressed: () {
// updateData();
_trackballBehavior.show(
chartCustomData[index - 1].x,
chartCustomData[index - 1].y!.toDouble(),
);
_crosshairBehavior.show(
chartCustomData[index - 1].x,
chartCustomData[index - 1].y!.toDouble(),
);
// print('index $index');
var p = _controller!.pointToPixel(CartesianChartPoint(
chartCustomData[index - 1].x,
chartCustomData[index - 1].y));
print(p);
setState(() {
// _trackballBehavior!.showByIndex(index);

stackList.add(
Transform.translate(
offset: Offset(p.dx, p.dy),
child: SizedBox(
width: 200,
child: Row(
children: [
Column(
children: const [
CircleAvatar(
backgroundColor: Colors.cyan,
radius: 5,
),
Text('x'),
],
),
Divider(),
Column(
children: const [
CircleAvatar(
backgroundColor: Colors.cyan,
radius: 5,
),
Text('y'),
],
),
],
),
),
),
);
});
print(" ----- list ${stackList.length}");
},
child: const Text('put'),
),
],
),
)),
),
),
);
}

Future<List<ChartSampleData>> updateData() async {
if (mounted) {
setState(() {
y = Random().nextInt(150);
x = x! + 20;

chartCustomData.add(
ChartSampleData(
x: x,
y: y,
),
);
});
}

if (chartCustomData.length > 20) {
chartCustomData.removeAt(0);
_controller?.updateDataSource(
addedDataIndex: chartCustomData.length - 1,
removedDataIndex: 0,
);
} else {
_controller?.updateDataSource(
addedDataIndex: chartCustomData.length - 1,
);
}
index = chartCustomData.length - 1;

return chartCustomData;
}

List<ChartSampleData> chartCustomData = <ChartSampleData>[
ChartSampleData(x: 10, y: 15),
ChartSampleData(x: 20, y: 30),
ChartSampleData(x: 30, y: 45),
ChartSampleData(x: 40, y: 77),
];

final List<SalesData> chartData = <SalesData>[
SalesData(DateTime(2005, 0, 1), 'India', 1.5, 21, 28, 680, 760),
SalesData(DateTime(2006, 0, 1), 'China', 2.2, 24, 44, 550, 880),
SalesData(DateTime(2007, 0, 1), 'USA', 3.32, 36, 48, 440, 788),
SalesData(DateTime(2008, 0, 1), 'Japan', 4.56, 38, 50, 350, 560),
SalesData(DateTime(2009, 0, 1), 'Russia', 5.87, 54, 66, 444, 566),
SalesData(DateTime(2010, 0, 1), 'France', 6.8, 57, 78, 780, 650),
SalesData(DateTime(2011, 0, 1), 'Germany', 8.5, 70, 84, 450, 800)
];
List<LineSeries<SalesData, num>> getDefaultData() {
return <LineSeries<SalesData, num>>[
LineSeries<SalesData, num>(
// enableToolTip: isTooltipVisible,
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.a1,
yValueMapper: (SalesData sales, _) => sales.a2,
width: 2,

// enableAnimation: false,
markerSettings: const MarkerSettings(
isVisible: true,
height: 4,
width: 4,
shape: DataMarkerType.circle,
borderWidth: 3,
borderColor: Colors.cyan,
),
dataLabelSettings: const DataLabelSettings(
isVisible: true,
labelAlignment: ChartDataLabelAlignment.auto,
),
),
LineSeries<SalesData, num>(
enableTooltip: true,
dataSource: chartData,
// enableAnimation: false,
width: 2,
xValueMapper: (SalesData sales, _) => sales.a3,
yValueMapper: (SalesData sales, _) => sales.a4,
markerSettings: const MarkerSettings(
isVisible: true,
height: 4,
width: 4,
shape: DataMarkerType.circle,
borderWidth: 3,
borderColor: Colors.black),
dataLabelSettings: const DataLabelSettings(
isVisible: true,
labelAlignment: ChartDataLabelAlignment.auto,
),
),
];
}
}

class SalesData {
DateTime? date;
String? text;
double? a;
int? a1, a2, a3, a4;

SalesData(
this.date,
this.text,
this.a,
this.a1,
this.a2,
this.a3,
this.a4,
);
}

class ChartSampleData {
int? x, y;
ChartSampleData({this.x, this.y});
}

class Position {
double? x, y;
Position({required this.x, required this.y});
}

2 Replies

YG Yuvaraj Gajaraj Syncfusion Team October 18, 2021 12:58 PM UTC

Hi md zeeshan Iqbal, 
  
We are analyzing the reported scenario, and we will update the status in two business days (20 Oct 2021). We appreciate your patience until then. 
  
Thanks, 
Yuvaraj


YG Yuvaraj Gajaraj Syncfusion Team October 20, 2021 02:33 PM UTC

Hi Zeeshan, 
 
Greeting from Syncfusion. We have analyzed your query, and we have tried to reproduce the reported issue that trackball show method is not working. We would like to let you know that in the updateData method, you have update the data source using our public method updateDataSource. But before this you have called the setState, which is unnecessary. In the setState, you have added the data to chartCustomData variable. We have removed this setState now, the trackball and crosshair is showing now properly. We have modified the sample and attached below for your reference. 
 
  
Regards, 
Yuvaraj. 


Loader.
Up arrow icon