Waterfall Chart
by Rishabh Sharma
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<div ng-controller="MyCtrl">
<div>
<select ng-model="selectData">
<option value="data1">data 1</option>
<option value="data2">data 2</option>
<option value="data3">data 3</option>
</select>
</div>
<div>
{{selectData}}
<waterfall chart-data="chartData" select-data="selectData"></waterfall>
</div>
</div>
CSS
.bar line.connector {
stroke: black;
stroke-dasharray: 3;
}
.bar text {
fill: white;
font: 12px sans-serif;
text-anchor: middle;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
JavaScript
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.selectData = "data2";
$scope.chartData = {
data1: [{
id: 1,
name: "LY",
value: 2000000
}, {
id: 2,
name: "P",
value: 100000
}, {
id: 3,
name: "I",
value: -200000
}, {
id: 4,
name: "D",
value: -500000
}],
data2: [{
id: 1,
name: "LY",
value: 3000000
}, {
id: 2,
name: "P",
value: -1000000
}, {
id: 3,
name: "I",
value: 500000
}, {
id: 4,
name: "D",
value: -300000
}],
data3: [{
id: 1,
name: "LY",
value: 1000000
}, {
id: 2,
name: "P",
value: 2000000
}, {
id: 3,
name: "I",
value: 500000
}, {
id: 4,
name: "D",
value: 2000000
}]
};
});
myApp.directive('waterfall', function() {
return {
restrict: 'E',
replace: true,
scope: {
chartData: '=',
selectData: '='
},
template: "<svg class='waterfall-chart'></svg>",
link: function(scope, element, attrs, fn) {
var rawSvg = element;
var data = scope.chartData.data1;
scope.$watch('selectData', function(newValue, oldValue) {
console.log(newValue);
if (newValue === "data1") {
data = scope.chartData.data1;
} else if (newValue === "data2") {
data = scope.chartData.data2;
} else {
data = scope.chartData.data3;
}
paintChart();
});
var margin = {
top: 100,
right: 0,
bottom: 0,
left: -70
},
width = 500 - margin.left - margin.right,
height = 220 - margin.top - margin.bottom,
padding = 0.80;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], padding);
var y = d3.scale.linear()
.range([height, 0]);
/* ...