<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <script type='text/javascript' src="https://d3js.org/d3.v3.min.js"></script>
    <script type='text/javascript' src="./word_wrap.js"></script> 
</head>
<body>

<script>
// Change the sizes here to see it wrap
var w = 300,
    h = 200,
    wrapWidth = w,
    fontSize = 20;

var svg = d3.select("body").append("svg")
    .style({border: '1px solid silver'})
    .attr({width: w, height: h})
    .append('g');

svg.append("text")
  .attr({y: fontSize})
  .style({'font-size': fontSize + 'px', 'font-family': 'sans-serif'})
  .text("“I can't believe I've been passed over for Long John Silver,” said Mr. Molesley. The lawn introduced the doctor. A poor man made sport of Highclere Castle. “Well we could always start with Mrs Crawley and Lady Grantham,” informed Mrs. Levinson. “Not worse than a maid serving a duke,” argued Mr. Mason.")
  .call(d3.util.wrap(wrapWidth));

</script>

</body>
</html>
This plugin automatically replaces a long string by tspans for word wrap in pure SVG.
d3.util = d3.util || {};

d3.util.wrap = function(_wrapW){ 
    return function(d, i){
        var that = this;

        function tspanify(){ 
            var lineH = this.node().getBBox().height;
            this.text('')
                .selectAll('tspan')
                .data(lineArray)
                .enter().append('tspan')
                .attr({
                    x: 0,
                    y: function(d, i){ return (i + 1) * lineH; } 
                })
                .text(function(d, i){ return d.join(' '); })
        }   

        function checkW(_text){ 
            var textTmp = that
                .style({visibility: 'hidden'})
                .text(_text);
            var textW = textTmp.node().getBBox().width;
            that.style({visibility: 'visible'}).text(text);
            return textW; 
        }

        var text = this.text();
        var parentNode = this.node().parentNode;
        var textSplitted = text.split(' ');
        var lineArray = [[]];
        var count = 0;
        textSplitted.forEach(function(d, i){ 
            if(checkW(lineArray[count].concat(d).join(' '), parentNode) >= _wrapW){
                count++;
                lineArray[count] = [];
            }
            lineArray[count].push(d)
        });

        this.call(tspanify)
    }
};