Skip to content

Instantly share code, notes, and snippets.

@irineu
Last active November 27, 2016 15:06
Show Gist options
  • Save irineu/8cddf58b7a16246a5cd55f007ad268a1 to your computer and use it in GitHub Desktop.
Save irineu/8cddf58b7a16246a5cd55f007ad268a1 to your computer and use it in GitHub Desktop.
d3 heartbeat
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();
}
}
});
@irineu
Copy link
Author

irineu commented Nov 27, 2016

Just add a heartbeat.html file with a div#heartbear inside

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment