Using Bostock's wrap method to format the text

In my current scenario, I am looking to add short to medium snippets of text in various parts of my visualization. However, the default behavior results in unattractive output as SVG text is simply appended all at once. After some research, I came across a clever method by Mike Bostock to handle longer strings in SVG text, which can be found here. I attempted to adapt this technique to my specific visualization, but it didn't yield the desired outcome. Here's the code snippet:

  

 var margins = {top:20, left:50, bottom:100, right:20};

var width = 1200;
var height = 500;

var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;

var svg = d3.select('body')
    .append('svg')
    .attr('width', totalWidth)
    .attr('height', totalHeight);

var graphGroup = svg.append('g')
    .attr('transform', "translate("+margins.left+","+margins.top+")");

// Rest of the JavaScript code...

d3.selectAll('.labelText')
  .call(wrap, 120);
text {
  font-family: Tw Cen MT;

}

.date {
    font-size: 18px;
    paint-order: stroke;
    stroke: #fff;
    stroke-width: 3px;
    stroke-linecap: butt;
    stroke-linejoin: miter;
    font-weight: 800;
}
<script src="https://d3js.org/d3.v5.min.js"></script>

I understand the concept behind it, and I followed the steps outlined by Bostock in the example. However, the text doesn't seem to pass through the function correctly for wrapping to occur, with no errors being reported.

Question

Can we modify Bostock's tspan wrap function to work universally? If so, how can we achieve this if the text isn't selected and the function isn't called with the desired width?

Further Clarifications:

  • Font size: 12px
  • Desired width: 120

