Feature: Charts in the dashboard for Cash Flow and Creditors using nvd3.js and d3.js
It is still a work in progress with not all charts supporting dynamic data. But working enough to be put in production use.
This commit is contained in:
1 parent
e5f8a4f86f
commit
89e1443b48
12 files changed
+15534
-5
No files matched your search
+141
@@ -200,3 +200,144 @@ overlord_directive.directive('tanClick', ['$parse', '$timeout', function ($parse
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
overlord_directive.directive('chartDiscreteBar', ['$parse', function ($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
nv.addGraph(function () {
|
||||
var chart = nv.models.discreteBarChart()
|
||||
.x(function (d) {return d.label;})
|
||||
.y(function (d) {return d.value;})
|
||||
.staggerLabels(true)
|
||||
.tooltips(false)
|
||||
.showValues(true);
|
||||
|
||||
var data = $parse(attrs.chartDiscreteBar)(scope);
|
||||
d3.select('#' + attrs.id + ' svg')
|
||||
.datum(data)
|
||||
.transition().duration(500)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
overlord_directive.directive('chartMultiBar', ['$parse', function ($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
nv.addGraph(function () {
|
||||
var chart = nv.models.multiBarChart();
|
||||
|
||||
var data = $parse(attrs.chartMultiBar)(scope);
|
||||
d3.select('#' + attrs.id + ' svg')
|
||||
.datum(data)
|
||||
.transition().duration(500)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
overlord_directive.directive('chartLine', ['$parse', function ($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
nv.addGraph(function () {
|
||||
var chart = nv.models.lineChart();
|
||||
chart.xAxis.axisLabel('Date').tickFormat(function (d) {
|
||||
return d3.time.format('%b %d')(new Date(d));
|
||||
});
|
||||
var data = $parse(attrs.chartLine)(scope);
|
||||
d3.select('#' + attrs.id + ' svg')
|
||||
.datum(data)
|
||||
.transition().duration(500)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
overlord_directive.directive('chartPie', ['$parse', function ($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
var chart;
|
||||
scope.$watch(attrs.chartPie, function (data) {
|
||||
if (!angular.isUndefined(chart)) {
|
||||
d3.select('#' + attrs.id + ' svg')
|
||||
.datum(data)
|
||||
.transition().duration(1200)
|
||||
.call(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
nv.addGraph(function () {
|
||||
chart = nv.models.pieChart()
|
||||
.x(function (d) {return d.label;})
|
||||
.y(function (d) {return d.value;})
|
||||
.showLabels(true);
|
||||
// var data = $parse(attrs.chartPie)(scope);
|
||||
d3.select('#' + attrs.id + ' svg')
|
||||
.datum(data)
|
||||
.transition().duration(1200)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
overlord_directive.directive('chartLinePlusBar', ['$parse', function ($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
var chart;
|
||||
scope.$watch(attrs.chartLinePlusBar, function (data) {
|
||||
if (!angular.isUndefined(chart)) {
|
||||
d3.select('#' + attrs.id + ' svg')
|
||||
.datum(data)
|
||||
.transition().duration(500)
|
||||
.call(chart);
|
||||
return chart;
|
||||
}
|
||||
nv.addGraph(function () {
|
||||
chart = nv.models.linePlusBarChart()
|
||||
.x(function (d) {return d.label;})
|
||||
.y(function (d) {return d.value;});
|
||||
chart.xAxis.axisLabel('Date').tickFormat(function (d) {
|
||||
return d3.time.format('%b %d')(new Date(d));
|
||||
});
|
||||
chart.bars.forceY([0]);
|
||||
// var data = $parse(attrs.chartLinePlusBar)(scope);
|
||||
d3.select('#' + attrs.id + ' svg')
|
||||
.datum(data)
|
||||
.transition().duration(500)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var HomeCtrl = ['$scope', '$location', 'messages', 'Message', function ($scope, $location, messages, Message) {
|
||||
var HomeCtrl = ['$scope', '$location', '$http', 'dateFilter', 'messages', 'dashboard', 'Message', function ($scope, $location, $http, dateFilter, messages, dashboard, Message) {
|
||||
$scope.chosen = messages.Type;
|
||||
$scope.dashboard = dashboard;
|
||||
$scope.info = messages.Threads;
|
||||
$scope.tags = messages.Tags;
|
||||
$scope.getMessages = function (type) {
|
||||
@@ -18,9 +19,98 @@ var HomeCtrl = ['$scope', '$location', 'messages', 'Message', function ($scope,
|
||||
$scope.chosen = result.Type;
|
||||
});
|
||||
};
|
||||
$scope.getDashboard = function () {
|
||||
var start_date = angular.isDate($scope.dashboard.StartDate) ? dateFilter($scope.dashboard.StartDate, 'dd-MMM-yyyy') : $scope.dashboard.StartDate;
|
||||
var finish_date = angular.isDate($scope.dashboard.FinishDate) ? dateFilter($scope.dashboard.FinishDate, 'dd-MMM-yyyy') : $scope.dashboard.FinishDate;
|
||||
return $http({ method: 'GET', url: '/api/Dashboard', params: {s: start_date, f: finish_date}}).then(function (data, status, headers, config) {
|
||||
$scope.dashboard = data.data;
|
||||
formatData();
|
||||
});
|
||||
};
|
||||
function formatData() {
|
||||
$scope.Data = {};
|
||||
if ('Cash' in $scope.dashboard) {
|
||||
$scope.Data.HasCash = true;
|
||||
$scope.Data.Cash = {
|
||||
Pie: _.chain($scope.dashboard.Cash.Details)
|
||||
.reduce(function (accumulator, value, index, collection) {
|
||||
if (accumulator.length < 4) {
|
||||
accumulator.push(value);
|
||||
} else if (accumulator.length === 4) {
|
||||
accumulator.push({Name: 'Others', Amount: value.Amount});
|
||||
} else {
|
||||
accumulator[4].Amount += value.Amount;
|
||||
}
|
||||
return accumulator;
|
||||
}, [])
|
||||
.map(function (item) {
|
||||
return {label: item.Name.substr(0, 5), value: item.Amount};
|
||||
})
|
||||
.value(),
|
||||
LinePlusBar: [
|
||||
{
|
||||
key: "Total Cash",
|
||||
values: _.map($scope.dashboard.Cash.Daily, function (item) {
|
||||
return {label: new Date(item.Date).getTime(), value: item.Amount};
|
||||
})
|
||||
},
|
||||
{
|
||||
key: "Cash Flow",
|
||||
bar: true,
|
||||
values: _.map($scope.dashboard.Cash.Changes, function (item) {
|
||||
return {label: new Date(item.Date).getTime(), value: item.Amount};
|
||||
})
|
||||
}
|
||||
],
|
||||
Total: _.last($scope.dashboard.Cash.Daily).Amount
|
||||
};
|
||||
}
|
||||
if ('Creditors' in $scope.dashboard) {
|
||||
$scope.Data.HasCreditors = true;
|
||||
$scope.Data.Creditors = {
|
||||
Pie: _.chain($scope.dashboard.Creditors.Details)
|
||||
.reduceRight(function (accumulator, value, index, collection) {
|
||||
if (accumulator.length < 4) {
|
||||
accumulator.push(value);
|
||||
} else if (accumulator.length === 4) {
|
||||
accumulator.push({Name: 'Others', Amount: value.Amount});
|
||||
} else {
|
||||
accumulator[4].Amount += value.Amount;
|
||||
}
|
||||
return accumulator;
|
||||
}, [])
|
||||
.map(function (item) {
|
||||
return {label: item.Name.substr(0, 5), value: item.Amount * -1};
|
||||
})
|
||||
.value(),
|
||||
LinePlusBar: [
|
||||
{
|
||||
key: "Total Creditors",
|
||||
values: _.map($scope.dashboard.Creditors.Daily, function (item) {
|
||||
return {label: new Date(item.Date).getTime(), value: item.Amount * -1};
|
||||
})
|
||||
},
|
||||
{
|
||||
key: "Change in Creditors",
|
||||
bar: true,
|
||||
values: _.map($scope.dashboard.Creditors.Changes, function (item) {
|
||||
return {label: new Date(item.Date).getTime(), value: item.Amount * -1};
|
||||
})
|
||||
}
|
||||
],
|
||||
Total: _.last($scope.dashboard.Creditors.Daily).Amount * -1
|
||||
};
|
||||
}
|
||||
}
|
||||
formatData();
|
||||
}];
|
||||
HomeCtrl.resolve = {
|
||||
messages: ['Message', function (Message) {
|
||||
return Message.query({type: 'open'}).$promise;
|
||||
}]
|
||||
}],
|
||||
dashboard: ['$http', function ($http) {
|
||||
return $http.get('/api/Dashboard', {}).then(function (data, status, headers, config) {
|
||||
return data.data;
|
||||
});
|
||||
} ]
|
||||
};
|
||||
Reference in new issue
Block a user