[SalesForce] Lightning Components and the tag (not icons)

I have a visualization library written in javascript that uses <svg /> elements to create a visual representation of some data. As with any vanilla javascript library there is a lot of code in there that is dedicated to actually manipulating the DOM. Aura (Lightning Components) seems like a great fit for this because I could simply use their rendering via <aura:iteration>, etc. to create my markup. However, I need to use the <svg /> tag. This is not for icons with <use /> but instead for a container with other graphical elements such as <mask />, <line />, <rect />, etc. I know that <svg /> has not been supported from day 1, but it has been years now and support is still not there. Originally the messaging was that this was a bug and would be fixed, but I have not heard any updates. Is this actually on the roadmap or is true <svg /> support something we are unlikely to ever see in the framework (maybe there is some security issue I am not aware of?).

Note: I understand that there are workarounds to get the tag to work, but I am hoping to move to Lightning Components to make maintenance easier. Implementing and maintaining a custom renderer would likely be more overhead than just using the vanilla javascript library I have today.

Best Answer

Here is how you can display SVGs, it's not ideal because the source is hard-coded but this technique should get you started.

Add this in your markup:

<aura:handler name="init" value="{!this}" action="{!c.onInit}"/>
<aura:unescapedHtml aura:id="mySvg"/>

Then, add the following JS in your controller:

onInit : function(component, event, helper) {
    const svgSource = '<svg width="100" height="100">'
        +'<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="#4CAF50"/>'
        +'<text fill="#ffffff" font-size="12" font-family="Verdana" x="25" y="50">It works!</text>'
        +'</svg>';
    component.find('mySvg').set('v.value', svgSource);
}

Another way of achieving this is to write a custom renderer for your component. this way you can work with the DOM but it's far more trickier.