major overhaul in presentation
This commit is contained in:
parent
6e30dc6d83
commit
b8b2d37940
2 changed files with 150 additions and 183 deletions
|
@ -23,9 +23,9 @@ app.controller( 'DashboardCtrl',
|
||||||
// compute an account's score: from 1 (good) to 10 (bad), 0 is neutral/undecided
|
// compute an account's score: from 1 (good) to 10 (bad), 0 is neutral/undecided
|
||||||
var score_account = function ( account ) {
|
var score_account = function ( account ) {
|
||||||
if ( account.match( /^Income:(salaire|Sécu|Mutuelle)$/ ) ) {
|
if ( account.match( /^Income:(salaire|Sécu|Mutuelle)$/ ) ) {
|
||||||
return 1;
|
return 11;
|
||||||
} else if ( account.match( /^Income:(Gift|Remboursement)$/ ) ) {
|
} else if ( account.match( /^Income:(Gift|Remboursement)$/ ) ) {
|
||||||
return 6;
|
return 12;
|
||||||
} else if ( account.match( /^Expenses:(courses|Hang)$/ ) ) {
|
} else if ( account.match( /^Expenses:(courses|Hang)$/ ) ) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if ( account.match( /^Expenses:Home/ ) ) {
|
} else if ( account.match( /^Expenses:Home/ ) ) {
|
||||||
|
@ -40,14 +40,34 @@ app.controller( 'DashboardCtrl',
|
||||||
return 9;
|
return 9;
|
||||||
} else if ( account.match( /^Expenses:Gadgets/ ) ) {
|
} else if ( account.match( /^Expenses:Gadgets/ ) ) {
|
||||||
return 10;
|
return 10;
|
||||||
|
} else if ( account.match( /^Liabilities/ ) ) {
|
||||||
|
return 1000;
|
||||||
|
} else if ( account.match( /^Assets/ ) ) {
|
||||||
|
return 100;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.coloring_score = function ( score ) {
|
$scope.coloring_score = function ( score ) {
|
||||||
|
var adjusted_score = score;
|
||||||
var color_scale = [ '#99f', '#0f0', '#3f0', '#6f0', '#9f0', '#cf0', '#fc0', '#f90', '#f60', '#f30', '#f00' ];
|
var color_scale = [ '#99f', '#0f0', '#3f0', '#6f0', '#9f0', '#cf0', '#fc0', '#f90', '#f60', '#f30', '#f00' ];
|
||||||
return color_scale[ score ];
|
|
||||||
|
if ( score >= 1000 ) {
|
||||||
|
// Liabilities
|
||||||
|
adjusted_score = score - 1000;
|
||||||
|
color_scale = [ '#0ff' ];
|
||||||
|
} else if ( score >= 100 ) {
|
||||||
|
// Assets
|
||||||
|
adjusted_score = score - 100;
|
||||||
|
color_scale = [ '#f0f' ];
|
||||||
|
} else if ( score >= 11 ) {
|
||||||
|
// Income
|
||||||
|
adjusted_score = score - 11;
|
||||||
|
color_scale = [ '#ff0', '#ff9' ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return color_scale[ adjusted_score ];
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.color = function () {
|
$scope.color = function () {
|
||||||
|
@ -96,8 +116,7 @@ app.controller( 'DashboardCtrl',
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.balance = {
|
$scope.balance = {
|
||||||
buckets: [ new Bucket( 'Expenses' ),
|
buckets: [ new Bucket( 'Expenses Assets Liabilities Income' ) ],
|
||||||
new Bucket( 'Income' ) ],
|
|
||||||
details: {}
|
details: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,12 +153,6 @@ app.controller( 'DashboardCtrl',
|
||||||
$scope.total_unbudgeted = _($scope.budget).findWhere( { percentage: -1 } ).amount;
|
$scope.total_unbudgeted = _($scope.budget).findWhere( { percentage: -1 } ).amount;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
API.register( { period: period,
|
|
||||||
categories: '' } )
|
|
||||||
.then( function( response ) {
|
|
||||||
$scope.balance.details = _($scope.balance.details).extend( _(response.data.values).groupBy( 'account' ) );
|
|
||||||
} );
|
|
||||||
|
|
||||||
_($scope.balance.buckets).each( function( bucket ) {
|
_($scope.balance.buckets).each( function( bucket ) {
|
||||||
API.balance( { period: period,
|
API.balance( { period: period,
|
||||||
categories: bucket.categories } )
|
categories: bucket.categories } )
|
||||||
|
@ -153,7 +166,11 @@ app.controller( 'DashboardCtrl',
|
||||||
.sortBy( function ( account ) {
|
.sortBy( function ( account ) {
|
||||||
return 1 / account.amount;
|
return 1 / account.amount;
|
||||||
} )
|
} )
|
||||||
.value();
|
.sortBy( function ( account ) {
|
||||||
|
return account.account.split(":")[0];
|
||||||
|
} )
|
||||||
|
.value()
|
||||||
|
.reverse();
|
||||||
bucket.raw_total = _( response.data ).reduce( function ( memo, account ) {
|
bucket.raw_total = _( response.data ).reduce( function ( memo, account ) {
|
||||||
return memo + account.amount;
|
return memo + account.amount;
|
||||||
}, 0 );
|
}, 0 );
|
||||||
|
|
|
@ -1,177 +1,127 @@
|
||||||
<md-toolbar flex="100" layout="column" layout-gt-md="row" layout-align="center center">
|
<md-toolbar flex="100" layout="column" layout-gt-md="row" layout-align="center center">
|
||||||
<h2 flex="48">From {{from_date | date:'longDate'}} <span data-ng-if="to_date">to {{to_date | date:'longDate'}}</span></h2>
|
<h2 flex="48">From {{from_date | date:'longDate'}} <span data-ng-if="to_date">to {{to_date | date:'longDate'}}</span></h2>
|
||||||
<div flex="48" layout="row" layout-align="space-around center">
|
<div flex="48" layout="row" layout-align="space-around center">
|
||||||
<md-button class="md-raised md-primary"
|
<md-button class="md-raised md-primary"
|
||||||
aria-label="before"
|
aria-label="before"
|
||||||
data-ng-click="before()"
|
data-ng-click="before()"
|
||||||
data-ng-class="{'disabled': period_offset == 0}">prev</span></md-button>
|
data-ng-class="{'disabled': period_offset == 0}">prev</span></md-button>
|
||||||
<md-button class="md-raised"
|
<md-button class="md-raised"
|
||||||
aria-label="now"
|
aria-label="now"
|
||||||
data-ng-click="reset_offset()"
|
data-ng-click="reset_offset()"
|
||||||
data-ng-class="{'disabled': period_offset == dates_salaries.length - 1}">Now</md-button>
|
data-ng-class="{'disabled': period_offset == dates_salaries.length - 1}">Now</md-button>
|
||||||
<md-button class="md-raised md-primary"
|
<md-button class="md-raised md-primary"
|
||||||
aria-label="after"
|
aria-label="after"
|
||||||
data-ng-click="after()"
|
data-ng-click="after()"
|
||||||
data-ng-class="{'disabled': period_offset == dates_salaries.length}">next</buttmd-on>
|
data-ng-class="{'disabled': period_offset == dates_salaries.length}">next</buttmd-on>
|
||||||
</div>
|
</div>
|
||||||
</md-toolbar>
|
</md-toolbar>
|
||||||
<md-content flex="100" layout="column" layout-gt-md="row">
|
<md-content flex="100" layout="column" layout-gt-md="row">
|
||||||
<md-card flex="48" layout="column">
|
<md-card flex="48" layout="column">
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style="width: 11%">Account</th>
|
|
||||||
<th style="width: 3%">Spent</th>
|
|
||||||
<th style="width: 3%">Budgeted</th>
|
|
||||||
<th style="width: 3%">Percentage</th>
|
|
||||||
<th>Progress</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr data-ng-repeat="account in budget"
|
|
||||||
data-ng-class="{'even': $even, 'odd': $odd}">
|
|
||||||
<td>
|
|
||||||
{{account.account}}
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
{{account.amount | number:2}}{{account.currency}}
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
<span data-ng-if="account.percentage >= 0">{{account.budget | number:2}}{{account.currency}}</span>
|
|
||||||
<span data-ng-if="account.percentage < 0">
|
|
||||||
{{balance.buckets[1].raw_total - total_budget | number:2}}{{account.currency}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
<span data-ng-if="account.percentage >= 0">{{account.percentage | number:2}}%</span>
|
|
||||||
<span data-ng-if="account.percentage < 0">
|
|
||||||
{{( account.amount / ( balance.buckets[1].raw_total - total_budget ) ) * 100 | number:2}}%
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<md-progress-linear md-theme="red" mode="determinate" value="{{account.percentage}}"
|
|
||||||
data-ng-if="account.percentage > 100"></md-progress-linear>
|
|
||||||
<md-progress-linear md-theme="brown" mode="determinate"
|
|
||||||
value="{{( account.amount / ( balance.buckets[1].raw_total - total_budget ) ) * 100}}"
|
|
||||||
data-ng-if="account.percentage < 0"></md-progress-linear>
|
|
||||||
<md-progress-linear mode="determinate" value="{{account.percentage}}"
|
|
||||||
data-ng-if="account.percentage <= 100"></md-progress-linear>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</md-card>
|
|
||||||
<md-card flex="48" layout="column">
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style="width: 11%">Account</th>
|
|
||||||
<th style="width: 3%">Left</th>
|
|
||||||
<th style="width: 3%">Total</th>
|
|
||||||
<th style="width: 3%">Percentage</th>
|
|
||||||
<th>Progress</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr class="odd">
|
|
||||||
<td>
|
|
||||||
Balance
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
{{balance.buckets[1].raw_total - balance.buckets[0].raw_total | number:2}}{{budget[0].currency}}
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
{{balance.buckets[1].raw_total | number:2}}{{budget[0].currency}}
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
{{( ( balance.buckets[1].raw_total - balance.buckets[0].raw_total ) / balance.buckets[1].raw_total ) * 100 | number:2}}%
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<md-progress-linear md-theme="green" mode="determinate"
|
|
||||||
value="{{( ( balance.buckets[1].raw_total - balance.buckets[0].raw_total ) / balance.buckets[1].raw_total ) * 100}}"></md-progress-linear>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="even">
|
|
||||||
<td>
|
|
||||||
Potential savings
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
{{balance.buckets[1].raw_total - total_budget - total_unbudgeted | number:2}}{{budget[0].currency}}
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
{{balance.buckets[1].raw_total - total_budget | number:2}}{{budget[0].currency}}
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;">
|
|
||||||
{{( ( balance.buckets[1].raw_total - total_budget - total_unbudgeted ) / ( balance.buckets[1].raw_total - total_budget ) ) * 100 | number:2}}%
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<md-progress-linear md-theme="green" mode="determinate"
|
|
||||||
value="{{( ( balance.buckets[1].raw_total - total_budget - total_unbudgeted ) / balance.buckets[1].raw_total ) * 100}}"></md-progress-linear>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</md-card>
|
|
||||||
</md-content>
|
|
||||||
<md-content flex="100" layout="column" layout-gt-md="row">
|
|
||||||
<md-card flex="48" layout="column"
|
|
||||||
data-ng-repeat="bucket in balance.buckets">
|
|
||||||
<md-toolbar>
|
|
||||||
<h3>{{bucket.categories}}, total = {{bucket.total | number:2}} €</h3>
|
|
||||||
<md-slider discrete
|
|
||||||
aria-label="score threshold"
|
|
||||||
min="0" max="10" step="1"
|
|
||||||
data-ng-model="bucket.score_threshold"
|
|
||||||
data-ng-change="select.score_higher_than( bucket, bucket.score_threshold ); filter_data()">
|
|
||||||
</md-slider>
|
|
||||||
<select multiple
|
|
||||||
data-ng-model="bucket.accounts_selected"
|
|
||||||
data-ng-options="account.account for account in bucket.raw_data | orderBy:'account'"
|
|
||||||
data-ng-change="filter_data()">
|
|
||||||
<option value=''>...</option>
|
|
||||||
</select>
|
|
||||||
</md-toolbar>
|
|
||||||
<md-content>
|
|
||||||
<md-card>
|
|
||||||
<nvd3-pie-chart data="bucket.data"
|
|
||||||
x="xFunction()"
|
|
||||||
y="yFunction()"
|
|
||||||
height="300"
|
|
||||||
margin="{left:0,top:0,bottom:0,right:0}"
|
|
||||||
color="color()"
|
|
||||||
tooltips="true"
|
|
||||||
tooltipcontent="toolTipContentFunction()"
|
|
||||||
showLabels="true"
|
|
||||||
labelType="value">
|
|
||||||
<svg></svg>
|
|
||||||
</nvd3-pie-chart>
|
|
||||||
</md-card>
|
|
||||||
<md-card>
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th><md-buton data-ng-click="bucket.order_by( 'account' )">account</md-buton></th>
|
<th style="width: 11%">Account</th>
|
||||||
<th><md-buton data-ng-click="bucket.order_by( 'amount' )">amount</md-buton></th>
|
<th style="width: 3%">Spent</th>
|
||||||
<th><md-buton data-ng-click="bucket.order_by( 'score' )">score</md-buton></th>
|
<th style="width: 3%">Budgeted</th>
|
||||||
</tr>
|
<th style="width: 3%">Percentage</th>
|
||||||
</thead>
|
<th>Progress</th>
|
||||||
<tbody>
|
</tr>
|
||||||
<tr data-ng-repeat="account in bucket.data | orderBy:bucket.orderBy:bucket.orderDesc"
|
</thead>
|
||||||
data-ng-class="{'even': $even, 'odd': $odd}"
|
<tbody>
|
||||||
style="border-left:10px solid {{coloring_score( account.score )}};border-right:10px solid {{coloring_score( account.score )}}">
|
<tr data-ng-repeat="account in budget"
|
||||||
<td style="border-bottom:1px solid {{coloring_score( account.score )}}">
|
data-ng-class="{'even': $even, 'odd': $odd}">
|
||||||
{{account.account}}
|
<td>
|
||||||
</td>
|
{{account.account}}
|
||||||
<td style="text-align:right;border-bottom:1px solid {{coloring_score( account.score )}}">
|
</td>
|
||||||
{{account.amount | number:2}} €
|
<td style="text-align: right;">
|
||||||
</td>
|
{{account.amount | number:2}}{{account.currency}}
|
||||||
<td style="text-align:right;border-bottom:1px solid {{coloring_score( account.score )}}">
|
</td>
|
||||||
{{account.score}}
|
<td style="text-align: right;">
|
||||||
</td>
|
<span data-ng-if="account.percentage >= 0">{{account.budget | number:2}}{{account.currency}}</span>
|
||||||
</tr>
|
<span data-ng-if="account.percentage < 0">
|
||||||
</tbody>
|
{{balance.buckets[1].raw_total - total_budget | number:2}}{{account.currency}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<span data-ng-if="account.percentage >= 0">{{account.percentage | number:2}}%</span>
|
||||||
|
<span data-ng-if="account.percentage < 0">
|
||||||
|
{{( account.amount / ( balance.buckets[1].raw_total - total_budget ) ) * 100 | number:2}}%
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<md-progress-linear md-theme="red" mode="determinate" value="{{account.percentage}}"
|
||||||
|
data-ng-if="account.percentage > 100"></md-progress-linear>
|
||||||
|
<md-progress-linear md-theme="brown" mode="determinate"
|
||||||
|
value="{{( account.amount / ( balance.buckets[1].raw_total - total_budget ) ) * 100}}"
|
||||||
|
data-ng-if="account.percentage < 0"></md-progress-linear>
|
||||||
|
<md-progress-linear mode="determinate" value="{{account.percentage}}"
|
||||||
|
data-ng-if="account.percentage <= 100"></md-progress-linear>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</md-card>
|
</md-card>
|
||||||
</md-content>
|
<md-card flex="48" layout="column"
|
||||||
</md-card>
|
data-ng-repeat="bucket in balance.buckets">
|
||||||
|
<md-toolbar>
|
||||||
|
<h3>{{bucket.categories}}, total = {{bucket.total | number:2}} €</h3>
|
||||||
|
<md-slider discrete
|
||||||
|
aria-label="score threshold"
|
||||||
|
min="0" max="10" step="1"
|
||||||
|
data-ng-model="bucket.score_threshold"
|
||||||
|
data-ng-change="select.score_higher_than( bucket, bucket.score_threshold ); filter_data()">
|
||||||
|
</md-slider>
|
||||||
|
<select multiple
|
||||||
|
data-ng-model="bucket.accounts_selected"
|
||||||
|
data-ng-options="account.account for account in bucket.raw_data | orderBy:'account'"
|
||||||
|
data-ng-change="filter_data()">
|
||||||
|
<option value=''>...</option>
|
||||||
|
</select>
|
||||||
|
</md-toolbar>
|
||||||
|
<md-content>
|
||||||
|
<md-card>
|
||||||
|
<nvd3-pie-chart
|
||||||
|
data="bucket.data"
|
||||||
|
x="xFunction()"
|
||||||
|
y="yFunction()"
|
||||||
|
height="300"
|
||||||
|
margin="{left:0,top:0,bottom:0,right:0}"
|
||||||
|
color="color()"
|
||||||
|
tooltips="true"
|
||||||
|
tooltipcontent="toolTipContentFunction()"
|
||||||
|
showLabels="true"
|
||||||
|
labelType="value"
|
||||||
|
donut="true"
|
||||||
|
donutRatio="0.25">
|
||||||
|
<svg></svg>
|
||||||
|
</nvd3-pie-chart>
|
||||||
|
</md-card>
|
||||||
|
<md-card>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><md-buton data-ng-click="bucket.order_by( 'account' )">account</md-buton></th>
|
||||||
|
<th><md-buton data-ng-click="bucket.order_by( 'amount' )">amount</md-buton></th>
|
||||||
|
<th><md-buton data-ng-click="bucket.order_by( 'score' )">score</md-buton></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr data-ng-repeat="account in bucket.data | orderBy:bucket.orderBy:bucket.orderDesc"
|
||||||
|
data-ng-class="{'even': $even, 'odd': $odd}"
|
||||||
|
style="border-left:10px solid {{coloring_score( account.score )}};border-right:10px solid {{coloring_score( account.score )}}">
|
||||||
|
<td style="border-bottom:1px solid {{coloring_score( account.score )}}">
|
||||||
|
{{account.account}}
|
||||||
|
</td>
|
||||||
|
<td style="text-align:right;border-bottom:1px solid {{coloring_score( account.score )}}">
|
||||||
|
{{account.amount | number:2}} €
|
||||||
|
</td>
|
||||||
|
<td style="text-align:right;border-bottom:1px solid {{coloring_score( account.score )}}">
|
||||||
|
{{account.score}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</md-card>
|
||||||
|
</md-content>
|
||||||
|
</md-card>
|
||||||
</md-content>
|
</md-content>
|
||||||
|
|
Loading…
Add table
Reference in a new issue