14 Commits 1ff8719534 ... f81ba2e14d

Autore SHA1 Messaggio Data
  Raghav Arora f81ba2e14d Added a Slicing Box to Wave 6 anni fa
  Raghav Arora dfed58a27d Updated Wave to add Slicebox 6 anni fa
  Raghav Arora 4e69131c54 Corrected Zoom indication when it goes out-of-bounds 6 anni fa
  Raghav Arora b26681d0ff Added Axis markings to zoom control 6 anni fa
  Raghav Arora 8b08634605 Removed zoom to slicing 6 anni fa
  Raghav Arora 1ff8719534 Added a Slicing Box to Wave 6 anni fa
  Raghav Arora 05065ddfda Updated Wave to add Slicebox 6 anni fa
  Raghav Arora 1e18cdafce Corrected Zoom indication when it goes out-of-bounds 6 anni fa
  Matthias Vogelgesang 991a1a02b7 Use current communication protocol and clean up 6 anni fa
  Raghav Arora d9a6547130 Added Axis markings to zoom control 6 anni fa
  Raghav Arora 4b2bb629c5 Removed zoom to slicing 6 anni fa
  Matthias Vogelgesang 751817efad Update for current nova-wave-server 6 anni fa
  Matthias Vogelgesang 7002d93442 Reconstruct order 6 anni fa
  Matthias Vogelgesang 3d7e05434f Use more slicemaps 6 anni fa
1 ha cambiato i file con 306 aggiunte e 287 eliminazioni
  1. 306 287
      nova/templates/dataset/wave.html

+ 306 - 287
nova/templates/dataset/wave.html

@@ -71,299 +71,318 @@
   <script src="{{ url_for('static', filename='js/wave/stats.min.js') }}"></script>
   <script src="{{ url_for('static', filename='js/dragslider.js') }}"></script>
   <script>
-        $slicemaps = []
-        var collection_name = '{{ collection }}';
-        var dataset_name = '{{ dataset.name }}';
-        var user_name = '{{ owner.name }}';
-        var is_wave = true;
+    var collection_name = '{{ collection }}';
+    var dataset_name = '{{ dataset.name }}';
+    var user_name = '{{ owner.name }}';
+    var is_wave = true;
+    var subsets = 5;
 
-        $minGT = 0, $maxGT = 255;
-        $current_x = 0, $current_y = 0, $current_z = 0, $current_dim = 100;
-        $subsets = 1;
-        $ops = {{ ops|tojson|safe if ops!=None else 'null' }};
-        if ($ops != null) {
-            $current_x = $ops["origin"][0];
-            $current_y = $ops["origin"][1];
-            $current_z = $ops["origin"][2];
-            $current_dim = $ops["dimensions"][0];
-            $gt = $ops["gray-thresholds"];
-            if ($gt != null) {
-                $minGT = $gt[0];
-                $maxGT = $gt[1];
-            }
+    var minGT = 0, maxGT = 255;
+    var current_x = 0, current_y = 0, current_z = 0, current_dim = 100;
+    var ops = {{ ops|tojson|safe if ops!=None else 'null' }};
+
+    if (ops != null) {
+      current_x = ops["origin"][0];
+      current_y = ops["origin"][1];
+      current_z = ops["origin"][2];
+      current_dim = ops["dimensions"][0];
+      var gt = ops["gray-thresholds"];
+
+      if (gt != null) {
+        minGT = gt[0];
+        maxGT = gt[1];
+      }
+    }
+
+    function beginWave(slicemaps) {
+      var config = {
+        "dom_container": "wave-container",
+        "slicemaps_paths": slicemaps,
+        "steps" : 144,
+        "shader_name": "secondPassSoebel",
+        "slices_range": [0, subsets * 256 - 1],
+        "row_col": [16, 16],
+        "renderer_size": [512, 512],
+        "renderer_canvas_size": ['*','*']
+      };
+
+      vrc = new VRC.VolumeRaycaster(config);
+      vrc.setGrayMinValue(minGT / 255);
+      vrc.setGrayMaxValue(maxGT / 255);
+      vrc.showZoomBox(false);
+    }
+
+    function sendContinuousGetToLocationUntilDone(queryUrl) {
+      $.ajax(queryUrl, {
+        method: "GET",
+        crossDomain: true
+      }).done(function(data, textStatus, jqXHR) {
+        if (data.status == 'running') {
+          setTimeout(function() {
+            sendContinuousGetToLocationUntilDone(queryUrl);
+          }, 2000);
+        }
+        else {
+          var slicemaps = [];
+          var mapUrl = jqXHR.getResponseHeader('location');
+
+          $("#loading-wave").remove();
+
+          for (var i = 0; i < subsets; i++) {
+            slicemaps.push(mapUrl + "/" + i);
+          }
+
+          beginWave(slicemaps);
+        }
+      });
+    }
+
+    $(document).ready(function() {
+      $("#wave-container").height($("#wave-container").width());
+      var origin_array = [current_x / 100, current_y / 100, current_z / 100];
+      var dimensions_array = [current_dim / 100, current_dim / 100];
+
+      var params = JSON.stringify({
+        "token": "{{token|safe}}",
+        "user": user_name,
+        "dataset": dataset_name,
+        "origin": origin_array,
+        "dimensions": dimensions_array,
+        "subsets": subsets
+      });
+
+      $.ajax("http://localhost:5001/maps", {
+        data: params,
+        contentType: "application/json",
+        method: "POST"
+      }).done(function(data, textStatus, jqXHR){
+        sendContinuousGetToLocationUntilDone(jqXHR.getResponseHeader('location'));
+      }).fail(function() {
+        alert("An error occured");
+      });
+
+      $("#slider-gray-threshold").slider ({
+        range: true,
+        min: 0,
+        max: 255,
+        values: [minGT, maxGT],
+        slide: function( event, ui ) {
+          var min = ui.values[0];
+          var max = ui.values[1];
+          vrc.setGrayMinValue(min / 255);
+          $("#gray-threshold-min-input").val(min);
+          vrc.setGrayMaxValue(max / 255);
+          $("#gray-threshold-max-input").val(max);
+        }
+      });
+
+      $("#slider-X").dragslider ({
+        range: true,
+        rangeDrag: true,
+        min: 0,
+        max: 100,
+        values: [0, 100],
+        slide: function( event, ui ) {
+          var min = ui.values[0];
+          var max = ui.values[1];
+          vrc.setGeometryMinX(min / 100);
+          $("#x-min-input").val(min);
+          vrc.setGeometryMaxX(max / 100);
+          $("#x-max-input").val(max);
+          vrc.setZoomXMinValue(min/100)
+          vrc.setZoomXMaxValue(max/100)
+        },
+        start: function( event, ui ){
+          vrc.showZoomBox(true);
+        },
+        stop: function( event, ui ){
+          vrc.showZoomBox(false);
         }
-        function beginWave() {
-            $config = {
-                "dom_container": "wave-container",
-                "slicemaps_paths": $slicemaps,
-                "steps" : 144,
-                "shader_name": "secondPassSoebel",
-                "slices_range": [0, 255],
-                "row_col": [16, 16],
-                "renderer_size": [512, 512],
-                "renderer_canvas_size": ['*','*']
-            };
+      });
 
-            $vrc = new VRC.VolumeRaycaster($config);
-            $vrc.setGrayMinValue($minGT/255);
-            $vrc.setGrayMaxValue($maxGT/255);
-            $vrc.showZoomBox(false);
+      $("#slider-Y").dragslider ({
+        range: true,
+        rangeDrag: true,
+        min: 0,
+        max: 100,
+        values: [0, 100],
+        slide: function( event, ui ) {
+          min = ui.values[0];
+          max = ui.values[1];
+          vrc.setGeometryMinY(min / 100);
+          $("#y-min-input").val(min);
+          vrc.setGeometryMaxY(max / 100);
+          $("#y-max-input").val(max);
+          vrc.setZoomYMinValue(min/100)
+          vrc.setZoomYMaxValue(max/100)
+        },
+        start: function( event, ui ){
+          vrc.showZoomBox(true);
+        },
+        stop: function( event, ui ){
+          vrc.showZoomBox(false);
         }
-        function sendContinuousGetToLocationUntilDone($loc) {
-            $.ajax($loc, {
-                method:"GET",
-                crossDomain:true
-            }).done(function(data, textStatus, jqXHR) {
-                if (data.status == 'running') {
-                    setTimeout(function() {
-                        sendContinuousGetToLocationUntilDone($loc);
-                    }, 2000);
-                } else {
-                    $location = jqXHR.getResponseHeader('location');
-                    $slicemaps.push($location);
-                    if ($slicemaps.length == $subsets) {
-                        $( "#loading-wave" ).remove();
-                        beginWave();
-                    }
-                }
-            });
+      });
+
+      $("#slider-Z").dragslider ({
+        range: true,
+        rangeDrag: true,
+        min: 0,
+        max: 100,
+        values: [0, 100],
+        slide: function( event, ui ) {
+          min = ui.values[0];
+          max = ui.values[1];
+          vrc.setGeometryMinZ(min / 100);
+          $("#z-min-input").val(min);
+          vrc.setGeometryMaxZ(max / 100);
+          $("#z-max-input").val(max);
+          vrc.setZoomZMinValue(min/100)
+          vrc.setZoomZMaxValue(max/100)
+        },
+        start: function( event, ui ){
+          vrc.showZoomBox(true);
+        },
+        stop: function( event, ui ){
+          vrc.showZoomBox(false);
         }
-        $( document ).ready(function() {
-            $("#wave-container").height($("#wave-container").width());
-            $origin_array = [$current_x/100, $current_y/100, $current_z/100];
-            $dimensions_array = [$current_dim/100, $current_dim/100];
-            for ($i = 1; $i <= $subsets; $i++) {
-                $params = JSON.stringify({
-                    "token": "{{token|safe}}",
-                    "user": user_name,
-                    "dataset": dataset_name,
-                    "subset": $i,
-                    "origin": $origin_array,
-                    "dimensions": $dimensions_array
-                });
-                $.ajax("http://localhost:5001/maps", {
-                    data:$params,
-                    contentType:"application/json",
-                    method:"POST"
-                }).done(function(data, textStatus, jqXHR){
-                    $location = jqXHR.getResponseHeader('location');
-                    sendContinuousGetToLocationUntilDone($location);
-                }).fail(function() { alert( "An error occured" ); });
-            }
+      });
+
+      $("#gray-threshold-min-input").val(minGT);
+      $("#gray-threshold-max-input").val(maxGT);
+      $("#x-min-input").val(0);
+      $("#x-max-input").val(100);
+      $("#y-min-input").val(0);
+      $("#y-max-input").val(100);
+      $("#z-min-input").val(0);
+      $("#z-max-input").val(100);
+
+
+      $("#gray-threshold-min-input").change(function() {
+        var max = $("#slider-gray-threshold" ).slider("option", "values")[1];
+        $(this).val($(this).val() < max ?$(this).val():max);
+        var values = [$(this).val(), max];
+        $("#slider-gray-threshold").slider("option", "values", values);
+        vrc.setGrayMinValue($(this).val()/255);
+      });
+      $("#gray-threshold-max-input").change(function() {
+        var min = $("#slider-gray-threshold" ).slider("option", "values")[0];
+        $(this).val($(this).val() > min ?$(this).val():min);
+        var values = [min, $(this).val()];
+        $("#slider-gray-threshold").slider("option", "values", values);
+        vrc.setGrayMaxValue($(this).val()/255);
+      });
+      $("#x-min-input").change(function() {
+        var max = $("#slider-X" ).dragslider("option", "values")[1];
+        $(this).val($(this).val() < max ?$(this).val():max);
+        var values = [$(this).val(), max];
+        $("#slider-X").dragslider("option", "values", values);
+        vrc.setGeometryMinX($(this).val()/100);
+      });
+      $("#x-max-input").change(function() {
+        var min = $("#slider-X" ).dragslider("option", "values")[0];
+        $(this).val($(this).val() > min ?$(this).val():min);
+        var values = [min, $(this).val()];
+        $("#slider-X").dragslider("option", "values", values);
+        vrc.setGeometryMaxX($(this).val()/100);
+      });
+      $("#y-min-input").change(function() {
+        var max = $("#slider-Y" ).dragslider("option", "values")[1];
+        $(this).val($(this).val() < max ?$(this).val():max);
+        var values = [$(this).val(), max];
+        $("#slider-Y").dragslider("option", "values", values);
+        vrc.setGeometryMinY($(this).val()/100);
+      });
+      $("#y-max-input").change(function() {
+        var min = $("#slider-Y" ).dragslider("option", "values")[0];
+        $(this).val($(this).val() > min ?$(this).val():min);
+        var values = [min, $(this).val()];
+        $("#slider-Y").dragslider("option", "values", values);
+        vrc.setGeometryMaxY($(this).val()/100);
+      });
+      $("#z-min-input").change(function() {
+        var max = $("#slider-Z" ).dragslider("option", "values")[1];
+        $(this).val($(this).val() < max ?$(this).val():max);
+        var values = [$(this).val(), max];
+        $("#slider-Z").dragslider("option", "values", values);
+        vrc.setGeometryMinZ($(this).val()/100);
+      });
+      $("#z-max-input").change(function() {
+        var min = $("#slider-Z" ).dragslider("option", "values")[0];
+        $(this).val($(this).val() > min ?$(this).val():min);
+        var values = [min, $(this).val()];
+        $("#slider-Z").dragslider("option", "values", values);
+        vrc.setGeometryMaxZ($(this).val()/100);
+      });
 
-            $("#slider-gray-threshold").slider ({
-                range: true,
-                min: 0,
-                max: 255,
-                values: [$minGT, $maxGT],
-                slide: function( event, ui ) {
-                    $min = ui.values[0];
-                    $max = ui.values[1];
-                    $vrc.setGrayMinValue($min/255);
-                    $("#gray-threshold-min-input").val($min);
-                    $vrc.setGrayMaxValue($max/255);
-                    $("#gray-threshold-max-input").val($max);
-                }
-            });
-            $("#slider-X").dragslider ({
-                range: true,
-                rangeDrag: true,
-                min: 0,
-                max: 100,
-                values: [0, 100],
-                slide: function( event, ui ) {
-                    $min = ui.values[0];
-                    $max = ui.values[1];
-                    $vrc.setGeometryMinX($min/100);
-                    $("#x-min-input").val($min);
-                    $vrc.setGeometryMaxX($max/100);
-                    $("#x-max-input").val($max);
-                    $vrc.setZoomXMinValue($min/100)
-                    $vrc.setZoomXMaxValue($max/100)
-                },
-                start: function( event, ui ){
-                    $vrc.showZoomBox(true);
-                },
-                stop: function( event, ui ){
-                    $vrc.showZoomBox(false);
-                }
-            });
-            $("#slider-Y").dragslider ({
-                range: true,
-                rangeDrag: true,
-                min: 0,
-                max: 100,
-                values: [0, 100],
-                slide: function( event, ui ) {
-                    $min = ui.values[0];
-                    $max = ui.values[1];
-                    $vrc.setGeometryMinY($min/100);
-                    $("#y-min-input").val($min);
-                    $vrc.setGeometryMaxY($max/100);
-                    $("#y-max-input").val($max);
-                    $vrc.setZoomYMinValue($min/100)
-                    $vrc.setZoomYMaxValue($max/100)
-                },
-                start: function( event, ui ){
-                    $vrc.showZoomBox(true);
-                },
-                stop: function( event, ui ){
-                    $vrc.showZoomBox(false);
-                }
-            });
-            $("#slider-Z").dragslider ({
-                range: true,
-                rangeDrag: true,
-                min: 0,
-                max: 100,
-                values: [0, 100],
-                slide: function( event, ui ) {
-                    $min = ui.values[0];
-                    $max = ui.values[1];
-                    $vrc.setGeometryMinZ($min/100);
-                    $("#z-min-input").val($min);
-                    $vrc.setGeometryMaxZ($max/100);
-                    $("#z-max-input").val($max);
-                    $vrc.setZoomZMinValue($min/100)
-                    $vrc.setZoomZMaxValue($max/100)
-                },
-                start: function( event, ui ){
-                    $vrc.showZoomBox(true);
-                },
-                stop: function( event, ui ){
-                    $vrc.showZoomBox(false);
-                }
-            });
-            $("#gray-threshold-min-input").val($minGT);
-            $("#gray-threshold-max-input").val($maxGT);
-            $("#x-min-input").val(0);
-            $("#x-max-input").val(100);
-            $("#y-min-input").val(0);
-            $("#y-max-input").val(100);
-            $("#z-min-input").val(0);
-            $("#z-max-input").val(100);
-            $("#gray-threshold-min-input").change(function() {
-                $max = $("#slider-gray-threshold" ).slider("option", "values")[1];
-                $(this).val($(this).val() < $max ?$(this).val():$max);
-                $values = [$(this).val(), $max];
-                $("#slider-gray-threshold").slider("option", "values", $values);
-                $vrc.setGrayMinValue($(this).val()/255);
-            });
-            $("#gray-threshold-max-input").change(function() {
-                $min = $("#slider-gray-threshold" ).slider("option", "values")[0];
-                $(this).val($(this).val() > $min ?$(this).val():$min);
-                $values = [$min, $(this).val()];
-                $("#slider-gray-threshold").slider("option", "values", $values);
-                $vrc.setGrayMaxValue($(this).val()/255);
-            });
-            $("#x-min-input").change(function() {
-                $max = $("#slider-X" ).dragslider("option", "values")[1];
-                $(this).val($(this).val() < $max ?$(this).val():$max);
-                $values = [$(this).val(), $max];
-                $("#slider-X").dragslider("option", "values", $values);
-                $vrc.setGeometryMinX($(this).val()/100);
-            });
-            $("#x-max-input").change(function() {
-                $min = $("#slider-X" ).dragslider("option", "values")[0];
-                $(this).val($(this).val() > $min ?$(this).val():$min);
-                $values = [$min, $(this).val()];
-                $("#slider-X").dragslider("option", "values", $values);
-                $vrc.setGeometryMaxX($(this).val()/100);
-            });
-            $("#y-min-input").change(function() {
-                $max = $("#slider-Y" ).dragslider("option", "values")[1];
-                $(this).val($(this).val() < $max ?$(this).val():$max);
-                $values = [$(this).val(), $max];
-                $("#slider-Y").dragslider("option", "values", $values);
-                $vrc.setGeometryMinY($(this).val()/100);
-            });
-            $("#y-max-input").change(function() {
-                $min = $("#slider-Y" ).dragslider("option", "values")[0];
-                $(this).val($(this).val() > $min ?$(this).val():$min);
-                $values = [$min, $(this).val()];
-                $("#slider-Y").dragslider("option", "values", $values);
-                $vrc.setGeometryMaxY($(this).val()/100);
-            });
-            $("#z-min-input").change(function() {
-                $max = $("#slider-Z" ).dragslider("option", "values")[1];
-                $(this).val($(this).val() < $max ?$(this).val():$max);
-                $values = [$(this).val(), $max];
-                $("#slider-Z").dragslider("option", "values", $values);
-                $vrc.setGeometryMinZ($(this).val()/100);
-            });
-            $("#z-max-input").change(function() {
-                $min = $("#slider-Z" ).dragslider("option", "values")[0];
-                $(this).val($(this).val() > $min ?$(this).val():$min);
-                $values = [$min, $(this).val()];
-                $("#slider-Z").dragslider("option", "values", $values);
-                $vrc.setGeometryMaxZ($(this).val()/100);
-            });
-            function zoomToVolume($v) {
-                $gray = [$("#gray-threshold-min-input").val(), $("#gray-threshold-max-input").val()];
-                window.location.href='/wave?user='+user_name+'&dataset='+dataset_name+'&collection='+collection_name+'&vol='+$v+'&gt='+$gray;
-            }
-            $("#res-zoom-button-selection").click( function() {
-                $W = $("#xy-zoom-selection").parent().width();
-                $x = Math.round(100*parseInt($("#xy-zoom-selection").css("left"), 10)/$W);
-                $y = Math.round(100*parseInt($("#xy-zoom-selection").css("top"), 10)/$W);
-                $z = Math.round(100*parseInt($("#yz-zoom-selection").css("top"), 10)/$W);
-                $size = Math.round(100*$("#yz-zoom-selection").width()/$W);
-                $vol = [$x, $y, $z, $size];
-                zoomToVolume($vol);
-            });
-            $("#xy-zoom-selection").resizable({
-                aspectRatio: 1,
-                containment: "parent",
-                create: function (event, ui ){
-                    $(this).css({
-                        'left': $current_x*$(this).parent().width()/100,
-                        'top': $current_y*$(this).parent().height()/100,
-                        'width': $current_dim*$(this).parent().width()/100,
-                        'height': $current_dim*$(this).parent().height()/100
-                    });
-                },
-                resize: function (event, ui ){
-                    h = ui.size.height;
-                    t = ui.position.top;
-                    W = $(this).parent().width();
-                    $("#yz-zoom-selection").css({'height':h, 'width': h,'left': t});
-                    t2 = Math.round(parseInt($("#yz-zoom-selection").css('top'), 10));
-                    if (h+ t2 >= W) $("#yz-zoom-selection").css({'top':W-h});
-                }
-            }).draggable({
-                containment: "parent",
-                drag: function (event, ui) {
-                    t = ui.position.top;
-                    $("#yz-zoom-selection").css({'left': t});
-                }
-            });
-            $("#yz-zoom-selection").resizable({
-                aspectRatio: 1,
-                containment: "parent",
-                create: function (event, ui ){
-                    $(this).css({
-                        'left': $current_y*$(this).parent().width()/100,
-                        'top': $current_z*$(this).parent().height()/100,
-                        'width': $current_dim*$(this).parent().width()/100,
-                        'height': $current_dim*$(this).parent().height()/100
-                    });
-                },
-                resize: function (event, ui ){
-                    w = ui.size.width;
-                    l = ui.position.left;
-                    H = $(this).parent().height()
-                    $("#xy-zoom-selection").css({'height':w, 'width': w,'top':l});
-                    l2 = Math.round(parseInt($("#xy-zoom-selection").css('left'), 10));
-                    if (w+ l2 >= H) $("#xy-zoom-selection").css({'left':H-w});
-                }
-            }).draggable({
-                containment: "parent",
-                drag: function (event, ui) {
-                    l = ui.position.left;
-                    $("#xy-zoom-selection").css({'top': l});
-                }
-            });
-         });
+      function zoomToVolume(v) {
+        var gray = [$("#gray-threshold-min-input").val(), $("#gray-threshold-max-input").val()];
+        window.location.href='/wave?user='+user_name+'&dataset='+dataset_name+'&collection='+collection_name+'&vol='+v+'&gt='+gray;
+      }
+
+      $("#res-zoom-button-selection").click( function() {
+        var W = $("#xy-zoom-selection").parent().width();
+        var x = Math.round(100 * parseInt($("#xy-zoom-selection").css("left"), 10) / W);
+        var y = Math.round(100 * parseInt($("#xy-zoom-selection").css("top"), 10) / W);
+        var z = Math.round(100 * parseInt($("#yz-zoom-selection").css("top"), 10) / W);
+        var size = Math.round(100 * $("#yz-zoom-selection").width() / W);
+        var vol = [x, y, z, size];
+        zoomToVolume(vol);
+      });
+
+      $("#xy-zoom-selection").resizable({
+        aspectRatio: 1,
+        containment: "parent",
+        create: function (event, ui ){
+          $(this).css({
+            'left': current_x*$(this).parent().width()/100,
+            'top': current_y*$(this).parent().height()/100,
+            'width': current_dim*$(this).parent().width()/100,
+            'height': current_dim*$(this).parent().height()/100
+          });
+        },
+        resize: function (event, ui ){
+          var h = ui.size.height;
+          var t = ui.position.top;
+          var W = $(this).parent().width();
+          $("#yz-zoom-selection").css({'height':h, 'width': h,'left': t});
+          var t2 = Math.round(parseInt($("#yz-zoom-selection").css('top'), 10));
+          if (h+ t2 >= W) $("#yz-zoom-selection").css({'top':W-h});
+        }
+      }).draggable({
+        containment: "parent",
+        drag: function (event, ui) {
+          var t = ui.position.top;
+          $("#yz-zoom-selection").css({'left': t});
+        }
+      });
+      $("#yz-zoom-selection").resizable({
+        aspectRatio: 1,
+        containment: "parent",
+        create: function (event, ui ){
+          $(this).css({
+            'left': current_y*$(this).parent().width()/100,
+            'top': current_z*$(this).parent().height()/100,
+            'width': current_dim*$(this).parent().width()/100,
+            'height': current_dim*$(this).parent().height()/100
+          });
+        },
+        resize: function (event, ui ){
+          var w = ui.size.width;
+          var l = ui.position.left;
+          var H = $(this).parent().height()
+          $("#xy-zoom-selection").css({'height':w, 'width': w,'top':l});
+          var l2 = Math.round(parseInt($("#xy-zoom-selection").css('left'), 10));
+          if (w+ l2 >= H) $("#xy-zoom-selection").css({'left':H-w});
+        }
+      }).draggable({
+        containment: "parent",
+        drag: function (event, ui) {
+          var l = ui.position.left;
+          $("#xy-zoom-selection").css({'top': l});
+        }
+      });
+    });
   </script>
   <script>System.import('dataset.js')</script>
   <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">