Skip to content

Commit

Permalink
Merge pull request #120 from imaNNeoFighT/feature/scatter-chart
Browse files Browse the repository at this point in the history
Feature/scatter chart
  • Loading branch information
imaNNeo authored Nov 29, 2019
2 parents 76ab24e + 00a9ecc commit 9e1091f
Show file tree
Hide file tree
Showing 23 changed files with 1,212 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.5.0
* 💥 Added ScatterChart ([read about it](https://jbt.github.io/markdown-editor/repo_files/documentations/scatter_chart.md)) 💥
* Added Velocity to in [FlPanEnd](https://github.com/imaNNeoFighT/fl_chart/blob/feature/scatter-chart/repo_files/documentations/base_chart.md#fltouchinput) to determine the Tap event.

## 0.4.3
* fixed a size bug, #100.
* direction support for gradient on the LineChart (added `gradientFrom` and `gradientTo` in the [LineChartBarData](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/line_chart.md#linechartbardata)).
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
| [![](https://github.com/imaNNeoFighT/fl_chart/raw/master/repo_files/images/line_chart/line_chart_sample_1.gif)](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/line_chart.md#sample-1-source-code) [![](https://github.com/imaNNeoFighT/fl_chart/raw/master/repo_files/images/line_chart/line_chart_sample_2.gif)](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/line_chart.md#sample-2-source-code) | [![](https://github.com/imaNNeoFighT/fl_chart/raw/master/repo_files/images/bar_chart/bar_chart_sample_1.gif)](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/bar_chart.md#sample-1-source-code) [![](https://github.com/imaNNeoFighT/fl_chart/raw/master/repo_files/images/bar_chart/bar_chart_sample_2.gif)](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/bar_chart.md#sample-2-source-code) | [![](https://github.com/imaNNeoFighT/fl_chart/raw/master/repo_files/images/pie_chart/pie_chart_sample_1.gif)](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/pie_chart.md#sample-1-source-code) [![](https://github.com/imaNNeoFighT/fl_chart/raw/master/repo_files/images/pie_chart/pie_chart_sample_2.gif)](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/pie_chart.md#sample-2-source-code) |
|[Read More](repo_files/documentations/line_chart.md)|[Read More](repo_files/documentations/bar_chart.md)|[Read More](repo_files/documentations/pie_chart.md)|

|ScatterChart |
|:------------:|
| [![](https://github.com/imaNNeoFighT/fl_chart/raw/master/repo_files/images/scatter_chart/scatter_chart_sample_1.gif)](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/scatter_chart.md#sample-1-source-code) [![](https://github.com/imaNNeoFighT/fl_chart/raw/master/repo_files/images/scatter_chart/scatter_chart_sample_2.gif)](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/scatter_chart.md#sample-2-source-code) |
|[Read More](repo_files/documentations/scatter_chart.md)|

Banner designed by [Soheil Saffar](https://www.linkedin.com/in/soheilsaffar), and
samples inspired from
[David Kovalev](https://dribbble.com/shots/5560237-Live-Graphs-XD),
Expand All @@ -36,7 +41,7 @@ Thank you all!

```kotlin
dependencies:
fl_chart: ^0.4.3
fl_chart: ^0.5.0
```


Expand Down
2 changes: 2 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:example/scatter_chart/scatter_chart_page.dart';
import 'package:flutter/material.dart';

import 'bar_chart/bar_chart_page.dart';
Expand Down Expand Up @@ -48,6 +49,7 @@ class _MyHomePageState extends State<MyHomePage> {
LineChartPage2(),
LineChartPage3(),
LineChartPage4(),
ScatterChartPage(),
],
),
),
Expand Down
195 changes: 195 additions & 0 deletions example/lib/scatter_chart/samples/scatter_chart_sample1.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import 'dart:math';

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

class ScatterChartSample1 extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ScatterChartSample1State();
}

class _ScatterChartSample1State extends State {

final maxX = 50.0;
final maxY = 50.0;
final radius = 8.0;

Color blue1 = const Color(0xFF0D47A1);
Color blue2 = const Color(0xFF42A5F5).withOpacity(0.8);

bool showFlutter = true;

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
showFlutter = !showFlutter;
});
},
child: AspectRatio(
aspectRatio: 1,
child: Card(
color: const Color(0xffffffff),
elevation: 6,
child: ScatterChart(
ScatterChartData(
scatterSpots: showFlutter ? flutterLogoData() : randomData(),
minX: 0,
maxX: maxX,
minY: 0,
maxY: maxY,
borderData: FlBorderData(
show: false,
),
gridData: const FlGridData(
show: false,
),
titlesData: const FlTitlesData(
show: false,
),
scatterTouchData: const ScatterTouchData(
enabled: false,
)
),
swapAnimationDuration: Duration(milliseconds: 600),
),
),
),
);
}

List<ScatterSpot> flutterLogoData() {
return [
/// section 1
ScatterSpot(20, 14.5, color: blue1, radius: radius),
ScatterSpot(22, 16.5, color: blue1, radius: radius),
ScatterSpot(24, 18.5, color: blue1, radius: radius),

ScatterSpot(22, 12.5, color: blue1, radius: radius),
ScatterSpot(24, 14.5, color: blue1, radius: radius),
ScatterSpot(26, 16.5, color: blue1, radius: radius),

ScatterSpot(24, 10.5, color: blue1, radius: radius),
ScatterSpot(26, 12.5, color: blue1, radius: radius),
ScatterSpot(28, 14.5, color: blue1, radius: radius),

ScatterSpot(26, 8.5, color: blue1, radius: radius),
ScatterSpot(28, 10.5, color: blue1, radius: radius),
ScatterSpot(30, 12.5, color: blue1, radius: radius),

ScatterSpot(28, 6.5, color: blue1, radius: radius),
ScatterSpot(30, 8.5, color: blue1, radius: radius),
ScatterSpot(32, 10.5, color: blue1, radius: radius),

ScatterSpot(30, 4.5, color: blue1, radius: radius),
ScatterSpot(32, 6.5, color: blue1, radius: radius),
ScatterSpot(34, 8.5, color: blue1, radius: radius),

ScatterSpot(34, 4.5, color: blue1, radius: radius),
ScatterSpot(36, 6.5, color: blue1, radius: radius),

ScatterSpot(38, 4.5, color: blue1, radius: radius),

/// section 2
ScatterSpot(20, 14.5, color: blue2, radius: radius),
ScatterSpot(22, 12.5, color: blue2, radius: radius),
ScatterSpot(24, 10.5, color: blue2, radius: radius),

ScatterSpot(22, 16.5, color: blue2, radius: radius),
ScatterSpot(24, 14.5, color: blue2, radius: radius),
ScatterSpot(26, 12.5, color: blue2, radius: radius),

ScatterSpot(24, 18.5, color: blue2, radius: radius),
ScatterSpot(26, 16.5, color: blue2, radius: radius),
ScatterSpot(28, 14.5, color: blue2, radius: radius),

ScatterSpot(26, 20.5, color: blue2, radius: radius),
ScatterSpot(28, 18.5, color: blue2, radius: radius),
ScatterSpot(30, 16.5, color: blue2, radius: radius),

ScatterSpot(28, 22.5, color: blue2, radius: radius),
ScatterSpot(30, 20.5, color: blue2, radius: radius),
ScatterSpot(32, 18.5, color: blue2, radius: radius),

ScatterSpot(30, 24.5, color: blue2, radius: radius),
ScatterSpot(32, 22.5, color: blue2, radius: radius),
ScatterSpot(34, 20.5, color: blue2, radius: radius),

ScatterSpot(34, 24.5, color: blue2, radius: radius),
ScatterSpot(36, 22.5, color: blue2, radius: radius),

ScatterSpot(38, 24.5, color: blue2, radius: radius),

/// section 3
ScatterSpot(10, 25, color: blue2, radius: radius),
ScatterSpot(12, 23, color: blue2, radius: radius),
ScatterSpot(14, 21, color: blue2, radius: radius),

ScatterSpot(12, 27, color: blue2, radius: radius),
ScatterSpot(14, 25, color: blue2, radius: radius),
ScatterSpot(16, 23, color: blue2, radius: radius),

ScatterSpot(14, 29, color: blue2, radius: radius),
ScatterSpot(16, 27, color: blue2, radius: radius),
ScatterSpot(18, 25, color: blue2, radius: radius),

ScatterSpot(16, 31, color: blue2, radius: radius),
ScatterSpot(18, 29, color: blue2, radius: radius),
ScatterSpot(20, 27, color: blue2, radius: radius),

ScatterSpot(18, 33, color: blue2, radius: radius),
ScatterSpot(20, 31, color: blue2, radius: radius),
ScatterSpot(22, 29, color: blue2, radius: radius),

ScatterSpot(20, 35, color: blue2, radius: radius),
ScatterSpot(22, 33, color: blue2, radius: radius),
ScatterSpot(24, 31, color: blue2, radius: radius),

ScatterSpot(22, 37, color: blue2, radius: radius),
ScatterSpot(24, 35, color: blue2, radius: radius),
ScatterSpot(26, 33, color: blue2, radius: radius),

ScatterSpot(24, 39, color: blue2, radius: radius),
ScatterSpot(26, 37, color: blue2, radius: radius),
ScatterSpot(28, 35, color: blue2, radius: radius),

ScatterSpot(26, 41, color: blue2, radius: radius),
ScatterSpot(28, 39, color: blue2, radius: radius),
ScatterSpot(30, 37, color: blue2, radius: radius),

ScatterSpot(28, 43, color: blue2, radius: radius),
ScatterSpot(30, 41, color: blue2, radius: radius),
ScatterSpot(32, 39, color: blue2, radius: radius),

ScatterSpot(30, 45, color: blue2, radius: radius),
ScatterSpot(32, 43, color: blue2, radius: radius),
ScatterSpot(34, 41, color: blue2, radius: radius),

ScatterSpot(34, 45, color: blue2, radius: radius),
ScatterSpot(36, 43, color: blue2, radius: radius),

ScatterSpot(38, 45, color: blue2, radius: radius),
];
}

List<ScatterSpot> randomData() {
const blue1Count = 21;
const blue2Count = 57;
return List.generate(blue1Count + blue2Count, (i) {
Color color;
if (i < blue1Count) {
color = blue1;
} else {
color = blue2;
}

return ScatterSpot(
(Random().nextDouble() * (maxX - 8)) + 4,
(Random().nextDouble() * (maxY - 8)) + 4,
color: color,
radius: (Random().nextDouble() * 16) + 4,
);
});
}
}
86 changes: 86 additions & 0 deletions example/lib/scatter_chart/samples/scatter_chart_sample2.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';

class ScatterChartSample2 extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ScatterChartSample2State();
}

class _ScatterChartSample2State extends State {
int touchedIndex;

Color greyColor = Colors.grey;

List<int> selectedSpots = [];

int lastPanStartOnIndex = -1;

@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1,
child: Card(
color: Color(0xff222222),
child: ScatterChart(
ScatterChartData(
scatterSpots: [
ScatterSpot(4, 4, color: selectedSpots.contains(0) ? Colors.green : greyColor,),
ScatterSpot(2, 5, color: selectedSpots.contains(1) ? Colors.yellow : greyColor, radius: 12,),
ScatterSpot(4, 5, color: selectedSpots.contains(2) ? Colors.purpleAccent : greyColor, radius: 8,),
ScatterSpot(8, 6, color: selectedSpots.contains(3) ? Colors.orange : greyColor, radius: 20,),
ScatterSpot(5, 7, color: selectedSpots.contains(4) ? Colors.brown : greyColor, radius: 14,),
ScatterSpot(7, 2, color: selectedSpots.contains(5) ? Colors.lightGreenAccent : greyColor, radius: 18,),
ScatterSpot(3, 2, color: selectedSpots.contains(6) ? Colors.red : greyColor, radius: 36,),
ScatterSpot(2, 8, color: selectedSpots.contains(7) ? Colors.tealAccent : greyColor, radius: 22,),
],
minX: 0,
maxX: 10,
minY: 0,
maxY: 10,
borderData: FlBorderData(
show: false,
),
gridData: FlGridData(
show: true,
drawHorizontalGrid: true,
checkToShowHorizontalGrid: (value) => true,
getDrawingHorizontalGridLine: (value) => FlLine(color: Colors.white.withOpacity(0.1)),
drawVerticalGrid: true,
checkToShowVerticalGrid: (value) => true,
getDrawingVerticalGridLine: (value) => FlLine(color: Colors.white.withOpacity(0.1)),
),
titlesData: const FlTitlesData(
show: false,
),
showingTooltipIndicators: selectedSpots,
scatterTouchData: ScatterTouchData(
enabled: true,
handleBuiltInTouches: false,
touchTooltipData: const ScatterTouchTooltipData(
tooltipBgColor: Colors.black,
),
touchCallback: (ScatterTouchResponse touchResponse) {
if (touchResponse.touchInput is FlPanStart) {
lastPanStartOnIndex = touchResponse.touchedSpotIndex;
} else if (touchResponse.touchInput is FlPanEnd) {
final FlPanEnd flPanEnd = touchResponse.touchInput;

if (flPanEnd.velocity.pixelsPerSecond <= const Offset(4, 4)) {
// Tap happened
setState(() {
if (selectedSpots.contains(lastPanStartOnIndex)) {
selectedSpots.remove(lastPanStartOnIndex);
} else {
selectedSpots.add(lastPanStartOnIndex);
}
});
}
}
}
)
),
),
),
);
}
}
45 changes: 45 additions & 0 deletions example/lib/scatter_chart/scatter_chart_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:example/scatter_chart/samples/scatter_chart_sample1.dart';
import 'package:example/scatter_chart/samples/scatter_chart_sample2.dart';
import 'package:flutter/material.dart';

