d3.js: 缩放拖拽失败

d3.js: zoom and drag failure

我正在使用 d3.js,但我遇到了问题。当我放大 SVG 时,不相称。另外,拖动后,我制作的 SVG 的处理;进一步漂流。我正在提供必要的代码。我该怎么做才能修复此代码?

代码:

            /* Tünelin bütün elemanları için bir dizi oluşturuldu
                Daha sonra her ayrı eleman için dizi oluşturulup,
                datalar bu doğrultuda çekilecektir.
            */
                var tunnelElements = new Array();
                tunnelElements = [{ "x": 0, "y": 0, "radius": 10, "color" : "green" },
                                { "x": 25, "y": 25, "radius": 10, "color" : "green"},
                                { "x": 50, "y": 50, "radius": 10, "color" : "green" },
                                { "x": 75, "y": 75, "radius": 10, "color" : "green"},
                                { "x": 100, "y": 100, "radius": 10, "color" : "green" },
                                { "x": 125, "y": 125, "radius": 10, "color" : "green" },
                                { "x": 62.5, "y": 62.5, "radius": 10, "color" : "red" },
                                { "x": 0, "y": 125, "radius": 10, "color" : "purple" },
                                { "x": 25, "y": 100, "radius": 10, "color" : "purple" },
                                { "x": 50, "y": 75, "radius": 10, "color" : "purple" },
                                { "x": 75, "y": 50, "radius": 10, "color" : "purple" },
                                { "x": 100, "y": 25, "radius": 10, "color" : "purple" },
                                { "x": 125, "y": 0, "radius": 10, "color" : "purple" }];

            /* Tünel elemanları datadan çekilip circles dizisine 
                kopyalanmaktadır. 
            */
            var circles = []
            for (var i = 0; i < tunnelElements.length; i++) {
                circles[i] = tunnelElements[i];
            };
            
            console.log(circles);

            var width = 719, height = 262;

            var X = d3.scale.linear()

            var Y = d3.scale.linear()

            /* Semantic zoom için zoom değişkeni oluşturuldu */
            var zoom = d3.behavior.zoom()
                .x(X).y(Y)
                .scaleExtent([1, 10])
                .on("zoom", zoomed);
          
                /* Alternatif zoom
                .on("zoom", function () {
                    circle.attr("transform", transform)
                });
                */

            /* Elementler svg olarak oluşturuldu */
            var svg = d3.select("#d3")
                .append("svg")
                    .attr("width", width)
                    .attr("height", height)
                    .call(zoom);

            /* Road background çağırdık */
            var road = svg.selectAll("image").data([0]);
                road.enter()
                    .append("svg:image")
                    .attr("xlink:href", "http://ahmetates.com.tr/road.svg")
                    .attr("width", width)
                    .attr("height", height);

            var circle;
            /* Bütün elemenlar seçilip transform fonksiyonu
                sayesinde drag and drop özelliği kazandı */
            circle = svg.selectAll("circle")
                .data(circles)
                .enter().append("circle")
                .attr("transform", transform);


            var drag = d3.behavior.drag()
                .origin(function(d) { return d; })
                .on("dragstart", dragstarted)
                .on("drag", dragged)
                .on("dragend", dragended);

            
            /* Fonksiyonlar */

            function zoomed() {
                road.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
                circle.attr("transform", transform)
            }

            function transform(d) {
                return "translate("+X(d.x)+", "+Y(d.y)+")";
            }

            function generateit(){
                var circles = svg.selectAll("circle");
                var json_circles = JSON.stringify(circles.data());
                d3.select("#console").html('tunnelElements = '+json_circles+';');
            }
            
            d3.select("#exportit").on("click", generateit);


            var circleAttributes = circle
                .attr("cx", function (d) { return d.x; })
                .attr("cy", function (d) { return d.y; })
                .attr("r", function (d) { return d.radius; })
                .style("fill", function(d) { return d.color; })
                .call(drag);

            function dragstarted(d) {
              d3.event.sourceEvent.stopPropagation();
              d3.select(this).classed("dragging", true);
            }

            function dragged(d) {
              d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
            }

            function dragended(d) {
              d3.select(this).classed("dragging", false);
            }
#d3 svg{
  margin:30px;
  padding:10px;
  border:1px solid #333;
  width: 100%;
  height: auto;
}
.line{
  stroke-width: 3px;  
}
#exportit {
    background:#000;
    cursor:pointer;
    color:#fff;
    width:45px;
    padding:2px 4px;
}
<script src="http://d3js.org/d3.v3.min.js"></script>

<div id="exportit">Export</div>
  <div id="d3"></div>
<div id="console"></div>

编辑:

好像问题没有解释清楚。第一个问题可以这样追溯:拖动任何圆圈,然后拖动背景,你会看到被拖动的圆圈移动到随机位置。第二个问题是缩放,你可以跟踪放大和缩小,然后你可以看到圆圈的位置根据背景变化。

您应该创建一个主组,然后在其中添加您想要缩放和拖动的所有组件。

像这样:

var maingroup = svg.append("g").call(zoom);
//add road and circles in this maingroup
//drag events on circle as you had done no change in that. 

这是一个工作 fiddle 这应该更清楚: http://jsfiddle.net/cyril123/ow8r5n6f/3/