markmarkoh / datamaps

Customizable SVG map visualizations for the web in a single Javascript file using D3.js
http://datamaps.github.io
MIT License
3.78k stars 1.01k forks source link

Responsive Maps - on resize event refresh d3 zoom behavior #274

Closed gregdevs closed 8 years ago

gregdevs commented 8 years ago

Working on a map using the Datamaps framework which also uses d3.

I'm simply trying to reset the d3 zoom behavior after the resize event. I'm not quite sure what the best approach is to achieve this using d3.

 var stateMap = new Datamap({
    scope: statevar,
    element: electionMap,
    responsive: true,
    geographyConfig: {
      dataUrl: 'js/state-topojson/tl_2010_' + statecode + '_county10.json',
      popupOnHover: false,
      highlightBorderColor: '#c4c4c4',
      highlightBorderWidth: 1

    },

    fills: {
      defaultFill: '#c4c4c4'
    },
    setProjection: function(element) {

      var width = window.innerWidth / 1.7,
        height = width * .5;

      var projection = d3.geo.transverseMercator()
        .rotate([74 + 30 / 60, -38 - 50 / 60]);

      var path = d3.geo.path()
        .projection(projection);

      var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);

      d3.json('js/state-topojson/tl_2010_' + statecode + '_county10.json', function(error, nj) {
        if (error) throw error;
        var tracts = topojson.feature(nj, nj.objects[statevar]);
        console.log(tracts)
        projection
          .scale(1)
          .translate([0, 0]);

        var b = path.bounds(tracts),
          s = .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
          t = [(width - s * (b[1][0] + b[0][0])) / 2 - 100, (height - s * (b[1][1] + b[0][1])) / 2];
        projection
          .scale(s)
          .translate(t);

      });

      var path = d3.geo.path()
        .projection(projection);

      return {
        path: path,
        projection: projection
      };
    },
    done: function(datamap) {
      datamap.svg.call(d3.behavior.zoom().on("zoom", function() {
        redraw();

        d3.event.sourceEvent.stopPropagation();
        console.log('Start Dragging Circle');
      }));

      $('.datamaps-subunit').each(function() {
        var thisState = $(this).attr('class');

        if ($(window).width() >= 490) {

          $(this).tooltip({
            title: "test",
            container: 'body',
            placement: 'bottom'
          });
        } else {

        }

      });

      window.addEventListener('resize', function() {
        stateMap.resize();

      });

      function redraw() {
        datamap.svg.selectAll("g").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        console.log('redrew')
      }

    }

  });

the initial zoom behavior works as expected

  datamap.svg.call(d3.behavior.zoom().on("zoom", function() {
    redraw();

    d3.event.sourceEvent.stopPropagation();
    console.log('Start Dragging Circle');
  }));

as does the stateMap.resize on the resize event. I did try adding the redraw function in the resize event, but it was not triggering.

gregdevs commented 8 years ago

Oops, I just updated to the latest version and it works perfectly. Thanks!