如何在D3 JS中调整矩形大小

kit*_*ttu 2 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());
Run Code Online (Sandbox Code Playgroud)

的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>
Run Code Online (Sandbox Code Playgroud)

这是现场演示:https : //jsbin.com/dejewumali/edit?html,js,output

pot*_*ngs 5

为代码添加了矩形调整大小。请注意,您需要使用右下角的大小进行调整(这是将调整大小添加到:-的最简单的角)

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());
Run Code Online (Sandbox Code Playgroud)

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


就是说,如果您想在概念验证之外使用它,将会非常困难。一旦您拥有更多元素,上述问题就会显现出来

  1. 使用的容器(g或g2)是全局变量。
  2. 代码很笨拙(我只是根据手表添加了大部分代码-可能有更高效的方法来执行相同的操作-例如,您无法在onDragStart上开始放置位置并使用它来计算尺寸变化)
  3. 该代码可能更简洁(认为对象,更好的命名约定等)。您可能只想d3.data... squares({ resize: true, move: true })在主块中执行操作,而不是所有单独的步骤。
  4. 您最好搜索一些现有的图形库(为什么要做所有的数学运算,当它已经完成并经过测试时:-))-我在这里找到了一个带有canvas变体的博客-http: //simonsarris.com/blog/ 510-makeing-html5-画布有用