【问题标题】:Using Googlemaps HeatmapLayer with in D3在 D3 中使用 Googlemaps HeatmapLayer
【发布时间】:2018-04-17 03:30:43
【问题描述】:

我正在尝试在我的 D3 可视化中使用 Google 地图热图图层。我跟着Mike Bostock's example 在 D3 内创建了一个谷歌地图图层,并使用我的数据文件添加了标记。然后我尝试将其扩展为使用 Google 地图中的热图图层,而不是标记上的简单圆圈。我不知道这段代码有什么问题,我不明白我得到的错误 (Uncaught TypeError: Cannot read property 'NaN' of undefined)。

var csvData = "lat,lon,temp1,temp2\n41.87148,-87.67644,6.68,39.8\n41.880497,-87.745268,4.75,7.6\n41.910922,-87.649518,7.39,36.5\n41.866786,-87.666306,6.5,39\n41.751142,-87.71299,5.46,14.2\n41.786756,-87.664343,5.33,34.1\n41.808594,-87.665048,6.15,27.8\n41.666078,-87.539374,3.79,32\n41.823527,-87.641054,5.12,31.6\n41.946373,-87.727382,6.73,35.2\n41.751142,-87.71299,5.02,37.5\n41.764122,-87.72242,4.5,34\n41.903632,-87.648093,5.3,30.6\n41.713867,-87.536509,4.68,31.3\n41.800846,-87.703739,4.99,32.7\n41.918733,-87.668257,5.24,34\n41.83107,-87.617298,5.8,8.4\n41.92617,-87.631533,5.31,33.5\n41.794477,-87.615957,4.9,33.3\n41.906481,-87.671373,5.28,18.4\n41.741148,-87.54045,,\n41.891964,-87.611603,,\n41.858136, -87.616055,,\n41.857797,-87.685806,,\n41.881172,-87.686359,,\n41.954626,-87.645247,,"
var colorScale = d3.scale.linear().range(['blue', 'yellow']);

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

// Create the Google Map…
var map = new google.maps.Map(d3.select("#map").node(), {
  zoom: 10,
  center: new google.maps.LatLng(41.83379085476929,-87.73212559320208),
  mapTypeId: google.maps.MapTypeId.TERRAIN
});

data=d3.csv.parse(csvData)
  var heatmapData = [];
  data.forEach(function(d){
	heatmapData.push(new google.maps.LatLng(d.lat, d.lng));
  });
  var heatmap = new google.maps.visualization.HeatmapLayer({
          data: heatmapData,
		  map: map
    });
  
  var max=d3.max(data, function(d) { return d.temp1; });
  var min=d3.min(data, function(d) { return d.temp1; });
  
  if(max>0 && min>0){ min=-max;}
  if(max<0 && min<0){ max=-min;}
  
  colorScale.domain([min,max]);

  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", "nodes");
		
    overlay.draw = function() {
      var projection = this.getProjection(),
          padding = 10;

      var marker = layer.selectAll("svg")
          .data(data)
          .each(transform)
        .enter().append("svg")
          .each(transform)
          .attr("class", "marker")
		.on("mouseover", function(d) {
			tooltip.transition()
				 .duration(200)
				 .style("opacity", 1);
			tooltip.html(d.node_id)
				 .style("left", (d3.event.pageX) + "px")
				 .style("top", (d3.event.pageY) + "px");
		})
		.on("mouseout", function(d) {
			tooltip.transition()
				.duration(500)
				.style("opacity", 0);
		});

      
      marker.append("circle")
          .attr("r", 7)
          .attr("cx", padding)
          .attr("cy", padding)
		  .style("fill", function(d) { 
			if(d.temp1){
				return colorScale(d.temp1); 
				}
			else 
				return "none";
			});
		  
      
      marker.append("text")
          .attr("x", padding + 7)
          .attr("y", padding)
          .attr("dy", ".31em")
          .text(function(d) { return d.temp1; });

      function transform(d) {
        d = new google.maps.LatLng(d.lat, d.lon);
        d = projection.fromLatLngToDivPixel(d);
        return d3.select(this)
            .style("left", (d.x - padding) + "px")
            .style("top", (d.y - padding) + "px");
      }
    };
  };

  overlay.setMap(map);
html, body, #map {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.nodes, .nodes svg {
  position: absolute;
}

.nodes svg {
  width: 60px;
  height: 20px;
  padding-right: 100px;
  font: 10px sans-serif;
}

.nodes circle {
  stroke: black;
  stroke-width: 1px;
}

.tooltip {
    position: absolute;
    text-align: center;
	min-width: 200;
    width: auto;
	min-height:25;
    height: auto;
    padding: 2px;		
    font: 10px sans-serif;
    background: rgba(0, 0, 0, 0.8);
	color: #fff;
    border: 0px;
    border-radius: 8px;
    pointer-events: none;
}
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.10/d3.min.js"></script>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=visualization"></script>

