D3.js在多个图表中渲染topoJSON

时间:2016-06-13 12:02:54

标签: d3.js topojson

我一直在尝试在DOM中的多个图表中绘制topoJson文件。我提供的示例仅包括两个图表,但我想最终扩展。我的问题是,尽管两个容器中的每个容器中的Javascript代码完全相同,但topoJSON文件仅显示在第二个容器中。我相信它与D3的渲染模式有关,但我无法弄明白。这是代码和结果页面。

P.S。很抱歉JS代码中的冗余。我只是为了示例而做了

<!doctype html>
<meta charset="utf-8">

<script src="./js/d3.js"></script>
<script src="./js/topojson.js"></script>


<body>
  First Map (Empty!!!)
  <div id='container1'>

    <script charset="utf-8">

    var width=2712/9;
    var height=1955/9;
    var rasterBounds=[[-1.3312652841195303 , 41.964452901889715] , [1.748235284119533 , 43.59348149262565]];

    var projection = d3.geo.mercator()
      .scale(1)
      .translate([0, 0])

    var b = [projection(rasterBounds[0]), projection(rasterBounds[1])],
      s = 1 / 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, (height - s * (b[1][1] + b[0][1])) / 2]
    //update projection
    projection
      .scale(s)
      .translate(t)

    // geo path generator
    var path = d3.geo.path()
      .projection(projection)


    var map = d3.select('#container1').append('svg')
      .attr('width', width)
      .attr('height', height)

    map.append("rect")
      .attr("width", "100%")
      .attr("height", "100%")
      .attr("fill", "#E6E6E6");

    var color = d3.scale.ordinal()
        .domain(["1", "2", "3"])
        .range(["#ffd633", "#aaff00" , "#267300"]);


    d3.json('MapTopoFinal.json', function(error, topology) {
            map.selectAll("path")
              .data(topojson.feature(topology, topology.objects.Fin_Map).features)
            .enter()
              .append("path")
            .attr("d", path)
            .attr("fill", function(d) {
                return color(d.properties.DN);
                })
            .style("opacity", .6);
  })


     </script>
  </div>


  Second Map (OK)
  <div id='container2'>
    <script charset="utf-8">

    var width=2712/9;
    var height=1955/9;
    var rasterBounds=[[-1.3312652841195303 , 41.964452901889715] , [1.748235284119533 , 43.59348149262565]];

    var projection = d3.geo.mercator()
      .scale(1)
      .translate([0, 0])

    var b = [projection(rasterBounds[0]), projection(rasterBounds[1])],
      s = 1 / 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, (height - s * (b[1][1] + b[0][1])) / 2]
    //update projection
    projection
      .scale(s)
      .translate(t)

    // geo path generator
    var path = d3.geo.path()
      .projection(projection)


    var map = d3.select('#container2').append('svg')
      .attr('width', width)
      .attr('height', height)

    map.append("rect")
      .attr("width", "100%")
      .attr("height", "100%")
      .attr("fill", "#E6E6E6");

    var color = d3.scale.ordinal()
        .domain(["1", "2", "3"])
        .range(["#ffd633", "#aaff00" , "#267300"]);


    d3.json('MapTopoFinal1.json', function(error, topology) {
            map.selectAll("path")
              .data(topojson.feature(topology, topology.objects.Fin_Map).features)
            .enter()
              .append("path")
            .attr("d", path)
            .attr("fill", function(d) {
                return color(d.properties.DN);
                })
            .style("opacity", .6);
  })

    </script>
  </div>

</body>

The resulting page

1 个答案:

答案 0 :(得分:0)

长话短说:在多个脚本标记中分隔您的代码不会创建不同的范围。

现在您正在使用脚本两次的几个变量。最重要的是map。从这里更改第二张地图:

var map = d3.select('#container2').append('svg')
  .attr('width', width)
  .attr('height', height)

到此:

var map2 = d3.select('#container2').append('svg')
  .attr('width', width)
  .attr('height', height)

并将所有后续map更改为map2或其他任何内容。此外,更改所有其他重复变量,例如colorprojection等。

不要将脚本分开。它们现在的方式,遍布HTML,并不是最佳实践,因为浏览器必须在继续解析HTML的其余部分之前解析每个脚本(这也可能导致其他问题)。将所有脚本放在<script></script>末尾的单个body内。

请注意,使用多个<script>标记不会在JavaScript中定义不同的范围。