diff --git a/w2v-server.pl b/w2v-server.pl
index c92400b..af8b55d 100644
--- a/w2v-server.pl
+++ b/w2v-server.pl
@@ -354,7 +354,11 @@
 </style>
 <script>
 
-var opt = {epsilon: 1, perplexity: 20};
+var opt = {epsilon: 1, perplexity: 20},
+		mapWidth = 800, // width map
+		mapHeight = 800,
+		jitterRadius = 7;
+
 var T = new tsnejs.tSNE(opt); // create a tSNE instance
 
 var Y;
@@ -369,8 +373,8 @@
     .transition()
     .duration(50)
     .attr("transform", function(d, i) {
-      T.Y[i][0] = (d.x - 400 - tx)/ss/20;
-      T.Y[i][1] = (d.y - 400 - ty)/ss/20;
+      T.Y[i][0] = (d.x - mapWidth/2 - tx)/ss/20;
+      T.Y[i][1] = (d.y - mapHeight/2 - ty)/ss/20;
       return "translate(" +
         (d.x) + "," +
         (d.y) + ")";
@@ -380,11 +384,11 @@
 function updateEmbedding() {
   var Y = T.getSolution();
   svg.selectAll('.u')
-    .data(data.words)
-    .attr("transform", function(d, i) { 
-			return "translate(" +
-        ((Y[i][0]*20*ss + tx) + 400) + "," +
-        ((Y[i][1]*20*ss + ty) + 400) + ")"; });
+     .data(data.words)
+     .attr("transform", function(d, i) { 
+			 return "translate(" +
+         ((Y[i][0]*20*ss + tx) + mapWidth/2) + "," +
+         ((Y[i][1]*20*ss + ty) + mapHeight/2) + ")"; });
 }
 
 var svg;
@@ -393,146 +397,140 @@
 var text;
 
 function drawEmbedding() {
-   $("#embed").empty();
-   var div = d3.select("#embed");
-	 
-   // get min and max in each column of Y
-   var Y = T.Y;
-   
-   svg = div.append("svg") // svg is global
-						.attr("width", 800)
-						.attr("height", 800);
-	 
-   var g = svg.selectAll(".b")
-							.data(data.words)
-							.enter().append("g")
-							.attr("class", "u");
-	 
-   g.append("a")
-		.attr("xlink:href", function(word) {return "/?word="+word;})
-	  .attr("title", function(d, i) {
-			return "rank: "+i +"  "+"freq. rank: "+data.ranks[i];
-		})
+  $("#embed").empty();
+  var div = d3.select("#embed");
+	
+  // get min and max in each column of Y
+  var Y = T.Y;
+  
+  svg = div.append("svg") // svg is global
+					 .attr("width", mapWidth)
+					 .attr("height", mapHeight);
+	
+  var g = svg.selectAll(".b")
+						 .data(data.words)
+						 .enter().append("g")
+						 .attr("class", "u");
+	
+  g.append("a")
+	 .attr("xlink:href", function(word) {return "/?word="+word;})
+	 .attr("title", function(d, i) {
+		 return "rank: "+i +"  "+"freq. rank: "+data.ranks[i];
+	 })
 		.append("text")
-    .attr("text-anchor", "top")
-    .attr("font-size", 12)
-    .attr("fill", function(d) {
+   .attr("text-anchor", "top")
+   .attr("font-size", 12)
+   .attr("fill", function(d) {
 			if(data.target.indexOf(" "+d+" ") >= 0) {
 				return "red";
 			} else {
 				return "#333"
 			}
-		})
-    .text(function(d) { return d; });
-	 
-   var zoomListener = d3.behavior.zoom()
-												.scaleExtent([0.1, 10])
-												.center([0,0])
-												.on("zoom", zoomHandler);
-   zoomListener(svg);
- }
- 
- var tx=0, ty=0;
- var ss=1;
- var iter_id=-1;
- 
- function zoomHandler() {
-   tx = d3.event.translate[0];
-   ty = d3.event.translate[1];
-   ss = d3.event.scale;
-   updateEmbedding();
- }
- 
- var stepnum = 0;
+	 })
+   .text(function(d) { return d; });
+	
+  var zoomListener = d3.behavior.zoom()
+											 .scaleExtent([0.1, 10])
+											 .center([0,0])
+											 .on("zoom", zoomHandler);
+  zoomListener(svg);
+}
 
- function stopStep() {
-   clearInterval(iter_id);
-	 text = svg.selectAll("text");
-	 
-	 labels = d3.range(data.words.length).map(function(i) {
-     var x = (T.Y[i][0]*20*ss + tx) + 400;
-     var y = (T.Y[i][1]*20*ss + ty) + 400;
-		 anchor_array.push({x: x, y: y, r: 5});
-		 return {
-         x: x,
-         y: y,
-			   name: data.words[i]
-		 };
-	 });
+var tx=0, ty=0;
+var ss=1;
+var iter_id=-1;
 
-	 var index = 0;
-	 text.each(function() {
-		 labels[index].width = this.getBBox().width;
-		 labels[index].height = this.getBBox().height;
-		 index += 1;
-	 });
+function zoomHandler() {
+  tx = d3.event.translate[0];
+  ty = d3.event.translate[1];
+  ss = d3.event.scale;
+  updateEmbedding();
+}
+
+var stepnum = 0;
+
+function stopStep() {
+  clearInterval(iter_id);
+	text = svg.selectAll("text");
+	
+  // jitter function needs different data and co-ordinate representation
+	labels = d3.range(data.words.length).map(function(i) {
+    var x = (T.Y[i][0]*20*ss + tx) + mapWidth/2;
+    var y = (T.Y[i][1]*20*ss + ty) + mapHeight/2;
+		anchor_array.push({x: x, y: y, r: jitterRadius});
+		return {
+      x: x,
+      y: y,
+			name: data.words[i]
+		};
+	});
+  
+  // get the actual label bounding boxes for the jitter function
+	var index = 0;
+	text.each(function() {
+		labels[index].width = this.getBBox().width;
+		labels[index].height = this.getBBox().height;
+		index += 1;
+	});
 
 	 
 //	 setTimeout(updateEmbedding, 1);
 //	 setTimeout(
-	   labeler =	 d3.labeler()
-			 .label(labels)
-			 .anchor(anchor_array)
-			 .width(800)
-			 .height(800)
-			   .update(applyJitter);
-//         .start(1000);
+	labeler =	 d3.labeler()
+			         .label(labels)
+			         .anchor(anchor_array)
+			         .width(mapWidth)
+			         .height(mapHeight)
+			         .update(applyJitter);
+  //         .start(1000);
 
-     iter_id = setInterval(jitterStep, 1);
+  iter_id = setInterval(jitterStep, 1);
+}
 
- }
-
-var jitter_i=0;;
+var jitter_i=0;
 
 function jitterStep() {
-    if(jitter_i++ > 100) {
-        clearInterval(iter_id);
-    } else {
-     labeler.start2(10);
-	      applyJitter();
-    }
+  if(jitter_i++ > 100) {
+    clearInterval(iter_id);
+  } else {
+		labeler.start2(10);
+	  applyJitter();
+  }
 }
 
 var last_cost=1000;
 
- function step() {
-   var i = T.iter;
-   
-   if(i > <%= $no_iterations %>) {
-		 stopStep();
-   } else {
-     var cost = Math.round(T.step() *100000) / 100000; // do a few steps
-     $("#cost").html("tsne iteration " + i + ", cost: " + cost.toFixed(5));
-       if(i % 250 == 0 && cost >= last_cost) {
-		       stopStep();
-       } else {
-           last_cost = cost;
-           updateEmbedding();
-       }
-   }
- }
+function step() {
+  var i = T.iter;
+  
+  if(i > <%= $no_iterations %>) {
+		stopStep();
+  } else {
+    var cost = Math.round(T.step() * 100000) / 100000; // do a few steps
+    $("#cost").html("tsne iteration " + i + ", cost: " + cost.toFixed(5));
+    if(i % 250 == 0 && cost >= last_cost) {
+		  stopStep();
+    } else {
+      last_cost = cost;
+      updateEmbedding();
+    }
+  }
+}
 
- function showMap(j) {
-	 data=j;
-   T.iter=0;
-   T.initDataRaw(data.vecs); // init embedding
-   drawEmbedding(); // draw initial embedding
-	 
-	 if(iter_id >= 0) {
-		 clearInterval(iter_id);
-	 }
-   //T.debugGrad();
-   iter_id = setInterval(step, 1);
-   //step();
- }
+function showMap(j) {
+	data=j;
+  T.iter=0;
+  T.initDataRaw(data.vecs); // init embedding
+  drawEmbedding(); // draw initial embedding
+	
+	if(iter_id >= 0) {
+		clearInterval(iter_id);
+	}
+  //T.debugGrad();
+  iter_id = setInterval(step, 1);
+  //step();
+}
  
- function update() {
-          
-   text.transition().duration(800)
-       .attr("transform", transform);
- }
-
-
 </script>
 </head>
 <body>
