Plot the streamgraph of ATFM delay causes and print highlighted value under the cursor.
Mar-2014 - Jul-2016 Done:
TODO:
forked from/inspired by biovisualize's block: Streamgraph extent under cursor
forked from espinielli's block: Streamgraph of ATFM delay causes
xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.chart {
background: #fff;
}
p {
font: 12px helvetica;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 2px;
shape-rendering: crispEdges;
}
.grid .tick {
stroke: grey;
stroke-opacity: 0.2;
shape-rendering: crispEdges;
}
.tooltip { background-color:rgba(68,136,187,0.5);;
margin: 10px;
height: 50px;
width: 150px;
padding-left: 10px;
padding-top: 10px;
-webkit-border-radius:10px;
-moz-border-radius:10px;
border-radius:10px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<!-- <script type="text/javascript" src="tooltip.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
<div class="chart">
</div>
<script>
// "blue"
colorrange = ["#045A8D", "#2B8CBE", "#74A9CF", "#A6BDDB", "#D0D1E6", "#F1EEF6"];
// "pink"
//colorrange = ["#980043", "#DD1C77", "#DF65B0", "#C994C7", "#D4B9DA", "#F1EEF6"];
// "orange"
//colorrange = ["#B30000", "#E34A33", "#FC8D59", "#FDBB84", "#FDD49E", "#FEF0D9"];
chart("https://192.168.0.13:3000/streamgraph/escobar", colorrange);
var datearray = [];
var colorrange = [];
function chart(csvpath, colorrange) {
strokecolor = colorrange[0];
var format = d3.time.format("%Y");
var margin = {top: 20, right: 40, bottom: 40, left: 30};
var width = document.body.clientWidth - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
// function for the x grid lines
function make_x_axis() {
return d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.months)
}
var tooltip = d3.select("body")
.append("div")
.attr("class", "remove")
.style("position", "absolute")
.style("z-index", "20")
.style("visibility", "hidden")
.style("top", "320px")
.style("left", "45px");
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height - 10, 0]);
var z = d3.scale.ordinal()
.range(colorrange);
var xAxis = make_x_axis();
var yAxis = d3.svg.axis()
.scale(y);
var stack = d3.layout.stack()
.offset("silhouette")
.values(function(d) { return d.values; })
.x(function(d) { return d.year; })
.y(function(d) { return d.cantidad; });
var nest = d3.nest()
.key(function(d) { return d.elec_type_name; });
var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) { return x(d.year); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
var svg = d3.select(".chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var graph = d3.csv(csvpath, function(data) {
data.forEach(function(d) {
d.year = format.parse(d.year);
d.cantidad = +d.cantidad;
});
var layers = stack(nest.entries(data));
var xdom = d3.extent(data, function(d) { return d.year; });
x.domain(xdom);
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
svg.selectAll(".layer")
.data(layers)
.enter().append("path")
.attr("class", "layer")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d, i) { return z(i); });
// Draw the x Grid lines
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(make_x_axis()
.tickSize(-height, 0, 0)
.tickFormat("")
);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text") // rotate ticks labels
.attr("y", 0)
.attr("x", 9)
.attr("dy", ".35em")
.attr("transform", "rotate(40)")
.style("text-anchor", "start");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ", 0)")
.call(yAxis.orient("right"));
svg.append("g")
.attr("class", "y axis")
.call(yAxis.orient("left"));
// the cursor for the tooltip
var axisExtentLine = svg.append("line")
.attr({"class": "extent",
"stroke-width": 5,
"stroke-opacity": 0.8,
"stroke": "red",
"pointer-events": "none"
});
// the cursor in the stream under the mouse
var cursorExtentLine = svg.append("line")
.attr({"class": "extent",
"stroke-width": 3,
"stroke-opacity": 0.8,
"stroke": "white",
"pointer-events": "none"
});
svg.selectAll(".layer")
.attr("opacity", 1)
.on("mouseover", function(d, i) {
svg.selectAll(".layer").transition()
.duration(250)
.attr("opacity", function(d, j) {
return j != i ? 0.6 : 1;
})
.attr("stroke", function(d, j) {
return j != i ? "none" : "black";
})
})
/* .call(d3.helper.tooltip(
function(d, i){
console.log(d);
console.log(i);
console.log(d.values);
return "<b>"+d + "</b><br/>pop: "+d;
}
)) */
.on("mousemove", function(d, i) {
mouse = d3.mouse(this);
// get the date at mouse position
var dateATx = x.invert(mouse[0]);
// make it the fisrt of the month
dateATx = new Date(dateATx.getFullYear(), dateATx.getMonth(), 1);
// get the entry in d.values that matches the first of the month under the mouse
var entry = _.find(d.values, function(o) {return o.year.getTime() == dateATx.getTime();});
pro = entry.cantidad || 0;
var posY = entry.y0;
var posX = x(entry.year);
axisExtentLine.attr({x1: 0, y1: y(pro),
x2: 0, y2: height -10 });
cursorExtentLine.attr({x1: posX, y1: y(pro) - (height - y(posY) - 10),
x2: posX, y2: height - (height - y(posY)) });
d3.select(this)
.classed("hover", true)
.attr("stroke", strokecolor)
.attr("stroke-width", "1px"),
tooltip.html( "<p>" + d.elec_type_name + "<br>" + pro + "</p>" )
.style("visibility", "visible");
})
// .on("mouseout", fade(1))
.on("mouseout", function(d, i) {
svg.selectAll(".layer")
.transition()
.duration(250)
.attr("opacity", "1");
d3.select(this)
.classed("hover", false)
.attr("stroke-width", "0px");
tooltip.html( "<p>" + d.elec_type_name + "<br>" + pro + "</p>" )
.style("visibility", "hidden");
})
var vertical = d3.select(".chart")
.append("div")
.attr("class", "remove")
.style("position", "absolute")
.style("z-index", "19")
.style("width", "1px")
.style("height", "340px")
.style("top", "20px")
.style("bottom", "30px")
.style("left", "0px")
.style("background", "#f00");
d3.select(".chart")
.on("mousemove", function(){
mousex = d3.mouse(this);
mousex = mousex[0] + 5;
vertical.style("left", mousex + "px" )})
.on("mouseover", function(){
mousex = d3.mouse(this);
mousex = mousex[0] + 5;
vertical.style("left", mousex + "px")});
});
}
function fade(opacity) {
return function(g, i) {
streamgraph.layers()
.filter(function(h, j) {
return j != i;
})
.transition(1000)
.style("opacity", opacity);
}
}
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js