D3 + ReactJS的世界地图缩放

时间:2018-08-30 10:25:58

标签: reactjs d3.js

我找到了下面的代码来放大一个简单的D3解决方案,该解决方案可与Javascript很好地兼容:

var zoom = d3.behavior.zoom()
        .on("zoom", function() {
            projection.translate(d3.event.translate).scale(d3.event.scale);
            feature.attr("d", path);
            circle.attr("transform", ctr);
        })
        ;

zoom.translate(projection.translate())
            .scale(projection.scale())
            .scaleExtent([h / 6, h])
        ;

当我尝试在D3 + ReactJS中转换此代码时,出现问题。自从我尝试了许多不同的解决方案以来,已经有了很多。最新的地图一次放大了我的世界地图,但全是一团糟。

这是我的代码:

import React, { Component } from 'react';
import 'd3';
import * as d3Z from 'd3-zoom'
import * as d3 from 'd3-selection';
//import d3Scale from 'd3-scale'
import { geoMercator, geoPath } from 'd3-geo';
import './WorldMap.css';
import countries from '../resources/world-countries.json';

//
export default class WorldMap extends Component {

  componentDidUpdate() {

    const width = 1300, //document.body.clientWidth,
      height = 600;//document.body.clientHeight;
    const circleRadius = 2;
    const lstRadius = [7, circleRadius];
    const lstColor = ["green", "white"];
    const duration = 500;
    const lstShots = [];
    const projection = geoMercator();
    const path = geoPath()
      .projection(projection);

    const d3Zoom = d3Z.zoom();


    for (var i = 0; i < this.props.data.length; i++) {

        lstShots.push(JSON.parse(JSON.stringify(this.props.data[i])));
    }

    const getCirclePos = (d) => {
      return "translate(" + projection([d.long, d.lat]) + ")";
    }

    const svgObj = d3.select(this.refs.svgMap);

    const feature = svgObj
      .selectAll("path.feature")
      .data(countries.features)
      .enter().append("path")
      .attr("class", "feature");

    projection
      .scale(width / 6.5)
      .translate([width / 2, height / 1.6]);

    const zoom = d3Zoom
                  .on("zoom", function() {

                    console.log(d3.event);
                      projection.translate([d3.event.transform.x, d3.event.transform.y]).scale(d3.event.scale);
                      feature.attr("d", path);
                    //  circle.attr("transform", getCirclePos);
                  })
                  ;

    svgObj.call(zoom);

// console.log(zoom);

    // zoom.translateTo(projection.translate())
    //           .scale(projection.scale())
    //           .scaleExtent([height / 6, height])
    //       ;

    feature.attr("d", path);
    // eslint-disable-next-line
    const circle = svgObj.selectAll("circle")
      .data(lstShots)
      .enter()
      .append("circle")
      .attr("r", circleRadius)
      .attr("fill", 'white')
      .attr("transform", getCirclePos)
      .attr("node", function(d) { return JSON.stringify(d); })
      .style("cursor", "pointer");


  }

  render() {
    return (

      <svg ref="svgMap"></svg>
    );
  }
}

问题在于d3.event不包含translatescale的字段,我已经看到人们在d3-zoom的其他示例中使用了这些字段。在缩放功能中,我用translate替换了transform,但我不知道该用d3.event.scale替换什么。

1 个答案:

答案 0 :(得分:2)

如果将代码从d3v3移植到d3v4,则需要全部完成,d3.event.scale在d3v4中不存在

projection.translate([d3.event.transform.x, d3.event.transform.y]).scale(d3.event.transform.k);

您也需要初始化缩放

svgObj.call(zoom);
svgObj.call(zoom.transform, d3.zoomIdentity.translate(projection.translate()[0], projection.translate()[1]).scale(projection.scale()));

不使用引用字符串,但使用Callback Refs

我需要使用componentDidMount()来查看任何内容。