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

Question / Need help #2136

Open
Welnnys opened this issue Oct 17, 2024 · 2 comments
Open

Question / Need help #2136

Welnnys opened this issue Oct 17, 2024 · 2 comments
Labels
charts Charts component open Open

Comments

@Welnnys
Copy link

Welnnys commented Oct 17, 2024

Is there a way to reverse the order of the labels on the right side without reversing the order of the circles and if possible to also keep the default legend icons (those little clickable circles)?

// overview_model.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:intl/intl.dart';

class OverviewModel {
final String userUID;

OverviewModel(this.userUID);

Future<List> fetchActivityCounts() async {
final now = DateTime.now();
final currentMonthYear = DateFormat('MM-yyyy').format(now);

final querySnapshot = await FirebaseFirestore.instance
    .collection('users')
    .doc(userUID)
    .collection(currentMonthYear)
    .where('ActivityName', isNotEqualTo: null)
    .where('ActivityName', isNotEqualTo: 'placeholder')
    .get();

if (querySnapshot.docs.isEmpty) {
  return generateExampleChartData();
}

Map<String, int> activityCounts = {};
for (var doc in querySnapshot.docs) {
  final activityName = doc['ActivityName'] as String;
  activityCounts[activityName] = (activityCounts[activityName] ?? 0) + 1;
}

List<ChartData> chartData = [];
activityCounts.forEach((activity, count) {
  final formattedTime = '$count $activity records';
  chartData.add(ChartData(activity, count.toDouble(), formattedTime));
});

chartData.sort((a, b) => b.value.compareTo(a.value));
chartData = chartData.take(5).toList();
chartData = chartData.reversed.toList();

return chartData;

}

Future<List> fetchTotalActivityTime() async {
final now = DateTime.now();
final currentMonthYear = DateFormat('MM-yyyy').format(now);

final querySnapshot = await FirebaseFirestore.instance
    .collection('users')
    .doc(userUID)
    .collection(currentMonthYear)
    .where('ActivityName', isNotEqualTo: null)
    .where('ActivityName', isNotEqualTo: 'placeholder')
    .get();

if (querySnapshot.docs.isEmpty) {
  return generateExampleChartData();
}

Map<String, double> activityTimes = {};
for (var doc in querySnapshot.docs) {
  final activityName = doc['ActivityName'] as String;
  final int activityTime = doc['ActivityTime'] as int;
  double activityTimeInHours = activityTime / 60.0;

  activityTimes[activityName] =
      (activityTimes[activityName] ?? 0) + activityTimeInHours;
}

List<ChartData> chartData = [];
activityTimes.forEach((activity, time) {
  final hours = time.floor();
  final minutes = ((time - hours) * 60).toInt();
  final formattedTime = '$hours hours $minutes minutes';
  chartData.add(ChartData(activity, time, formattedTime));
});

chartData.sort((a, b) => b.value.compareTo(a.value));
chartData = chartData.take(5).toList();
chartData = chartData.reversed.toList();

return chartData;

}

Future<List<Map<String, dynamic>>> fetchPersonalBestActivities(
List sortedActivityTypes) async {
List allActivityTypes = [
'Running',
'Cycling',
'Walking',
'Swimming',
'Volleyball',
'Bouldering',
'Football',
'Basketball',
'Fitness',
];

List<Map<String, dynamic>> allActivities = [];
for (String activityType in allActivityTypes) {
  final querySnapshot = await FirebaseFirestore.instance
      .collection('users')
      .doc(userUID)
      .collection(activityType)
      .orderBy('steps', descending: true)
      .limit(1)
      .get();

  if (querySnapshot.docs.isNotEmpty) {
    final bestActivity = querySnapshot.docs.first.data();
    bestActivity['docId'] = querySnapshot.docs.first.id;
    bestActivity['activityType'] = activityType;
    allActivities.add(bestActivity);
  }
}

List<Map<String, dynamic>> chartActivities = [];
List<Map<String, dynamic>> nonChartActivities = [];

for (var activity in allActivities) {
  if (sortedActivityTypes.contains(activity['activityType'])) {
    chartActivities.add(activity);
  } else {
    nonChartActivities.add(activity);
  }
}

chartActivities.sort((a, b) {
  String typeA = a['activityType'];
  String typeB = b['activityType'];
  return sortedActivityTypes
      .indexOf(typeA)
      .compareTo(sortedActivityTypes.indexOf(typeB));
});

chartActivities = chartActivities.reversed.toList();

return [...chartActivities, ...nonChartActivities];

}

List generateExampleChartData() {
List exampleData = [
ChartData('Example 1', 3, 'No Data'),
ChartData('Example 2', 5, 'No Data'),
ChartData('Example 3', 10, 'No Data'),
ChartData('Example 4', 15, 'No Data'),
ChartData('Example 5', 20, 'No Data'),
];

return exampleData;

}
}

