根据缩放调整点的大小

Resize points based on zoom

本文关键字:调整 缩放      更新时间:2023-09-26

我试图在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创建点时(我相信有更好的解决方案,如使用对象来存储此信息…

1.

在创建时将资金金额信息保存为点的'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))

2.

定义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/