forked from eatvio/eatvio_app
fix: fix errors
This commit is contained in:
60
README.md
60
README.md
@@ -1,59 +1 @@
|
||||
|
||||
# eatvio_app
|
||||
### Системные требования
|
||||
|
||||
- Flutter (Channel stable, 3.19.0, on Ubuntu 22.04.3 LTS 6.2.0-39-generic, locale en_US.UTF-8)
|
||||
- Android Studio (version 2023.1)
|
||||
- VS Code (version 1.85.0)
|
||||
- Android SDK (version 34.0.0) - устанавливается из Android Studio (Tools->SDK Manager->Android Command Line Tools)
|
||||
- Эмулятор (2 available)
|
||||
|
||||
### Структура приложения
|
||||
|
||||
```
|
||||
.
|
||||
├── android - Папка для крмпиляции Android приложения
|
||||
├── assets - Медиа и шрифты
|
||||
├── ios - Папка для крмпиляции iOS приложения
|
||||
├── lib - Основной код
|
||||
├── main.dart - Файл из которого компилируется приложение
|
||||
├── presentation - Виджеты экранов (верстка)
|
||||
├── routes - Роутер (пути до экранов)
|
||||
└── theme - Темы и оформление
|
||||
└── widgets - Кастомные виджеты
|
||||
├── pubspec.yaml - Пакеты
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Как запускать?
|
||||
|
||||
Для запуска на эмуляторе в программе VS Code скомпилируйте и запустите файл main.dart (предварительно необходимо установить эмулятор в Android Studio или подключите устройство в режиме разработчика через USB)
|
||||
|
||||
Для тестирования на устройствах Android в корневой папке проекта выполните команду
|
||||
|
||||
`# flutter build apk`
|
||||
|
||||
после чего `.apk` файл скомпилируется в директории `build/app/outputs/flutter-apk/app-release.apk`
|
||||
|
||||
Данный файл установит приложение на устройство с актуальной версией OS
|
||||
|
||||
### Библиотеки и инструменты
|
||||
|
||||
- **flutter_bloc** - контроль состояний
|
||||
- **cached_network_image** - кеширование картинок из веба
|
||||
- **flutter_svg** - работа с изображениями
|
||||
- **equatable** - сравнение без оператора "=="
|
||||
- **validators** - валидация
|
||||
- **hive** - локальная бд (1)
|
||||
- **hive_flutter** - локальная бд (2)
|
||||
- **isar_flutter_libs** - локальная бд (3)
|
||||
- **path_provider** - динамичкские пути до файлов
|
||||
- **fl_chart** - построение графиков
|
||||
- **flutter_spinkit** - прелоадеры
|
||||
- **flutter_dotenv** - переменные окружения
|
||||
|
||||
|
||||
### Поддержка
|
||||
|
||||
Telegram: @maxx_kim (https://t.me/maxx_kim)
|
||||
# eatvio_app
|
||||
@@ -19,7 +19,7 @@ pluginManagement {
|
||||
plugins {
|
||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||
id "com.android.application" version "7.3.1" apply false
|
||||
id "org.jetbrains.kotlin.android" version "1.9.10" apply false
|
||||
id "org.jetbrains.kotlin.android" version "2.0.20" apply false
|
||||
}
|
||||
|
||||
include ":app"
|
||||
|
||||
@@ -78,7 +78,7 @@ class _BlogPostCreateScreenState extends State<BlogPostCreateScreen> {
|
||||
floatingActionButton: SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
child: FloatingActionButton.extended(
|
||||
heroTag: 'nextButtonRegistration',
|
||||
heroTag: 'createBlogPost',
|
||||
highlightElevation: 0,
|
||||
elevation: 0,
|
||||
focusElevation: 0,
|
||||
|
||||
@@ -201,6 +201,7 @@ class DiaryScreen extends StatelessWidget {
|
||||
width: MediaQuery.of(context).size.width,
|
||||
padding: EdgeInsets.only(left: 4, right: 4),
|
||||
child: FloatingActionButton.extended(
|
||||
heroTag: 'endDayButton',
|
||||
highlightElevation: 0,
|
||||
elevation: 0,
|
||||
focusElevation: 0,
|
||||
@@ -264,6 +265,7 @@ class DiaryScreen extends StatelessWidget {
|
||||
width: MediaQuery.of(context).size.width,
|
||||
padding: EdgeInsets.only(left: 4, right: 4),
|
||||
child: FloatingActionButton.extended(
|
||||
heroTag: 'addProduct',
|
||||
highlightElevation: 0,
|
||||
elevation: 0,
|
||||
focusElevation: 0,
|
||||
|
||||
@@ -126,7 +126,7 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
height: 48,
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
child: FloatingActionButton.extended(
|
||||
heroTag: 'nextButtonRegistration',
|
||||
heroTag: 'authButton',
|
||||
highlightElevation: 0,
|
||||
elevation: 0,
|
||||
focusElevation: 0,
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:carousel_slider_plus/carousel_slider_plus.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_subtitle.dart';
|
||||
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'bloc/my_profile_bloc.dart';
|
||||
import 'models/my_profile_model.dart';
|
||||
|
||||
class MyProfileScreen extends StatelessWidget {
|
||||
int valuteToInt(String value) {
|
||||
// Преобразование строки в целое число
|
||||
return int.tryParse(value) ?? 0; // Возвращает 0, если преобразование не удалось
|
||||
}
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<MyProfileBloc>(
|
||||
create: (context) => MyProfileBloc(
|
||||
@@ -193,7 +192,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
|
||||
_buildCarousel(BuildContext contex, MyProfileLoadedState state) {
|
||||
return CarouselSlider(
|
||||
options: CarouselOptions(height: 370),
|
||||
options: CarouselOptions(height: 340),
|
||||
items: [1, 2, 3].map((chartType) {
|
||||
return Builder(
|
||||
builder: (BuildContext context) {
|
||||
@@ -210,11 +209,11 @@ class MyProfileScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 50.v),
|
||||
// _buildChart(
|
||||
// context,
|
||||
// state.chartPoints?.values.map<int>((e) => e['weight']).toList().map((i) => i.toDouble()).toList() ?? [0.0, 0.0, 0.0, 0.0],
|
||||
// state.chartDates,
|
||||
// ),
|
||||
_buildChart(
|
||||
context,
|
||||
state.chartPoints?.values.map<int>((e) => e['weight']).toList().map((i) => i.toDouble()).toList() ?? [0.0, 0.0, 0.0, 0.0],
|
||||
state.chartDates,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -228,14 +227,14 @@ class MyProfileScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 50.v),
|
||||
// _buildChart(
|
||||
// context,
|
||||
// _bodyMassIndex(
|
||||
// state.chartPoints?.values.map<int>((e) => e['weight']).toList().map((i) => i.toDouble()).toList() ?? [0.0, 0.0, 0.0, 0.0],
|
||||
// state.userDetails?['height'].toInt() ?? 160,
|
||||
// ),
|
||||
// state.chartDates,
|
||||
// ),
|
||||
_buildChart(
|
||||
context,
|
||||
_bodyMassIndex(
|
||||
state.chartPoints?.values.map<int>((e) => e['weight']).toList().map((i) => i.toDouble()).toList() ?? [0.0, 0.0, 0.0, 0.0],
|
||||
state.userDetails?['height'].toInt() ?? 160,
|
||||
),
|
||||
state.chartDates,
|
||||
),
|
||||
],
|
||||
);
|
||||
case 3: //График обхватов
|
||||
@@ -250,7 +249,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 30.v),
|
||||
// _buildCircumferenceChart(context, state.circumferences, state.chartDates),
|
||||
_buildCircumferenceChart(context, state.circumferences, state.chartDates),
|
||||
_buildChartLegend(),
|
||||
],
|
||||
),
|
||||
@@ -296,34 +295,354 @@ class MyProfileScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
// Widget _buildChart(BuildContext context, List<double> chartPoints, List<String>? dates) {
|
||||
// // Проверяем, что у нас есть 4 элемента в обоих списках
|
||||
// if (chartPoints.length != 4 || (dates != null && dates.length != 4)) {
|
||||
// return Center(child: Text('Должно быть ровно 4 точки и 4 даты.'));
|
||||
// }
|
||||
_buildChart(BuildContext context, List<double> chartPoints, List<String>? dates) {
|
||||
List<FlSpot> spots = [];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
spots.add(
|
||||
FlSpot((i * 10 / 10) + 1, chartPoints[i]),
|
||||
);
|
||||
}
|
||||
|
||||
// // Преобразуем данные в список точек для графика
|
||||
// List<ChartData> chartData = List.generate(4, (index) {
|
||||
// return ChartData(dates![index], chartPoints[index]);
|
||||
// });
|
||||
Widget bottomTitleWidgets(double value, TitleMeta meta, double chartWidth, List<String>? dates) {
|
||||
if (value % 1 != 0) {
|
||||
return Container();
|
||||
}
|
||||
final style = TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: min(13, 13 * chartWidth / 300),
|
||||
);
|
||||
int index = value.toInt();
|
||||
if (index >= 0 && index < dates!.length) {
|
||||
// Проверка на допустимый индекс в массиве dates
|
||||
String formattedDate = DateFormat('dd.MM').format(DateTime.parse(dates[index]));
|
||||
return SideTitleWidget(
|
||||
axisSide: meta.axisSide,
|
||||
space: 16,
|
||||
child: Text(formattedDate, style: style),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
// return Container(
|
||||
// height: 300, // Задайте нужную высоту для графика
|
||||
// child: SfCartesianChart(
|
||||
// title: ChartTitle(text: 'График значений'),
|
||||
// primaryXAxis: CategoryAxis(),
|
||||
// series: <CartesianSeries<ChartData, String>>[
|
||||
// // Изменяем на CartesianSeries
|
||||
// LineSeries<ChartData, String>(
|
||||
// dataSource: chartData,
|
||||
// xValueMapper: (ChartData data, _) => data.date,
|
||||
// yValueMapper: (ChartData data, _) => data.value,
|
||||
// dataLabelSettings: DataLabelSettings(isVisible: true),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
Widget leftTitleWidgets(double value, TitleMeta meta, double chartWidth) {
|
||||
final style = TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: min(18, 18 * chartWidth / 300),
|
||||
);
|
||||
return SideTitleWidget(
|
||||
axisSide: meta.axisSide,
|
||||
space: 16,
|
||||
child: Text(meta.formattedValue, style: style),
|
||||
);
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12,
|
||||
right: 20,
|
||||
),
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return LineChart(
|
||||
LineChartData(
|
||||
lineTouchData: LineTouchData(
|
||||
touchTooltipData: LineTouchTooltipData(
|
||||
maxContentWidth: 100,
|
||||
// tooltipBgColor: Colors.black,
|
||||
getTooltipItems: mapSpots(),
|
||||
),
|
||||
handleBuiltInTouches: true,
|
||||
getTouchLineStart: (data, index) => 0,
|
||||
),
|
||||
lineBarsData: [
|
||||
LineChartBarData(
|
||||
color: Colors.pink,
|
||||
spots: spots,
|
||||
isCurved: true,
|
||||
isStrokeCapRound: true,
|
||||
barWidth: 3,
|
||||
belowBarData: BarAreaData(
|
||||
show: false,
|
||||
),
|
||||
dotData: const FlDotData(show: false),
|
||||
),
|
||||
],
|
||||
minY: chartPoints.reduce((value, element) => value < element ? value : element),
|
||||
maxY: chartPoints.reduce((value, element) => value > element ? value : element),
|
||||
minX: 1,
|
||||
maxX: 4,
|
||||
titlesData: FlTitlesData(
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTitlesWidget: (value, meta) => leftTitleWidgets(value, meta, constraints.maxWidth),
|
||||
reservedSize: 56,
|
||||
),
|
||||
drawBelowEverything: true,
|
||||
),
|
||||
rightTitles: const AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTitlesWidget: (value, meta) => bottomTitleWidgets(value, meta, constraints.maxWidth, dates),
|
||||
reservedSize: 36,
|
||||
interval: 1,
|
||||
),
|
||||
drawBelowEverything: true,
|
||||
),
|
||||
topTitles: const AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
),
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: true,
|
||||
drawHorizontalLine: true,
|
||||
drawVerticalLine: true,
|
||||
horizontalInterval: 1.5,
|
||||
verticalInterval: 5,
|
||||
checkToShowHorizontalLine: valuteToInt(),
|
||||
getDrawingHorizontalLine: (_) => FlLine(
|
||||
color: Colors.blue.withOpacity(1),
|
||||
dashArray: [8, 2],
|
||||
strokeWidth: 0.8,
|
||||
),
|
||||
getDrawingVerticalLine: (_) => FlLine(
|
||||
color: Colors.blue.withOpacity(1),
|
||||
dashArray: [8, 2],
|
||||
strokeWidth: 0.8,
|
||||
),
|
||||
checkToShowVerticalLine: valuteToInt(),
|
||||
),
|
||||
borderData: FlBorderData(show: false),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
valuteToInt() {
|
||||
return (value) {
|
||||
return value.toInt() == 0;
|
||||
};
|
||||
}
|
||||
|
||||
List<LineTooltipItem?> Function(List<LineBarSpot>) mapSpots() {
|
||||
return (touchedSpots) {
|
||||
return touchedSpots.map((LineBarSpot touchedSpot) {
|
||||
final textStyle = TextStyle(
|
||||
color: touchedSpot.bar.gradient?.colors[0] ?? touchedSpot.bar.color,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
);
|
||||
return LineTooltipItem(
|
||||
'${touchedSpot.x}, ${touchedSpot.y.toStringAsFixed(2)}',
|
||||
textStyle,
|
||||
);
|
||||
}).toList();
|
||||
};
|
||||
}
|
||||
|
||||
_buildCircumferenceChart(BuildContext context, chartPoints, List<String>? dates) {
|
||||
// Определение осей графика
|
||||
final chestCircumferences = chartPoints.values.map((e) => e['chest_circumference']).toList();
|
||||
List<FlSpot> spotsChest = [];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
chestCircumferences[i] = chestCircumferences[i] * 10 / 10;
|
||||
spotsChest.add(
|
||||
FlSpot((i * 10 / 10) + 1, chestCircumferences[i] * 10 / 10),
|
||||
);
|
||||
}
|
||||
final waistCircumferences = chartPoints.values.map((e) => e['waist_circumference']).toList();
|
||||
List<FlSpot> spotsWaist = [];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
waistCircumferences[i] = waistCircumferences[i] * 10 / 10;
|
||||
spotsWaist.add(
|
||||
FlSpot((i * 10 / 10) + 1, waistCircumferences[i] * 10 / 10),
|
||||
);
|
||||
}
|
||||
final hipCircumferences = chartPoints.values.map((e) => e['hip_circumference']).toList();
|
||||
List<FlSpot> spotsHip = [];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
hipCircumferences[i] = hipCircumferences[i] * 10 / 10;
|
||||
spotsHip.add(
|
||||
FlSpot((i * 10 / 10) + 1, hipCircumferences[i]),
|
||||
);
|
||||
}
|
||||
|
||||
final allCircumferences = [...chestCircumferences, ...hipCircumferences, ...waistCircumferences];
|
||||
|
||||
Widget bottomTitleWidgets(double value, TitleMeta meta, double chartWidth, List<String>? dates) {
|
||||
if (value % 1 != 0) {
|
||||
return Container();
|
||||
}
|
||||
final style = TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: min(13, 13 * chartWidth / 300),
|
||||
);
|
||||
int index = value.toInt();
|
||||
if (index >= 0 && index < dates!.length) {
|
||||
// Проверка на допустимый индекс в массиве dates
|
||||
String formattedDate = DateFormat('dd.MM').format(DateTime.parse(dates[index]));
|
||||
return SideTitleWidget(
|
||||
axisSide: meta.axisSide,
|
||||
space: 16,
|
||||
child: Text(formattedDate, style: style),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
Widget leftTitleWidgets(double value, TitleMeta meta, double chartWidth) {
|
||||
final style = TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: min(18, 18 * chartWidth / 300),
|
||||
);
|
||||
return SideTitleWidget(
|
||||
axisSide: meta.axisSide,
|
||||
space: 16,
|
||||
child: Text(meta.formattedValue, style: style),
|
||||
);
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12,
|
||||
right: 20,
|
||||
),
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return LineChart(
|
||||
LineChartData(
|
||||
lineTouchData: LineTouchData(
|
||||
touchTooltipData: LineTouchTooltipData(
|
||||
maxContentWidth: 100,
|
||||
// tooltipBgColor: Colors.black,
|
||||
getTooltipItems: mapTouchedSpots(),
|
||||
),
|
||||
handleBuiltInTouches: true,
|
||||
getTouchLineStart: (data, index) => 0,
|
||||
),
|
||||
lineBarsData: [
|
||||
LineChartBarData(
|
||||
color: Colors.pink,
|
||||
spots: spotsChest,
|
||||
isCurved: true,
|
||||
isStrokeCapRound: true,
|
||||
barWidth: 3,
|
||||
belowBarData: BarAreaData(
|
||||
show: false,
|
||||
),
|
||||
dotData: const FlDotData(show: false),
|
||||
),
|
||||
LineChartBarData(
|
||||
color: Colors.green,
|
||||
spots: spotsWaist,
|
||||
isCurved: true,
|
||||
isStrokeCapRound: true,
|
||||
barWidth: 3,
|
||||
belowBarData: BarAreaData(
|
||||
show: false,
|
||||
),
|
||||
dotData: const FlDotData(show: false),
|
||||
),
|
||||
LineChartBarData(
|
||||
color: Colors.purple,
|
||||
spots: spotsHip,
|
||||
isCurved: true,
|
||||
isStrokeCapRound: true,
|
||||
barWidth: 3,
|
||||
belowBarData: BarAreaData(
|
||||
show: false,
|
||||
),
|
||||
dotData: const FlDotData(show: false),
|
||||
),
|
||||
],
|
||||
minY: allCircumferences.reduce((value, element) => value < element ? value : element),
|
||||
maxY: allCircumferences.reduce((value, element) => value > element ? value : element),
|
||||
minX: 1,
|
||||
maxX: 4,
|
||||
titlesData: FlTitlesData(
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTitlesWidget: (value, meta) => leftTitleWidgets(value, meta, constraints.maxWidth),
|
||||
reservedSize: 56,
|
||||
),
|
||||
drawBelowEverything: true,
|
||||
),
|
||||
rightTitles: const AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTitlesWidget: (value, meta) => bottomTitleWidgets(value, meta, constraints.maxWidth, dates),
|
||||
reservedSize: 36,
|
||||
interval: 1,
|
||||
),
|
||||
drawBelowEverything: true,
|
||||
),
|
||||
topTitles: const AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
),
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: true,
|
||||
drawHorizontalLine: true,
|
||||
drawVerticalLine: true,
|
||||
horizontalInterval: 1.5,
|
||||
verticalInterval: 5,
|
||||
checkToShowHorizontalLine: valuteToInt(),
|
||||
getDrawingHorizontalLine: (_) => FlLine(
|
||||
color: Colors.blue.withOpacity(1),
|
||||
dashArray: [8, 2],
|
||||
strokeWidth: 0.8,
|
||||
),
|
||||
getDrawingVerticalLine: (_) => FlLine(
|
||||
color: Colors.blue.withOpacity(1),
|
||||
dashArray: [8, 2],
|
||||
strokeWidth: 0.8,
|
||||
),
|
||||
checkToShowVerticalLine: valuteToInt(),
|
||||
),
|
||||
borderData: FlBorderData(show: false),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<LineTooltipItem?> Function(List<LineBarSpot>) mapTouchedSpots() {
|
||||
return (touchedSpots) {
|
||||
return touchedSpots.map((LineBarSpot touchedSpot) {
|
||||
final textStyle = TextStyle(
|
||||
color: touchedSpot.bar.gradient?.colors[0] ?? touchedSpot.bar.color,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
);
|
||||
return LineTooltipItem(
|
||||
'${touchedSpot.x}, ${touchedSpot.y.toStringAsFixed(2)}',
|
||||
textStyle,
|
||||
);
|
||||
}).toList();
|
||||
};
|
||||
}
|
||||
|
||||
/// Section Widget
|
||||
_buildPlans(BuildContext context, List<dynamic>? plans, List<dynamic>? imagePaths, List<dynamic>? states) {
|
||||
@@ -643,16 +962,3 @@ class MyProfileScreen extends StatelessWidget {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ChartData {
|
||||
final String date;
|
||||
final double value;
|
||||
|
||||
ChartData(this.date, this.value);
|
||||
|
||||
valuteToInt() {
|
||||
return (value) {
|
||||
return value.toInt() == 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ dependencies:
|
||||
freezed_annotation: ^2.4.4
|
||||
json_annotation: ^4.9.0
|
||||
validators: ^3.0.0
|
||||
isar_flutter_libs: ^3.1.0
|
||||
path_provider: ^2.1.4
|
||||
fl_chart: ^0.68.0
|
||||
flutter_spinkit: ^5.2.1
|
||||
@@ -45,7 +44,7 @@ dependencies:
|
||||
badges: ^3.1.2
|
||||
google_fonts: ^6.2.1
|
||||
location: ^6.0.2
|
||||
# syncfusion_flutter_charts: ^26.2.9
|
||||
syncfusion_flutter_charts: ^26.2.10
|
||||
table_calendar: ^3.1.2
|
||||
flutter_keyboard_visibility: ^6.0.0
|
||||
share_plus: ^10.0.0
|
||||
|
||||
Reference in New Issue
Block a user