Skip to content

Instantly share code, notes, and snippets.

@kiennq
Last active March 18, 2025 22:38
Show Gist options
  • Save kiennq/890bebf82a801867ba2366b03ea47d35 to your computer and use it in GitHub Desktop.
Save kiennq/890bebf82a801867ba2366b03ea47d35 to your computer and use it in GitHub Desktop.
Enable `Mermaid diagrams` on github wiki and markdown files
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.pnp.*
// ==UserScript==
// @name Mermaid Diagrams
// @namespace https://gist.github.com/kiennq
// @version 1.1.6
// @author Kien Nguyen <kien.n.quang at gmail dot com>
// @description Enable `Mermaid diagrams` on github wiki and markdown files
// @homepage https://github.com/Redisrupt/mermaid-diagrams
// @downloadURL https://gist.github.com/kiennq/890bebf82a801867ba2366b03ea47d35/raw/mermaid-diagrams.user.js
// @updateURL https://gist.github.com/kiennq/890bebf82a801867ba2366b03ea47d35/raw/mermaid-diagrams.user.js
// @match https://*.visualstudio.com/*
// @match https://dev.azure.com/*
// @match https://github.com/*
// @match https://gist.github.com/*
// @match https://bitbucket.org/*
// @match file:///*
// @run-at document-idle
// @grant none
// ==/UserScript==
(async () => {
'use strict';
console.log('Load');
const $ = (selector, ctx = document) => [].slice.call(ctx.querySelectorAll(selector));
const { default: mermaid } = await import('https://cdn.jsdelivr.net/npm/[email protected]/+esm');
mermaid.initialize({
startOnLoad: false,
theme: 'neutral',
look: 'handDrawn ',
layout: 'elk',
});
function addGlobalStyle(css) {
let head = $('head')[0];
if (!head) { return; }
let style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
}
addGlobalStyle(`@keyframes mermaidDiagramCodeInserted {
from { opacity: 0.99; }
to { opacity: 1; }
}`);
addGlobalStyle(`.language-mermaid, [lang="mermaid"], .hljs {
animation-duration: 0.001s;
animation-name: mermaidDiagramCodeInserted;
}`);
async function setupChart(elem, code) {
var sourceName = elem.id;
if (elem.id == "") {
const postfix = Math.random().toString(36).substr(2, 9);
sourceName = 'id-' + postfix;
elem.id = sourceName;
}
var mermaidName = 'mermaid-' + sourceName;
let existingDiagrams = $(`#${mermaidName}`);
let existingDiagram = null;
if (existingDiagrams.length > 0) {
existingDiagram = existingDiagrams[0];
existingDiagram.innerHTML = code;
} else {
// Create the element that will house the rendered diagram.
elem.insertAdjacentHTML('afterend', `<div id="${mermaidName}" />`);
existingDiagram = $(`#${mermaidName}`)[0];
// Create an observer to track changes to the diagram code.
const observer = new MutationObserver(() => { processElement(elem) });
observer.observe(elem, { characterData: true });
}
try {
// Generate or regenerate diagram if it is existing.
const {svg} = await mermaid.render('svg-' + mermaidName, code);
elem.style.display = 'none';
existingDiagram.innerHTML = svg;
}
catch (error) {
console.log("Err: " + error);
existingDiagram.style.display = 'none';
let svg = $(`#${'svg-' + mermaidName}`)[0];
svg.style.display = 'none';
}
};
function processElement(elem) {
const codeElem = $('code', elem)[0];
if (codeElem !== undefined) {
const code = codeElem.textContent;
setupChart(elem, code);
} else {
const code = elem.textContent;
setupChart(elem, code);
}
};
function onElementInsert(event) {
// We are only interested in the diagrams that trigger the css animation
// called "mermaidDiagramCodeInserted". This is determined by the file
// "on_change_animations.css".
if (event.animationName !== "mermaidDiagramCodeInserted") {
return
}
processElement(event.target);
}
// These will be run after DOMContentLoaded
// Github
$('[lang="mermaid"]').forEach(processElement);
$('[lang="mermaid-x"]').forEach(processElement);
$('pre.mermaid').forEach(processElement);
$('.language-mermaid').forEach(processElement);
// This catches diagrams that are added to the page after it is loaded.
// This might include comments from other users.
document.addEventListener("animationstart", onElementInsert, false);
})();
@216217717MT
Copy link

graph TD;
    %% External Users
    Client["Client - Books Appointments"] -->|Uses| WebApp
    Barber["Barber - Manages Schedules"] -->|Uses| WebApp
    Admin["Admin - Oversees Operations"] -->|Manages| WebApp

    %% Main System Components
    subgraph "Online Booking System"
        WebApp["Web Application (Frontend)"]
        API["API Gateway (Backend)"]
        MobileApp["Mobile App"]
        Database["Database"]
    end

    %% External Services
    API -->|Stores/Retrieves Data| Database
    API -->|Processes Payments| PaymentService["Payment Service"]
    API -->|Sends Notifications| NotificationService["Notification Service"]

    %% Queue Management (Optional)
    API -->|Handles Booking Requests| BookingQueue["Booking Queue"]
    API -->|Processes Payment Requests| PaymentQueue["Payment Queue"]

    %% Styling
    style WebApp fill:#ff4d4d,stroke:#b30000,stroke-width:2px
    style MobileApp fill:#ff4d4d,stroke:#b30000,stroke-width:2px
    style API fill:#ff9933,stroke:#b36b00,stroke-width:2px
    style Database fill:#66cc66,stroke:#006600,stroke-width:2px
    style PaymentService fill:#cc66ff,stroke:#6600cc,stroke-width:2px
    style NotificationService fill:#66cccc,stroke:#008080,stroke-width:2px
    style BookingQueue fill:#ffcc00,stroke:#b38f00,stroke-width:2px
    style PaymentQueue fill:#ffcc00,stroke:#b38f00,stroke-width:2px
    style Client fill:#4d79ff,stroke:#0033cc,stroke-width:2px
    style Barber fill:#66cc66,stroke:#006600,stroke-width:2px
    style Admin fill:#999999,stroke:#4d4d4d,stroke-width:2px
