2015-07-03 56 views
2

現在我可以調整一個圓的大小。我創建使用g.append('svg:rect')一個矩形,但我不知道如何在D3如何在d3中調整矩形的大小js

調整矩形這是我曾嘗試:

var boxWidth = 1300; 
var boxHeight = 600; 

var box = d3.select('body') 
     .append('svg') 
     .attr('class', 'box') 
     .attr('width', boxWidth) 
     .attr('height', boxHeight); 

var drag = d3.behavior.drag() 
     .on('drag', function() { 
      g.selectAll('*') 
        .attr('cx', d3.event.x) 
        .attr('cy', d3.event.y); 
     }); 

var resize = d3.behavior.drag() 
     .on('drag', function() { 
      g.selectAll('.resizingContainer') 
        .attr('r', function (c) { 
         return Math.pow(Math.pow(this.attributes.cx.value - d3.event.x, 2) + Math.pow(this.attributes.cy.value - d3.event.y, 2), 0.5) + 6; 
        }); 
      g.selectAll('.draggableCircle') 
        .attr('r', function (c) { 
         return Math.pow(Math.pow(this.attributes.cx.value - d3.event.x, 2) + Math.pow(this.attributes.cy.value - d3.event.y, 2), 0.5); 
        }); 
     }); 

var g = box.selectAll('.draggableGroup') 
     .data([{ 
       x: 65, 
       y: 55, 
       r: 25 
      }]) 
     .enter() 
     .append('g'); 

g.append('svg:circle') 
     .attr('class', 'resizingContainer') 
     .attr('cx', function (d) { 
      return d.x; 
     }) 
     .attr('cy', function (d) { 
      return d.y; 
     }) 
     .attr('r', function (d) { 
      return d.r + 6; 
     }) 
     .style('fill', '#999') 
     .call(resize); 

g.append('svg:circle') 
     .attr('class', 'draggableCircle') 
     .attr('cx', function (d) { 
      return d.x; 
     }) 
     .attr('cy', function (d) { 
      return d.y; 
     }) 
     .attr('r', function (d) { 
      return d.r; 
     }) 
     .call(drag) 
     .style('fill', 'black'); 

g.append('svg:rect') 
     .attr("width", 70) 
     .attr("height", 70) 
     .attr("x", 30) 
     .attr("y", 130) 
     .attr("rx", 6) 
     .attr("ry", 6) 
     .style("fill", d3.scale.category20c()); 

HTML:

<!DOCTYPE html> 
<html> 
    <head> 
     <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> 
     <script src='d3.js' charset='utf-8'></script> 

     <style> 
      .box { 
       border: 1px black; 
       border-radius: 10px; 
      } 
      .resizingContainer { 
       cursor: nesw-resize; 
      } 
     </style> 
    </head> 
    <body> 
     <script src='drag.js'></script> 
     <div id="checks"> 
     X-axis:<input type="checkbox" id="xChecked" checked/> 
     Y-axis:<input type="checkbox" id="yChecked" checked/> 
    </div> 
    </body> 
</html> 

這裏的現場演示:https://jsbin.com/dejewumali/edit?html,js,output

+0

你應該爲它製作一個JSFiddle。它會幫助你得到迴應。 –

+0

更新了鏈接 – kittu

回答

4

爲您的代碼添加了矩形調整大小。請注意,您需要使用右下角的調整(這是添加調整大小:-)最簡單的角落)

var boxWidth = 1300; 
var boxHeight = 600; 

var box = 
    d3.select('body') 
     .append('svg') 
     .attr('class', 'box') 
     .attr('width', boxWidth) 
     .attr('height', boxHeight); 

var drag = d3.behavior.drag() 
     .on('drag', function() { 
      g.selectAll('*') 
       .attr('cx', d3.event.x) 
       .attr('cy', d3.event.y); 
     }); 

var resize = d3.behavior.drag() 
     .on('drag', function() { 
      g.selectAll('.resizingContainer') 
        .attr('r', function (c) { 
         return Math.pow(Math.pow(this.attributes.cx.value - d3.event.x, 2) + Math.pow(this.attributes.cy.value - d3.event.y, 2), 0.5) + 6; 
        }); 
      g.selectAll('.circle') 
        .attr('r', function (c) { 
         return Math.pow(Math.pow(this.attributes.cx.value - d3.event.x, 2) + Math.pow(this.attributes.cy.value - d3.event.y, 2), 0.5); 
        }); 
     }); 


var g = box.selectAll('.draggableCircle') 
     .data([{ 
      x: 65, 
      y: 55, 
      r: 25 
     }]) 
     .enter() 
     .append('g') 
     .attr('class', 'draggableCircle'); 

g.append('svg:circle') 
     .attr('class', 'resizingContainer') 
     .attr('cx', function (d) { 
      return d.x; 
     }) 
     .attr('cy', function (d) { 
      return d.y; 
     }) 
     .attr('r', function (d) { 
      return d.r + 6; 
     }) 
     .style('fill', '#999') 
     .call(resize); 

