Designing engaging svg maps with vue.js functionality

As a newcomer to Vue, I have experience working with SVG interactive maps using JavaScript and d3.js to manipulate DOM elements. Now, I am attempting to integrate these maps into the Vue framework and facing challenges.

I have created SvgMap.vue component that includes an inline SVG map.

<template>
<svg id="karta"
     :class="name"
     xmlns="http://www.w3.org/2000/svg" 
     width="1400" 
     height="960" 
     viewBox="0 0 1400 960">
<g id="wrap">
 <g id="lake">
   <path  d="....">
 </g>
 <g id="area1" class="pol">
   <path  d="....">
 </g>
 <g id="area2" class="pol">
   <path  d="....">
 </g>
 ....
</g>
</svg>
</template>

The aim of SvgMap.vue component is to contain all the necessary map data (regions, rivers, lakes, cities, etc.) so that other Vue components can import <svg-map> for customization based on what the map represents. For instance, RegionMap.vue may only display regions without other elements like rivers, cities, or lakes. Therefore, the ability to modify SVG attributes is essential. While some changes can be achieved through scoped styles and CSS, there are times when JavaScript intervention is required.

In RegionMap.vue:

<template>
  <svg-map name="Region"></svg-map>
</template>

<style scoped>
#karta /deep/ #wrap .pol {
    fill:red
}

#karta /deep/ #wrap .pol:hover {
    fill:black     
}
</style>

Sometimes, direct manipulation of SVG elements using JavaScript is necessary for dynamic changes. A simplified example could involve selecting all elements with the class .pol and changing their fill color to pink. However, attempts to achieve this within the Vue component's script section using the created() lifecycle hook resulted in errors.

<script>
import SvgMap from "./SvgMap"

export default {
    name: "RegionMap",

    components: {
        SvgMap
    },

    created(){
    var pol = document.getElementsByClassName("pol")
    pol.setAttribute("style", "fill:pink")
    }
  }
 </script>

Although the code successfully identified the target elements as an HTMLCollection, an error stating that setAttribute is not a function was encountered. This raises questions about how to effectively access specific elements within the main SVG map Component and alter them dynamically without relying solely on props and CSS styling.

If you have any suggestions on how to address this issue or if there's a better approach to achieving this task, please share your insights. The strategy of having a central SVG map component for reusability aims to streamline updates across multiple components whenever changes to map data occur.

Answer №1

Just had a breakthrough! I finally figured out why the code wasn't working. Turns out, the JavaScript code needs to be placed in the mounted property instead of inside the created property. It's puzzling why it works this way, especially considering that Vue runs the created() hook when the component object is created and before it's mounted to the DOM. My instincts tell me it should work either way. If anyone has insight into this, I'd love to hear it. In any case, it's now functioning perfectly.

Answer №2

By exploring the details of the created hook here, it is pointed out that towards the end:

However, keep in mind that the mounting phase has not initiated yet, and hence the $el property will not be accessible at this point.

During the execution of the created hook, the component is still not mounted, which means it is not present in the DOM yet! For a better understanding, take a look at the lifecycle diagram :)

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

Automatically collapse the responsive menu upon selecting a menu item

I have implemented a custom JavaScript code for a basic open/close menu movement on multi-page websites. The code works by closing the menu only when the user clicks the menu symbol. However, I now need to incorporate this code into a one-page website and ...

Utilizing nested array object values in ReactJS mappings

My JSON API is set up to provide a data structure for a single record, with an array of associations nested within the record. An example of the response from the api looks like this: { "name":"foo", "bars":[ { "name":"bar1" ...

Executing a conditional onClick function when the page loads

I have implemented a php-based authorization system that loads different authorization levels into a JavaScript variable. My goal is to disable certain onclick events based on the user's authorization level. I've come up with the following code ...

Node.js causing excessive CPU usage due to repeated gettimeofday calls

Recently, I encountered a situation with a long-running node.js process that would occasionally spike to 100% CPU usage and stop responding to requests. In an effort to diagnose the issue, I used strace to inspect the process and discovered a series of get ...

Present Images and Text Alongside Each Other in a Grid Layout

My goal is to have an image and text displayed side by side, but for some reason they are appearing stacked on top of each other. https://i.stack.imgur.com/F8OXL.png If you want to take a look at the code I am using, here is the link to my CodePen: https: ...

Can I safely temporarily overwrite a prototype method in a route handler in express?

I'm currently facing a scenario where I have an object containing numerous instances of the Date data type. This object is then converted into JSON format and returned as follows: router.post('/', function () { // Some code that retur ...

Position the text to the left of the floating paragraph on the right

I am looking to align some text on the right side of the page with consistent starting positions. Each paragraph has two spans, one floated left and the other floated right. Here is an example with HTML and an image included for clarity. .card { ma ...

Uploading images in Summernote using AJAX triggers a page refresh

My current task involves enabling image uploads from the summernote plugin to the server using AJAX and ASP.NET MVC. After studying various examples, I have managed to develop the following JavaScript code: Initialization: $('#contentEditor').su ...

Capturing all response requests from the main process in Electron: A step-by-step guide

I am looking to retrieve the responses for all requests made in my electron app from the main process. In this image, it shows that the desired response can be found in the Response tab rather than the Headers tab on Chrome Dev Tools. Instead of using a ...

Creating a dropdown menu that functions for 24 hours non-stop by utilizing the Array.from( Array(n) )

Struggling to make my code less dense, I'm looking for the best way to implement a dropdown menu that allows users to choose between options 1-24 while the array is nested within an object. Thoughts? I'm working on a chrome extension that genera ...

Tips for utilizing ng-repeat with standard JSON data structures

I have a JSON structure like this: [{ Entry: [{ ID:123, Name: 'XYZ', Address: '600, PA' }, { ID:123, Name: 'ABC', Address: '700, PA' }, { ID:321, Name: 'RRR', ...

retrieve data from JSON file

function retrieveDataFromProfiles(){ const fs = require('fs') fs.readFile('src/data/profileInfo.json', function(error, data){ if(error){ alert(error); } var profileData = JSON.parse(data); //retrieves the JSON data of ...

Arrange two elements next to each other within a container div

I thought this task would be a piece of cake, but after staring at it for the past half hour, I'm still stumped. Check out the HTML code below: <div style="width: 250px;"> <img style="float: left; width: 20px;" src="public/_images/ok_kutu ...

Discovering the following element containing an ID attribute with jQuery

Upon clicking a link, my goal is to locate the subsequent <section> with an ID attribute and retrieve its ID. In the provided code snippet and JavaScript function, the expected outcome upon clicking the link is for "section_3" to be logged in the co ...

RTL in TextInput only functions properly every other time it is rendered

I am facing a strange problem with RTL where everything seems to be flipped correctly except for TextInput, which only works about half of the time. Check out this gif that demonstrates the issue as I switch between English and Hebrew: (click to view a la ...

Angular tree dropdown menu structure

Check out this functional jsfiddle: working example for the secondary level In the jsfiddle, I am able to assign a brand from the first dropdown and a model from the second dropdown to each car created through ng-repeat. It is all working smoothly. Howev ...

What is the best way to alter the color of the text cursor using html/css?

I'm a beginner when it comes to HTML and CSS, so my knowledge about them is quite limited. I recently encountered an issue where my text cursor disappears when the background-color of a <div> element is dark. Here's an example: <style&g ...

Issues with the loading and display of Bootstrap Carousels

Hey there! I'm facing an issue with implementing a Bootstrap carousel on my website. Despite trying out several examples from Bootsnip and even the one from the official Bootstrap website, the carousel slides are not working as expected. Any ideas on ...

Issue with Scrollspy Functionality in Bootstrap 4

Scrollspy feature isn't working in my code. <nav class="navbar navbar-expand-lg fixed-top navbar-dark" role="navigation"> <div class="container"> <a class="navbar-brand" href="#featured"><h1></h1></a> < ...

Is it possible to enhance the appearance of the select2 options in any way?

I am currently using a select2 plugin to handle select boxes, where the options are generated by concatenating two values together. However, I am looking for a way to style one of the values in the select2 box with a different color. Are there any options ...