2017-10-16 12 views
-1

J'ai implémenté le zoom avec D3 js, donc chaque fois que la souris survole la toile, les événements de zoom se déclenchent et permettent à un utilisateur d'utiliser la molette de la souris pour zoomer et dézoomer.Comment implémenter le zoom de la molette de la souris dans D3 comme Google Map avec superposition et Ctrl + Défilement?

Démo: https://diversity.rcc.uchicago.edu/collapsible_tree

Mais je veux éviter ce comportement par défaut du zoom D3 et la nécessité d'appliquer un utilisateur à Ctrl + défilement pour agrandir la toile comme carte google fait: http://jsfiddle.net/maunovaha/jptLfhc8/

Y at-il de toute façon nous peut afficher la superposition pour demander à un utilisateur d'utiliser la combinaison, puis autoriser uniquement le zoom.

Mon code pour le zoom est comme ceci:

var svg = d3.select("#collapsible-tree") 
    .append("svg") 
    .attr("width", width + margin.right + margin.left) 
    .attr("height", height + margin.top + margin.bottom) 
    .call(zm = d3.behavior.zoom().scaleExtent([0.1, 3]).on("zoom", redraw)) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

//Redraw for zoom 
function redraw() { 
    //console.log("here", d3.event.translate, d3.event.scale); 
    svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); 
} 
+0

S'il vous plaît jeter un oeil à ma réponse à https://stackoverflow.com/a/47421474/1111654 –

Répondre

1

J'ai eu le même problème il y a quelques semaines. Mais j'ai utilisé dagreD3. La fonction que j'ai utilisée provient de D3. Voici mon violon de travail.

JS Fiddle

// Create a new directed graph 
var g = new dagreD3.graphlib.Graph().setGraph({}) 
    .setDefaultEdgeLabel(function() { 
    return {}; 
    }); 
// Disable Browserzoom with strg + mousewheel 
$(document).keydown(function(event) { 
    if (event.ctrlKey == true && (event.which == '61' || event.which == '107' || event.which == '173' || event.which == '109' || event.which == '187' || event.which == '189')) { 
    alert('disabling zooming'); 
    event.preventDefault(); 
    } 
}); 

$(window).bind('mousewheel DOMMouseScroll', function(event) { 
    if (event.ctrlKey == true) { 
    event.preventDefault(); 
    } 
}); 

// Check if strg is pressed 
var ctrlPressed = false; 
$(window).keydown(function(evt) { 
    if (evt.which == 17) { 
    ctrlPressed = true; 
    console.log("pressed"); 
    } 
}).keyup(function(evt) { 
    if (evt.which == 17) { 
    ctrlPressed = false; 
    console.log("not pressed"); 
    } 
}); 

//adding nodes and edges 

g.setNode(0, { 
    label: "TOP", 
}); 
g.setNode(1, { 
    label: "S", 
}); 
g.setNode(2, { 
    label: "NP", 
}); 
g.setNode(3, { 
    label: "DT", 
}); 
g.setNode(4, { 
    label: "This", 
}); 
g.setNode(5, { 
    label: "VP", 
}); 
g.setNode(6, { 
    label: "VBZ", 
}); 
g.setNode(7, { 
    label: "is", 
}); 
g.setNode(8, { 
    label: "NP", 
}); 
g.setNode(9, { 
    label: "DT", 
}); 
g.setNode(10, { 
    label: "an", 
}); 
g.setNode(11, { 
    label: "NN", 
}); 
g.setNode(12, { 
    label: "example", 
}); 
g.setNode(13, { 
    label: ".", 
}); 
g.setNode(14, { 
    label: "sentence", 
}); 

g.setEdge(3, 4); 
g.setEdge(2, 3); 
g.setEdge(1, 2); 
g.setEdge(6, 7); 
g.setEdge(5, 6); 
g.setEdge(9, 10); 
g.setEdge(8, 9); 
g.setEdge(11, 12); 
g.setEdge(8, 11); 
g.setEdge(5, 8); 
g.setEdge(1, 5); 
g.setEdge(13, 14); 
g.setEdge(1, 13); 
g.setEdge(0, 1); 

// Round the corners of the nodes 
g.nodes().forEach(function(v) { 
    var node = g.node(v); 
    node.rx = node.ry = 5; 
}); 

//makes the lines smooth 
g.edges().forEach(function(e) { 
    var edge = g.edge(e.v, e.w); 
    edge.lineInterpolate = 'basis'; 
}); 

// Create the renderer 
var render = new dagreD3.render(); 
var width = 500, 
    height = 1000, 
    center = [width/2, height/2]; 
// Set up an SVG group so that we can translate the final graph. 
var svg = d3.select("svg"), 
    inner = svg.append("g"); 
var zoom = d3.behavior.zoom() 
    .on("zoom", zoomed); 

function zoomed() { 
    inner.attr("transform", "translate(" + zoom.translate() + ")scale(" + zoom.scale() + ")"); 
} 
svg.call(zoom) 
svg.on("wheel.zoom", null); 
svg.on("dblclick.zoom", null); 
svg.call(zoom.event); 
document.getElementById("container").addEventListener("wheel", myFunction); 

function myFunction(event) { 
    if (ctrlPressed == true) { 
    if (event.wheelDelta > 0) { 
     zoom_by(1.03); 
    } else if (event.wheelDelta < 0) { 
     zoom_by(1/1.03); 
    } 
    } 
} 

function zoom_by(factor) { 
    var scale = zoom.scale(), 
    extent = zoom.scaleExtent(), 
    translate = zoom.translate(), 
    x = translate[0], 
    y = translate[1], 
    target_scale = scale * factor; 

    // If we're already at an extent, done 
    if (target_scale === extent[0] || target_scale === extent[1]) { 
    return false; 
    } 
    // If the factor is too much, scale it down to reach the extent exactly 
    var clamped_target_scale = Math.max(extent[0], Math.min(extent[1], target_scale)); 
    if (clamped_target_scale != target_scale) { 
    target_scale = clamped_target_scale; 
    factor = target_scale/scale; 
    } 

    // Center each vector, stretch, then put back 
    x = (x - center[0]) * factor + center[0]; 
    y = (y - center[1]) * factor + center[1]; 

    // Enact the zoom immediately 
    zoom.scale(target_scale) 
    .translate([x, y]); 
    zoomed(); 
} 
// Run the renderer. This is what draws the final graph. 
render(inner, g); 

// Center the graph 
var initialScale = 1.0; 
zoom.translate([(svg.attr("width") - g.graph().width * initialScale)/2, 20]) 
    .scale(initialScale) 
    .event(svg); 
svg.attr("height", g.graph().height * initialScale + 40); 
+0

merci, nous allons voir ce que les geeks D3 peuvent suggérer! – Milson

+0

Peut-être qu'il existe une solution plus simple :) –

0

Vous pouvez désactiver les événements de zoom d3 requis en définissant cet événement particulier null.

svg.call(zoom) // zoom disable 
       .on("wheel.zoom", null) 
       .on("mousedown.zoom", null) 
       .on("touchstart.zoom", null) 
       .on("touchmove.zoom", null) 
       .on("touchend.zoom", null);