I want to show fl line chart using this plugin https://pub.dev/packages/fl_chart.
data is double value and date in format of yyyy-MM-dd. Now I tried to show this data in chart.
Y axis showing data correctly but date calculations are not may be correct it showing lots of dates.
and If I add minX and maxX app got stuck due to lots of dates calculation between min and max X date values.
this is my code: in this data x is Date value and Y is double value.
I got the idea from this link https://github.com/imaNNeoFighT/fl_chart/issues/471
class AnalyticsChart extends StatefulWidget {
const AnalyticsChart({Key? key}) : super(key: key);
@override
_AnalyticsChartState createState() => _AnalyticsChartState();
}
class _AnalyticsChartState extends State<AnalyticsChart> {
List<Color> gradientColors = [
const Color(0xff099f53),
const Color(0xfffefffe),
];
bool showAvg = false;
final dateList = [];
@override
Widget build(BuildContext context) {
double windowHeight = MediaQuery.of(context).size.height - 370;
return Container(
height: windowHeight,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(0),
),
color: whiteColor),
child: Padding(
padding:
const EdgeInsets.only(right: 18.0, left: 12.0, top: 15, bottom: 12),
child: BlocBuilder<AnalyticsChartBloc, AnalyticsChartState>(
builder: (BuildContext context, AnalyticsChartState state) {
if (state is LoadAnalyticsStatesState) {
if (state.totalSales != null &&
(state.totalSales?.isNotEmpty ?? false)) {
List<FlSpot>? flSpots = [];
dateList.clear();
flSpots = state.totalSales?.map((e) {
dateList.add(e.x);
return FlSpot(
DateTime.parse(e.x ?? '') // e.date = "2020-10-24"
.millisecondsSinceEpoch
.toDouble(),
double.parse(e.y ?? '0'));
}).toList();
return LineChart(
mainData(flSpots),
);
}
}
return _buildNoChart();
}),
),
);
}
Widget bottomTitleWidgets(double value, TitleMeta meta) {
const style = TextStyle(
height: 1,
color: placeholderColor,
fontWeight: weight500,
fontSize: fontsize12,
);
final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
final parts = date.toIso8601String().split("T");
return SideTitleWidget(
space: 12,
child: Text(parts.first, style: style),
axisSide: meta.axisSide,
);
}
Widget leftTitleWidgets(double value, TitleMeta meta) {
const style = TextStyle(
color: placeholderColor,
fontWeight: weight100,
fontSize: fontsize9,
);
return Container(
padding: const EdgeInsets.only(right: 10),
height: 50.0,
child: Text(
value.toStringAsFixed(0),
style: style,
));
}
LineChartData mainData(List<FlSpot>? flSpots) {
final List<double> xList = [];
final List<double> yList = [];
flSpots?.map((e) {
xList.add(e.x);
yList.add(e.y);
}).toList();
final minX = xList.reduce(min); //
final maxX = xList.reduce(max); //
final minY = yList.reduce(min); //
final maxY = ((yList.reduce(max)) + 1000).toInt().toDouble(); //
debugPrint('minX/maxX $minX $maxX ');
debugPrint('minY/maxY $minY $maxY ');
debugPrint('maxX-minX ${maxX - minX} ');
return LineChartData(
lineTouchData: LineTouchData(
enabled: true,
touchTooltipData: LineTouchTooltipData(
tooltipBgColor: primaryColorGreen,
tooltipRoundedRadius: 4.0,
showOnTopOfTheChartBoxArea: false,
fitInsideHorizontally: true,
getTooltipItems: (touchedSpots) {
return touchedSpots.map(
(LineBarSpot touchedSpot) {
const textStyle = TextStyle(
fontSize: fontsize13,
fontWeight: weight500,
color: whiteColor,
height: 1.4,
);
return LineTooltipItem(
'Total Sales \n 17,500',
textStyle,
);
},
).toList();
},
),
),
gridData: FlGridData(
show: true,
drawVerticalLine: true,
horizontalInterval: 1,
verticalInterval: 1,
getDrawingHorizontalLine: (value) {
return FlLine(
color: borderColor,
strokeWidth: 1,
);
},
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.transparent,
strokeWidth: 1,
);
},
),
titlesData: FlTitlesData(
show: true,
rightTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
interval: (flSpots![flSpots.length - 1].x - flSpots[0].x),
getTitlesWidget: bottomTitleWidgets,
))),
maxX: maxX,
minX: minX,
maxY: maxY,
minY: minY,
borderData: FlBorderData(
show: true, border: Border.all(color: Colors.transparent, width: 0)),
lineBarsData: [
LineChartBarData(
spots: flSpots.asMap().entries.map((e) {
return FlSpot(e.key.toDouble(), e.value.y);
}).toList(),
isCurved: false,
color: primaryColorGreen,
barWidth: 2,
isStrokeCapRound: true,
dotData: FlDotData(
show: true,
),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: gradientColors
.map((color) => color.withOpacity(0.3))
.toList(),
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
),
],
);
}
Widget _buildNoChart() => const SizedBox(
child: Center(
child: Text('No chart data found'),
),
);
}
///////////////////////