过渡后在D3投影上重绘一个键

时间:2017-11-20 22:05:05

标签: javascript d3.js geojson

我正在使用类似于Mike Bostock's Choropleth seen here的D3地图投影。

我遇到的问题是我已经添加了转换;当我转换投影时,地图键(在右上角看到)被地图的背景颜色覆盖。

我知道我可能只需要在转换后重绘g层,但我无法按预期工作。

我最初使用以下代码在地图上绘制关键字:

var g = svg.append("g")
    .attr("class", "key")
    .attr("transform", "translate(0,40)");

g.selectAll("rect")
  .data(color.range().map(function(d) {
      d = color.invertExtent(d);
      if (d[0] == null) d[0] = x.domain()[0];
      if (d[1] == null) d[1] = x.domain()[1];
      return d;
    }))
  .enter().append("rect")
    .attr("height", 8)
    .attr("x", function(d, i) { return 350 + (i * 30)})
    .attr("width", 30)
    .attr("fill", function(d) { console.log(d[1]); return color(d[1]); });

g.append("text")
    .attr("class", "caption")
    .attr("x", x.range()[0])
    .attr("y", -6)
    .attr("fill", "#000")
    .attr("text-anchor", "start")
    .attr("font-weight", "bold")
    .text("Number of Licensed Establishments");

    g.call(d3.axisBottom(x)
        .tickSize(13)
        .tickValues(color.domain()))
      .select(".domain")
        .remove();

然后我用这段代码转换投影(也可以正常工作)。

path = d3.geoPath(projection);
    svg.selectAll("path").transition().duration(2000).attr("d", path);

但关键是被覆盖。我试过这样重绘:

g.selectAll("g").attr("transform", "translate(0,40)");

但它没有做任何事情。我错过了在顶部正确重绘g层的步骤吗?

1 个答案:

答案 0 :(得分:1)

转换路径不应该改变它在DOM中出现的位置。使用d3转换元素属性会在DOM中修改该元素。下面的示例应该演示这一点(首先附加路径并且应该在文本后面,然后路径将其d属性转换为文本后面的两个d3符号路径):

var svg = d3.select('body').append('svg').attr('width',400).attr('height',200);

var cross = "M-21.213203435596427,-7.0710678118654755L-7.0710678118654755,-7.0710678118654755L-7.0710678118654755,-21.213203435596427L7.0710678118654755,-21.213203435596427L7.0710678118654755,-7.0710678118654755L21.213203435596427,-7.0710678118654755L21.213203435596427,7.0710678118654755L7.0710678118654755,7.0710678118654755L7.0710678118654755,21.213203435596427L-7.0710678118654755,21.213203435596427L-7.0710678118654755,7.0710678118654755L-21.213203435596427,7.0710678118654755Z";

var star = "M0,-29.846492114305246L6.700954981042517,-9.223073285798176L28.38570081386192,-9.223073285798177L10.8423729164097,3.5229005144437298L17.543327897452222,24.146319342950797L1.7763568394002505e-15,11.400345542708891L-17.543327897452215,24.1463193429508L-10.842372916409698,3.522900514443731L-28.38570081386192,-9.22307328579817L-6.7009549810425195,-9.223073285798176Z";

var wye = "M8.533600336205877,4.926876451265144L8.533600336205877,21.9940771236769L-8.533600336205877,21.9940771236769L-8.533600336205877,4.9268764512651435L-23.31422969000131,-3.6067238849407337L-14.78062935379543,-18.387353238736164L0,-9.853752902530289L14.78062935379543,-18.387353238736164L23.31422969000131,-3.6067238849407337Z"

var symbol = svg.append('path')
   .attr('transform','translate(100,100)')
   .attr('d', cross )
   .attr("fill","orange");
   
var text = svg.append('text')
  .attr('x', 100)
  .attr('y', 105)
  .style('text-anchor','middle')
  .text('THIS IS SOME TEXT')
   
symbol.transition()
  .delay(2000)
  .attr('d', star )
  .duration(2000)
  .transition()
  .attr('d', wye )
  .duration(2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

根据你的例子,很可能钥匙最初是在地图的特征后面渲染的 - 只是两者之间没有重叠。每个都按预期显示。转换时,例如缩放,功能重叠并且密钥被隐藏。如评论中所述,尝试g.raise()d3.select(".key").raise()将密钥移动到父容器的底部,有效地将其提升到其他svg元素之上(因为元素按照它们在DOM中出现的顺序呈现,尽可能接近svg中的z-index。您应该只需要应用.raise()一次 - 因为转换不会改变顺序,或者确保密钥最后附加到svg。