I am having trouble specifying a class within an SVG using D3.js

I have been facing a strange issue with my script. When I try to execute the following code:

var key="#US"
d3.select(key).style("fill", "red");

it seems like it's not working for me. Interestingly, when I run the same code in the console, it works perfectly fine.

I have tried using functions like document.ready and window.onload, but none of them seem to solve the problem.

After experimenting with different approaches, I came up with this solution:

window.onload = function() {
    Object.keys(countries).forEach(function(key){
        d3.select(key).style("fill", "red");
    });
};

Object.keys(countries).forEach(function(key){
    d3.select(key).style("fill", "red");
    console.log("t")
});

The strange thing is that it only seems to work when the dev console is active, and even then it only works 1 out of every 4 times. This error has got me puzzled.

Answer №1

In this unique scenario, I acquired an SVG world map and addressed the class attributes by substituting spaces with hyphens.

Currently, when presented with a map resembling the following:

const countries = {
  '.United-States': true
};

You can now identify the US and its associated regions, and color them red, using:

Object.keys(countries).forEach(function(key) {
  d3.selectAll(key).style("fill", "red");
});

Innovative demonstration

If there was sufficient time available, all path class names could potentially be converted into a 2 or 3-digit country code for enhanced simplicity to align better with your selection approach.

const svgUrl = 'https://gist.githubusercontent.com/rmkane/4fb74736f090d9145b53e56d7e42989e/raw/e3e6fc625094ab84b3b2381afc447cf109bc601a/world.svg';
const svgContainer = document.querySelector('#svg-container');

const countries = {
  '.United-States': true
};

const parseSvg = (svgText) =>
  new DOMParser().parseFromString(svgText, 'image/svg+xml');

