1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Flutter] "Flutter: Previous week's performance bar not displaying in bar chart with SQFlite...

Discussão em 'Mobile' iniciado por Stack, Setembro 10, 2024.

  1. Stack

    Stack Membro Participativo

    I am working a habit tracker app using flutter with sqflite where if the task is checked then it shows the task completing bar in the bar graph when ever i opened the same task by clicking on it another day the bar will automatically should display the bar for that particular task but i am trying to display the previous week bar but i am not able to displaying the previous week performance bar as well as the previous day bar also not displaying in some of the tasks when i clcik on same task next day it just only shows for current day progress bar .i want that whenever i swipe left the previous week days task perfomance should display in the bar graph as bar in blue color,The main problem i am facing in the two methods which may be fetchProgressDataForPreviousWeek and fetchProgressDataForWeek. kindly help me .thanks


    • task has been added from habit screen and display in a listview format in the habitscreen


    • after clciking on particular task in habit screen navigate to Taskscreen in which performance of the task is displayed wth of bar in a bar graph


    • I used getx state management

    TaskScreen.dart

    '''//TaskScreen.dart

    class TaskScreen extends StatelessWidget {
    final String taskName;
    final bool isTaskChecked;

    TaskScreen({required this.taskName, required this.isTaskChecked});

    @override
    Widget build(BuildContext context) {
    final TaskController taskController = Get.find();

    return Scaffold(
    appBar: AppBar(
    title: Text("Task Details"),
    backgroundColor: Colors.blue,
    ),
    body: PageView(
    children: [
    // Current Week Graph
    FutureBuilder<List<double>>(
    future: taskController.fetchProgressDataForWeek(taskName),
    builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
    return Center(child: CircularProgressIndicator());
    } else if (snapshot.hasError) {
    return Center(child: Text('Error: ${snapshot.error}'));
    } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
    return Center(child: Text('No data available for this week'));
    }

    if (!isTaskChecked) {
    return Center(child: Text('No data available for this task.'));
    }

    final dailyProgress = snapshot.data!;
    final daysOfWeek = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
    final today = DateTime.now();
    final currentDayIndex = (today.weekday - DateTime.monday + 7) % 7;

    final progressData = List<double>.filled(7, 0.0);
    for (int i = 0; i < dailyProgress.length; i++) {
    progressData = dailyProgress;
    }

    final barGroups = progressData.asMap().entries.map((entry) {
    int index = entry.key;
    double value = entry.value;
    Color barColor = Colors.blue;
    double barHeight = value;

    if (index < currentDayIndex) {
    if (value == 0.0) {
    barColor = Colors.grey;
    barHeight = 0.2;
    } else {
    barColor = Colors.blue;
    barHeight = value;
    }
    } else if (index > currentDayIndex) {
    // Future days should not be shown
    barColor = Colors.transparent;
    barHeight = 0.0;
    }

    return BarChartGroupData(
    x: index,
    barRods: [
    BarChartRodData(
    toY: barHeight,
    color: barColor,
    width: 20,
    borderRadius: BorderRadius.circular(4),
    ),
    ],
    );
    }).toList();

    return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
    Text(
    'Current Week',
    style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
    ),
    ),
    SizedBox(height: 20),
    Container(
    height: 300,
    child: BarChart(
    BarChartData(
    alignment: BarChartAlignment.spaceAround,
    maxY: progressData.isNotEmpty ? progressData.reduce((a, b) => a > b ? a : b) + 1 : 1,
    barGroups: barGroups,
    titlesData: FlTitlesData(
    bottomTitles: AxisTitles(
    sideTitles: SideTitles(
    showTitles: true,
    reservedSize: 40,
    getTitlesWidget: (value, meta) {
    final dayLabel = daysOfWeek[value.toInt() % 7];
    return SideTitleWidget(
    axisSide: meta.axisSide,
    child: Text(dayLabel, style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
    );
    },
    ),
    ),
    leftTitles: AxisTitles(
    sideTitles: SideTitles(
    showTitles: true,
    reservedSize: 40,
    getTitlesWidget: (value, meta) {
    return SideTitleWidget(
    axisSide: meta.axisSide,
    child: Text('${value.toInt()}', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
    );
    },
    ),
    ),
    ),
    borderData: FlBorderData(
    show: true,
    border: Border.all(color: const Color(0xff37434d), width: 1),
    ),
    gridData: FlGridData(show: true),
    ),
    ),
    ),
    ],
    );
    },
    ),
    // Previous Week Graph
    FutureBuilder<List<double>>(
    future: taskController.fetchProgressDataForPreviousWeek(taskName),
    builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
    return Center(child: CircularProgressIndicator());
    } else if (snapshot.hasError) {
    return Center(child: Text('Error: ${snapshot.error}'));
    } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
    return Center(child: Text('No data available for the previous week'));
    }

    if (!isTaskChecked) {
    return Center(child: Text('No data available for this task.'));
    }

    final dailyProgress = snapshot.data!;
    final daysOfWeek = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];


    final progressData = List<double>.filled(7, 0.0);
    for (int i = 0; i < dailyProgress.length; i++) {
    progressData = dailyProgress;
    }

    final barGroups = progressData.asMap().entries.map((entry) {
    int index = entry.key;
    double value = entry.value;
    Color barColor = value == 1.0 ? Colors.blue : Colors.grey;
    double barHeight = value == 1.0 ? 1.0 : 0.1;

    return BarChartGroupData(
    x: index,
    barRods: [
    BarChartRodData(
    toY: barHeight,
    color: barColor,
    width: 20,
    borderRadius: BorderRadius.circular(4),
    ),
    ],
    );
    }).toList();

    return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
    Text(
    'Previous Week',
    style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
    ),
    ),
    SizedBox(height: 20),
    Container(
    height: 300,
    child: BarChart(
    BarChartData(
    alignment: BarChartAlignment.spaceAround,
    maxY: progressData.isNotEmpty ? progressData.reduce((a, b) => a > b ? a : b) + 1 : 1,
    barGroups: barGroups,
    titlesData: FlTitlesData(
    bottomTitles: AxisTitles(
    sideTitles: SideTitles(
    showTitles: true,
    reservedSize: 40,
    getTitlesWidget: (value, meta) {
    final dayLabel = daysOfWeek[value.toInt() % 7];
    return SideTitleWidget(
    axisSide: meta.axisSide,
    child: Text(dayLabel, style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
    );
    },
    ),
    ),
    leftTitles: AxisTitles(
    sideTitles: SideTitles(
    showTitles: true,
    reservedSize: 40,
    getTitlesWidget: (value, meta) {
    return SideTitleWidget(
    axisSide: meta.axisSide,
    child: Text('${value.toInt()}', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
    );
    },
    ),
    ),
    ),
    borderData: FlBorderData(
    show: true,
    border: Border.all(color: const Color(0xff37434d), width: 1),
    ),
    gridData: FlGridData(show: true),
    ),
    ),
    ),
    ],
    );
    },
    ),
    ],
    ),
    );
    }
    }'''


    DatabaseHelper.dart

    '''
    import 'package:intl/intl.dart';
    import 'package:sqflite/sqflite.dart';
    import 'package:path/path.dart';

    class DatabaseHelper {
    static final DatabaseHelper _instance = DatabaseHelper._internal();
    factory DatabaseHelper() => _instance;
    DatabaseHelper._internal();

    static Database? _database;

    // Static constants for table and column names
    static const String _tableTasks = 'tasks';
    static const String _columnId = 'id';
    static const String _columnTask = 'task';
    static const String _columnIsChecked = 'is_checked';
    static const String _columnProgress = 'progress';
    static const String _columnCreatedDate = 'created_date';

    Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDatabase();
    return _database!;
    }

    Future<Database> _initDatabase() async {
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, 'tasks.db');

    return await openDatabase(
    path,
    version: 1,
    onCreate: (db, version) async {
    await db.execute('''
    CREATE TABLE $_tableTasks (
    $_columnId INTEGER PRIMARY KEY AUTOINCREMENT,
    $_columnTask TEXT UNIQUE,
    $_columnIsChecked INTEGER,
    $_columnProgress REAL,
    $_columnCreatedDate TEXT
    )
    ''');
    },
    );
    }

    Future<List<Map<String, dynamic>>> getTasks() async {
    final db = await database;
    return await db.query(_tableTasks);
    }

    Future<int?> insertTask(
    String task, bool isChecked, double progress, String createdDate) async {
    final db = await database;
    try {
    return await db.insert(
    _tableTasks,
    {
    _columnTask: task,
    _columnIsChecked: isChecked ? 1 : 0,
    _columnProgress: progress,
    _columnCreatedDate: createdDate,
    },
    conflictAlgorithm: ConflictAlgorithm.ignore,
    );
    } catch (e) {
    print("Error inserting task: $e");
    return null;
    }
    }

    Future<int> deleteTask(String task) async {
    final db = await database;
    return await db.delete(
    _tableTasks,
    where: '$_columnTask = ?',
    whereArgs: [task],
    );
    }

    Future<int> updateTask(String oldTask, String newTask, bool isChecked,
    double progress, String updatedDate) async {
    final db = await database;
    return await db.update(
    _tableTasks,
    {
    _columnTask: newTask,
    _columnIsChecked: isChecked ? 1 : 0,
    _columnProgress: progress,
    _columnCreatedDate: updatedDate,
    },
    where: '$_columnTask = ?',
    whereArgs: [oldTask],
    );
    }

    Future<List<Map<String, dynamic>>> getTaskProgressForRange(
    String taskName, String startDate, String endDate) async {
    final db = await database;
    final results = await db.query(
    _tableTasks,
    where: '$_columnTask = ? AND $_columnCreatedDate BETWEEN ? AND ?',
    whereArgs: [taskName, startDate, endDate],
    );
    //final progressData = await getTaskProgressForRange(taskName, startDate, endDate);
    print('Queried Data: $results');
    return results;
    }

    Future<List<double>> fetchProgressDataForWeek(String taskName) async {
    final now = DateTime.now();
    final currentWeekday = now.weekday;

    // Calculate the start and end of the week (Monday to Sunday)
    final startOfWeek =
    now.subtract(Duration(days: currentWeekday - DateTime.monday));
    final endOfWeek = now.add(Duration(days: DateTime.sunday - currentWeekday));

    final startDate = DateFormat('yyyy-MM-dd').format(startOfWeek);
    final endDate = DateFormat('yyyy-MM-dd').format(endOfWeek);

    print('Fetching data from $startDate to $endDate');

    try {
    final progressData =
    await getTaskProgressForRange(taskName, startDate, endDate);

    // Initialize result list with zeros for all 7 days
    final result = List<double>.filled(7, 0.0);

    // Populate result list with actual data
    if (progressData.isNotEmpty) {
    for (var entry in progressData) {
    final dateString = entry[_columnCreatedDate] as String?;
    final progressValue = entry[_columnProgress] as double?;

    if (dateString != null && progressValue != null) {
    final date = DateTime.parse(dateString).toLocal();
    final dayOfWeek = (date.weekday - DateTime.monday + 7) %
    7; // Adjust to match Monday start
    if (dayOfWeek >= 0 && dayOfWeek < 7) {
    result[dayOfWeek] = progressValue;
    }
    }
    }
    } else {
    print('No progress data found for the specified range.');
    }

    // current day's bar is visible with the correct progress
    final currentDayIndex = (now.weekday - DateTime.monday + 7) % 7;
    if (result[currentDayIndex] == 0.0) {
    result[currentDayIndex] = 1.0; // current day's bar shows 1.0 progress if the task is completed
    }

    print('Progress Data for the Week: $result');
    return result;
    } catch (e) {
    print('Error fetching progress data: $e');
    return List<double>.filled(7, 0.0);
    }
    }

    Future<List<double>> fetchProgressDataForPreviousWeek(String taskName) async {
    final now = DateTime.now();
    final currentWeekday = now.weekday;

    // current week monday
    final mondayOfCurrentWeek = now.subtract(Duration(days: (currentWeekday - 1) % 7));

    // Calculate Start and End of Previous Week
    final startOfPreviousWeek = mondayOfCurrentWeek.subtract(Duration(days: 7));
    final endOfPreviousWeek = mondayOfCurrentWeek.subtract(Duration(days: 1));


    final startDate = DateFormat('yyyy-MM-dd').format(startOfPreviousWeek);
    final endDate = DateFormat('yyyy-MM-dd').format(endOfPreviousWeek);
    print('Monday of Current Week: $mondayOfCurrentWeek');
    print('Start of Previous Week: $startOfPreviousWeek');
    print('End of Previous Week: $endOfPreviousWeek');

    print('Fetching data from $startDate to $endDate');

    try {
    final progressData =
    await getTaskProgressForRange(taskName, startDate, endDate);

    print('Fetched Data: $progressData');

    final result = List<double>.filled(7, 0.0);

    if (progressData.isNotEmpty) {
    for (var entry in progressData) {
    final dateString = entry[_columnCreatedDate] as String?;
    final progressValue = entry[_columnProgress] as double?;

    print('Date String: $dateString, Progress Value: $progressValue');

    if (dateString != null && progressValue != null) {
    final date = DateTime.parse(dateString).toLocal();
    final dayOfWeek = (date.weekday - DateTime.monday + 7) % 7; // Adjust to match Monday start
    print('Day of Week: $dayOfWeek');
    if (dayOfWeek >= 0 && dayOfWeek < 7) {
    result[dayOfWeek] = progressValue;
    }
    }
    }
    } else {
    print('No progress data found for the specified range.');
    }

    print('Progress Data for the Previous Week: $result');
    return result;
    } catch (e) {
    print('Error fetching progress data: $e');
    return List<double>.filled(7, 0.0);
    }
    }
    }
    '''


    TaskController.dart

    '''
    import 'package:get/get.dart';
    import '../database/dbhelper.dart';

    class TaskController extends GetxController {
    final DatabaseHelper _databaseHelper = DatabaseHelper();
    var taskList = <String>[].obs;
    var isTaskSelected = <bool>[].obs;

    @override
    void onInit() {
    super.onInit();
    loadTasks();
    }

    void loadTasks() async {
    try {
    final tasks = await _databaseHelper.getTasks();
    taskList.value = tasks.map((task) => task['task'] as String).toList();
    isTaskSelected.value = tasks.map((task) {
    final isChecked = task['is_checked'];
    return (isChecked != null && (isChecked as int) == 1);
    }).toList();
    } catch (e) {
    print("Error loading tasks: $e");
    }
    }

    void addTask(String task) async {
    try {
    bool isChecked = false;
    double progress = 0.0;
    String createdDate = DateTime.now().toIso8601String();

    int? result = await _databaseHelper.insertTask(
    task, isChecked, progress, createdDate);
    if (result == null) {
    print("Task already exists");
    } else {
    print("Task added successfully");
    loadTasks();
    }
    } catch (e) {
    print("Error adding task: $e");
    }
    }

    void deleteTask(int index) async {
    try {
    String taskToDelete = taskList[index];
    await _databaseHelper.deleteTask(taskToDelete);
    taskList.removeAt(index);
    isTaskSelected.removeAt(index);
    } catch (e) {
    print("Error deleting task: $e");
    }
    }

    Future<void> toggleTaskSelection(int index, bool value) async {
    try {
    if (index < 0 || index >= taskList.length) {
    throw ArgumentError("Index out of range");
    }

    String taskToUpdate = taskList[index];
    double progress = value ? 1.0 : 0.0;
    String updatedDate = DateTime.now().toIso8601String();

    isTaskSelected[index] = value;
    await _databaseHelper.updateTask(
    taskToUpdate, taskToUpdate, value, progress, updatedDate);
    print("Task updated successfully");
    } catch (e) {
    print("Error toggling task selection: $e");
    }
    }

    Future<List<double>> fetchProgressDataForWeek(String taskName) async {
    try {
    print("Fetching progress data for the week for task: $taskName");
    final progressData =
    await _databaseHelper.fetchProgressDataForWeek(taskName);
    print("Fetched weekly progress data: $progressData");
    return progressData;
    } catch (e) {
    print("Error fetching weekly progress data: $e");
    return List<double>.filled(7, 0.0);
    }
    }

    Future<List<double>> fetchProgressDataForPreviousWeek(String taskName) async {
    try {
    print("Fetching progress data for the previous week for task: $taskName");
    final progressData =
    await _databaseHelper.fetchProgressDataForPreviousWeek(taskName);
    print("Fetched previous week's progress data: $progressData");
    return progressData;
    } catch (e) {
    print("Error fetching previous week's progress data: $e");
    return List<double>.filled(7, 0.0);
    }
    }
    }
    '''


    HabitScreen.dart

    '''
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    import 'package:goalsync/controller/task_controller.dart';
    import 'package:goalsync/screens/task_screen.dart';

    class HabitScreen extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    final TaskController taskController = Get.find();

    return Scaffold(
    appBar: _appBar(),
    body: Column(
    children: [
    Padding(
    padding: const EdgeInsets.all(17.0),
    child: Row(
    children: [],
    ),
    ),
    Expanded(
    child: Obx(() {
    if (taskController.isTaskSelected.length < taskController.taskList.length) {
    taskController.isTaskSelected.addAll(
    List.generate(
    taskController.taskList.length - taskController.isTaskSelected.length,
    (_) => false,
    ),
    );
    }

    return ListView.builder(
    itemCount: taskController.taskList.length,
    itemBuilder: (context, index) {
    return Dismissible(
    key: ValueKey(taskController.taskList[index]),
    background: Container(
    color: Colors.blue.shade300,
    child: Icon(Icons.delete_outline, size: 35),
    alignment: Alignment.centerRight,
    padding: EdgeInsets.symmetric(horizontal: 20),
    ),
    direction: DismissDirection.endToStart,
    onDismissed: (direction) {
    taskController.deleteTask(index);
    },
    child: Padding(
    padding: const EdgeInsets.symmetric(horizontal: 16),
    child: GestureDetector(
    onTap: () {
    Get.to(TaskScreen(
    taskName: taskController.taskList[index],
    isTaskChecked: taskController.isTaskSelected[index],

    ));
    },
    child: Container(
    margin: EdgeInsets.symmetric(vertical: 5.0),
    padding: EdgeInsets.all(6.0),
    decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(12),
    border: Border.all(color: Colors.black54, width: 2),
    ),
    child: Row(
    children: [
    Expanded(
    child: Text(
    taskController.taskList[index],
    style: TextStyle(color: Colors.black, fontSize: 18),
    ),
    ),
    Checkbox(
    value: taskController.isTaskSelected[index],
    onChanged: (bool? value) {
    if (value != null) {
    taskController.toggleTaskSelection(index, value);
    }
    },
    activeColor: Colors.blue,
    checkColor: Colors.white,
    ),
    ],
    ),
    ),
    ),
    ),
    );
    },
    );
    }),
    )
    ],
    ),
    );
    }

    AppBar _appBar() {
    return AppBar(
    title: Text("Habit Screen"),
    backgroundColor: Colors.blue,
    actions: [
    TextButton(
    onPressed: () {
    _showAddTaskDialog();
    },
    child: Text(
    'Add Task',
    style: TextStyle(
    color: Colors.black,
    fontSize: 16,
    ),
    ),
    ),
    ],
    );
    }

    void _showAddTaskDialog() {
    final TaskController taskController = Get.find();
    final TextEditingController taskControllerInput = TextEditingController();

    showDialog(
    context: Get.context!,
    builder: (BuildContext context) {
    return AlertDialog(
    title: Text('Add New Task'),
    content: Column(
    mainAxisSize: MainAxisSize.min,
    children: [
    TextField(
    controller: taskControllerInput,
    decoration: InputDecoration(hintText: 'Enter task'),
    autofocus: true,
    ),

    ],
    ),
    actions: [
    TextButton(
    onPressed: () {
    final task = taskControllerInput.text.trim();
    if (task.isNotEmpty) {
    taskController.addTask(task);
    }
    Get.back(); // Close the dialog
    },
    child: Text('Save'),
    ),
    TextButton(
    onPressed: () {
    Get.back(); // Close the dialog
    },
    child: Text('Cancel'),
    ),
    ],
    );
    },
    );
    }
    }
    '''

    Continue reading...

Compartilhe esta Página