// vim: set tw=80 ts=2 sw=2 sts=2: import * as moment from 'moment'; import * as c3 from 'c3'; import { Component, ElementRef, Inject, Input, Output, EventEmitter, OnInit, OnChanges } from '@angular/core'; import { Account } from '../accounts/account'; import { DailyBalanceService } from '../accounts/dailyBalance.service'; class DateRange { minDate: Date; maxDate: Date; } @Component({ selector: 'balance-chart', template: '
' }) export class BalanceChartComponent implements OnInit, OnChanges { @Input() account: Account; @Output() onUpdate: EventEmitter = new EventEmitter(); private chart: c3.ChartAPI; private balances: number[]; constructor( private elementRef: ElementRef, private dailyBalanceService: DailyBalanceService, @Inject('accountIdService') private accountIdService, ) { } loadData(account: Account) { this.dailyBalanceService.query( account.id ).subscribe((results) => { var headers: any[][] = [['date', 'balances', 'expenses', 'revenues']]; 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({ minDate: balances[0], maxDate: balances[balances.length - 1] }); }); }; 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) { if(this.chart) { this.chart.ygrids([ { value: 0, axis: 'y2' }, { value: 0, axis: 'y', class: 'zeroline'}, ]); if(account) { this.chart.ygrids.add({ value: account.authorized_overdraft, axis: 'y', class: 'overdraft' }); } } }; ngOnChanges(changes) { if('account' in changes && changes.account.currentValue) { this.loadData(changes.account.currentValue); this.setLines(changes.account.currentValue); } else { this.setLines(this.account); } }; }