2016-10-20 3 views
1

Я использую d3.js с компоновкой сил, чтобы визуализировать большое количество узлов. Я хотел бы применить ограничение к опции панорамирования масштабирования. JSFiddle: https://jsfiddle.net/40z5tw8h/24/d3.js limit panning in force layout

Вышеупомянутая скрипка содержит простую версию того, над чем я работаю. Поскольку я мог бы визуализировать очень большой набор данных, я использую функцию, чтобы уменьшить размер элемента удерживания группы («g») после того, как силы будут выполнены. Таким образом, у меня всегда есть полная визуализация, видимая впоследствии.

Я хотел бы ограничить панорамирование - когда график полностью виден, чтобы его можно было перемещать только в окне просмотра. В случае масштабируется макет, я хотел бы ограничить панорамирование следующим образом:

Удерживающий элемент группы не должен быть в состоянии пойти:

  1. вниз более чем на 20 пикселей от верхней части SVG ,
  2. право более 20 px с левой стороны svg.
  3. более 20 пикселей снизу svg.
  4. оставил более 20 px с правой стороны svg.

Я думаю, что все реализации должны быть в пределах функции масштабирования, которая на данный момент является:

function zoomed(){ 
     if (d3.event.sourceEvent == null){ //when fitFullGraph uses the zoom 
      g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); 
     } 
     else{ 
      var gElementBounds = g.node().getBoundingClientRect(); 
      var g_bottom = gElementBounds.bottom; 
      var g_top = gElementBounds.top; 
      var g_left = gElementBounds.left; 
      var g_right = gElementBounds.right; 
      var g_height = gElementBounds.height; 
      var g_width = gElementBounds.width; 

      var svg = g.node().parentElement; 
      var svgElementBounds = svg.getBoundingClientRect(); 
      var svg_bottom = svgElementBounds.bottom; 
      var svg_top = svgElementBounds.top; 
      var svg_left = svgElementBounds.left; 
      var svg_right = svgElementBounds.right; 
      var svg_height = svgElementBounds.height; 
      var svg_width = svgElementBounds.width; 

      var t = d3.event.translate; 
      var margin = 20; 

      if(d3.event.sourceEvent.type == 'wheel'){//event is zoom 
       g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); 

      } 
      else{//event is pan 
       // if(t[0] < svg_left + margin) t[0]= svg_left + margin; 
       //else if(t[0] > svg_width-g_width - margin) t[0] = svg_width-g_width - margin; 
       // if(t[1] < g_height +margin) t[1] = g_height + margin; 
       //else if (t[1] > svg_height - margin) t[1] = svg_height - margin; 
       //.attr("transform", "translate(" + t+ ")scale(" + d3.event.scale + ")"); 
       //3.event.translate = t; 
       g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); 
      } 

     } 

    } 

Ограничения я пытался реализовать закомментировано, потому что они не работают должным образом.

У кого-нибудь есть решение?

ответ

0

Это не полный ответ на ваш вопрос.

я использовал для блока панорамирования на левую сторону перевести шкалу на X Спонсор

var translate = d3.event.translate; 
var translateX = translate[0]; 
var translateY = translate[1]; 
var scale = d3.event.scale; 
var tX = translateX * scale; 
var tY = translateY * scale; 
console.log('tx', tX, 'ty', tY); 
// Do not pan more to left 
if (tX> 0) { 
    g.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")"); 
} else { 
    translate[0] = 0; 
    g.attr("transform", "translate(" + translate + ") scale(" + d3.event.scale + ")"); 
} 

, отменяющий перевод налево, но внутренне он продолжает. Ваш пользователь, вероятно, перестанет перемещаться влево. Панорамирование справа становится странным, когда вы начинаете кастрюлю, так как внутреннее событие запустилось далеко влево.

Смежные вопросы