I'm using d3.js but I'm having a problem. When I zoom in SVG, is not commensurate. Also, after dragging, the handling of SVG I made; a further drifting. I'm giving the necessary code. What can I do to fix this code?
Code:
/* 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>
EDIT:
It seems that problem is not explained very well. The first problem can be traced like this: drag any circle, then drag background and you will see that dragged circle moved to random position. The second problem is scaling and you can trace that zooming in and out, then you can see that positions of circles are changed according to background.
You should make a main group and in that add all the components to which you want to give zoom and drag.
Something like this:
Here is a working fiddle this should give more clarity: http://jsfiddle.net/cyril123/ow8r5n6f/3/