mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-05-06 05:01:48 +02:00
Moved JS to separate file, removed bar chart
This commit is contained in:
parent
918d4a3c3c
commit
a2c3364266
5 changed files with 185 additions and 227 deletions
|
@ -129,7 +129,7 @@ class Project(db.Model):
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"member": member,
|
"member": member._to_serialize,
|
||||||
"paid": sum(
|
"paid": sum(
|
||||||
[
|
[
|
||||||
bill.converted_amount
|
bill.converted_amount
|
||||||
|
|
178
ihatemoney/static/js/charts.js
Normal file
178
ihatemoney/static/js/charts.js
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
function populateCharts(member_stats, months_in, monthly_stats) {
|
||||||
|
|
||||||
|
var members = [];
|
||||||
|
var total_per_member = ['CurrentBalance'];
|
||||||
|
var total_exp_per_member = {};
|
||||||
|
member_stats.forEach(function(stat) {
|
||||||
|
var member_name = stat.member.name;
|
||||||
|
members.push(member_name)
|
||||||
|
var val = stat.balance;
|
||||||
|
total_per_member.push(val);
|
||||||
|
total_exp_per_member[member_name] = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//Start of chart for total expenditure per month
|
||||||
|
var month_to_int = {
|
||||||
|
"Jan": 1,
|
||||||
|
"Feb": 2,
|
||||||
|
"Mar": 3,
|
||||||
|
"Apr": 4,
|
||||||
|
"May": 5,
|
||||||
|
"Jun": 6,
|
||||||
|
"Jul": 7,
|
||||||
|
"Aug": 8,
|
||||||
|
"Sep": 9,
|
||||||
|
"Oct": 10,
|
||||||
|
"Nov": 11,
|
||||||
|
"Dec": 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
var months =[];
|
||||||
|
var exp_per_month = [];
|
||||||
|
//date_time is of form Sun, 11 Apr 2021 12:50:23 GMT
|
||||||
|
|
||||||
|
months_in.forEach(function(date_time) {
|
||||||
|
var month_year = monthYearStr(date_time);
|
||||||
|
// month_year is of form Apr 2021
|
||||||
|
var year = parseInt(month_year.slice(4, 8));
|
||||||
|
var month = month_year.slice(0,3);
|
||||||
|
months.push(month_year);
|
||||||
|
exp_per_month.push(monthly_stats[year][month_to_int[month]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
months.reverse();
|
||||||
|
exp_per_month.reverse()
|
||||||
|
exp_per_month.splice(0,0,"Combined Monthly Expenditure");
|
||||||
|
|
||||||
|
|
||||||
|
var exp_per_month_chart = bb.generate({
|
||||||
|
title: {
|
||||||
|
text: "Combined Monthly Expenditure"
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
columns: [
|
||||||
|
exp_per_month
|
||||||
|
],
|
||||||
|
type: "line",
|
||||||
|
},
|
||||||
|
axis: {
|
||||||
|
x: {
|
||||||
|
type: "category",
|
||||||
|
categories: months
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
label: "Expenditure"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bindto: "#combinedPerMonth"
|
||||||
|
});
|
||||||
|
|
||||||
|
// End of total expenditure per month chart
|
||||||
|
|
||||||
|
// Start of expenditure per member per month chart
|
||||||
|
var members_exp_by_month = [];
|
||||||
|
member_stats.forEach(function(stat) {
|
||||||
|
var month_dict = [];
|
||||||
|
var month_amount = {};
|
||||||
|
stat.monthly_exp.forEach(function(data) {
|
||||||
|
// data is a tuple with a datetime object (Mon Year) at index 0 and amount at idx 1.
|
||||||
|
month_dict.push({
|
||||||
|
date: monthYearStr(data[0]),
|
||||||
|
amount: data[1],
|
||||||
|
});
|
||||||
|
var date = monthYearStr(data[0]);
|
||||||
|
month_amount[date] = data[1] ;
|
||||||
|
total_exp_per_member[stat.member.name] += data[1];
|
||||||
|
});
|
||||||
|
month_dict.reverse();
|
||||||
|
|
||||||
|
members_exp_by_month.push({
|
||||||
|
name: stat.member.name,
|
||||||
|
exp_by_month: month_dict,
|
||||||
|
member_months: month_amount,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var member_exp_dict = {};
|
||||||
|
|
||||||
|
members_exp_by_month.forEach(function(member) {
|
||||||
|
// inserting the name of the member as the first element of the array, as per bb docs
|
||||||
|
member_exp_dict[member.name] = [member.name];
|
||||||
|
});
|
||||||
|
|
||||||
|
var chart_columns = [];
|
||||||
|
months.forEach(function(month) {
|
||||||
|
members_exp_by_month.forEach(function(member) {
|
||||||
|
// If current member had expenditure on current month
|
||||||
|
if (month in member.member_months) {
|
||||||
|
member_exp_dict[member.name].push(member.member_months[month]);
|
||||||
|
} else {
|
||||||
|
member_exp_dict[member.name].push(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Pushing each individual member's expenditure per month array into the chart array
|
||||||
|
// chart array is what is given to bb.generate
|
||||||
|
members_exp_by_month.forEach(function(member) {
|
||||||
|
chart_columns.push(member_exp_dict[member.name]);
|
||||||
|
});
|
||||||
|
var members_exp_month_chart = bb.generate({
|
||||||
|
title: {
|
||||||
|
text: "Monthly Expenditure Per Member"
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
columns: chart_columns,
|
||||||
|
type: "line"
|
||||||
|
},
|
||||||
|
axis: {
|
||||||
|
x: {
|
||||||
|
type: "category",
|
||||||
|
categories: months,
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
label: "Expenditure"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bindto: "#memberPerMonth"
|
||||||
|
});
|
||||||
|
|
||||||
|
//end of expenditure per month per member
|
||||||
|
|
||||||
|
// Start of Expenditure Pie Chart
|
||||||
|
pie_cols = [];
|
||||||
|
members_exp_by_month.forEach(function(member) {
|
||||||
|
var particpant = member.name;
|
||||||
|
var spent = total_exp_per_member[member.name];
|
||||||
|
var exp_arr = [particpant, spent];
|
||||||
|
pie_cols.push(exp_arr);
|
||||||
|
});
|
||||||
|
|
||||||
|
var pie = bb.generate({
|
||||||
|
data: {
|
||||||
|
columns: pie_cols,
|
||||||
|
type: "pie",
|
||||||
|
},
|
||||||
|
bindto: "#expPie"
|
||||||
|
});
|
||||||
|
|
||||||
|
// End of Expenditure Pie Chart
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function monthYearStr(date_time) {
|
||||||
|
//date_time is of form Sun, 11 Apr 2021 12:50:23 GMT
|
||||||
|
var start_date_idx = date_time.indexOf(',') + 2;
|
||||||
|
var end_date_idx = date_time.indexOf(':') - 3;
|
||||||
|
var date = date_time.slice(start_date_idx, end_date_idx);
|
||||||
|
// date in the form 11 Apr 2021
|
||||||
|
// date in the form 11 Apr 2021
|
||||||
|
var month_start_idx = date.indexOf(' ') + 1;
|
||||||
|
var month = date.slice(month_start_idx, month_start_idx + 3);
|
||||||
|
var year_start_idx = date.lastIndexOf(' ') + 1;
|
||||||
|
var year = parseInt(date.slice(year_start_idx, year_start_idx + 4));
|
||||||
|
var month_year = month + ' ' + year.toString();
|
||||||
|
// returns date in form Apr 2021
|
||||||
|
return month_year;
|
||||||
|
}
|
2
ihatemoney/static/js/d3.v6.min.js
vendored
Normal file
2
ihatemoney/static/js/d3.v6.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -7,7 +7,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel=stylesheet type=text/css href="{{ url_for("static", filename='css/main.css') }}">
|
<link rel=stylesheet type=text/css href="{{ url_for("static", filename='css/main.css') }}">
|
||||||
<!-- Load d3.js -->
|
<!-- Load d3.js -->
|
||||||
<script src="https://d3js.org/d3.v6.min.js" charset="utf-8"></script>
|
<script src="{{ url_for("static", filename='js/d3.v6.min.js') }}" charset="utf-8"></script>
|
||||||
<!-- Load billboard.js with base style -->
|
<!-- Load billboard.js with base style -->
|
||||||
<link rel="stylesheet" href="{{url_for("static", filename='css/billboard.min.css')}}">
|
<link rel="stylesheet" href="{{url_for("static", filename='css/billboard.min.css')}}">
|
||||||
<script src="{{ url_for("static", filename='js/billboard.min.js')}}"></script>
|
<script src="{{ url_for("static", filename='js/billboard.min.js')}}"></script>
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
<script src="{{ url_for("static", filename="js/popper.min.js") }}"></script>
|
<script src="{{ url_for("static", filename="js/popper.min.js") }}"></script>
|
||||||
<script src="{{ url_for("static", filename="js/tagsinput.js") }}"></script>
|
<script src="{{ url_for("static", filename="js/tagsinput.js") }}"></script>
|
||||||
<script src="{{ url_for("static", filename="js/bootstrap.min.js") }}"></script>
|
<script src="{{ url_for("static", filename="js/bootstrap.min.js") }}"></script>
|
||||||
|
<script src="{{ url_for("static", filename="js/charts.js") }}"></script>
|
||||||
{%- if request.path == "/dashboard" %}
|
{%- if request.path == "/dashboard" %}
|
||||||
<link rel=stylesheet type=text/css href="{{ url_for("static", filename='css/datatables.min.css') }}">
|
<link rel=stylesheet type=text/css href="{{ url_for("static", filename='css/datatables.min.css') }}">
|
||||||
<script src="{{ url_for("static", filename="js/datatables.min.js") }}"></script>
|
<script src="{{ url_for("static", filename="js/datatables.min.js") }}"></script>
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="d-flex flex-column">
|
<div class="d-flex flex-column">
|
||||||
<table id="bill_table" class="split_bills table table-striped ml-md-n3">
|
<table id="bill_table" class="split_bills table table-striped ml-md-n3">
|
||||||
|
@ -36,15 +35,6 @@
|
||||||
<h2> {{ _("Visualization") }}</h2>
|
<h2> {{ _("Visualization") }}</h2>
|
||||||
|
|
||||||
|
|
||||||
<!-- Required for some style in charts, feel free to move from here -->
|
|
||||||
<style>
|
|
||||||
#balanceBar .bb-ygrid-line line {stroke: red;}
|
|
||||||
|
|
||||||
#balanceBar .fill_green { fill: green; }
|
|
||||||
#balanceBar .fill_red { fill: red; }
|
|
||||||
</style>
|
|
||||||
<br>
|
|
||||||
<div id="balanceBar"></div>
|
|
||||||
<br>
|
<br>
|
||||||
<div id="memberPerMonth"></div>
|
<div id="memberPerMonth"></div>
|
||||||
<br>
|
<br>
|
||||||
|
@ -53,222 +43,9 @@
|
||||||
<div id="expPie"></div>
|
<div id="expPie"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Onload does not work with divs, so in this case func call must go here-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var members = [];
|
populateCharts({{ members_stats|tojson }}, {{ months|tojson }}, {{ monthly_stats|tojson }});
|
||||||
var total_per_member = ['CurrentBalance'];
|
|
||||||
var total_exp_per_member = {};
|
|
||||||
var balance_min_value = Number.POSITIVE_INFINITY;
|
|
||||||
var balance_max_value = Number.NEGATIVE_INFINITY;
|
|
||||||
{% for stat in members_stats %}
|
|
||||||
var member_name = "{{ stat.member.name }}"
|
|
||||||
members.push(member_name)
|
|
||||||
var val = {{ stat.balance }};
|
|
||||||
total_per_member.push(val);
|
|
||||||
total_exp_per_member[member_name] = 0;
|
|
||||||
if (val > balance_max_value) {
|
|
||||||
balance_max_value = val;
|
|
||||||
}
|
|
||||||
if (val < balance_min_value) {
|
|
||||||
balance_min_value = val;
|
|
||||||
}
|
|
||||||
{% endfor %}
|
|
||||||
//TODO: Remove this, its for debugging.
|
|
||||||
members.forEach(function(entry) {
|
|
||||||
console.log(entry);
|
|
||||||
});
|
|
||||||
//TODO: Remove this, its for debugging.
|
|
||||||
total_per_member.forEach(function(entry) {
|
|
||||||
console.log(entry);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Start of current balance per month chart
|
|
||||||
var balance_bar = bb.generate({
|
|
||||||
title: {
|
|
||||||
text: "Current Balance per Member"
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
columns: [
|
|
||||||
total_per_member
|
|
||||||
],
|
|
||||||
type: "bar",
|
|
||||||
colors: {
|
|
||||||
CurrentBalance: "#999C9F",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axis: {
|
|
||||||
x: {
|
|
||||||
type: "category",
|
|
||||||
categories: members
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
label: "Expenditure"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
y: {
|
|
||||||
lines: [
|
|
||||||
{
|
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
regions: [
|
|
||||||
{
|
|
||||||
axis:"y",
|
|
||||||
start: 0,
|
|
||||||
end: balance_max_value,
|
|
||||||
class: "fill_green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
axis:"y",
|
|
||||||
start: balance_min_value,
|
|
||||||
end: 0,
|
|
||||||
class: "fill_red"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
bar: {
|
|
||||||
width: {
|
|
||||||
ratio: 0.5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bindto: "#balanceBar"
|
|
||||||
});
|
|
||||||
// End of current balance per month chart
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Start of chart for total expenditure per month
|
|
||||||
var months =[];
|
|
||||||
var exp_per_month = [];
|
|
||||||
{% for month in months %}
|
|
||||||
var month_year = "{{ _(month.strftime("%B")) }} {{ month.year }}";
|
|
||||||
months.push(month_year);
|
|
||||||
exp_per_month.push({{ monthly_stats[month.year][month.month] }});
|
|
||||||
{% endfor %}
|
|
||||||
months.reverse();
|
|
||||||
exp_per_month.reverse()
|
|
||||||
exp_per_month.splice(0,0,"Combined Monthly Expenditure");
|
|
||||||
//TODO: Remove this, its for debugging.
|
|
||||||
months.forEach(function(entry) {
|
|
||||||
console.log(entry);
|
|
||||||
});
|
|
||||||
|
|
||||||
var exp_per_month_chart = bb.generate({
|
|
||||||
title: {
|
|
||||||
text: "Combined Monthly Expenditure"
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
columns: [
|
|
||||||
exp_per_month
|
|
||||||
],
|
|
||||||
type: "line",
|
|
||||||
},
|
|
||||||
axis: {
|
|
||||||
x: {
|
|
||||||
type: "category",
|
|
||||||
categories: months
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
label: "Expenditure"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bindto: "#combinedPerMonth"
|
|
||||||
});
|
|
||||||
// End of total expenditure per month chart
|
|
||||||
|
|
||||||
// Start of expenditure per member per month chart
|
|
||||||
var members_exp_by_month = [];
|
|
||||||
{% for stat in members_stats|sort(attribute='member.name') %}
|
|
||||||
var month_dict = [];
|
|
||||||
var month_amount = {};
|
|
||||||
{% for data in stat.monthly_exp %}
|
|
||||||
// data is a tuple with a datetime object (Mon Year) at index 0 and amount at idx 1.
|
|
||||||
month_dict.push({
|
|
||||||
date: "{{ _(data[0].strftime("%B")) }} {{ data[0].year }}",
|
|
||||||
amount: {{ data[1] }}
|
|
||||||
});
|
|
||||||
var date = "{{ _(data[0].strftime("%B")) }} {{ data[0].year }}";
|
|
||||||
month_amount[date] = {{ data[1] }};
|
|
||||||
total_exp_per_member["{{ stat.member.name }}"] += {{ data[1] }};
|
|
||||||
{% endfor %}
|
|
||||||
month_dict.reverse();
|
|
||||||
|
|
||||||
members_exp_by_month.push({
|
|
||||||
name: "{{stat.member.name}}",
|
|
||||||
exp_by_month: month_dict,
|
|
||||||
member_months: month_amount,
|
|
||||||
});
|
|
||||||
{% endfor %}
|
|
||||||
var member_exp_dict = {};
|
|
||||||
|
|
||||||
members_exp_by_month.forEach(function(member) {
|
|
||||||
// inserting the name of the member as the first element of the array, as per bb docs
|
|
||||||
member_exp_dict[member.name] = [member.name];
|
|
||||||
});
|
|
||||||
var chart_columns = [];
|
|
||||||
months.forEach(function(month) {
|
|
||||||
members_exp_by_month.forEach(function(member) {
|
|
||||||
// If current member had expenditure on current month
|
|
||||||
if (month in member.member_months) {
|
|
||||||
member_exp_dict[member.name].push(member.member_months[month]);
|
|
||||||
} else {
|
|
||||||
member_exp_dict[member.name].push(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
console.log(member_exp_dict);
|
|
||||||
// Pushing each individual member's expenditure per month array into the chart array
|
|
||||||
// chart array is what is given to bb.generate
|
|
||||||
members_exp_by_month.forEach(function(member) {
|
|
||||||
chart_columns.push(member_exp_dict[member.name]);
|
|
||||||
});
|
|
||||||
var members_exp_month_chart = bb.generate({
|
|
||||||
title: {
|
|
||||||
text: "Monthly Expenditure Per Member"
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
columns: chart_columns,
|
|
||||||
type: "line"
|
|
||||||
},
|
|
||||||
axis: {
|
|
||||||
x: {
|
|
||||||
type: "category",
|
|
||||||
categories: months,
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
label: "Expenditure"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bindto: "#memberPerMonth"
|
|
||||||
});
|
|
||||||
|
|
||||||
//end of expenditure per month per member
|
|
||||||
|
|
||||||
// Start of Expenditure Pie Chart
|
|
||||||
pie_cols = [];
|
|
||||||
members_exp_by_month.forEach(function(member) {
|
|
||||||
var particpant = member.name;
|
|
||||||
var spent = total_exp_per_member[member.name];
|
|
||||||
var exp_arr = [particpant, spent];
|
|
||||||
pie_cols.push(exp_arr);
|
|
||||||
})
|
|
||||||
console.log(pie_cols);
|
|
||||||
var pie = bb.generate({
|
|
||||||
data: {
|
|
||||||
columns: pie_cols,
|
|
||||||
type: "pie",
|
|
||||||
},
|
|
||||||
bindto: "#expPie"
|
|
||||||
});
|
|
||||||
|
|
||||||
// End of Expenditure Pie Chart
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue