Reputation: 93
So i need little help on my project. I need to do semantic zoom on SVG that is in html part of page. It comes from uploaded therefore, SVG is mostly out of my control. I need to apply pan and zoom on that SVG. I found this example http://bl.ocks.org/mbostock/3680957 and tried to use it. Here is my fiddle (!!fiddle removed, see update bellow!!) and as you can see pretty nothing happens. But in console there is warnind that d is undefined. Could you please find what I got wrong in here?
Thanks guys! :)
Code here:
HTML
<div id="cont">
<script src="http://d3js.org/d3.v3.min.js"></script>
<svg width="1000" height="500" id="map_cont">
<g>
<rect width="1000" height="500" fill="white"></rect>
<circle r="2.5" fill="blue" transform="translate(217.28118519969917,41.890758131264526)"></circle>
<circle r="2.5" fill="blue" transform="translate(608.2409059060647,344.2198244793161)"></circle>
<circle r="2.5" fill="blue" transform="translate(216.72484978866146,298.20041939104055)"></circle>
<circle r="2.5" fill="blue" transform="translate(476.96900214940524,237.46273824202763)"></circle>
<circle r="2.5" fill="blue" transform="translate(321.1504206509037,73.86045864552166)"></circle>
<circle r="2.5" fill="blue" transform="translate(490.2928916777491,357.3678736179799)"></circle>
<circle r="2.5" fill="blue" transform="translate(899.1499819566533,100.34312493154246)"></circle>
<circle r="2.5" fill="blue" transform="translate(334.13921027824017,165.69359981846532)"></circle>
<circle r="2.5" fill="blue" transform="translate(311.52586706987836,23.96973930478341)"></circle>
<circle r="2.5" fill="blue" transform="translate(378.0376019607231,331.57321612058746)"></circle>
<circle r="2.5" fill="blue" transform="translate(309.8850901872685,161.59290497259988)"></circle>
<circle r="2.5" fill="blue" transform="translate(253.86150170977407,-102.58470619117588)"></circle>
<circle r="2.5" fill="blue" transform="translate(514.6405714044365,453.63661200884786)"></circle>
</g>
</svg>
</div>
Javascript:
var width = 1000,
height = 500;
var x = d3.scale.linear()
.domain([0, width])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, height])
.range([height, 0]);
var svg2 = d3.select("#map_cont")
.select("g")
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom2));
var circle2 = svg2.selectAll("circle");
function zoom2() {
console.log(circle2);
circle2.attr("transform", transform);
}
function transform(d) {
return "translate(" + x(d[0]) + "," + y(d[1]) + ")";
}
UPDATE
So after a while and thanks to @Kaiido I made some progress. Now I have this http://jsfiddle.net/syj4jhes/8/ As you can see, the x and y coordinates are calucated wrong. Now I'm looking for the help to calculate them correctly... :)
Upvotes: 2
Views: 253
Reputation: 93
I solved it! It was hell of using console.log, but I got it working in the 9th version. Hope this helps anyone. Fiddle here http://jsfiddle.net/syj4jhes/9/
Whole trick was that d was array of initial positions of circles. Little bit of mocking and BA DUM TSS! It worked. Code bellow 'cause you never know what can happen.
HTML
<div id="cont">
<script src="http://d3js.org/d3.v3.min.js"></script>
<svg width="1000" height="500" id="map_cont">
<g>
<rect width="1000" height="500" fill="white"></rect>
<circle r="2.5" fill="blue" transform="translate(217.28118519969917,41.890758131264526)"></circle>
<circle r="2.5" fill="blue" transform="translate(608.2409059060647,344.2198244793161)"></circle>
<circle r="2.5" fill="blue" transform="translate(216.72484978866146,298.20041939104055)"></circle>
<circle r="2.5" fill="blue" transform="translate(476.96900214940524,237.46273824202763)"></circle>
<circle r="2.5" fill="blue" transform="translate(321.1504206509037,73.86045864552166)"></circle>
<circle r="2.5" fill="blue" transform="translate(490.2928916777491,357.3678736179799)"></circle>
<circle r="2.5" fill="blue" transform="translate(899.1499819566533,100.34312493154246)"></circle>
<circle r="2.5" fill="blue" transform="translate(334.13921027824017,165.69359981846532)"></circle>
<circle r="2.5" fill="blue" transform="translate(311.52586706987836,23.96973930478341)"></circle>
<circle r="2.5" fill="blue" transform="translate(378.0376019607231,331.57321612058746)"></circle>
<circle r="2.5" fill="blue" transform="translate(309.8850901872685,161.59290497259988)"></circle>
<circle r="2.5" fill="blue" transform="translate(253.86150170977407,-102.58470619117588)"></circle>
<circle r="2.5" fill="blue" transform="translate(514.6405714044365,453.63661200884786)"></circle>
</g>
</svg>
</div>
Javascript
var width = 1000,
height = 500;
var x = d3.scale.linear()
.domain([0, width])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, height])
.range([0, height]);
var svg2 = d3.select("#map_cont")
.select("g")
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([0.1, 8]).on("zoom", zoom2));
var circles = svg2.selectAll("circle")[0];
var circle2 = circles;
var arrayLength = circle2.length;
var orig_pos=[];
for (var i = 0; i < arrayLength; i++) {
var atribut=$(circle2[i]).attr("transform");
var xval = atribut.match(/([-0-9.]*),/);
var yval = atribut.match(/,([-0-9.]*)/);
var pos= [ parseFloat(xval[1]),parseFloat(yval[1]) ];
orig_pos.push(pos);
}
function zoom2() {
$(circle2).attr("transform", transform);
}
function transform(d) {
var xval = orig_pos[d][0];
var yval = orig_pos[d][1];
return "translate(" + x(xval) + "," + y(yval) + ")";
}
Upvotes: 1