我试图在d3.js中创建一个地图,其中点(美国科学资助机构),从。csv中读取,缩放级别(基于此入门工具包)。我在其他地方看到过这个问题的其他解决方案,但是它们通常是在更复杂的项目中实例化的(这使得我很难从中提取出这种能力)。
Read in data:
var data;
function draw(){
....
d3.csv("data/funders.csv", function(err, locations) {
locations.forEach(function(i){
addPoint(i['lng'], i['lat'], i['TotalFunding']);
});
});
}
我这样定义svg:
svg = d3.select("#container").append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom) // my zoom function
.on("click", click) // my click function
.append("g");
g = svg.append("g");
接下来,我定义了一个将"g"追加到SVG的函数,然后我继续添加一个类"gpoint"(地理点)。
function addPoint(lat, lon, size){
var gpoint = g.append("g").attr("class", "gpoint");
var location = projection([lat,lon])
var x = location[0];
var y = location[1];
// Here I append 'circle' to the svg.
gpoint.append("svg:circle")
.attr("cx", x)
.attr("cy", y)
.attr("class","point")
.style("fill", "blue")
.attr("r", size/10); //*
}
*这个原始的大小信息需要保留,只是缩放。
在这里,我想用size
乘以当前的缩放级别(可以从var scale = d3.event.scale;
中获得)。在我的代码中,我使用scale来调整一个CSS元素,控制国家轮廓的笔画宽度:
d3.selectAll(".country").style("stroke-width", 1.5 / scale);
然而,这很容易,因为我可以创建一个简单的链来访问'。国家的CSS,并改变这个属性。但是,我不清楚如何选择和改变这个gpoint类中的元素。
我很乐意添加任何额外的信息,我只是越来越警惕张贴代码墙。
funders.csv:
funder,lat,lng,TotalFunding
NIH,39.000443,-77.102394,5000
NASA,38.883,-77.0163,1000
编辑
我发现我可以用
改变圆的半径g.attr("class", "gpoint").selectAll("circle").attr("r", s)
然而,我仍然有困难访问圆的当前半径和改变它,例如,
g.attr("class", "gpoint").selectAll("circle").data(data).attr("r", function(d){return(d.r*s);})
编辑2
感谢@kscandrett的帮助,我才能完成这项工作。
其中一个要求是保持原来的尺寸。简单地改变'r'
不会做到这一点,但amount
信息可以设置为点的id
创建点时(我相信有更好的解决方案,如使用对象来存储此信息…
在创建时将资金金额信息保存为点的'id'
(同样,可能不习惯,但现在可以了)。
gpoint.append("svg:circle")
//...
.attr("id", Math.sqrt(parseInt(amount) * 0.001))
.attr("r", Math.sqrt(parseInt(amount) * 0.001))
//...
编辑3:
我现在知道如何"正确"地做这件事。而不是attr
,应该使用datum
将此信息附加到每个圆圈上,即.datum(Math.sqrt(parseInt(amount) * 0.001))
。
定义pointScale函数
function pointScale(amount, zoomScale){
// Ugly code that will almost certainly be replaced, but it is good enough for now.
var maxPossibleZoom = 100;
var sizeFloor = 0.12;
var size = amount * (maxPossibleZoom/zoomScale*0.05);
if (size > amount){
return amount;
} else if (size < sizeFloor){
return sizeFloor * amount;
} else {
return size;
}
}
3.我上面链接到的初学者工具包有一个move()
功能。最后一步是使用@kscandrett的答案向其添加一些代码,以提取分配给attr('id')
的值,并使用d3.event.scale
根据当前缩放级别缩放此值。…
function move(){
//...
var s = d3.event.scale;
//...
d3.selectAll('circle').attr('r', function (d, i){
var amount = d3.select(this).attr('id');
return pointScale(amount, s);
});
}
作品完美!
这个例子将把圆圈增加10%
function changeSize() {
d3.selectAll('circle').attr('r', function (d, i)
{
return d3.select(this).attr('r') * 1.1;
});
}
的例子:http://codepen.io/anon/pen/vXRdGx
作为起点,我使用了Jerome Cuckier创建的一些数据http://www.jeromecukier.net/blog/2012/05/28/manipulating-data-like-a-boss-with-d3/