|
|
|
|
@ -19,7 +19,7 @@ class DynamicResultChart extends StatelessWidget {
|
|
|
|
|
return FlSpot(entry.key.toDouble(), entry.value.value);
|
|
|
|
|
}).toList();
|
|
|
|
|
final widthPerPoint = 30.0; // Customize as needed
|
|
|
|
|
final chartWidth = (dataPoints.length+1) * widthPerPoint;
|
|
|
|
|
final chartWidth = (dataPoints.length + 1) * widthPerPoint;
|
|
|
|
|
|
|
|
|
|
return Material(
|
|
|
|
|
color: Colors.white,
|
|
|
|
|
@ -28,20 +28,37 @@ class DynamicResultChart extends StatelessWidget {
|
|
|
|
|
child: SingleChildScrollView(
|
|
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
width: MediaQuery.sizeOf(context).width,
|
|
|
|
|
width: MediaQuery.sizeOf(context).width - 77,
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.all(16.0),
|
|
|
|
|
padding: const EdgeInsets.only(top: 8.0, bottom: 8),
|
|
|
|
|
child: LineChart(
|
|
|
|
|
LineChartData(
|
|
|
|
|
minY: minY,
|
|
|
|
|
maxY: maxY,
|
|
|
|
|
minX : dataPoints.first.labelValue - 1 ,
|
|
|
|
|
maxX : dataPoints.first.labelValue + 1 ,
|
|
|
|
|
minX: dataPoints.first.labelValue - 1,
|
|
|
|
|
maxX: dataPoints.first.labelValue + 1,
|
|
|
|
|
lineTouchData:
|
|
|
|
|
LineTouchData(touchTooltipData: LineTouchTooltipData(
|
|
|
|
|
getTooltipItems: (touchedSpots) {
|
|
|
|
|
if (touchedSpots.isEmpty) return [];
|
|
|
|
|
|
|
|
|
|
// Only show tooltip for the first touched spot, hide others
|
|
|
|
|
return touchedSpots.map((spot) {
|
|
|
|
|
if (spot == touchedSpots.first) {
|
|
|
|
|
return LineTooltipItem(
|
|
|
|
|
'${spot.y}',
|
|
|
|
|
const TextStyle(color: Colors.white),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return null; // hides the rest
|
|
|
|
|
}).toList();
|
|
|
|
|
}
|
|
|
|
|
)),
|
|
|
|
|
titlesData: FlTitlesData(
|
|
|
|
|
leftTitles: AxisTitles(
|
|
|
|
|
sideTitles: SideTitles(
|
|
|
|
|
showTitles: true,
|
|
|
|
|
reservedSize: 70,
|
|
|
|
|
reservedSize: 77,
|
|
|
|
|
interval: .1, // Let fl_chart handle it
|
|
|
|
|
getTitlesWidget: (value, _) {
|
|
|
|
|
// print("the value is ======== ${value}");
|
|
|
|
|
@ -58,7 +75,10 @@ class DynamicResultChart extends StatelessWidget {
|
|
|
|
|
lineColor: Colors.transparent),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
var actualValue = (matchingThreshold.actualValue != null )?"'${matchingThreshold.label} (${matchingThreshold.actualValue})'":'${matchingThreshold.label}';
|
|
|
|
|
var actualValue = (matchingThreshold.actualValue !=
|
|
|
|
|
null)
|
|
|
|
|
? "${TranslationBase.of(context).getTranslation(matchingThreshold.label)} (${matchingThreshold.actualValue})"
|
|
|
|
|
: '${TranslationBase.of(context).getTranslation(matchingThreshold.label)}';
|
|
|
|
|
if (matchingThreshold.label.isNotEmpty) {
|
|
|
|
|
return Text(
|
|
|
|
|
actualValue,
|
|
|
|
|
@ -70,20 +90,26 @@ class DynamicResultChart extends StatelessWidget {
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
bottomTitles: AxisTitles(
|
|
|
|
|
axisNameSize: 60,
|
|
|
|
|
sideTitles: SideTitles(
|
|
|
|
|
showTitles: true,
|
|
|
|
|
reservedSize: 50,
|
|
|
|
|
getTitlesWidget: (value, _) {
|
|
|
|
|
if (value.toInt() >= 0 &&
|
|
|
|
|
value.toInt() < dataPoints.length) {
|
|
|
|
|
var label = dataPoints[value.toInt()].label;
|
|
|
|
|
if(dataPoints[value.toInt()].isStringResource)
|
|
|
|
|
{
|
|
|
|
|
label = TranslationBase.of(context).getTranslation(dataPoints[value.toInt()].label);
|
|
|
|
|
}
|
|
|
|
|
if (dataPoints[value.toInt()].isStringResource) {
|
|
|
|
|
label = TranslationBase.of(context)
|
|
|
|
|
.getTranslation(
|
|
|
|
|
dataPoints[value.toInt()].label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Text(
|
|
|
|
|
label,
|
|
|
|
|
style: const TextStyle(fontSize: 12),
|
|
|
|
|
return Padding(
|
|
|
|
|
padding: const EdgeInsets.only(top: 8.0),
|
|
|
|
|
child: Text(
|
|
|
|
|
label,
|
|
|
|
|
style: const TextStyle(fontSize: 12),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return const SizedBox.shrink();
|
|
|
|
|
@ -163,6 +189,7 @@ class DynamicResultChart extends StatelessWidget {
|
|
|
|
|
final List<FlSpot> allSpots = dataPoints.asMap().entries.map((entry) {
|
|
|
|
|
return FlSpot(entry.key.toDouble(), entry.value.value);
|
|
|
|
|
}).toList();
|
|
|
|
|
print("the spots are $allSpots");
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
...segments,
|
|
|
|
|
@ -236,12 +263,17 @@ final List<ThresholdRange> thresholdLevels = [
|
|
|
|
|
|
|
|
|
|
class DataPoint {
|
|
|
|
|
final double value;
|
|
|
|
|
double labelValue;
|
|
|
|
|
String label; // e.g., "This Result"
|
|
|
|
|
double labelValue;
|
|
|
|
|
String label; // e.g., "This Result"
|
|
|
|
|
final DateTime date;
|
|
|
|
|
bool isStringResource;
|
|
|
|
|
|
|
|
|
|
DataPoint({required this.value, required this.label, required this.date, this.isStringResource = false, this.labelValue = 0.0});
|
|
|
|
|
DataPoint(
|
|
|
|
|
{required this.value,
|
|
|
|
|
required this.label,
|
|
|
|
|
required this.date,
|
|
|
|
|
this.isStringResource = false,
|
|
|
|
|
this.labelValue = 0.0});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ThresholdRange {
|
|
|
|
|
@ -256,9 +288,7 @@ class ThresholdRange {
|
|
|
|
|
required this.value,
|
|
|
|
|
required this.color,
|
|
|
|
|
required this.lineColor,
|
|
|
|
|
this.actualValue
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.actualValue});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
String toString() {
|
|
|
|
|
|