JSFiddle - React, Tailwind, and code Playground
by IPWright83
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.</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</text>
<rect class="shape" height="150px" width="150px" y="50px" x="200px"></rect>
<text id="rectResize" 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.</text>
<circle class="shape" r="75px" cx="275px" cy="300px"></circle>
<text id="circleResize" 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>
<!-- For comparison, how SVG would display the text without D3plus. -->
<text class="type" dy="15px" x="475px">Default Behavior</text>
<rect class="shape" height="150px" width="150px" y="50px" x="400px"></rect>
<text 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 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>
</svg>
CSS
svg {
font-family:"Helvetica", "Arial", sans-serif;
height: 425px;
margin: 25px;
width: 900px;
}
.type {
fill: #888;
text-anchor: middle;
}
.shape {
fill: #eee;
stroke: #ccc;
}
JavaScript
var d3plus = {};
d3plus.textwrap = function () {
var alignment = "center";
var format = "en_GB";
var resize = false;
var rotate = "0";
var shape = "square";
var size;
var text = "";
var valign = "middle";
var height;
var width;
var padding;
var x;
var y;
var container = function (value) {
if (value === false) {
return false;
} else if (d3selection(value)) {
return value;
} else if (value instanceof Array) {
return d3.select(value[0][0]);
} else {
return d3.select(value);
}
};
var accepted = [false, Array, Number, String];
var html = {
accepted: [Boolean],
value: false
};
var init = function (vars) {
var s;
s = this.split.value;
this["break"] = new RegExp("[^\\s\\" + s.join("\\") + "]+\\" + s.join("?\\") + "?", "g");
return false;
};
var split = {
accepted: [Array],
value: ["-", "/", ";", ":", "&"]
};
var flow = function (vars) {
if (vars.text.html.value) {
foreign(vars);
} else {
tspan(vars);
}
};
var foreign = function (vars) {
var anchor, color, family, opacity, text;
text = vars.container.value;
family = text.attr("font-family") || text.style("font-family");
anchor = vars.align.value || text.attr("text-anchor") || text.style("text-anchor");
color = text.attr("fill") || text.style("fill");
opacity = text.attr("opacity") || text.style("opacity");
anchor = anchor === "end" ? "right" : (anchor === "middle" ? "center" : "left");
d3.select(text.node().parentNode)
.append("foreignObject")
.attr("width", vars.width.value + "px")
.attr("height", vars.height.value + "px")
.attr("x", "0px")
.attr("y", "0px")
.append("xhtml:div")
.style("font-family", family)
.style("font-size", vars.size.value[1] + "px")
.style("color", color)
.style("text-align", anchor)
.style("opacity", opacity)
...