2017-01-15 61 views
1

我想實現一個圖表框架,它能夠創建與每個方向多軸線圖和麪積圖,即2-Y軸的左邊,1-y軸右1-x軸底部。d3js V4:獨立的多個軸縮放和平移

我開始工作了。我的下一個任務是對圖表實施縮放行爲。我縮進以具有全局縮放行爲,如果用戶在繪圖區域內使用鼠標,則會觸發該行爲。所顯示的系列將會重新縮放,並且可以平移該圖。這一個我也得到了工作。

另外我想每個軸的獨立縮放比例。我得到了縮放,但我仍然遇到全局縮放和平移的問題。如果我縮放一個座標軸,繪圖區域中的相關係列將重新縮放,但平移不起作用。在軸的獨立縮放之後,如果使用全局縮放比例,縮放比例會被重置,然後通過全局縮放行爲縮放。

在d3.js頁面,我發現一個簡單的example獨立和全局縮放和平移,但D3V3寫的。

我以這樣的方式改變的例子,所以它顯示我的問題jsfiddle demo。使用鼠標在座標軸上和繪圖區域中。

<!DOCTYPE html> 
<html> 
    <head> 
    <title>TODO supply a title</title> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <title>Simple Independent Axis Zooms on x, y, or xy</title> 
    <script src="//d3js.org/d3.v4.min.js"></script> 
    <style> 
     .axis path, .axis line { 
      fill: none; 
      stroke: #000; 
      shape-rendering: crispEdges; 
     } 
    </style> 
</head> 
<body> 
    <div id="chart"></div> 
    <script> 


     var data = []; 
     for (var i = 0; i < 100; i++) { 
      data.push([Math.random(), Math.random()]); 
     } 
     var svg = d3.select('#chart') 
       .append("svg") 
       .attr("width", window.innerWidth).attr("height", window.innerHeight); 

     function example(svg, data) { 
      var svg; 
      var margin = { 
       top: 60, 
       bottom: 80, 
       left: 60, 
       right: 0 
      }; 
      var width = 500; 
      var height = 400; 
      var xaxis = d3.axisBottom(); 
      var yaxis = d3.axisLeft(); 
      var xscale = d3.scaleLinear(); 
      var yscale = d3.scaleLinear(); 
      var xcopyScale, ycopyScale; 
      var xyzoom, xzoom, yzoom; 
      updateZooms(); 





      function update() { 

       var gs = svg.select("g.scatter"); 

       var circle = gs.selectAll("circle") 
         .data(data); 

       circle.enter().append("svg:circle") 
         .attr("class", "points") 
         .style("fill", "steelblue") 
         .attr("cx", function (d) { 
          return X(d); 
         }) 
         .attr("cy", function (d) { 
          return Y(d); 
         }) 
         .attr("r", 4); 

       circle.attr("cx", function (d) { 
        return X(d); 
       }) 
         .attr("cy", function (d) { 
          return Y(d); 
         }); 

       circle.exit().remove(); 
      } 

      function updateZooms() { 
       xyzoom = d3.zoom() 
         .on("zoom", function() { 
          xaxis.scale(d3.event.transform.rescaleX(xscale)); 
          yaxis.scale(d3.event.transform.rescaleY(yscale)); 
          draw(); 
         }); 

       xzoom = d3.zoom() 
         .on("zoom", function() { 
          xaxis.scale(d3.event.transform.rescaleX(xscale)); 
          draw(); 
         }); 

       yzoom = d3.zoom() 
         .on("zoom", function() { 
          yaxis.scale(d3.event.transform.rescaleY(yscale)); 
          draw(); 
         }); 
      } 

      function draw() { 
       svg.select('g.x.axis').call(xaxis); 
       svg.select('g.y.axis').call(yaxis); 
       update(); 
       // After every draw, we reinitialize zoom. After every zoom, we reexecute draw, which will reinitialize zoom. 
       // This is how we can apply multiple independent zoom behaviors to the scales. 
       // (Note that the zoom behaviors will always end up with zoom at around 1.0, and translate at around [0,0]) 
       svg.select('rect.zoom.xy.box').call(xyzoom); 
       svg.select('rect.zoom.x.box').call(xzoom); 
       svg.select('rect.zoom.y.box').call(yzoom); 
      } 
      // X value to scale 
      function X(d) { 
       return xaxis.scale() !== undefined && xaxis.scale() !== null 
         ? xaxis.scale()(d[0]) 
         : xscale(d[0]); 
      } 

      // Y value to scale 
      function Y(d) { 
       return yaxis.scale() !== undefined && yaxis.scale() !== null 
         ? yaxis.scale()(d[1]) 
         : yscale(d[1]); 
      } 


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

      g.append("defs").append("clipPath") 
        .attr("id", "clip") 
        .append("rect") 
        .attr("width", width - margin.left - margin.right) 
        .attr("height", height - margin.top - margin.bottom); 

      g.append("svg:rect") 
        .attr("class", "border") 
        .attr("width", width - margin.left - margin.right) 
        .attr("height", height - margin.top - margin.bottom) 
        .style("stroke", "black") 
        .style("fill", "none"); 

      g.append("g").attr("class", "x axis") 
        .attr("transform", "translate(" + 0 + "," + (height - margin.top - margin.bottom) + ")"); 

      g.append("g").attr("class", "y axis"); 

      g.append("g") 
        .attr("class", "scatter") 
        .attr("clip-path", "url(#clip)"); 

      g 
        .append("svg:rect") 
        .attr("class", "zoom xy box") 
        .attr("width", width - margin.left - margin.right) 
        .attr("height", height - margin.top - margin.bottom) 
        .style("visibility", "hidden") 
        .attr("pointer-events", "all") 
        .call(xyzoom); 

      g 
        .append("svg:rect") 
        .attr("class", "zoom x box") 
        .attr("width", width - margin.left - margin.right) 
        .attr("height", height - margin.top - margin.bottom) 
        .attr("transform", "translate(" + 0 + "," + (height - margin.top - margin.bottom) + ")") 
        .style("visibility", "hidden") 
        .attr("pointer-events", "all") 
        .call(xzoom); 

      g 
        .append("svg:rect") 
        .attr("class", "zoom y box") 
        .attr("width", margin.left) 
        .attr("height", height - margin.top - margin.bottom) 
        .attr("transform", "translate(" + -margin.left + "," + 0 + ")") 
        .style("visibility", "hidden") 
        .attr("pointer-events", "all") 
        .call(yzoom); 

      // Update the x-axis 
      xscale.domain(d3.extent(data, function (d) { 
       return d[0]; 
      })).range([0, width - margin.left - margin.right]); 

      xaxis.scale(xscale) 
        .tickPadding(10); 

      svg.select('g.x.axis').call(xaxis); 

      // Update the y-scale. 
      yscale.domain(d3.extent(data, function (d) { 
       return d[1]; 
      })).range([height - margin.top - margin.bottom, 0]); 

      yaxis.scale(yscale) 
        .tickPadding(10); 

      svg.select('g.y.axis').call(yaxis); 

      draw(); 

     } 

     var exampleChart = example(svg, data); 
    </script> 
    </body> 
</html> 

簡單的說:我怎樣才能解決使用d3v4創建與具有全局和獨立縮放和平移行爲多軸圖表我的問題嗎?

回答

1

截至目前,當前版本的d3v4本身不支持多個獨立縮放行爲。

一個可能的解決辦法是重置存儲在其上調用適當的縮放行爲裏面選擇內部變換狀態。 關於論點已有open issue,我鼓勵你去閱讀並提供你的意見。

祝你好運!