Skip to content

Commit

Permalink
Handled click in line_chart.
Browse files Browse the repository at this point in the history
  • Loading branch information
imaNNeo committed Mar 19, 2021
1 parent 256d3d4 commit b6cc456
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 13 deletions.
7 changes: 4 additions & 3 deletions example/lib/line_chart/samples/line_chart_sample3.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ class _LineChartSample3State extends State<LineChartSample3> {
}).toList();
}),
touchCallback: (LineTouchResponse lineTouch) {
if (lineTouch.lineBarSpots.length == 1 &&
lineTouch.touchInput is! PointerExitEvent &&
lineTouch.touchInput is! PointerUpEvent) {
final desiredTouch = lineTouch.touchInput is! PointerExitEvent &&
lineTouch.touchInput is! PointerUpEvent;

if (desiredTouch && lineTouch.lineBarSpots != null) {
final value = lineTouch.lineBarSpots[0].x;

if (value == 0 || value == 6) {
Expand Down
11 changes: 6 additions & 5 deletions lib/src/chart/line_chart/line_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,17 @@ class _LineChartState extends AnimatedWidgetBaseState<LineChart> {
void _handleBuiltInTouch(LineTouchResponse touchResponse) {
widget.data.lineTouchData.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.lineBarSpots != null) {
setState(() {
final sortedLineSpots = List.of(touchResponse.lineBarSpots);
final sortedLineSpots = List.of(touchResponse.lineBarSpots!);
sortedLineSpots.sort((spot1, spot2) => spot2.y.compareTo(spot1.y));

_showingTouchedIndicators.clear();
for (var i = 0; i < touchResponse.lineBarSpots.length; i++) {
final touchedBarSpot = touchResponse.lineBarSpots[i];
for (var i = 0; i < touchResponse.lineBarSpots!.length; i++) {
final touchedBarSpot = touchResponse.lineBarSpots![i];
final barPos = touchedBarSpot.barIndex;
_showingTouchedIndicators[barPos] = [touchedBarSpot.spotIndex];
}
Expand Down
20 changes: 18 additions & 2 deletions lib/src/chart/line_chart/line_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1618,15 +1618,31 @@ typedef LineTouchCallback = void Function(LineTouchResponse);
class LineTouchResponse extends BaseTouchResponse {
/// touch happened on these spots
/// (if a single line provided on the chart, [lineBarSpots]'s length will be 1 always)
final List<LineBarSpot> lineBarSpots;
final List<LineBarSpot>? lineBarSpots;

/// If touch happens, [LineChart] processes it internally and
/// passes out a list of [lineBarSpots] it gives you information about the touched spot.
/// [touchInput] is the type of happened touch.
/// [clickHappened] will be true, if we detect a click event.
LineTouchResponse(
this.lineBarSpots,
PointerEvent touchInput,
) : super(touchInput);
bool clickHappened,
) : super(touchInput, clickHappened);

/// Copies current [LineTouchResponse] to a new [LineTouchResponse],
/// and replaces provided values.
LineTouchResponse copyWith({
List<LineBarSpot>? lineBarSpots,
PointerEvent? touchInput,
bool? clickHappened,
}) {
return LineTouchResponse(
lineBarSpots ?? this.lineBarSpots,
touchInput ?? this.touchInput,
clickHappened ?? this.clickHappened,
);
}
}

/// It lerps a [LineChartData] to another [LineChartData] (handles animation for updating values)
Expand Down
4 changes: 2 additions & 2 deletions lib/src/chart/line_chart/line_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1370,7 +1370,7 @@ class LineChartPainter extends AxisChartPainter<LineChartData> {
/// Processes [PointerEvent.localPosition] and checks
/// the elements of the chart that are near the offset,
/// then makes a [LineTouchResponse] from the elements that has been touched.
LineTouchResponse handleTouch(
List<LineBarSpot>? handleTouch(
PointerEvent touchInput,
Size size,
PaintHolder<LineChartData> holder,
Expand All @@ -1393,7 +1393,7 @@ class LineChartPainter extends AxisChartPainter<LineChartData> {
}
}

return LineTouchResponse(touchedSpots, touchInput);
return touchedSpots.isEmpty ? null : touchedSpots;
}

/// find the nearest spot base on the touched offset
Expand Down
25 changes: 24 additions & 1 deletion lib/src/chart/line_chart/line_chart_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class RenderLineChart extends RenderBox {
return PaintHolder(data, targetData, textScale);
}

List<LineBarSpot>? _lastTouchedSpots;

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

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

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

if (event is PointerDownEvent) {
_lastTouchedSpots = touchedSpots;
} else if (event is PointerUpEvent) {
if (_lastTouchedSpots == touchedSpots) {
response = response.copyWith(clickHappened: true);
}
_lastTouchedSpots = null;
}

_touchCallback!.call(response);
}
}

0 comments on commit b6cc456

Please sign in to comment.