diff --git a/src/main/java/de/deadlocker8/budgetmaster/charts/DefaultCharts.java b/src/main/java/de/deadlocker8/budgetmaster/charts/DefaultCharts.java
index 936f577b9d4a15e6071c7f1d35c0582c698cd210..44424b926a84d2058a82f3b6756cd129a3484059 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/charts/DefaultCharts.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/charts/DefaultCharts.java
@@ -29,6 +29,10 @@ public class DefaultCharts
 			getChartFromFile("charts/IncomesAndExpendituresPerMonthLine.js"),
 			ChartType.DEFAULT, 2);
 
+	private static final Chart CHART_INCOMES_AND_EXPENDITURES_BY_CATEGORY_BAR = new Chart("charts.default.incomesAndExpendituresByCategoryBar",
+			getChartFromFile("charts/IncomesAndExpendituresByCategoryBar.js"),
+			ChartType.DEFAULT, 11);
+
 
 	public static List<Chart> getDefaultCharts()
 	{
@@ -36,6 +40,7 @@ public class DefaultCharts
 		charts.add(CHART_ACCOUNT_SUM_PER_DAY);
 		charts.add(CHART_INCOMES_AND_EXPENDITURES_PER_MONTH_BAR);
 		charts.add(CHART_INCOMES_AND_EXPENDITURES_PER_MONTH_LINE);
+		charts.add(CHART_INCOMES_AND_EXPENDITURES_BY_CATEGORY_BAR);
 
 		charts.sort(Comparator.comparing(Chart::getName));
 		return charts;
diff --git a/src/main/resources/charts/IncomesAndExpendituresByCategoryBar.js b/src/main/resources/charts/IncomesAndExpendituresByCategoryBar.js
new file mode 100644
index 0000000000000000000000000000000000000000..218f4d545678b0925c8e26fa0c339fe3d3c7d4cf
--- /dev/null
+++ b/src/main/resources/charts/IncomesAndExpendituresByCategoryBar.js
@@ -0,0 +1,118 @@
+/* This list will be dynamically filled with all the transactions between
+ * the start and and date you select on the "Show Chart" page
+ * and filtered according to your specified filter.
+ * An example entry for this list and tutorial about how to create custom charts ca be found in the BudgetMaster wiki:
+ * https://github.com/deadlocker8/BudgetMaster/wiki/How-to-create-custom-charts
+ */
+var transactionData = [];
+
+// Note: All variables starting with "localized" are only available inside default charts.
+
+var categoryNames = [];
+var incomes = [];
+var expenditures = [];
+
+for(var i = 0; i < transactionData.length; i++)
+{
+    var transaction = transactionData[i];
+
+    var categoryName = transaction.category.name;
+    // create new category is not already in dict
+    if(!categoryNames.includes(categoryName))
+    {
+        categoryNames.push(categoryName);
+        incomes.push(0);
+        expenditures.push(0);
+    }
+
+    // determine index of categoryName in list because the transactions are not ordered by category and some categories
+    // will be missing either for income or expenditures
+    var index = categoryNames.indexOf(categoryName);
+
+    // add to income or expenditure sum
+    var amount = transaction.amount;
+    if(amount > 0)
+    {
+        incomes[index] = incomes[index] + amount;
+    } else
+    {
+        expenditures[index] = expenditures[index] + Math.abs(amount);
+    }
+}
+
+// calculate total sums
+var totalIncomes = 0;
+var totalExpenditures = 0;
+
+incomes.forEach(function(value)
+{
+    totalIncomes += value;
+});
+
+expenditures.forEach(function(value)
+{
+    totalExpenditures += value;
+});
+
+
+// Prepare your chart settings here (mandatory)
+var plotlyData = [];
+
+for(var j = 0; j < categoryNames.length; j++)
+{
+    var percentageIncome = (100 / totalIncomes) * incomes[j];
+    var percentageExpenditure = (100 / totalExpenditures) * expenditures[j];
+
+    var textIncome = prepareHoverText(percentageIncome, incomes[j]);
+    var textExpenditure = prepareHoverText(percentageExpenditure, expenditures[j]);
+
+    plotlyData.push({
+        x: [percentageExpenditure, percentageIncome],
+        y: [localizedData['label1'], localizedData['label2']],
+        orientation: 'h',
+        type: 'bar',
+        hoverinfo: 'text',
+        text: [textExpenditure, textIncome],
+        name: categoryNames[j]
+    });
+}
+
+
+// Add your Plotly layout settings here (optional)
+var plotlyLayout = {
+    title: {
+        text: localizedTitle
+    },
+    xaxis: {
+        showgrid: false,
+        showticklabels: false
+    },
+    yaxis: {
+        tickangle: 90,
+        tickfont: {
+            family: 'sans-serif',
+            size: 14,
+            color: 'black'
+        }
+    },
+    barmode: 'stack',
+    hovermode: 'closest'
+};
+
+// Add your Plotly configuration settings here (optional)
+var plotlyConfig = {
+    showSendToCloud: false,
+    displaylogo: false,
+    showLink: false,
+    responsive: true
+};
+
+// Don't touch this line
+Plotly.newPlot('chart-canvas', plotlyData, plotlyLayout, plotlyConfig);
+
+
+function prepareHoverText(percentage, value)
+{
+    value = value / 100;
+    return percentage.toFixed(1) + '% (' + value.toFixed(1) + ' ' + localizedCurrency + ')';
+}
\ No newline at end of file
diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties
index fe0810c4979b20301da7ace915093de48479ecef..edec359bdae79ddfa7b2f0be9d513656d4dae0b3 100644
--- a/src/main/resources/languages/_de.properties
+++ b/src/main/resources/languages/_de.properties
@@ -335,6 +335,8 @@ charts.default.incomesAndExpendituresPerMonthBar=Eingaben/Ausgaben pro Monat (Ba
 charts.default.incomesAndExpendituresPerMonthBar.localization='{"axisY": "Summe in ", "traceName1": "Einnahmen", "traceName2": "Ausgaben"'}
 charts.default.incomesAndExpendituresPerMonthLine=Eingaben/Ausgaben pro Monat (Liniendiagramm)
 charts.default.incomesAndExpendituresPerMonthLine.localization='{"axisY": "Summe in ", "traceName1": "Einnahmen", "traceName2": "Ausgaben"'}
