2017-10-16 5 views
-1

私はD3 jsでズームを実装しました。そのため、マウスがキャンバスの上にマウスオーバーすると、ズームイベントがトリガーされ、マウスホイールを使用して拡大/縮小できます。オーバーレイとCtrl +スクロールイベントでGoogleマップのようなD3でマウスホイールのズームを実装する方法は?

デモ:https://diversity.rcc.uchicago.edu/collapsible_tree

しかし、私はD3ズームのこのデフォルトの動作を防止したいとGoogleマップが行うようキャンバスを拡大するには、ユーザーはCtrl +スクロールにユーザーを強制する必要があります:http://jsfiddle.net/maunovaha/jptLfhc8/

は、我々はとにかくありオーバーレイを表示してユーザーに組み合わせを使用するよう要求し、次にズームのみ許可することができます。

ズームのための私のコードは次のようである:

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

のは、D3オタクが示唆することができるか見てみましょうhttps://stackoverflow.com/a/47421474/1111654 –

答えて

1

私は数週間前に同じ問題を抱えていました。しかし、私はdagreD3を使用しました。私が使用した関数はD3からです。ここに私の働くフィドルがあります。

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

おかげで私の答えを見てみてください! – Milson

+0

多分簡単な解決策があります:) –

0

あなたはnullに、特定のイベントを設定することにより、必要なD3ズームイベントを無効にすることができます。

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); 
関連する問題