Loading

@216217717MT
Copy link

graph TD;
    %% Main System Components
    Frontend["Frontend (Web/Mobile)"] -->|Sends Requests| Backend["Backend (API Server)"]
    
    %% Backend Connections
    Backend -->|Stores Data| Database["Database"]
    Backend -->|Processes Payments| PaymentService["Payment Service"]
    Backend -->|Sends Notifications| NotificationService["Notification Service"]

    %% Styling
    style Frontend fill:#4d79ff,stroke:#0033cc,stroke-width:2px
    style Backend fill:#ff9933,stroke:#b36b00,stroke-width:2px
    style Database fill:#66cc66,stroke:#006600,stroke-width:2px
    style PaymentService fill:#cc66ff,stroke:#6600cc,stroke-width:2px
    style NotificationService fill:#66cccc,stroke:#008080,stroke-width:2px
Loading

@216217717MT
Copy link

graph TD
    %% External Users
    Client["Client - Books Appointments"] -->|Interacts with| UI
    Barber["Barber - Manages Schedules"] -->|Interacts with| UI
    Admin["Admin - Oversees Operations"] -->|Interacts with| UI

    %% Main System Components
    subgraph "Online Booking System"
        UI["User Interface (Web & Mobile)"]
        API["API Gateway (Backend)"]
        
        subgraph "Backend Services"
            BookingService["Booking Service"]
            UserService["User Management Service"]
            PaymentService["Payment Processing Service"]
            NotificationService["Notification Service"]
        end
        
        Database["Database"]
    end

    %% Connections
    UI -->|Requests| API
    API -->|Handles Bookings| BookingService
    API -->|Manages Users| UserService
    API -->|Processes Payments| PaymentService
    API -->|Sends Notifications| NotificationService

    BookingService -->|Stores Appointments| Database
    UserService -->|Manages Users| Database
    PaymentService -->|Verifies Transactions| Database
    NotificationService -->|Sends Messages| Database

    %% Styling
    style UI fill:#ff4d4d,stroke:#b30000,stroke-width:2px
    style API fill:#ff9933,stroke:#b36b00,stroke-width:2px
    style BookingService fill:#66cc66,stroke:#006600,stroke-width:2px
    style UserService fill:#66cc66,stroke:#006600,stroke-width:2px
    style PaymentService fill:#cc66ff,stroke:#6600cc,stroke-width:2px
    style NotificationService fill:#66cccc,stroke:#008080,stroke-width:2px
    style Database fill:#ffcc00,stroke:#b38f00,stroke-width:2px
    style Client fill:#4d79ff,stroke:#0033cc,stroke-width:2px
    style Barber fill:#66cc66,stroke:#006600,stroke-width:2px
    style Admin fill:#999999,stroke:#4d4d4d,stroke-width:2px
Loading

@216217717M
Copy link

   graph TD
    %% External Users
    Client["Client - Books Appointments"] -->|Interacts with| UI
    Barber["Barber - Manages Schedules"] -->|Interacts with| UI
    Admin["Admin - Oversees Operations"] -->|Interacts with| UI

    %% Main System Components
    subgraph "Online Booking System"
        UI["User Interface (Web & Mobile)"]
        API["API Gateway (Backend)"]
        
        subgraph "Backend Services"
            BookingService["Booking Service"]
            UserService["User Management Service"]
            PaymentService["Payment Processing Service"]
            NotificationService["Notification Service"]
        end
        
        Database["Database"]
    end

    %% Connections
    UI -->|Requests| API
    API -->|Handles Bookings| BookingService
    API -->|Manages Users| UserService
    API -->|Processes Payments| PaymentService
    API -->|Sends Notifications| NotificationService

    BookingService -->|Stores Appointments| Database
    UserService -->|Manages Users| Database
    PaymentService -->|Verifies Transactions| Database
    NotificationService -->|Sends Messages| Database

    %% Styling
    style UI fill:#ff4d4d,stroke:#b30000,stroke-width:2px
    style API fill:#ff9933,stroke:#b36b00,stroke-width:2px
    style BookingService fill:#66cc66,stroke:#006600,stroke-width:2px
    style UserService fill:#66cc66,stroke:#006600,stroke-width:2px
    style PaymentService fill:#cc66ff,stroke:#6600cc,stroke-width:2px
    style NotificationService fill:#66cccc,stroke:#008080,stroke-width:2px
    style Database fill:#ffcc00,stroke:#b38f00,stroke-width:2px
    style Client fill:#4d79ff,stroke:#0033cc,stroke-width:2px
    style Barber fill:#66cc66,stroke:#006600,stroke-width:2px
    style Admin fill:#999999,stroke:#4d4d4d,stroke-width:2px
...
Loading

@216217717M
Copy link

216217717M commented Mar 16, 2025

graph TD;
    Customer -->|Books| BookAppointment;
    Customer -->|Pays| MakePayment;
    Customer -->|Cancels| CancelAppointment;
    
    Barber -->|Views| ViewAppointments;
    Barber -->|Updates| UpdateAvailability;
    
    Admin -->|Manages| ManageUsers;
    Admin -->|Oversees| ManageAppointments;
    
    PaymentGateway -->|Processes| ProcessPayment;
Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment