fl_chart
fl_chart copied to clipboard
chart only shows after clicked or tapped
I enter the page where the chart supposed to show, but it shows only when i click on it.
@imaNNeoFighT
Hi @mickykro. Can you please check it with the latest version?
I have the same problem now on the some devices. The graph line is only visible when you click on the graph itself - the points are always visible
Can you please give me a reproducible code? (a main.dart file content)
@imaNNeo
That is my chart file:
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:package_name/domain/chart/chart_time_period.dart';
import 'package:package_name/extensions/context_extension.dart';
import 'package:package_name/style/app_colors.dart';
import 'package:package_name/style/dimens.dart';
class PackageChartTile extends StatelessWidget {
final Map<DateTime, double> aggregatedChartData;
final ChartTimePeriod selectedTimePeriod;
final Set<double> leftTitlesSet = {};
PackageChartTile(this.aggregatedChartData, this.selectedTimePeriod);
@override
Widget build(BuildContext context) {
final List<Color> gradientColors = [AppColors.shakespeare, AppColors.aphroditeAqua];
double minY = 0;
double maxY = 0;
double maxX = 11;
if (aggregatedChartData.isNotEmpty) {
minY = aggregatedChartData.values.reduce(min);
maxY = aggregatedChartData.values.reduce(max);
final double padding = (maxY - minY) * 0.2;
minY -= padding;
maxY += padding;
maxX = aggregatedChartData.length.toDouble() - 1;
}
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: _getChartWidth(),
height: 210,
padding: const EdgeInsets.only(top: Dimens.spacingM, right: Dimens.spacingM),
child: LineChart(
LineChartData(
gridData: FlGridData(
show: true,
drawVerticalLine: false,
horizontalInterval: ((maxY - minY) / 7) <= 0 ? 1 : ((maxY - minY) / 7),
getDrawingHorizontalLine: (value) {
return FlLine(
color: AppColors.lightSilver,
strokeWidth: 1,
);
},
),
// lineTouchData: LineTouchData(
// touchCallback: (_, __) {},
// touchTooltipData: LineTouchTooltipData(
// tooltipBgColor: AppColors.aeroBlue,
// tooltipMargin: Dimens.spacingM,
// getTooltipItems: (List<LineBarSpot> touchedBarSpots) {
// return touchedBarSpots.map((barSpot) {
// final flSpot = barSpot;
// final DateTime date = aggregatedChartData.keys.elementAt(flSpot.x.toInt());
// return LineTooltipItem(
// '${DateFormat.MMM().format(date)}: ${flSpot.y.toStringAsFixed(1)}',
// context.typo.body3.shakespeare().copyWith(),
// );
// }).toList();
// },
// ),
// ),
titlesData: FlTitlesData(
show: true,
rightTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 35,
interval: ((maxY - minY) / 7) <= 0 ? 1 : ((maxY - minY) / 7),
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: AxisSide.bottom,
child: Text(
double.tryParse(meta.formattedValue) == minY || double.tryParse(meta.formattedValue) == maxY
? ''
: meta.formattedValue,
style: context.typo.body4,
textAlign: TextAlign.left,
),
);
},
),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
interval: 1,
getTitlesWidget: (double value, TitleMeta meta) {
final DateTime date = aggregatedChartData.isNotEmpty && value.toInt() < aggregatedChartData.length
? aggregatedChartData.keys.elementAt(value.toInt())
: DateTime.now();
return SideTitleWidget(
axisSide: AxisSide.bottom,
child: Text(
_bottomTileText(date),
style: context.typo.body4,
textAlign: TextAlign.left,
),
);
},
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
interval: ((maxY - minY) / 7) <= 0 ? 1 : ((maxY - minY) / 7),
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: AxisSide.bottom,
child: Text(
double.tryParse(meta.formattedValue) == minY || double.tryParse(meta.formattedValue) == maxY
? ''
: meta.formattedValue,
style: context.typo.body4,
textAlign: TextAlign.left,
),
);
},
),
),
),
borderData: FlBorderData(show: false),
minX: 0,
maxX: maxX,
minY: minY,
maxY: maxY,
lineBarsData: [
LineChartBarData(
spots: _generateFlSpots(),
isCurved: true,
barWidth: 2,
isStrokeCapRound: true,
dotData: FlDotData(
show: true,
),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: gradientColors.map((color) => color.withOpacity(0.2)).toList(),
),
),
),
],
),
),
),
);
}
List<FlSpot> _generateFlSpots() {
final List<FlSpot> flSpots = [];
int index = 0;
for (final entry in aggregatedChartData.entries) {
flSpots.add(FlSpot(index.toDouble(), entry.value));
index++;
}
return flSpots;
}
String _bottomTileText(DateTime date) {
String formatPattern;
switch (selectedTimePeriod) {
case ChartTimePeriod.all:
formatPattern = 'dd.MM.yy';
break;
case ChartTimePeriod.week:
formatPattern = 'dd.MM';
break;
case ChartTimePeriod.month:
formatPattern = 'dd.MM';
break;
case ChartTimePeriod.year:
formatPattern = 'MMM';
break;
case ChartTimePeriod.day:
formatPattern = 'HH:mm';
break;
}
return DateFormat(formatPattern).format(date);
}
double _getChartWidth() {
if (aggregatedChartData.length <= 10) {
return aggregatedChartData.length * 150;
} else {
return aggregatedChartData.length * (selectedTimePeriod == ChartTimePeriod.all ? 55 : 40);
}
}
}
I've commented lineTouchData
for testing but with and without that lineTouchData
code the user has the same effect.
https://github.com/imaNNeo/fl_chart/assets/13346676/c880f041-4036-4458-ae05-49c3ad758ad0
In my devices I don't have that problem but users on other phones gave me know about that.
@imaNNeo any ideas?
import 'dart:math';
import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart';
I cannot run your code, it has compile issue.
@imaNNeo
Okay, I've changed my code, should be better to reproducible:
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class PackageNameChartTile extends StatelessWidget {
final Map<DateTime, double> aggregatedChartData;
final Set<double> leftTitlesSet = {};
PackageNameChartTile(this.aggregatedChartData);
@override
Widget build(BuildContext context) {
final List<Color> gradientColors = [const Color(0xff418AB9), const Color(0xff50EDCB)];
double minY = 0;
double maxY = 0;
double maxX = 11;
if (aggregatedChartData.isNotEmpty) {
minY = aggregatedChartData.values.reduce(min);
maxY = aggregatedChartData.values.reduce(max);
final double padding = (maxY - minY) * 0.2;
minY -= padding;
maxY += padding;
maxX = aggregatedChartData.length.toDouble() - 1;
minY = (minY - 0.1 * padding).roundToDouble(); //adjusting minY slightly
maxY = (maxY + 0.1 * padding).roundToDouble(); //adjusting maxY slightly
}
final double? calculatedInterval = ((maxY - minY) / 8) <= 0
? 1
: double.tryParse(((maxY - minY) / 8).toStringAsFixed(1));
final double? verticalLabelInterval = calculatedInterval == 0 ? 1 : calculatedInterval;
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: _getChartWidth(),
height: 210,
padding: const EdgeInsets.only(top: 16, right: 16),
child: LineChart(
LineChartData(
gridData: FlGridData(
show: true,
drawVerticalLine: false,
horizontalInterval: verticalLabelInterval,
getDrawingHorizontalLine: (value) {
return FlLine(
color: const Color(0xffD9D9D9),
strokeWidth: 1,
);
},
),
lineTouchData: LineTouchData(
touchCallback: (_, __) {},
touchTooltipData: LineTouchTooltipData(
tooltipBgColor: const Color(0xffC8F9EE),
tooltipMargin: 16,
getTooltipItems: (List<LineBarSpot> touchedBarSpots) {
return touchedBarSpots.map((barSpot) {
final flSpot = barSpot;
final DateTime date = aggregatedChartData.keys.elementAt(flSpot.x.toInt());
return LineTooltipItem(
'${DateFormat.MMM().format(date)}: ${flSpot.y.toStringAsFixed(1)}',
const TextStyle(
height: 1.71,
fontSize: 14.0,
fontWeight: FontWeight.w400,
)
);
}).toList();
},
),
),
titlesData: FlTitlesData(
show: true,
rightTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 35,
interval: verticalLabelInterval,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: AxisSide.bottom,
child: Text(
double.tryParse(meta.formattedValue) == minY || double.tryParse(meta.formattedValue) == maxY
? ''
: meta.formattedValue,
style: const TextStyle(
height: 1.36,
fontSize: 10.0,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.left,
),
);
},
),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
interval: 1,
getTitlesWidget: (double value, TitleMeta meta) {
final DateTime date = aggregatedChartData.isNotEmpty && value.toInt() < aggregatedChartData.length
? aggregatedChartData.keys.elementAt(value.toInt())
: DateTime.now();
return SideTitleWidget(
axisSide: AxisSide.bottom,
child: Text(
_bottomTileText(date),
style: const TextStyle(
height: 1.36,
fontSize: 10.0,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.left,
),
);
},
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
interval: verticalLabelInterval,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: AxisSide.bottom,
child: Text(
double.tryParse(meta.formattedValue) == minY || double.tryParse(meta.formattedValue) == maxY
? ''
: meta.formattedValue,
style: const TextStyle(
height: 1.36,
fontSize: 10.0,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.left,
),
);
},
),
),
),
borderData: FlBorderData(show: false),
minX: 0,
maxX: maxX,
minY: minY,
maxY: maxY,
lineBarsData: [
LineChartBarData(
spots: _generateFlSpots(),
isCurved: true,
barWidth: 2,
isStrokeCapRound: true,
dotData: FlDotData(
show: true,
),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: gradientColors.map((color) => color.withOpacity(0.2)).toList(),
),
),
),
],
),
),
),
);
}
List<FlSpot> _generateFlSpots() {
final List<FlSpot> flSpots = [];
int index = 0;
for (final entry in aggregatedChartData.entries) {
flSpots.add(FlSpot(index.toDouble(), entry.value));
index++;
}
return flSpots;
}
String _bottomTileText(DateTime date) {
const String formatPattern = 'dd.MM.yy';
return DateFormat(formatPattern).format(date);
}
double _getChartWidth() {
if (aggregatedChartData.length <= 10) {
return aggregatedChartData.length * 150;
} else {
return aggregatedChartData.length * (55);
}
}
}
@imaNNeo I've added more information.
In Flutter 3.10.5, the same thing happens
I ran the app and this is what I see: (It seems working well)
https://github.com/imaNNeo/fl_chart/assets/7009300/31a8fcdc-e0ac-487c-832f-b268b0a3e31b