当前位置:  开发笔记 > 编程语言 > 正文

d3美国国家地图与标记,缩放转换问题

如何解决《d3美国国家地图与标记,缩放转换问题》经验,为你挑选了1个好方法。

我按照这个例子创建了一个美国各州的d3地图:

http://bl.ocks.org/mbostock/4699541

并在此SO问题后添加标记:

将标记放到使用topoJSON和d3.js生成的地图上

问题是在缩放时,地图标记保持不变.我相信我需要将它们转化为新的位置,但不确定如何实现这一目标.

在此输入图像描述

var width = 900,
  height = 500,
  active = d3.select(null);

var projection = d3.geo.albersUsa()
  .scale(1000)
  .translate([width / 2, height / 2]);

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

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

svg.append("rect")
  .attr("class", "background")
  .attr("width", width)
  .attr("height", height)
  .on("click", reset);

var g = svg.append("g")
  .style("stroke-width", "1.5px");

d3.json("/files/d3-geo/us.json", function(error, us) {
  if (error) { throw error; }

  g.selectAll("path")
    .data(topojson.feature(us, us.objects.states).features)
    .enter().append("path")
    .attr("d", path)
    .attr("class", function(item) {
      return window.US_STATES[item.id].water_authorities > 0 ? 'avail' : 'unavail';
    })
    .on("click", clicked);

  g.append("path")
    .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
    .attr("class", "mesh")
    .attr("d", path);
});

d3.json('/files/coordinates.json', function(error, coords) {
  if (error) { throw error; }

  svg.selectAll(".mark")
    .data(coords)
    .enter()
    .append("image")
    .attr('class','mark')
    .attr('width', 20)
    .attr('height', 20)
    .attr("xlink:href",'assets/gmap_red.png')
    .attr("transform", function(d) {
      return "translate(" + projection([d[1],d[0]]) + ")";
    });
});

function clicked(d) {
  if (active.node() === this) { return reset(); }
  if (window.US_STATES[d.id].water_authorities === 0) { return; }

  active.classed("active", false);
  active = d3.select(this).classed("active", true);

  var bounds = path.bounds(d),
    dx = bounds[1][0] - bounds[0][0],
    dy = bounds[1][1] - bounds[0][1],
    x = (bounds[0][0] + bounds[1][0]) / 2,
    y = (bounds[0][1] + bounds[1][1]) / 2,
    scale = .9 / Math.max(dx / width, dy / height),
    translate = [width / 2 - scale * x, height / 2 - scale * y];

  g.transition()
    .duration(750)
    .style("stroke-width", 1.5 / scale + "px")
    .attr("transform", "translate(" + translate + ")scale(" + scale + ")");
}

function reset() {
  active.classed("active", false);
  active = d3.select(null);

  rebatesTable.clear().draw();

  g.transition()
    .duration(750)
    .style("stroke-width", "1.5px")
    .attr("transform", "");
}

Cyril Cheria.. 7

步骤1

添加组中的所有点,而不是svg中的所有点.这将确保标记点与主组一起转换.

  g.selectAll(".mark")//adding mark in the group
    .data(marks)
    .enter()
    .append("image")
    .attr('class', 'mark')
    .attr('width', 20)
    .attr('height', 20)
    .attr("xlink:href", 'https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/24x24/DrawingPin1_Blue.png')
    .attr("transform", function(d) {
      return "translate(" + projection([d.long, d.lat]) + ")";
    });

第2步

否定主组的缩放效果.否则标记会变大.

  g.selectAll(".mark")
  .transition()
    .duration(750)
    .attr("transform", function(d) {
      var t = d3.transform(d3.select(this).attr("transform")).translate;//maintain aold marker translate 
      return "translate(" + t[0] +","+ t[1] + ")scale("+1/scale+")";//inverse the scale of parent
    });        

第三步:

缩小时,使标记缩放回1.

  g.selectAll(".mark")
    .attr("transform", function(d) {
      var t = d3.transform(d3.select(this).attr("transform")).translate;
      console.log(t)
      return "translate(" + t[0] +","+ t[1] + ")scale("+1+")";
    });   

在这里工作代码

希望这可以帮助!



1> Cyril Cheria..:

步骤1

添加组中的所有点,而不是svg中的所有点.这将确保标记点与主组一起转换.

  g.selectAll(".mark")//adding mark in the group
    .data(marks)
    .enter()
    .append("image")
    .attr('class', 'mark')
    .attr('width', 20)
    .attr('height', 20)
    .attr("xlink:href", 'https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/24x24/DrawingPin1_Blue.png')
    .attr("transform", function(d) {
      return "translate(" + projection([d.long, d.lat]) + ")";
    });

第2步

否定主组的缩放效果.否则标记会变大.

  g.selectAll(".mark")
  .transition()
    .duration(750)
    .attr("transform", function(d) {
      var t = d3.transform(d3.select(this).attr("transform")).translate;//maintain aold marker translate 
      return "translate(" + t[0] +","+ t[1] + ")scale("+1/scale+")";//inverse the scale of parent
    });        

第三步:

缩小时,使标记缩放回1.

  g.selectAll(".mark")
    .attr("transform", function(d) {
      var t = d3.transform(d3.select(this).attr("transform")).translate;
      console.log(t)
      return "translate(" + t[0] +","+ t[1] + ")scale("+1+")";
    });   

在这里工作代码

希望这可以帮助!

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有