Summary
Add into streamlit an svg image that can provide interactivity.
More specifically, I am looking to add an svg image generated by Graphviz into my streamlit project.
Furthermore, be able to react to clicks on such an image.
Find details in this github: GitHub - susuhahnml/streamlit-issue: Describing the streamlit feature-issue
I tried something as suggested in Display SVG - #4 by jeremie
Steps to reproduce
Streamlit app
import streamlit as st
import base64
def render_svg(svg):
"""Renders the given svg string."""
b64 = base64.b64encode(svg.encode('utf-8')).decode("utf-8")
html = r'<img src="data:image/svg+xml;base64,%s"/>' % b64
c = st.container()
c.write(html, unsafe_allow_html=True)
render_svg(open("issue/default.svg").read())
I can not listen to the clicks on the svg image
SVG to include
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 8.1.0 (20230707.0739)
-->
<!-- Title: default Pages: 1 -->
<svg width="62pt" height="116pt"
viewBox="0.00 0.00 62.00 116.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)">
<title>default</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-112 58,-112 58,4 -4,4"/>
<!-- b -->
<g id="node1" class="node">
<title>b</title>
<ellipse fill="none" stroke="black" cx="27" cy="-18" rx="27" ry="18"/>
<text text-anchor="middle" x="27" y="-12.95" font-family="Times,serif" font-size="14.00">b</text>
</g>
<!-- a -->
<g id="node2" class="node">
<title>a</title>
<polygon fill="none" stroke="red" points="54,-108 0,-108 0,-72 54,-72 54,-108"/>
<text text-anchor="middle" x="27" y="-84.95" font-family="Times,serif" font-size="14.00">a</text>
</g>
<!-- a--b -->
<g id="edge1" class="edge">
<title>a--b</title>
<path fill="none" stroke="black" d="M27,-71.7C27,-60.85 27,-46.92 27,-36.1"/>
</g>
</g>
<script>
<script type="text/javascript">
var nodes = Object.values(document.getElementsByClassName('node'));
window.onload=function(){
nodes.forEach(node=>{
node.addEventListener("click", function() {
console.log("On click")
console.log(node)
node.style['opacity']='0.2'
})
})
}
</script>
</script>
</svg>
Debug info
- Streamlit version: 1.26
- Python version: 3.10.12
- Using Conda
- OS version: MAC OS
- Browser version: Same for different edditions
Other
I also tried adding the svg directly like described in the github but the svg componets are reordered