我正在尝试创建一个地图,用户可以在其中选择一个新投影,并且它将在运行中应用。
这是我做的(你可以找到一个演示here)
<!DOCTYPE html>
<html>
<head>
<meta content="utf-8">
<style type="text/css">
svg {
border: 1px solid #ccc;
}
path {
fill: #ccc;
stroke: #fff;
stroke-width: .5px;
}
path:hover {
fill: #00AEEC;
}
#projectionList {
width: 200px;
height: 500px;
float: left;
border: 1px solid grey;
}
</style>
</head>
<body>
<div id="mainContainer">
<div id="projectionList">
</div>
<div id="graphContainer">
</div>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script type="text/javascript">
// d3.js graph
var width = 900,
height = 500;
var path = d3.geo.path();
var svg = d3.select("#graphContainer").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("tunisia.json", function(error, topology) {
console.log(topology);
//console.clear();
var featureCollection = topojson.feature(topology, topology.objects.governorates);
var bounds = d3.geo.bounds(featureCollection);
var centerX = d3.sum(bounds, function(d) {return d[0];}) / 2,
centerY = d3.sum(bounds, function(d) {return d[1];}) / 2;
var projection = d3.geo.mercator()
.scale(3000)
.center([centerX, centerY]);
path.projection(projection);
svg.selectAll("path")
.data(featureCollection.features)
.enter().append("path")
.attr("d", path);
});
//end of d3.js graph
var selectProjection = {projection_list: []};
// add the list of supported projection
/*schema of objects:
{
id: "unique_int",
projection_name: "a name",
projection_function: "a function name",
projection_description: "a description"
}
*/
//add first projection
selectProjection.projection_list.push({
id: 1,
projection_name: "azimuthalEqualArea", // to be updated with a more descriptive name
projection_function: "azimuthalEqualArea",
projection_description: "azimuthalEqualArea" // to be updated with more detailed description
});
// add second projection
selectProjection.projection_list.push({
id: 2,
projection_name: "conicConformal", // to be updated with a more descriptive name
projection_function: "conicConformal",
projection_description: "conicConformal" // to be updated with more detailed description
});
// add thrid projection
selectProjection.projection_list.push({
id: 3,
projection_name: "equirectangular", // to be updated with a more descriptive name
projection_function: "equirectangular",
projection_description: "equirectangular" // to be updated with more detailed description
});
selectProjection.projection_list.push({
id: 4,
projection_name: "Mercator", // to be updated with a more descriptive name
projection_function: "mercator",
projection_description: "mercator" // to be updated with more detailed description
});
// the above storage method is used temporary in order to leverage a demo, in production mode, there will be a database table to hold these information
function set_projection(option) {
proj = option.value
projection = eval("d3.geo."+proj+"().scale(500);");
path = d3.geo.path()
.projection(projection);
svg.selectAll("path").transition()
.duration(1000)
.attr("d", path);
/*var link = "https://github.com/mbostock/d3/wiki/Geo-Projections#wiki-" + proj
d3.selectAll("div#current_proj_info").html("Current projection: <a href=\""+link+"\">"+option.text+"</a>");*/
}
function apply_projection(e){
// applying a new projection
set_projection(e.target[e.target.selectedIndex]);
}
var newSelect = document.createElement("select");
newSelect.id = "selectProjection";
newSelect.onchange = apply_projection;
for (var i = selectProjection.projection_list.length - 1; i >= 0; i--) {
console.log(selectProjection.projection_list[i].projection_name);
newSelect[newSelect.length] = new Option(selectProjection.projection_list[i].projection_name, selectProjection.projection_list[i].projection_function, false, false);
};
console.log("newSelect content");
console.log(newSelect);
document.getElementById('projectionList').appendChild(newSelect);
</script>
</body>
</html>
问题在于,当我尝试在应用新投影后缩放图形时,它会超出div的可见区域。
请你检查一下是什么问题。