问题
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