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.