(async () => {
  const response = await fetch(svgUrl);
  let svgText = await response.text();
  // Rectify path class names
  svgText = svgText.replaceAll(/class="(\w+)\s(\w+)"/g, 'class="$1-$2"');
  const svg = parseSvg(svgText).firstElementChild;
  // Integrate the SVG
  svgContainer.append(svg);
  // Prominently feature US and its territories
  Object.keys(countries).forEach(function(key) {
    d3.selectAll(key).style('fill', 'red');
  });
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="svg-container"></div>
<!-- See: https://gist.github.com/rmkane/4fb74736f090d9145b53e56d7e42989e#file-world-svg -->

Alternate illustration

This specific example involves an SVG sourced from MapSVG:

const svgUrl = 'https://gist.githubusercontent.com/rmkane/4fb74736f090d9145b53e56d7e42989e/raw/ce11d29d4595e9c386bac41efaa82d33b8f07aec/world-2.svg';
const svgContainer = document.querySelector('#svg-container');

const countries = {
  '#US': true
};

const parseSvg = (svgText) =>
  new DOMParser().parseFromString(svgText, 'image/svg+xml');

(async () => {
  const response = await fetch(svgUrl);
  let svgText = await response.text();
  const svg = parseSvg(svgText).firstElementChild;
  svgContainer.append(svg);
  Object.keys(countries).forEach(function(key) {
    d3.selectAll(key).style('fill', 'red');
  });
})();
#svg-container svg {
  background: lightblue;
}

#svg-container svg path {
  fill: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="svg-container"></div>
<!-- See: https://gist.github.com/rmkane/4fb74736f090d9145b53e56d7e42989e#file-world-2-svg -->

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

Save the HTML elements in an object and then use the ng-include directive to include the template

Currently experimenting with this code snippet: var CustomTable = function($elem) { this.properties.element = $elem; this.initialize(); }; CustomTable.prototype.PROPERTIE = { secondElement: $('.second') // this element ...

If a different link is selected, remove the class from the ID, and vice versa

I've been working on solving a jQuery issue that involves manipulating classes in a parent container with two divs and links. The goal is to add a class to change the background when a link is clicked in one div, and remove it if the other link is cli ...

Angular 2 Aot Issue: CRITICAL ERROR: CALL_AND_RETRY_LAST Allocation unsuccessful - JavaScript heap exhausted

Encountered an issue while running Angular 2 AOT rollup: <--- Last few GCs ---> 144518 ms: Mark-sweep 1317.0 (1404.4) -> 1317.0 (1404.4) MB, 1522.9 / 0.0 ms [allocation failure] [GC in old space requested]. 146029 ms: Mark-sweep 1317.0 (1404 ...

Combine two events in jQuery using the AND operator

Can I create a condition where two events are bound by an AND logic operator, requiring both to be active in order for a function to be called? Let's say you have something like this: foobar.bind("foo AND bar", barfunc); function barfunc(e) { al ...

filtering the properties of mongoose documents

I have created a schema as shown below: var UserSchema = new Schema({ firstName: { type: String, required: true }, lastName: { type: String, required: true }, email: { type: String, required: true }, location: { type: String, required: true }, p ...

How can I simply show a specific value from an object in Vue?

I've created a Vue application that filters messages and displays them on a page. Currently, when a user selects a message from the list, the entire JSON data associated with that message is shown on the page. However, I want to only display a specifi ...

Switch between showing and hiding a div by clicking on an image

Currently, I am experimenting with the toggle div function and utilizing images as triggers for toggling. For instance, when a div is closed, an image of a "plus" sign indicates to the user that it can be expanded, and vice versa for compressing the div. T ...

Combining strings and variables in Vue.js with the use of bootstrap-vue syntax

Hey, I'm facing a little syntax hiccup with '="collapse-{{ product.id }}"' in both the b-button and b-collapse. Any ideas on how to properly structure this? Just looking to set up a unique ID that connects the button to the collaps ...

Calculate the total count of responses within the JSON data returned

Hello all, I need some guidance on calculating the total number of responses in a JSON response that adhere to a specific rule using JavaScript. Here is the JSON response that I am discussing: [ { "InvoiceNumber":"INV0319", "InvoiceOrd ...

Send out data every 250 milliseconds in a way that resembles debounceTime(), but without any waiting period

When the window is resized, I have a complex operation that rearranges multiple DOM elements. To prevent frequent updates, I implemented debounceTime(250ms) to introduce a delay before refreshing the components. However, this approach can cause issues if ...

Issue encountered while creating a token in a JavaScript Chrome extension and attempting to validate it on a backend Node.js server

Trying to create a token within a chrome extension and utilizing it to authenticate requests to the backend server has proven challenging. While successfully generating a token on the front end, encountering an error when verifying it with the google-auth- ...

Preventing a Click Event on Child Element from Triggering the Parent's Click Event in jQuery

Can you help me figure out how to prevent a button from executing the onclick function of its parent div in this example? <div onclick="$('#extra-info').slideToggle();" class="card card-body item"> <div class="ro ...

Use CSS media queries to swap out the map for an embedded image

Looking to make a change on my index page - swapping out a long Google Map for an embedded image version on mobile. The map displays fine on desktop, but on mobile it's too lengthy and makes scrolling difficult. I already adjusted the JS setting to "s ...

Error in MEAN Stack: Unable to access the property 'companyTitle' because it is undefined

I have established a MongoDB collection named joblist in my database. Additionally, I have developed a DB schema known as jobList.js. var mongoose = require('mongoose'); const joblistSchema = mongoose.Schema({ companyTitle: String, jobT ...

The browser encountered an issue trying to load a resource from a directory with multiple nested levels

I've stumbled upon an unusual issue. Here is a snapshot from the inspector tools. The browser is unable to load certain resources even though they do exist. When I try to access the URL in another tab, the resource loads successfully. URLs in the i ...

Utilize the grouping functionality provided by the Lodash module

I successfully utilized the lodash module to group my data, demonstrated in the code snippet below: export class DtoTransactionCategory { categoryName: String; totalPrice: number; } Using groupBy function: import { groupBy} from 'lodash&apo ...

The Angular performance may be impacted by the constant recalculation of ngStyle when clicking on various input fields

I am facing a frustrating performance issue. Within my component, I have implemented ngStyle and I would rather not rewrite it. However, every time I interact with random input fields on the same page (even from another component), the ngStyle recalculate ...

Modifying the language of the response (error/success) in stripe.js

I have successfully implemented stripe.js v2 for processing payments in my application catering to a French client. Everything is working smoothly, but I am facing an issue with form validation. I want the error messages to be displayed in French instead o ...

Obtaining the name of the image that has been uploaded using jQuery

//Image upload function $(function() { $(":file").change(function() { if (this.files && this.files[0]) { var reader = new FileReader(); reader.onload = imageIsLoaded; reader.readAsDataURL(this.files[0]); } }); }); function im ...

The error message is indicating that the property `match` is being attempted on an undefined object. This issue is puzzling as it does not reference any specific files or

I encountered an issue while working on my project: I kept receiving the error message "Cannot read property match of undefined." Cannot read property 'match' of undefined The error points to a specific line in polyfills.js: process.version.ma ...