Skip to content

Commit

Permalink
Handled click in scatter_chart.
Browse files Browse the repository at this point in the history
  • Loading branch information
imaNNeo committed Mar 19, 2021
1 parent c7a2ae3 commit 4dde875
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 27 deletions.
14 changes: 5 additions & 9 deletions example/lib/scatter_chart/samples/scatter_chart_sample2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ class _ScatterChartSample2State extends State {

List<int> selectedSpots = [];

int lastPanStartOnIndex = -1;

@override
Widget build(BuildContext context) {
return AspectRatio(
Expand Down Expand Up @@ -99,16 +97,14 @@ class _ScatterChartSample2State extends State {
tooltipBgColor: Colors.black,
),
touchCallback: (ScatterTouchResponse touchResponse) {
if (touchResponse.touchInput is PointerDownEvent) {
lastPanStartOnIndex = touchResponse.touchedSpotIndex;
} else if (touchResponse.touchInput is PointerUpEvent) {
final PointerUpEvent PointerUpEven = touchResponse.touchInput;
if (touchResponse.clickHappened && touchResponse.touchedSpot != null) {
final sectionIndex = touchResponse.touchedSpot.spotIndex;
// Tap happened
setState(() {
if (selectedSpots.contains(lastPanStartOnIndex)) {
selectedSpots.remove(lastPanStartOnIndex);
if (selectedSpots.contains(sectionIndex)) {
selectedSpots.remove(sectionIndex);
} else {
selectedSpots.add(lastPanStartOnIndex);
selectedSpots.add(sectionIndex);
}
});
}
Expand Down
7 changes: 4 additions & 3 deletions lib/src/chart/scatter_chart/scatter_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ class _ScatterChartState extends AnimatedWidgetBaseState<ScatterChart> {
void _handleBuiltInTouch(ScatterTouchResponse touchResponse) {
widget.data.scatterTouchData.touchCallback?.call(touchResponse);

if (touchResponse.touchInput is PointerDownEvent ||
final desiredTouch = touchResponse.touchInput is PointerDownEvent ||
touchResponse.touchInput is PointerMoveEvent ||
touchResponse.touchInput is PointerHoverEvent) {
touchResponse.touchInput is PointerHoverEvent;
if (desiredTouch && touchResponse.touchedSpot != null) {
setState(() {
touchedSpots = [touchResponse.touchedSpotIndex];
touchedSpots = [touchResponse.touchedSpot!.spotIndex];
});
} else {
setState(() {
Expand Down
49 changes: 42 additions & 7 deletions lib/src/chart/scatter_chart/scatter_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -290,23 +290,58 @@ typedef ScatterTouchCallback = void Function(ScatterTouchResponse);
/// You can override [ScatterTouchData.touchCallback] to handle touch events,
/// it gives you a [ScatterTouchResponse] and you can do whatever you want.
class ScatterTouchResponse extends BaseTouchResponse {
final ScatterSpot? touchedSpot;
final int touchedSpotIndex;
final ScatterTouchedSpot? touchedSpot;

/// If touch happens, [ScatterChart] processes it internally and
/// passes out a [ScatterTouchResponse], it gives you information about the touched spot.
///
/// [touchedSpot], and [touchedSpotIndex] tells you
/// [touchedSpot] tells you
/// in which spot (of [ScatterChartData.scatterSpots]) touch happened.
///
/// [touchInput] is the type of happened touch.
///
/// [clickHappened] will be true, if we detect a click event.
ScatterTouchResponse(
PointerEvent touchInput,
ScatterSpot? touchedSpot,
int touchedSpotIndex,
ScatterTouchedSpot? touchedSpot,
bool clickHappened,
) : touchedSpot = touchedSpot,
touchedSpotIndex = touchedSpotIndex,
super(touchInput);
super(touchInput, clickHappened);

/// Copies current [ScatterTouchResponse] to a new [ScatterTouchResponse],
/// and replaces provided values.
ScatterTouchResponse copyWith({
PointerEvent? touchInput,
ScatterTouchedSpot? touchedSpot,
bool? clickHappened,
}) {
return ScatterTouchResponse(
touchInput ?? this.touchInput,
touchedSpot ?? this.touchedSpot,
clickHappened ?? this.clickHappened,
);
}
}

/// Holds the touched spot data
class ScatterTouchedSpot with EquatableMixin {

/// Touch happened on this spot
final ScatterSpot spot;

/// Touch happened on this spot index
final int spotIndex;

/// [spot], and [spotIndex] tells you
/// in which spot (of [ScatterChartData.scatterSpots]) touch happened.
ScatterTouchedSpot(this.spot, this.spotIndex);

/// Used for equality check, see [EquatableMixin].
@override
List<Object?> get props => [
spot,
spotIndex,
];
}

/// Holds representation data for showing tooltip popup on top of spots.
Expand Down
15 changes: 8 additions & 7 deletions lib/src/chart/scatter_chart/scatter_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -417,12 +417,14 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData> {
return sum;
}

/// Makes a [ScatterTouchResponse] based on the provided [FlTouchInput]
/// Makes a [ScatterTouchedSpot] based on the provided [touchInput]
///
/// Processes [FlTouchInput.getOffset] and checks
/// Processes [touchInput.localPosition] and checks
/// the elements of the chart that are near the offset,
/// then makes a [ScatterTouchResponse] from the elements that has been touched.
ScatterTouchResponse handleTouch(
/// then makes a [ScatterTouchedSpot] from the elements that has been touched.
///
/// Returns null if finds nothing!
ScatterTouchedSpot? handleTouch(
PointerEvent touchInput,
Size size,
PaintHolder<ScatterChartData> holder,
Expand All @@ -440,10 +442,9 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData> {
(spot.radius / 2) + data.scatterTouchData.touchSpotThreshold &&
(touchInput.localPosition.dy - spotPixelY).abs() <=
(spot.radius / 2) + data.scatterTouchData.touchSpotThreshold) {
return ScatterTouchResponse(touchInput, spot, i);
return ScatterTouchedSpot(spot, i);
}
}

return ScatterTouchResponse(touchInput, null, -1);
return null;
}
}
25 changes: 24 additions & 1 deletion lib/src/chart/scatter_chart/scatter_chart_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class RenderScatterChart extends RenderBox {
return PaintHolder(data, targetData, textScale);
}

ScatterTouchedSpot? _lastTouchedSpot;

@override
void performLayout() {
size = computeDryLayout(constraints);
Expand All @@ -99,6 +101,27 @@ class RenderScatterChart extends RenderBox {

@override
void handleEvent(PointerEvent event, covariant BoxHitTestEntry entry) {
_touchCallback?.call(_painter.handleTouch(event, size, paintHolder));
if (_touchCallback == null) {
return;
}
var response = ScatterTouchResponse(event, null, false);

var touchedSpot = _painter.handleTouch(event, size, paintHolder);
if (touchedSpot == null) {
_touchCallback!.call(response);
return;
}
response = response.copyWith(touchedSpot: touchedSpot);

if (event is PointerDownEvent) {
_lastTouchedSpot = touchedSpot;
} else if (event is PointerUpEvent) {
if (_lastTouchedSpot != null && _lastTouchedSpot == touchedSpot) {
response = response.copyWith(clickHappened: true);
}
_lastTouchedSpot = null;
}

_touchCallback!.call(response);
}
}

0 comments on commit 4dde875

Please sign in to comment.