SVG Text Wrapping

A modification from the D3Plus library to allow SVG text wrapping.

HTML

<svg>
        <!-- Text that will use the D3plus default wrapping. -->
        <text class="type" dy="15px" x="75px">Wrapped</text>
        <rect class="shape" height="150px" width="150px" y="50px"></rect>
        <text id="rectWrap" class="wrap" y="50px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.aaaaaaaaaaaaaaaaaa</text>
        <circle class="shape" r="75px" cx="75px" cy="300px"></circle>
        <text id="circleWrap" class="wrap" y="225px" x="0px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.</text>

        <!-- Text that D3plus will resize to fit the available space. -->
        <text class="type" dy="15px" x="275px">Resized + Wrapped</text>
        <rect class="shape" height="150px" width="150px" y="50px" x="200px"></rect>
        <text id="rectResizeWrap" class="wrap" y="50px" x="200px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.aaaaaaaaaaa</text>
        <circle class="shape" r="75px" cx="275px" cy="300px"></circle>
        <text id="circleResizeWrap" class="wrap" y="225px" x="200px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.</text>

        <!-- Text that D3plus will resize to fit the available space. -->
        <text class="type" dy="15px" x="475px">Resized </text>
        <rect class="shape" height="150px" width="150px" y="50px" x="400px"></rect>
        <text id="rectResize" class="wrap" y="50px" x="400px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.</text>
        <circle class="shape" r="75px" cx="475px" cy="300px"></circle>
        <text id="circleResize" class="wrap" y="225px" x="400px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.</text>

        <!-- For comparison, how SVG would display the text without D3plus. -->
        <text class="type" dy="15px"...

CSS

svg {
        font-family:"Helvetica", "Arial", sans-serif;
        height: 400px;
        margin: 25px;
        width: 1300px;
        border: thin solid red;
    }
  
    .type {
        fill: #888;
        text-anchor: middle;
    }
    
    .shape {
        fill: #eee;
        stroke: #ccc;
    }

JavaScript

var d3plus = {};

d3plus.textwrap = function() {
    
    var _resize = false;            // Should the text be resized in the container?
    var _wrap = false;              // Should the text be wrapped in the container?
    var _textElement;               // Represents the text element that will have the wrapping applied

    var _x;                         // The offset x-position
    var _y;                         // The offset y-position
    var _width;                     // The maximum width that should be afforded for text rendering
    var _height;                    // The maximum height that should be afforded for text rendering
    


    var _alignment = "center";
    
    
    var _rotate = 0;
    
    var _size;
    
    var _valign = null;
    
    var _innerHeight;
    var _innerWidth;
    
    var _padding = null;
    
    

    // Calculates the sizes of the words that we need to render when put into SVG
    function fontSizes(vars, maxSize) {

        var sizes = [];
        var svg = d3.select("body").append("svg");

        // Create some spans such that we can work out the length of the various words
        var tspans = svg.append("text")
            .selectAll("tspan")
            .data(vars.words)
            .enter()
            .append("tspan")
            .attr("left", "0px")
            .attr("position", "absolute")
            .attr("top", "0px")
            .attr("x", 0)
            .attr("y", 0)
            .style("font-size", maxSize + "px")
            .text(function(d) {
                return d;
            })
            .each(function(d) {
              
                var width = this.getComputedTextLength();   
                var height = this.offsetHeight || this.getBoundingClientRect().height || this.parentNode.getBBox().height;
                          
                var children = d3.select(this).selectAll("tspan");
                if (children.size()) {
                    alert("didn't expect to get here");
   ...