如何在d3 js中调整矩形的大小

时间:2015-07-03 12:08:20

标签: d3.js

现在我可以调整一个圆圈的大小。我使用g.append('svg:rect')创建了一个矩形,但我不确定如何在d3

中调整矩形的大小

这就是我的尝试:

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

2 个答案:

答案 0 :(得分: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 Bin - https://jsbin.com/zenomoziso/1/edit

那就是说,如果你想要在概念证明之外使用它,那将是非常困难的。一旦你有更多元素

,上面会出现一些问题
  1. 正在使用的容器(g或g2)是全局变量。
  2. 代码很笨重(我刚刚根据手表加上大部分代码 - 可能有更有效的方法做同样的事情 - 例如你不能在启动位置onDragStart并使用它来计算尺寸的变化)
  3. 代码可以更清晰(想想对象,更好的命名约定等)。您可能只想在主要块中执行d3.data... squares({ resize: true, move: true })而不是所有单独的步骤。
  4. 你会更好地寻找一些现有的图表库(为什么所有的数学,当它已经完成并经过测试:-)) - 我在这里找到了一个带有画布变体的博客 - http://simonsarris.com/blog/510-making-html5-canvas-useful

答案 1 :(得分: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是一个简单的应用程序,它展示了拖动和重新调整矩形的大小。

为了获得更高的可靠性,您希望通过类标识符而不是全局矩形选择进行选择,但这是基本想法。