Incorporating an external SVG file into an Angular project and enhancing a particular SVG element within the SVG with an Angular Material Tooltip, all from a TypeScript file

Parts of the angular code that are specific

|SVG File|

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
     width="950" height="450" viewBox="0 0 1280.000000 1119.000000"
     preserveAspectRatio="xMidYMid meet">
<circle r="50px" cx="650" cy="968" fill="red" stroke="black" visibility="visible"/>
  <rect x="650.117" y="968.413" width="1000" height="800" fill="green" visibility="visible"/>
</svg>

|HTML File|

<object #svgmyimage>
</object>

|Type Script File|

 @ViewChild('svgmyimage') imageSvg?:ElementRef;

 ngOnInit() {
    this.reset();
    this.httpClient
          .get(`assets/svgimages/image1.svg`, { responseType: 'text' })
          .subscribe((value: string) => {
            this.svgStr = value;
//             console.log(this.svgStr);
            this.drawImage();
          });

  }

  drawImage() {
    if (this.imageSvg && this.svgStr) {

      this.imageSvg.nativeElement.innerHTML = this.svgStr;

      if(this.imageSvg.nativeElement.children[0])
      {
          this.imageSvg.nativeElement.children[0]setAttribute('visibility', 'visible');
          this.imageSvg.nativeElement.children[1]setAttribute('fill', 'yellow');
      }

    }
  }

It is possible to access and modify attributes in order to incorporate an Angular Material Tooltip. The tooltip property can be utilized within the HTML file itself, with the requirement that the entire SVG code is contained within the HTML rather than being referenced as an external file. Assistance is needed on how to achieve this.
As

this.imageSvg.nativeElement.children[0]setAttribute('matTooltip', 'information');

does not make sense since Tooltip is not a property of the SVG. Therefore, the query remains on how to add a tooltip specifically to the circle element in the externally linked SVG file from the Typescript file. The objective is to implement a tooltip solely for the circle in the SVG!

Answer №1

When creating a tooltip, there are two approaches we can take: using popperjs (such as ng-bootstrap or bootstrap) or utilizing the built-in cdkoverlay (like material angular).

To implement ckdoverlay, we need to inject Overlay in the constructor, create a Portal, and then attach it on mouseenter and detach it on mouseleave. If we prefer using HTMLElements, we can create a class to encapsulate all the functionality.

 // code example goes here

An important aspect when using DomPortal is that it remains in the .html when not attached—we can also opt for a TemplatePortal, but that requires injecting a ViewContainerRef as well. To show/hide the tooltip, we can toggle its visibility with typical CSS:

.tooltip {
  ...
  display:none;
}

.tooltip[data-show] {
  display:block
}

Another crucial detail is indicating the position conveniently as top, bottom, left, or right. This can be achieved by defining an object like this:

// Code snippet goes here 

With this class, we have two options: either use it as a directive or integrate it into a component that injects OverLay.

// Code snippet goes here 

In an HTML example, you can include the directive as follows:

// Code snippet goes here 

In case you prefer using the library in a TypeScript component, ensure to properly initialize and later destroy the TooltipOverLay instance:

// Code snippet goes here 

You can find an example showcasing both methods in the following stackblitz. Alternatively, you can explore another demonstration by forking GRM's code and adapting it to attach a tooltip to an inner element of an SVG in this modified stackblitz.

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

a helpful utility type for extracting a union from a constant array of strings

I create string arrays using const assertions and then use them to generate union types. const elements = ["apple", "banana", "orange"] as const; type elementsUnion = typeof elements[number]; // type elementsUnion = "appl ...

What methods does Angular use to display custom HTML tags in IE9/10 without causing any issues for the browser?

Exploring web components and utilizing customElements.define tends to cause issues in IE9/10. I've noticed that Angular is compatible with IE9/10, and upon inspecting the DOM tree, it seems like Angular successfully displays the custom element tags. ...

Tips for showcasing styled text in Vue using API data

I'm having trouble formatting text in Vue. Within a component, I have a textarea that stores a string with backspaces, etc ... in an API like this: A cellar but not only...\n\nWelcome to the Nature & Wine cellar, a true Ali-baba's cave ...

Exploring the power of Vue CLI service in conjunction with TypeScript

I've recently set up a Vue project using the Vue CLI, but now I am looking to incorporate TypeScript into it. While exploring options, I came across this helpful guide. However, it suggests adding a Webpack configuration and replacing vue-cli-service ...

Showcasing a single JSON object in an Angular application

After receiving a Json object from an API, I attempted to display it in my component with no success. Below is the code snippet of my component: selector: 'app-links-page-detail', templateUrl: './links-page-detail.component.html', ...

Bar chart in Chart.js becomes crowded and illegible on smaller screens due to overlapping bars

Hello there! I've encountered an issue where the bar chart overlaps when the screen width is too low. It seems to be related to the maintainAspectRatio property, which I set to false because I wanted the charts to shrink only in width, not in both axe ...

Issue with Nuxt: Property accessed during rendering without being defined on the instance

As I attempt to create cards for my blog posts, I encountered an issue with a Post component in my code. The cards are displaying like shown in the picture, but without any text. How do I insert text into these cards? Currently, all the text is within attr ...

Determine parameter types and return values by analyzing the generic interface

I am currently working on a feature where I need to create a function that takes an interface as input and automatically determines the return types based on the 'key' provided in the options object passed to the function. Here is an example of ...

Problems encountered while building TypeScript on Azure's Hosted Agent

I'm currently working on an ASP.NET MVC application built in .Net5 that utilizes TypeScript files and includes NuGet package references for the following: <PackageReference Include="BuildBundlerMinifier" Version="3.2.449" /> ...

What is the meaning of '=>' in typescript/javascript?

I keep coming across lots of '=>' in the code I found on the internet. Could someone please explain it to me as if I were 5 years old? (I'm searching for the specific code, and I'll share it here once I locate it).. Found it: ...

Compilation with Webpack and Postcss failed due to the inability to locate the scss file within the library in node_modules

Here is the layout of my project structure: node_modules dist config - webpack.common.js - webpack.dev.js - webpack.prod.js - webpack.test.js src - app - app-routing.module.ts - app.component.html - app.component.scss - app.compo ...

Ionic 2 - Dynamically Loading Segments

I am dealing with categories and dishes. Each dish is associated with a specific category. My goal is to send an http request to retrieve all the dishes belonging to a particular category. This will result in an array like: { Soup[{'Name',&ap ...

Tips for deleting multiple objects from an array in angular version 13

I am facing an issue where I am trying to delete multiple objects from an array by selecting the checkbox on a table row. However, I am only able to delete one item at a time. How can I resolve this problem and successfully delete multiple selected objects ...

Datatable - pagination - retrieving data from a specific page

Can someone tell me how to retrieve the records from a specific page in a PrimeNG datatable using Angular 2.0? ...

Best Practices for Architecture and Routing in Angular 8 (suggestions)

As a newcomer to Angular, I find myself grappling with the recommended architecture for my project. In an effort to streamline my inquiry, I will structure it in the form of choosing between options A or B and exploring how to implement that choice. Specif ...

What is the connection between @types, TypeScript, and Webpack?

When using an exported type in a .ts file, it is necessary to import it: import {jQuery} from 'jQuery' Even after adding the import, intellisense may not work until npm install @types\jQuery is executed. If @types are installed, intellis ...

What is the reason behind the command "npm-install" placing files directly into the root directory?

After pulling my front-end project from the repository, I noticed that the node_modules folder was missing. My usual approach is to use npm install to get all the dependencies listed in the package.json file installed. However, this time around, I ended u ...

Prevent a React component from unnecessarily re-rendering after a property has been set

I am working on a react component that displays a streaming page similar to the one shown in this image. Here is a snippet of the code : const [currentStream, setCurrentStream] = useState<IStream>(); const [currentStreams] = useCollectionData<ISt ...

The module ~/assets/images/flags/undefined.png could not be found in the directory

When I use the img tag with a dynamic address filled using require, it works well in the component. However, when I try to write a test for it, an error is thrown. console.error Error: Configuration error: Could not locate module ~/assets/ima ...

storing information in localStorage using react-big-calendar

Incorporating react-big-calendar into my project, I encountered a problem where the events in the calendar would disappear upon page refresh despite saving them in localStorage. I had planned to store the events using localStorage and retrieve them later, ...