g.append('svg:circle') 
     .attr('class', 'circle') 
     .attr('cx', function (d) { 
      return d.x; 
     }) 
     .attr('cy', function (d) { 
      return d.y; 
     }) 
     .attr('r', function (d) { 
      return d.r; 
     }) 
     .call(drag) 
     .style('fill', 'black'); 


var distance = function (p1, p2) { 
    return Math.pow(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2), 0.5); 
} 

var resize2 = d3.behavior.drag() 
     .on('drag', function() { 
      var c = g2.selectAll('.resizingSquare'); 
      var s = g2.selectAll('.square'); 

      var e = d3.event; 
      var x = Number(this.attributes.x.value); 
      var y = Number(this.attributes.y.value); 
      var w = Number(this.attributes.width.value); 
      var h = Number(this.attributes.height.value); 
      var c1 = { x: x, y: y }; 
      var c2 = { x: x + w, y: y }; 
      var c3 = { x: x + w, y: y + h }; 
      var c4 = { x: x, y: y + h }; 

      // figure out which corner this is closest to 
      var d = [] 
      var m1 = distance(e, c1) 
      var m2 = distance(e, c2) 
      var m3 = distance(e, c3) 
      var m4 = distance(e, c4) 
      switch (Math.min(m1, m2, m3, m4)) { 
       case m3: 
        c 
         .attr('width', function() { return w + (e.x - c3.x) + 12 }) 
         .attr('height', function() { return h + (e.y - c3.y) + 12 }) 
        s 
         .attr('width', function() { return w + (e.x - c3.x) }) 
         .attr('height', function() { return h + (e.y - c3.y) }) 
        break; 
      } 
     }); 

var g2 = box.selectAll('.draggableSquare') 
    .data([{ 
     x: 65, 
     y: 155, 
     width: 70, 
     height: 70 
    }]) 
    .enter() 
    .append('g') 
    .attr('class', 'draggableSquare'); 

g2 
    .append('svg:rect') 
     .attr('class', 'resizingSquare') 
     .attr("width", function (d) { 
      return d.width + 12; 
     }) 
     .attr("height", function (d) { 
      return d.height + 12; 
     }) 
     .attr("x", function (d) { 
      return d.x - 6; 
     }) 
     .attr("y", function (d) { 
      return d.y - 6; 
     }) 
     .attr("rx", 6) 
     .attr("ry", 6) 
     .style("fill", '#999') 
     .call(resize2); 

g2 
    .append('svg:rect') 
     .attr('class', 'square') 
     .attr("width", function (d) { 
      return d.width; 
     }) 
     .attr("height", function (d) { 
      return d.height; 
     }) 
     .attr("x", function (d) { 
      return d.x; 
     }) 
     .attr("y", function (d) { 
      return d.y; 
     }) 
     .attr("rx", 6) 
     .attr("ry", 6) 
     .style("fill", d3.scale.category20c()); 

JS斌 - https://jsbin.com/zenomoziso/1/edit


這就是說,如果你正在尋求超越概念證明使用它將會非常困難。上面有幾個問題,一旦你有更多的元素將會出現

  1. 正在使用的容器(g或g2)是一個全局變量。這個代碼很笨拙(我剛剛在手錶的基礎上加入了大部分代碼 - 可能會有更有效的方法來做同樣的事情 - 例如,你不能在onDragStart上的開始位置並使用它來計算維度的變化)
  2. 代碼可能更乾淨(考慮對象,更好的命名約定等)。你可能只想在你的主塊中做d3.data... squares({ resize: true, move: true })而不是所有的單獨步驟。
  3. 你會好起來尋找一些現有圖表庫(爲什麼所有的數學,當它已經完成和測試,:-)) - 我發現與畫布變種這裏博客 - http://simonsarris.com/blog/510-making-html5-canvas-useful
+0

的問題非常感謝你的解決方案,但我的經理希望我在svg中創建一個類似http://rigrr.rapilabs.com/的工作流程。我正在想着要去哪個圖書館去實現工作流程。 PS我還是新的即使基本的JS:( – kittu

+0

http://www.jointjs.com/看起來不錯。http://modeling-languages.com/javascript-drawing-libraries-diagrams/有一個列表。但我避風港沒有使用它們中的任何一個來繪製圖表。 – potatopeelings

+0

聯合js在風格上看起來不太好...和鏈接的樣式是不可定製的,因爲我可以看到....我今天檢查它自己 – kittu

1

矩形大小基於widthheight屬性。因此,要調整你要使用這個之流的東西矩形:

d3.selectAll('rect') 
     .attr('width', function(c){ 
      return d3.event.x - this.attributes.x.value; 
     }).attr('height', function(c){ 
      return d3.event.y - this.attributes.y.value; 
     }); 

插入到您的resize行爲。如果你這樣做,然後點擊拖動圓圈並移動到矩形的原點,它會隨着光標線性展開。如果將拖動事件附加到矩形,它可能會稍作修改。 Here是一個簡單的應用程序,展示了矩形的拖動和重新調整大小。

爲了獲得更高的可靠性,您希望通過類標識符而不是全局矩形選擇進行選擇,但這是基本思路。