d3谷歌地图上的图表与节点之间的链接 [英] d3 graphs on google maps with link between nodes

查看:266
本文介绍了d3谷歌地图上的图表与节点之间的链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的要求是在google地图上显示d3图表,其中有多个节点以及它们之间的链接。我试过下面的代码段。但它根本不工作。

 <!DOCTYPE html> 
< html>
< head>
< meta name =viewportcontent =initial-scale = 1.0,user-scalable = no/>
< script src =https://maps.googleapis.com/maps/api/js?v=3.exp>< / script>
< script src =http://d3js.org/topojson.v1.min.js>< / script>
< script src =// code.jquery.com/jquery-1.10.2.js\"> ;</script>
< script src =https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js> < / script>
< style type =text / css>
html,
body,
#map {
width:100%;
height:100%;
margin:0;
padding:0;
}

.stations,
.stations svg {
position:absolute;
margin:0 auto;
}

.links {
position:absolute;
}

.stations svg {
width:20px;
height:20px;
margin:0 auto;
z-index:4;
}

.stations circle {
fill:blue;
stroke:none;
stroke-width:1px;
}
< / style>
< / head>
< body>
< div id =map>< / div>
< script type =text / javascript>
var map = new google.maps.Map(d3.select(#map)。node(),{
zoom:7,
center:new google.maps.LatLng -22.1629209,-47.9922608),
mapTypeId:google.maps.MapTypeId.MAP
});

