What is the best way to break a line of text within an SVG using JavaScript?

As I dive into the world of d3.js, my current project involves creating a network graph where each circle must contain a label.

I am specifically looking for a way to include line breaks in an SVG text element.

My approach so far has been to divide the text into multiple <tspan>s, setting x="0" and varying "y" values to mimic separate lines. However, the code I've implemented is yielding unexpected results.


var text = svg.selectAll("text").data(force.nodes()).enter().append("text");

text       
 .text(function (d) {
 arr = d.name.split(" ");
 var arr = d.name.split(" ");
 if (arr !== undefined) {
  for (i = 0; i < arr.length; i++) {
   text.append("tspan")
    .text(arr[i])
    .attr("class", "tspan" + i);
  }
 }
});

In this snippet, I break down the text string by spaces and assign each segment to a tspan element. However, the issue arises where text from one circle appears in all circles. How can I resolve this problem?

For reference, check out this JSFIDDLE http://jsfiddle.net/xhNXS/ with only SVG text.

Additionally, here is another JSFIDDLE http://jsfiddle.net/2NJ25/16/ that showcases the problematic behavior with tspan elements.

Answer №1

To create a line break using the tspan element, you must specify the position or offset of each one individually. These elements act as text containers that can be positioned in any way you choose. It is recommended to wrap the text elements in g elements for easier positioning by specifying absolute coordinates (x and y) within them.

The following code snippet demonstrates how to add these elements:

text.append("text")       
    .each(function (d) {
        var words = d.name.split(" ");
        for (var j = 0; j < words.length; j++) {
            d3.select(this).append("tspan")
                .text(words[j])
                .attr("dy", j ? "1.2em" : 0)
                .attr("x", 0)
                .attr("text-anchor", "middle")
                .attr("class", "tspan" + j);
        }
    });

Instead of using .text(), I recommend using .each(), which iterates over each element without expecting a return value. The dy attribute defines the line height, while setting x to 0 ensures each new line starts at the beginning of the block.

You can find the modified jsfiddle here, along with some additional optimizations.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Cover a cube with a material using Three.js

After following the tutorial on creating a Cube with a texture, I encountered an issue where the texture repeated on every face of the cube. I am seeking a solution to use a single texture that 'wraps' around the cube. Is there a way to achieve t ...

Ways to show text on a donut chart when hovering with the mouse

I have been attempting to make adjustments to this sample. My goal is to display a word in the center of the donut chart upon mouseover, similar to this: https://i.sstatic.net/dCPKP.png Although I have included code for mouseover, it seems to not be func ...

The DeepL API encounters issues when translating lengthy passages of text

While working with the DeepL API for text translation, everything was running smoothly until I encountered an issue. If the text to be translated exceeds 4000 characters, the API returns an error status without actually translating the data. https://api.de ...

A guide to customizing the appearance of Textfield labels in Material-UI using React

Can someone assist me with changing the label color in Material-UI from grey to black? I am new to Material-UI and struggling to figure it out. Below is the code snippet: import React from "react"; import ReactDOM from "react-dom"; import { TextField, Bu ...

Is it possible to utilize BootstrapVue alongside Vue.Draggable for dragging and dropping items between a list and a b-table?

Would it be feasible to integrate Vue.Draggable with the Table component from BootstrapVue? Additionally, can items be dragged from a list and dropped into a column within a B-table, resulting in a new field named after the dropped item? Thank you for yo ...

What is the best way to implement a dropdown in MUI and React that displays functional components as items?

Here is a list of dummy components: const OwnerList = () => { return ( <Box sx={{ display: 'flex', }} className="owner-container" > <Avatar src='https://hips.hearstapps.com/hmg- ...

Uncertainty about the integration of a JavaScript file into a PHP file

Having two PHP files where one is executed through a URL and makes AJAX calls to the second PHP file can present challenges. Sometimes, the AJAX results return HTML content with JavaScript events that do not work as expected. To solve this issue, I have in ...

What is the best way to instruct Ajax to choose the specific item clicked within a list?

I am currently working on creating a list of people on vacation and I want to calculate their return date when the "Return Date" link is clicked. I have been able to achieve this, however, whenever I click any of the buttons in the list, it always passes t ...

Displaying different content inside a div based on the selection made in a dropdown menu

I'm experiencing difficulties with a jQuery script that should display the content of a div based on selected options in a drop-down menu. The drop-down menu is supposed to provide numerical values for a calculator to determine a loan amount. However ...

Use JavaScript and AJAX to easily assign multiple variables with unique IDs to an array with just one click

This function is no longer supported Original query : I would greatly appreciate any assistance and guidance. I am attempting to create a function that moves selected products from the Cart to another table so I can reorder them according to customer de ...

No image upload possible until 'submit' button is clicked

I'm attempting to send an mp3 file to the server using AJAX without the need for a submit button, but I'm facing an issue where the file isn't getting uploaded. Can anyone help me pinpoint the mistake in my code? <script> $(document). ...

What is the best way to establish my permit requirements on a monthly basis?

An employee is only allowed to request up to 3 permits per month. If they need a fourth permit, they will have to wait until the following month. Here is my table structure for permissions: Permissions id (integer), format (text), date_r ...

Tips for setting up outlet in Next.js with the app router

I recently set up a basic Next.js app with the following structure app(dir) page.js layout.js student(dir) --page.js Within this structure, layout.js includes: import { Inter } from "next/font/google"; const inter = Inter({ subsets: ["lati ...

Animate with Jquery sliding technique

Allow me to explain a situation that may seem unclear at first glance. I have implemented a jQuery script that animates a sliding box upon hover. $(function() { $('.toggler').hover(function() { $(this).find('div').slideTog ...

Angular 2 template is nowhere to be found

As a newcomer to Angular 2, I am currently developing an app where I have successfully completed the Root component containing a navigation bar and footer. However, as I delve into working on the homepage module, I encountered an error. [Error] Unhandle ...

retrieve all JSON entries with more than x number of calls

Working with a json file containing 50 entries per page spread across multiple pages, I have a total of 500 entries split over 10 pages. My challenge lies in ensuring that the function waits for each page's data to be processed and added to an array ...

The Node -v command is functioning properly, while the npm -v command seems to be experiencing some issues

'Executing the command "c: program files/nodejs/node.exe"prefix -g' returns an error stating it is neither an internal nor external command. ...

Using a JavaScript variable within an Angular component: a step-by-step guide

I am currently working with some javascript code for mapbox in my .ts file within an angular component. My goal is to access a variable called polygonCoordinates[] from the javascript code and use it in my typescript code. Unfortunately, I'm facing di ...

Transferring Information from Angular Interface to NodeJS through a JSON Document

I am currently working on establishing a connection between an AngularJS front end and a NodeJS back end application. The main objective is to manipulate data in a JSON file instead of a traditional database. I have attempted to set up the post method on ...

What could be causing the second image to not drop in the proper position in an HTML and JavaScript environment?

I am encountering an issue with a simple drag and drop implementation using images in my code. The first image works fine, but for some reason the second image does not display correctly when dragged inside the div boxes; it appears outside of the box. Can ...