Select Git revision
IncomesAndExpendituresByCategoryPie.js
-
Robert Goldmann authoredRobert Goldmann authored
IncomesAndExpendituresByCategoryPie.js 4.98 KiB
/* 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.
// objects for easier handling of categories with corresponding sums
class CategorySum
{
constructor(categoryName, color)
{
this.categoryName = categoryName;
this.color = color;
this.amount = 0;
}
add(amount)
{
this.amount += amount;
}
}
CategorySum.prototype.toString = function(){return this.categoryName + " , " + this.amount;};
class CategorySumHandler
{
constructor()
{
this.sums = [];
}
getByCategoryName(categoryName)
{
return this.sums.find(obj => {
return obj.categoryName === categoryName
});
}
add(categorySum)
{
this.sums.push(categorySum);
}
getTotalSum()
{
var total = 0;
this.sums.forEach(function(sum)
{
total += sum.amount;
});
return total;
}
static sortNumber(a, b)
{
return a.amount - b.amount;
}
getSumsSorted()
{
var sumsSorted = this.sums.filter(function(item){
return item.amount !== 0;
});
return sumsSorted.sort(CategorySumHandler.sortNumber);
}
}
var incomeHandler = new CategorySumHandler();
var expenditureHandler = new CategorySumHandler();
for(var i = 0; i < transactionData.length; i++)
{
var transaction = transactionData[i];
var categoryName = transaction.category.name;
// create new category if not already in dict
if(incomeHandler.getByCategoryName(categoryName) === undefined)
{
incomeHandler.add(new CategorySum(categoryName, transaction.category.color));
}
if(expenditureHandler.getByCategoryName(categoryName) === undefined)
{
expenditureHandler.add(new CategorySum(categoryName, transaction.category.color));
}
var amount = transaction.amount;
if(amount > 0)
{
incomeHandler.getByCategoryName(categoryName).add(amount);
}
else
{
expenditureHandler.getByCategoryName(categoryName).add(Math.abs(amount));
}
}
// Prepare your chart settings here (mandatory)
var plotlyData = addSeries(incomeHandler, 0);
plotlyData = plotlyData.concat(addSeries(expenditureHandler, 1));
// Add your Plotly layout settings here (optional)
var plotlyLayout = {
title: {
text: localizedTitle
},
hovermode: 'closest', // show hover popup only for hovered item
grid: {rows: 1, columns: 2},
annotations: [
{
font: {
size: 20
},
xref: "paper",
yref: "paper",
xanchor: "center",
yanchor: "top",
showarrow: false,
text: localizedData['label2'],
x: 0.25,
y: 0
},
{
font: {
size: 20
},
xref: "paper",
yref: "paper",
xanchor: "center",
yanchor: "top",
showarrow: false,
text: localizedData['label1'],
x: 0.75,
y: 0
}
],
};
// Add your Plotly configuration settings here (optional)
var plotlyConfig = {
showSendToCloud: false,
displaylogo: false,
showLink: false,
responsive: true,
displayModeBar: true,
toImageButtonOptions: {
format: 'png',
filename: 'BudgetMaster_chart_export',
height: 1080,
width: 1920,
}
};
// Don't touch this line
Plotly.newPlot("containerID", plotlyData, plotlyLayout, plotlyConfig);
function addSeries(sumHandler, column)
{
var plotlyData = [];
var total = sumHandler.getTotalSum();
var sums = sumHandler.getSumsSorted();
var values = sums.map(item => item.amount);
var colors = sums.map(item => item.color);
var labels = sums.map(item => item.categoryName);
var hoverTexts = sums.map((item, index) => `
${labels[index]}<br>
${(values[index]/100).toFixed(1) + ' ' + localizedCurrency}<br>
${(values[index] / total * 100).toFixed(1)}%
`);
var borders = sums.map(item => {
if(item.color.toUpperCase().startsWith('#FFFFFF'))
{
return 1;
}
return 0;
});
plotlyData.push({
values: values,
labels: labels,
type: 'pie',
text: hoverTexts,
hoverinfo: 'text',
textinfo: 'none',
marker: {
colors: colors,
line: {
color: '#212121',
width: borders
}
},
domain: {
row: 0,
column: column,
},
});
return plotlyData;
}