w2v-server: add hidden button to show maps for collocators

TODO:
* put 2D-map functions into objects
* parametrize dom destinations
diff --git a/templates/index.html.ep b/templates/index.html.ep
index fa641f7..08f7630 100644
--- a/templates/index.html.ep
+++ b/templates/index.html.ep
@@ -17,6 +17,7 @@
      var urlParams = new URLSearchParams(window.location.search);
      var currentWords = urlParams.get("word");
      var CIIsearchWords = (currentWords.includes(" ") ? '('+currentWords.replace(/ +/g, " oder ")+')' : currentWords);
+     var collocatorTable = null;
 
      $('#firstable').hide();
      $(document).ready(function() {
@@ -124,7 +125,7 @@
 
          if (collocatorData != null) {
              maxHeat = Math.max.apply(Math,collocatorData.map(function(o){return Math.max.apply(Math,o.heat);}))
-             var t = $('#secondtable').DataTable({
+             collocatorTable = $('#secondtable').DataTable({
                  data: collocatorData,
                  "sScrollY": "780px",
                  "bScrollCollapse": true,
@@ -139,18 +140,20 @@
                      { "data": "prob", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) }  },
                      { "data": "cprob", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) }  },
                      { "data": "overall", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) } },
-                     { "data": "word",  sClass: "collocator" }
+                     { "data": "word",  sClass: "collocator" },
+                     { "data": "rank", type: "allnumeric" }
                  ],
                  "columnDefs": [
                      { className: "dt-right", "targets": [0,2,3,4,5,6] },
                      { className: "dt-center", "targets": [ 1] },
                      { "searchable": false,
                        "orderable": false,
-                       "targets": 0
+                       "targets": [0, 8]
                      },
                      { "type": "scientific", targets: [2,3,4,5,6] },
                      { "orderSequence": [ "desc" ], "targets": [ 2, 3, 4, 5, 6 ] },
                      { "orderSequence": [ "asc", "desc" ], "targets": [ 1, 7 ] },
+                     { "targets": [8], "visible": false }
                  ],
                  "oLanguage": {
                      "sSearch": "Filter: "
@@ -158,8 +161,8 @@
                  "order": [[ 4, 'desc' ]],
              } );
 
-             t.on( 'order.dt search.dt', function () {
-                 t.column(0, {order:'applied'}).nodes().each( function (cell, i) {
+             collocatorTable.on( 'order.dt search.dt', function () {
+                 collocatorTable.column(0, {order:'applied'}).nodes().each( function (cell, i) {
                      cell.innerHTML = i+1;
                  } );
              } ).draw();
@@ -509,8 +512,8 @@
                 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) + ")";
+                                              (d.x) + "," +
+                                              (d.y) + ")";
             });
      }
 
@@ -520,8 +523,8 @@
             .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) + ")"; });
+                                               ((Y[i][0]*20*ss + tx) + mapWidth/2) + "," +
+                                               ((Y[i][1]*20*ss + ty) + mapHeight/2) + ")"; });
      }
 
      var svg;
@@ -672,6 +675,8 @@
      function showMap(j) {
          data=j;
          T.iter=0;
+         iter_id = -1;
+         last_cost=1000;
          T.initDataRaw(data.vecs); // init embedding
          drawEmbedding(); // draw initial embedding
 
@@ -686,6 +691,23 @@
      }
      var queryword;
 
+     function showCollocatorSOM() {
+         if (collocatorTable) {
+             var ctableData = collocatorTable.rows().data();
+             var nwords = [],
+                 nranks = [];
+             for (var i=0; i < ctableData.length && i < 100; i++) {
+                 nranks.push(ctableData[i].rank);
+                 nwords.push(ctableData[i].word);
+             }
+             $.post('/derekovecs/getVecsByRanks',
+                    JSON.stringify(nranks),
+                    function(data, status){
+                        showMap({target: " "+urlParams.get('word')+" ", mergedEnd: 0, words: nwords, vecs: data, ranks: nranks, marked: Array(100).fill(false)} );
+                    }, 'json');
+         }
+     }
+
      function onload() {
          queryword = document.getElementById('word');
      }
@@ -809,7 +831,7 @@
             % }
         </div>
         <div id="tabs-2">
-          <div id="som2" style="width: 800; height: 800px">
+          <div id="som2" style="width: 800;">
           </div>
           <div id="sominfo1"><span id="somcolor1">   </span> <span id="somword1"> </span> <span id="somcolor2">   </span> <span id="somword2"> </span> <span id="somcolor3">   </span></div>
           <div id="sominfo">SOM iteration <span id="iterations">0</span></div>
@@ -845,14 +867,13 @@
                   </td>
                   <td align="right">
                   </td>
-                  <script
-                      src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
-                      </td>
                 </tr>
               </tbody>
             </table>
-          </div> <!-- - tab2 -->
-        </div> <!-- tabs -->
+          </div>
+          <div style="float: right; overflow: hidden" id="extra"><button onClick="showCollocatorSOM()"> </button></div>
+          <div style="float: right; overflow: hidden" id="clock"></div>
+        </div>
       </div>
     </div> <!-- topwrapper  -->
     <div style="clear: both;"></div>
diff --git a/w2v-server.pl b/w2v-server.pl
index 2768296..22dbb3a 100755
--- a/w2v-server.pl
+++ b/w2v-server.pl
@@ -11,6 +11,7 @@
 use Getopt::Std;
 use Mojo::Server::Daemon;
 use Cwd;
+
 app->static->paths->[0] = getcwd;
 
 plugin 'Log::Access';
@@ -82,6 +83,12 @@
 	$c->reply->static($url);
 };
 
+post '/derekovecs/getVecsByRanks' => sub {
+  my $self = shift;
+  my $vec = getVecs($self->req->json);
+  $self->render(json => $vec);
+};
+
 get '*/img/*' => sub {
 	my $c = shift;
 	my $url = $c->req->url;
@@ -524,6 +531,23 @@
 }
 
 
+AV *getVecs(AV *array) {
+  int i, b;
+  AV *result = newAV();
+  for (i=0; i<=av_len(array); i++) {
+    SV** elem = av_fetch(array, i, 0);
+    if (elem != NULL) {
+      long j = (long) SvNV(*elem);
+      AV *vector = newAV();
+      for (b = 0; b < size; b++) {
+        av_push(vector, newSVnv(M[b + j * size]));
+      }
+      av_push(result, newRV_noinc(vector));
+    }
+  }
+  return result;
+}
+
 wordlist *getTargetWords(char *st1, int search_backw) {
   wordlist *wl = malloc(sizeof(wordlist));
   char st[100][max_size], sep[100];