2015-12-31 2 views
3

Я адаптировал Christopher Manning's force-directed graph on a sphere. Я хотел бы, чтобы график располагался, а затем поворачивал сферу, не изменяя отношения между точками графика. Вместо этого, когда я перетаскиваю, он, кажется, перетаскивает график и не вращает сферу. Перетаскивание графика активирует запуск силы. Если я выключу force.start(), ничего не изменится.d3.js сила направленная сферическая сфера

var svg = d3.select("#cluster").append("svg") 
    .attr("width", width) 
    .attr("height", height) 
    .call(d3.behavior.drag() 
     .origin(function() { var r = projection.rotate(); return {x: 2 * r[0], y: -2 * r[1]}; }) 
     .on("drag", function() { force.start(); var r = [d3.event.x/2, -d3.event.y/2, projection.rotate()[2]]; t0 = Date.now(); origin = r; projection.rotate(r); })) 

От http://bl.ocks.org/mbostock/3795040, я обнаружил, что я мог повернуть координатную сетку, но потом все мои ссылки и узлы исчезают.

var path = d3.geo.path() 
    .projection(projection); 

var λ = d3.scale.linear() 
    .domain([0, width]) 
    .range([-180, 180]); 

var φ = d3.scale.linear() 
    .domain([0, height]) 
    .range([90, -90]); 

var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

svg.on("mousemove", function() { 
    var p = d3.mouse(this); 
    projection.rotate([λ(p[0]), φ(p[1])]); 
    svg.selectAll("path").attr("d", path); 
}); 

Ссылки и узлы добавляются так:

var link = svg.selectAll("path.link") 
     .data(graph.links) 
     .enter().append("path").attr("class", "link") 
     .attr ("stroke-width", function(d){return d.value/3}); 

    var node = svg.selectAll("path.node") 
     .data(graph.nodes) 
     .enter() 
     .append("g") 
     .attr("class", "gnode") 
     .attr("text-anchor", "middle") 

     .append("path").attr("class", "node") 
     .style("fill", function(d) { return d.color; }) 
     .style("stroke", function(d) { return d3.rgb(fill(d.group)).darker(); }) 

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

Как это сделать?

ответ

0

Это может вращаться вдоль одной оси

var rotateScale = d3.scale.linear().domain([0, width]).range([-180,180]);//width of SVG 

d3.select("svg").on("mousedown",startRotating).on("mouseup",stopRotating); 

function startRotating() { 
    d3.select("svg").on("mousemove",function() { 
     var p = d3.mouse(this); 
     projection.rotate([rotateScale(p[0]),0]); 
    }); 
} 
function stopRotating() { 
    d3.select("svg").on("mousemove",null); 
} 
2

Это может быть сделано путем изменения обработчика зарегистрированного для drag события на svg, который определен в первом фрагменте. Это требует двух изменений:

  1. Избавьтесь от force.start(), потому что вы не хотите перезагружать силу при перетаскивании.
  2. Запуск рендеринга узлов и ссылок после обновления проекции, что можно легко сделать, позвонив по телефону tick(). Если на шаге 1 сила не была деактивирована, это будет вызываться повторно, потому что функция зарегистрирована как обработчик события компоновки силы tick. Теперь, когда вы отключили силу, вам придется называть ее явно.

Переформатированный код будет выглядеть следующим образом:

.on("drag", function() { 
    //force.start();  // 1. Don't restart the force. 
    var r = [d3.event.x/2, -d3.event.y/2, projection.rotate()[2]]; 
    t0 = Date.now(); 
    origin = r; 
    projection.rotate(r); 
    tick();    // 2. Trigger the rendering after adjusting the projection. 
})) 

Посмотрите на эту working example.

+0

Спасибо, этот пример именно то, что я ищу. Мое быстрое применение вашего предложения не решило проблему, но пример явно работает. Я изучу его еще и это должно решить мою проблему. Спасибо. – user1430965

+0

Это работало как шарм. Необходимо включить функцию tick из вашего примера. Еще раз спасибо! – user1430965

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