+charts.default.incomesAndExpendituresByCategoryBar=Eingaben/Ausgaben nach Kategorien
+charts.default.incomesAndExpendituresByCategoryBar.localization='{"label1": "Ausgaben", "label2": "Einnahmen"'}
 charts.default.categoryBudget=Verbrauch nach Kategorien
 
 chart.new.label.name=Name
diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties
index 8d69f84522fa6ed4e743d55ccef0b4ecd6bf7eeb..a35b9dbd6471ce7df957eff499e53b90b1bbe42f 100644
--- a/src/main/resources/languages/_en.properties
+++ b/src/main/resources/languages/_en.properties
@@ -335,6 +335,8 @@ charts.default.incomesAndExpendituresPerMonthBar=Incomes/Expenditures per month
 charts.default.incomesAndExpendituresPerMonthBar.localization='{"axisY": "Sum in ", "traceName1": "Incomes", "traceName2": "Expenditures"'}
 charts.default.incomesAndExpendituresPerMonthLine=Incomes/Expenditures per month (Line chart)
 charts.default.incomesAndExpendituresPerMonthLine.localization='{"axisY": "Sum in ", "traceName1": "Incomes", "traceName2": "Expenditures"'}
+charts.default.incomesAndExpendituresByCategoryBar=Incomes/Expenditures by categories
+charts.default.incomesAndExpendituresByCategoryBar.localization='{"label1": "Expenditures", "label2": "Incomes"'}
 charts.default.categoryBudget=Consumption by categories
 
 chart.new.label.name=Name
diff --git a/src/main/resources/templates/charts/charts.ftl b/src/main/resources/templates/charts/charts.ftl
index a17fd595722ab416516a8d87ccfe1722c7ca0d80..a23798e510e9b0b63da6d3c4b0d12763a39f2a57 100644
--- a/src/main/resources/templates/charts/charts.ftl
+++ b/src/main/resources/templates/charts/charts.ftl
@@ -172,7 +172,7 @@
                     localizedData = JSON.parse('${locale.getString(chart.getName() + ".localization")}');
                 </#if>
 
-                ${chart.getScript()?replace("var transactionData = []", "var transactionData = ${transactionData};")}
+                ${chart.getScript()?replace("var transactionData = [];", "var transactionData = ${transactionData};")}
             </script>
         </#if>
     </body>