D3: Accessing bound data after using .datum()

半世苍凉 提交于 2019-12-25 18:01:06

问题


I'm having trouble figuring out how to add a title element with bound data after using .datum()

When .datum() is called 'd' contains all of the expected properties, but after calling .datum() subsequent attempts to access the properties fails... 'd' contains only the path:

var oc = og.selectAll('.oc-circle')
   .data(function(d) { return [d]; }, get_key);

oc.enter()
   .append('path')
   .attr({ 'class': 'occ oc-circle' });

oc.exit().remove();

oc
   .datum(function(d) {
      console.log(d);
      // d has all of its properties
      // Object {type: "Feature", properties: Object, geometry: Object, id: "nn00564043"}
      return circle
          .origin([d.geometry.coordinates[0], d.geometry.coordinates[1]])
          .angle(.5)();
   })
   .style({ 
      "fill" : 'red',
      'opacity': 0.75,
   })
   .attr("d", geoPath)
   .append('title')
   .text(function(d) {
      console.log(d);
      // d only contains path data
      // Object {type: "Polygon", coordinates: Array[1]}
      // return 'Magnitue ' + d.properties.mag + ' ' + d.properties.place;
   })

The inline comments above show what is accessible after calling .datum()

What am I missing?

Thanks!


回答1:


Mark's suggestion was correct. With the help of this fiddle: http://jsfiddle.net/Lg9z57g5/ I came up with the following, including functions to draw circles using either d3.geo.circle() or path.pointRadius()

var pointPath = function(d, r) {
   var coords = [d.geometry.coordinates[0], d.geometry.coordinates[1]];
   var pr = geoPath.pointRadius(globe.scale() / 100 * 1.5);
   return pr({
      type: "Point",
      coordinates: coords
   })
}

var circlePath = function(d) {
   var circle = d3.geo.circle();
   var coords = [d.geometry.coordinates[0], d.geometry.coordinates[1]];
   var cc = circle.origin(coords).angle(.5)();
   return geoPath(cc);
}

var oc = og.selectAll('.oc-circle')
    .data(function(d) { return [d]; }, get_key);

oc.enter()
    .append('path')
    .attr({ 'class': 'occ oc-circle' });

oc.exit().remove();

oc
    .attr("d", pointPath)
    .style({ 
         'fill' : 'red',
         'opacity': 0.75,
     })
     .append('title')
     .text(function(d) {
         return 'Magnitue ' + d.properties.mag + ' ' + d.properties.place;
     })

The bigger issue in my situation was the reDraw() function, which was basically:

 surface.selectAll("path").attr("d", d3.geo.path().projection(projection));

this expected all data bound to paths to contain d.geometry.coordinates

I had to add this line:

surface.selectAll('.occ').attr('d', pointPath)

I learned that when appending a 'path' with d3 it is not necessary to add .attr('d', path) if the bound data is already in the correct format for path.




回答2:


Your .datum call is returning

return circle
  .origin([d.geometry.coordinates[0], d.geometry.coordinates[1]])
  .angle(.5)();

which is a path and this is what's being data-bound, not d.

I'm not sure you need that datum call at all:

oc
   .style({ 
      "fill" : 'red',
      'opacity': 0.75,
   })
   .attr("d", function(d){
     return geopath(circle
      .origin([d.geometry.coordinates[0], d.geometry.coordinates[1]])
      .angle(.5)());
   })
   .append('title')
   .text(function(d) {
      console.log(d);
      // d only contains path data
      // Object {type: "Polygon", coordinates: Array[1]}
      // return 'Magnitue ' + d.properties.mag + ' ' + d.properties.place;
   })


来源:https://stackoverflow.com/questions/40225671/d3-accessing-bound-data-after-using-datum

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!