Use jqWidgets for balance chart.
This commit is contained in:
parent
a915d33a54
commit
f19403f0ea
@ -1,15 +1,15 @@
|
|||||||
// vim: set tw=80 ts=2 sw=2 sts=2:
|
// vim: set tw=80 ts=2 sw=2 sts=2:
|
||||||
|
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import * as c3 from 'c3';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component, ElementRef,
|
Component,
|
||||||
Inject, Input, Output, EventEmitter,
|
Inject, Input, Output, EventEmitter,
|
||||||
OnInit, OnChanges
|
OnChanges
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import { Account } from '../accounts/account';
|
import { Account } from '../accounts/account';
|
||||||
|
import { DailyBalance } from './dailyBalance';
|
||||||
import { DailyBalanceService } from '../accounts/dailyBalance.service';
|
import { DailyBalanceService } from '../accounts/dailyBalance.service';
|
||||||
|
|
||||||
class DateRange {
|
class DateRange {
|
||||||
@ -19,152 +19,91 @@ class DateRange {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'balance-chart',
|
selector: 'balance-chart',
|
||||||
template: '<div></div>'
|
template: `
|
||||||
|
<jqxChart #balanceChart
|
||||||
|
[width]="'100%'"
|
||||||
|
[height]="'100%'"
|
||||||
|
[title]="'Balance evolution'"
|
||||||
|
[description]="''"
|
||||||
|
[source]="data"
|
||||||
|
[xAxis]="xAxis"
|
||||||
|
[seriesGroups]="seriesGroups"
|
||||||
|
(onRangeSelectionChanged)="select($event)">
|
||||||
|
</jqxChart>
|
||||||
|
`
|
||||||
})
|
})
|
||||||
export class BalanceChartComponent implements OnInit, OnChanges {
|
export class BalanceChartComponent implements OnChanges {
|
||||||
@Input() account: Account;
|
@Input() account: Account;
|
||||||
@Output() onUpdate: EventEmitter<DateRange> = new EventEmitter<DateRange>();
|
@Output() onUpdate: EventEmitter<DateRange> = new EventEmitter<DateRange>();
|
||||||
|
|
||||||
private chart: c3.ChartAPI;
|
public data;
|
||||||
private balances: number[];
|
|
||||||
|
public xAxis: any = {
|
||||||
|
dataField: 'operation_date',
|
||||||
|
type: 'date',
|
||||||
|
baseUnit: 'day',
|
||||||
|
//unitInterval: 10,
|
||||||
|
|
||||||
|
rangeSelector: {
|
||||||
|
size: 80,
|
||||||
|
padding: { /*left: 0, right: 0,*/top: 0, bottom: 0 },
|
||||||
|
backgroundColor: 'white',
|
||||||
|
dataField: 'balance',
|
||||||
|
baseUnit: 'month',
|
||||||
|
gridLines: { visible: false },
|
||||||
|
serieType: 'line',
|
||||||
|
//labels: {
|
||||||
|
// formatFunction: (value: any): any => {
|
||||||
|
// return this.months[value.getMonth()] + '\'' + value.getFullYear().toString().substring(2);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public seriesGroups: any = [{
|
||||||
|
// type: 'column',
|
||||||
|
// series: [{
|
||||||
|
// dataField: 'revenues'
|
||||||
|
// }, {
|
||||||
|
// dataField: 'expenses'
|
||||||
|
// }]
|
||||||
|
//}, {
|
||||||
|
type: 'line',
|
||||||
|
series: [{
|
||||||
|
dataField: 'balance'
|
||||||
|
}],
|
||||||
|
bands: [{
|
||||||
|
minValue: 0, maxValue: 0, fillColor: 'orange', lineWidth: 2
|
||||||
|
}, {
|
||||||
|
minValue: 0, maxValue: 0, fillColor: 'red', lineWidth: 2
|
||||||
|
}]
|
||||||
|
}];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private elementRef: ElementRef,
|
|
||||||
private dailyBalanceService: DailyBalanceService,
|
private dailyBalanceService: DailyBalanceService,
|
||||||
) {
|
) {
|
||||||
|
this.data = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
loadData(account: Account) {
|
loadData(account: Account) {
|
||||||
this.dailyBalanceService.query(
|
this.dailyBalanceService.query(
|
||||||
account.id
|
account.id
|
||||||
).subscribe((results) => {
|
).subscribe((results) => {
|
||||||
var headers: any[][] = [['date', 'balances', 'expenses', 'revenues']];
|
this.data = results;
|
||||||
|
|
||||||
var rows = results.map(function(result) {
|
|
||||||
return [
|
|
||||||
result.operation_date,
|
|
||||||
result.balance,
|
|
||||||
result.expenses,
|
|
||||||
result.revenues
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
this.chart.unload();
|
|
||||||
|
|
||||||
this.chart.load({
|
|
||||||
rows: headers.concat(rows)
|
|
||||||
});
|
|
||||||
|
|
||||||
var x: any;
|
|
||||||
|
|
||||||
x = this.chart.x();
|
|
||||||
|
|
||||||
var balances = x.balances;
|
|
||||||
|
|
||||||
this.onUpdate.emit({
|
this.onUpdate.emit({
|
||||||
minDate: balances[0],
|
minDate: moment(results[0].operation_date).toDate(),
|
||||||
maxDate: balances[balances.length - 1]
|
maxDate: moment(results[results.length - 1].operation_date).toDate()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
var tomorrow = moment().endOf('day').valueOf();
|
|
||||||
|
|
||||||
this.chart = c3.generate({
|
|
||||||
bindto: this.elementRef.nativeElement.children[0],
|
|
||||||
size: {
|
|
||||||
height: 450,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
x: 'date',
|
|
||||||
rows: [],
|
|
||||||
axes: {
|
|
||||||
expenses: 'y2',
|
|
||||||
revenues: 'y2'
|
|
||||||
},
|
|
||||||
type: 'bar',
|
|
||||||
types: {
|
|
||||||
balances: 'area'
|
|
||||||
},
|
|
||||||
groups: [
|
|
||||||
['expenses', 'revenues']
|
|
||||||
],
|
|
||||||
// Disable for the moment because there is an issue when
|
|
||||||
// using subchart line is not refreshed after subset
|
|
||||||
// selection.
|
|
||||||
//regions: {
|
|
||||||
// balances: [{
|
|
||||||
// start: tomorrow,
|
|
||||||
// style: 'dashed'
|
|
||||||
// }]
|
|
||||||
//}
|
|
||||||
},
|
|
||||||
regions: [{
|
|
||||||
start: tomorrow,
|
|
||||||
}],
|
|
||||||
axis: {
|
|
||||||
x: {
|
|
||||||
type: 'timeseries',
|
|
||||||
tick: {
|
|
||||||
format: '%Y-%m-%d',
|
|
||||||
rotate: 50,
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
y: {
|
|
||||||
label: {
|
|
||||||
text: 'Amount',
|
|
||||||
position: 'outer-middle'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
y2: {
|
|
||||||
show: true,
|
|
||||||
label: {
|
|
||||||
text: 'Amount',
|
|
||||||
position: 'outer-middle'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
x: {
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
show: true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
format: {
|
|
||||||
value: function(value, ratio, id, index) {
|
|
||||||
return value + '€';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
subchart: {
|
|
||||||
show: true,
|
|
||||||
onbrush: (domain) => {
|
|
||||||
this.onUpdate.emit({minDate: domain[0], maxDate: domain[1]});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
setLines(account: Account) {
|
setLines(account: Account) {
|
||||||
if(this.chart) {
|
|
||||||
this.chart.ygrids([
|
|
||||||
{ value: 0, axis: 'y2' },
|
|
||||||
{ value: 0, axis: 'y', class: 'zeroline'},
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (account) {
|
if (account) {
|
||||||
this.chart.ygrids.add({
|
this.seriesGroups[0].bands[1].minValue = account.authorized_overdraft;
|
||||||
value: account.authorized_overdraft,
|
this.seriesGroups[0].bands[1].maxValue = account.authorized_overdraft;
|
||||||
axis: 'y',
|
|
||||||
class: 'overdraft'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
ngOnChanges(changes) {
|
ngOnChanges(changes) {
|
||||||
if('account' in changes && changes.account.currentValue) {
|
if('account' in changes && changes.account.currentValue) {
|
||||||
@ -173,5 +112,10 @@ export class BalanceChartComponent implements OnInit, OnChanges {
|
|||||||
} else {
|
} else {
|
||||||
this.setLines(this.account);
|
this.setLines(this.account);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
select(event: any) {
|
||||||
|
let args = event.args;
|
||||||
|
this.onUpdate.emit({minDate: args.minValue, maxDate: args.maxValue});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
|||||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||||
import { ToastrModule } from 'ngx-toastr';
|
import { ToastrModule } from 'ngx-toastr';
|
||||||
import { TextMaskModule } from 'angular2-text-mask';
|
import { TextMaskModule } from 'angular2-text-mask';
|
||||||
|
import { jqxChartComponent } from 'jqwidgets-scripts/jqwidgets-ts/angular_jqxchart';
|
||||||
|
|
||||||
import { BalanceChartComponent } from './balanceChart.component';
|
import { BalanceChartComponent } from './balanceChart.component';
|
||||||
import { CategoryChartComponent } from './categoryChart.component';
|
import { CategoryChartComponent } from './categoryChart.component';
|
||||||
@ -42,6 +43,7 @@ import { OperationListState } from './operation.states';
|
|||||||
OperationService,
|
OperationService,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
|
jqxChartComponent,
|
||||||
BalanceChartComponent,
|
BalanceChartComponent,
|
||||||
CategoryChartComponent,
|
CategoryChartComponent,
|
||||||
OperationRowComponent,
|
OperationRowComponent,
|
||||||
|
Loading…
Reference in New Issue
Block a user