Accepted answer

Instead of this:

var phrases = svg.selectAll("phrases")//there is no DOM as phrases it will return an empty selection always.
        .data(data, function(d) { return d.i; });

it should be this:

var phrases = svg.selectAll("text")//select all the text
        .data(data, function(d) { return d.i; });

Reason: This will return an empty selection always svg.selectAll("phrases") that is why its appending all the time.

In second case it will return a selection of text DOMs.

working code here

Related Query