Skip to content

Commit

Permalink
lots of new viz stuff for the interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Cliff Moon committed Oct 24, 2008
1 parent 43f9aa2 commit 808acc7
Show file tree
Hide file tree
Showing 6 changed files with 400 additions and 32 deletions.
50 changes: 22 additions & 28 deletions web/index.html
Expand Up @@ -8,13 +8,7 @@
<script type="text/javascript" src="/javascripts/drawarrows.js"></script>
<script type="text/javascript" src="/javascripts/viz.js"></script>
<script type="text/javascript">
function decimals(number, value) {
with(Math) {
var coefficient = pow(10, number);
return round(value * coefficient) / coefficient;
}
}


$(document).ready(function(data) {
$.getJSON("/rpc/info/stats", function(stats) {
$("#node").text(stats.node);
Expand All @@ -38,20 +32,20 @@
var canvas = document.getElementById("canvas");
draw_nodes(stats.member_nodes, stats.running_nodes, canvas);
});
$.getJSON("/rpc/rates/" + escape(stats.node), function(rates) {
$("#get_rate").text(decimals(2, rates.get_rate));
$("#put_rate").text(decimals(2, rates.put_rate));
$("#in_rate").text(decimals(2, rates.in_rate / Math.pow(2, 10)));
$("#out_rate").text(decimals(2, rates.out_rate / Math.pow(2, 10)));
$("#connections").text(rates.connections);
});
$.getJSON("/rpc/rates/cluster", function(rates) {
$("#c_get_rate").text(decimals(2, rates.get_rate));
$("#c_put_rate").text(decimals(2, rates.put_rate));
$("#c_in_rate").text(decimals(2, rates.in_rate / Math.pow(2, 10)));
$("#c_out_rate").text(decimals(2, rates.out_rate / Math.pow(2, 10)));
$("#c_connections").text(rates.connections);
});
// $.getJSON("/rpc/rates/" + escape(stats.node), function(rates) {
// $("#get_rate").text(decimals(2, rates.get_rate));
// $("#put_rate").text(decimals(2, rates.put_rate));
// $("#in_rate").text(decimals(2, rates.in_rate / Math.pow(2, 10)));
// $("#out_rate").text(decimals(2, rates.out_rate / Math.pow(2, 10)));
// $("#connections").text(rates.connections);
// });
// $.getJSON("/rpc/rates/cluster", function(rates) {
// $("#c_get_rate").text(decimals(2, rates.get_rate));
// $("#c_put_rate").text(decimals(2, rates.put_rate));
// $("#c_in_rate").text(decimals(2, rates.in_rate / Math.pow(2, 10)));
// $("#c_out_rate").text(decimals(2, rates.out_rate / Math.pow(2, 10)));
// $("#c_connections").text(rates.connections);
// });
});
});
});
Expand All @@ -60,16 +54,16 @@
<body>
<div class="header"><!-- <img src="/images/dynomite_logo.png" style="float: right;"/> -->
<h1>Dynomite</h1>
<h2>Dashboard for <span id="node"></span></h2>
<h2>Health for <span id="node"></span></h2>
</div>
<ul id="menu">
<li>Health</li>
<li><a href="">Stats</a></li>
<li><a href="">Sync</a></li>
<li><a href="">Partitioning</a></li>
<li><a href="/load.html">Load</a></li>
<li><a href="/sync.html">Replication</a></li>
<li><a href="/partitions.html">Partitioning</a></li>
</ul>
<canvas id="canvas" width="600" height="600" style="float: right; padding-right: 10px;"></canvas>
<h3>Node Stats</h3>
<canvas id="canvas" width="600" height="600"></canvas>
<!-- <h3>Node Stats</h3>
<ul>
<li><span id="get_rate">0.0</span> gets/sec</li>
<li><span id="put_rate">0.0</span> puts/sec</li>
Expand All @@ -83,7 +77,7 @@ <h3>Cluster Stats</h3>
<li><span id="c_put_rate">0.0</span> puts/sec</li>
<li><span id="c_out_rate">0.0</span> KB/sec out</li>
<li><span id="c_in_rate">0.0</span> KB/sec in</li>
<li><span id="c_connections">0.0</span> connections</li>
<li><span id="c_connections">0.0</span> connections</li> -->
<!-- <li>Running Nodes:</li><ul id="running_nodes"></ul>
<li>Member Nodes:</li><ul id="member_nodes"></ul> -->
</ul>
Expand Down
21 changes: 21 additions & 0 deletions web/javascripts/color.js
@@ -0,0 +1,21 @@
function hsv2rgb(h, s, v) {
var hi = Math.floor(h/60) % 6;
var f = h / 60 - Math.floor(h/60);
var p = Math.round(255 * v * (1-s));
var q = Math.round(255 * v * (1-f*s));
var t = Math.round(255 * v * (1-(1-f)*s));
v = Math.round(v * 255);
switch (hi) {
case 0: return [v,t,p];
case 1: return [q,v,p];
case 2: return [p,v,t];
case 3: return [p,q,v];
case 4: return [t,p,v];
case 5: return [v,p,q];
}
}

