-
Notifications
You must be signed in to change notification settings - Fork 814
feat: added csv functionalities in accelerometer screen. #2820
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
Conversation
Reviewer's GuideImplements CSV-based data recording/export in AccelerometerScreen with UI dialogs and navigation, refactors the logged data chart for multi-axis sensor support and dynamic scaling, extends the accelerometer provider to manage recordings, updates CSV storage path logic, and adjusts navigation parameters for logged data display. Sequence diagram for accelerometer data recording and CSV exportsequenceDiagram
actor User
participant AccelerometerScreen
participant AccelerometerStateProvider
participant CsvService
User->>AccelerometerScreen: Tap record button
AccelerometerScreen->>AccelerometerStateProvider: startRecording()
AccelerometerStateProvider-->>AccelerometerScreen: isRecording = true
AccelerometerStateProvider->>AccelerometerStateProvider: Collects sensor data
User->>AccelerometerScreen: Tap stop record button
AccelerometerScreen->>AccelerometerStateProvider: stopRecording()
AccelerometerStateProvider-->>AccelerometerScreen: Returns recorded data
AccelerometerScreen->>User: Show save file dialog
User->>AccelerometerScreen: Enter file name and confirm
AccelerometerScreen->>CsvService: saveCsvFile('accelerometer', fileName, data)
CsvService-->>AccelerometerScreen: File saved (or error)
AccelerometerScreen->>User: Show success/failure message
Entity relationship diagram for recorded accelerometer CSV dataerDiagram
ACCELEROMETER_RECORDINGS {
string Timestamp
string DateTime
double ReadingsX
double ReadingsY
double ReadingsZ
double Latitude
double Longitude
}
ACCELEROMETER_RECORDINGS ||..|| CSV_FILE : exported_to
Class diagram for updated AccelerometerStateProvider and CSV integrationclassDiagram
class AccelerometerStateProvider {
- AccelerometerEvent _accelerometerEvent
- StreamSubscription _accelerometerSubscription
- List<double> _xData
- List<double> _yData
- List<double> _zData
- double _xMin
- double _xMax
- double _yMin
- double _yMax
- double _zMin
- double _zMax
- bool _isRecording
- List<List<dynamic>> _recordedData
+ bool isRecording
+ void initializeSensors()
+ void disposeSensors()
+ void startRecording()
+ List<List<dynamic>> stopRecording()
+ List<FlSpot> getAxisData(String axis)
}
class CsvService {
+ Future<Directory> getInstrumentDirectory(String instrumentName)
+ Future<File?> saveCsvFile(String instrumentName, String fileName, List<List<dynamic>> data)
+ void writeMetaData(String instrumentName, List<List<dynamic>> data)
}
AccelerometerStateProvider -- CsvService : uses
Class diagram for updated LoggedDataChartScreen multi-axis supportclassDiagram
class LoggedDataChartScreen {
+ String fileName
+ List<List<dynamic>> data
+ String yAxisLabel
+ int xDataColumnIndex
+ int yDataColumnIndex
+ String? instrumentName
- String selectedAxis
- bool get _shouldShowAxisSelector
- int _getYDataColumnIndex()
- Widget _buildChart(...)
- Widget _sideTitleWidgets(...)
}
LoggedDataChartScreen <|-- StatefulWidget
LoggedDataChartScreen : +axis selector for accelerometer/gyroscope
LoggedDataChartScreen : +dynamic scaling and axis selection
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @Yugesh-Kumar-S - I've reviewed your changes - here's some feedback:
- Consider using Provider’s
create
constructor instead of manually instantiating and disposingAccelerometerStateProvider
in yourState
; that will simplify lifecycle management and avoid potential double-dispose issues. - The CSVService currently writes to external storage without guarding for platform differences or null paths—add proper permission checks and handle cases where
getExternalStorageDirectory()
might return null. - The chart range, padding, and interval calculations are fairly complex and partially duplicated—extract them into utility methods to make the rendering logic more concise and maintainable.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider using Provider’s `create` constructor instead of manually instantiating and disposing `AccelerometerStateProvider` in your `State`; that will simplify lifecycle management and avoid potential double-dispose issues.
- The CSVService currently writes to external storage without guarding for platform differences or null paths—add proper permission checks and handle cases where `getExternalStorageDirectory()` might return null.
- The chart range, padding, and interval calculations are fairly complex and partially duplicated—extract them into utility methods to make the rendering logic more concise and maintainable.
## Individual Comments
### Comment 1
<location> `lib/view/accelerometer_screen.dart:160` </location>
<code_context>
+ Future<void> _showSaveFileDialog(List<List<dynamic>> data) async {
</code_context>
<issue_to_address>
writeMetaData is called before saveCsvFile, but its result is not checked.
If writeMetaData can fail, handle its result or exceptions, or document why errors are ignored.
Suggested implementation:
```
Future<void> _showSaveFileDialog(List<List<dynamic>> data) async {
final TextEditingController filenameController = TextEditingController();
final String defaultFilename = '';
filenameController.text = defaultFilename;
final String? fileName = await showDialog<String>(
context: context,
builder: (context) {
return AlertDialog(
title: Text(appLocalizations.saveRecording),
content: TextField(
```
```
// Example: handle writeMetaData result before saving CSV file
// (Assuming writeMetaData returns a bool or throws on error)
Future<bool> writeMetaDataSafe() async {
try {
final result = await writeMetaData();
if (result == false) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(appLocalizations.metaDataWriteFailed),
backgroundColor: Colors.red,
),
);
return false;
}
return true;
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('${appLocalizations.metaDataWriteFailed}: $e'),
backgroundColor: Colors.red,
),
);
return false;
}
}
// Usage example:
// if (await writeMetaDataSafe()) {
// await saveCsvFile(data);
// }
}
```
- Replace the call to `writeMetaData` in your save logic with `await writeMetaDataSafe()`, and only proceed to `saveCsvFile` if it returns true.
- If `writeMetaData` has a different signature or error handling, adjust the helper accordingly.
- Add a localized string for `metaDataWriteFailed` if it does not exist.
</issue_to_address>
### Comment 2
<location> `lib/providers/accelerometer_state_provider.dart:103` </location>
<code_context>
}
+ void startRecording() {
+ _isRecording = true;
+ _recordedData = [
+ [
+ 'Timestamp',
+ 'DateTime',
+ 'ReadingsX',
+ 'ReadingsY',
+ 'ReadingsZ',
+ 'Latitude',
+ 'Longitude'
+ ]
+ ];
+ notifyListeners();
+ }
+
</code_context>
<issue_to_address>
Recording state is reset on every startRecording call.
If startRecording is called while already recording, existing data will be overwritten. Add a check to prevent this or document the intended behavior.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
void startRecording() {
_isRecording = true;
_recordedData = [
[
'Timestamp',
'DateTime',
'ReadingsX',
'ReadingsY',
'ReadingsZ',
'Latitude',
'Longitude'
]
];
notifyListeners();
}
=======
/// Starts recording accelerometer data.
/// If already recording, this method does nothing.
void startRecording() {
if (_isRecording) {
// Already recording; do not reset data.
return;
}
_isRecording = true;
_recordedData = [
[
'Timestamp',
'DateTime',
'ReadingsX',
'ReadingsY',
'ReadingsZ',
'Latitude',
'Longitude'
]
];
notifyListeners();
}
>>>>>>> REPLACE
</suggested_fix>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Build successful. APKs to test: https://github.com/fossasia/pslab-app/actions/runs/17009089034/artifacts/3780230251 |
Fixes #2819
Changes
Screenshots / Recordings
screen-20250807-194948.mp4
Checklist:
strings.xml
,dimens.xml
andcolors.xml
without hard coding any value.strings.xml
,dimens.xml
orcolors.xml
.Summary by Sourcery
Enable CSV recording and export of accelerometer readings, integrate UI controls for recording and saving, and enhance logged-data screens and chart rendering for multi-axis instruments
New Features:
Enhancements: