Skip to content

Instantly share code, notes, and snippets.

@Karmak23
Created November 2, 2011 03:32
Show Gist options
  • Save Karmak23/1332784 to your computer and use it in GitHub Desktop.
Save Karmak23/1332784 to your computer and use it in GitHub Desktop.
ram-swap double-donut representation
<html>
<head>
<script language="javascript" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="https://raw.github.com/mbostock/d3/master/d3.min.js"></script>
<script language="javascript" type="text/javascript" src="https://raw.github.com/mbostock/d3/master/d3.layout.min.js"></script>
<style type="text/css">
#ramswap_wrapper {
#border: 1px dotted blue;
text-align: center;
background-color: #fafafa;
padding: 10px 10px;
border-radius: 5px;
margin-bottom: 10px;
}
#ramswap_label {
text-align: center;
width: 175px;
margin: -250px auto 0;
padding-bottom: 212px;
#font-variant: small-caps;
#padding: 0 0 5px 0;
#opacity: 0.08;
#line-height: 0.8em;
#border: 1px dotted red;
}
#ramswap_update {
margin: -280px auto 0;
padding-bottom: 252px;
}
.ramswap_value_label {
font: sans-serif;
font-size: 11px;
color: #580d27;
}
</style>
</head>
<body>
<div id="ramswap_wrapper">
<div id="ramswap_donut"></div>
<div id="ramswap_label">Physical and virtual memory occupation</div>
<div id="ramswap_update">
<input type="button" id="ramswap_update_button" value="UPDATE" />
</div>
</div>
</div>
<script language="javascript">
$("#ramswap_label").hide();
$("#ramswap_update").hide();
$("#ramswap_label").delay(2500).fadeIn('slow');
// this is meant for debug only
$("#ramswap_update").delay(2500).fadeIn('slow');
var ramswap_w = 450,
ramswap_h = 450,
ramswap_r = Math.min(ramswap_w, ramswap_h) / 2,
ram_colors = d3.scale.ordinal().range([ "#5c112f", "#646542", "#e13971", "#969863", "#89dafa" ]),
swap_colors = d3.scale.ordinal().range([ "#5c112f", "#e13971" ]),
ram_arc = d3.svg.arc().outerRadius(ramswap_r * 0.8),
swap_arc = d3.svg.arc().outerRadius(ramswap_r * 0.55),
ram_donut = d3.layout.pie();
swap_donut = d3.layout.pie();
function build_ramswap_data() {
//only for testing on bl.ocks.org ; to feed random data to make the representation animate.
active = Math.random() * 1000;
if (active > 500)
active -= 500;
free = 1024 - 500 - active;
swapfree = Math.random() * 1000;
return $.parseJSON('{ "MemTotal": 1024 , "Active": '+ active +', "Inactive": 300, "Cached": 100, "Buffers": 100, "MemFree": '+ free +', "SwapTotal": 1024, "SwapFree": '+ swapfree +' }');
}
function ram_tweenPie(b) {
b.innerRadius = 0;
var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
return function(t) {
return ram_arc(i(t));
};
}
function ram_tweenDonut(b) {
b.innerRadius = ramswap_r * .87;
var i = d3.interpolate({innerRadius: 0}, b);
return function(t) {
return ram_arc(i(t));
};
}
function swap_tweenPie(b) {
b.innerRadius = 0;
var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
return function(t) {
return swap_arc(i(t));
};
}
function swap_tweenDonut(b) {
b.innerRadius = ramswap_r * .62;
var i = d3.interpolate({innerRadius: 0}, b);
return function(t) {
return swap_arc(i(t));
};
}
// Stash the old values for transition.
function stash(d, i) {
//console.log('saving ' + d + '/' + i + ' angles, OLD: '
// + d.startAngle0 + '/' + d.endAngle0 + ' NEW:'
// + d.startAngle + '/' + d.endAngle);
d.startAngle0 = d.startAngle;
d.endAngle0 = d.endAngle;
}
function ram_tweenPie_update(a) {
//console.log('RAM moving from ' + a.startAngle0
// + '/' + a.endAngle0
// + ' to ' + a.startAngle
// + '/' + a.endAngle);
a.innerRadius = ramswap_r * .87;
var i = d3.interpolate({startAngle: a.startAngle0, endAngle: a.endAngle0 }, a);
return function(t) {
var b = i(t);
a.startAngle0 = b.startAngle;
a.endAngle0 = b.endAngle;
return ram_arc(b);
};
}
function swap_tweenPie_update(a) {
//console.log('SWAP moving from ' + b.startAngle0
// + '/' + b.endAngle0
// + ' to ' + b.startAngle
// + '/' + b.endAngle);
a.innerRadius = ramswap_r * .62;
var i = d3.interpolate({startAngle: a.startAngle0, endAngle: a.endAngle0 }, a);
return function(t) {
var b = i(t);
a.startAngle0 = b.startAngle;
a.endAngle0 = b.endAngle;
return swap_arc(b);
};
}
var ram_labels = [
"Active Applications:",
"Inactive Applications:",
"Cached:",
"Buffers:",
"Free:"
];
var swap_labels = [ "Occupied:", "Free:" ];
var ram_total = ram_data = swap_total = swap_data = 0;
// hold global references to the vis SVG and paths, to update the data
// more easily afterwards.
var vis =
ram_arcs_group = ram_arcs = ram_paths =
ram_txt1 = ram_txt2 =
swap_arcs_group = swap_arcs = swap_paths =
swap_txt1 = swap_txt2 = null;
update_ramswap_data(build_ramswap_data());
// for bl.ocks.org
ram_total = 1024;
swap_total = 1024;
create_ramswap();
d3.select("#ramswap_update_button").on("click", function() {
//console.log('update clicked');
//console.log('JSON fetched');
redraw_ramswap(build_ramswap_data());
});
function update_ramswap_data(rs_data) {
ram_data = [ rs_data.Active, rs_data.Inactive,
rs_data.Cached, rs_data.Buffers, rs_data.MemFree ];
swap_data = [ rs_data.SwapTotal - rs_data.SwapFree, rs_data.SwapFree ];
//console.log('RS data updated');
}
function create_ramswap() {
vis = d3.select("#ramswap_donut")
.append("svg:svg")
.attr("width", ramswap_w)
.attr("height", ramswap_h);
ram_arcs_group = vis.selectAll("g.ram_arcs_data")
.data([ram_data])
.enter().append("svg:g")
.attr("class", "ram_arcs_data");
ram_arcs = ram_arcs_group.selectAll("g.ram_arc")
.data(ram_donut)
.enter().append("svg:g")
.attr("class", "ram_arc")
.attr("transform", "translate(" + ramswap_r + "," + ramswap_r + ")");
ram_paths = ram_arcs.append("svg:path")
.attr("fill", function(d, i) { return ram_colors(i); });
ram_paths.transition()
.duration(500)
.attrTween("d", ram_tweenPie);
ram_paths.transition()
.ease("elastic")
.delay(function(d, i) { return 500 + i * 50; })
.duration(500)
.attrTween("d", ram_tweenDonut)
.each(stash);
ram_txt1 = ram_arcs.append("svg:text")
.transition()
.delay(function(d, i) { return 500 + i * 100; })
.attr("class", "ramswap_value_label ramswap_value_descr")
.attr("transform", function(d) { return "translate(" + ram_arc.centroid(d) + ")"; })
.attr("dy", "0em")
.attr("text-anchor", "middle")
.text(function(d, i) { return ram_labels[i] });
ram_txt2 = ram_arcs.append("svg:text")
.transition()
.delay(function(d, i) { return 500 + i * 100; })
.attr("class", "ramswap_value_label ramswap_value_number")
.attr("transform", function(d) { return "translate(" + ram_arc.centroid(d) + ")"; })
.attr("dy", "1.1em")
.attr("text-anchor", "middle")
.text(function(d, i) { return d.value.toFixed(0)
+ 'Mb' + ' ('
+ (d.value / ram_total * 100.00).toFixed(1)
+ '%)'; });
setTimeout(create_swap, 1500);
}
function create_swap() {
// the SWAP inner donut
swap_arcs_group = vis.selectAll("g.swap_arcs_data")
.data([swap_data])
.enter().append("svg:g")
.attr("class", "swap_arcs_data");
swap_arcs = swap_arcs_group.selectAll("g.swap_arc")
.data(swap_donut)
.enter().append("svg:g")
.attr("class", "swap_arc")
.attr("transform", "translate(" + ramswap_r + "," + ramswap_r + ")");
swap_paths = swap_arcs.append("svg:path")
.attr("fill", function(d, i) { return swap_colors(i); });
swap_paths.transition()
.duration(500)
.attrTween("d", swap_tweenPie);
swap_paths.transition()
.ease("elastic")
.delay(function(d, i) { return 500 + i * 50; })
.duration(500)
.attrTween("d", swap_tweenDonut);
swap_txt1 = swap_arcs.append("svg:text")
.transition()
.delay(function(d, i) { return 500 + i * 100; })
.attr("class", "ramswap_value_label ramswap_value_descr")
.attr("transform", function(d) { return "translate(" + swap_arc.centroid(d) + ")"; })
.attr("dy", "0em")
.attr("text-anchor", "middle")
.text(function(d, i) { return swap_labels[i] });
swap_txt2 = swap_arcs.append("svg:text")
.transition()
.delay(function(d, i) { return 500 + i * 100; })
.attr("class", "ramswap_value_label ramswap_value_number")
.attr("transform", function(d) { return "translate(" + swap_arc.centroid(d) + ")"; })
.attr("dy", "1.1em")
.attr("text-anchor", "middle")
.text(function(d, i) { return d.value.toFixed(0)
+ 'Mb' + ' ('
+ (d.value / swap_total * 100.00).toFixed(1)
+ '%)'; });
}
function redraw_ramswap(data) {
//console.log('OLD RS ' + ram_data + ' ' + swap_data);
update_ramswap_data(data);
//console.log('NEW RS ' + ram_data + ' ' + swap_data);
ram_arcs_group.data([ram_data]);
ram_donut(ram_data);
ram_arcs.data(ram_donut);
ram_paths.data(ram_donut);
// these doesn't help, I can't seem to find how to move the text.
//ram_txt1.data(ram_donut);
//ram_txt2.data(ram_donut);
ram_paths.transition()
.duration(500)
.attrTween("d", ram_tweenPie_update);
// record new position after move.
ram_paths.each(stash);
ram_arcs.select("text.ramswap_value_number")
.text(function(d, i) { return d.value.toFixed(0)
+ 'Mb' + ' ('
+ (d.value / ram_total * 100.00).toFixed(1)
+ '%)'; });
swap_arcs_group.data([swap_data]);
swap_donut(swap_data);
swap_arcs.data(swap_donut);
swap_paths.data(swap_donut);
swap_paths.transition()
.duration(500)
.attrTween("d", swap_tweenPie_update);
// record new positions.
swap_paths.each(stash);
swap_arcs.select("text.ramswap_value_number")
.text(function(d, i) { return d.value.toFixed(0)
+ 'Mb' + ' ('
+ (d.value / swap_total * 100.00).toFixed(1)
+ '%)'; });
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment