diff --git a/android/gradle.properties b/android/gradle.properties
index 663881258a10822c0b4abc064b6e0bc0ccf48833..81949dfd2077495aaea8a6bc81ad9c75442f9ebb 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
 android.useAndroidX=true
 android.enableJetifier=true
-app.versionName=0.0.13
-app.versionCode=13
+app.versionName=0.0.14
+app.versionCode=14
diff --git a/fastlane/metadata/android/en-US/changelogs/14.txt b/fastlane/metadata/android/en-US/changelogs/14.txt
new file mode 100644
index 0000000000000000000000000000000000000000..56166fee1016f6aec9f4eb0e7f08c5bf00e44491
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/14.txt
@@ -0,0 +1 @@
+Improve/merge charts code.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/14.txt b/fastlane/metadata/android/fr-FR/changelogs/14.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3b6735dad9ecfe13d976f0fe36a6464ec670b249
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/14.txt
@@ -0,0 +1 @@
+Amélioration / mutualisation du code pour les graphiques.
diff --git a/lib/ui/widgets/charts/custom_bar_chart.dart b/lib/ui/widgets/charts/custom_bar_chart.dart
new file mode 100644
index 0000000000000000000000000000000000000000..166c7021aca2f870913106f502c3513fe775c611
--- /dev/null
+++ b/lib/ui/widgets/charts/custom_bar_chart.dart
@@ -0,0 +1,200 @@
+import 'package:easy_localization/easy_localization.dart';
+import 'package:fl_chart/fl_chart.dart';
+import 'package:flutter/material.dart';
+
+import '../../../config/app_colors.dart';
+import '../../../utils/color_extensions.dart';
+
+class CustomBarChart extends StatelessWidget {
+  CustomBarChart({super.key});
+
+  final double chartHeight = 120.0;
+  final double verticalTicksInterval = 10;
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      child: SizedBox(
+        height: this.chartHeight,
+      ),
+    );
+  }
+
+  BarChart getBarChart({barWidth, backgroundColor}) {
+    return BarChart(
+      BarChartData(
+        barGroups: getDataCounts(barWidth),
+        backgroundColor: backgroundColor,
+        borderData: getBorderData(),
+        gridData: getGridData(),
+        titlesData: getTitlesData(),
+        barTouchData: getBarTouchData(),
+        maxY: getNextRoundNumber(getMaxCountsValue(), this.verticalTicksInterval),
+      ),
+    );
+  }
+
+  double getBarWidth(double containerWidth, int barsCount) {
+    return 0.7 * (containerWidth / barsCount);
+  }
+
+  List<BarChartGroupData> getDataCounts(double barWidth) {
+    return [];
+  }
+
+  double getMaxCountsValue() {
+    return 0.0;
+  }
+
+  double getNextRoundNumber(double number, double scale) {
+    return scale * ((number ~/ scale).toInt() + 1);
+  }
+
+  BarChartGroupData getBarItem(
+      {required int x,
+      required double value,
+      required Color barColor,
+      required double barWidth}) {
+    final gradient = this.getGradient(barColor);
+    final borderColor = barColor.darken(20);
+
+    return BarChartGroupData(
+      x: x,
+      barRods: [
+        BarChartRodData(
+          toY: value,
+          color: barColor,
+          gradient: gradient,
+          width: barWidth,
+          borderRadius: BorderRadius.all(Radius.zero),
+          borderSide: BorderSide(
+            color: borderColor,
+          ),
+        ),
+      ],
+    );
+  }
+
+  LinearGradient getGradient(Color baseColor) {
+    return LinearGradient(
+      begin: Alignment.topLeft,
+      end: Alignment(0.8, 1),
+      colors: <Color>[
+        baseColor.lighten(30),
+        baseColor,
+        baseColor.darken(30),
+      ],
+      tileMode: TileMode.mirror,
+    );
+  }
+
+  FlBorderData getBorderData() {
+    return FlBorderData(
+      show: true,
+      border: Border.all(
+        color: AppColors.borderColor,
+        width: 2,
+      ),
+    );
+  }
+
+  FlGridData getGridData() {
+    return const FlGridData(
+      show: true,
+      drawHorizontalLine: true,
+      drawVerticalLine: false,
+    );
+  }
+
+  FlTitlesData getTitlesData() {
+    const AxisTitles none = const AxisTitles(
+      sideTitles: SideTitles(showTitles: false),
+    );
+
+    final AxisTitles verticalTitles = AxisTitles(
+      sideTitles: SideTitles(
+        showTitles: true,
+        reservedSize: 30,
+        getTitlesWidget: getVerticalTitlesWidget,
+        interval: this.verticalTicksInterval,
+      ),
+    );
+    final AxisTitles horizontalTitles = AxisTitles(
+      sideTitles: SideTitles(
+        showTitles: true,
+        reservedSize: 20,
+        getTitlesWidget: getHorizontalTitlesWidget,
+      ),
+    );
+
+    return FlTitlesData(
+      show: true,
+      bottomTitles: horizontalTitles,
+      leftTitles: verticalTitles,
+      topTitles: none,
+      rightTitles: verticalTitles,
+    );
+  }
+
+  Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
+    return SideTitleWidget(
+      axisSide: meta.axisSide,
+      space: 4,
+      child: Text(
+        value.toInt().toString(),
+        style: const TextStyle(
+          color: AppColors.mainTextColor1,
+          fontSize: 12,
+        ),
+      ),
+    );
+  }
+
+  Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
+    final DateFormat formatter = DateFormat('dd/MM');
+
+    final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
+    final String text = formatter.format(date);
+
+    return SideTitleWidget(
+      axisSide: meta.axisSide,
+      space: 4,
+      child: RotationTransition(
+        turns: new AlwaysStoppedAnimation(-30 / 360),
+        child: Text(
+          text,
+          style: const TextStyle(
+            color: AppColors.mainTextColor1,
+            fontSize: 11,
+          ),
+        ),
+      ),
+    );
+  }
+
+  BarTouchData getBarTouchData() {
+    return BarTouchData(
+      enabled: true,
+      touchTooltipData: BarTouchTooltipData(
+        tooltipBgColor: Colors.transparent,
+        tooltipPadding: EdgeInsets.zero,
+        tooltipMargin: 2,
+        getTooltipItem: (
+          BarChartGroupData group,
+          int groupIndex,
+          BarChartRodData rod,
+          int rodIndex,
+        ) {
+          return BarTooltipItem(
+            rod.toY.round().toString(),
+            const TextStyle(
+              color: AppColors.mainTextColor2,
+              fontWeight: FontWeight.bold,
+              fontSize: 10,
+            ),
+          );
+        },
+      ),
+    );
+  }
+}
diff --git a/lib/ui/widgets/charts/custom_line_chart.dart b/lib/ui/widgets/charts/custom_line_chart.dart
new file mode 100644
index 0000000000000000000000000000000000000000..2debb0bf838910abeadad0b29408bef76ed9b4af
--- /dev/null
+++ b/lib/ui/widgets/charts/custom_line_chart.dart
@@ -0,0 +1,112 @@
+import 'package:easy_localization/easy_localization.dart';
+import 'package:fl_chart/fl_chart.dart';
+import 'package:flutter/material.dart';
+
+import '../../../config/app_colors.dart';
+import '../../../utils/color_extensions.dart';
+
+class CustomLineChart extends StatelessWidget {
+  CustomLineChart({super.key});
+
+  final double chartHeight = 120.0;
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      child: SizedBox(
+        height: this.chartHeight,
+      ),
+    );
+  }
+
+  LinearGradient getGradient(Color baseColor) {
+    return LinearGradient(
+      begin: Alignment.topCenter,
+      end: Alignment.bottomCenter,
+      colors: <Color>[
+        baseColor.lighten(30),
+        baseColor,
+        baseColor.darken(30),
+      ],
+      tileMode: TileMode.mirror,
+    );
+  }
+
+  FlBorderData getBorderData() {
+    return FlBorderData(
+      show: true,
+      border: Border.all(
+        color: AppColors.borderColor,
+        width: 2,
+      ),
+    );
+  }
+
+  FlGridData getGridData() {
+    return const FlGridData(
+      show: true,
+      drawHorizontalLine: true,
+      drawVerticalLine: false,
+    );
+  }
+
+  Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
+    return SideTitleWidget(
+      axisSide: meta.axisSide,
+      space: 4,
+      child: Text(
+        value.toInt().toString(),
+        style: const TextStyle(
+          color: AppColors.mainTextColor1,
+          fontSize: 12,
+        ),
+      ),
+    );
+  }
+
+  Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
+    final DateFormat formatter = DateFormat('dd/MM');
+
+    final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
+    final String text = formatter.format(date);
+
+    return SideTitleWidget(
+      axisSide: meta.axisSide,
+      space: 4,
+      child: RotationTransition(
+        turns: new AlwaysStoppedAnimation(-30 / 360),
+        child: Text(
+          text,
+          style: const TextStyle(
+            color: AppColors.mainTextColor1,
+            fontSize: 11,
+          ),
+        ),
+      ),
+    );
+  }
+
+  LineTouchData getLineTouchDataEclecticism() {
+    return LineTouchData(
+      handleBuiltInTouches: true,
+      touchTooltipData: LineTouchTooltipData(
+        tooltipBgColor: Colors.transparent,
+        tooltipPadding: EdgeInsets.all(8),
+        tooltipMargin: 2,
+        getTooltipItems: (List<LineBarSpot> touchedSpots) {
+          return touchedSpots.map((LineBarSpot touchedSpot) {
+            final textStyle = TextStyle(
+              color: AppColors.mainTextColor2,
+              fontWeight: FontWeight.bold,
+              fontSize: 10,
+            );
+            return LineTooltipItem(
+              touchedSpot.y.toString(),
+              textStyle,
+            );
+          }).toList();
+        },
+      ),
+    );
+  }
+}
diff --git a/lib/ui/widgets/main_screen/counts_by_day_chart.dart b/lib/ui/widgets/main_screen/counts_by_day_chart.dart
index 0e6deae738c9aa5bd4986809cb4c18358aba9f2a..e6eca846120a4470604340fe95a2dc5932179f27 100644
--- a/lib/ui/widgets/main_screen/counts_by_day_chart.dart
+++ b/lib/ui/widgets/main_screen/counts_by_day_chart.dart
@@ -4,32 +4,21 @@ import 'package:fl_chart/fl_chart.dart';
 
 import '../../../config/app_colors.dart';
 import '../../../models/counts_by_day.dart';
