d3.js 的多个地图:更改比例和中心的值
Multiple maps with d3.js: change values of scale and center
我正在构建一个 (d3 v4) 制图可视化,它允许用户在多个数据集(json 文件)和 两个数据集之间切换不同地区(一个国家的行政单位和更小的行政单位进入其首都)。实际上,通过按钮和 jquery.
,在初始国家/地区级别上从一个数据集切换到另一个数据集效果很好。
问题:切换到关于首都的 map/dataset 时不太令人信服,因为 投影最初是针对整个国家 设置的,因此用户必须多次缩放才能正确显示首都地图。我想在调用投影时更改 .scale 和 .center 的值,但经过多次尝试我还没有找到如何去做。
因为我只有两个不同的区域要显示,我的直觉是设置 scale 和 center 的第一个值并将它们更改为其他值(我知道我想在中使用的 .scale 和 .center 的值这两种情况)当用户通过功能切换到首都地图时。是否有可能轻松切换这些值?你对解决这个问题有什么建议吗?
当用户单击按钮切换到另一个数据集时,我将 json 文件路径加载到一个函数中,我试图以相同的方式加载比例值,但我可能正在做错误的。好像关于投影的那部分代码不能放在函数里?
感谢您的帮助!
我的一小部分代码:
var width = 1100, height = 770;
var projection = d3.geoConicConformal()
.scale(19000) // value I would like to which when the region changes
.center([4.45, 50.53]) // value I would like to which when the region changes
.translate([width/2,height/2]);
var svg = d3.select( "#mapcontainer" )
.append( "svg" )
.attr("width", width)
.attr("height", height)
.style("border", "solid 1px black");
var path = d3.geoPath()
.projection(projection);
var color, jsonfile, legendtext;
function load (jsonfile, legendtext, color) {
d3.selectAll(".currentmap").remove() ;
d3.json(jsonfile, function(error, belgique) {
g.selectAll("path")
.data(belgique.features)
.enter()
.append("path")
.attr("d", path)
.style("stroke", "#fff")
.attr( "class", "currentmap")
.style("fill", function(d) {
var value = d.properties.DATA;
if (value) {return color(value);}
else {return "rgb(250,110,110)"}
});
})
};
//one of the following function for each map
function BGQprovinces() {
jsonfile = "ATLAS/NewGeoJson/bgq-data1-provinces.json";
legendText [= …];
color = d3.scaleOrdinal()
.domain( […])
.range([…]);
load(jsonfile, legendtext, color) ;
};
;
实现此目的的方法很少。
fitSize 和 fitExtent
一个是修改投影比例和平移,而不是比例和中心。这几乎是相同的操作,但 translate 平移投影平面,center 平移未投影平面。为此,您需要使用 projection.fitSize([width,height],geojsonObject) 或 projection.fitExtent([[x0,y0],[x1,y1]],geojsonObject)。后者将允许边距,例如,提供的第一个坐标是左上角,第二个坐标是边界框的右下角,在该边界框中将限制特征。
d3.json(jsonfile, function(error, belgique) {
projection.fitSize([width,height], belgique);
// now draw as you would:
d3.selectAll(".currentmap").remove() ;
g.selectAll("path")
.data(belgique.features)
.enter()
.append("path")
.attr("d", path)
...
请注意,要显示一个国家/地区的全部,您需要有一个显示整个国家/地区的地图项或显示一个国家/地区所有部分的地图项集合。您不能将数组与 fitSize 或 fitExtent 一起使用,如果您有一个特征数组,则可以使用以下方法创建一个特征集合:
var featureCollection = {"type":"featureCollection","features":featureArray}
对于你的情况,我建议使用 fitSize 或 fitExtent。
质心
如果您真的想修改中心属性而不是平移,或者您可能想更改旋转(世界上许多地方更可能出现圆锥保形的结果,比利时应该没问题),那么您需要中心的地理坐标。少数方法之一是从 path.geoCentroid:
获取特征的质心
var centroid = path.geoCentroid(geojsonObject);
然后用它来设置要旋转的投影参数:
projection.rotate([ -centroid[0],-centroid[1] ])
projection.center([0,0])
或居中:
projection.rotate([0,0])
projection.center(centroid)
或两者结合(取决于地图投影类型)。现在您可以应用 fitSize 或 fitExtent,特征已经在中间,但现在我们可以设置比例。我建议将其作为一个潜在答案的原因是因为并非所有投影,尤其是圆锥投影,都可以通过仅修改比例和平移 and/or 中心来提供所需的结果。
当然,对于圆锥投影,您可能还需要找到一种方法来设置平行线,但如果它出现,我会把它留给另一个答案。
我正在构建一个 (d3 v4) 制图可视化,它允许用户在多个数据集(json 文件)和 两个数据集之间切换不同地区(一个国家的行政单位和更小的行政单位进入其首都)。实际上,通过按钮和 jquery.
,在初始国家/地区级别上从一个数据集切换到另一个数据集效果很好。问题:切换到关于首都的 map/dataset 时不太令人信服,因为 投影最初是针对整个国家 设置的,因此用户必须多次缩放才能正确显示首都地图。我想在调用投影时更改 .scale 和 .center 的值,但经过多次尝试我还没有找到如何去做。
因为我只有两个不同的区域要显示,我的直觉是设置 scale 和 center 的第一个值并将它们更改为其他值(我知道我想在中使用的 .scale 和 .center 的值这两种情况)当用户通过功能切换到首都地图时。是否有可能轻松切换这些值?你对解决这个问题有什么建议吗?
当用户单击按钮切换到另一个数据集时,我将 json 文件路径加载到一个函数中,我试图以相同的方式加载比例值,但我可能正在做错误的。好像关于投影的那部分代码不能放在函数里?
感谢您的帮助!
我的一小部分代码:
var width = 1100, height = 770;
var projection = d3.geoConicConformal()
.scale(19000) // value I would like to which when the region changes
.center([4.45, 50.53]) // value I would like to which when the region changes
.translate([width/2,height/2]);
var svg = d3.select( "#mapcontainer" )
.append( "svg" )
.attr("width", width)
.attr("height", height)
.style("border", "solid 1px black");
var path = d3.geoPath()
.projection(projection);
var color, jsonfile, legendtext;
function load (jsonfile, legendtext, color) {
d3.selectAll(".currentmap").remove() ;
d3.json(jsonfile, function(error, belgique) {
g.selectAll("path")
.data(belgique.features)
.enter()
.append("path")
.attr("d", path)
.style("stroke", "#fff")
.attr( "class", "currentmap")
.style("fill", function(d) {
var value = d.properties.DATA;
if (value) {return color(value);}
else {return "rgb(250,110,110)"}
});
})
};
//one of the following function for each map
function BGQprovinces() {
jsonfile = "ATLAS/NewGeoJson/bgq-data1-provinces.json";
legendText [= …];
color = d3.scaleOrdinal()
.domain( […])
.range([…]);
load(jsonfile, legendtext, color) ;
};
;
实现此目的的方法很少。
fitSize 和 fitExtent
一个是修改投影比例和平移,而不是比例和中心。这几乎是相同的操作,但 translate 平移投影平面,center 平移未投影平面。为此,您需要使用 projection.fitSize([width,height],geojsonObject) 或 projection.fitExtent([[x0,y0],[x1,y1]],geojsonObject)。后者将允许边距,例如,提供的第一个坐标是左上角,第二个坐标是边界框的右下角,在该边界框中将限制特征。
d3.json(jsonfile, function(error, belgique) {
projection.fitSize([width,height], belgique);
// now draw as you would:
d3.selectAll(".currentmap").remove() ;
g.selectAll("path")
.data(belgique.features)
.enter()
.append("path")
.attr("d", path)
...
请注意,要显示一个国家/地区的全部,您需要有一个显示整个国家/地区的地图项或显示一个国家/地区所有部分的地图项集合。您不能将数组与 fitSize 或 fitExtent 一起使用,如果您有一个特征数组,则可以使用以下方法创建一个特征集合:
var featureCollection = {"type":"featureCollection","features":featureArray}
对于你的情况,我建议使用 fitSize 或 fitExtent。
质心
如果您真的想修改中心属性而不是平移,或者您可能想更改旋转(世界上许多地方更可能出现圆锥保形的结果,比利时应该没问题),那么您需要中心的地理坐标。少数方法之一是从 path.geoCentroid:
获取特征的质心var centroid = path.geoCentroid(geojsonObject);
然后用它来设置要旋转的投影参数:
projection.rotate([ -centroid[0],-centroid[1] ])
projection.center([0,0])
或居中:
projection.rotate([0,0])
projection.center(centroid)
或两者结合(取决于地图投影类型)。现在您可以应用 fitSize 或 fitExtent,特征已经在中间,但现在我们可以设置比例。我建议将其作为一个潜在答案的原因是因为并非所有投影,尤其是圆锥投影,都可以通过仅修改比例和平移 and/or 中心来提供所需的结果。
当然,对于圆锥投影,您可能还需要找到一种方法来设置平行线,但如果它出现,我会把它留给另一个答案。