mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
wip: Broke out flowchar shapes for common rendering
This commit is contained in:
parent
a56aa56cbc
commit
4f6586873f
775
cypress/platform/flowchart-refactor.html
Normal file
775
cypress/platform/flowchart-refactor.html
Normal file
@ -0,0 +1,775 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Caveat:wght@400..700&family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap"
|
||||
rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap"
|
||||
rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Arial';
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid black;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.separator {
|
||||
height: 20px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.vertical-header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.collapsible {
|
||||
background-color: #f9f9f9;
|
||||
color: #444;
|
||||
cursor: pointer;
|
||||
padding: 18px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
text-align: left;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.active,
|
||||
.collapsible:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.collapsible:after {
|
||||
content: '\002B';
|
||||
color: #777;
|
||||
font-weight: bold;
|
||||
float: right;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.active:after {
|
||||
content: "\2212";
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 5px;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.2s ease-out;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.content .pre-scrollable {
|
||||
max-height: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<th></th> <!-- Placeholder for the top left corner -->
|
||||
<th>Dagre</th>
|
||||
<th>Dagre with rough</th>
|
||||
<th>ELK</th>
|
||||
<th>ELK with rough</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Stadium shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1([This is the text in the box])
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram1" class="mermaid">
|
||||
flowchart LR
|
||||
id1([This is the text in the box])
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram2" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1([This is the text in the box])
|
||||
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram3" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1([This is the text in the box])
|
||||
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram4" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1([This is the text in the box])
|
||||
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Sub-Routine shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1[[This is the text in the box]]
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram5" class="mermaid">
|
||||
flowchart LR
|
||||
id1[[This is the text in the box]]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram6" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1[[This is the text in the box]]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram7" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1[[This is the text in the box]]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram8" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1[[This is the text in the box]]
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Cylindrical shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1[(Database)]
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram9" class="mermaid">
|
||||
flowchart LR
|
||||
id1[(Database)]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram10" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1[(Database)]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram11" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1[(Database)]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram12" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1[(Database)]
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Circle shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1((This is the text in the circle))
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram13" class="mermaid">
|
||||
flowchart LR
|
||||
id1((This is the text in the circle))
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram14" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1((This is the text in the circle))
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram15" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1((This is the text in the circle))
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram16" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1((This is the text in the circle))
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Double Circle shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart TD
|
||||
id1(((This is the text in the circle)))
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram17" class="mermaid">
|
||||
flowchart TD
|
||||
id1(((This is the text in the circle)))
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram18" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart TD
|
||||
id1(((This is the text in the circle)))
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram19" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
id1(((This is the text in the circle)))
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram20" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
id1(((This is the text in the circle)))
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Asymmetric shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1>This is the text in the box]
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram21" class="mermaid">
|
||||
flowchart LR
|
||||
id1>This is the text in the box]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram22" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1>This is the text in the box]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram23" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1>This is the text in the box]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram24" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1>This is the text in the box]
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Rhombus/Diamond/Question shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1{This is the text in the box}
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram25" class="mermaid">
|
||||
flowchart LR
|
||||
id1{This is the text in the box}
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram26" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1{This is the text in the box}
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram27" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1{This is the text in the box}
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram28" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1{This is the text in the box}
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Hexagon shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1{{This is the text in the box}}
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram29" class="mermaid">
|
||||
flowchart LR
|
||||
id1{{This is the text in the box}}
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram30" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1{{This is the text in the box}}
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram31" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1{{This is the text in the box}}
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram32" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1{{This is the text in the box}}
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Parallelogram shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart TD
|
||||
id1[/This is the text in the box/]
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram33" class="mermaid">
|
||||
flowchart TD
|
||||
id1[/This is the text in the box/]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram34" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart TD
|
||||
id1[/This is the text in the box/]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram35" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
id1[/This is the text in the box/]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram36" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
id1[/This is the text in the box/]
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Parallelogram Alt shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart TD
|
||||
id1[\This is the text in the box\]
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram37" class="mermaid">
|
||||
flowchart TD
|
||||
id1[\This is the text in the box\]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram38" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart TD
|
||||
id1[\This is the text in the box\]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram39" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
id1[\This is the text in the box\]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram40" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
id1[\This is the text in the box\]
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Trapezoid shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart TD
|
||||
A[/Christmas\]
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram41" class="mermaid">
|
||||
flowchart TD
|
||||
A[/Christmas\]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram42" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart TD
|
||||
A[/Christmas\]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram43" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
A[/Christmas\]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram44" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
A[/Christmas\]
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Trapezoid Alt shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart TD
|
||||
A[\Christmas/]
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram45" class="mermaid">
|
||||
flowchart TD
|
||||
A[\Christmas/]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram46" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart TD
|
||||
A[\Christmas/]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram47" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
A[\Christmas/]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram48" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart TD
|
||||
A[\Christmas/]
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Rect with rounded corner</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1(This is the text in the box)
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram49" class="mermaid">
|
||||
flowchart LR
|
||||
id1(This is the text in the box)
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram50" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1(This is the text in the box)
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram51" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1(This is the text in the box)
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram52" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1(This is the text in the box)
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Rect with sharp corner</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1[This is the text in the box]
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram53" class="mermaid">
|
||||
flowchart LR
|
||||
id1[This is the text in the box]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram54" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1[This is the text in the box]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram55" class="mermaid">
|
||||
%%{init: {"handdrawn": false, "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1[This is the text in the box]
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram56" class="mermaid">
|
||||
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
|
||||
flowchart LR
|
||||
id1[This is the text in the box]
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Separator row -->
|
||||
<tr class="separator">
|
||||
<td colspan="5"></td> <!-- This cell spans all columns including the vertical header -->
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import { layouts } from './mermaid-layout-elk.esm.mjs';
|
||||
mermaid.registerLayoutLoaders(layouts);
|
||||
mermaid.parseError = function (err, hash) {
|
||||
|
||||
};
|
||||
|
||||
mermaid.initialize({
|
||||
handdrawn: false,
|
||||
mergeEdges: true,
|
||||
layout: 'dagre',
|
||||
flowchart: { titleTopMargin: 10 },
|
||||
// fontFamily: 'Caveat',
|
||||
fontFamily: 'Kalam',
|
||||
sequence: {
|
||||
actorFontFamily: 'courier',
|
||||
noteFontFamily: 'courier',
|
||||
messageFontFamily: 'courier',
|
||||
},
|
||||
fontSize: 16,
|
||||
logLevel: 0,
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('In parse error:');
|
||||
console.error(err);
|
||||
};
|
||||
|
||||
|
||||
let coll = document.getElementsByClassName("collapsible");
|
||||
for (const element of coll) {
|
||||
element.addEventListener("click", function () {
|
||||
this.classList.toggle("active");
|
||||
let content = this.nextElementSibling;
|
||||
if (content.style.maxHeight) {
|
||||
content.style.maxHeight = null;
|
||||
} else {
|
||||
content.style.maxHeight = content.scrollHeight + "px";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
183
cypress/platform/flowchart-sate.html
Normal file
183
cypress/platform/flowchart-sate.html
Normal file
@ -0,0 +1,183 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Caveat:wght@400..700&family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap"
|
||||
rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap"
|
||||
rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Arial';
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid black;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.separator {
|
||||
height: 20px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.vertical-header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.collapsible {
|
||||
background-color: #f9f9f9;
|
||||
color: #444;
|
||||
cursor: pointer;
|
||||
padding: 18px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
text-align: left;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.active,
|
||||
.collapsible:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.collapsible:after {
|
||||
content: '\002B';
|
||||
color: #777;
|
||||
font-weight: bold;
|
||||
float: right;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.active:after {
|
||||
content: "\2212";
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 5px;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.2s ease-out;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.content .pre-scrollable {
|
||||
max-height: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<th></th> <!-- Placeholder for the top left corner -->
|
||||
<th>Dagre</th>
|
||||
<th>Dagre with rough</th>
|
||||
<th>ELK</th>
|
||||
<th>ELK with rough</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Stadium shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1([This is the text in the box])
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram1" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
stateDiagram-v2
|
||||
stateA
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram2" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1([This is the text in the box])
|
||||
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import { layouts } from './mermaid-layout-elk.esm.mjs';
|
||||
mermaid.registerLayoutLoaders(layouts);
|
||||
mermaid.parseError = function (err, hash) {
|
||||
|
||||
};
|
||||
|
||||
mermaid.initialize({
|
||||
handdrawn: false,
|
||||
mergeEdges: true,
|
||||
layout: 'dagre',
|
||||
flowchart: { titleTopMargin: 10 },
|
||||
// fontFamily: 'Caveat',
|
||||
fontFamily: 'Kalam',
|
||||
sequence: {
|
||||
actorFontFamily: 'courier',
|
||||
noteFontFamily: 'courier',
|
||||
messageFontFamily: 'courier',
|
||||
},
|
||||
fontSize: 16,
|
||||
logLevel: 0,
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('In parse error:');
|
||||
console.error(err);
|
||||
};
|
||||
|
||||
|
||||
let coll = document.getElementsByClassName("collapsible");
|
||||
for (const element of coll) {
|
||||
element.addEventListener("click", function () {
|
||||
this.classList.toggle("active");
|
||||
let content = this.nextElementSibling;
|
||||
if (content.style.maxHeight) {
|
||||
content.style.maxHeight = null;
|
||||
} else {
|
||||
content.style.maxHeight = content.scrollHeight + "px";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -774,6 +774,7 @@ export const getData = () => {
|
||||
|
||||
// extract(getRootDocV2());
|
||||
// const diagramStates = getStates();
|
||||
const useRough = config.look === 'handdrawn';
|
||||
const n = getVertices();
|
||||
n.forEach((vertex) => {
|
||||
const node: Node = {
|
||||
@ -788,11 +789,12 @@ export const getData = () => {
|
||||
domId: vertex.domId,
|
||||
type: undefined,
|
||||
isGroup: false,
|
||||
useRough,
|
||||
};
|
||||
nodes.push(node);
|
||||
});
|
||||
|
||||
const useRough = config.look === 'handdrawn';
|
||||
//const useRough = config.look === 'handdrawn';
|
||||
|
||||
return { nodes, edges, other: {}, config };
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ import type { DiagramStyleClassDef } from '../../diagram-api/types.js';
|
||||
import type { LayoutData, LayoutMethod } from '../../rendering-util/types.js';
|
||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
|
||||
import { render } from '../../rendering-util/render.js';
|
||||
import { getDiagramElements } from '../../rendering-util/inserElementsForSize.js';
|
||||
import { getDiagramElements } from '../../rendering-util/insertElementsForSize.js';
|
||||
import { setupViewPortForSVG } from '../../rendering-util/setupViewPortForSVG.js';
|
||||
import { getDirection } from './flowDb.js';
|
||||
|
||||
|
@ -7,8 +7,19 @@ import { stateEnd } from './shapes/stateEnd.ts';
|
||||
import { forkJoin } from './shapes/forkJoin.ts';
|
||||
import { choice } from './shapes/choice.ts';
|
||||
import { note } from './shapes/note.ts';
|
||||
import { stadium } from './shapes/stadium.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
|
||||
import { subroutine } from './shapes/subroutine.js';
|
||||
import { cylinder } from './shapes/cylinder.js';
|
||||
import { circle } from './shapes/circle.js';
|
||||
import { doublecircle } from './shapes/doubleCircle.js';
|
||||
import { rect_left_inv_arrow } from './shapes/rectLeftInvArrow.js';
|
||||
import { question } from './shapes/question.js';
|
||||
import { hexagon } from './shapes/hexagon.js';
|
||||
import { lean_right } from './shapes/leanRight.js';
|
||||
import { lean_left } from './shapes/leanLeft.js';
|
||||
import { trapezoid } from './shapes/trapezoid.js';
|
||||
import { inv_trapezoid } from './shapes/invertedTrapezoid.js';
|
||||
const formatClass = (str) => {
|
||||
if (str) {
|
||||
return ' ' + str;
|
||||
@ -26,6 +37,18 @@ const shapes = {
|
||||
note,
|
||||
roundedRect,
|
||||
squareRect,
|
||||
stadium,
|
||||
subroutine,
|
||||
cylinder,
|
||||
circle,
|
||||
doublecircle,
|
||||
odd: rect_left_inv_arrow,
|
||||
diamond: question,
|
||||
hexagon,
|
||||
lean_right,
|
||||
lean_left,
|
||||
trapezoid,
|
||||
inv_trapezoid,
|
||||
};
|
||||
|
||||
let nodeElems = {};
|
||||
@ -34,6 +57,18 @@ export const insertNode = async (elem, node, dir) => {
|
||||
let newEl;
|
||||
let el;
|
||||
|
||||
if (node) {
|
||||
console.log('BLA: rect node', JSON.stringify(node));
|
||||
}
|
||||
//special check for rect shape (with or without rounded corners)
|
||||
if (node.shape === 'rect') {
|
||||
if (node.rx && node.ry) {
|
||||
node.shape = 'roundedRect';
|
||||
} else {
|
||||
node.shape = 'squareRect';
|
||||
}
|
||||
}
|
||||
|
||||
// Add link when appropriate
|
||||
if (node.link) {
|
||||
let target;
|
||||
|
@ -0,0 +1,58 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
|
||||
export const circle = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
|
||||
const radius = bbox.width / 2 + halfPadding;
|
||||
let circleElem;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('Circle: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.9,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const roughNode = rc.circle(0, 0, radius * 2, options);
|
||||
|
||||
circleElem = shapeSvg.insert(() => roughNode, ':first-child');
|
||||
circleElem.attr('class', 'basic label-container').attr('style', cssStyles);
|
||||
} else {
|
||||
circleElem = shapeSvg
|
||||
.insert('circle', ':first-child')
|
||||
.attr('class', 'basic label-container')
|
||||
.attr('style', cssStyles)
|
||||
.attr('r', radius)
|
||||
.attr('cx', 0)
|
||||
.attr('cy', 0);
|
||||
}
|
||||
|
||||
updateNodeBounds(node, circleElem);
|
||||
|
||||
node.intersect = function (point) {
|
||||
log.info('Circle intersect', node, radius, point);
|
||||
return intersect.circle(node, radius, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,116 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
|
||||
/**
|
||||
* Creates an SVG path for a cylindrical shape.
|
||||
* @param {number} x - The x coordinate of the top-left corner.
|
||||
* @param {number} y - The y coordinate of the top-left corner.
|
||||
* @param {number} width - The width of the cylinder.
|
||||
* @param {number} height - The height of the cylinder.
|
||||
* @param {number} rx - The x-radius of the cylinder's ends.
|
||||
* @param {number} ry - The y-radius of the cylinder's ends.
|
||||
* @returns {string} The path data for the cylindrical shape.
|
||||
*/
|
||||
export const createCylinderPathD = (
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
rx: number,
|
||||
ry: number
|
||||
): string => {
|
||||
return [
|
||||
`M${x},${y + ry}`,
|
||||
`a${rx},${ry} 0,0,0 ${width},0`,
|
||||
`a${rx},${ry} 0,0,0 ${-width},0`,
|
||||
`l0,${height}`,
|
||||
`a${rx},${ry} 0,0,0 ${width},0`,
|
||||
`l0,${-height}`,
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const cylinder = async (parent: SVGAElement, node: Node) => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses, // + ' ' + node.class,
|
||||
true
|
||||
);
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const rx = w / 2;
|
||||
const ry = rx / (2.5 + w / 50);
|
||||
const h = bbox.height + ry + node.padding;
|
||||
|
||||
let cylinder: d3.Selection<SVGPathElement | SVGGElement, unknown, null, undefined>;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('Cylinder: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const pathData = createCylinderPathD(0, 0, w, h, rx, ry);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
cylinder = shapeSvg.insert(() => roughNode, ':first-child');
|
||||
cylinder.attr('class', 'basic label-container');
|
||||
if (cssStyles) {
|
||||
cylinder.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
const pathData = createCylinderPathD(0, 0, w, h, rx, ry);
|
||||
cylinder = shapeSvg
|
||||
.insert('path', ':first-child')
|
||||
.attr('d', pathData)
|
||||
.attr('class', 'basic label-container')
|
||||
.attr('style', cssStyles);
|
||||
}
|
||||
|
||||
cylinder.attr('label-offset-y', ry);
|
||||
cylinder.attr('transform', `translate(${-w / 2}, ${-(h / 2 + ry)})`);
|
||||
|
||||
updateNodeBounds(node, cylinder);
|
||||
|
||||
node.intersect = function (point) {
|
||||
const pos = intersect.rect(node, point);
|
||||
const x = pos.x - (node.x ?? 0);
|
||||
|
||||
if (
|
||||
rx != 0 &&
|
||||
(Math.abs(x) < (node.width ?? 0) / 2 ||
|
||||
(Math.abs(x) == (node.width ?? 0) / 2 &&
|
||||
Math.abs(pos.y - (node.y ?? 0)) > (node.height ?? 0) / 2 - ry))
|
||||
) {
|
||||
let y = ry * ry * (1 - (x * x) / (rx * rx));
|
||||
if (y != 0) {
|
||||
y = Math.sqrt(y);
|
||||
}
|
||||
y = ry - y;
|
||||
if (point.y - (node.y ?? 0) > 0) {
|
||||
y = -y;
|
||||
}
|
||||
|
||||
pos.y += y;
|
||||
}
|
||||
|
||||
return pos;
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,81 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
//import d3 from 'd3';
|
||||
|
||||
export const doublecircle = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
const gap = 5;
|
||||
const outerRadius = bbox.width / 2 + halfPadding + gap;
|
||||
const innerRadius = bbox.width / 2 + halfPadding;
|
||||
|
||||
let circleGroup;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('DoubleCircle: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const outerOptions = userNodeOverrides(node, {
|
||||
roughness: 0.9,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
|
||||
const innerOptions = { ...outerOptions, fill: mainBkg };
|
||||
const outerRoughNode = rc.circle(0, 0, outerRadius * 2, outerOptions);
|
||||
const innerRoughNode = rc.circle(0, 0, innerRadius * 2, innerOptions);
|
||||
|
||||
circleGroup = shapeSvg.insert('g', ':first-child');
|
||||
circleGroup.attr('class', node.cssClasses).attr('style', cssStyles);
|
||||
// d3.select(outerRoughNode).attr('class', 'outer-circle').attr('style', cssStyles);
|
||||
// d3.select(innerRoughNode).attr('class', 'inner-circle').attr('style', cssStyles);
|
||||
|
||||
circleGroup.node()?.appendChild(outerRoughNode);
|
||||
circleGroup.node()?.appendChild(innerRoughNode);
|
||||
} else {
|
||||
circleGroup = shapeSvg.insert('g', ':first-child');
|
||||
const outerCircle = circleGroup.insert('circle', ':first-child');
|
||||
const innerCircle = circleGroup.insert('circle', ':first-child');
|
||||
|
||||
circleGroup.attr('class', 'basic label-container').attr('style', cssStyles);
|
||||
|
||||
outerCircle
|
||||
.attr('class', 'outer-circle')
|
||||
.attr('style', cssStyles)
|
||||
.attr('r', outerRadius)
|
||||
.attr('cx', 0)
|
||||
.attr('cy', 0);
|
||||
|
||||
innerCircle
|
||||
.attr('class', 'inner-circle')
|
||||
.attr('style', cssStyles)
|
||||
.attr('r', innerRadius)
|
||||
.attr('cx', 0)
|
||||
.attr('cy', 0);
|
||||
}
|
||||
|
||||
updateNodeBounds(node, circleGroup);
|
||||
|
||||
node.intersect = function (point) {
|
||||
log.info('DoubleCircle intersect', node, outerRadius, point);
|
||||
return intersect.circle(node, outerRadius, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -68,7 +68,14 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt
|
||||
const y = -bbox.height / 2 - halfPadding;
|
||||
|
||||
let rect;
|
||||
const { rx, ry, cssStyles, useRough } = node;
|
||||
let { rx, ry, cssStyles, useRough } = node;
|
||||
|
||||
//use options rx, ry overrides if present
|
||||
if (options && options.rx && options.ry) {
|
||||
rx = options.rx;
|
||||
ry = options.ry;
|
||||
}
|
||||
|
||||
if (useRough) {
|
||||
// @ts-ignore TODO: Fix rough typings
|
||||
const rc = rough.svg(shapeSvg);
|
||||
@ -81,6 +88,8 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
});
|
||||
|
||||
console.log('rect options: ', options);
|
||||
const roughNode =
|
||||
rx || ry
|
||||
? rc.path(createRoundedRectPathD(x, y, totalWidth, totalHeight, rx || 0), options)
|
||||
|
@ -0,0 +1,105 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
|
||||
/**
|
||||
* Creates an SVG path for a hexagon shape.
|
||||
* @param {number} x - The x coordinate of the top-left corner.
|
||||
* @param {number} y - The y coordinate of the top-left corner.
|
||||
* @param {number} width - The width of the hexagon.
|
||||
* @param {number} height - The height of the hexagon.
|
||||
* @param {number} m - The margin size for the hexagon.
|
||||
* @returns {string} The path data for the hexagon shape.
|
||||
*/
|
||||
export const createHexagonPathD = (
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
m: number
|
||||
): string => {
|
||||
return [
|
||||
`M${x + m},${y}`,
|
||||
`L${x + width - m},${y}`,
|
||||
`L${x + width},${y - height / 2}`,
|
||||
`L${x + width - m},${y - height}`,
|
||||
`L${x + m},${y - height}`,
|
||||
`L${x},${y - height / 2}`,
|
||||
'Z',
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const hexagon = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
|
||||
const f = 4;
|
||||
const h = bbox.height + node.padding;
|
||||
const m = h / f;
|
||||
const w = bbox.width + 2 * m + node.padding;
|
||||
const points = [
|
||||
{ x: m, y: 0 },
|
||||
{ x: w - m, y: 0 },
|
||||
{ x: w, y: -h / 2 },
|
||||
{ x: w - m, y: -h },
|
||||
{ x: m, y: -h },
|
||||
{ x: 0, y: -h / 2 },
|
||||
];
|
||||
|
||||
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('Hexagon: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const pathData = createHexagonPathD(0, 0, w, h, m);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
polygon = shapeSvg
|
||||
.insert(() => roughNode, ':first-child')
|
||||
.attr('transform', `translate(${-w / 2}, ${h / 2})`);
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
polygon = insertPolygonShape(shapeSvg, w, h, points);
|
||||
}
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
|
||||
node.width = w;
|
||||
node.height = h;
|
||||
|
||||
updateNodeBounds(node, polygon);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.polygon(node, points, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @param parent
|
||||
* @param w
|
||||
* @param h
|
||||
* @param points
|
||||
*/
|
||||
export function insertPolygonShape(
|
||||
parent: any,
|
||||
w: number,
|
||||
h: number,
|
||||
points: { x: number; y: number }[]
|
||||
) {
|
||||
return parent
|
||||
.insert('polygon', ':first-child')
|
||||
.attr(
|
||||
'points',
|
||||
points
|
||||
.map(function (d) {
|
||||
return d.x + ',' + d.y;
|
||||
})
|
||||
.join(' ')
|
||||
)
|
||||
.attr('class', 'label-container')
|
||||
.attr('transform', 'translate(' + -w / 2 + ',' + h / 2 + ')');
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
|
||||
/**
|
||||
* Creates an SVG path for an inverted trapezoid shape.
|
||||
* @param {number} x - The x coordinate of the top-left corner.
|
||||
* @param {number} y - The y coordinate of the top-left corner.
|
||||
* @param {number} width - The width of the shape.
|
||||
* @param {number} height - The height of the shape.
|
||||
* @returns {string} The path data for the inverted trapezoid shape.
|
||||
*/
|
||||
export const createInvertedTrapezoidPathD = (
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number
|
||||
): string => {
|
||||
return [
|
||||
`M${x + height / 6},${y}`,
|
||||
`L${x + width - height / 6},${y}`,
|
||||
`L${x + width + (2 * height) / 6},${y - height}`,
|
||||
`L${x - (2 * height) / 6},${y - height}`,
|
||||
'Z',
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const inv_trapezoid = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
const points = [
|
||||
{ x: h / 6, y: 0 },
|
||||
{ x: w - h / 6, y: 0 },
|
||||
{ x: w + (2 * h) / 6, y: -h },
|
||||
{ x: (-2 * h) / 6, y: -h },
|
||||
];
|
||||
|
||||
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('Inverted Trapezoid: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const pathData = createInvertedTrapezoidPathD(0, 0, w, h);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
polygon = shapeSvg
|
||||
.insert(() => roughNode, ':first-child')
|
||||
.attr('transform', `translate(${-w / 2}, ${h / 2})`);
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
polygon = insertPolygonShape(shapeSvg, w, h, points);
|
||||
}
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
|
||||
node.width = w;
|
||||
node.height = h;
|
||||
|
||||
updateNodeBounds(node, polygon);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.polygon(node, points, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,96 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
|
||||
/**
|
||||
* Creates an SVG path for a lean left shape.
|
||||
* @param {number} x - The x coordinate of the top-left corner.
|
||||
* @param {number} y - The y coordinate of the top-left corner.
|
||||
* @param {number} width - The width of the shape.
|
||||
* @param {number} height - The height of the shape.
|
||||
* @returns {string} The path data for the lean left shape.
|
||||
*/
|
||||
export const createLeanLeftPathD = (
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number
|
||||
): string => {
|
||||
return [
|
||||
`M${x + (2 * height) / 6},${y}`,
|
||||
`L${x + width + height / 6},${y}`,
|
||||
`L${x + width - (2 * height) / 6},${y - height}`,
|
||||
`L${x - height / 6},${y - height}`,
|
||||
'Z',
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const lean_left = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
const points = [
|
||||
{ x: (2 * h) / 6, y: 0 },
|
||||
{ x: w + h / 6, y: 0 },
|
||||
{ x: w - (2 * h) / 6, y: -h },
|
||||
{ x: -h / 6, y: -h },
|
||||
];
|
||||
|
||||
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('Lean Left: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const pathData = createLeanLeftPathD(0, 0, w, h);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
polygon = shapeSvg
|
||||
.insert(() => roughNode, ':first-child')
|
||||
.attr('transform', `translate(${-w / 2}, ${h / 2})`);
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
polygon = insertPolygonShape(shapeSvg, w, h, points);
|
||||
}
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
|
||||
node.width = w;
|
||||
node.height = h;
|
||||
|
||||
updateNodeBounds(node, polygon);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.polygon(node, points, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,96 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
|
||||
/**
|
||||
* Creates an SVG path for a lean right shape.
|
||||
* @param {number} x - The x coordinate of the top-left corner.
|
||||
* @param {number} y - The y coordinate of the top-left corner.
|
||||
* @param {number} width - The width of the shape.
|
||||
* @param {number} height - The height of the shape.
|
||||
* @returns {string} The path data for the lean right shape.
|
||||
*/
|
||||
export const createLeanRightPathD = (
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number
|
||||
): string => {
|
||||
return [
|
||||
`M${x - (2 * height) / 6},${y}`,
|
||||
`L${x + width - height / 6},${y}`,
|
||||
`L${x + width + (2 * height) / 6},${y - height}`,
|
||||
`L${x + height / 6},${y - height}`,
|
||||
'Z',
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const lean_right = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
const points = [
|
||||
{ x: (-2 * h) / 6, y: 0 },
|
||||
{ x: w - h / 6, y: 0 },
|
||||
{ x: w + (2 * h) / 6, y: -h },
|
||||
{ x: h / 6, y: -h },
|
||||
];
|
||||
|
||||
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('Lean Right: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const pathData = createLeanRightPathD(0, 0, w, h);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
polygon = shapeSvg
|
||||
.insert(() => roughNode, ':first-child')
|
||||
.attr('transform', `translate(${-w / 2}, ${h / 2})`);
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
polygon = insertPolygonShape(shapeSvg, w, h, points);
|
||||
}
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
|
||||
node.width = w;
|
||||
node.height = h;
|
||||
|
||||
updateNodeBounds(node, polygon);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.polygon(node, points, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,90 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
|
||||
/**
|
||||
* Creates an SVG path for a decision box shape (question shape).
|
||||
* @param {number} x - The x coordinate of the top-left corner.
|
||||
* @param {number} y - The y coordinate of the top-left corner.
|
||||
* @param {number} size - The size of the shape.
|
||||
* @returns {string} The path data for the decision box shape.
|
||||
*/
|
||||
export const createDecisionBoxPathD = (x: number, y: number, size: number): string => {
|
||||
return [
|
||||
`M${x + size / 2},${y}`,
|
||||
`L${x + size},${y - size / 2}`,
|
||||
`L${x + size / 2},${y - size}`,
|
||||
`L${x},${y - size / 2}`,
|
||||
'Z',
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const question = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
const s = w + h;
|
||||
|
||||
const points = [
|
||||
{ x: s / 2, y: 0 },
|
||||
{ x: s, y: -s / 2 },
|
||||
{ x: s / 2, y: -s },
|
||||
{ x: 0, y: -s / 2 },
|
||||
];
|
||||
|
||||
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('DecisionBox: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const pathData = createDecisionBoxPathD(0, 0, s);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
polygon = shapeSvg
|
||||
.insert(() => roughNode, ':first-child')
|
||||
.attr('transform', `translate(${-s / 2}, ${s / 2})`);
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
polygon = insertPolygonShape(shapeSvg, s, s, points);
|
||||
}
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
|
||||
updateNodeBounds(node, polygon);
|
||||
|
||||
node.intersect = function (point) {
|
||||
log.warn('Intersect called');
|
||||
return intersect.polygon(node, points, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,94 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
|
||||
/**
|
||||
* Creates an SVG path for a special polygon shape with a left-inverted arrow.
|
||||
* @param {number} x - The x coordinate of the top-left corner.
|
||||
* @param {number} y - The y coordinate of the top-left corner.
|
||||
* @param {number} width - The width of the shape.
|
||||
* @param {number} height - The height of the shape.
|
||||
* @returns {string} The path data for the special polygon shape.
|
||||
*/
|
||||
export const createPolygonPathD = (x: number, y: number, width: number, height: number): string => {
|
||||
return [
|
||||
`M${x - height / 2},${y}`,
|
||||
`L${x + width},${y}`,
|
||||
`L${x + width},${y - height}`,
|
||||
`L${x - height / 2},${y - height}`,
|
||||
`L${x},${y - height / 2}`,
|
||||
'Z',
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const rect_left_inv_arrow = async (
|
||||
parent: SVGAElement,
|
||||
node: Node
|
||||
): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
const points = [
|
||||
{ x: -h / 2, y: 0 },
|
||||
{ x: w, y: 0 },
|
||||
{ x: w, y: -h },
|
||||
{ x: -h / 2, y: -h },
|
||||
{ x: 0, y: -h / 2 },
|
||||
];
|
||||
|
||||
let polygon;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('Polygon: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const pathData = createPolygonPathD(0, 0, w, h);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
polygon = shapeSvg
|
||||
.insert(() => roughNode, ':first-child')
|
||||
.attr('transform', `translate(${-w / 2}, ${h / 2})`);
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
polygon = insertPolygonShape(shapeSvg, w, h, points);
|
||||
}
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
node.width = w + h;
|
||||
node.height = h;
|
||||
|
||||
updateNodeBounds(node, polygon);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.polygon(node, points, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,111 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { createRoundedRectPathD } from './roundedRectPath.js';
|
||||
|
||||
export const createStadiumPathD = (
|
||||
x: number,
|
||||
y: number,
|
||||
totalWidth: number,
|
||||
totalHeight: number
|
||||
) => {
|
||||
const radius = totalHeight / 2;
|
||||
return [
|
||||
'M',
|
||||
x + radius,
|
||||
y, // Move to the start of the top-left arc
|
||||
'H',
|
||||
x + totalWidth - radius, // Draw horizontal line to the start of the top-right arc
|
||||
'A',
|
||||
radius,
|
||||
radius,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
x + totalWidth,
|
||||
y + radius, // Draw top-right arc
|
||||
'H',
|
||||
x, // Draw horizontal line to the start of the bottom-right arc
|
||||
'A',
|
||||
radius,
|
||||
radius,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
x + totalWidth - radius,
|
||||
y + totalHeight, // Draw bottom-right arc
|
||||
'H',
|
||||
x + radius, // Draw horizontal line to the start of the bottom-left arc
|
||||
'A',
|
||||
radius,
|
||||
radius,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
x,
|
||||
y + radius, // Draw bottom-left arc
|
||||
'Z', // Close the path
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const stadium = async (parent: SVGAElement, node: Node) => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses, // + ' ' + node.class,
|
||||
true
|
||||
);
|
||||
|
||||
const h = bbox.height + node.padding;
|
||||
const w = bbox.width + h / 4 + node.padding;
|
||||
|
||||
let rect;
|
||||
const { cssStyles, useRough } = node;
|
||||
if (useRough) {
|
||||
console.log('Stadium:Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure', // solid fill
|
||||
fillWeight: 3.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
// strokeWidth: 1,
|
||||
});
|
||||
|
||||
console.log('Stadium options: ', options);
|
||||
const pathData = createRoundedRectPathD(-w / 2, -h / 2, w, h, h / 3);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
rect = shapeSvg.insert(() => roughNode, ':first-child');
|
||||
rect.attr('class', 'basic label-container').attr('style', cssStyles);
|
||||
} else {
|
||||
rect = shapeSvg.insert('rect', ':first-child');
|
||||
|
||||
rect
|
||||
.attr('class', 'basic label-container')
|
||||
.attr('style', cssStyles)
|
||||
.attr('rx', h / 2)
|
||||
.attr('ry', h / 2)
|
||||
.attr('x', -w / 2)
|
||||
.attr('y', -h / 2)
|
||||
.attr('width', w)
|
||||
.attr('height', h);
|
||||
}
|
||||
|
||||
updateNodeBounds(node, rect);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.rect(node, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -0,0 +1,97 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
|
||||
export const createSubroutinePathD = (
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number
|
||||
): string => {
|
||||
const offset = 8;
|
||||
return [
|
||||
`M${x - offset},${y}`,
|
||||
`H${x + width + offset}`,
|
||||
`V${y + height}`,
|
||||
`H${x - offset}`,
|
||||
`V${y}`,
|
||||
'M',
|
||||
x,
|
||||
y,
|
||||
'H',
|
||||
x + width,
|
||||
'V',
|
||||
y + height,
|
||||
'H',
|
||||
x,
|
||||
'Z',
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const subroutine = async (parent: SVGAElement, node: Node) => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses, // + ' ' + node.class,
|
||||
true
|
||||
);
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
|
||||
let rect;
|
||||
const { cssStyles, useRough } = node;
|
||||
if (useRough) {
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1,
|
||||
});
|
||||
const pathData = createSubroutinePathD(-w / 2, -h / 2, w, h);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
rect = shapeSvg.insert(() => roughNode, ':first-child');
|
||||
rect.attr('class', 'basic label-container').attr('style', cssStyles);
|
||||
}
|
||||
|
||||
const points = [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: w, y: 0 },
|
||||
{ x: w, y: -h },
|
||||
{ x: 0, y: -h },
|
||||
{ x: 0, y: 0 },
|
||||
{ x: -8, y: 0 },
|
||||
{ x: w + 8, y: 0 },
|
||||
{ x: w + 8, y: -h },
|
||||
{ x: -8, y: -h },
|
||||
{ x: -8, y: 0 },
|
||||
];
|
||||
|
||||
const el = insertPolygonShape(shapeSvg, w, h, points);
|
||||
if (cssStyles) {
|
||||
el.attr('style', cssStyles);
|
||||
}
|
||||
|
||||
updateNodeBounds(node, el);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.polygon(node, points, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
||||
|
||||
export default subroutine;
|
@ -0,0 +1,96 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
|
||||
/**
|
||||
* Creates an SVG path for a trapezoid shape.
|
||||
* @param {number} x - The x coordinate of the top-left corner.
|
||||
* @param {number} y - The y coordinate of the top-left corner.
|
||||
* @param {number} width - The width of the shape.
|
||||
* @param {number} height - The height of the shape.
|
||||
* @returns {string} The path data for the trapezoid shape.
|
||||
*/
|
||||
export const createTrapezoidPathD = (
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number
|
||||
): string => {
|
||||
return [
|
||||
`M${x - (2 * height) / 6},${y}`,
|
||||
`L${x + width + (2 * height) / 6},${y}`,
|
||||
`L${x + width - height / 6},${y - height}`,
|
||||
`L${x + height / 6},${y - height}`,
|
||||
'Z',
|
||||
].join(' ');
|
||||
};
|
||||
|
||||
export const trapezoid = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
);
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
const points = [
|
||||
{ x: (-2 * h) / 6, y: 0 },
|
||||
{ x: w + (2 * h) / 6, y: 0 },
|
||||
{ x: w - h / 6, y: -h },
|
||||
{ x: h / 6, y: -h },
|
||||
];
|
||||
|
||||
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
|
||||
const { cssStyles, useRough } = node;
|
||||
|
||||
if (useRough) {
|
||||
console.log('Trapezoid: Inside use useRough');
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {
|
||||
roughness: 0.7,
|
||||
fill: mainBkg,
|
||||
fillStyle: 'hachure',
|
||||
fillWeight: 1.5,
|
||||
//stroke: nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
//strokeWidth: 1,
|
||||
});
|
||||
const pathData = createTrapezoidPathD(0, 0, w, h);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
polygon = shapeSvg
|
||||
.insert(() => roughNode, ':first-child')
|
||||
.attr('transform', `translate(${-w / 2}, ${h / 2})`);
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
polygon = insertPolygonShape(shapeSvg, w, h, points);
|
||||
}
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
|
||||
node.width = w;
|
||||
node.height = h;
|
||||
|
||||
updateNodeBounds(node, polygon);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.polygon(node, points, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
@ -57,6 +57,10 @@ interface Node {
|
||||
borderStyle?: string;
|
||||
borderWidth?: number;
|
||||
labelTextColor?: string;
|
||||
|
||||
// Flowchart specific properties
|
||||
x?: number;
|
||||
y?: number;
|
||||
}
|
||||
|
||||
// Common properties for any edge in the system
|
||||
|
Loading…
x
Reference in New Issue
Block a user