Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect bounding box for htmlLabels with images in Mermaid v10.2.0 #4455

Closed
aloisklink opened this issue Jun 4, 2023 · 3 comments
Closed
Labels
Graph: Flow Status: Triage Needs to be verified, categorized, etc Type: Bug / Error Something isn't working or is incorrect

Comments

@aloisklink
Copy link
Member

aloisklink commented Jun 4, 2023

Description

Images in flowcharts used to work fine in Mermaid v10.1.0 or before, but in Mermaid v10.2.0, the boxes are now smaller, and longer automatically expand to fit the entire image.

This was caught by mermaid-cli's automated visual regression tests, see mermaid-js/mermaid-cli#541 (review)

Steps to reproduce

Copy in the code sample below in Mermaid v10.1.0 and v10.2.0 (or commit d132d26 and 9bb0cef).

However, they both do not work with the mermaid.live editor. So you may find it easier to add the following patch to the demos/flowchart.html file:

diff --git a/demos/flowchart.html b/demos/flowchart.html
index 02405c5e..f259717a 100644
--- a/demos/flowchart.html
+++ b/demos/flowchart.html
@@ -1505,6 +1505,16 @@
     </pre>
     <hr />
 
+    <pre class="mermaid">
+      graph TD
+      B[&quot;fa:fa-car for peace&quot;]
+      B--&gt;C[fa:fa-ban forbidden]
+      B--&gt;D(fa:fa-spinner);
+      B--&gt;E(A fa:fa-camera-retro perhaps?);
+      %% Test whether embed &lt;img&gt; work correctly
+      D--&gt;F(&quot;&lt;img height='100' width='100' src='data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22%3E%3Ccircle cx=%2250%22 cy=%2250%22 r=%2240%22 stroke=%22black%22 stroke-width=%223%22 fill=%22red%22 /%3E%3C/svg%3E'/&gt; &lt;br/&gt; Red Circle&quot;)
+    </pre>
+
     <h1 id="link-clicked">Anchor for "link-clicked" test</h1>
 
     <script type="module">

Screenshots

Working in Mermaid v10.1.0

SVG (may miss fontawesome fonts when rendered on GitHub)

v10-1-0

PNG

v10-1-0

Broken in Mermaid v10.2.0

SVG (may miss fontawesome fonts when rendered on GitHub)

v10-2-0

PNG

v10-2-0

Code Sample

graph TD
    B["fa:fa-car for peace"]
    B-->C[fa:fa-ban forbidden]
    B-->D(fa:fa-spinner);
    B-->E(A fa:fa-camera-retro perhaps?);
    %% Test whether embed <img> work correctly
    D-->F("<img height='100' width='100' src='data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22%3E%3Ccircle cx=%2250%22 cy=%2250%22 r=%2240%22 stroke=%22black%22 stroke-width=%223%22 fill=%22red%22 /%3E%3C/svg%3E'/> <br/> Red Circle")

Setup

  • Mermaid version: v10.2.0
  • Browser and Version: Chrome

Additional Context

I've done a diff on the output SVGs, after passing the SVGs through an XML prettier to make it a bit prettier:

< <svg aria-roledescription="flowchart-v2" role="graphics-document document" viewBox="-8 -8 353.140625 322" height="322"
---
> <svg aria-roledescription="flowchart-v2" role="graphics-document document" viewBox="-8 -8 353.140625 337" height="337"
4c4
<     <style>#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#000000;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:2px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#000000;stroke:#000000;}#my-svg .marker.cross{stroke:#000000;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#000000;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span,#my-svg p{color:#333;}#my-svg .label text,#my-svg span,#my-svg p{fill:#000000;color:#000000;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#cde498;stroke:#13540c;stroke-width:1px;}#my-svg .flowchart-label text{text-anchor:middle;}#my-svg .node .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .arrowheadPath{fill:green;}#my-svg .edgePath .path{stroke:#000000;stroke-width:2.0px;}#my-svg .flowchart-link{stroke:#000000;fill:none;}#my-svg .edgeLabel{background-color:#e8e8e8;text-align:center;}#my-svg .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#my-svg .cluster rect{fill:#cdffb2;stroke:#6eaa49;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span,#my-svg p{color:#333;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(78.1578947368, 58.4615384615%, 84.5098039216%);border:1px solid #6eaa49;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#000000;}#my-svg .node rect{fill:white;}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
---
>     <style>#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#000000;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:2px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#000000;stroke:#000000;}#my-svg .marker.cross{stroke:#000000;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#000000;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span,#my-svg p{color:#333;}#my-svg .label text,#my-svg span,#my-svg p{fill:#000000;color:#000000;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#cde498;stroke:#13540c;stroke-width:1px;}#my-svg .flowchart-label text{text-anchor:middle;}#my-svg .node .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .arrowheadPath{fill:green;}#my-svg .edgePath .path{stroke:#000000;stroke-width:2.0px;}#my-svg .flowchart-link{stroke:#000000;fill:none;}#my-svg .edgeLabel{background-color:#e8e8e8;text-align:center;}#my-svg .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#my-svg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#my-svg .cluster rect{fill:#cdffb2;stroke:#6eaa49;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span,#my-svg p{color:#333;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(78.1578947368, 58.4615384615%, 84.5098039216%);border:1px solid #6eaa49;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#000000;}#my-svg .node rect{fill:white;}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
6c6
<         <marker orient="auto" markerHeight="12" markerWidth="12" markerUnits="userSpaceOnUse" refY="5" refX="10" viewBox="0 0 12 20" class="marker flowchart" id="flowchart-pointEnd">
---
>         <marker orient="auto" markerHeight="12" markerWidth="12" markerUnits="userSpaceOnUse" refY="5" refX="10" viewBox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd">
131,133c131,133
<                 <g transform="translate(165.4921875, 237)" id="flowchart-F-26" class="node default default flowchart-label">
<                     <rect height="138" width="115" y="-69" x="-57.5" ry="5" rx="5" style="" class="basic label-container"/>
<                     <g transform="translate(-50, -61.5)" style="" class="label">
---
>                 <g transform="translate(165.4921875, 244.5)" id="flowchart-F-26" class="node default default flowchart-label">
>                     <rect height="153" width="87.84375" y="-76.5" x="-43.921875" ry="5" rx="5" style="" class="basic label-container"/>
>                     <g transform="translate(-36.421875, -69)" style="" class="label">
135c135
<                         <foreignObject height="123" width="100">
---
>                         <foreignObject height="138" width="72.84375">
139c139
<                                     <img src="data:image/svg+xml,%3Csvg
---
>                                     <img style="display: flex; flex-direction: column; width: 100%;" src="data:image/svg+xml,%3Csvg

