Leonardo
Leonardo

Reputation: 4228

D3 different behavior when using method chaining

I have an object that takes care of generating a d3 chart:

this.svg = elem
    .selectAll("svg")
    .data([{}])
    .enter()
    .append("svg")

this.axis = this.svg
    .append("g")
    .attr("class", "axis")

// weird block
this.axis
    .selectAll("g.axis-y")
    .data([{}])
    .append("g")
    .attr("class", "axis-y")

this.axis
    .selectAll("g.axis-y")
    .attr("transform", "translate(100,0)")
    .call(yAxis)

The code in this form won't generate the yAxis. The fault is in the block marked with weird block. If I change that one with:

this.axis
    .selectAll("g.axis-y")
    .data([{}])

this.axis
    .append("g")
    .attr("class", "axis-y")

Then things will work. I've only split the long methods chain in two separate block. Shouldn't the two be equals? Someone can explain why I have these two different behaviors?

Upvotes: 0

Views: 83

Answers (2)

Cool Blue
Cool Blue

Reputation: 6476

this.axis
    .selectAll("g.axis-y")
    .data([{}])

this.axis
    .append("g")
    .attr("class", "axis-y")

Is not the same as

this.axis
    .selectAll("g.axis-y")
    .data([{}])
    .append("g")
    .attr("class", "axis-y")

This is the same...

var thisAxis = this.axis
    .selectAll("g.axis-y")
    .data([{}])

thisAxis
    .append("g")
    .attr("class", "axis-y")

Upvotes: 0

skay-
skay-

Reputation: 1576

The reason is because in your first code example, you are appending to the element return from the data (which doesn't exists) whereas on the second one you are appending to the this.axis element which from your code is the svg element (this.axis = this.svg).

You in order to make your first example you to work you need to call enter() when after you call data() as follows:

this.axis
 .selectAll("g.axis-y")
 .data([{}]).enter()
  .append("g")
  .attr("class", "axis-y")

Hope this helps.

Upvotes: 2

Related Questions