更新圆半径并在d3.js中为其设置动画

时间:2016-06-13 03:54:42

标签: javascript d3.js

我在csv文件的地图上绘制了n个圆圈,我希望在2年的容量时间内更新圆的半径。我的csv文件格式是:

ID,纬度,经度,CapaYr1,CapaYr2

1,38.957,-122.642,94261,288839.2857

2,40.718,-122.42,3690993.143 3799364.714。

以下是我的代码:

g.selectAll("circle")
                .data(result)
                .enter()
                .append("circle")
                .attr("r", 0)
                .attr('cx', function(d) {
                    return projection([d.Longitude, d.Latitude])[0];
                })
                .attr('cy', function(d) {
                    return projection([d.Longitude, d.Latitude])[1];
                })
                .attr('r', function(d){

                    var hd = d3.keys(d);
                    var radDataSet = [];


                    for (var i = hd.length - 1; i >= 0; i--) {
                        if((hd[i] === "ID") || (hd[i] === "Latitude") || (hd[i] === "Longitude")){
                        }else{
                            radDataSet.push(Math.round(Math.sqrt((d[hd[i]]/30000))));
                        }
                    }

                    radDataSet.forEach(function(d, i) {
                            g.selectAll("circle").transition().duration(2000).delay(i * 1000)
                            .attr("r", d);
                    });

                });

因此上面代码中的radDataSet数组具有CapaYr1和CapaYr2值。 所有圆的半径都会更新,但所有圆都具有相同的radSet值。那么我怎样才能使每个圆转换具有不同的值,具体取决于csv文件中每行的计算radDataSet值。

每行中的

radSet值是[3,2]和[11,11]。它的更新圆半径为[11,11]。

这是我的小提琴 - > https://jsfiddle.net/7zumngdq/72/

1 个答案:

答案 0 :(得分:1)

这是我的方法(我希望这是你试图解决的问题),虽然你使用线性比例可能需要两个以上的数据值才能工作。让我解释一下:

首先,我创建了一个包含数据的新数据结构(我不喜欢带斜线的键:S)

var parsed = ca2.map(function(d, i) {
  return {
    firstYear: +d['2000/01/31'],
    secondYear: +d['2000/02/29'],
    id: d['ID'],
    lat: +d['Latitude'],
    lng: +d['Longitude']
  };
});
// Pushing a new value in order to have at least one circle that
// will change radius
parsed.push({
  firstYear: 2678933,
  secondYear: 80000000,
  id: 'DOVAL',
  lat: 35.2931129,
  lng: -119.465589
})

让我们设置一个刻度来处理半径尺寸:

var max = d3.max(parsed, function(d) {
  return d.firstYear
});
var min = d3.min(parsed, function(d) {
  return d.firstYear
});
var linearScale = d3.scale.linear()
  .domain([min, max]) 
  // If we just had two values all our circles would end up being the smallest 
  // and largest values of the range defined below
  .range([5, 25]);

现在让我们添加圈子:

var circles_first = g.selectAll(".circle-year")
  .data(parsed)
  .enter()
  .append("circle")
  .attr('class', 'circle-year')
  .attr("r", 0)
  .attr('cx', function(d) {
    return projection([d.lng, d.lat])[0];
  })
  .attr('cy', function(d) {
    return projection([d.lng, d.lat])[1];
  });

制作第一年值的动画

g.selectAll(".circle-year")
  .transition().duration(2000).delay(1000)
  .attr('fill', 'red')
  .attr('r', function(d) {
    return linearScale(d.firstYear);
  });

最后制作第二年值的动画

setTimeout(function() {
  var maxS = d3.max(parsed, function(d) {
    return d.secondYear
  });
  var minS = d3.min(parsed, function(d) {
    return d.secondYear
  });
  linearScale.domain([minS, maxS]);
  g.selectAll(".circle-year")
    .transition().duration(2000).delay(1000)
    .attr('fill', 'green')
    .attr('r', function(d) {
      return linearScale(d.secondYear);
    });
}, 8000)

工作jsfiddle:https://jsfiddle.net/e693hrdL/

更新

这是一个应该有效的更新版本,唯一的问题是您的数据在您的' SHA'数据元素,从而使数据变化最小。

d3.csv('./ca.csv', function(ca2) {
  console.log('ca2', ca2);
  var parsed = ca2.map(function(d, i) {
    var dates = d3.keys(d).filter(function(key) { // get all date keys
      if (key === 'ID' || key === 'Latitude' || key === 'Longitude') {
        return false;
      }
      return true;
    });
    var dateValues = dates.map(function(date) { // Add them as an array
      // if (d.ID === 'SHA') {
      //  return +d[date] - 2000000;
      // }
      return +d[date];
    });
    return {
      dates: dateValues,
      id: d['ID'],
      lat: +d['Latitude'],
      lng: +d['Longitude']
    };
  });
  console.log(parsed);
  var circles_first = g.selectAll(".circle-year")
    .data(parsed)
    .enter()
    .append("circle")
    .attr('class', 'circle-year')
    .attr("r", 0)
    .attr('cx', function(d) {
      return projection([d.lng, d.lat])[0];
    })
    .attr('cy', function(d) {
      return projection([d.lng, d.lat])[1];
    });

  parsed[0].dates.forEach(function(d, i) { // call function based on index!
    setTimeout(function() {
      changeRadius(i);
    }, i * 500);
  })
  var linearScale = d3.scale.linear()
    .range([0, 25]);

  function changeRadius(index) {
    var maxS = d3.max(parsed, function(d) {
      return d.dates[index];
    });
    var minS = d3.min(parsed, function(d) {
      return d.dates[index];
    });
    console.log(minS, maxS)
    linearScale.domain([minS, maxS]);
    g.selectAll(".circle-year")
      .attr('fill', function(d) {
        return
      })
      .attr('r', function(d) {
        return linearScale(d.dates[index]);
      });
  }
});

工作plnkr:https://plnkr.co/edit/6GH2VWwtUp5DHOeqrKDj?p=preview