Bonus Points:

  • Desired text alignment: Right (Bostock's example features centered text)

Answer №1

The main issue you are encountering is with the sequence of setting the class prior to the enter method:

graphGroup.selectAll('.labelText')
    .data(data.filter(function(d) {return d.penalty==false}))
    .attr('class', 'labelText')
    .enter()
    .append('text')
    //etc...

The correct order should be:

graphGroup.selectAll('.labelText')
  .data(data.filter(function(d) {
    return d.penalty == false
  }))
  .enter()
  .append('text')
  .attr('class', 'labelText')
  //etc...
 

Because of this, your d3.selectAll('.labelText') selection ends up being empty (having a size() of zero).

Therefore, some minor adjustments need to be made to incorporate the wrap function as follows:

  1. Set the text-anchor to end, and eliminate padding in the x position;
  2. In the wrap function, obtain the x positions of the texts...

    x = text.attr("x")
    

    and utilize them in the tspans:

    .attr("x", x)
    

Here is the revised code snippet provided for reference:

[Updated Code Snippet]

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

The delay in loading HTML content using FOSJsRoutingBundle and Ajax for a specific route parameter (ID)

I'm using FOSjSrouting in my symfony2.7 project. This is the code in my html.twig view: <table> <!--table header code ...etc... --> <tbody> {% for currentData in arrayData %} <tr> <td>{{ currentData. ...

Ways to modify the color of a container's border by interacting with radio buttons through JavaScript

I'm currently facing a challenge with creating a settings dropdown menu that allows users to select different themes. Each theme is supposed to modify the background color and border color, but I have successfully implemented only the background color ...

JavaScript must be able to detect when the checkbox value is reversed, which is dependent on the user-entered data

Hey there, I come across a situation where users are selecting a checkbox to insert or update a row of data in a MySQL database through SparkJava/ Java. The functionality is working fine except for a minor glitch. The issue arises when the checkbox behav ...

Difficulty arising while trying to access the following element after the designated target using JQuery

JSFiddle I'm encountering a strange issue in the fiddle linked above. When typing a character into an input followed by pressing the down key, the console logs two values: one correct value of 3, and one incorrect value of 0. The challenge is to sel ...

ExpressJS: How to resolve the undefined error in Express session

After using express-generator to create my project, I installed the express-session package. Below is how express-session is ordered in my app: app.js var expressSession = require('express-session'); app.use(logger('dev')); app.use( ...

Discovering the data-id value in an HTML element by clicking it with JavaScript and returning that value through a for loop

this is my unique html content <ul class="dialogs"> {% if t_dialogs %} <li class="grouping">Today</li> {% for item in t_dialogs %} <li class=&qu ...

Javascript chart

Hello everyone, I am diving into the world of fetch API. Currently, I am faced with a challenge where I need to generate the following list items: <li>Zimmerman, Paul</li> <li>Yimmerman, Raul</li> <li>Limmerman, Caul</li> ...

What is the best way to compare an attribute value with a JSON value in JavaScript?

I have a JSON string that looks like this: { "DocID": "NA2", "DocType": "Phase1.1 - Visa Documents (This section is applicable for HK work location only)", "DocSubType": "New Application", "DocName": "Passport / Travel Document (Soft copy only) ...

Prevent event bubbling when clicking

I have a code snippet that I'm struggling with. <p>haha</p> <button class="btn btn-light" onclick="nextSibling.classList.toggle('d-none');"> <i class="fa fa-ellipsis-h"></i> </button> <div class= ...

calculation of progress bar advancement

I want to make the progress bar in my game responsive to changes in the winning score. Currently, it moves from 0% to 100%, which is equivalent to 100 points - the default winning score. But I need the progress bar to adjust accordingly based on the user-i ...

Check to see whether the coordinates fall inside the specified bounding box

I am faced with the task of creating a function that can determine whether a given coordinate c lies within the boundaries of coordinates a and b. All variables in this scenario are of type: type Coordinate = { lat: number; lon: number; }; Initially ...

How can I toggle the visibility of form inputs while utilizing Vue Formulate Schemas?

I've been experimenting with Vue Formulate schemas to build a form. My goal is to have two radio buttons, A and B, where clicking A reveals an additional input field below. When B is clicked, the extra input field should be hidden. Using a schema is ...

Modify CSS image according to the user interface language in asp.net

Is there a way to dynamically change the image based on different cultures in my ASP.NET webpage? I have successfully been able to switch strings using a resource file, but I am unsure how to handle images. Currently, I have an A tag with a specific clas ...

Issues with AngularJS edit functionality for records not functioning as expected

I have implemented a feature on my page where users can add objects to an array. These objects are then displayed on the page along with links for editing each item in the array. Each added item is assigned a primary key, allowing users to edit it later e ...

Combining router.get and https.get in Node.js: A step-by-step guide

Looking for a more efficient method to retrieve information from an http request and send it to the frontend using the path '/get'. Currently, I have combined two functions that seem to work but may not be the most optimal: const router = express ...

Is your Angular5 service failing to transmit data?

I have two components in my code, A and B. Component A contains a form with data that I want to send to component B. However, it seems like component B is not receiving any data. Here is the code for Component A: import { MyService } from 'path/my ...

The use of url.resolve() function with greater than two arguments

Currently, I'm utilizing the url.resolve() function to combine components of a URL from a configuration file in this manner: var uri = url.resolve(config.baseUrl, this.orgId, this.appId, type) However, it appears that using more than two arguments d ...

Using Mongoose schema with a reference to an undefined 'ObjectID' data type

I am currently working on establishing relationships between my schemas, and I have encountered some issues with my solution. Here is how my device schema looks like: var deviceSchema = schema({ name : String, type : String, room: {type: mongo ...

The objects-to-csv module encountered an error: fs.existsSync is not a valid function for this

"TypeError: fs.existsSync is not a function" Whenever I try to create a CSV file and input some data into it, this error message pops up. const objectstocsv = require('objects-to-csv'); export default { data () { return { ...

Extract specific index from a JSON array

I'm a beginner in Jquery and javascript, I am using ajax to upload an image and trying to fetch the image url. However, I keep encountering errors every time I try. Can someone assist me with this? Thank you! Here is the error message I received: Un ...