Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
79 views
in Technique[技术] by (71.8m points)

javascript - Cannot use attr with an object in D3 v4

I've been trying to convert a nice D3 chart example ( https://jsfiddle.net/thudfactor/HdwTH/ ) to an Angular2 component with the new D3 v4.

I do however get a "cannot read property text of null" exception with the following code:

var textLabels = labelGroups.append("text").attr({
    x: function (d, i) {
        var centroid = pied_arc.centroid(d);
        var midAngle = Math.atan2(centroid[1], centroid[0]);
        var x = Math.cos(midAngle) * cDim.labelRadius;
        var sign = (x > 0) ? 1 : -1
        var labelX = x + (5 * sign)
        return labelX;
    },
    y: function (d, i) {
        var centroid = pied_arc.centroid(d);
        var midAngle = Math.atan2(centroid[1], centroid[0]);
        var y = Math.sin(midAngle) * cDim.labelRadius;
        return y;
    },
    'text-anchor': function (d, i) {
        var centroid = pied_arc.centroid(d);
        var midAngle = Math.atan2(centroid[1], centroid[0]);
        var x = Math.cos(midAngle) * cDim.labelRadius;
        return (x > 0) ? "start" : "end";
    },
    'class': 'label-text'
}).text(function (d, i) {      <--------------- exception
    return d.data.label;
});

labelgroups is a selection, append should work, so it must be the .attr({}) causing the problem. It does however work fine in the jsfiddle.

Has this syntax changed in D3 v4? How would it be correct?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From D3 v4 onwards you cannot use objects to set attr or style anymore. To do so, you have to reference the mini library D3-selection-multi:

<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>

After doing that, change your code from attr to attrs (yes, like a plural):

var textLabels = labelGroups.append("text").attrs({
    //mind the 's' here-------------------------?
});

Do the same for the styles: it should be styles, as a plural, not style.

If you don't want to change all this, simply do as the "regular" way: set x, y, text-anchor and class in separate attr.

Here is the selection-multi documentation: https://github.com/d3/d3-selection-multi/blob/master/README.md#selection_attrs


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...