var dataset = JSON.parse('{directed:true,graph:[],nodes:[{lat:44.391643516091975,lng:23.159677682342053} lat:44.315988,lng:23.818359,id:a:a ::},{lat:44.29844994776969,lng:24.402314492323608,id:b: lat:44.351118152120485,lng:23.341791630955303,id:a:c},{lat:44.889424527442685,lng:23.960970697645276,id:e:d},{lat :43.46084400349923,lng:23.975774627524885,id:d:6104:1},{lat:44.64680010013528,lng:23.20292820976948,id:c:6104: lat:44.40446080879215,lng:23.953536570796015,id:b:6104:3},{lat:44.18593375168617,lng:23.769879901486856,id:af:6104:4} ,{lat:44.09051846584001,lng:24.14130778735744},{lat:44.66376251969314,lng:23.77379490100736},{lat:44.6240449587762,lng:24.08347249542858,id:aaaa3bab:3d :6f06},{lat:45.00138334367271,lng:24.092331272179138,id:aaaa3bab:3d:1306},{lat:44.55033831045195,lng:24.312914121854526,id:aaaa3bab :3c:ef05},{lat:44.74421652327631,lng:24.728457702115804,id:aaaa3bab:3c:ea03},{lat:43.79401723931746,lng:23.77846416630604,id aaaa3bab:3d:7200},{lat:43.67351687345779,lng:23.00140978137842,id:aaaa3bab:3d:5d07},{lat:43.87692500855015,lng:24.28543591328852,id :aaaa3bab:3d:550b},{lat:44.28189405244278,lng:23.972410391551893,id:aaaa3bab:3d:2706},{lat:43.94916218711252,lng:23.9733463072956} ,{lat:44.61479884874806,lng:24.27581898293906},{lat:44.92223011339065,lng:23.505887513934034},{lat:44.20117807597118,lng:23.70555450810448,id:aaaa3bab:3d :2603},{lat:43.547714841247966,lng:24.56985383484244,id:aaaa3bab:3d:2601},{lat:43.92116991202797,lng:22.82805535024416,id:aaaa3bab :3d:5803},{lat:44.56587414638437,lng:22.970799697228976,id:aaaa3bab:3d:7406},{lat:44.10230727065641,lng:23.701204095342597,id aaaa3bab:3d:7407},{lat:45.25416535851712,lng:24.434312172789625,id:aaaa3bab:3d:7404},{lat:44.91647619491961,lng:23.678252259828515, :aaaa3bab:3d:7405},{lat:45.03473433359779,lng:24.07596179597473},{lat:45.16855171992733,lng:23.435986773864467},{lat:44.553669079256146,lng 23.05123326220677},{lat:43.32871087231798,lng:23.325707869122013,id:aaaa3bab:3d:5308},{lat:43.40444516345915,lng:23.485798521785892,id:aaaa3bab:3c :f107},{lat:43.9435337313432,lng:22.968285824722354},{lat:44.74549949495889,lng:22.832034225254052},{lat:44.34901730307382,lng:24.33506529636527} :43.53125851464172,lng:24.763229039168245,id:aaaa3bab:3d:6602},{lat:44.155575603194634,lng:23.250881840942217,id:aaaa3bab:3c:e300 links:[{source:1,target:25},{source:1,target:26},{source:1,target:27} :1,target:28},{source:1,target:29},{source:1,target:30} 31,{source:1,target:36},{source:1,target:34},{source:1,target:35} 3target:5},{source:3,target:6},{source:4,target:15} ,{source:5,target:19},{source:5,target:23},{source:6,target:18} target:20},{source:7,target:22},{source:8,target:37} source:10,target:11},{source:17,target:21},{source:18,target:13} :14},{source:19,target:33},{source:19,target:38},{source:23,target:2} :25,target:10},{source:28,target:4},{source:28,target:17} 32},{source:32,target:25},{source:34,target:24},{source:35,target:8} 35,target:16},{source:37,target:7},{source:37,target:12}],multigraph:false}

d3.json(dataset,function(json){
var overlay = new google.maps.OverlayView();

//添加容器覆盖被添加到地图
overlay.onAdd = function(){

var layer = d3.select(this.getPanes()。overlayLayer)
.append div)
.attr(height,100%)
.attr(width,100%)
.attr(class,stations) ;
overlay.draw = function(){
var radius = 5;
var projection = this.getProjection(),
padding = 10;
$ b b
var node_coord = {};

var marker = layer.selectAll(svg)
.data(d3.entries(dataset))
.each (transform)//更新现有标记
.enter()。append(svg:svg)
.each(transform)
.attr(class,marker);
mark.append(svg:circle)
.attr(r,radius)
.attr(cx,padding)
.attr ,padding);


var markerLink = layer.selectAll(。links)
.data(d3.entries(dataset))
.each(pathTransform)// update现有标记
.enter()。append(svg:svg)
.attr(class,links)
.each(pathTransform);

function pathTransform(d){
var t,b,l,r,w,h,currentSvg;
var d1 = new Object();
var d2 = new Object();
$(this).empty();
d1.x = node_coord [d.source +,+ 0]
d1.y = node_coord [d.source +,+ 1]
d2.x = node_coord [ d.target +,+ 0]
d2.y = node_coord [d.target +,+ 1]

if(d1.y t = d1.y;
b = d2.y;
} else {
t = d2.y;
b = d1.y;
}
if(d1.x l = d1.x;
r = d2.x;
} else {
l = d2.x;
r = d1.x;
}
currentSvg = d3.select(this)
.style(z-index,1)
.style(left,(l + 2 *半径)+px)
.style(top,(t + 2 * radius)+px)
.style +px)
.style(height,(b - t + 2 * radius)+px);


var x1 = 0,y1 = 0,x2 = 0,y2 = 0;
if((d1.y< d2.y)&&(d1.x< d2.x)){
x2 = r-l;
y2 = b-t;
} else if((d1.x> d2.x)&&(d1.y> d2.y)){
x2 = r-1;
y2 = b-t;
} else if((d1.y< d2.y)&&(d1.x> d2.x)){
x1 = r-l;
y2 = b-t;
} else if((d1.x< d2.x)&&(d1.y> d2.y)){
x1 = r-l;
y2 = b-t;
}
currentSvg.append(svg:line)
.style(stroke-width,2)
.style(stroke,black)
.attr(x1,x1)
.attr(y1,y1)
.attr(x2,x2)
.attr );

return currentSvg;
}

function transform(d,i){
d = new google.maps.LatLng(d.lat,d.lng);
d = projection.fromLatLngToDivPixel(d);

node_coord [i +,+ 0] = d.x;
node_coord [i +,+ 1] = d.y;

return d3.select(this)
.style(left,(dx)+px)
.style px);
}
layer.append(div)
.attr(class,stations.line);

};

};

//将我们的叠加层绑定到地图...
overlay.setMap(map);
});



仅绘制节点的

解决方案

您的代码中有错误。绑定到链接和节点的数据集不正确。您必须将节点数组设置为节点元素和到链接元素的链接数组。



  var marker = layer.selectAll(svg)
.data(d3.entries(dataset))//替换这行
。 each(transform)
.enter()。append(svg:svg)
.each(transform)
.attr(class,marker);

mark.append(svg:circle)
.attr(r,radius)
.attr(cx,padding)
.attr (cy,padding);

var markerLink = layer.selectAll(。links)
.data(d3.entries(dataset))//替换这行
.each(pathTransform)
.enter()。append(svg:svg)
.attr(class,links)
.each(pathTransform);

使用以下代码。

  var marker = layer.selectAll(svg)