【问题讨论】:

    标签: google-maps d3.js heatmap


    【解决方案1】:

    你的代码的错误是:

    Uncaught TypeError: Cannot read property 'NaN' of undefined

    您的代码中有错字。你传入d.lat/d.lon;但代码需要d.lat/d.lng。更改代码以使用d.lon 或更改对象以包含d.lng。 (你的代码不一致,它在热图中使用d.lng,在d3代码中使用d.lon

    更新的代码 sn-p(使用 d.lng 并在隐藏热图时删除 d3 标记):

    var csvData = "lat,lng,temp1,temp2\n41.87148,-87.67644,6.68,39.8\n41.880497,-87.745268,4.75,7.6\n41.910922,-87.649518,7.39,36.5\n41.866786,-87.666306,6.5,39\n41.751142,-87.71299,5.46,14.2\n41.786756,-87.664343,5.33,34.1\n41.808594,-87.665048,6.15,27.8\n41.666078,-87.539374,3.79,32\n41.823527,-87.641054,5.12,31.6\n41.946373,-87.727382,6.73,35.2\n41.751142,-87.71299,5.02,37.5\n41.764122,-87.72242,4.5,34\n41.903632,-87.648093,5.3,30.6\n41.713867,-87.536509,4.68,31.3\n41.800846,-87.703739,4.99,32.7\n41.918733,-87.668257,5.24,34\n41.83107,-87.617298,5.8,8.4\n41.92617,-87.631533,5.31,33.5\n41.794477,-87.615957,4.9,33.3\n41.906481,-87.671373,5.28,18.4\n41.741148,-87.54045,,\n41.891964,-87.611603,,\n41.858136, -87.616055,,\n41.857797,-87.685806,,\n41.881172,-87.686359,,\n41.954626,-87.645247,,"
    var colorScale = d3.scale.linear().range(['blue', 'yellow']);
    
    var tooltip = d3.select("#map").append("div")
      .attr("class", "tooltip")
      .style("opacity", 0);
    
    // Create the Google Map…
    var map = new google.maps.Map(d3.select("#map").node(), {
      zoom: 10,
      center: new google.maps.LatLng(41.83379085476929, -87.73212559320208),
      mapTypeId: google.maps.MapTypeId.TERRAIN
    });
    
    data = d3.csv.parse(csvData)
    var heatmapData = [];
    data.forEach(function(d) {
      heatmapData.push(new google.maps.LatLng(d.lat, d.lng));
    });
    var heatmap = new google.maps.visualization.HeatmapLayer({
      data: heatmapData,
      map: map
    });
    
    var max = d3.max(data, function(d) {
      return d.temp1;
    });
    var min = d3.min(data, function(d) {
      return d.temp1;
    });
    
    if (max > 0 && min > 0) {
      min = -max;
    }
    if (max < 0 && min < 0) {
      max = -min;
    }
    
    colorScale.domain([min, max]);
    
    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", "nodes");
    
      overlay.draw = function() {
        /* var projection = this.getProjection(),
          padding = 10;
    
        var marker = layer.selectAll("svg")
          .data(data)
          .each(transform)
          .enter().append("svg")
          .each(transform)
          .attr("class", "marker")
          .on("mouseover", function(d) {
            tooltip.transition()
              .duration(200)
              .style("opacity", 1);
            tooltip.html(d.node_id)
              .style("left", (d3.event.pageX) + "px")
              .style("top", (d3.event.pageY) + "px");
          })
          .on("mouseout", function(d) {
            tooltip.transition()
              .duration(500)
              .style("opacity", 0);
          });
    
    
        marker.append("circle")
          .attr("r", 7)
          .attr("cx", padding)
          .attr("cy", padding)
          .style("fill", function(d) {
            if (d.temp1) {
              return colorScale(d.temp1);
            } else
              return "none";
          });
    
    
        marker.append("text")
          .attr("x", padding + 7)
          .attr("y", padding)
          .attr("dy", ".31em")
          .text(function(d) {
            return d.temp1;
          });
    */
        function transform(d) {
          d = new google.maps.LatLng(d.lat, d.lng);
          d = projection.fromLatLngToDivPixel(d);
          return d3.select(this)
            .style("left", (d.x - padding) + "px")
            .style("top", (d.y - padding) + "px");
        }
      };
    };
    
    overlay.setMap(map);
    html,
    body,
    #map {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }
    
    .nodes,
    .nodes svg {
      position: absolute;
    }
    
    .nodes svg {
      width: 60px;
      height: 20px;
      padding-right: 100px;
      font: 10px sans-serif;
    }
    
    .nodes circle {
      stroke: black;
      stroke-width: 1px;
    }
    
    .tooltip {
      position: absolute;
      text-align: center;
      min-width: 200;
      width: auto;
      min-height: 25;
      height: auto;
      padding: 2px;
      font: 10px sans-serif;
      background: rgba(0, 0, 0, 0.8);
      color: #fff;
      border: 0px;
      border-radius: 8px;
      pointer-events: none;
    }
    <!DOCTYPE html>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.10/d3.min.js"></script>
    <div id="map"></div>
    <script src="https://maps.googleapis.com/maps/api/js?libraries=visualization"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      • 2016-09-08
      • 2016-01-25
      • 2014-09-15
      • 2017-08-31
      • 2017-12-21
      相关资源
      最近更新 更多