根据缩放

时间:2016-10-05 02:17:23

标签: javascript d3.js data-visualization geospatial

我正在尝试在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类中的元素。

我很乐意添加任何其他信息,我只是对发布一堆代码变得谨慎。

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); 
   });
}

完美无缺!

1 个答案:

答案 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/

创建的一些数据