1

我在完成函数中使用数据映射实现了鼠标滚动时的缩放,如下所示,成功:

 done: function (datamap) {
        /* zoom on mouse scroll */
        datamap.svg.call(d3.behavior.zoom().on("zoom", redraw));
        function redraw() {
          datamap.svg
            .selectAll("g")
            .attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        }

并且还成功地实现了对特定国家的缩放:

const canvas = document.getElementById("choropleth_map");
    const { width, height } = canvas.getBoundingClientRect();
    const canvasFactor = width / height;
    selectedCountry = isoCodeConverter[Country[0].code];
    const countryFeature = map.current.svg.selectAll(`.datamaps-subunit.${selectedCountry}`)["0"]["0"].__data__;
    if (countryFeature !== undefined) {
      const bounds = path.bounds(countryFeature); // get bounds of selected country
      bounds.s = bounds[0][1];
      bounds.n = bounds[1][1];
      bounds.w = bounds[0][0];
      bounds.e = bounds[1][0];
      bounds.height = Math.abs(bounds.n - bounds.s);
      bounds.width = Math.abs(bounds.e - bounds.w);
      newScale = 0.95 / Math.max(bounds.width / width, bounds.height / height);
      const factor = bounds.width / bounds.height;
      /* for maintaining width and height relative to the canvas size to keep the country in the middle */
      if (factor < 1.8) {
        bounds.w = bounds.w - Math.abs(bounds.height * canvasFactor - bounds.width) / 2;
      }
      if (factor > 1.8) {
        bounds.s = bounds.s - Math.abs(bounds.width / canvasFactor - bounds.height) / 2;
      }
      /* update the current map*/
      map.current.svg
        .selectAll("g")
        .transition()
        .duration(750)
        .attr("transform", `scale(${newScale})translate(${-bounds.w},${-bounds.s})`);
    }

但是当我点击特定国家时出现问题(假设地图被缩放到大约 6 的缩放级别)并且在该级别使用鼠标滚动时,地图缩小到原始比例,即 1,而不是从当前比例,即6. 我解决这个问题的方法是在点击特定国家时保存当前的缩放和变换,如果可能的话,将其分配给 d3.event.scale。有没有更好的办法?单击特定国家/地区时如何获取地图的当前缩放级别以及如何将其分配给 d3.event?当控制台在特定国家函数中记录 d3.event 时,它给了我 null。我也是数据地图的新手,所以我自己没有更好的理解来解决它。

4

1 回答 1

1

我在 Andrew Reid 的指导下让它工作了。这里是代码:

const canvas = document.getElementById("choropleth_map");
    const { width, height } = canvas.getBoundingClientRect();
    const canvasFactor = width / height;
    selectedCountry = isoCodeConverter[Country[0].code];
    const countryFeature = map.current.svg.selectAll(`.datamaps-subunit.${selectedCountry}`)["0"]["0"].__data__;
    if (countryFeature !== undefined) {
      const bounds = path.bounds(countryFeature); // get bounds of selected country
      bounds.s = bounds[0][1];
      bounds.n = bounds[1][1];
      bounds.w = bounds[0][0];
      bounds.e = bounds[1][0];
      bounds.height = Math.abs(bounds.n - bounds.s);
      bounds.width = Math.abs(bounds.e - bounds.w);
      newScale = 0.95 / Math.max(bounds.width / width, bounds.height / height);
      const x = (bounds.w + bounds.e) / 2;
      const y = (bounds.s + bounds.n) / 2;

      /* specify the current zoom and translation vector */
      zoom.scale(newScale);
      zoom.translate([width / 2 - newScale * x, height / 2 - newScale * y]);

      /* dispatches a zoom gesture to registered listeners */
      zoom.event(map.current.svg.selectAll("g").transition().duration(2000));
      map.current.svg.selectAll("g").call(zoom);
    }
于 2021-07-15T01:58:12.347 回答