It looks like the change was in PR #4268, or commit 9bb0cef.

Edit: I've done some testing and confirmed that commit 9bb0cef is the one that changed this behavior.

@aloisklink aloisklink added Type: Bug / Error Something isn't working or is incorrect Status: Triage Needs to be verified, categorized, etc Graph: Flow labels Jun 4, 2023
@aloisklink aloisklink changed the title Regression in v10.2.0, boxes in flowcharts crop images Incorrect bounding box for htmlLabels with images in Mermaid v10.2.0 Jun 4, 2023
@Valentine14th
Copy link
Contributor

Hi,

I'm the one who wrote PR #4268. Sorry about this issue.
The way the code is supposed to work is to scale the images to the width of the text in the same node by setting width=100% in the node style. This works with most images, however for this svg it seems that it crops it instead of scaling it. I'm not an svg expert but it seems like it is because it doesn't have a viewBox attribute. If you use this slightly modified svg with a viewBox:

<img height='100' width='100' src='data:image/svg+xml,%3Csvg viewBox=%220 0 100 100%22 xmlns=%22http://www.w3.org/2000/svg%22%3E%3Ccircle cx=%2250%22 cy=%2250%22 r=%2240%22 stroke=%22black%22 stroke-width=%223%22 fill=%22red%22 /%3E%3C/svg%3E'/>

the image is not cropped anymore. So

graph TD
      B["fa:fa-car for peace"]
      B-->C[fa:fa-ban forbidden]
      B-->D(fa:fa-spinner);
      B-->E(A fa:fa-camera-retro perhaps?);
      %% Test whether embed <img> work correctly
      D-->F("<img height='100' width='100' src='data:image/svg+xml,%3Csvg viewBox=%220 0 100 100%22 xmlns=%22http://www.w3.org/2000/svg%22%3E%3Ccircle cx=%2250%22 cy=%2250%22 r=%2240%22 stroke=%22black%22 stroke-width=%223%22 fill=%22red%22 /%3E%3C/svg%3E'/> <br/> Red Circle")

renders a
redcircle

I am not sure how big of an issue that is?

aloisklink added a commit to aloisklink/mermaid-cli that referenced this issue Jun 10, 2023
Mermaid v10.2.0 changed some behavior for htmlLabels with embedded
SVG images. The `width=100%` is now set in the node CSS, which normally
scales the images to the width of the text, but for this SVG, it seems
to crop it. See mermaid-js/mermaid#4455.

Setting a well-defined `viewBox` attribute to our SVG fixes this.

Co-authored-by: Laura Valentine Tscharner <[email protected]>
@aloisklink
Copy link
Member Author

I'm the one who wrote PR #4268. Sorry about this issue.

No worries! The image rendering improvements in PR #4268 seem really useful. To be honest, this might be my fault, I'm not an expert on SVGs, but from some quick googling, it sounds like SVGs without a viewBox have weird behaviors, and some browsers treat them differently.

In fact, adding a viewBox also makes the mermaid diagram work correctly on https://mermaid.live too!

I'm going to close this issue, since it sounds like missing a viewBox in SVGs have strange behaviors in most browsers, but I'm an SVG novice, so I'm happy to re-open this if somebody more knowledgeable about SVGs/browsers chimes in.

If you use this slightly modified svg with a viewBox:

@Valentine14th, do you mind if I submit the change you've recommended to the mermaid-cli project and credit you as a Co-author? I've tested the change, and adding a viewBox works great!

@Valentine14th
Copy link
Contributor

Valentine14th commented Jun 11, 2023

@Valentine14th, do you mind if I submit the change you've recommended to the mermaid-cli project and credit you as a Co-author? I've tested the change, and adding a viewBox works great!

@aloisklink Of course go ahead! Thank you!

MindaugasLaganeckas pushed a commit to mermaid-js/mermaid-cli that referenced this issue Jun 12, 2023
Mermaid v10.2.0 changed some behavior for htmlLabels with embedded
SVG images. The `width=100%` is now set in the node CSS, which normally
scales the images to the width of the text, but for this SVG, it seems
to crop it. See mermaid-js/mermaid#4455.

Setting a well-defined `viewBox` attribute to our SVG fixes this.

Co-authored-by: Laura Valentine Tscharner <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Graph: Flow Status: Triage Needs to be verified, categorized, etc Type: Bug / Error Something isn't working or is incorrect
Projects
None yet
Development

No branches or pull requests

2 participants