2017-02-06 7 views
2

d3でズームが可能な傾向を構築しようとしています。それは非常にうまく動作しています。トレンド内ではズームイン(ズームイン)したり、マウスホイールで各軸をズームすることができます。D3 V4マウスによるズームとプログラムによるズームがそれぞれ独立しています

今、ボタンをクリックしていくつかのズームを追加したかったのです。これらのズームも正常に動作しています。

ボタンでX方向にズームしてから、マウスホイールでY方向またはトレンドをズームすると完璧に動作します。

しかし、X方向にボタンでズームした後、マウスホイールでX方向にズームすると、トレンドはデフォルトからズームし始めます。ここで

は私の例です:https://jsfiddle.net/DaWa/d5fdLwv0/

<label>X</label> 
<button onclick="zoomXIn()">+</button> 
<button onclick="zoomXOut()">-</button> 
<br/> 
<label>Y</label> 
<button onclick="zoomYIn()">+</button> 
<button onclick="zoomYOut()">-</button> 
<br/> 
<svg width="960" height="500"></svg> 

<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 
    var xyTransform; 
    var xTransform; 
    var yTransform; 

    function zoomXIn() { 
    xZoom.scaleBy(xGroup, 2); 
    } 

    function zoomXOut() { 
    xZoom.scaleBy(xGroup, 0.5); 
    } 

    function zoomYIn() { 
    yZoom.scaleBy(yGroup, 2); 
    } 

    function zoomYOut() { 
    yZoom.scaleBy(yGroup, 0.5); 
    } 

    var svg = d3.select("svg"), 
    margin = {top: 20, right: 20, bottom: 110, left: 40}, 
    width = +svg.attr("width") - margin.left - margin.right, 
    height = +svg.attr("height") - margin.top - margin.bottom; 

    var xScale = d3.scaleTime().range([0, width]), 
    yScale = d3.scaleLinear().range([height, 0]), 
    yOld, xOld; 

    var xAxis = d3.axisBottom(xScale), 
    yAxis = d3.axisLeft(yScale); 

    var xZoom = d3.zoom() 
    .on("zoom", function() { 
     xTransform = d3.event.transform; 
     zoomBoth("x") 
    }); 
    var yZoom = d3.zoom() 
    .on("zoom", function() { 
     yTransform = d3.event.transform; 
     zoomBoth("y") 
    }); 
    var zoom = d3.zoom() 
    .on("zoom", function() { 
     xyTransform = d3.event.transform; 
     setDefault(); 
     zoomBoth() 
    }); 

    function setDefault() { 
    if (!xTransform) { 
     xTransform = d3.zoomTransform(overlayX.node()); 
    } 
    if (!yTransform) { 
     yTransform = d3.zoomTransform(overlayY.node()); 
    } 

    } 


    var line = d3.line() 
    .curve(d3.curveMonotoneX) 
    .x(function (d) { 
     return xScale(d.date); 
    }) 
    .y(function (d) { 
     return yScale(d.price); 
    }); 

    svg.append("defs").append("clipPath") 
    .attr("id", "clip") 
    .append("rect") 
    .attr("width", width) 
    .attr("height", height); 

    var focus = svg.append("g") 
    .attr("class", "focus") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 


    var data = getData(); 
    xScale.domain(d3.extent(data, function (d) { 
    return d.date; 
    })); 
    yScale.domain([0, d3.max(data, function (d) { 
    return d.price; 
    })]); 

    var path = focus.append("path") 
    .datum(data) 
    .attr("class", "line") 
    .attr("d", line); 


    var xGroup = focus.append("g") 
    .attr("transform", "translate(0," + height + ")").call(xAxis); 

    var yGroup = focus.append("g") 
    .call(yAxis); 

    var overlayX = focus 
    .append("rect") 
    .attr("fill", "rgba(0,0,0,0.5)") 
    .attr("width", width) 
    .attr("height", 30) 
    .attr("y", height) 
    .call(xZoom); 


    var overlayY = focus 
    .append("rect") 
    .attr("fill", "rgba(0,0,0,0.5)") 
    .attr("width", 30) 
    .attr("height", height) 
    .attr("x", -30) 
    .call(yZoom); 

    var overlayRect = svg.append("rect") 
    .attr("class", "zoom") 
    .attr("width", width) 
    .attr("height", height) 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
    .call(zoom); 

    function zoomBoth(axisType) { 
    getZoomedScales(axisType); 
    updateData(); 
    updateAxes(); 
    } 


    function getZoomedScales(axisType) { 
    if (!xOld) { 
     xOld = xScale.copy(); 
    } 

    if (!yOld) { 
     yOld = yScale.copy(); 
    } 


    var transformXY = d3.zoomTransform(overlayRect.node()); 
    if (axisType === 'x') { 
     xScale = transformXY.rescaleX(xTransform.rescaleX(xOld)); 
    } else if (axisType === 'y') { 
     yScale = transformXY.rescaleY(yTransform.rescaleY(yOld)); 
    } else { 
     xScale = xyTransform.rescaleX(xTransform.rescaleX(xOld)); 
     yScale = xyTransform.rescaleY(yTransform.rescaleY(yOld)); 
    } 
    } 


    function updateAxes() { 
    xGroup.call(xAxis.scale(xScale)); 
    yGroup.call(yAxis.scale(yScale)); 
    } 


    function updateData() { 
    focus.select(".line").attr("d", line); 
    } 

    function getData() { 
    var data = []; 
    var date = new Date('Jan 2000'); 
    for (var i = 0; i < 120; i++) { 

     data.push({date: new Date(date), price: Math.random() * 100}); 
     date.setMonth(date.getMonth() + 1); 
    } 
    return data; 
    } 

</script> 

どのように私はその問題を解決することができますか?

私の問題を理解して助けてくれることを願っています。

敬具、 DW

答えて

1

SVGからキャンバスに自分のズームを変更することにより、私はすでに私の問題を解決しました。

See https://jsfiddle.net/DaWa/d5fdLwv0/4/ 
+0

私はSVGを使用するといいですか? –

+0

私は既にここに投稿されている他のソリューションを見つけました:https://github.com/d3/d3-zoom/issues/48 – user7521838

関連する問題