Skip to content

Commit

Permalink
handling touch added to RadarChart
Browse files Browse the repository at this point in the history
  • Loading branch information
payam-zahedi committed Feb 18, 2021
1 parent 22d3bfc commit 2bc83df
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 41 deletions.
66 changes: 42 additions & 24 deletions example/lib/radar_chart/samples/radar_chart_sample1.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:developer';

import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';

Expand All @@ -7,6 +9,8 @@ class RadarChartSample extends StatefulWidget {
}

class _RadarChartSampleState extends State<RadarChartSample> {
int touchedDataSetIndex = -1;

@override
Widget build(BuildContext context) {
return AspectRatio(
Expand All @@ -15,46 +19,60 @@ class _RadarChartSampleState extends State<RadarChartSample> {
color: Colors.white,
child: RadarChart(
RadarChartData(
titleCount: 3,
fillColor: Colors.grey,
dataSets: showingDataSets(),
tickCount: 4,
getTitle: (index) => '$index + values',
gridData: const BorderSide(color: Colors.black, width: 1.5),
titlePositionPercentageOffset: 0.3,
ticksTextStyle: const TextStyle(
color: Colors.deepPurple,
fontSize: 10,
),
titleTextStyle: const TextStyle(
color: Colors.blue,
fontSize: 14,
),
),
titleCount: 3,
fillColor: Colors.grey,
dataSets: showingDataSets(),
tickCount: 4,
getTitle: (index) => '$index + values',
gridData: const BorderSide(color: Colors.black, width: 1.5),
titlePositionPercentageOffset: 0.3,
ticksTextStyle: const TextStyle(
color: Colors.deepPurple,
fontSize: 10,
),
titleTextStyle: const TextStyle(
color: Colors.blue,
fontSize: 14,
),
radarTouchData: RadarTouchData(touchCallback: (response) {
setState(() {
log('response type: ${response.touchInput}');

if (response.touchedSpot != null &&
response.touchInput is! FlPanEnd &&
response.touchInput is! FlLongPressEnd) {
touchedDataSetIndex = response?.touchedSpot?.touchedDataSetIndex ?? -1;
} else {
touchedDataSetIndex = -1;
}
});
})),
),
),
);
}

List<RadarDataSet> showingDataSets() {
return [
const RadarDataSet(
RadarDataSet(
dataEntries: [
RadarEntry(value: 5),
RadarEntry(value: 28),
RadarEntry(value: 25),
const RadarEntry(value: 5),
const RadarEntry(value: 28),
const RadarEntry(value: 25),
],
borderWidth: 3,
color: Colors.red,
entryRadius: (touchedDataSetIndex == 0) ? 6.0 : 3.0,
),
const RadarDataSet(
RadarDataSet(
dataEntries: [
RadarEntry(value: 18),
RadarEntry(value: 20),
RadarEntry(value: 30),
const RadarEntry(value: 18),
const RadarEntry(value: 20),
const RadarEntry(value: 30),
],
borderWidth: 3,
color: Colors.orange,
entryRadius: (touchedDataSetIndex == 1) ? 6.0 : 3.0,
),
];
}
Expand Down
132 changes: 118 additions & 14 deletions lib/src/chart/radar_chart/radar_chart.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:fl_chart/src/chart/base/base_chart/base_chart_painter.dart';
import 'package:fl_chart/src/chart/base/base_chart/touch_input.dart';
import 'package:fl_chart/src/chart/radar_chart/radar_chart_data.dart';
import 'package:fl_chart/src/chart/radar_chart/radar_chart_painter.dart';
import 'package:fl_chart/src/utils/utils.dart';
Expand All @@ -15,7 +16,6 @@ class RadarChart extends StatefulWidget {
}

//ToDo(payam) : handle animation
//ToDo(payam) : handle touch
class _RadarChartState extends State<RadarChart> {
/// we handle under the hood animations (implicit animations) via this tween,
/// it lerps between the old [PieChartData] to the new one.
Expand All @@ -29,20 +29,124 @@ class _RadarChartState extends State<RadarChart> {

@override
Widget build(BuildContext context) {
return CustomPaint(
key: _chartKey,
size: getDefaultSize(context),
painter: RadarChartPainter(
widget.data,
//ToDo(payam) : update it for animations
widget.data,
(touchHandler) {
setState(() {
_touchHandler = touchHandler;
});
},
textScale: MediaQuery.of(context).textScaleFactor,
final showingData = _getDate();
final touchData = showingData.radarTouchData;

return GestureDetector(
onLongPressStart: (d) {
final Size chartSize = _getChartSize();
if (chartSize == null) return;

final RadarTouchResponse response = _touchHandler?.handleTouch(
FlLongPressStart(d.localPosition),
chartSize,
);

if (_canHandleTouch(response, touchData)) touchData.touchCallback(response);
},
onLongPressEnd: (d) {
final Size chartSize = _getChartSize();
if (chartSize == null) return;

final RadarTouchResponse response = _touchHandler?.handleTouch(
FlLongPressEnd(d.localPosition),
chartSize,
);

if (_canHandleTouch(response, touchData)) touchData.touchCallback(response);
},
onLongPressMoveUpdate: (d) {
final Size chartSize = _getChartSize();
if (chartSize == null) return;

final RadarTouchResponse response = _touchHandler?.handleTouch(
FlLongPressMoveUpdate(d.localPosition),
chartSize,
);

if (_canHandleTouch(response, touchData)) touchData.touchCallback(response);
},
onPanCancel: () {
final Size chartSize = _getChartSize();
if (chartSize == null) return;

final RadarTouchResponse response = _touchHandler?.handleTouch(
FlPanEnd(Offset.zero, const Velocity(pixelsPerSecond: Offset.zero)),
chartSize,
);

if (_canHandleTouch(response, touchData)) touchData.touchCallback(response);
},
onPanEnd: (DragEndDetails details) {
final Size chartSize = _getChartSize();
if (chartSize == null) {
return;
}

final response =
_touchHandler?.handleTouch(FlPanEnd(Offset.zero, details.velocity), chartSize);
if (_canHandleTouch(response, touchData)) {
touchData.touchCallback(response);
}
},
onPanDown: (DragDownDetails details) {
final Size chartSize = _getChartSize();
if (chartSize == null) {
return;
}

final response = _touchHandler?.handleTouch(FlPanStart(details.localPosition), chartSize);
if (_canHandleTouch(response, touchData)) {
touchData.touchCallback(response);
}
},
onPanUpdate: (DragUpdateDetails details) {
final Size chartSize = _getChartSize();
if (chartSize == null) {
return;
}

final response =
_touchHandler?.handleTouch(FlPanMoveUpdate(details.localPosition), chartSize);
if (_canHandleTouch(response, touchData)) {
touchData.touchCallback(response);
}
},
child: CustomPaint(
key: _chartKey,
size: getDefaultSize(context),
painter: RadarChartPainter(
widget.data,
//ToDo(payam) : update it for animations
widget.data,
(touchHandler) {
setState(() {
_touchHandler = touchHandler;
});
},
textScale: MediaQuery.of(context).textScaleFactor,
),
),
);
}

RadarChartData _getDate() {
return widget.data;
}

Size _getChartSize() {
if (_chartKey.currentContext != null) {
final RenderBox containerRenderBox = _chartKey.currentContext.findRenderObject();
if (containerRenderBox.hasSize) {
return containerRenderBox.size;
}
return null;
} else {
return null;
}
}

bool _canHandleTouch(RadarTouchResponse response, RadarTouchData touchData) {
return response != null && touchData != null && touchData.touchCallback != null;
}
}
24 changes: 21 additions & 3 deletions lib/src/chart/radar_chart/radar_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class RadarChartPainter extends BaseChartPainter<RadarChartData>
RadarChartData data,
RadarChartData targetData,
Function(TouchHandler) touchHandler, {
double textScale,
double textScale =1 ,
}) : _backgroundPaint = Paint()
..color = data.fillColor
..style = PaintingStyle.fill
Expand Down Expand Up @@ -169,7 +169,6 @@ class RadarChartPainter extends BaseChartPainter<RadarChartData>
}

void drawDataSets(Size size, Canvas canvas) {

// we will use dataSetsPosition to draw the graphs
dataSetsPosition.asMap().forEach((index, dataSetOffset) {
final graph = data.dataSets[index];
Expand Down Expand Up @@ -222,7 +221,7 @@ class RadarChartPainter extends BaseChartPainter<RadarChartData>

@override
RadarTouchResponse handleTouch(FlTouchInput touchInput, Size size) {
final touchedSpot = _getNearestTouchSpot(size, touchInput.getOffset(), null);
final touchedSpot = _getNearestTouchSpot(size, touchInput.getOffset(), dataSetsPosition);
return RadarTouchResponse(touchedSpot, touchInput);
}

Expand All @@ -231,6 +230,25 @@ class RadarChartPainter extends BaseChartPainter<RadarChartData>
Offset touchedPoint,
List<RadarDataSetsPosition> radarDataSetsPosition,
) {
for (int i = 0; i < radarDataSetsPosition.length; i++) {
final dataSetPosition = radarDataSetsPosition[i];
for (int j = 0; j < dataSetPosition.entriesOffset.length; j++) {
final entryOffset = dataSetPosition.entriesOffset[j];
if ((touchedPoint.dx - entryOffset.dx).abs() <=
targetData.radarTouchData.touchSpotThreshold &&
(touchedPoint.dy - entryOffset.dy).abs() <=
targetData.radarTouchData.touchSpotThreshold) {
return RadarTouchedSpot(
targetData.dataSets[i],
i,
targetData.dataSets[i].dataEntries[j],
j,
FlSpot(entryOffset.dx, entryOffset.dy),
entryOffset,
);
}
}
}
return null;
}

Expand Down

0 comments on commit 2bc83df

Please sign in to comment.