Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vis #666

Closed
wants to merge 1 commit into from
Closed

vis #666

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 60;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -491,7 +491,7 @@
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = PG566C9XUK;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.14;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -676,7 +676,7 @@
DEVELOPMENT_TEAM = PG566C9XUK;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.14;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -704,7 +704,7 @@
DEVELOPMENT_TEAM = PG566C9XUK;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.14;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
17 changes: 17 additions & 0 deletions app/lib/screens/study/report/sections/average_section_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import 'package:studyu_app/screens/study/report/util/plot_utilities.dart';
import 'package:studyu_app/theme.dart';
import 'package:studyu_app/util/data_processing.dart';
import 'package:studyu_core/core.dart';
import 'results_descriptive_statistics.dart';
import 'results_gauge.dart';
import 'results_textual_summary.dart';

class AverageSectionWidget extends ReportSectionWidget {
final AverageSection section;
Expand All @@ -15,6 +18,8 @@ class AverageSectionWidget extends ReportSectionWidget {

@override
Widget build(BuildContext context) {
ValueNotifier<bool> showDescriptionNotifier = ValueNotifier(false);

final data = getAggregatedData().toList();
final taskTitle = subject.study.observations
.firstWhereOrNull(
Expand All @@ -32,8 +37,20 @@ class AverageSectionWidget extends ReportSectionWidget {
.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
const TextualSummaryWidget(), //Row 2
const SizedBox(height: 8),
const GaugeTitleWidget(), //Row 3
const SizedBox(height: 8),
const GaugesWidget(), //Row 4
const SizedBox(height: 8),
getLegend(context, data),
const SizedBox(height: 8),
ExpansionTile(
title: Text('Descriptive Statistics'),
children: [
DescriptiveStatisticsWidget(),
],
),
AspectRatio(aspectRatio: 1.5, child: getDiagram(context, data)),
],
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import 'package:flutter/material.dart';

// Row 6: Descriptive Statistics
class DescriptiveStatisticsWidget extends StatelessWidget {

const DescriptiveStatisticsWidget({super.key});

@override
Widget build(BuildContext context) {
return GestureDetector(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Icon(
true ? Icons.arrow_drop_up : Icons.arrow_drop_down,
),
],
),
if (true)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Column(
children: [
_buildStatisticsTable(),
const Padding(
padding: EdgeInsets.only(top: 8.0),
child: Text(
'p-value: 0.01\nLevel of significance: α = 0.05',
style: TextStyle(fontSize: 8, color: Colors.black),
textAlign: TextAlign.center,
),
),
],
),
),
],
),
);
}

Widget _buildStatisticsTable() {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: Table(
border: TableBorder.all(color: Colors.grey),
columnWidths: const {
0: FixedColumnWidth(65),
1: FixedColumnWidth(65),
2: FixedColumnWidth(50),
3: FixedColumnWidth(50),
4: FixedColumnWidth(50),
5: FixedColumnWidth(65),
},
children: [
_buildTableRow(
['Intervention', 'Observations', 'Average', 'Min', 'Max', 'Variance'],
isHeader: true,
),
_buildTableRow(['Tea', '14', '5.0', '4', '3', '1.2']),
_buildTableRow(['No Tea', '14', '7.5', '8', '6', '2']),
],
),
);
}

TableRow _buildTableRow(List<String> cells, {bool isHeader = false}) {
return TableRow(
children: cells.map((cell) {
return _buildTableCell(cell, isHeader: isHeader);
}).toList(),
);
}

Widget _buildTableCell(String text, {bool isHeader = false}) {
return Padding(
padding: const EdgeInsets.all(6.0),
child: Text(
text,
style: TextStyle(
fontSize: isHeader ? 8 : 8,
fontWeight: isHeader ? FontWeight.bold : FontWeight.normal,
color: isHeader ? Colors.black : Colors.grey[800],
),
textAlign: TextAlign.center,
),
);
}
}
125 changes: 125 additions & 0 deletions app/lib/screens/study/report/sections/results_gauge.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_gauges/gauges.dart';

// Row 3: Gauge title
class GaugeTitleWidget extends StatelessWidget {
const GaugeTitleWidget({super.key});

@override
Widget build(BuildContext context) {
return const Center(
child: Text(
'Average Sleep Quality',
style: TextStyle(fontSize: 16, color: Colors.blueAccent),
),
);
}
}

// Row 4: Two gauges
class GaugesWidget extends StatelessWidget {
const GaugesWidget({super.key});

@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Container(
width: 140, // Set the desired width
height: 140, // Set the desired height
child: createGauge(0, 10, 10, 5), // min, max, steps, value
),
Text('With Tea', style: TextStyle(fontSize: 14)),
],
),
),
Expanded(
child: Column(
children: <Widget>[
Container(
width: 140, // Set the desired width
height: 140, // Set the desired height
child: createGauge(0, 10, 10, 7.5), // min, max, steps, value
),
Text('Without Tea', style: TextStyle(fontSize: 14)),
],
),
),
],
);
}

// Create gauge with min and max values, steps to switch colors, value to point at
Widget createGauge(double min, double max, int steps, double value) {
// List of colors
List<Color> colors = [
Colors.red[900]!,
Colors.red[700]!,
Colors.red[500]!,
Colors.orange[900]!,
Colors.orange[700]!,
Colors.yellow[700]!,
Colors.yellow[500]!,
Colors.green[300]!,
Colors.green[500]!,
Colors.green[700]!
];

// Create gauge ranges based on steps and the color list
List<GaugeRange> createRanges() {
double stepValue = (max - min) / steps;
return List.generate(steps, (index) {
double start = min + (index * stepValue);
double end = start + stepValue;
return GaugeRange(
startValue: start,
endValue: end,
color: colors[index],
);
});
}

return SfRadialGauge(
axes: <RadialAxis>[
RadialAxis(
minimum: min,
maximum: max,
pointers: <GaugePointer>[
NeedlePointer(
value: value,
needleColor: Colors.blue,
needleEndWidth: 7,
),
],
ranges: createRanges(),
annotations: <GaugeAnnotation>[
GaugeAnnotation(
widget: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '$value',
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.blue),
),
TextSpan(
text: '/$max',
style: const TextStyle(fontSize: 10, color: Colors.blue),
),
],
),
),
angle: 90,
positionFactor: 0.8,
),
],
),
],
);
}
}
82 changes: 82 additions & 0 deletions app/lib/screens/study/report/sections/results_textual_summary.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
// Row 2: Textual Summary

class TextualSummaryWidget extends StatelessWidget {
const TextualSummaryWidget({super.key});

@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(12.0),
),
child: const Column(
children: <Widget>[
Text(
'With tea',
style: TextStyle(
fontSize: 16,
color: Colors.green,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4), // SizedBox for spacing
Text(
'Your sleep quality was slightly better', // Text 1 for box 1
style: TextStyle(
fontSize: 12,
color: Colors.black,
),
),
],
),
),
],
),
),
Expanded(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(12.0),
),
child: const Column(
children: <Widget>[
Text(
'Without tea',
style: TextStyle(
fontSize: 16,
color: Colors.red,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4), // SizedBox for spacing
Text(
'Your sleep quality was slightly worse', // Text 2 for box 2
style: TextStyle(
fontSize: 12,
color: Colors.black,
),
),
],
),
),
],
),
),
],
);
}
}
Loading
Loading