class ChartData {
ChartData(this.category, this.value, this.formattedTime);
final String category;
final double value;
final String formattedTime;
}


// overview_page.dart

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:sporti_angel_kolev/models/overview_model.dart';
import 'package:sporti_angel_kolev/controllers/overview_controller.dart';
import 'package:sporti_angel_kolev/common/activity_list_widget.dart';
import 'package:sporti_angel_kolev/common/profile_picture.dart';
import 'package:sporti_angel_kolev/common/user_information.dart';

class OverviewPage extends StatefulWidget {
const OverviewPage({super.key});

@OverRide
_OverviewPageState createState() => _OverviewPageState();
}

class _OverviewPageState extends State {
bool showTotalActivityTime = true;
late OverviewController _controller;

@OverRide
void initState() {
super.initState();
final userUID = UserInformation().userUID;
_controller = OverviewController(OverviewModel(userUID));
}

@OverRide
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
surfaceTintColor: Colors.white,
title: const Text(
'Overview',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
centerTitle: true,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
actions: const [ProfilePicture()],
),
body: Center(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: () {
setState(() {
showTotalActivityTime = !showTotalActivityTime;
});
},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
vertical: 15.0, horizontal: 30.0),
backgroundColor: Colors.redAccent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
elevation: 5,
shadowColor: Colors.black,
),
child: Text(
showTotalActivityTime
? 'Monthly Activity Count'
: 'Monthly Total Activity Time',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
),
Expanded(
child: Column(
children: [
Flexible(
child: FutureBuilder<List>(
future: showTotalActivityTime
? _controller.fetchTotalActivityTime()
: _controller.fetchActivityCounts(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(
Colors.red)));
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
final chartData = snapshot.data ?? [];

                      List<String> sortedActivityTypes =
                          chartData.map((data) => data.category).toList();

                      return Column(
                        children: [
                          SfCircularChart(
                            centerX: '130',
                            legend: const Legend(
                                isVisible: true,
                                position: LegendPosition.right),
                            series: <CircularSeries>[
                              RadialBarSeries<ChartData, String>(
                                dataSource: chartData,
                                xValueMapper: (ChartData data, _) =>
                                    data.category,
                                yValueMapper: (ChartData data, _) =>
                                    data.value,
                                dataLabelMapper: (ChartData data, _) =>
                                    data.formattedTime,
                                dataLabelSettings: const DataLabelSettings(
                                    isVisible: true),
                                trackBorderWidth: 2,
                                gap: '17%',
                                innerRadius: '10%',
                              ),
                            ],
                          ),
                          Expanded(
                            child: SingleChildScrollView(
                              child: ActivityListWidget(
                                fetchActivities: () =>
                                    _controller.fetchPersonalBestActivities(
                                        sortedActivityTypes),
                                onActivityDeleted: () {
                                  setState(() {});
                                },
                                centerEmptyMessage: false,
                              ),
                            ),
                          ),
                        ],
                      );
                    }
                  },
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  ),
);

}
}

image

@VijayakumarMariappan VijayakumarMariappan added charts Charts component open Open labels Oct 18, 2024
@Welnnys
Copy link
Author

Welnnys commented Oct 30, 2024

Can I please get a response :/?

@Welnnys
Copy link
Author

Welnnys commented Nov 4, 2024

Hello :/, it's been 3 weeks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
charts Charts component open Open
Projects
None yet
Development

No branches or pull requests

2 participants