我制作了一张地图,其中显示了一些圆圈,单击时会显示线条。该地图叠加在传单底图上。 地图工作正常。这是我投影地图的方式:
d3.csv("going.csv", function(data) {
going = data;
d3.json("lor_migration.geojson", function(json) {
//Projection
transform = d3.geo.transform({
point: projectPoint
});
path = d3.geo.path().projection(transform);
function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
//Bind data and create one path per GeoJSON feature
var feature = g.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("id", function(d) {
return d.properties.state;
})
.attr("d", path)
.attr("stroke-width", 0.5)
.attr("fill-opacity", "0.5")
.style("stroke", "#666")
.style("fill", "#fff");
map.on("viewreset", reset);
reset();
//Reset function
function reset() {
var bounds = path.bounds(json);
topLeft = bounds[0],
bottomRight = bounds[1];
svg.attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
feature.attr("d", path);
}
以下是在地图上绘制圆圈的方式:
//Create circles for net migration
var circles = g.selectAll("circle")
.data(json.features)
.enter().append("circle")
.attr("cx", function(d) {
d.centroid = path.centroid(d);
return d.centroid[0];
})
.attr("cy", function(d) {
return d.centroid[1];
})
.attr("r", function(d) { //circle size
console.log("Value: " + value);
var diff = d.properties.total_imm - d.properties.total_emm;
return circleSize((Math.abs(diff)/Math.PI));
})
.attr("class", "circ")
.attr("id", function(d) {
return d.abbrev;
})
.attr("fill", function(d) { //circle color
var diff = d.properties.total_imm - d.properties.total_emm;
if (diff > 0) {
return "#65a89d";
}
else {
return "#a96a46";
}
})
.attr("fill-opacity", "0.5")
.attr("stroke", "#fff")
.attr("stroke-weight", "0.5")
.on("mouseover", function(d) {
return toolOver(d, this);
})
.on("mousemove", function(d) {
var m = d3.mouse(this);
mx = m[0];
my = m[1];
return toolMove(mx, my, d);
})
.on("mouseout", function(d) {
return toolOut(d, this);
})
.on("click", function(d) {
clicked(d)
});
这是各行的onclick函数:
function clicked(selected) {
var selname = selected.id;
var homex = selected.centroid[0];
var homey = selected.centroid[1];
g.selectAll(".goingline")
.attr("stroke-dasharray", 0)
.remove()
g.selectAll(".goingline")
.data(going)
.enter().append("path")
.attr("class", "goingline")
.attr("d", function(d, i) {
var finalval = coming[i][selname] - going[i][selname];
come = coming[i][selname];
go = going[i][selname];
try {
var theState = d3.select("#" + d.abbrev).datum();
if (!isNaN(finalval)) {
var startx = theState.centroid[0];
var starty = theState.centroid[1];
if (finalval > 0)
return "M" + startx + "," + starty + " Q" + (startx + homex) / 2 + " " + (starty + homey) / 1.5 + " " + homex + " " + homey;
else
return "M" + homex + "," + homey + " Q" + (startx + homex) / 2 + " " + (starty + homey) / 5 + " " + startx + " " + starty;
}
}
catch (err) {
console.log(err)
console.log('No datum found for ' + d.abbrev)
}
})
.call(transition)
.attr("stroke-width", function(d, i) {
var finalval = coming[i][selname] - going[i][selname];
return 0.75//(Math.abs(finalval));
})
.attr("stroke", function(d, i) {
var finalval = coming[i][selname] - going[i][selname];
if (finalval > 0) {
return "#65a89d";
}
else {
return "#a96a46";
}
})
.attr("fill", "none")
.attr("opacity", 0.5)
.attr("stroke-linecap", "round")
.on("mouseover", function(d) {
return toolOver2(d, this);
})
.on("mousemove", function(d, i) {
var m = d3.mouse(this);
mx = m[0];
my = m[1];
return toolMove2(mx, my, selname, d.state, coming[i][selname], going[i][selname]);
})
.on("mouseout", function(d) {
return toolOut2(d, this);
});
}
问题是投影不适用于圆和直线。您能提出一个解决方案吗? 谢谢
已编辑
:所以这是我尝试解决的问题:还有一些问题
//Create SVG element
var svg = d3.select(map.getPanes().overlayPane)
.append("svg")
var g = svg.append("g").attr("class", "leaflet-zoom-hide");
var svgCircles = svg.append("g").attr("class", "leaflet-zoom-hide");
var coming, going;
var by_name = {};
//Define the coming and going of csv
d3.csv("coming.csv", function(data) {
coming = data;
});
d3.csv("going.csv", function(data) {
going = data;
d3.json("lor_migration.geojson", function(json) {
//Projection
transform = d3.geo.transform({
point: projectPoint
});
path = d3.geo.path().projection(transform);
/* json.features.forEach(function(d) {
d.LatLng = new L.LatLng(d.geometry.coordinates[1], d.geometry.coordinates[0]);
});*/
function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
for (var i = 0; i < data.length; i++) {
by_name[ data[i].state ] = {};
for (var propt in data[i]) {
by_name[ data[i].state ][propt] = +data[i][propt];
}
by_name[ data[i].state ].abbrev = data[i].abbrev;
by_name[ data[i].state ].state = data[i].state;
}
//Find the corresponding state inside the GeoJSON
json.features.forEach( function (j) {
var jsonState = j.properties.name;
if ( by_name[jsonState] ) {
j.properties.state = by_name[jsonState].state;
j.id = by_name[jsonState].state;
j.abbrev = by_name[jsonState].abbrev;
j.properties.total_imm = by_name[jsonState].total_imm;
j.properties.total_emm = by_name[jsonState].total_emm;
}
else {
console.log('No data for ' + jsonState)
}
})
//Bind data and create one path per GeoJSON feature
var feature = g.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("id", function(d) {
return d.properties.state;
})
.attr("d", path)
.attr("stroke-width", 0.5)
.attr("fill-opacity", "0.5")
.style("stroke", "#666")
.style("fill", "#fff");
//Net migration circles
var circles = svgCircles.selectAll("circle")
.data(json.features)
.enter().append("circle")
.attr("cx", function(d) {
d.centroid = path.centroid(d);
return d.centroid[0];
})
.attr("cy", function(d) {
return d.centroid[1];
})
.attr("r", function(d) { //circle size
console.log("Value: " + value);
var diff = d.properties.total_imm - d.properties.total_emm;
// if (diff > 200){
return circleSize((Math.abs(diff)/Math.PI));
// }
})
.attr("class", "circ")
.attr("id", function(d) {
return d.abbrev;
})
.attr("fill", function(d) { //circle color
var diff = d.properties.total_imm - d.properties.total_emm;
if (diff > 0) {
return "#65a89d";
}
else {
return "#a96a46";
}
})
.attr("fill-opacity", "0.5")
.attr("stroke", "#fff")
.attr("stroke-weight", "0.5")
.on("mouseover", function(d) {
return toolOver(d, this);
})
.on("mousemove", function(d) {
var m = d3.mouse(this);
mx = m[0];
my = m[1];
return toolMove(mx, my, d);
})
.on("mouseout", function(d) {
return toolOut(d, this);
})
.on("click", function(d) {
clicked(d)
});
map.on("viewreset", reset);
reset();
//Reset function
function reset() {
var bounds = path.bounds(json);
topLeft = bounds[0],
bottomRight = bounds[1];
svg.attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
feature.attr("d", path);
circles.attr("cx", function(d) {
return map.latLngToLayerPoint(d.LatLng).x;
});
circles.attr("cy", function(d) {
return map.latLngToLayerPoint(d.LatLng).y;
});
svgCircles.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
}
});
});
问题是,如果我尝试使用此功能,则什么也没有显示:
json.features.forEach(function(d) {
d.LatLng = new L.LatLng(d.geometry.coordinates[1],
d.geometry.coordinates[0]);
});
我也收到错误消息:
TypeError: t is undefined, can't access property "lat" of it
请帮助
答案 0 :(得分:0)
所以我至少固定了圆圈。问题是我没有返回正确的属性。应该退还质心而不记录纬度。这是我的重置功能的更新版本:
//Reset function
function reset() {
//Defining Bounds
var bounds = path.bounds(json);
topLeft = bounds[0],
bottomRight = bounds[1];
svg.attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
//Recalculating Projections for Json map
g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
feature.attr("d", path);
//Recalculating Projections for Circles
circles.attr("cx", function(d) {
d.centroid = path.centroid(d);
return d.centroid[0];
});
circles.attr("cy", function(d) {
return d.centroid[1];
});
g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
circles.attr("d", path);
}
我仍然需要弄清楚线条的投影。有什么建议吗?