Last active
November 27, 2016 15:06
-
-
Save irineu/8cddf58b7a16246a5cd55f007ad268a1 to your computer and use it in GitHub Desktop.
d3 heartbeat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var myApp = angular.module("myApp",[]); | |
myApp.directive('heartbeat', function($interval, $window) { | |
return { | |
restrict: 'E', | |
scope: {}, | |
templateUrl: 'directives/heartbeat.html', | |
link: function(scope, element, attr) { | |
var el = $(element).find(".heartbeat").get(0); | |
scope.attr = attr; | |
var data = []; | |
var beat = 0; | |
var offset; | |
var svg; | |
var margin = { | |
top: 15, | |
left: 20, | |
bottom: 15, | |
right: 20 | |
}; | |
var width = $(el).width() - margin.left - margin.right; | |
var height = $(el).height() - margin.top - margin.bottom - 10; | |
var beatTicks = 5 | |
var steps = 50; | |
var tickInterval; | |
var tickTimeout; | |
var stepX = stepY = 0; | |
var line; | |
function buildData() { | |
data = []; | |
for (var i = 0; i < steps; i++) { | |
if (scope.attr.status == "online") { | |
data.push({ | |
x: 0, | |
y: offset + i % 2 == 0 ? 1 : 0 | |
}); | |
} else { | |
data.push({ | |
x: 0, | |
y: offset | |
}); | |
} | |
} | |
} | |
function doTick() { | |
beat = data.length; | |
tickInterval = setInterval(function() { | |
width = $(el).width() - margin.left - margin.right; | |
height = $(el).height() - margin.top - margin.bottom - 10; | |
data = []; | |
for (var i = 0; i < steps; i++) { | |
if (i == beat) { | |
for (var j = 0; j < beatTicks; j++) | |
if (scope.attr.status == "online") { | |
data.push({ | |
x: 0, | |
y: j % 2 == 0 ? -(j * i) / 10 + offset : (j * i) / 10 + offset | |
}); | |
} else { | |
data.push({ | |
x: 0, | |
y: j % 2 == 0 ? -(j * i) / 50 + offset : (j * i) / 50 + offset | |
}); | |
} | |
i = i + beatTicks - 1 | |
} else { | |
if (scope.attr.status == "online") { | |
data.push({ | |
x: 0, | |
y: offset + i % 2 == 0 ? 1 : 0 | |
}); | |
} else { | |
data.push({ | |
x: 0, | |
y: offset | |
}); | |
} | |
} | |
} | |
beat--; | |
if (beat == 0) { | |
buildData(); | |
beat = data.length - data.length / 5; | |
clearInterval(tickInterval); | |
tickTimeout = setTimeout(doTick, 3000); | |
} | |
svg.transition() | |
.duration(0) | |
.select(".line") | |
.attr("class", "line " + (scope.attr.status == "online" ? "online" : "offline")) | |
.attr("d", line(data)); | |
}, 60); | |
} | |
function draw() { | |
width = $(el).width() - margin.left - margin.right; | |
height = $(el).height() - margin.top - margin.bottom - 10; | |
stepX = stepY = (width / data.length); | |
line = d3.line() | |
.x(function(d, i) { | |
return i * stepX | |
}) | |
.y(function(d, i) { | |
return d.y | |
}); | |
svg = d3.select(el).select("svg"); | |
if (!svg.empty()) { | |
svg.remove(); | |
} | |
console.log($(element).get(0)); | |
svg = d3.select(el).append("svg") | |
.attr("class", "graph-heartbeat") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
svg.append("path") | |
.attr("class", "line " + (scope.attr.status == "online" ? "online" : "offline")) | |
.attr("d", line(data)) | |
doTick(); | |
} | |
function adjustOffset() { | |
if (scope.attr.status == "online") { | |
offset = 0; | |
} else { | |
offset = $(el).height() - 30; | |
} | |
} | |
adjustOffset(); | |
buildData(); | |
angular.element($window).bind('resize', function() { | |
if (tickInterval) clearInterval(tickInterval); | |
if (tickTimeout) clearTimeout(tickTimeout); | |
draw(); | |
}) | |
scope.$watch("attr.status", function() { | |
adjustOffset(); | |
if (tickInterval) clearInterval(tickInterval); | |
if (tickTimeout) clearTimeout(tickTimeout); | |
doTick(); | |
}); | |
draw(); | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just add a heartbeat.html file with a div#heartbear inside