function hsv2rgba(h, s, v) {
var color = hsv2rgb(h, s, v);
return "rgba(" + color[0] + "," + color[1] + "," + color[2] + ",1)";
}
215 changes: 211 additions & 4 deletions web/javascripts/viz.js
@@ -1,4 +1,9 @@

function decimals(number, value) {
with(Math) {
var coefficient = pow(10, number);
return round(value * coefficient) / coefficient;
}
}

function node_index(member_nodes, node_name) {
var index = -1;
Expand Down Expand Up @@ -35,9 +40,9 @@ function draw_nodes(member_nodes, running_nodes, canvas) {
ctx.strokeStyle = "#193E4A";
ctx.fillStyle = "#193E4A";
ctx.drawLineArrow(
Math.cos(beginTheta) * scale + xoffset - 2.5,
Math.cos(beginTheta) * scale + xoffset,
Math.sin(beginTheta) * scale + yoffset,
Math.cos(endTheta) * scale + xoffset - 2.5,
Math.cos(endTheta) * scale + xoffset,
Math.sin(endTheta) * scale + yoffset);
}
});
Expand All @@ -55,11 +60,213 @@ function draw_nodes(member_nodes, running_nodes, canvas) {
var x = Math.cos(theta) * scale + xoffset;
var y = Math.sin(theta) * scale + yoffset;
// ctx.moveTo(x, y);
ctx.arc(x-5,y,5,0,Math.PI*2,true);
ctx.arc(x,y,5,0,Math.PI*2,true);
ctx.fill();
ctx.stroke();
ctx.drawTextCenter("sans", 10, x, y-15, node.name);
});
}

function pickColors(nodes) {
var angle = 360 / nodes.length;
var hash = new Array();
$.each(nodes, function(n, node) {
hash[node] = n*angle;
});
return hash;
}

function partMap(member_nodes) {
var hash = new Array();
$.each(member_nodes, function(n, node) {
hash[node.name] = node.partitions;
});
return hash;
}

function replicaMap(member_nodes) {
var hash = new Array();
$.each(member_nodes, function(n, node) {
hash[node.name] = node.replicas;
});
return hash;
}

function syncMap(syncs) {
var hash = new Array();
$.each(syncs, function(n, sync) {
hash[sync.partition + ""] = sync.nodes;
});
return hash;
}

function drawArcSection(ctx,x,y,radius,width,startAngle,endAngle,unfilled,closed) {
ctx.beginPath();
ctx.arc(x,y,radius,startAngle,endAngle,false);
ctx.lineTo(Math.cos(endAngle) * (radius-width) + x, Math.sin(endAngle) * (radius-width) + y);
ctx.arc(x,y,radius-width,endAngle,startAngle,true);
if (closed) {
ctx.lineTo(Math.cos(startAngle) * radius + x, Math.sin(startAngle) * radius + y);
}
if (!unfilled) {
ctx.fill();
}
ctx.stroke();
}

function drawPartitions(nodes, partitions, member_nodes, canvas) {
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
CanvasTextFunctions.enable(ctx);

var xoffset = canvas.width / 2 + 100;
var yoffset = canvas.height / 2;
var radius = yoffset - 50;

var angular_offset = Math.PI / 2 * 3;
var angle = 2 * Math.PI / partitions.length;
var colormap = pickColors(nodes);
var partmap = partMap(member_nodes);

$.each(nodes, function(n, node) {
ctx.fillStyle = hsv2rgba(colormap[node], 1, 1);
ctx.strokeStyle = "#000";
ctx.fillRect(5, n*20 + 15, 30, 15);
ctx.strokeRect(5, n*20 + 15, 30, 15);
ctx.drawText('sans', 12, 45, n*20 + 27, node // + " " + partmap[node].length
);
});

$.each(partitions, function(n, part) {
ctx.beginPath();
ctx.strokeStyle = "rgba(0, 0, 0, 1)"
ctx.fillStyle = hsv2rgba(colormap[part.node], 1, 1);
var startAngle = n * angle + angular_offset;
var endAngle = (n+1) * angle + angular_offset;
drawArcSection(ctx,xoffset,yoffset,radius,20,startAngle,endAngle);
});
}

function drawRates(node_rates, canvas) {
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
CanvasTextFunctions.enable(ctx);

var xoffset = canvas.width / 2 + 100;
var yoffset = canvas.height / 2;
var radius = yoffset - 50;

var angular_offset = Math.PI / 2 * 3;
var colormap = pickColors($.map(node_rates, function(node) { return node.name }));

var totalLoad = 0;
$.each(node_rates, function(n, node) { totalLoad += node.get_rate + node.put_rate });

$.each(node_rates, function(n, node) {
ctx.fillStyle = hsv2rgba(colormap[node.name], 1, 1);
ctx.strokeStyle = "#000";
ctx.fillRect(5, n*20 + 15, 30, 15);
ctx.strokeRect(5, n*20 + 15, 30, 15);
if (totalLoad == 0) {
var percentage = "0%"
} else {
var percentage = decimals(1, (node.get_rate + node.put_rate) / totalLoad * 100) + "%"
}

ctx.drawText('sans', 12, 45, n*20 + 27, node.name + " " + percentage); // + " " + partmap[node].length);
});


$.each(node_rates, function(n, node) {
if (totalLoad == 0) {
var angle = 2 * Math.PI / node_rates.length;
} else {
var angle = 2 * Math.PI * ((node.get_rate + node.put_rate) / totalLoad);
}
ctx.fillStyle = hsv2rgba(colormap[node.name], 1, 1);
drawArcSection(ctx,xoffset,yoffset,radius,20,angular_offset,angular_offset+angle);
angular_offset += angle;
});
}

function drawSync(nodes, partitions, member_nodes, syncs_running, diff_sizes, canvas) {
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
CanvasTextFunctions.enable(ctx);

var xoffset = canvas.width / 2 + 100;
var yoffset = canvas.height / 2;
var radius = yoffset - 50;

var angular_offset = Math.PI / 2 * 3;
var angle = 2 * Math.PI / partitions.length;
var colormap = pickColors(nodes);
var partmap = partMap(member_nodes);
var replicamap = replicaMap(member_nodes);
var syncmap = syncMap(syncs_running);

$.each(nodes, function(n, node) {
ctx.fillStyle = hsv2rgba(colormap[node], 1, 1);
ctx.strokeStyle = "#000";
ctx.fillRect(5, n*20 + 15, 30, 15);
ctx.strokeRect(5, n*20 + 15, 30, 15);
ctx.drawText('sans', 12, 45, n*20 + 27, node); // + " " + partmap[node].length);
});

$.each(partitions, function(n, part) {
ctx.beginPath();
ctx.strokeStyle = "rgba(0,0,0,1)"
ctx.fillStyle = hsv2rgba(colormap[part.node], 1, 1);

var startAngle = n * angle + angular_offset;
var endAngle = (n+1) * angle + angular_offset;
drawArcSection(ctx,xoffset,yoffset,radius,20,startAngle,endAngle);

$.each(replicamap[part.node], function(i, replica) {
if (replica == part.node) {
return;
}

if (diff_sizes[part.partition + ""] && diff_sizes[part.partition + ""][replica]) {
diff = diff_sizes[part.partition + ""][replica];
if (diff == 0) {
var value = 1;
} else {
var value = 1 - Math.log(diff) / Math.log(2) / 32;
}
ctx.strokeStyle = "rgba(0, 0, 0, 1)"
ctx.fillStyle = hsv2rgba(colormap[replica], 1, value);
} else {
ctx.strokeStyle = "rgba(0, 0, 0, 1)"
ctx.fillStyle = hsv2rgba(colormap[replica], 1, 1);
}
// ctx.fillStyle = colormap[replica];
drawArcSection(ctx,xoffset,yoffset,radius-(i*25),20,startAngle,endAngle);
});
});

$.each(partitions, function(n, part) {
var startAngle = n * angle + angular_offset;
var endAngle = (n+1) * angle + angular_offset;

if (syncmap[part.partition + ""] && $.inArray(part.node, syncmap[part.partition + ""]) != -1) {
// ctx.strokeStyle = "#ffffff";
ctx.lineWidth = 3;
drawArcSection(ctx,xoffset,yoffset,radius,20,startAngle,endAngle,true,true);
} else {
return;
}

$.each(replicamap[part.node], function(i, replica) {
if (replica == part.node) {
return;
}
if (syncmap[part.partition + ""] && $.inArray(replica, syncmap[part.partition + ""]) != -1) {
// ctx.strokeStyle = "#ffffff";
ctx.lineWidth = 2;
for(x=0;x<5;x++) {drawArcSection(ctx,xoffset,yoffset,radius-(i*25),20,startAngle,endAngle,true,true);}
}
});
ctx.lineWidth = 1;
});
}
46 changes: 46 additions & 0 deletions web/load.html
@@ -0,0 +1,46 @@
<html>
<head>
<link href="/stylesheets/master.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="/javascripts/jquery-1.2.6.js"></script>
<script type="text/javascript" src="/javascripts/domec.js"></script>
<script type="text/javascript" src="/javascripts/jquery.timer.js"></script>
<script type="text/javascript" src="/javascripts/canvastext.js"></script>
<script type="text/javascript" src="/javascripts/drawarrows.js"></script>
<script type="text/javascript" src="/javascripts/color.js"></script>
<script type="text/javascript" src="/javascripts/viz.js"></script>
<script type="text/javascript">
$(document).ready(function(data) {
$.getJSON("/rpc/info/stats", function(stats) {
$("#node").text(stats.node);
});

$.getJSON("/rpc/rates/nodes", function(node_rates) {
var canvas = document.getElementById("canvas");
drawRates(node_rates, canvas);
});

$.timer(1000, function(timer) {
$.getJSON("/rpc/rates/nodes", function(node_rates) {
var canvas = document.getElementById("canvas");
drawRates(node_rates, canvas);
});
});
});
</script>
</head>
<body>
<div class="header"><!-- <img src="/images/dynomite_logo.png" style="float: right;"/> -->
<h1>Dynomite</h1>
<h2>Load for <span id="node"></span></h2>
</div>
<ul id="menu">
<li><a href="/index.html">Health</a></li>
<li>Load</li>
<li><a href="/sync.html">Replication</a></li>
<li><a href="/partitions.html">Partitioning</a></li>
</ul>
<canvas id="canvas" width="800" height="600"></canvas>
</ul>

</body>
</html>

0 comments on commit 808acc7

Please sign in to comment.