Skip to content

Commit

Permalink
Add a feature to allow user to select a painterType in ScatterChartSa…
Browse files Browse the repository at this point in the history
…mple2
  • Loading branch information
imaNNeo committed Dec 3, 2023
1 parent 2f6a0e1 commit 2bb9c81
Showing 1 changed file with 183 additions and 165 deletions.
348 changes: 183 additions & 165 deletions example/lib/presentation/samples/scatter/scatter_chart_sample2.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math';

import 'package:fl_chart_app/presentation/resources/app_resources.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
Expand All @@ -13,188 +15,204 @@ class _ScatterChartSample2State extends State {
int touchedIndex = -1;

Color greyColor = Colors.grey;
final _availableColors = [
AppColors.contentColorGreen,
AppColors.contentColorYellow,
AppColors.contentColorPink,
AppColors.contentColorOrange,
AppColors.contentColorPurple,
AppColors.contentColorBlue,
AppColors.contentColorRed,
AppColors.contentColorCyan,
AppColors.contentColorBlue,
AppColors.contentColorGreen,
AppColors.contentColorPink,
];

List<int> selectedSpots = [];

PainterType _currentPaintType = PainterType.circle;

static FlDotPainter _getPaint(PainterType type, double size, Color color) {
switch (type) {
case PainterType.circle:
return FlDotCirclePainter(
color: color,
radius: size,
);
case PainterType.square:
return FlDotSquarePainter(
color: color,
size: size * 2,
strokeWidth: 0,
);
case PainterType.cross:
return FlDotCrossPainter(
color: color,
size: size * 2,
width: max(size / 5, 2),
);
}
}

@override
Widget build(BuildContext context) {
// (x, y, size)
final data = [
(4.0, 4.0, 4.0),
(2.0, 5.0, 12.0),
(4.0, 5.0, 8.0),
(8.0, 6.0, 20.0),
(5.0, 7.0, 14.0),
(7.0, 2.0, 18.0),
(3.0, 2.0, 36.0),
(2.0, 8.0, 22.0),
(8.0, 8.0, 32.0),
(5.0, 2.5, 24.0),
(3.0, 7.0, 18.0),
];
return AspectRatio(
aspectRatio: 1,
child: ScatterChart(
ScatterChartData(
scatterSpots: [
ScatterSpot(
4,
4,
dotPainter: FlDotCirclePainter(
color: selectedSpots.contains(0)
? AppColors.contentColorGreen
: AppColors.contentColorWhite.withOpacity(0.5),
),
),
ScatterSpot(
2,
5,
dotPainter: FlDotCirclePainter(
color: selectedSpots.contains(1)
? AppColors.contentColorYellow
: AppColors.contentColorWhite.withOpacity(0.5),
radius: 12,
),
),
ScatterSpot(
4,
5,
dotPainter: FlDotCirclePainter(
color: selectedSpots.contains(2)
? AppColors.contentColorPink
: AppColors.contentColorWhite.withOpacity(0.5),
radius: 8,
),
),
ScatterSpot(
8,
6,
dotPainter: FlDotCirclePainter(
color: selectedSpots.contains(3)
? AppColors.contentColorOrange
: AppColors.contentColorWhite.withOpacity(0.5),
radius: 20,
),
),
ScatterSpot(
5,
7,
dotPainter: FlDotCirclePainter(
color: selectedSpots.contains(4)
? AppColors.contentColorPurple
: AppColors.contentColorWhite.withOpacity(0.5),
radius: 14,
),
),
ScatterSpot(
7,
2,
dotPainter: FlDotCirclePainter(
color: selectedSpots.contains(5)
? AppColors.contentColorBlue
: AppColors.contentColorWhite.withOpacity(0.5),
radius: 18,
child: Stack(
children: [
ScatterChart(
ScatterChartData(
scatterSpots: data.asMap().entries.map((e) {
final index = e.key;
final (double x, double y, double size) = e.value;
return ScatterSpot(
x,
y,
dotPainter: _getPaint(
_currentPaintType,
size,
selectedSpots.contains(index)
? _availableColors[index % _availableColors.length]
: AppColors.contentColorWhite.withOpacity(0.5),
),
);
}).toList(),
minX: 0,
maxX: 10,
minY: 0,
maxY: 10,
borderData: FlBorderData(
show: false,
),
),
ScatterSpot(
3,
2,
dotPainter: FlDotCirclePainter(
color: selectedSpots.contains(6)
? AppColors.contentColorRed
: AppColors.contentColorWhite.withOpacity(0.5),
radius: 36,
gridData: FlGridData(
show: true,
drawHorizontalLine: true,
checkToShowHorizontalLine: (value) => true,
getDrawingHorizontalLine: (value) => const FlLine(
color: AppColors.gridLinesColor,
),
drawVerticalLine: true,
checkToShowVerticalLine: (value) => true,
getDrawingVerticalLine: (value) => const FlLine(
color: AppColors.gridLinesColor,
),
),
),
ScatterSpot(
2,
8,
dotPainter: FlDotCirclePainter(
color: selectedSpots.contains(7)
? AppColors.contentColorCyan
: AppColors.contentColorWhite.withOpacity(0.5),
radius: 22,
titlesData: const FlTitlesData(
show: false,
),
),
],
minX: 0,
maxX: 10,
minY: 0,
maxY: 10,
borderData: FlBorderData(
show: false,
),
gridData: FlGridData(
show: true,
drawHorizontalLine: true,
checkToShowHorizontalLine: (value) => true,
getDrawingHorizontalLine: (value) => const FlLine(
color: AppColors.gridLinesColor,
),
drawVerticalLine: true,
checkToShowVerticalLine: (value) => true,
getDrawingVerticalLine: (value) => const FlLine(
color: AppColors.gridLinesColor,
),
),
titlesData: const FlTitlesData(
show: false,
),
showingTooltipIndicators: selectedSpots,
scatterTouchData: ScatterTouchData(
enabled: true,
handleBuiltInTouches: false,
mouseCursorResolver:
(FlTouchEvent touchEvent, ScatterTouchResponse? response) {
return response == null || response.touchedSpot == null
? MouseCursor.defer
: SystemMouseCursors.click;
},
touchTooltipData: ScatterTouchTooltipData(
tooltipBgColor: Colors.black,
getTooltipItems: (ScatterSpot touchedBarSpot) {
return 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(
showingTooltipIndicators: selectedSpots,
scatterTouchData: ScatterTouchData(
enabled: true,
handleBuiltInTouches: false,
mouseCursorResolver:
(FlTouchEvent touchEvent, ScatterTouchResponse? response) {
return response == null || response.touchedSpot == null
? MouseCursor.defer
: SystemMouseCursors.click;
},
touchTooltipData: ScatterTouchTooltipData(
tooltipBgColor: Colors.black,
getTooltipItems: (ScatterSpot touchedBarSpot) {
return ScatterTooltipItem(
'X: ',
textStyle: 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:
(FlTouchEvent event, ScatterTouchResponse? touchResponse) {
if (touchResponse == null || touchResponse.touchedSpot == null) {
return;
}
if (event is FlTapUpEvent) {
final sectionIndex = touchResponse.touchedSpot!.spotIndex;
setState(() {
if (selectedSpots.contains(sectionIndex)) {
selectedSpots.remove(sectionIndex);
} else {
selectedSpots.add(sectionIndex);
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:
(FlTouchEvent event, ScatterTouchResponse? touchResponse) {
if (touchResponse == null ||
touchResponse.touchedSpot == null) {
return;
}
if (event is FlTapUpEvent) {
final sectionIndex = touchResponse.touchedSpot!.spotIndex;
setState(() {
if (selectedSpots.contains(sectionIndex)) {
selectedSpots.remove(sectionIndex);
} else {
selectedSpots.add(sectionIndex);
}
});
}
});
}
},
},
),
),
),
),
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButton(
value: _currentPaintType,
items: PainterType.values
.map((e) => DropdownMenuItem(
value: e,
child: Text(e.name),
))
.toList(),
onChanged: (PainterType? value) {
setState(() {
_currentPaintType = value!;
});
},
),
),
),
],
),
);
}
}

enum PainterType {
circle,
square,
cross,
}

0 comments on commit 2bb9c81

Please sign in to comment.