【问题标题】:d3.json() undefined googleoverlayd3.json() 未定义的 googleoverlay
【发布时间】:2017-03-17 18:08:53
【问题描述】:

我对编码和尝试实现以下代码非常陌生:https://bl.ocks.org/mbostock/899711。我从 url 读取 json 而不是本地 .json 文件,不幸的是 LAT 和 LONG 是字符串,所以我使用 data.forEach() 解析它们,但是当我调用解析后的 d.LAT 和 d.LONG 外部数据时。 forEach()、d.LAT 和 d.LONG 正在被读取,但返回未定义。

var map = new google.maps.Map(d3.select(".box-panel-map").node(), {
  zoom: 15,
  draggableCursor: 'crosshair',
  center: new google.maps.LatLng(54.52936037,-117.46484254),
  mapTypeId: google.maps.MapTypeId.TERRAIN,
  backgroundColor: "white",
  mapMaker: 'True',
  styles: [
  {
    featureType: "all",
    elementType: "labels",
    stylers: [{ visibility: "off" }]
  }
  ]
});


var url ="";

d3.json(url, function(data) {
        data.forEach(function(d) {
            d.LAT = +d.LAT___DEG; 
            d.LONG = +d.LONG___DEG;
        });

  var overlay = new google.maps.OverlayView();

  // Add the container when the overlay is added to the map.
  overlay.onAdd = function() {
    var layer = d3.select(this.getPanes().overlayMouseTarget).append("div")
      .attr("class", "pipemap");

    // Draw each marker as a separate SVG element.
    overlay.draw = function() {

      var projection = this.getProjection(),
        padding = 10;

      function transform (d) {
            console.log(d.LAT); //THIS IS RETURNING AS UNDEFINED
            var googleCoordinates = new google.maps.LatLng(d.LAT, d.LONG);
            var pos = projection.fromLatLngToDivPixel(googleCoordinates);
            return d3.select(this)
              .style("left", (pos.x - padding) + "px")
              .style("top", (pos.y - padding) + "px");
              //.attr('fill', color(d.value[2]))     
          }


      /*var color = d3.scale.linear()
        .domain([0, 1])
        .range(["blue", "red"]);   */
      var cValue = function(d) { return d.GFLAG;},
           color = d3.scale.linear()
            .domain([0, 1])
            .range(["blue", "red"]);  

      var tooltip = d3.select("body")
        .append("div")
        .attr("class", "tooltip")
        .style("opacity", 0);

      var marker = layer.selectAll("svg")
        .data(d3.entries(data))
        .each(transform) // update existing markers 
        .enter().append("svg:svg")
          .each(transform)
          .attr("class", "marker");

      // Add a circle.
      marker.append("circle")
        .attr("r", 2.5)
        .attr("cx", padding)
        .attr("cy", padding)
        .style("fill", function(d) { return color(cValue(d));}) 
        .on("mouseover", function(d) {
          tooltip.transition()
            .duration(200)
            .style("opacity", .9);
         // tooltip.html('Population: '+d.key+'<br>'+'Allele Frequencey: '+d.value[2].toPrecision(3))
          tooltip.html('Feature-Type: '+d.key+'')
            .style("left", (d3.event.pageX + 5) + "px")
            .style("top", (d3.event.pageY - 28) + "px");
        })
        .on("mouseout", function(d) {
          tooltip.transition()
          .duration(200)
          .style("opacity", 0);
          });


        };
      }; 
   overlay.setMap(map);
}); 

我正在阅读的 URL 中的 JSON 对象示例:

    [{"FEATURE_NUMBER":"ABC-1115",
"LAT___DEG":"54.412530",
"LONG___DEG":"-117.447681",
"FLAG":0,"COMMENTS":null}]     

【问题讨论】:

    标签: javascript json node.js google-maps d3.js


    【解决方案1】:

    虽然其他地方可能有错误,但我相信你会发现这些行让你很伤心:

     var marker = layer.selectAll("svg")
        .data(d3.entries(data))
    

    在 Mike 的 bl.ock 中,他使用 d3.entries(),你也一样。 D3 条目接受具有 n 个属性的对象并创建具有 n 个对象的数组,每个对象代表一个属性。您的数据已经是一个对象数组。看看d3.entries() 用你的数据和他的数据返回了什么:

    迈克的街区:

    var data = {"KMAE":[-120.12,36.98,"MADERA MUNICIPAL AIRPORT",[26,1,2,5,6,3,2,1,2,7,29,12,3]],"KSJC":[-121.92,37.37,"SAN JOSE INTERNATIONAL  AIRPORT",[28,1,1,1,6,10,5,3,2,4,14,21,7]]}
    
    console.log(d3.entries(data));
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"&gt;&lt;/script&gt;

    您的 JSON 格式:

    var data = [
    {"FEATURE_NUMBER":"ABC","LAT___DEG":"54.412530","LONG___DEG":"-117.447681","FLAG":0,"COMMENTS":null},{"FEATURE_NUMBER":"DEF","LAT___DEG":"11","LONG___DEG":"-12","FLAG":1,"COMMENTS":null}
    ];
    
    console.log(d3.entries(data))
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"&gt;&lt;/script&gt;

    您的数据设置方式不适合使用 d3.entries()。但是,您可以使用这种方法,如果您在转换函数中使用 console.log(d);,您应该能够看到您的 lat long 值现在位于 d.value.lat/long


    为了演示,这里有一个 d3.entries() 的最小示例:

    { a:1,b:2,c:3 } -> [ {key:a,value:1},{key:b,value:2},{key:c,value:3} ]

    var data = {
      a:1,b:2,c:3
    }
    
    console.log(d3.entries(data));
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案2】:

      发布此问题后不久,我设法让它工作。我之前没有注意到,但事实证明该对象确实“变形”了。我通过在转换函数中执行 console.log(d) 而不是 console.log(d.LAT) 或 console.log(data.lat) 发现了这一点。

      它不是原来的 JSON 格式,而是变成这样的:

       {[key,value: {["LAT": "123", "LONG":567]}
      ]}
       {[key,value: {["LAT": "123", "LONG":567]}
      ]}
      

      所以我需要的对象可以通过以下方式访问:d.value.LAT

        function transform (d) {
              console.log(d); //TEST HERE
              var googleCoordinates = new google.maps.LatLng(d.value.LAT, d.value.LONG);
              var pos = projection.fromLatLngToDivPixel(googleCoordinates);
              return d3.select(this)
                .style("left", (pos.x - padding) + "px")
                .style("top", (pos.y - padding) + "px");
                //.attr('fill', color(d.value[2]))     
            }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 2013-05-14
        • 1970-01-01
        • 1970-01-01
        • 2016-12-14
        • 1970-01-01
        相关资源
        最近更新 更多