var app = angular.module('plunker', ['nvd3']);
app.component('chartTotal', {
templateUrl: 'summary13.html',
bindings: {
d: '=',
title: '@',
f: '@'
}
});
app.controller('MainCtrl', function($scope) {
//need to get it from server
var periods = ["Jan-16", "Feb-16", "Mar-16", "Apr-16", "May-16", "Jun-16", "Jul-16","Aug-16", "Sep-16",
"Oct-16", "Nov-16", "Dev-16", "Jan-17"];
var chart;
$scope.getSBarOptions = function(isStacked=true, yFormat='.f')
{
//debugger;
//isStacked=true,yFormat='.f'
// var yFormat='.f';
//var isStacked = true;
//var yFormat='%';
return {
chart: {
type: 'multiBarChart',
height: 250,
margin : {
top: 25,
right: 20,
bottom: 20,
left: 45
},
//clipEdge: true,
duration: 300,
stacked: isStacked,
xAxis: {
showMaxMin: false,
tickFormat: function(d){
return d;//d3.format(',f')(d);
}
},
yAxis: {
axisLabelDistance: -10,
tickFormat: function(d){
return d3.format(',' + yFormat)(d);
}
},
groupSpacing :0.1
}
};
};
//todo remove
$scope.options = {
chart: {
type: 'multiBarChart',
height: 250,
margin : {
top: 20,
right: 20,
bottom: 20,
left: 45
},
//clipEdge: true,
duration:300,
stacked: true,
xAxis: {
showMaxMin: false,
tickFormat: function(d){
//debugger;
return d;//d3.format(',f')(d);
}
},
yAxis: {
axisLabelDistance: -10,
tickFormat: function(d){
return d3.format(',.f')(d);
}
}
}
};
$scope.getLineOptions = function(yFormat=',.f')
{
return {
chart: {
type: 'lineChart',
height: 250,
margin : {
top: 25,
right: 20,
bottom: 25,
left: 60
},
duration:1000,
x: function(d){ return d.x; },
y: function(d){ return d.y; },
//interpolate: "cardinal",
xAxis: {
showMaxMin: false,
tickFormat: function(d){
//debugger;
return periods[d];//d;//d3.format(',f')(d);
}
},
yAxis: {
axisLabelDistance: 5,
tickFormat: function(d){
return d3.format(yFormat)(d);
},
}
}
};
};
//todo remove
$scope.optionsLine = {
chart: {
type: 'lineChart',
height: 250,
margin : {
top: 20,
right: 20,
bottom: 25,
left: 45
},
duration:1000,
x: function(d){ return d.x; },
y: function(d){ return d.y; },
//interpolate: "cardinal",
xAxis: {
showMaxMin: false,
tickFormat: function(d){
//debugger;
return periods[d];//d;//d3.format(',f')(d);
}
},
yAxis: {
axisLabelDistance: 5,
tickFormat: function(d){
return d3.format(',.f')(d);
},
axisLabelDistance: 5
}
//,callback: highlightPoints,
//dispatch: {
// renderEnd: function(){
// highlightPoints(chart)
// }
// }
}
};
$scope.getPieOptions = function(isDonut = false)
{
return {
chart: {
type: 'pieChart',
height: 230,
donut: isDonut,
x: function(d){return d.key;},
y: function(d){return d.value;},
showLabels: false,
pie: {
startAngle: function(d) { return d.startAngle },
endAngle: function(d) { return d.endAngle }
},
duration: 300,
legend: {
margin: {
top: 5, right: 1, bottom: 1, left: 1
},
},
legendPosition: 'top'
}
};
};
$scope.getBarOptions = function(yFormat=',.f')
{
return {
chart: {
type: 'discreteBarChart',
height: 220,
margin : {
top: 10,
right: 1,
bottom: 15,
left: -5 //30
},
x: function(d){ return d.key; },
y: function(d){ return d.value; },
showValues: true,
valueFormat: function(d){
return d3.format(yFormat)(d);
},
duration: 800,
yAxis: {
},
xAxis: {
},
}
};
};
//wip start
$scope.onReady = function(scope, el){
chart = scope.chart;
}
function highlightPoints(chart){
var data = d3.d3.select('svg').datum(); //select('#productsSold').datum();
debugger;
d3.select('.nv-groups')
.selectAll("circle.myPoint")
.remove();
var points = d3.select('.nv-groups')
.selectAll("circle.myPoint")
.data(data[0].values.filter(function(d) { return d.y > 10; }));
points.enter().append("circle")
.attr("class", "myPoint")
.attr("cx", function(d) { return chart.xAxis.scale()(d.x); })
.attr("cy", function(d) { return chart.yAxis.scale()(d.y); })
.attr("r", 5);
}
//wip end
$scope.dataVSPie = {"chartData": [{
"key": "New",
"value": 49
},
{
"key": "Used",
"value": 149
}
]};
//todo: pull together once we know data structure
$scope.dataVS = [
{"key":"New",
"values": [
{"x":"Jan-16","y":100},
{"x":"Feb-16","y":90},
{"x":"Mar-16","y":60},
{"x":"Apr-16","y":140},
{"x":"May-16","y":110},
{"x":"Jun-16","y":96},
{"x":"Jul-16","y":33},
{"x":"Aug-16","y":45},
{"x":"Sep-16","y":78},
{"x":"Oct-16","y":89},
{"x":"Nov-16","y":45},
{"x":"Dev-16","y":48},
{"x":"Jan-17","y":49}
]},
{"key":"Used",
"values": [
{"x":"Jan-16","y":100},
{"x":"Feb-16","y":89},
{"x":"Mar-16","y":106},
{"x":"Apr-16","y":240},
{"x":"May-16","y":101},
{"x":"Jun-16","y":96},
{"x":"Jul-16","y":83},
{"x":"Aug-16","y":190},
{"x":"Sep-16","y":230},
{"x":"Oct-16","y":330},
{"x":"Nov-16","y":89},
{"x":"Dev-16","y":95},
{"x":"Jan-17","y":149}
]}
];
$scope.dataDeals = [
{"key":"Finance",
"values": [
{"x":"Jan-16","y":10},
{"x":"Feb-16","y":9},
{"x":"Mar-16","y":6},
{"x":"Apr-16","y":14},
{"x":"May-16","y":11},
{"x":"Jun-16","y":26},
{"x":"Jul-16","y":33},
{"x":"Aug-16","y":19},
{"x":"Sep-16","y":23},
{"x":"Oct-16","y":33},
{"x":"Nov-16","y":45},
{"x":"Dev-16","y":48},
{"x":"Jan-17","y":49}
]},
{"key":"Lease",
"values": [
{"x":"Jan-16","y":10},
{"x":"Feb-16","y":9},
{"x":"Mar-16","y":16},
{"x":"Apr-16","y":24},
{"x":"May-16","y":11},
{"x":"Jun-16","y":26},
{"x":"Jul-16","y":33},
{"x":"Aug-16","y":19},
{"x":"Sep-16","y":23},
{"x":"Oct-16","y":33},
{"x":"Nov-16","y":45},
{"x":"Dev-16","y":48},
{"x":"Jan-17","y":49}
]},
{"key":"Cash",
"values": [
{"x":"Jan-16","y":10},
{"x":"Feb-16","y":9},
{"x":"Mar-16","y":6},
{"x":"Apr-16","y":4},
{"x":"May-16","y":1},
{"x":"Jun-16","y":6},
{"x":"Jul-16","y":33},
{"x":"Aug-16","y":19},
{"x":"Sep-16","y":3},
{"x":"Oct-16","y":33},
{"x":"Nov-16","y":45},
{"x":"Dev-16","y":48},
{"x":"Jan-17","y":49}
]},
{"key":"Product Only",
"values": [
{"x":"Jan-16","y":10},
{"x":"Feb-16","y":9},
{"x":"Mar-16","y":6},
{"x":"Apr-16","y":41},
{"x":"May-16","y":11},
{"x":"Jun-16","y":26},
{"x":"Jul-16","y":33},
{"x":"Aug-16","y":19},
{"x":"Sep-16","y":23},
{"x":"Oct-16","y":3},
{"x":"Nov-16","y":5},
{"x":"Dev-16","y":18},
{"x":"Jan-17","y":29}
]}
];
$scope.dataProductsSold = [
{"key":"MAINT",
"values": [
{"x":"0","y":10},
{"x":"1","y":9},
{"x":"2","y":6},
{"x":"3","y":14},
{"x":"4","y":11},
{"x":"5","y":26},
{"x":"6","y":33},
{"x":"7","y":19},
{"x":"8","y":23},
{"x":"9","y":33},
{"x":"10","y":45},
{"x":"11","y":48},
{"x":"12","y":49}
]},
{"key":"VSC",
"values": [
{"x":"0","y":10},
{"x":"1","y":19},
{"x":"2","y":16},
{"x":"3","y":4},
{"x":"4","y":21},
{"x":"5","y":26},
{"x":"6","y":3},
{"x":"7","y":19},
{"x":"8","y":3},
{"x":"9","y":53},
{"x":"10","y":5},
{"x":"11","y":28},
{"x":"12","y":19}
]},
{"key":"GAP",
"values": [
{"x":"0","y":10},
{"x":"1","y":12},
{"x":"2","y":26},
{"x":"3","y":41},
{"x":"4","y":31},
{"x":"5","y":22},
{"x":"6","y":31},
{"x":"7","y":12},
{"x":"8","y":32},
{"x":"9","y":3},
{"x":"10","y":51},
{"x":"11","y":8},
{"x":"12","y":9}
]},
{"key":"KEY",
"values": [
{"x":"0","y":10},
{"x":"1","y":9},
{"x":"2","y":46},
{"x":"3","y":41},
{"x":"4","y":11},
{"x":"5","y":36},
{"x":"6","y":32},
{"x":"7","y":29},
{"x":"8","y":3},
{"x":"9","y":33},
{"x":"10","y":51},
{"x":"11","y":38},
{"x":"12","y":9}
]}
];
$scope.dataProductsIncome = [
{"key":"MAINT",
"values": [
{"x":"0","y":10000},
{"x":"1","y":19000},
{"x":"2","y":26000},
{"x":"3","y":15445},
{"x":"4","y":11454},
{"x":"5","y":26454},
{"x":"6","y":33787},
{"x":"7","y":19101},
{"x":"8","y":23100},
{"x":"9", "y":33124},
{"x":"10", "y":45578},
{"x":"11", "y":47888},
{"x":"12", "y":49787}
]},
{"key":"GAP",
"values": [
{"x":"0", "y":10144},
{"x":"1","y":9454},
{"x":"2","y":14546},
{"x":"3","y":14546},
{"x":"4","y":14546},
{"x":"5","y":14546},
{"x":"6","y":34232},
{"x":"7","y":45453},
{"x":"8","y":23345},
{"x":"9","y":45455},
{"x":"10","y":78784},
{"x":"11","y":43434},
{"x":"12","y":12212}
]},
{"key":"VSC",
"values": [
{"x":"0","y":34545},
{"x":"1","y":56456},
{"x":"2","y":56765},
{"x":"3","y":45454},
{"x":"4","y":14545},
{"x":"5","y":63534},
{"x":"6","y":134633},
{"x":"7","y":76777},
{"x":"8","y":38785},
{"x":"9","y":33676},
{"x":"10","y":45454},
{"x":"11", "y":44548},
{"x":"12", "y":49344}
]},
{"key":"KEY",
"values": [
{"x":"0","y":43410},
{"x":"1","y":94545},
{"x":"2","y":62323},
{"x":"3","y":45455},
{"x":"4","y":11566},
{"x":"5","y":23446},
{"x":"6","y":34555},
{"x":"7","y":14559},
{"x":"8","y":54545},
{"x":"9","y":45553},
{"x":"10","y":45455},
{"x":"11","y":15668},
{"x":"12","y":23449}
]}
];
$scope.dataProductsPerSale = [
{"key":"New",
"values": [
{"x":"Jan-16","y":1},
{"x":"Feb-16","y":.90},
{"x":"Mar-16","y":.60},
{"x":"Apr-16","y":1.40},
{"x":"May-16","y":1.10},
{"x":"Jun-16","y":.90},
{"x":"Jul-16","y":.30},
{"x":"Aug-16","y":.40},
{"x":"Sep-16","y":.80},
{"x":"Oct-16","y":.90},
{"x":"Nov-16","y":.40},
{"x":"Dev-16","y":.50},
{"x":"Jan-17","y":.60}
]},
{"key":"Used",
"values": [
{"x":"Jan-16","y":1},
{"x":"Feb-16","y":.80},
{"x":"Mar-16","y":1},
{"x":"Apr-16","y":1.20},
{"x":"May-16","y":1},
{"x":"Jun-16","y":.90},
{"x":"Jul-16","y":.40},
{"x":"Aug-16","y":1.90},
{"x":"Sep-16","y":1.30},
{"x":"Oct-16","y":.30},
{"x":"Nov-16","y":.90},
{"x":"Dev-16","y":.50},
{"x":"Jan-17","y":.70}
]}
];
$scope.dataProfitPerSale = [
{"key":"NEW",
"values": [
{"x":"0","y":100},
{"x":"1","y":199},
{"x":"2","y":260},
{"x":"3","y":154},
{"x":"4","y":114},
{"x":"5","y":264},
{"x":"6","y":337},
{"x":"7","y":191},
{"x":"8","y":231},
{"x":"9", "y":331},
{"x":"10", "y":455},
{"x":"11", "y":478},
{"x":"12", "y":497}
]},
{"key":"USED",
"values": [
{"x":"0", "y":101},
{"x":"1","y":94},
{"x":"2","y":145},
{"x":"3","y":145},
{"x":"4","y":145},
{"x":"5","y":145},
{"x":"6","y":342},
{"x":"7","y":454},
{"x":"8","y":230},
{"x":"9","y":454},
{"x":"10","y":787},
{"x":"11","y":434},
{"x":"12","y":122}
]}
];
$scope.dataPenetration = [
{"key":"New",
"values": [
{"x":"Jan-16","y":1},
{"x":"Feb-16","y":.9},
{"x":"Mar-16","y":.60},
{"x":"Apr-16","y":.15},
{"x":"May-16","y":.11},
{"x":"Jun-16","y":.96},
{"x":"Jul-16","y":.33},
{"x":"Aug-16","y":.45},
{"x":"Sep-16","y":.78},
{"x":"Oct-16","y":.89},
{"x":"Nov-16","y":.45},
{"x":"Dev-16","y":.48},
{"x":"Jan-17","y":.49}
]},
{"key":"Used",
"values": [
{"x":"Jan-16","y":.1},
{"x":"Feb-16","y":.89},
{"x":"Mar-16","y":.10},
{"x":"Apr-16","y":.24},
{"x":"May-16","y":.97},
{"x":"Jun-16","y":.96},
{"x":"Jul-16","y":.83},
{"x":"Aug-16","y":.19},
{"x":"Sep-16","y":.23},
{"x":"Oct-16","y":.33},
{"x":"Nov-16","y":.89},
{"x":"Dev-16","y":.95},
{"x":"Jan-17","y":.14}
]}
];
//helper also used on perf dashboard
$scope.toBarChart = function (d){
var tData = [{values: []}];
angular.copy(d, tData[0].values)
return tData;
};
$scope.getChartAvg = function(d,i){
var total=0;
var count=0;
angular.forEach(d, function(value, key) {
//debugger;
count=count+1;
total = total + value.values[i].y
//console.log(value.values.y / count);
});
return (total / count);
};
$scope.getChartTotal = function(d,i){
var total=0;
angular.forEach(d, function(value, key) {
//debugger;
total = total + value.values[i].y
//console.log(value.values.y);
});
return total;
};
$scope.getChartData = function(d,i,isBarChart=false){
var cData = [];
angular.forEach(d, function(value, key) {
cData.push({"key": value.key,"value": value.values[i].y});
});
//console.log(cData);
return (isBarChart ? $scope.toBarChart(cData) : cData);
};
//$scope.getChartData($scope.dataVS,12);
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>Angular-nvD3 Multi Bar Chart</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.js"></script>
<script src="https://rawgit.com/krispo/angular-nvd3/v1.0.9/dist/angular-nvd3.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class='container dashboard'>
<div class='row'>
<div class='col-md-12'>
<h5 class="sectionTitle">VEHICLE SALES</h5>
<div class="panel panel-default">
<div class='row'>
<div class='col-md-9'>
<nvd3 options="options" data="dataVS"></nvd3>
</div>
<div class='col-md-3'>
<nvd3 options="getPieOptions()" data="getChartData(dataVS,12)"></nvd3>
<!--<chart-total title='Total'></chart-total>-->
<div class='text-center'>TOTAL: {{getChartTotal(dataVS,12)}} </div>
</div>
</div>
</div>
</div>
</div>
<div class='row'>
<div class='col-md-12'>
<h5 class="sectionTitle">DEALS</h5>
<div class="panel panel-default">
<div class='row'>
<div class='col-md-9'>
<nvd3 options="options" data="dataDeals"></nvd3>
</div>
<div class='col-md-3'>
<nvd3 options="getPieOptions(true)" data="getChartData(dataDeals,12)"></nvd3>
<div class='text-center'>TOTAL DEALS: {{getChartTotal(dataDeals,12)}} </div>
</div>
</div>
</div>
</div>
</div>
<div class='row'>
<div class='col-md-12'>
<h5 class="sectionTitle">PRODUCTS SOLD</h5>
<div class="panel panel-default">
<div class='row'>
<div class='col-md-9'>
<nvd3 options="optionsLine" data="dataProductsSold" id='productsSold'></nvd3>
</div>
<div class='col-md-3'>
<nvd3 options="getBarOptions()" data="getChartData(dataProductsSold,12, true)"></nvd3>
<div class='text-center'>TOTAL PRODUCTS: {{getChartTotal(dataProductsSold,12)}} </div>
</div>
</div>
</div>
</div>
</div>
<div class='row'>
<div class='col-md-12'>
<h5 class="sectionTitle">PRODUCT INCOME</h5>
<div class="panel panel-default">
<div class='row'>
<div class='col-md-9'>
<nvd3 options="getLineOptions('$,.')" data="dataProductsIncome"></nvd3>
</div>
<div class='col-md-3'>
<nvd3 options="getBarOptions('$,.')" data="getChartData(dataProductsIncome,12, true)"></nvd3>
<div class='text-center'>TOTAL INCOME: {{getChartTotal(dataProductsIncome,12) |currency:"$":0}} </div>
</div>
</div>
</div>
</div>
</div>
<div class='row'>
<div class='col-md-12'>
<h5 class="sectionTitle">PRODUCTS PER SALE</h5>
<div class="panel panel-default">
<div class='row'>
<div class='col-md-9'>
<nvd3 options="getSBarOptions(false)" data="dataProductsPerSale"></nvd3>
</div>
<div class='col-md-3'>
<nvd3 options="getPieOptions(true)" data="getChartData(dataProductsPerSale,12)"></nvd3>
<div class='text-center'>AVG PER SALE: {{getChartAvg(dataProductsPerSale,12) |number:1}}
</div>
</div>
</div>
</div>
</div>
</div>
<div class='row'>
<div class='col-md-12'>
<h5 class="sectionTitle">PROFIT PER SALE</h5>
<div class="panel panel-default">
<div class='row'>
<div class='col-md-9'>
<nvd3 options="getLineOptions('$,.')" data="dataProfitPerSale"></nvd3>
</div>
<div class='col-md-3'>
<nvd3 options="getPieOptions(true)" data="getChartData(dataProfitPerSale,12)"></nvd3>
<div class='text-center'>TOTAL PROFIT: {{getChartTotal(dataProfitPerSale,12) |currency:"$":0}} </div>
</div>
</div>
</div>
</div>
</div>
<div class='row'>
<div class='col-md-12'>
<h5 class="sectionTitle">PENETRATION</h5>
<div class="panel panel-default">
<div class='row'>
<div class='col-md-9'>
<nvd3 options="getSBarOptions(false,'%')" config="{extended: true}" data="dataPenetration"></nvd3>
</div>
<div class='col-md-3'>
<nvd3 options="getPieOptions(true)" data="getChartData(dataPenetration,12)"></nvd3>
<div class='text-center'>AVG PENETRATION: {{getChartAvg(dataPenetration,12) * 100 | number:0}} % </div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
/* Put your css in here */
.nv-axis.nv-x .tick line {
display:none;
}
.nv-axis.nv-x .tick line {
display:none;
}
.dashboard .sectionTitle{margin-left:5px; font-weight:bold;}
<h5 class='text-center'>{{::$ctrl.title}} :asdsd </h5>