-import '../../../utils/color_extensions.dart';
+import '../../../ui/widgets/charts/custom_bar_chart.dart';
 
-class CountsByDayCardContentChart extends StatelessWidget {
+class CountsByDayCardContentChart extends CustomBarChart {
   final CountsByDayData chartData;
 
-  const CountsByDayCardContentChart({super.key, required this.chartData});
+  CountsByDayCardContentChart({super.key, required this.chartData});
 
   @override
   Widget build(BuildContext context) {
     return Container(
-      height: 120.0,
+      height: this.chartHeight,
       child: LayoutBuilder(builder: (context, constraints) {
-        final double maxWidth = constraints.maxWidth;
-        final int barsCount = this.chartData.data.keys.length;
-        final double barWidth = 0.7 * (maxWidth / barsCount);
-
-        return BarChart(
-          BarChartData(
-            barGroups: getDataCounts(barWidth),
-            backgroundColor: Theme.of(context).colorScheme.onSurface,
-            borderData: getBorderData(),
-            gridData: getGridData(),
-            titlesData: getTitlesData(),
-            barTouchData: getBarTouchData(),
-            maxY: getNextRoundNumber(getMaxCountsValue(), 10),
-          ),
+        return getBarChart(
+          barWidth: this.getBarWidth(constraints.maxWidth, this.chartData.data.keys.length),
+          backgroundColor: Theme.of(context).colorScheme.onSurface,
         );
       }),
     );
@@ -50,21 +39,33 @@ class CountsByDayCardContentChart extends StatelessWidget {
     return maxValue;
   }
 
-  double getNextRoundNumber(double number, int scale) {
-    return scale * ((number ~/ scale).toInt() + 1);
-  }
-
-  LinearGradient getGradient(Color baseColor) {
-    return LinearGradient(
-      begin: Alignment.topLeft,
-      end: Alignment(0.8, 1),
-      colors: <Color>[
-        baseColor.lighten(30),
-        baseColor,
-        baseColor.darken(30),
-      ],
-      tileMode: TileMode.mirror,
-    );
+  Color getColorFromIndex(int index) {
+    Color barColor = AppColors.contentColorBlack;
+    switch (index) {
+      case 1:
+        barColor = Color.fromARGB(255, 255, 99, 132);
+        break;
+      case 2:
+        barColor = Color.fromARGB(255, 255, 159, 64);
+        break;
+      case 3:
+        barColor = Color.fromARGB(255, 255, 205, 86);
+        break;
+      case 4:
+        barColor = Color.fromARGB(255, 75, 192, 192);
+        break;
+      case 5:
+        barColor = Color.fromARGB(255, 54, 162, 235);
+        break;
+      case 6:
+        barColor = Color.fromARGB(255, 153, 102, 255);
+        break;
+      case 7:
+        barColor = Color.fromARGB(255, 201, 203, 207);
+        break;
+      default:
+    }
+    return barColor;
   }
 
   List<BarChartGroupData> getDataCounts(double barWidth) {
@@ -74,49 +75,13 @@ class CountsByDayCardContentChart extends StatelessWidget {
       final double? counts = this.chartData.data[day];
 
       if (counts != null) {
-        Color barColor = AppColors.contentColorBlack;
-        switch (day) {
-          case 1:
-            barColor = Color.fromARGB(255, 255, 99, 132);
-            break;
-          case 2:
-            barColor = Color.fromARGB(255, 255, 159, 64);
-            break;
-          case 3:
-            barColor = Color.fromARGB(255, 255, 205, 86);
-            break;
-          case 4:
-            barColor = Color.fromARGB(255, 75, 192, 192);
-            break;
-          case 5:
-            barColor = Color.fromARGB(255, 54, 162, 235);
-            break;
-          case 6:
-            barColor = Color.fromARGB(255, 153, 102, 255);
-            break;
-          case 7:
-            barColor = Color.fromARGB(255, 201, 203, 207);
-            break;
-          default:
-        }
+        final Color barColor = this.getColorFromIndex(day);
 
-        final gradient = getGradient(barColor);
-        final borderColor = barColor.darken(20);
-
-        data.add(BarChartGroupData(
+        data.add(this.getBarItem(
           x: day,
-          barRods: [
-            BarChartRodData(
-              toY: counts,
-              color: barColor,
-              gradient: gradient,
-              width: barWidth,
-              borderRadius: BorderRadius.all(Radius.zero),
-              borderSide: BorderSide(
-                color: borderColor,
-              ),
-            ),
-          ],
+          value: counts,
+          barColor: barColor,
+          barWidth: barWidth,
         ));
       }
     });
@@ -124,68 +89,6 @@ class CountsByDayCardContentChart extends StatelessWidget {
     return data;
   }
 
-  FlBorderData getBorderData() {
-    return FlBorderData(
-      show: true,
-      border: Border.all(
-        color: AppColors.borderColor,
-        width: 2,
-      ),
-    );
-  }
-
-  FlGridData getGridData() {
-    return const FlGridData(
-      show: true,
-      drawHorizontalLine: true,
-      drawVerticalLine: false,
-    );
-  }
-
-  FlTitlesData getTitlesData() {
-    const AxisTitles none = const AxisTitles(
-      sideTitles: SideTitles(showTitles: false),
-    );
-
-    final AxisTitles verticalTitles = AxisTitles(
-      sideTitles: SideTitles(
-        showTitles: true,
-        reservedSize: 30,
-        getTitlesWidget: getVerticalTitlesWidget,
-        interval: 10,
-      ),
-    );
-    final AxisTitles horizontalTitles = AxisTitles(
-      sideTitles: SideTitles(
-        showTitles: true,
-        reservedSize: 20,
-        getTitlesWidget: getHorizontalTitlesWidget,
-      ),
-    );
-
-    return FlTitlesData(
-      show: true,
-      bottomTitles: horizontalTitles,
-      leftTitles: verticalTitles,
-      topTitles: none,
-      rightTitles: verticalTitles,
-    );
-  }
-
-  Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
-    return SideTitleWidget(
-      axisSide: meta.axisSide,
-      space: 4,
-      child: Text(
-        value.toInt().toString(),
-        style: const TextStyle(
-          color: AppColors.mainTextColor1,
-          fontSize: 12,
-        ),
-      ),
-    );
-  }
-
   Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
     final int day = value.toInt();
     String dayShortName = '';
@@ -214,13 +117,11 @@ class CountsByDayCardContentChart extends StatelessWidget {
       default:
     }
 
-    final String text = tr(dayShortName);
-
     return SideTitleWidget(
       axisSide: meta.axisSide,
       space: 2,
       child: Text(
-        text,
+        tr(dayShortName),
         style: const TextStyle(
           color: AppColors.mainTextColor1,
           fontSize: 11,
@@ -228,30 +129,4 @@ class CountsByDayCardContentChart extends StatelessWidget {
       ),
     );
   }
-
-  BarTouchData getBarTouchData() {
-    return BarTouchData(
-      enabled: true,
-      touchTooltipData: BarTouchTooltipData(
-        tooltipBgColor: Colors.transparent,
-        tooltipPadding: EdgeInsets.zero,
-        tooltipMargin: 2,
-        getTooltipItem: (
-          BarChartGroupData group,
-          int groupIndex,
-          BarChartRodData rod,
-          int rodIndex,
-        ) {
-          return BarTooltipItem(
-            rod.toY.round().toString(),
-            const TextStyle(
-              color: AppColors.mainTextColor2,
-              fontWeight: FontWeight.bold,
-              fontSize: 10,
-            ),
-          );
-        },
-      ),
-    );
-  }
 }
diff --git a/lib/ui/widgets/main_screen/counts_by_hour_chart.dart b/lib/ui/widgets/main_screen/counts_by_hour_chart.dart
index 0dd1df31db85a726ce9e2cf5b39e416aaba10d88..81182f4ce5cd1652d9625636a80b3b64dbdc55cf 100644
--- a/lib/ui/widgets/main_screen/counts_by_hour_chart.dart
+++ b/lib/ui/widgets/main_screen/counts_by_hour_chart.dart
@@ -3,32 +3,22 @@ import 'package:fl_chart/fl_chart.dart';
 
 import '../../../config/app_colors.dart';
 import '../../../models/counts_by_hour.dart';
+import '../../../ui/widgets/charts/custom_bar_chart.dart';
 import '../../../utils/color_extensions.dart';
 
-class CountsByHourCardContentChart extends StatelessWidget {
+class CountsByHourCardContentChart extends CustomBarChart {
   final CountsByHourData chartData;
 
-  const CountsByHourCardContentChart({super.key, required this.chartData});
+  CountsByHourCardContentChart({super.key, required this.chartData});
 
   @override
   Widget build(BuildContext context) {
     return Container(
-      height: 120.0,
+      height: this.chartHeight,
       child: LayoutBuilder(builder: (context, constraints) {
-        final double maxWidth = constraints.maxWidth;
-        final int barsCount = this.chartData.data.keys.length;
-        final double barWidth = 0.7 * (maxWidth / barsCount);
-
-        return BarChart(
-          BarChartData(
-            barGroups: getDataCounts(barWidth),
-            backgroundColor: Theme.of(context).colorScheme.onSurface,
-            borderData: getBorderData(),
-            gridData: getGridData(),
-            titlesData: getTitlesData(),
-            barTouchData: getBarTouchData(),
-            maxY: getNextRoundNumber(getMaxCountsValue(), 5),
-          ),
+        return getBarChart(
+          barWidth: this.getBarWidth(constraints.maxWidth, this.chartData.data.keys.length),
+          backgroundColor: Theme.of(context).colorScheme.onSurface,
         );
       }),
     );
@@ -49,48 +39,20 @@ class CountsByHourCardContentChart extends StatelessWidget {
     return maxValue;
   }
 
-  double getNextRoundNumber(double number, int scale) {
-    return scale * ((number ~/ scale).toInt() + 1);
-  }
-
-  LinearGradient getGradient(Color baseColor) {
-    return LinearGradient(
-      begin: Alignment.topLeft,
-      end: Alignment(0.8, 1),
-      colors: <Color>[
-        baseColor.lighten(30),
-        baseColor,
-        baseColor.darken(30),
-      ],
-      tileMode: TileMode.mirror,
-    );
-  }
-
   List<BarChartGroupData> getDataCounts(double barWidth) {
     List<BarChartGroupData> data = [];
 
-    final baseColor = AppColors.contentColorCyan.darken(30);
-    final gradient = getGradient(baseColor);
-    final borderColor = baseColor.darken(20);
+    final barColor = AppColors.contentColorCyan.darken(30);
 
     this.chartData.data.keys.forEach((day) {
       final double? counts = this.chartData.data[day];
 
       if (counts != null) {
-        data.add(BarChartGroupData(
+        data.add(getBarItem(
           x: day,
-          barRods: [
-            BarChartRodData(
-              toY: counts,
-              color: baseColor,
-              gradient: gradient,
-              width: barWidth,
-              borderRadius: BorderRadius.all(Radius.zero),
-              borderSide: BorderSide(
-                color: borderColor,
-              ),
-            ),
-          ],
+          value: counts,
+          barColor: barColor,
+          barWidth: barWidth,
         ));
       }
     });
@@ -98,68 +60,6 @@ class CountsByHourCardContentChart extends StatelessWidget {
     return data;
   }
 
-  FlBorderData getBorderData() {
-    return FlBorderData(
-      show: true,
-      border: Border.all(
-        color: AppColors.borderColor,
-        width: 2,
-      ),
-    );
-  }
-
-  FlGridData getGridData() {
-    return const FlGridData(
-      show: true,
-      drawHorizontalLine: true,
-      drawVerticalLine: false,
-    );
-  }
-
-  FlTitlesData getTitlesData() {
-    const AxisTitles none = const AxisTitles(
-      sideTitles: SideTitles(showTitles: false),
-    );
-
-    final AxisTitles verticalTitles = AxisTitles(
-      sideTitles: SideTitles(
-        showTitles: true,
-        reservedSize: 30,
-        getTitlesWidget: getVerticalTitlesWidget,
-        interval: 5,
-      ),
-    );
-    final AxisTitles horizontalTitles = AxisTitles(
-      sideTitles: SideTitles(
-        showTitles: true,
-        reservedSize: 20,
-        getTitlesWidget: getHorizontalTitlesWidget,
-      ),
-    );
-
-    return FlTitlesData(
-      show: true,
-      bottomTitles: horizontalTitles,
-      leftTitles: verticalTitles,
-      topTitles: none,
-      rightTitles: verticalTitles,
-    );
-  }
-
-  Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
-    return SideTitleWidget(
-      axisSide: meta.axisSide,
-      space: 4,
-      child: Text(
-        value.toInt().toString(),
-        style: const TextStyle(
-          color: AppColors.mainTextColor1,
-          fontSize: 12,
-        ),
-      ),
-    );
-  }
-
   Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
     String text = '';
 
@@ -179,30 +79,4 @@ class CountsByHourCardContentChart extends StatelessWidget {
       ),
     );
   }
-
-  BarTouchData getBarTouchData() {
-    return BarTouchData(
-      enabled: true,
-      touchTooltipData: BarTouchTooltipData(
-        tooltipBgColor: Colors.transparent,
-        tooltipPadding: EdgeInsets.zero,
-        tooltipMargin: 2,
-        getTooltipItem: (
-          BarChartGroupData group,
-          int groupIndex,
-          BarChartRodData rod,
-          int rodIndex,
-        ) {
-          return BarTooltipItem(
-            rod.toY.round().toString(),
-            const TextStyle(
-              color: AppColors.mainTextColor2,
-              fontWeight: FontWeight.bold,
-              fontSize: 10,
-            ),
-          );
-        },
-      ),
-    );
-  }
 }
diff --git a/lib/ui/widgets/main_screen/timeline_chart_counts.dart b/lib/ui/widgets/main_screen/timeline_chart_counts.dart
index 7378c05802e1cb4c27d2f72b6344c141acd7b29d..4024e7a38182804cdb7d8f69afde2b2f6d469124 100644
--- a/lib/ui/widgets/main_screen/timeline_chart_counts.dart
+++ b/lib/ui/widgets/main_screen/timeline_chart_counts.dart
@@ -1,35 +1,26 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:fl_chart/fl_chart.dart';
 
 import '../../../config/app_colors.dart';
 import '../../../models/timeline.dart';
-import '../../../utils/color_extensions.dart';
+import '../../../ui/widgets/charts/custom_bar_chart.dart';
 
-class ChartTimelineCounts extends StatelessWidget {
+class ChartTimelineCounts extends CustomBarChart {
   final TimelineData chartData;
 
-  const ChartTimelineCounts({super.key, required this.chartData});
+  ChartTimelineCounts({super.key, required this.chartData});
+
+  final double chartHeight = 150.0;
+  final double verticalTicksInterval = 50;
 
   @override
   Widget build(BuildContext context) {
     return Container(
-      height: 150.0,
+      height: this.chartHeight,
       child: LayoutBuilder(builder: (context, constraints) {
-        final double maxWidth = constraints.maxWidth;
-        final int barsCount = this.chartData.data.keys.length;
-        final double barWidth = 0.7 * (maxWidth / barsCount);
-
-        return BarChart(
-          BarChartData(
-            barGroups: getDataCounts(barWidth),
-            backgroundColor: Theme.of(context).colorScheme.onSurface,
-            borderData: getBorderData(),
-            gridData: getGridData(),
-            titlesData: getTitlesData(),
-            barTouchData: getBarTouchData(),
-            maxY: getNextRoundNumber(getMaxCountsValue(), 50),
-          ),
+        return getBarChart(
+          barWidth: this.getBarWidth(constraints.maxWidth, this.chartData.data.keys.length),
+          backgroundColor: Theme.of(context).colorScheme.onSurface,
         );
       }),
     );
@@ -51,29 +42,10 @@ class ChartTimelineCounts extends StatelessWidget {
     return maxValue;
   }
 
-  double getNextRoundNumber(double number, int scale) {
-    return scale * ((number ~/ scale).toInt() + 1);
-  }
-
-  LinearGradient getGradient(Color baseColor) {
-    return LinearGradient(
-      begin: Alignment.topLeft,
-      end: Alignment(0.8, 1),
-      colors: <Color>[
-        baseColor.lighten(30),
-        baseColor,
-        baseColor.darken(30),
-      ],
-      tileMode: TileMode.mirror,
-    );
-  }
-
   List<BarChartGroupData> getDataCounts(double barWidth) {
     List<BarChartGroupData> data = [];
 
-    final baseColor = AppColors.contentColorOrange;
-    final gradient = getGradient(baseColor);
-    final borderColor = baseColor.darken(20);
+    final barColor = AppColors.contentColorOrange;
 
     this.chartData.data.keys.forEach((key) {
       TimelineDataValue? value = this.chartData.data[key];
@@ -81,133 +53,15 @@ class ChartTimelineCounts extends StatelessWidget {
         final int date = DateTime.parse(key).millisecondsSinceEpoch;
         final double counts = value.counts.toDouble();
 
-        data.add(BarChartGroupData(
+        data.add(this.getBarItem(
           x: date,
-          barRods: [
-            BarChartRodData(
-              toY: counts,
-              color: baseColor,
-              gradient: gradient,
-              width: barWidth,
-              borderRadius: BorderRadius.all(Radius.zero),
-              borderSide: BorderSide(
-                color: borderColor,
-              ),
-            ),
-          ],
+          value: counts,
+          barColor: barColor,
+          barWidth: barWidth,
         ));
       }
     });
 
     return data;
   }
-
-  FlBorderData getBorderData() {
-    return FlBorderData(
-      show: true,
-      border: Border.all(
-        color: AppColors.borderColor,
-        width: 2,
-      ),
-    );
-  }
-
-  FlGridData getGridData() {
-    return const FlGridData(
-      show: true,
-      drawHorizontalLine: true,
-      drawVerticalLine: false,
-    );
-  }
-
-  FlTitlesData getTitlesData() {
-    const AxisTitles none = const AxisTitles(
-      sideTitles: SideTitles(showTitles: false),
-    );
-
-    final AxisTitles verticalTitles = AxisTitles(
-      sideTitles: SideTitles(
-        showTitles: true,
-        reservedSize: 30,
-        getTitlesWidget: getVerticalTitlesWidget,
-      ),
-    );
-    final AxisTitles horizontalTitles = AxisTitles(
-      sideTitles: SideTitles(
-        showTitles: true,
-        reservedSize: 20,
-        getTitlesWidget: getHorizontalTitlesWidget,
-      ),
-    );
-
-    return FlTitlesData(
-      show: true,
-      bottomTitles: horizontalTitles,
-      leftTitles: verticalTitles,
-      topTitles: none,
-      rightTitles: verticalTitles,
-    );
-  }
-
-  Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
-    return SideTitleWidget(
-      axisSide: meta.axisSide,
-      space: 4,
-      child: Text(
-        value.toInt().toString(),
-        style: const TextStyle(
-          color: AppColors.mainTextColor1,
-          fontSize: 12,
-        ),
-      ),
-    );
-  }
-
-  Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
-    final DateFormat formatter = DateFormat('dd/MM');
-
-    final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
-    final String text = formatter.format(date);
-
-    return SideTitleWidget(
-      axisSide: meta.axisSide,
-      space: 4,
-      child: RotationTransition(
-        turns: new AlwaysStoppedAnimation(-30 / 360),
-        child: Text(
-          text,
-          style: const TextStyle(
-            color: AppColors.mainTextColor1,
-            fontSize: 11,
-          ),
-        ),
-      ),
-    );
-  }
-
-  BarTouchData getBarTouchData() {
-    return BarTouchData(
-      enabled: true,
-      touchTooltipData: BarTouchTooltipData(
-        tooltipBgColor: Colors.transparent,
-        tooltipPadding: EdgeInsets.zero,
-        tooltipMargin: 2,
-        getTooltipItem: (
-          BarChartGroupData group,
-          int groupIndex,
-          BarChartRodData rod,
-          int rodIndex,
-        ) {
-          return BarTooltipItem(
-            rod.toY.round().toString(),
-            const TextStyle(
-              color: AppColors.mainTextColor2,
-              fontWeight: FontWeight.bold,
-              fontSize: 10,
-            ),
-          );
-        },
-      ),
-    );
-  }
 }
diff --git a/lib/ui/widgets/main_screen/timeline_chart_eclecticism.dart b/lib/ui/widgets/main_screen/timeline_chart_eclecticism.dart
index 2490ac037296622a30bc98c66eed776cb5711caf..c78e8fac576f816b27df7585553d96ebce134963 100644
--- a/lib/ui/widgets/main_screen/timeline_chart_eclecticism.dart
+++ b/lib/ui/widgets/main_screen/timeline_chart_eclecticism.dart
@@ -1,20 +1,20 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:fl_chart/fl_chart.dart';
 
 import '../../../config/app_colors.dart';
 import '../../../models/timeline.dart';
+import '../../../ui/widgets/charts/custom_line_chart.dart';
 import '../../../utils/color_extensions.dart';
 
-class ChartTimelineEclecticism extends StatelessWidget {
+class ChartTimelineEclecticism extends CustomLineChart {
   final TimelineData chartData;
 
-  const ChartTimelineEclecticism({super.key, required this.chartData});
+  ChartTimelineEclecticism({super.key, required this.chartData});
 
   @override
   Widget build(BuildContext context) {
     return Container(
-      height: 120.0,
+      height: this.chartHeight,
       child: LineChart(
         LineChartData(
           lineBarsData: getDataEclecticism(),
@@ -31,19 +31,6 @@ class ChartTimelineEclecticism extends StatelessWidget {
     );
   }
 
-  LinearGradient getGradient(Color baseColor) {
-    return LinearGradient(
-      begin: Alignment.topCenter,
-      end: Alignment.bottomCenter,
-      colors: <Color>[
-        baseColor.lighten(30),
-        baseColor,
-        baseColor.darken(30),
-      ],
-      tileMode: TileMode.mirror,
-    );
-  }
-
   List<LineChartBarData> getDataEclecticism() {
     List<FlSpot> spots = [];
 
@@ -78,24 +65,6 @@ class ChartTimelineEclecticism extends StatelessWidget {
     ];
   }
 
-  FlBorderData getBorderData() {
-    return FlBorderData(
-      show: true,
-      border: Border.all(
-        color: AppColors.borderColor,
-        width: 2,
-      ),
-    );
-  }
-
-  FlGridData getGridData() {
-    return const FlGridData(
-      show: true,
-      drawHorizontalLine: true,
-      drawVerticalLine: false,
-    );
-  }
-
   FlTitlesData getTitlesData() {
     const AxisTitles none = const AxisTitles(
       sideTitles: SideTitles(showTitles: false),
@@ -125,64 +94,4 @@ class ChartTimelineEclecticism extends StatelessWidget {
       rightTitles: verticalTitles,
     );
   }
-
-  Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
-    return SideTitleWidget(
-      axisSide: meta.axisSide,
-      space: 4,
-      child: Text(
-        value.toInt().toString(),
-        style: const TextStyle(
-          color: AppColors.mainTextColor1,
-          fontSize: 12,
-        ),
-      ),
-    );
-  }
-
-  Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
-    final DateFormat formatter = DateFormat('dd/MM');
-
-    final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
-    final String text = formatter.format(date);
-
-    return SideTitleWidget(
-      axisSide: meta.axisSide,
-      space: 4,
-      child: RotationTransition(
-        turns: new AlwaysStoppedAnimation(-30 / 360),
-        child: Text(
-          text,
-          style: const TextStyle(
-            color: AppColors.mainTextColor1,
-            fontSize: 11,
-          ),
-        ),
-      ),
-    );
-  }
-
-  LineTouchData getLineTouchDataEclecticism() {
-    return LineTouchData(
-      handleBuiltInTouches: true,
-      touchTooltipData: LineTouchTooltipData(
-        tooltipBgColor: Colors.transparent,
-        tooltipPadding: EdgeInsets.all(8),
-        tooltipMargin: 2,
-        getTooltipItems: (List<LineBarSpot> touchedSpots) {
-          return touchedSpots.map((LineBarSpot touchedSpot) {
-            final textStyle = TextStyle(
-              color: AppColors.mainTextColor2,
-              fontWeight: FontWeight.bold,
-              fontSize: 10,
-            );
-            return LineTooltipItem(
-              touchedSpot.y.toString(),
-              textStyle,
-            );
-          }).toList();
-        },
-      ),
-    );
-  }
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index f86f6c6eb8121bee0cb7ee4a0035379005764420..96e1872347f95bc069aa987b776b8f6874e7107a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: Display scrobbles data and charts
 
 publish_to: 'none'
 
-version: 0.0.13+13
+version: 0.0.14+14
 
 environment:
   sdk: '^3.0.0'