class ScatterChartPage extends StatelessWidget {
final Color barColor = Colors.white;
final Color barBackgroundColor = const Color(0xff72d8bf);
final double width = 22;

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffffffff),
body: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
vertical: 18.0,
horizontal: 22,
),
child: Text(
'Scatter Charts',
style: TextStyle(
color: Colors.black,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(
height: 9,
),
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0, bottom: 18.0),
child: ScatterChartSample1(),
),
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0, bottom: 18.0),
child: ScatterChartSample2(),
)
],
),
);
}
}
4 changes: 3 additions & 1 deletion lib/fl_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ export 'src/chart/base/base_chart/touch_input.dart';
export 'src/chart/line_chart/line_chart.dart';
export 'src/chart/line_chart/line_chart_data.dart';
export 'src/chart/pie_chart/pie_chart.dart';
export 'src/chart/pie_chart/pie_chart_data.dart';
export 'src/chart/pie_chart/pie_chart_data.dart';
export 'src/chart/scatter_chart/scatter_chart.dart';
export 'src/chart/scatter_chart/scatter_chart_data.dart';
4 changes: 2 additions & 2 deletions lib/src/chart/bar_chart/bar_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ class BarChartState extends AnimatedWidgetBaseState<BarChart> {
},
onPanCancel: () async {
final BarTouchResponse response =
_touchHandler?.handleTouch(FlPanEnd(Offset.zero), chartSize);
_touchHandler?.handleTouch(FlPanEnd(Offset.zero, Velocity(pixelsPerSecond: Offset.zero)), chartSize);
if (_canHandleTouch(response, touchData)) {
touchData.touchCallback(response);
}
},
onPanEnd: (DragEndDetails details) async {
final BarTouchResponse response =
_touchHandler?.handleTouch(FlPanEnd(Offset.zero), chartSize);
_touchHandler?.handleTouch(FlPanEnd(Offset.zero, details.velocity), chartSize);
if (_canHandleTouch(response, touchData)) {
touchData.touchCallback(response);
}
Expand Down
Loading

0 comments on commit 9e1091f

Please sign in to comment.