Skip to content

Instantly share code, notes, and snippets.

@lager1
Last active January 22, 2019 15:46
Show Gist options
  • Save lager1/e536715e9b5bb20120e8f2f58b0d8e57 to your computer and use it in GitHub Desktop.
Save lager1/e536715e9b5bb20120e8f2f58b0d8e57 to your computer and use it in GitHub Desktop.
data updates
license: mit
[[
[
"cuni.cz",
{
"ok": 2,
"fail": 0
}
],
[
"iem.cas.cz",
{
"ok": 1,
"fail": 0
}
],
[
"faf.cuni.cz",
{
"ok": 1,
"fail": 0
}
],
[
"gymzl.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fd.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"skolarajhrad.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fit.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fbmi.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"mzk.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cvut.cz",
{
"ok": 1,
"fail": 0
}
]
],[
[
"cuni.cz",
{
"ok": 3,
"fail": 0
}
],
[
"iem.cas.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fel.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"gymzl.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fd.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"skolarajhrad.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fit.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fbmi.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"mzk.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cvut.cz",
{
"ok": 1,
"fail": 0
}
]
],[
[
"cuni.cz",
{
"ok": 4,
"fail": 0
}
],
[
"fbmi.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cubexcentrum.cz",
{
"ok": 1,
"fail": 0
}
],
[
"gymzl.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fd.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"skolarajhrad.cz",
{
"ok": 1,
"fail": 0
}
],
[
"iem.cas.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fit.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"mzk.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cvut.cz",
{
"ok": 1,
"fail": 0
}
]
],[
[
"cuni.cz",
{
"ok": 5,
"fail": 0
}
],
[
"fbmi.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cubexcentrum.cz",
{
"ok": 1,
"fail": 0
}
],
[
"gymzl.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fd.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"skolarajhrad.cz",
{
"ok": 1,
"fail": 0
}
],
[
"iem.cas.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fit.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"mzk.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cvut.cz",
{
"ok": 1,
"fail": 0
}
]
],[
[
"cuni.cz",
{
"ok": 6,
"fail": 0
}
],
[
"fbmi.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"ipm.cz",
{
"ok": 1,
"fail": 0
}
],
[
"gymzl.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fd.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"skolarajhrad.cz",
{
"ok": 1,
"fail": 0
}
],
[
"iem.cas.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fit.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"mzk.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cvut.cz",
{
"ok": 1,
"fail": 0
}
]
],[
[
"cuni.cz",
{
"ok": 6,
"fail": 1
}
],
[
"mzk.cz",
{
"ok": 1,
"fail": 0
}
],
[
"ipm.cz",
{
"ok": 1,
"fail": 0
}
],
[
"gymzl.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fd.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"skolarajhrad.cz",
{
"ok": 1,
"fail": 0
}
],
[
"iem.cas.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fbmi.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fit.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cvut.cz",
{
"ok": 1,
"fail": 0
}
]
],[
[
"cuni.cz",
{
"ok": 6,
"fail": 1
}
],
[
"fel.cvut.cz",
{
"ok": 2,
"fail": 0
}
],
[
"mzk.cz",
{
"ok": 1,
"fail": 0
}
],
[
"gymzl.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fd.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"skolarajhrad.cz",
{
"ok": 1,
"fail": 0
}
],
[
"iem.cas.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fbmi.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"fit.cvut.cz",
{
"ok": 1,
"fail": 0
}
],
[
"cvut.cz",
{
"ok": 1,
"fail": 0
}
]
]]
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<button id="slow"> slow animation / slow updates
</button>
<button id="clear"> clear
</button>
<script>
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
var data = [[["cuni.cz",{"ok":2,"fail":0}],["iem.cas.cz",{"ok":1,"fail":0}],["faf.cuni.cz",{"ok":1,"fail":0}],["gymzl.cz",{"ok":1,"fail":0}],["fd.cvut.cz",{"ok":1,"fail":0}],["skolarajhrad.cz",{"ok":1,"fail":0}],["fit.cvut.cz",{"ok":1,"fail":0}],["fbmi.cvut.cz",{"ok":1,"fail":0}],["mzk.cz",{"ok":1,"fail":0}],["cvut.cz",{"ok":1,"fail":0}]],[["cuni.cz",{"ok":3,"fail":0}],["iem.cas.cz",{"ok":1,"fail":0}],["fel.cvut.cz",{"ok":1,"fail":0}],["gymzl.cz",{"ok":1,"fail":0}],["fd.cvut.cz",{"ok":1,"fail":0}],["skolarajhrad.cz",{"ok":1,"fail":0}],["fit.cvut.cz",{"ok":1,"fail":0}],["fbmi.cvut.cz",{"ok":1,"fail":0}],["mzk.cz",{"ok":1,"fail":0}],["cvut.cz",{"ok":1,"fail":0}]],[["cuni.cz",{"ok":4,"fail":0}],["fbmi.cvut.cz",{"ok":1,"fail":0}],["cubexcentrum.cz",{"ok":1,"fail":0}],["gymzl.cz",{"ok":1,"fail":0}],["fd.cvut.cz",{"ok":1,"fail":0}],["skolarajhrad.cz",{"ok":1,"fail":0}],["iem.cas.cz",{"ok":1,"fail":0}],["fit.cvut.cz",{"ok":1,"fail":0}],["mzk.cz",{"ok":1,"fail":0}],["cvut.cz",{"ok":1,"fail":0}]],[["cuni.cz",{"ok":5,"fail":0}],["fbmi.cvut.cz",{"ok":1,"fail":0}],["cubexcentrum.cz",{"ok":1,"fail":0}],["gymzl.cz",{"ok":1,"fail":0}],["fd.cvut.cz",{"ok":1,"fail":0}],["skolarajhrad.cz",{"ok":1,"fail":0}],["iem.cas.cz",{"ok":1,"fail":0}],["fit.cvut.cz",{"ok":1,"fail":0}],["mzk.cz",{"ok":1,"fail":0}],["cvut.cz",{"ok":1,"fail":0}]],[["cuni.cz",{"ok":6,"fail":0}],["fbmi.cvut.cz",{"ok":1,"fail":0}],["ipm.cz",{"ok":1,"fail":0}],["gymzl.cz",{"ok":1,"fail":0}],["fd.cvut.cz",{"ok":1,"fail":0}],["skolarajhrad.cz",{"ok":1,"fail":0}],["iem.cas.cz",{"ok":1,"fail":0}],["fit.cvut.cz",{"ok":1,"fail":0}],["mzk.cz",{"ok":1,"fail":0}],["cvut.cz",{"ok":1,"fail":0}]],[["cuni.cz",{"ok":6,"fail":1}],["mzk.cz",{"ok":1,"fail":0}],["ipm.cz",{"ok":1,"fail":0}],["gymzl.cz",{"ok":1,"fail":0}],["fd.cvut.cz",{"ok":1,"fail":0}],["skolarajhrad.cz",{"ok":1,"fail":0}],["iem.cas.cz",{"ok":1,"fail":0}],["fbmi.cvut.cz",{"ok":1,"fail":0}],["fit.cvut.cz",{"ok":1,"fail":0}],["cvut.cz",{"ok":1,"fail":0}]],[["cuni.cz",{"ok":6,"fail":1}],["fel.cvut.cz",{"ok":2,"fail":0}],["mzk.cz",{"ok":1,"fail":0}],["gymzl.cz",{"ok":1,"fail":0}],["fd.cvut.cz",{"ok":1,"fail":0}],["skolarajhrad.cz",{"ok":1,"fail":0}],["iem.cas.cz",{"ok":1,"fail":0}],["fbmi.cvut.cz",{"ok":1,"fail":0}],["fit.cvut.cz",{"ok":1,"fail":0}],["cvut.cz",{"ok":1,"fail":0}]]];
// the actual code uses socket.io for event handling
// this is just a simulation of the problem
// the original code is at https://github.com/CESNET/eduroam-live
document.getElementById("slow").addEventListener("click", function(){
for(var i = 1; i <= 3; i++) {
setTimeout((function(i) {
if(i == 1)
graph_demo("some_title", svg, "slow", true, data[i]);
else
graph_demo("some_title", svg, "slow", false, data[i]);
}).bind(null, i), 1500 * i); // run updates every 1.5 seconds
}
});
document.getElementById("clear").addEventListener("click", function(){
d3.select("body").select("svg").remove();
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
});
// --------------------------------------------------------------------------------------
function graph_demo(title, tag, speed, init, data)
{
// Setup svg using Bostock's margin convention
var margin = {top: 80, right: 20, bottom: 180, left: 80};
//var width = $(window).width() / 2 - 130; // compensate for y axis labels
var width = 500; // compensate for y axis labels
var height = 600 - margin.top - margin.bottom;
var colors = [ "#225885", "#ea3933" ];
// --------------------------------------------------------------------
// set the ranges
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
// --------------------------------------------------------------------
var svg = tag;
if(init) {
svg = svg.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// ==================================================
// set graph title
svg.append("text")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "36px")
.style("fill", "white")
.style("text-decoration", "underline")
.text(title);
// ==================================================
// text label for the y axis
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left + 20)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("font-size", "18px")
.style("fill", "white")
.style("text-anchor", "middle")
.text("počet autentizací");
// ==================================================
// add the x Axis
var x_axis = svg.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("class", "x axis")
.style("fill", "white")
.style("font-size", "18px");
// ==================================================
// add the y Axis
var y_axis = svg.append("g")
.attr("class", "y axis")
.style("fill", "white")
.style("font-size", "18px");
}
// ==================================================
// get initial data
//socket.on(event_name, function(data) {
// ==================================================
if(speed === "slow") {
var transition = svg.transition().duration(750);
var delay = function(d, i) { return i * 50; };
var t = d3.transition().duration(750);
}
// ==================================================
else {
var transition = svg.transition().duration(200);
var delay = function(d, i) { return i * 15; };
var t = d3.transition().duration(200);
}
// debug
console.log(data);
// ==================================================
// Scale the range of the data in the domains
x.domain(data.map(function(d) { return d[0]; }));
y.domain([0, d3.max(data, function(d) {
if(d[1].fail > d[1].ok)
return d[1].fail;
return d[1].ok;
})]);
// ==================================================
var bars = svg.selectAll(".bar").data(data, function(d) { return d[0]; }); // JOIN new data with old elements
svg.selectAll(".bar").selectAll(".blue")
.data(function(d) { return [d]; });
svg.selectAll(".bar").selectAll(".red")
.data(function(d) { return [d]; });
// ==================================================
// exit old elements
bars.exit()
.selectAll('.box')
.attr("class", "remove") // different class to not be selected by update
.transition(t)
.attr("y", y(0))
.attr("height", 0)
.remove(); // EXIT old elements not present in new data
bars.exit()
.transition(t) // wait for removing .box
.remove() // EXIT old elements not present in new data
// ==================================================
// UPDATE old elements present in new data
transition.selectAll(".box")
.delay(delay)
.attr("width", x.bandwidth()) // also set bar width in case different number of bars was present
.attr("x", function(d) { return x(d[0]); }); // move on x
transition.selectAll(".blue")
.delay(delay)
.attr("y", function(d) { return y(d[1].ok); })
.attr("height", function(d) { return y(0) - y(d[1].ok); }); // update OK
transition.selectAll(".red")
.delay(delay)
.attr("y", function(d) { return y(d[1].fail); })
.attr("height", function(d) { return y(0) - y(d[1].fail); }) // update FAIL
// ==================================================
// add new data
bars = bars.enter()
.append('g')
.attr('class', 'bar');
// blue
bars.append("rect")
.attr("class", "blue box")
.attr("x", function(d) { return x(d[0]); })
.attr("width", x.bandwidth())
.attr("y", y(0))
.transition(t)
.attr("height", function(d) { return y(0) - y(d[1].ok); })
.attr("y", function(d) { return y(d[1].ok); })
bars.append("rect")
.attr("class", "red box")
.attr("x", function(d) { return x(d[0]); })
.attr("width", x.bandwidth())
.attr("y", y(0))
.transition(t)
.attr("height", function(d) { return y(0) - y(d[1].fail); })
.attr("y", function(d) { return y(d[1].fail); })
bars = bars.merge(bars);
// ==================================================
// dynamic axes transitions
transition.select(".x.axis")
.call(d3.axisBottom(x))
.selectAll("text")
.attr("dy", ".35em")
.attr("y", 20)
.attr("x", 0)
.attr("transform", "rotate(45)")
.style("text-anchor", "start")
.delay(delay);
transition.select(".y.axis")
.call(d3.axisLeft(y)
.tickSize(-width, 0, 0)
.tickFormat(d3.format("d"))) // custom format - disable comma for thousands
.delay(delay);
//});
}
// --------------------------------------------------------------------------------------
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment