Skip to content

Instantly share code, notes, and snippets.

@bobbae
Last active May 20, 2025 17:56
Show Gist options
  • Select an option

  • Save bobbae/e66b7b1004705bee9ce9f130acaec9ff to your computer and use it in GitHub Desktop.

Select an option

Save bobbae/e66b7b1004705bee9ce9f130acaec9ff to your computer and use it in GitHub Desktop.
mermaid js diagram renderer
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mermaid Diagram Renderer</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
margin: 0;
padding: 20px;
background-color: #f0f2f5;
color: #333;
display: flex;
flex-direction: column;
align-items: center;
}
h1 {
text-align: center;
color: #1a237e; /* Dark blue */
margin-bottom: 20px;
}
.controls {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
width: 90%;
max-width: 700px;
box-sizing: border-box;
}
textarea {
width: 100%; /* Full width of parent .controls */
height: 200px;
padding: 10px;
font-family: monospace;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
margin-bottom: 15px;
box-sizing: border-box;
resize: vertical;
}
button {
display: block;
width: 100%; /* Full width of parent .controls */
padding: 12px 20px;
font-size: 16px;
font-weight: bold;
color: white;
background-color: #28a745; /* Green */
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s ease-in-out;
}
button:hover {
background-color: #218838; /* Darker green */
}
.mermaid {
margin-top: 20px;
padding: 20px;
border: 1px solid #e0e0e0;
border-radius: 8px;
background-color: #ffffff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
display: flex;
justify-content: center;
align-items: center;
min-height: 100px;
width: 90%;
max-width: 700px;
box-sizing: border-box;
}
.mermaid svg {
max-width: 100%; /* Ensure SVG is responsive */
height: auto; /* Maintain aspect ratio */
}
#err {
margin-top: 15px;
padding: 10px 15px;
background-color: #f8d7da; /* Light red for errors */
color: #721c24; /* Dark red text for errors */
border: 1px solid #f5c6cb;
border-radius: 4px;
white-space: pre-wrap;
word-break: break-all;
width: 90%; /* Match .controls and .mermaid width */
max-width: 700px; /* Match .controls and .mermaid max-width */
box-sizing: border-box;
}
#err:empty {
display: none; /* Hide error box if empty */
}
</style>
</head>
<body>
<h1>Mermaid Diagram Renderer</h1>
<div class="controls">
<textarea>
mermaid
graph LR
subgraph Core Layer
C1[Core Router 1]
C2[Core Router 2]
end
subgraph Distribution Layer
D1[Dist. Switch 1]
D2[Dist. Switch 2]
D3[Dist. Switch 3]
end
subgraph Access Layer A
A1[Access Switch 1]
A2[Access Switch 2]
A3[Access Switch 3]
A4[Access Switch 4]
end
subgraph Access Layer B
B1[Access Switch 5]
B2[Access Switch 6]
B3[Access Switch 7]
B4[Access Switch 8]
end
C1 --> D1 & D2
C2 --> D2 & D3
D1 --> A1 & A2
D2 --> A2 & A3 & B1
D3 --> A4 & B2 & B3 & B4
style C1 fill:#f9f,stroke:#333,stroke-width:2px
style C2 fill:#f9f,stroke:#333,stroke-width:2px
style D1 fill:#ccf,stroke:#333,stroke-width:2px
style D2 fill:#ccf,stroke:#333,stroke-width:2px
style D3 fill:#ccf,stroke:#333,stroke-width:2px
</textarea>
<button onclick="mermaidDraw()">Render Diagram</button>
</div>
<div class="mermaid"></div>
<pre id="err"></pre>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.9.0/mermaid.min.js"></script>
<script>
mermaid.initialize({
startOnLoad: true
});
eleM = document.querySelector('.mermaid');
eleE = document.querySelector('#err');
setTimeout(mermaidDraw, 200);
async function mermaidDraw() {
try {
eleE.innerHTML = ''; // Clear previous errors
graphDefinition = await mermaidEval('LocalFile.md');
const {
svg
} = await mermaid.render('graphDiv', graphDefinition);
eleM.innerHTML = svg;
} catch (err) {
if (err instanceof ReferenceError) {
varname = err.message.split(' ')[0];
window[varname] = varname;
setTimeout(mermaidDraw, 0);
}
console.error(err);
eleE.insertAdjacentHTML('beforeend', `🚫 ${err.message}\n`);
}
};
async function mermaidEval(url) {
text = document.querySelector('textarea').value;
if (!text.match(/^[a-zA-Z]/)) {
// markdown ```mermaid, remove first and last line
text = text.split('\n').slice(1, -1).join('\n');
}
text = text.replace(/"`.*?`"/g, function(match) {
return eval(match.slice(1, -1));
});
text = text.replace(/"\{.*?\}"/g, function(match) {
return eval(match.slice(1, -1));
});
return text;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment