Skip to content

Instantly share code, notes, and snippets.

@agea
Created December 6, 2012 08:14
Show Gist options
  • Save agea/4222690 to your computer and use it in GitHub Desktop.
Save agea/4222690 to your computer and use it in GitHub Desktop.
Urban terror Log visualization
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
* { margin: 0; padding: 0;}
body, html { height:100%; background: white;}
</style>
<script type="text/javascript">
function countProperties(obj) {
var count = 0;
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
++count;
}
return count;
}
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.overrideMimeType('text/plain');
xmlhttp.open("GET","games.log",false);
xmlhttp.send();
logTxt=xmlhttp.responseText.split('\n');
var killPattern = /\s+(\S+)\s+killed\s+(\S+)\s+/;
var teamPattern = /\s+red:(\d+)\s+blue:(\d+)/;
var kmap={};
var plscore={};
var emap = {};
//teams = ['red','blue'];
var teams = [];
var red=0;
var blue=0;
</script>
<script type="text/javascript" src="lib/paper.js"></script>
<script type="text/paperscript" canvas="myCanvas">
var viewport = new Path.Rectangle(new Point(20,20),new Point(view.viewSize)-30).bounds;
var i = 0;
var ti = 0;
var rtxt = new PointText(viewport.bottomLeft + new Point(32,-46));
rtxt.content= red;
rtxt.fillColor = 'red';
rtxt.fillColor.alpha = .8;
rtxt.justification = 'right';
var btxt = new PointText(viewport.bottomLeft + new Point(32,-32));
btxt.content= blue;
btxt.fillColor = 'blue';
btxt.fillColor.alpha = .8;
btxt.justification = 'right';
function onFrame(){
i++;
if ( i < logTxt.length) {
var line = logTxt[i];
if (line.indexOf("MOD_CHANGE_TEAM")!=-1){
return;
}
var update = false;
var kmatch = killPattern.exec(line);
if (kmatch){
update = true;
var killer = kmatch[1];
var victim = kmatch[2];
if (!kmap[killer]){
kmap[killer] = {};
}
if (!kmap[victim]){
kmap[victim] = {};
}
if (!plscore[killer]){
plscore[killer] = {'score':0,'mark':null};
}
if (!plscore[victim]){
plscore[victim] = {'score':0,'mark':null};
}
var pkills = kmap[killer];
if (!pkills.hasOwnProperty(victim)){
pkills[victim] = 0;
}
plscore[killer]['score'] = plscore[killer]['score']+1;
plscore[victim]['score'] = plscore[victim]['score']-1;
pkills[victim] = pkills[victim]+1;
}
var tmatch = teamPattern.exec(line);
if (tmatch){
var r = parseInt(tmatch[1],10);
var b = parseInt(tmatch[2],10);
teams.push([r,b]);
var rstxt = new PointText(viewport.topLeft + new Point(32,48*(ti+1)));
rstxt.content = teams[ti][0];
rstxt.justification = 'right';
rstxt.fillColor = 'red';
rstxt.fillColor.alpha = 0.8;
var rsbar = new Path.Line(rstxt.position + new Point(4,-4),rstxt.position + new Point(4+teams[ti][0],-4))
rsbar.strokeColor = 'red';
rsbar.strokeColor.alpha= 0.8;
rsbar.strokeWidth = 12;
var bstxt = new PointText(rstxt.position + new Point(0,16));
bstxt.content = teams[ti][1];
bstxt.justification = 'right';
bstxt.fillColor = 'blue';
bstxt.fillColor.alpha = 0.8;
var bsbar = new Path.Line(bstxt.position + new Point(4,-4),bstxt.position + new Point(4+teams[ti][1],-4))
bsbar.strokeColor = 'blue';
bsbar.strokeColor.alpha= 0.8;
bsbar.strokeWidth = 12;
var rbar = new Path.Line(rtxt.position + new Point(4+red,-4),rtxt.position + new Point(3+red+teams[ti][0],-4))
rbar.strokeColor = 'red';
rbar.strokeColor.alpha= 0.8;
rbar.strokeWidth = 12;
var bbar = new Path.Line(btxt.position + new Point(4+blue,-4),btxt.position + new Point(3+blue+teams[ti][1],-4))
bbar.strokeColor = 'blue';
bbar.strokeColor.alpha= 0.8;
bbar.strokeWidth = 12;
ti++;
red += r;
blue += b;
rtxt.content = red;
btxt.content = blue;
}
};
if (!update){
return;
}
var minscore = 1000;
var maxscore = -1000;
for (var pl in plscore){
if (plscore[pl]['score'] < minscore){
minscore = plscore[pl]['score'];
}
if (plscore[pl]['score'] > maxscore){
maxscore = plscore[pl]['score'];
}
}
for (var pl in plscore){
if (plscore[pl]['score'] == minscore){
plscore[pl]['mark'] = 'loser';
} else if (plscore[pl]['score'] == maxscore){
plscore[pl]['mark'] = 'winner';
} else {
plscore[pl]['mark'] = null;
}
}
var players = countProperties(plscore);
var baseangle = 360/players;
var circles = {};
var c = 0;
for(var pl in plscore) {
var s = plscore[pl]['score'];
var as = Math.abs(s);
if (!plscore[pl]['circle']){
plscore[pl]['circle'] = new Path.Circle(viewport.topCenter + new Point(0,as*2) ,2+as*2);
}
var circle = plscore[pl]['circle'];
var angle = baseangle * c++;
circle.scale((2+as*2)/(circle.bounds.width/2.0));
circle.position = viewport.topCenter + new Point(0,as*2);
circle.rotate(angle,viewport.center);
circle.fillColor = s<0 ? 'red' : 'green';
if (plscore[pl]['mark']){
circle.strokeWidth=4;
circle.strokeColor = plscore[pl]['mark']=='winner' ? 'yellow' : '#7a3700';
} else{
circle.strokeWidth = 0;
circle.strokeColor = circle.fillColor;
}
var right = (c-1)<players/2;
if (!plscore[pl]['txt']){
plscore[pl]['txt'] = new PointText(right ? circle.bounds.rightCenter+new Point(10,0) : circle.bounds.leftCenter-new Point(10,0));
plscore[pl]['txt'].fillColor = 'black;'
}
var txt = plscore[pl]['txt'];
txt.position = right ? circle.bounds.rightCenter+new Point(10,0) : circle.bounds.leftCenter-new Point(10,0);
txt.content=pl + ": " + s ;
txt.justification = right ? 'left' : 'right';
circles[pl] = circle;
}
for (var pl in kmap){
var edges = kmap[pl];
for (var target in edges){
var w = edges[target];
var sc = circles[pl];
var sp = sc.bounds.center;
var tc = circles[target];
var tp = tc.bounds.center;
var nsp = sc.getNearestPoint(tp);
var ntp = (nsp + tc.getNearestPoint(sp)*2.5)/3.5;
var txtpoint = (ntp + (ntp-nsp).normalize(20)).rotate(45,ntp);
if (!emap[pl+"-"+target]){
emap[pl+"-"+target] = {};
emap[pl+"-"+target]['tl'] = new Path.Line(ntp,txtpoint);
emap[pl+"-"+target]['arc'] = new Path.Line(nsp,ntp);
emap[pl+"-"+target]['txt'] = new PointText(txtpoint);
}
var tl = emap[pl+"-"+target]['tl'];
var arc = emap[pl+"-"+target]['arc'];
var txt = emap[pl+"-"+target]['txt'];
arc.firstSegment.point = nsp;
arc.lastSegment.point = ntp;
tl.firstSegment.point = ntp;
tl.lastSegment.point = txtpoint;
tl.strokeColor = 'black';
tl.strokeColor.alpha = 0.1;
txt.position = txtpoint;
txt.fillColor = 'black';
txt.content=w;
txt.justification = 'center';
arc.strokeColor = 'black';
arc.strokeColor.alpha = 0.25;
arc.strokeWidth = w;
}
}
}
</script>
</head>
<body>
<canvas id="myCanvas" resize></canvas>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
* { margin: 0; padding: 0;}
body, html { height:100%; background: white;}
</style>
<script type="text/javascript">
function countProperties(obj) {
var count = 0;
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
++count;
}
return count;
}
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.overrideMimeType('text/plain');
xmlhttp.open("GET","games.log",false);
xmlhttp.send();
logTxt=xmlhttp.responseText.split('\n');
var killPattern = /\s+(\S+)\s+killed\s+(\S+)\s+/;
var teamPattern = /\s+red:(\d+)\s+blue:(\d+)/;
var kmap={};
var plscore={};
//teams = ['red','blue'];
var teams = [];
var red=0;
var blue=0;
for (var i = 0; i< logTxt.length; i++) {
var line = logTxt[i];
if (line.indexOf("MOD_CHANGE_TEAM")!=-1){
continue;
}
var kmatch = killPattern.exec(line);
if (kmatch){
var killer = kmatch[1];
var victim = kmatch[2];
if (!kmap[killer]){
kmap[killer] = {};
}
if (!kmap[victim]){
kmap[victim] = {};
}
if (!plscore[killer]){
plscore[killer] = {'score':0,'mark':null};
}
if (!plscore[victim]){
plscore[victim] = {'score':0,'mark':null};
}
var pkills = kmap[killer];
if (!pkills.hasOwnProperty(victim)){
pkills[victim] = 0;
}
plscore[killer]['score'] = plscore[killer]['score']+1;
plscore[victim]['score'] = plscore[victim]['score']-1;
pkills[victim] = pkills[victim]+1;
}
var tmatch = teamPattern.exec(line);
if (tmatch){
var r = parseInt(tmatch[1],10);
var b = parseInt(tmatch[2],10);
teams.push([r,b]);
red += r;
blue += b;
}
};
var minscore = 1000;
var maxscore = -1000;
for (var pl in plscore){
if (plscore[pl]['score'] < minscore){
minscore = plscore[pl]['score'];
}
if (plscore[pl]['score'] > maxscore){
maxscore = plscore[pl]['score'];
}
}
for (var pl in plscore){
if (plscore[pl]['score'] == minscore){
plscore[pl]['mark'] = 'loser';
}
if (plscore[pl]['score'] == maxscore){
plscore[pl]['mark'] = 'winner';
}
}
</script>
<script type="text/javascript" src="lib/paper.js"></script>
<script type="text/paperscript" canvas="myCanvas">
var viewport = new Path.Rectangle(new Point(20,20),new Point(view.viewSize)-30).bounds;
var players = countProperties(plscore);
var baseangle = 360/players;
var circles = {};
var c = 0;
for(var pl in plscore) {
var s = plscore[pl]['score'];
var as = Math.abs(s);
var circle = new Path.Circle(viewport.topCenter + new Point(0,as*2) ,2+as*2);
var angle = baseangle * c++;
circle.rotate(angle,viewport.center);
circle.fillColor = s<0 ? 'red' : 'green';
if (plscore[pl]['mark']!=null){
circle.strokeWidth=4;
circle.strokeColor = plscore[pl]['mark']=='winner' ? 'yellow' : '#7a3700';
}
var right = (c-1)<players/2;
var txt = new PointText(right ? circle.bounds.rightCenter+new Point(10,0) : circle.bounds.leftCenter-new Point(10,0));
txt.content=pl + ": " + s ;
txt.fillColor = 'black;'
txt.justification = right ? 'left' : 'right';
circles[pl] = circle;
}
for (var pl in kmap){
var edges = kmap[pl];
for (var target in edges){
var w = edges[target];
var sc = circles[pl];
var sp = sc.bounds.center;
var tc = circles[target];
var tp = tc.bounds.center;
var nsp = sc.getNearestPoint(tp);
var ntp = (nsp + tc.getNearestPoint(sp)*2.5)/3.5;
var arc = new Path.Line(nsp,ntp);
var txtpoint = (ntp + (ntp-nsp).normalize(20)).rotate(45,ntp);
var tl = new Path.Line(ntp,txtpoint);
tl.strokeColor = 'black';
tl.strokeColor.alpha = 0.1;
var txt = new PointText(txtpoint);
txt.fillColor = 'black';
txt.content=w;
txt.justification = 'center';
arc.strokeColor = 'black';
arc.strokeColor.alpha = 0.25;
arc.strokeWidth = w;
}
}
for (var i = 0; i< teams.length;i++){
var rstxt = new PointText(viewport.topLeft + new Point(32,32*(i+1)));
rstxt.content = teams[i][0];
rstxt.fillColor = 'red';
var bstxt = new PointText(viewport.topLeft + new Point(64,32*(i+1)));
bstxt.content = teams[i][1];
bstxt.fillColor = 'blue';
}
var rtxt = new PointText(viewport.bottomLeft + new Point(100,-100));
rtxt.content= red;
rtxt.characterStyle = {
fontSize: red/3,
fillColor: 'red',
};
var btxt = new PointText(viewport.bottomRight - new Point(100,100));
btxt.content= blue;
btxt.justification = 'right';
btxt.characterStyle = {
fontSize: blue/3,
fillColor: 'blue',
};
function onFrame(){
}
</script>
</head>
<body>
<canvas id="myCanvas" resize></canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment