Jack Bizon
Jack Bizon

Reputation: 93

Svg semantic zoom not working on SVG in HTML

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

Answers (1)

Jack Bizon
Jack Bizon

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

Related Questions