I used the sample code from the github and only changed 1 variable: the handleBuiltInTouches to true, I expect it to have the tooltip pop up when I hold it, but it popped up for a splitsecond before disappearing.
also when I set handleBuiltInTouches to true, even when showingtooltipIndicators has selected all spots, none of the spots have the tooltip popup.
class ScatterChartSample2 extends StatefulWidget {
const ScatterChartSample2({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _ScatterChartSample2State();
}
class _ScatterChartSample2State extends State {
int touchedIndex = -1;
Color greyColor = Colors.grey;
List<int> selectedSpots = [];
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1,
child: Card(
color: const Color(0xff222222),
child: fl.ScatterChart(
fl.ScatterChartData(
scatterSpots: [
fl.ScatterSpot(
4,
4,
color: selectedSpots.contains(0) ? Colors.green : greyColor,
),
fl.ScatterSpot(
2,
5,
color: selectedSpots.contains(1) ? Colors.yellow : greyColor,
radius: 12,
),
fl.ScatterSpot(
4,
5,
color:
selectedSpots.contains(2) ? Colors.purpleAccent : greyColor,
radius: 8,
),
fl.ScatterSpot(
8,
6,
color: selectedSpots.contains(3) ? Colors.orange : greyColor,
radius: 20,
),
fl.ScatterSpot(
5,
7,
color: selectedSpots.contains(4) ? Colors.brown : greyColor,
radius: 14,
),
fl.ScatterSpot(
7,
2,
color: selectedSpots.contains(5)
? Colors.lightGreenAccent
: greyColor,
radius: 18,
),
fl.ScatterSpot(
3,
2,
color: selectedSpots.contains(6) ? Colors.red : greyColor,
radius: 36,
),
fl.ScatterSpot(
2,
8,
color:
selectedSpots.contains(7) ? Colors.tealAccent : greyColor,
radius: 22,
),
],
minX: 0,
maxX: 10,
minY: 0,
maxY: 10,
borderData: fl.FlBorderData(
show: false,
),
gridData: fl.FlGridData(
show: true,
drawHorizontalLine: true,
checkToShowHorizontalLine: (value) => true,
getDrawingHorizontalLine: (value) =>
fl.FlLine(color: Colors.white.withOpacity(0.1)),
drawVerticalLine: true,
checkToShowVerticalLine: (value) => true,
getDrawingVerticalLine: (value) =>
fl.FlLine(color: Colors.white.withOpacity(0.1)),
),
titlesData: fl.FlTitlesData(
show: false,
),
showingTooltipIndicators: selectedSpots,
scatterTouchData: fl.ScatterTouchData(
enabled: true,
handleBuiltInTouches: true,
touchTooltipData: fl.ScatterTouchTooltipData(
tooltipBgColor: Colors.black,
getTooltipItems: (fl.ScatterSpot touchedBarSpot) {
return fl.ScatterTooltipItem(
'X: ',
textStyle: TextStyle(
height: 1.2,
color: Colors.grey[100],
fontStyle: FontStyle.italic,
),
bottomMargin: 10,
children: [
TextSpan(
text: '${touchedBarSpot.x.toInt()} \n',
style: const TextStyle(
color: Colors.white,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.bold,
),
),
TextSpan(
text: 'Y: ',
style: TextStyle(
height: 1.2,
color: Colors.grey[100],
fontStyle: FontStyle.italic,
),
),
TextSpan(
text: touchedBarSpot.y.toInt().toString(),
style: const TextStyle(
color: Colors.white,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.bold,
),
),
],
);
},
),
touchCallback: (fl.FlTouchEvent event,
fl.ScatterTouchResponse? touchResponse) {
if (touchResponse == null ||
touchResponse.touchedSpot == null) {
return;
}
if (event is fl.FlTapUpEvent) {
final sectionIndex = touchResponse.touchedSpot!.spotIndex;
setState(() {
if (selectedSpots.contains(sectionIndex)) {
selectedSpots.remove(sectionIndex);
} else {
selectedSpots.add(sectionIndex);
}
});
}
},
),
),
),
),
);
}
}
The fl
will give the return fl.FlTapDownEvent
and fl.FlLongPressEnd
if you give long press.
Set fl
condition like this:
// Show tooltip if tap down detected
if (event is fl.FlTapDownEvent) {
final sectionIndex = touchResponse.touchedSpot!.spotIndex;
setState(() {
selectedSpots.add(sectionIndex);
});
// Hide/clear tooltip if long press was ended or tap up detected
}else if(event is fl.FlLongPressEnd || event is fl.FlTapUpEvent){
setState(() {
selectedSpots.clear();
});
}
Don't forget to choose and set one between 1-3 condition
I found that you can show the tooltip if inside scatterTouchData
:
enable:false
and handleBuiltInTouches: false
enable:false
and handleBuiltInTouches: true
enable:true
and handleBuiltInTouches: false
but not for enable:true
and handleBuiltInTouches: true
Who knows why this happened? I'll updated if I found the answer or you can comment to complete the answer.
Full code
class ScatterChartSample2 extends StatefulWidget {
const ScatterChartSample2({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _ScatterChartSample2State();
}
class _ScatterChartSample2State extends State {
int touchedIndex = -1;
Color greyColor = Colors.grey;
List<int> selectedSpots = [];
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1,
child: Card(
color: const Color(0xff222222),
child: fl.ScatterChart(
fl.ScatterChartData(
scatterSpots: [
fl.ScatterSpot(
4,
4,
color: selectedSpots.contains(0) ? Colors.green : greyColor,
),
fl.ScatterSpot(
2,
5,
color: selectedSpots.contains(1) ? Colors.yellow : greyColor,
radius: 12,
),
fl.ScatterSpot(
4,
5,
color:
selectedSpots.contains(2) ? Colors.purpleAccent : greyColor,
radius: 8,
),
fl.ScatterSpot(
8,
6,
color: selectedSpots.contains(3) ? Colors.orange : greyColor,
radius: 20,
),
fl.ScatterSpot(
5,
7,
color: selectedSpots.contains(4) ? Colors.brown : greyColor,
radius: 14,
),
fl.ScatterSpot(
7,
2,
color: selectedSpots.contains(5)
? Colors.lightGreenAccent
: greyColor,
radius: 18,
),
fl.ScatterSpot(
3,
2,
color: selectedSpots.contains(6) ? Colors.red : greyColor,
radius: 36,
),
fl.ScatterSpot(
2,
8,
color:
selectedSpots.contains(7) ? Colors.tealAccent : greyColor,
radius: 22,
),
],
minX: 0,
maxX: 10,
minY: 0,
maxY: 10,
borderData: fl.FlBorderData(
show: false,
),
gridData: fl.FlGridData(
show: true,
drawHorizontalLine: true,
checkToShowHorizontalLine: (value) => true,
getDrawingHorizontalLine: (value) =>
fl.FlLine(color: Colors.white.withOpacity(0.1)),
drawVerticalLine: true,
checkToShowVerticalLine: (value) => true,
getDrawingVerticalLine: (value) =>
fl.FlLine(color: Colors.white.withOpacity(0.1)),
),
titlesData: fl.FlTitlesData(
show: false,
),
showingTooltipIndicators: selectedSpots,
scatterTouchData: fl.ScatterTouchData(
// ====================== Set this false =================================
enabled: false,
handleBuiltInTouches: true,
touchTooltipData: fl.ScatterTouchTooltipData(
tooltipBgColor: Colors.black,
getTooltipItems: (fl.ScatterSpot touchedBarSpot) {
return fl.ScatterTooltipItem(
'X: ',
textStyle: TextStyle(
height: 1.2,
color: Colors.grey[100],
fontStyle: FontStyle.italic,
),
bottomMargin: 10,
children: [
TextSpan(
text: '${touchedBarSpot.x.toInt()} \n',
style: const TextStyle(
color: Colors.white,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.bold,
),
),
TextSpan(
text: 'Y: ',
style: TextStyle(
height: 1.2,
color: Colors.grey[100],
fontStyle: FontStyle.italic,
),
),
TextSpan(
text: touchedBarSpot.y.toInt().toString(),
style: const TextStyle(
color: Colors.white,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.bold,
),
),
],
);
},
),
touchCallback: (fl.FlTouchEvent event,
fl.ScatterTouchResponse? touchResponse) {
if (touchResponse == null ||
touchResponse.touchedSpot == null) {
return;
}
// Show tooltip if tap down detected
if (event is fl.FlTapDownEvent) {
final sectionIndex = touchResponse.touchedSpot!.spotIndex;
setState(() {
selectedSpots.add(sectionIndex);
});
// Hide/clear tooltip if long press was ended or tap up detected
}else if(event is fl.FlLongPressEnd || event is fl.FlTapUpEvent){
setState(() {
selectedSpots.clear();
});
}
},
),
),
),
),
);
}
}