w2v-server.pl: clean-up code
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>