Created
May 12, 2022 23:11
-
-
Save imaNNeo/678d5bdfb31421f133c404c1d7be60b2 to your computer and use it in GitHub Desktop.
Chart renderer key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:fl_chart/fl_chart.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/rendering.dart'; | |
import 'package:flutter/scheduler.dart'; | |
class _LineChart extends StatefulWidget { | |
const _LineChart({required this.isShowingMainData}); | |
final bool isShowingMainData; | |
@override | |
State<_LineChart> createState() => _LineChartState(); | |
} | |
class _LineChartState extends State<_LineChart> { | |
GlobalKey insideChartKey = GlobalKey(); | |
Size? size; | |
Offset? offset; | |
@override | |
void initState() { | |
SchedulerBinding.instance.addPostFrameCallback((_) { | |
final renderBox = | |
(insideChartKey.currentContext?.findRenderObject() as RenderBox); | |
size = renderBox.size; // or _widgetKey.currentContext?.size | |
offset = (renderBox.parentData as BoxParentData).offset; | |
}); | |
super.initState(); | |
} | |
bool isHovered = false; | |
@override | |
Widget build(BuildContext context) { | |
return Stack( | |
children: [ | |
LineChart( | |
widget.isShowingMainData ? sampleData1 : sampleData2, | |
chartRendererKey: insideChartKey, | |
swapAnimationDuration: const Duration(milliseconds: 250), | |
), | |
Positioned( | |
left: offset?.dx ?? 0, | |
top: offset?.dy ?? 0, | |
child: MouseRegion( | |
onEnter: (event) { | |
setState(() { | |
isHovered = true; | |
}); | |
}, | |
onExit: (exit) { | |
setState(() { | |
isHovered = false; | |
}); | |
}, | |
onHover: (hoverEvent) { | |
setState(() { | |
isHovered = true; | |
}); | |
}, | |
child: IgnorePointer( | |
child: Container( | |
width: size?.width ?? 0, | |
height: size?.height ?? 0, | |
color: isHovered ? Colors.white60 : Colors.transparent, | |
), | |
), | |
), | |
), | |
], | |
); | |
} | |
LineChartData get sampleData1 => LineChartData( | |
lineTouchData: lineTouchData1, | |
gridData: gridData, | |
titlesData: titlesData1, | |
borderData: borderData, | |
lineBarsData: lineBarsData1, | |
minX: 0, | |
maxX: 14, | |
maxY: 4, | |
minY: 0, | |
); | |
LineChartData get sampleData2 => LineChartData( | |
lineTouchData: lineTouchData2, | |
gridData: gridData, | |
titlesData: titlesData2, | |
borderData: borderData, | |
lineBarsData: lineBarsData2, | |
minX: 0, | |
maxX: 14, | |
maxY: 6, | |
minY: 0, | |
); | |
LineTouchData get lineTouchData1 => LineTouchData( | |
handleBuiltInTouches: true, | |
touchTooltipData: LineTouchTooltipData( | |
tooltipBgColor: Colors.blueGrey.withOpacity(0.8), | |
), | |
); | |
FlTitlesData get titlesData1 => FlTitlesData( | |
bottomTitles: AxisTitles( | |
sideTitles: bottomTitles, | |
), | |
rightTitles: AxisTitles( | |
sideTitles: SideTitles(showTitles: false), | |
), | |
topTitles: AxisTitles( | |
sideTitles: SideTitles(showTitles: false), | |
), | |
leftTitles: AxisTitles( | |
sideTitles: leftTitles(), | |
), | |
); | |
List<LineChartBarData> get lineBarsData1 => [ | |
lineChartBarData1_1, | |
lineChartBarData1_2, | |
lineChartBarData1_3, | |
]; | |
LineTouchData get lineTouchData2 => LineTouchData( | |
enabled: false, | |
); | |
FlTitlesData get titlesData2 => FlTitlesData( | |
bottomTitles: AxisTitles( | |
sideTitles: bottomTitles, | |
), | |
rightTitles: AxisTitles( | |
sideTitles: SideTitles(showTitles: false), | |
), | |
topTitles: AxisTitles( | |
sideTitles: SideTitles(showTitles: false), | |
), | |
leftTitles: AxisTitles( | |
sideTitles: leftTitles(), | |
), | |
); | |
List<LineChartBarData> get lineBarsData2 => [ | |
lineChartBarData2_1, | |
lineChartBarData2_2, | |
lineChartBarData2_3, | |
]; | |
Widget leftTitleWidgets(double value, TitleMeta meta) { | |
const style = TextStyle( | |
color: Color(0xff75729e), | |
fontWeight: FontWeight.bold, | |
fontSize: 14, | |
); | |
String text; | |
switch (value.toInt()) { | |
case 1: | |
text = '1m'; | |
break; | |
case 2: | |
text = '2m'; | |
break; | |
case 3: | |
text = '3m'; | |
break; | |
case 4: | |
text = '5m'; | |
break; | |
case 5: | |
text = '6m'; | |
break; | |
default: | |
return Container(); | |
} | |
return Text(text, style: style, textAlign: TextAlign.center); | |
} | |
SideTitles leftTitles() => SideTitles( | |
getTitlesWidget: leftTitleWidgets, | |
showTitles: true, | |
interval: 1, | |
reservedSize: 40, | |
); | |
Widget bottomTitleWidgets(double value, TitleMeta meta) { | |
const style = TextStyle( | |
color: Color(0xff72719b), | |
fontWeight: FontWeight.bold, | |
fontSize: 16, | |
); | |
Widget text; | |
switch (value.toInt()) { | |
case 2: | |
text = const Text('SEPT', style: style); | |
break; | |
case 7: | |
text = const Text('OCT', style: style); | |
break; | |
case 12: | |
text = const Text('DEC', style: style); | |
break; | |
default: | |
text = const Text(''); | |
break; | |
} | |
return Padding(child: text, padding: const EdgeInsets.only(top: 10.0)); | |
} | |
SideTitles get bottomTitles => SideTitles( | |
showTitles: true, | |
reservedSize: 32, | |
interval: 1, | |
getTitlesWidget: bottomTitleWidgets, | |
); | |
FlGridData get gridData => FlGridData(show: false); | |
FlBorderData get borderData => FlBorderData( | |
show: true, | |
border: const Border( | |
bottom: BorderSide(color: Color(0xff4e4965), width: 4), | |
left: BorderSide(color: Colors.transparent), | |
right: BorderSide(color: Colors.transparent), | |
top: BorderSide(color: Colors.transparent), | |
), | |
); | |
LineChartBarData get lineChartBarData1_1 => LineChartBarData( | |
isCurved: true, | |
color: const Color(0xff4af699), | |
barWidth: 8, | |
isStrokeCapRound: true, | |
dotData: FlDotData(show: false), | |
belowBarData: BarAreaData(show: false), | |
spots: const [ | |
FlSpot(1, 1), | |
FlSpot(3, 1.5), | |
FlSpot(5, 1.4), | |
FlSpot(7, 3.4), | |
FlSpot(10, 2), | |
FlSpot(12, 2.2), | |
FlSpot(13, 1.8), | |
], | |
); | |
LineChartBarData get lineChartBarData1_2 => LineChartBarData( | |
isCurved: true, | |
color: const Color(0xffaa4cfc), | |
barWidth: 8, | |
isStrokeCapRound: true, | |
dotData: FlDotData(show: false), | |
belowBarData: BarAreaData( | |
show: false, | |
color: const Color(0x00aa4cfc), | |
), | |
spots: const [ | |
FlSpot(1, 1), | |
FlSpot(3, 2.8), | |
FlSpot(7, 1.2), | |
FlSpot(10, 2.8), | |
FlSpot(12, 2.6), | |
FlSpot(13, 3.9), | |
], | |
); | |
LineChartBarData get lineChartBarData1_3 => LineChartBarData( | |
isCurved: true, | |
color: const Color(0xff27b6fc), | |
barWidth: 8, | |
isStrokeCapRound: true, | |
dotData: FlDotData(show: false), | |
belowBarData: BarAreaData(show: false), | |
spots: const [ | |
FlSpot(1, 2.8), | |
FlSpot(3, 1.9), | |
FlSpot(6, 3), | |
FlSpot(10, 1.3), | |
FlSpot(13, 2.5), | |
], | |
); | |
LineChartBarData get lineChartBarData2_1 => LineChartBarData( | |
isCurved: true, | |
curveSmoothness: 0, | |
color: const Color(0x444af699), | |
barWidth: 4, | |
isStrokeCapRound: true, | |
dotData: FlDotData(show: false), | |
belowBarData: BarAreaData(show: false), | |
spots: const [ | |
FlSpot(1, 1), | |
FlSpot(3, 4), | |
FlSpot(5, 1.8), | |
FlSpot(7, 5), | |
FlSpot(10, 2), | |
FlSpot(12, 2.2), | |
FlSpot(13, 1.8), | |
], | |
); | |
LineChartBarData get lineChartBarData2_2 => LineChartBarData( | |
isCurved: true, | |
color: const Color(0x99aa4cfc), | |
barWidth: 4, | |
isStrokeCapRound: true, | |
dotData: FlDotData(show: false), | |
belowBarData: BarAreaData( | |
show: true, | |
color: const Color(0x33aa4cfc), | |
), | |
spots: const [ | |
FlSpot(1, 1), | |
FlSpot(3, 2.8), | |
FlSpot(7, 1.2), | |
FlSpot(10, 2.8), | |
FlSpot(12, 2.6), | |
FlSpot(13, 3.9), | |
], | |
); | |
LineChartBarData get lineChartBarData2_3 => LineChartBarData( | |
isCurved: true, | |
curveSmoothness: 0, | |
color: const Color(0x4427b6fc), | |
barWidth: 2, | |
isStrokeCapRound: true, | |
dotData: FlDotData(show: true), | |
belowBarData: BarAreaData(show: false), | |
spots: const [ | |
FlSpot(1, 3.8), | |
FlSpot(3, 1.9), | |
FlSpot(6, 5), | |
FlSpot(10, 3.3), | |
FlSpot(13, 4.5), | |
], | |
); | |
} | |
class LineChartSample1 extends StatefulWidget { | |
const LineChartSample1({Key? key}) : super(key: key); | |
@override | |
State<StatefulWidget> createState() => LineChartSample1State(); | |
} | |
class LineChartSample1State extends State<LineChartSample1> { | |
late bool isShowingMainData; | |
@override | |
void initState() { | |
super.initState(); | |
isShowingMainData = true; | |
} | |
@override | |
Widget build(BuildContext context) { | |
return AspectRatio( | |
aspectRatio: 1.23, | |
child: Container( | |
decoration: const BoxDecoration( | |
borderRadius: BorderRadius.all(Radius.circular(18)), | |
gradient: LinearGradient( | |
colors: [ | |
Color(0xff2c274c), | |
Color(0xff46426c), | |
], | |
begin: Alignment.bottomCenter, | |
end: Alignment.topCenter, | |
), | |
), | |
child: Stack( | |
children: <Widget>[ | |
Column( | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: <Widget>[ | |
const SizedBox( | |
height: 37, | |
), | |
const Text( | |
'Unfold Shop 2018', | |
style: TextStyle( | |
color: Color(0xff827daa), | |
fontSize: 16, | |
), | |
textAlign: TextAlign.center, | |
), | |
const SizedBox( | |
height: 4, | |
), | |
const Text( | |
'Monthly Sales', | |
style: TextStyle( | |
color: Colors.white, | |
fontSize: 32, | |
fontWeight: FontWeight.bold, | |
letterSpacing: 2, | |
), | |
textAlign: TextAlign.center, | |
), | |
const SizedBox( | |
height: 37, | |
), | |
Expanded( | |
child: Padding( | |
padding: const EdgeInsets.only(right: 16.0, left: 6.0), | |
child: _LineChart(isShowingMainData: isShowingMainData), | |
), | |
), | |
const SizedBox( | |
height: 10, | |
), | |
], | |
), | |
IconButton( | |
icon: Icon( | |
Icons.refresh, | |
color: Colors.white.withOpacity(isShowingMainData ? 1.0 : 0.5), | |
), | |
onPressed: () { | |
setState(() { | |
isShowingMainData = !isShowingMainData; | |
}); | |
}, | |
) | |
], | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Screen.Recording.2022-05-13.at.03.39.54.mov