.data(dataset.nodes)
.each(transform)//更新现有标记
.enter ).append(svg:svg)
.each(transform)
.attr(class,marker);
mark.append(svg:circle)
.attr(r,radius)
.attr(cx,padding)
.attr ,padding);

var markerLink = layer.selectAll(。links)
.data(dataset.links)
.each(pathTransform)//更新现有标记
。 enter()。append(svg:svg)
.attr(class,links)
.each(pathTransform);

工作代码段



  var map = new google.maps.Map(d3.select(#map)。node(),{zoom:7,center:new google。 maps.LatLng(-22.1629209,-47.9922608),mapTypeId:google.maps.MapTypeId.MAP}); var dataset = JSON.parse('{directed:true,graph:[],nodes:[{lat:44.391643516091975,lng:23.159677682342053},{lat:44.315988,lng :23.818359,id:a:a ::},{lat:44.29844994776969,lng:24.402314492323608,id:b:b},{lat:44.351118152120485,lng :23.341791630955303,id:a:c},{lat:44.889424527442685,lng:23.960970697645276,id:e:d},{lat:43.46084400349923,lng 23.975774627524885,id:d:6104:1},{lat:44.64680010013528,lng:23.20292820976948,id:c:6104:2},{lat:44.40446080879215, :23.953536570796015,id:b:6104:3},{lat:44.18593375168617,lng:23.769879901486856,id:af:6104:4},{lat:44.09051846584001, lng:24.14130778735744},{lat:44.66376251969314,lng:23.77379490100736},{lat:44.6240449587762,lng:24.08347249542858,id:aaaa3bab:3d:6f06},{lat :45.00138334367271,lng:24.092331272179138,id:aaaa3bab:3d:1306},{lat:44.55033831045195,lng:24.312914121854526,id:aaaa3bab:3c:ef05 lat:44.74421652327631,lng:24.728457702115804,id:aaaa3bab:3c:ea03},{lat:43.79401723931746,lng:23.77846416630604,id:aaaa3bab:3d:7200} ,{lat:43.67351687345779,lng:23.00140978137842,id:aaaa3bab:3d:5d07},{lat:43.87692500855015,lng:24.28543591328852,id:aaaa3bab:3d:550b },{lat:44.28189405244278,lng:23.972410391551893,id:aaaa3bab:3d:2706},{lat:43.94916218711252,lng:23.9733463072956},{lat:44.61479884874806, lng:24.27581898293906},{lat:44.92223011339065,lng:23.505887513934034},{lat:44.20117807597118,lng:23.70555450810448,id:aaaa3bab:3d:2603},{lat :43.547714841247966,lng:24.56985383484244,id:aaaa3bab:3d:2601},{lat:43.92116991202797,lng:22.82805535024416,id:aaaa3bab:3d:5803},{ lat:44.56587414638437,lng:22.970799697228976,id:aaaa3bab:3d:7406},{lat:44.10230727065641,lng:23.701204095342597,id:aaaa3bab:3d:7407} ,{lat:45.25416535851712,lng:24.434312172789625,id:aaaa3bab:3d:7404},{lat:44.91647619491961,lng:23.678252259828515,id:aaaa3bab:3d:7405 },{lat:45.03473433359779,lng:24.07596179597473},{lat:45.16855171992733,lng:23.435986773864467},{lat:44.553669079256146,lng:23.05123326220677},{lat: 43.32871087231798,lng:23.325707869122013,id:aaaa3bab:3d:5308},{lat:43.40444516345915,lng:23.485798521785892,id:aaaa3bab:3c:f107},{lat :43.9435337313432,lng:22.968285824722354},{lat:44.74549949495889,lng:22.832034225254052},{lat:44.34901730307382,lng:24.33506529636527},{lat:43.53125851464172,lng 24.763229039168245,id:aaaa3bab:3d:6602},{lat:44.155575603194634,lng:23.250881840942217,id:aaaa3bab:3c:e300}] :1,target:25},{source:1,target:26},{source:1,target:27} 28},{source:1,target:29},{source:1,target:30},{source:1,target:31} 1,target:34},{source:1,target:35},{source:1,target:36} ,{source:3,target:6},{source:4,target:15},{source:4,target:9} target:19},{source:5,target:23},{source:6,target:18} source:7,target:22},{source:8,target:37},{source:8,target:3} :11},{source:17,target:21},{source:18,target:13},{source:18,target:14} :19:target:33},{source:19,target:38},{source:23,target:2} 10},{source:28,target:4},{source:28,target:17},{source:29,target:32} 32,target:25},{source:34,target:24},{source:35,target:8} ,{source:37,target:7},{source:37,target:12}],multigraph:false} d3.json(dataset,function(json){var overlay = new google.maps.OverlayView(); //将叠加层添加到地图时添加容器overlay.onAdd = function(){var layer = d3。选择(this.getPanes()。overlayLayer).append(div).attr(height,100%).attr(width,100%).attr(class,stations ; overlay.draw = function(){var radius = 5; var projection = this.getProjection(),padding = 10; var node_coord = {}; var marker = layer.selectAll(svg).data .nodes).each(transform)//更新现有标记.enter()。append(svg:svg).each(transform).attr(class,marker); marker.append(svg:圆).attr(r,radius).attr(cx,padding).attr(cy,padding); var markerLink = layer.selectAll(。links).data(dataset.links) .each(pathTransform)//更新现有标记.enter()。append(svg:svg).attr(class,links)。 function pathTransform(d){var t,b,l,r,w,h,currentSvg; var d1 = new Object(); var d2 = new Object(); $(this).empty(); d1.x = node_coord [d.source +,+ 0] d1.y = node_coord [d.source +,+ 1] d2.x = node_coord [d.target +,+ 0] y = node_coord [d.target +,+ 1] if(d1.y  d2.x)&&(d1.y> d2.y)){x2 = r-1; y2 = b-t; } else if((d1.y< d2.y)&&(d1.x> d2.x)){x1 = r-1; y2 = b-t; } else if((d1.x< d2.x)&&(d1.y> d2.y)){x1 = r-1; y2 = b-t; } currentSvg.append(svg:line).style(stroke-width,2).style(stroke,black).attr(x1,x1).attr(y1,y1 ).attr(x2,x2).attr(y2,y2); return currentSvg; } function transform(d,i){console.log(here); d = new google.maps.LatLng(d.lat,d.lng); d = projection.fromLatLngToDivPixel(d); node_coord [i +,+ 0] = d.x; node_coord [i +,+ 1] = d.y; return d3.select(this).style(left,(d.x)+px).style(top,(d.y)+px); } layer.append(div).attr(class,stations.line); }; }; //将我们的叠加层绑定到地图上... overlay.setMap(map); };;  

  html,body,#map {width: 100%;高度:100%; margin:0; padding:0;}。stations,.stations svg {position:absolute; margin:0 auto;}。links {position:absolute;}。svg {width:20px; height:20px; margin:0 auto; z-index:4;}。中风:无; stroke-width:1px;}  

 < head& < meta name =viewportcontent =initial-scale = 1.0,user-scalable = no/> < script src =https://maps.googleapis.com/maps/api/js?v=3.exp>< / script> < script src =http://d3js.org/topojson.v1.min.js>< / script> < script src =// code.jquery.com/jquery-1.10.2.js\"> ;</script> < script src =https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js> < / script>< / head>< body> < div id =map>< / div>  


My Requirement is to show the d3 graphs on google maps with multiple nodes and links between them. i have tried the following snippet. But it is not at all working.

<!DOCTYPE html>
<html> 
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js">        </script>
<style type="text/css">
html,
body,
#map {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

.stations,
.stations svg {
    position: absolute;
    margin: 0 auto;
}

.links {
    position: absolute;
}

.stations svg {
    width: 20px;
    height: 20px;
    margin: 0 auto;
    z-index: 4;
}

.stations circle {
    fill: blue;
    stroke: none;
    stroke-width: 1px;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
         var map = new google.maps.Map(d3.select("#map").node(), {
        zoom: 7,
        center: new google.maps.LatLng(-22.1629209, -47.9922608),
        mapTypeId: google.maps.MapTypeId.MAP
      });

var dataset = JSON.parse('{"directed": true, "graph": [], "nodes": [{"lat": 44.391643516091975, "lng": 23.159677682342053}, {"lat": 44.315988, "lng": 23.818359, "id": "a:a::"},  {"lat": 44.29844994776969, "lng": 24.402314492323608, "id": "b:b"},  {"lat": 44.351118152120485, "lng": 23.341791630955303, "id": "a:c"},  {"lat": 44.889424527442685, "lng": 23.960970697645276, "id": "e:d"},  {"lat": 43.46084400349923, "lng": 23.975774627524885, "id": "d:6104:1"},  {"lat": 44.64680010013528, "lng": 23.20292820976948, "id": "c:6104:2"},  {"lat": 44.40446080879215, "lng": 23.953536570796015, "id": "b:6104:3"},  {"lat": 44.18593375168617, "lng": 23.769879901486856, "id": "af:6104:4"},  {"lat": 44.09051846584001, "lng": 24.14130778735744},  {"lat": 44.66376251969314, "lng": 23.77379490100736},  {"lat": 44.6240449587762, "lng": 24.08347249542858, "id": "aaaa3bab:3d:6f06"},  {"lat": 45.00138334367271, "lng": 24.092331272179138, "id": "aaaa3bab:3d:1306"},  {"lat": 44.55033831045195, "lng": 24.312914121854526, "id": "aaaa3bab:3c:ef05"},  {"lat": 44.74421652327631, "lng": 24.728457702115804, "id": "aaaa3bab:3c:ea03"},  {"lat": 43.79401723931746, "lng": 23.77846416630604, "id": "aaaa3bab:3d:7200"},  {"lat": 43.67351687345779, "lng": 23.00140978137842, "id": "aaaa3bab:3d:5d07"},  {"lat": 43.87692500855015, "lng": 24.28543591328852, "id": "aaaa3bab:3d:550b"},  {"lat": 44.28189405244278, "lng": 23.972410391551893, "id": "aaaa3bab:3d:2706"},  {"lat": 43.94916218711252, "lng": 23.9733463072956},  {"lat": 44.61479884874806, "lng": 24.27581898293906},  {"lat": 44.92223011339065, "lng": 23.505887513934034},  {"lat": 44.20117807597118, "lng": 23.70555450810448, "id": "aaaa3bab:3d:2603"},  {"lat": 43.547714841247966, "lng": 24.56985383484244, "id": "aaaa3bab:3d:2601"},  {"lat": 43.92116991202797, "lng": 22.82805535024416, "id": "aaaa3bab:3d:5803"},  {"lat": 44.56587414638437, "lng": 22.970799697228976, "id": "aaaa3bab:3d:7406"},  {"lat": 44.10230727065641, "lng": 23.701204095342597, "id": "aaaa3bab:3d:7407"},  {"lat": 45.25416535851712, "lng": 24.434312172789625, "id": "aaaa3bab:3d:7404"},  {"lat": 44.91647619491961, "lng": 23.678252259828515, "id": "aaaa3bab:3d:7405"},  {"lat": 45.03473433359779, "lng": 24.07596179597473},  {"lat": 45.16855171992733, "lng": 23.435986773864467},  {"lat": 44.553669079256146, "lng": 23.05123326220677},  {"lat": 43.32871087231798, "lng": 23.325707869122013, "id": "aaaa3bab:3d:5308"},  {"lat": 43.40444516345915, "lng": 23.485798521785892, "id": "aaaa3bab:3c:f107"},  {"lat": 43.9435337313432, "lng": 22.968285824722354},  {"lat": 44.74549949495889, "lng": 22.832034225254052},  {"lat": 44.34901730307382, "lng": 24.33506529636527},  {"lat": 43.53125851464172, "lng": 24.763229039168245, "id": "aaaa3bab:3d:6602"},  {"lat": 44.155575603194634, "lng": 23.250881840942217, "id": "aaaa3bab:3c:e300"}], "links": [ {"source": 1, "target": 25},  {"source": 1, "target": 26},  {"source": 1, "target": 27},  {"source": 1, "target": 28},  {"source": 1, "target": 29},  {"source": 1, "target": 30},  {"source": 1, "target": 31},  {"source": 1, "target": 34},  {"source": 1, "target": 35},  {"source": 1, "target": 36},  {"source": 3, "target": 5},  {"source": 3, "target": 6},  {"source": 4, "target": 15},  {"source": 4, "target": 9},  {"source": 5, "target": 19},  {"source": 5, "target": 23},  {"source": 6, "target": 18},  {"source": 6, "target": 20},  {"source": 7, "target": 22},  {"source": 8, "target": 37},  {"source": 8, "target": 3},  {"source": 10, "target": 11},  {"source": 17, "target": 21}, {"source": 18, "target": 13}, {"source": 18, "target": 14}, {"source": 19, "target": 33}, {"source": 19, "target": 38}, {"source": 23, "target": 2}, {"source": 25, "target": 10}, {"source": 28, "target": 4}, {"source": 28, "target": 17}, {"source": 29, "target": 32}, {"source": 32, "target": 25}, {"source": 34, "target": 24}, {"source": 35, "target": 8}, {"source": 35, "target": 16}, {"source": 37, "target": 7}, {"source": 37, "target": 12}], "multigraph": false}');

 d3.json(dataset, function (json) {
    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().overlayLayer)
            .append("div")
            .attr("height", "100%")
            .attr("width", "100%")
            .attr("class", "stations");
        overlay.draw = function () {
            var radius = 5;
            var projection = this.getProjection(),
                padding = 10;


            var node_coord = {};

            var marker = layer.selectAll("svg")
                .data(d3.entries(dataset))
                .each(transform) // update existing markers
                .enter().append("svg:svg")
                .each(transform)
                .attr("class", "marker");
            marker.append("svg:circle")
                .attr("r", radius)
                .attr("cx", padding)
                .attr("cy", padding);


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

            function pathTransform(d) {
                var t, b, l, r, w, h, currentSvg;
                var d1 = new Object();
                var d2 = new Object();
                $(this).empty();
                d1.x = node_coord[d.source + "," + 0]
                d1.y = node_coord[d.source + "," + 1]
                d2.x = node_coord[d.target + "," + 0]
                d2.y = node_coord[d.target + "," + 1]

                if (d1.y < d2.y) {
                    t = d1.y;
                    b = d2.y;
                } else {
                    t = d2.y;
                    b = d1.y;
                }
                if (d1.x < d2.x) {
                    l = d1.x;
                    r = d2.x;
                } else {
                    l = d2.x;
                    r = d1.x;
                }
                currentSvg = d3.select(this)
        .style("z-index", "1")
        .style("left", (l + 2 * radius) + "px")
                    .style("top", (t + 2 * radius) + "px")
                    .style("width", (r - l + 2 * radius) + "px")
                    .style("height", (b - t + 2 * radius) + "px");


                var x1 = 0, y1 = 0, x2 = 0, y2 = 0;
                if ((d1.y < d2.y) && (d1.x < d2.x)) {
                    x2 = r - l;
                    y2 = b - t;
                } else if ((d1.x > d2.x) && (d1.y > d2.y)) {
                    x2 = r - l;
                    y2 = b - t;
                } else if ((d1.y < d2.y) && (d1.x > d2.x)) {
                    x1 = r - l;
                    y2 = b - t;
                } else if ((d1.x < d2.x) && (d1.y > d2.y)) {
                    x1 = r - l;
                    y2 = b - t;
                }
                currentSvg.append("svg:line")
                        .style("stroke-width", 2)
                        .style("stroke", "black")
                        .attr("x1", x1)
                        .attr("y1", y1)
                        .attr("x2", x2)
                        .attr("y2", y2);

                return currentSvg;
            }

            function transform(d, i) {
                d = new google.maps.LatLng(d.lat, d.lng);
                d = projection.fromLatLngToDivPixel(d);

                node_coord[i + "," + 0] = d.x;
                node_coord[i + "," + 1] = d.y;

                return d3.select(this)
                    .style("left", (d.x) + "px")
                    .style("top", (d.y) + "px");
            }
            layer.append("div")
                .attr("class", "stations.line");

        };

    };

    // Bind our overlay to the map…
    overlay.setMap(map);
});

when i tried to implement the example which plots only the nodes, It works well. But i need to create a link between those nodes using the source and target details in the link object.

Need to show the kind of graph (attached) over google maps. where each node represents location.

解决方案

There is an error in your code. The dataset bonded to the links and nodes are not correct. You have to set the array of nodes to the node elements and array of links to the link elements.

Instead of following code,

 var marker = layer.selectAll("svg")
   .data(d3.entries(dataset)) //Replace this line
   .each(transform) 
   .enter().append("svg:svg")
   .each(transform)
   .attr("class", "marker");

 marker.append("svg:circle")
   .attr("r", radius)
   .attr("cx", padding)
   .attr("cy", padding);   

 var markerLink = layer.selectAll(".links")
   .data(d3.entries(dataset)) //Replace this line
   .each(pathTransform)
   .enter().append("svg:svg")
   .attr("class", "links")
   .each(pathTransform);

use following code.

var marker = layer.selectAll("svg")
   .data(dataset.nodes) 
   .each(transform) // update existing markers
   .enter().append("svg:svg")
   .each(transform)
   .attr("class", "marker");
 marker.append("svg:circle")
   .attr("r", radius)
   .attr("cx", padding)
   .attr("cy", padding);

 var markerLink = layer.selectAll(".links")
   .data(dataset.links)
   .each(pathTransform) // update existing markers       
   .enter().append("svg:svg")
   .attr("class", "links")
   .each(pathTransform);

Working code snippet:

var map = new google.maps.Map(d3.select("#map").node(), {
    zoom: 7,
    center: new google.maps.LatLng(-22.1629209, -47.9922608),
    mapTypeId: google.maps.MapTypeId.MAP
  });

  var dataset = JSON.parse('{"directed": true, "graph": [], "nodes": [{"lat": 44.391643516091975, "lng": 23.159677682342053}, {"lat": 44.315988, "lng": 23.818359, "id": "a:a::"},  {"lat": 44.29844994776969, "lng": 24.402314492323608, "id": "b:b"},  {"lat": 44.351118152120485, "lng": 23.341791630955303, "id": "a:c"},  {"lat": 44.889424527442685, "lng": 23.960970697645276, "id": "e:d"},  {"lat": 43.46084400349923, "lng": 23.975774627524885, "id": "d:6104:1"},  {"lat": 44.64680010013528, "lng": 23.20292820976948, "id": "c:6104:2"},  {"lat": 44.40446080879215, "lng": 23.953536570796015, "id": "b:6104:3"},  {"lat": 44.18593375168617, "lng": 23.769879901486856, "id": "af:6104:4"},  {"lat": 44.09051846584001, "lng": 24.14130778735744},  {"lat": 44.66376251969314, "lng": 23.77379490100736},  {"lat": 44.6240449587762, "lng": 24.08347249542858, "id": "aaaa3bab:3d:6f06"},  {"lat": 45.00138334367271, "lng": 24.092331272179138, "id": "aaaa3bab:3d:1306"},  {"lat": 44.55033831045195, "lng": 24.312914121854526, "id": "aaaa3bab:3c:ef05"},  {"lat": 44.74421652327631, "lng": 24.728457702115804, "id": "aaaa3bab:3c:ea03"},  {"lat": 43.79401723931746, "lng": 23.77846416630604, "id": "aaaa3bab:3d:7200"},  {"lat": 43.67351687345779, "lng": 23.00140978137842, "id": "aaaa3bab:3d:5d07"},  {"lat": 43.87692500855015, "lng": 24.28543591328852, "id": "aaaa3bab:3d:550b"},  {"lat": 44.28189405244278, "lng": 23.972410391551893, "id": "aaaa3bab:3d:2706"},  {"lat": 43.94916218711252, "lng": 23.9733463072956},  {"lat": 44.61479884874806, "lng": 24.27581898293906},  {"lat": 44.92223011339065, "lng": 23.505887513934034},  {"lat": 44.20117807597118, "lng": 23.70555450810448, "id": "aaaa3bab:3d:2603"},  {"lat": 43.547714841247966, "lng": 24.56985383484244, "id": "aaaa3bab:3d:2601"},  {"lat": 43.92116991202797, "lng": 22.82805535024416, "id": "aaaa3bab:3d:5803"},  {"lat": 44.56587414638437, "lng": 22.970799697228976, "id": "aaaa3bab:3d:7406"},  {"lat": 44.10230727065641, "lng": 23.701204095342597, "id": "aaaa3bab:3d:7407"},  {"lat": 45.25416535851712, "lng": 24.434312172789625, "id": "aaaa3bab:3d:7404"},  {"lat": 44.91647619491961, "lng": 23.678252259828515, "id": "aaaa3bab:3d:7405"},  {"lat": 45.03473433359779, "lng": 24.07596179597473},  {"lat": 45.16855171992733, "lng": 23.435986773864467},  {"lat": 44.553669079256146, "lng": 23.05123326220677},  {"lat": 43.32871087231798, "lng": 23.325707869122013, "id": "aaaa3bab:3d:5308"},  {"lat": 43.40444516345915, "lng": 23.485798521785892, "id": "aaaa3bab:3c:f107"},  {"lat": 43.9435337313432, "lng": 22.968285824722354},  {"lat": 44.74549949495889, "lng": 22.832034225254052},  {"lat": 44.34901730307382, "lng": 24.33506529636527},  {"lat": 43.53125851464172, "lng": 24.763229039168245, "id": "aaaa3bab:3d:6602"},  {"lat": 44.155575603194634, "lng": 23.250881840942217, "id": "aaaa3bab:3c:e300"}], "links": [ {"source": 1, "target": 25},  {"source": 1, "target": 26},  {"source": 1, "target": 27},  {"source": 1, "target": 28},  {"source": 1, "target": 29},  {"source": 1, "target": 30},  {"source": 1, "target": 31},  {"source": 1, "target": 34},  {"source": 1, "target": 35},  {"source": 1, "target": 36},  {"source": 3, "target": 5},  {"source": 3, "target": 6},  {"source": 4, "target": 15},  {"source": 4, "target": 9},  {"source": 5, "target": 19},  {"source": 5, "target": 23},  {"source": 6, "target": 18},  {"source": 6, "target": 20},  {"source": 7, "target": 22},  {"source": 8, "target": 37},  {"source": 8, "target": 3},  {"source": 10, "target": 11},  {"source": 17, "target": 21}, {"source": 18, "target": 13}, {"source": 18, "target": 14}, {"source": 19, "target": 33}, {"source": 19, "target": 38}, {"source": 23, "target": 2}, {"source": 25, "target": 10}, {"source": 28, "target": 4}, {"source": 28, "target": 17}, {"source": 29, "target": 32}, {"source": 32, "target": 25}, {"source": 34, "target": 24}, {"source": 35, "target": 8}, {"source": 35, "target": 16}, {"source": 37, "target": 7}, {"source": 37, "target": 12}], "multigraph": false}');

  d3.json(dataset, function(json) {
    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().overlayLayer)
        .append("div")
        .attr("height", "100%")
        .attr("width", "100%")
        .attr("class", "stations");
      overlay.draw = function() {
        var radius = 5;
        var projection = this.getProjection(),
          padding = 10;


        var node_coord = {};

        var marker = layer.selectAll("svg")
          .data(dataset.nodes)
          .each(transform) // update existing markers
          .enter().append("svg:svg")
          .each(transform)
          .attr("class", "marker");
        marker.append("svg:circle")
          .attr("r", radius)
          .attr("cx", padding)
          .attr("cy", padding);


        var markerLink = layer.selectAll(".links")
          .data(dataset.links)
          .each(pathTransform) // update existing markers       
          .enter().append("svg:svg")
          .attr("class", "links")
          .each(pathTransform);

        function pathTransform(d) {
          var t, b, l, r, w, h, currentSvg;
          var d1 = new Object();
          var d2 = new Object();
          $(this).empty();
          d1.x = node_coord[d.source + "," + 0]
          d1.y = node_coord[d.source + "," + 1]
          d2.x = node_coord[d.target + "," + 0]
          d2.y = node_coord[d.target + "," + 1]

          if (d1.y < d2.y) {
            t = d1.y;
            b = d2.y;
          } else {
            t = d2.y;
            b = d1.y;
          }
          if (d1.x < d2.x) {
            l = d1.x;
            r = d2.x;
          } else {
            l = d2.x;
            r = d1.x;
          }
          currentSvg = d3.select(this)
            .style("z-index", "1")
            .style("left", (l + 2 * radius) + "px")
            .style("top", (t + 2 * radius) + "px")
            .style("width", (r - l + 2 * radius) + "px")
            .style("height", (b - t + 2 * radius) + "px");


          var x1 = 0,
            y1 = 0,
            x2 = 0,
            y2 = 0;
          if ((d1.y < d2.y) && (d1.x < d2.x)) {
            x2 = r - l;
            y2 = b - t;
          } else if ((d1.x > d2.x) && (d1.y > d2.y)) {
            x2 = r - l;
            y2 = b - t;
          } else if ((d1.y < d2.y) && (d1.x > d2.x)) {
            x1 = r - l;
            y2 = b - t;
          } else if ((d1.x < d2.x) && (d1.y > d2.y)) {
            x1 = r - l;
            y2 = b - t;
          }
          currentSvg.append("svg:line")
            .style("stroke-width", 2)
            .style("stroke", "black")
            .attr("x1", x1)
            .attr("y1", y1)
            .attr("x2", x2)
            .attr("y2", y2);

          return currentSvg;
        }

        function transform(d, i) {
          console.log("here");
          d = new google.maps.LatLng(d.lat, d.lng);
          d = projection.fromLatLngToDivPixel(d);

          node_coord[i + "," + 0] = d.x;
          node_coord[i + "," + 1] = d.y;

          return d3.select(this)
            .style("left", (d.x) + "px")
            .style("top", (d.y) + "px");
        }
        layer.append("div")
          .attr("class", "stations.line");

      };

    };

    // Bind our overlay to the map…
    overlay.setMap(map);
  });

html,
body,
#map {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
.stations,
.stations svg {
  position: absolute;
  margin: 0 auto;
}
.links {
  position: absolute;
}
.stations svg {
  width: 20px;
  height: 20px;
  margin: 0 auto;
  z-index: 4;
}
.stations circle {
  fill: blue;
  stroke: none;
  stroke-width: 1px;
}

<head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
  <script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
  <script src="http://d3js.org/topojson.v1.min.js"></script>
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js">
  </script>
</head>

<body>
  <div id="map"></div>

这篇关于d3谷歌地图上的图表与节点之间的链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