我正在尝试在d3.js中创建一个地图,其中点(美国科学基金机构)从.csv读入,按比例缩放(基于 this 入门套件)。我已经在其他地方看到了其他问题的解决方案,但它们经常在更复杂的项目中实例化(这使得我很难从中提取这些功能)。
读入数据:
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);
然而,这很容易,因为我可以创建一个简单的链来访问'.country'CSS并改变这个属性。但是,我不知道如何选择和改变这个gpoint类中的元素。
我很乐意添加任何其他信息,我只是对发布一堆代码变得谨慎。
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);})
感谢@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))
//...
我现在知道如何'正确'。
我应该使用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);
});
}
完美无缺!
答案 0 :(得分:2)
此示例会将圈子增加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/
创建的一些数据