By applying a dy attribute and resetting the x position, we effectively create a line break effect with our text. The rendered output looks like the following.

Accomplishing this with D3.js requires us to use the data function twice. The first data operation will loop through every block of text. The second data operation will loop through every line. If you need help with D3’s enter, exit, and merge functions, check out my previous post.

// Create a new <text> element for every data element.lettext=canvas.selectAll("text").data(data).enter().append("text").attr("x",20).attr("y",20);// Add a <tspan class="title"> for every data element.text.append("tspan").text(d=>d.title).attr("class","title");// Add a <tspan class="author"> for every data element.text.append("tspan").text(d=>`-- ${d.author}`).attr("class","author").attr("x",20).attr("dx",20).attr("dy",25);// Add a <tspan class="text"> for every text line.text.selectAll("tspan.text").data(d=>d.text.split("\n")).enter().append("tspan").attr("class","text").text(d=>d).attr("x",20).attr("dx",10).attr("dy",22);

This works because the data function allows to enter into embedded attributes and create new arrays from the original data set. In our case, our new array is d.text.split(\n).