Merge branch 'develop' into release/8.6.0

This commit is contained in:
Neil Cuzon 2020-07-20 20:01:32 -07:00 committed by GitHub
commit 575c34467f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 316878 additions and 24865 deletions

3
.gitignore vendored
View File

@ -16,4 +16,5 @@ dist/sequenceTest.html
.vscode/
cypress/platform/current.html
cypress/platform/experimental.html
cypress/platform/experimental.html
local/

View File

@ -6,6 +6,6 @@ describe('Sequencediagram', () => {
cy.visit(url);
cy.get('body')
.find('svg')
.should('have.length', 2);
.should('have.length', 1);
});
});

View File

@ -0,0 +1,31 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util';
describe('Flowchart v2', () => {
it('1: should render a simple flowchart', () => {
imgSnapshotTest(
`flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
`,
{}
);
});
it('2: should render a simple flowchart with diagramPadding set to 0', () => {
imgSnapshotTest(
`flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
%% this is a comment
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
`,
{ flowchart: { diagramPadding: 0 } }
);
});
});

View File

@ -671,4 +671,18 @@ describe('Flowchart', () => {
{ flowchart: { htmlLabels: false } }
);
});
it('33: should render a simple flowchart with diagramPadding set to 0', () => {
imgSnapshotTest(
`graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
%% this is a comment
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
`,
{ flowchart: { diagramPadding: 0 } }
);
});
});

View File

@ -2,6 +2,9 @@
import { imgSnapshotTest } from '../../helpers/util.js';
describe('Gantt diagram', () => {
beforeEach(()=>{
cy.clock((new Date('1010-10-10')).getTime())
})
it('should render a gantt chart', () => {
imgSnapshotTest(
`

View File

@ -0,0 +1,278 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util.js';
describe('Pie Chart', () => {
// beforeEach(()=>{
// cy.clock((new Date('2014-06-09')).getTime());
// });
['default', 'forest', 'dark', 'neutral'].forEach(theme=>{
describe(theme, () => {
it('should render a pie diagram', () => {
imgSnapshotTest(
`
pie title Sports in Sweden
"Bandy" : 40
"Ice-Hockey" : 80
"Football" : 90
`,
{theme}
);
cy.get('svg');
});
it('should render a flowchart diagram', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
`,
{theme}
);
cy.get('svg');
});
it('should render a new flowchart diagram', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[Another]
C ==>|One| D[Laptop]
C x--x|Two| E[iPhone]
C o--o|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
`,
{theme}
);
cy.get('svg');
});
it('should render a sequence diagram', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
sequenceDiagram
autonumber
par Action 1
Alice->>John: Hello John, how are you?
and Action 2
Alice->>Bob: Hello Bob, how are you?
end
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
Note right of John: John is perceptive
John-->>-Alice: I feel great!
loop Every minute
John-->Alice: Great!
end
`,
{theme}
);
cy.get('svg');
});
it('should render a class diagram', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
classDiagram
Animal "*" <|-- "1" Duck
Animal "1" <|-- "10" Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
classA <|-- classB
classC *-- classD
classE o-- classF
classG <-- classH
classI -- classJ
classK <.. classL
classM <|.. classN
classO .. classP
classA --|> classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --> classH : Association
classI -- classJ : Link(Solid)
classK ..> classL : Dependency
classM ..|> classN : Realization
classO .. classP : Link(Dashed)
`,
{theme}
);
cy.get('svg');
});
it('should render a state diagram', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
stateDiagram
[*] --> Active
state Active {
[*] --> NumLockOff
NumLockOff --> NumLockOn : EvNumLockPressed
NumLockOn --> NumLockOff : EvNumLockPressed
--
[*] --> CapsLockOff
CapsLockOff --> CapsLockOn : EvCapsLockPressed
CapsLockOn --> CapsLockOff : EvCapsLockPressed
--
[*] --> ScrollLockOff
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
}
state SomethingElse {
A --> B
B --> A
}
Active --> SomethingElse
note right of SomethingElse : This is the note to the right.
`,
{theme}
);
cy.get('svg');
});
it('should render a state diagram (v2)', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
stateDiagram-v2
[*] --> Active
state Active {
[*] --> NumLockOff
NumLockOff --> NumLockOn : EvNumLockPressed
NumLockOn --> NumLockOff : EvNumLockPressed
--
[*] --> CapsLockOff
CapsLockOff --> CapsLockOn : EvCapsLockPressed
CapsLockOn --> CapsLockOff : EvCapsLockPressed
--
[*] --> ScrollLockOff
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
}
state SomethingElse {
A --> B
B --> A
}
Active --> SomethingElse2
note right of SomethingElse2 : This is the note to the right.
`,
{theme}
);
cy.get('svg');
});
it('should render a er diagram', () => {
imgSnapshotTest(
`
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
`,
{theme}
);
cy.get('svg');
});
it('should render a user journey diagram', () => {
imgSnapshotTest(
`
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 5: Me `,
{theme}
);
cy.get('svg');
});
it('should render a gantt diagram', () => {
cy.clock((new Date('2014-01-06')).getTime());
imgSnapshotTest(
`
gantt
dateFormat :YYYY-MM-DD
title :Adding GANTT diagram functionality to mermaid
excludes :excludes the named dates/days from being included in a charted task..
section A section
Completed task :done, des1, 2014-01-06,2014-01-08
Active task :active, des2, 2014-01-09, 3d
Future task : des3, after des2, 5d
Future task2 : des4, after des3, 5d
section Critical tasks
Completed task in the critical line :crit, done, 2014-01-06,24h
Implement parser and jison :crit, done, after des1, 2d
Create tests for parser :crit, active, 3d
Future task in critical line :crit, 5d
Create tests for renderer :2d
Add to mermaid :1d
section Documentation
Describe gantt syntax :active, a1, after des1, 3d
Add gantt diagram to demo page :after a1 , 20h
Add another diagram to demo page :doc1, after a1 , 48h
section Last section
Describe gantt syntax :after doc1, 3d
Add gantt diagram to demo page :20h
Add another diagram to demo page :48h
`,
{theme}
);
cy.get('svg');
});
});
});
});

View File

@ -1,10 +1,36 @@
import mermaid from '../../dist/mermaid.core'
import mermaid from '../../dist/mermaid.core';
const code = `graph LR
Power_Supply --> Transmitter_A
Power_Supply --> Transmitter_B
Transmitter_A --> D
Transmitter_B --> D`;
mermaid.initialize({
theme: 'forest',
gantt: { axisFormatter: [
['%Y-%m-%d', (d) => {
return d.getDay() === 1
}]
] }
})
fontFamily: '"Lucida Console", Monaco, monospace',
startOnLoad: false,
flowchart: {
htmlLabels: true
},
gantt: {
axisFormatter: [
[
'%Y-%m-%d',
d => {
return d.getDay() === 1;
}
]
]
}
});
mermaid.render(
'the-id-of-the-svg',
code,
svg => {
console.log(svg);
const elem = document.querySelector('#graph-to-be');
elem.innerHTML = svg;
}
// ,document.querySelector('#tmp')
);

View File

@ -17,66 +17,110 @@
.mermaid2 {
display: none;
}
.someClass > * {
/* fill: red !important; */
}
</style>
</head>
<body>
<h1>info below</h1>
<div class="flex">
<div class="flex flex-wrap">
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart BT
subgraph two
b1
end
subgraph three
c1-->c2
end
c1 --apa apa apa--> b1
two --> c2
%%{init: { 'logLevel': 0, 'theme': 'forest'} }%%
pie title Sports in Sweden
"Bandy" : 40
"Ice-Hockey" : 80
"Football" : 90
</div>
<div class="mermaid" style="width: 50%; height: 200px;">
sequenceDiagram
Alice->>Bob:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
Bob->>Alice: I'm short though
<div class="mermaid2" style="width: 50%; height: 20%;">
%%{init: { 'logLevel': 0, 'theme': 'default'} }%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
<div class="mermaid" style="width: 50%; height: 200px;">
%%{init: {'securityLevel': 'loose'}}%%
<div class="mermaid2" style="width: 50%; height: 20%;">
%%{init: { 'logLevel': 1, 'theme': 'forest'} }%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{{Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?}}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[Car]
click A "index.html#link-clicked" "link test"
click B callback "click test"
classDef someclass fill:#f96;
class A someclass;
class C someclass;
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
<div class="mermaid2" style="width: 50%; height: 200px;">
<div class="mermaid" style="width: 50%; height: 20%;">
%%{init: { 'logLevel': 1, 'theme': 'neutral'} }%%
flowchart BT
subgraph a
b1 -- ok --> b2
end
a -- sert --> c
c --> d
b1 --> d
a --asd123 --> d
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
stateDiagram-v2
state A {
B1 --> B2: ok
}
A --> C: sert
C --> D
B1 --> D
A --> D: asd123
</div>
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
<div class="mermaid2" style="background: #3f3f3f; width: 50%; height: 20%;">
%%{init: { 'logLevel': 1, 'theme': 'dark'} }%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
<div class="mermaid2" style="background: #3f3f3f; width: 50%; height: 20%;">
%%{init: { 'logLevel': 1} }%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
</div>
<script src="./mermaid.js"></script>
<script>
@ -84,17 +128,20 @@ stateDiagram-v2
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'forest',
// theme: 'dark',
// theme: 'dark',
// arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
flowchart: { curve: 'cardinal', "htmlLabels": false },
flowchart: { useMaxWidth: true },
graph: { curve: 'cardinal', "htmlLabels": false },
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorMargin: 50, showSequenceNumbers: true },
// sequenceDiagram: { actorMargin: 300 } // deprecated
fontFamily: '"arial", sans-serif',
curve: 'cardinal',
securityLevel: 'strict'
securityLevel: 'strict',
});
function callback(){alert('It worked');}
</script>

View File

@ -1,12 +1,16 @@
<html>
<head>
<meta charset="utf-8"/>
<!-- <meta charset="iso-8859-15"/> -->
<script src="/e2e.js"></script>
<link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
<!-- <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet"> -->
<style>
body {
/* font-family: 'Mansalva', cursive;*/
font-family: 'Mansalva', cursive;
/* font-family: 'Mansalva', cursive; */
/* font-family: '"Noto Sans SC", sans-serif'; */
/* font-family: "trebuchet ms", verdana, arial; */
}
/* .mermaid-main-font {
font-family: "trebuchet ms", verdana, arial;
@ -34,6 +38,7 @@
// fontFamily: '\"trebuchet ms\", verdana, arial;'
// fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
// fontFamily: '"Mansalva", cursive',
// fontFamily: '"Noto Sans SC", sans-serif'
fontFamily: '"Noto Sans SC", sans-serif'
});
</script>

View File

@ -0,0 +1,141 @@
<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://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.someClass > * {
/* fill: red !important; */
}
</style>
</head>
<body>
<h1>info below</h1>
<div class="flex flex-wrap">
<div class="mermaid" style="width: 50%; height: 20%;">
%%{init: { 'logLevel': 0, 'theme': 'default'} }%%
graph TD
A[Default] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
<div class="mermaid" style="width: 50%; height: 20%;">
%%{init: { 'logLevel': 1, 'theme': 'forest'} }%%
graph TD
A[Forest] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
<div class="mermaid" style="width: 50%; height: 20%;">
%%{init: { 'logLevel': 1, 'theme': 'neutral'} }%%
graph TD
A[Neutral] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
<div class="mermaid" style="background: #3f3f3f; width: 50%; height: 20%;">
%%{init: { 'logLevel': 1, 'theme': 'dark'} }%%
graph TD
A[Dark] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
<div class="mermaid" style="background: #3f3f3f; width: 50%; height: 20%;">
%%{init: { 'logLevel': 1} }%%
graph TD
A[None set] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
</div>
</div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
// theme: 'dark',
// theme: 'dark',
// arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
flowchart: { useMaxWidth: true },
graph: { curve: 'cardinal', "htmlLabels": false },
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorMargin: 50, showSequenceNumbers: true },
// sequenceDiagram: { actorMargin: 300 } // deprecated
fontFamily: '"arial", sans-serif',
curve: 'cardinal',
securityLevel: 'strict',
});
function callback(){alert('It worked');}
</script>
</body>
</html>

View File

@ -12,7 +12,9 @@ const contentLoaded = function() {
pos = pos + 7;
const graphBase64 = document.location.href.substr(pos);
const graphObj = JSON.parse(Base64.decode(graphBase64));
// const graph = 'hello'
if (graphObj.mermaid && graphObj.mermaid.theme === 'dark') {
document.body.style.background = '#3f3f3f';
}
console.log(graphObj);
if (Array.isArray(graphObj.code)) {
const numCodes = graphObj.code.length;
@ -30,6 +32,7 @@ const contentLoaded = function() {
div.innerHTML = graphObj.code;
document.getElementsByTagName('body')[0].appendChild(div);
}
global.mermaid.initialize(graphObj.mermaid);
global.mermaid.init();
}

View File

@ -1,22 +1,17 @@
<!doctype html>
<html>
<head>
<style>
/* .mermaid {
font-family: "trebuchet ms", verdana, arial;;
} */
/* .mermaid {
font-family: 'arial';
} */
</style>
</head>
<body>
<div class="mermaid">
graph LR
A-->B
</div>
<div class="mermaid">
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d
</div>
<div id="graph-to-be"></div>
<script src="./bundle-test.js" charset="utf-8"></script>
</body>

1465
dist/mermaid.core.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

28515
dist/mermaid.js vendored

File diff suppressed because one or more lines are too long

2
dist/mermaid.js.map vendored

File diff suppressed because one or more lines are too long

27
dist/mermaid.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -89,14 +89,15 @@ theme , the CSS style sheet
## securityLevel
| Parameter | Description | Type | Required | Values |
| ------------- | --------------------------------- | ------ | -------- | ------------- |
| securitylevel | Level of trust for parsed diagram | String | Required | Strict, Loose |
| Parameter | Description | Type | Required | Values |
| ------------- | --------------------------------- | ------ | -------- | ------------------------- |
| securitylevel | Level of trust for parsed diagram | String | Required | Strict, Loose, antiscript |
\*\*Notes:
- **strict**: (**default**) tags in text are encoded, click functionality is disabeled
- **loose**: tags in text are allowed, click functionality is enabled
- **antiscript**: html tags in text are allowed, (only script element is removed), click functionality is enabled
## startOnLoad
@ -128,6 +129,15 @@ overriding a site's default security.
The object containing configurations specific for flowcharts
### diagramPadding
| Parameter | Description | Type | Required | Values |
| -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
| diagramPadding | amount of padding around the diagram as a whole | Integer | Required | Any Positive Value |
**Notes:**The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels
**Default value: 8**.
### htmlLabels
| Parameter | Description | Type | Required | Values |
@ -711,9 +721,21 @@ T = top, B = bottom, L = left, and R = right.
| --------- | ------------------- | ------- | -------- | ------------------ |
| fontSize | Font Size in pixels | Integer | | Any Positive Value |
**Notes:**Font size (expressed as an integer representing a number of pixels)
**Notes:**Font size (expressed as an integer representing a number of pixels)
**Default value: 12 **
### useMaxWidth
| Parameter | Description | Type | Required | Values |
| ----------- | ----------- | ------- | -------- | ----------- |
| useMaxWidth | See Notes | Boolean | Required | true, false |
**Notes:**
When this flag is set to true, the diagram width is locked to 100% and
scaled based on available space. If set to false, the diagram reserves its
absolute width.
**Default value: true**.
## render
Function that renders an svg with a graph from a chart definition. Usage example below.
@ -754,7 +776,19 @@ mermaidAPI.initialize({
startOnLoad:true,
arrowMarkerAbsolute:false,
er:{
diagramPadding:20,
layoutDirection:'TB',
minEntityWidth:100,
minEntityHeight:75,
entityPadding:15,
stroke:'gray',
fill:'honeydew',
fontSize:12,
useMaxWidth:true,
},
flowchart:{
diagramPadding:8,
htmlLabels:true,
curve:'linear',
},
@ -794,11 +828,20 @@ mermaidAPI.initialize({
## setSiteConfig
## setSiteConfig
| Function | Description | Type | Values |
| ------------- | ------------------------------------- | ----------- | --------------------------------------- |
| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array |
**Notes:**
Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset
the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig
to the defaultConfig
Note: currentConfig is set in this function
\*Default value: At default, will mirror Global Config\*\*
### Parameters
- `conf` the base currentConfig to use as siteConfig
@ -807,13 +850,27 @@ Returns **any** the siteConfig
## getSiteConfig
Obtains the current siteConfig base configuration
## getSiteConfig
| Function | Description | Type | Values |
| ------------- | ------------------------------------------------- | ----------- | --------------------------------- |
| setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig |
**Notes**:
Returns **any** values in siteConfig.
Returns **any**
## setConfig
Sets the currentConfig. The param conf is sanitized based on the siteConfig.secure keys. Any
## setConfig
| Function | Description | Type | Values |
| ------------- | ------------------------------------- | ----------- | --------------------------------------- |
| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array |
**Notes**:
Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any
values found in conf with key found in siteConfig.secure will be replaced with the corresponding
siteConfig value.
@ -825,12 +882,25 @@ Returns **any** the currentConfig merged with the sanitized conf
## getConfig
Obtains the currentConfig
## getConfig
| Function | Description | Type | Return Values |
| --------- | ------------------------- | ----------- | ----------------------------- |
| getConfig | Obtains the currentConfig | Get Request | Any Values from currentConfig |
**Notes**:
Returns **any** the currentConfig
Returns **any** the currentConfig
## sanitize
## sanitize
| Function | Description | Type | Values |
| -------- | -------------------------------------- | ----------- | ------ |
| sanitize | Sets the siteConfig to desired values. | Put Request | None |
Ensures options parameter does not attempt to override siteConfig secure keys
Note: modifies options in-place
@ -840,7 +910,18 @@ Note: modifies options in-place
## reset
Resets this currentConfig to conf
## reset
| Function | Description | Type | Required | Values |
| -------- | ---------------------------- | ----------- | -------- | ------ |
| reset | Resets currentConfig to conf | Put Request | Required | None |
| Parameter | Description | Type | Required | Values |
| --------- | ------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- |
| conf | base set of values, which currentConfig coul be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array |
\*Notes :
(default: current siteConfig ) (optional, default `getSiteConfig()`)
### Parameters

View File

@ -5,17 +5,19 @@
Note that practitioners of ER modelling almost always refer to *entity types* simply as *entities*. For example the CUSTOMER entity type would be referred to simply as the CUSTOMER entity. This is so common it would be inadvisable to do anything else, but technically an entity is an abstract *instance* of an entity type, and this is what an ER diagram shows - abstract instances, and the relationships between them. This is why entities are always named using singular nouns.
Mermaid can render ER diagrams
```
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
```
```mermaid
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
```
```mermaid
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
```
Entity names are often capitalised, although there is no accepted standard on this, and it is not required in Mermaid.
@ -31,9 +33,11 @@ ER diagrams are a new feature in Mermaid and are **experimental**. There are li
### Entities and Relationships
Mermaid syntax for ER diagrams is compatible with PlantUML, with an extension to label the relationship. Each statement consists of the following parts, all of which are mandatory:
```
```mermaid
<first-entity> <relationship> <second-entity> : <relationship-label>
```
Where:
- `first-entity` is the name of an entity. Names must begin with an alphabetic character and may also contain digits and hyphens
@ -43,7 +47,7 @@ Where:
For example:
```
```mermaid
PROPERTY ||--|{ ROOM : contains
```
@ -51,9 +55,9 @@ This statement can be read as *a property contains one or more rooms, and a room
### Relationship Syntax
The `relationship` part of each statement can be broken down into three sub-components:
The `relationship` part of each statement can be broken down into three sub-components:
- the cardinality of the first entity with respect to the second,
- the cardinality of the first entity with respect to the second,
- whether the relationship confers identity on a 'child' entity
- the cardinality of the second entity with respect to the first
@ -68,13 +72,37 @@ Cardinality is a property that describes how many elements of another entity can
### Identification
Relationships may be classified as either *identifying* or *non-identifying* and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line:
Relationships may be classified as either *identifying* or *non-identifying* and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line:
```
```mermaid
CAR ||--o{ NAMED-DRIVER : allows
PERSON ||--o{ NAMED-DRIVER : is
```
### Other Things
- If you want the relationship label to be more than one word, you must use double quotes around the phrase
- If you don't want a label at all on a relationship, you must use an empty double-quoted string
## Styling
### Config options
For simple color customization:
| Name | Used as |
| :------- | :------------------------------------------------------ |
| `fill` | Background color of an entity |
| `stroke` | Border color of an entity, line color of a relationship |
### Classes used
The following CSS class selectors are available for richer styling:
| Selector | Description |
| :------------------------- | :---------------------------------------------------- |
| `.er.entityBox` | The box representing an entity |
| `.er.entityLabel` | The label for an entity |
| `.er.relationshipLabel` | The label for a relationship |
| `.er.relationshipLabelBox` | The box surrounding a relationship label |
| `.er.relationshipLine` | The line representing a relationship between entities |

View File

@ -29,7 +29,6 @@
"test": "yarn lint && jest src/.*",
"test:watch": "jest --watch src",
"prepublishOnly": "yarn build && yarn test && yarn e2e",
"prepush": "yarn test",
"prepare": "yarn build"
},
"repository": {
@ -50,16 +49,16 @@
},
"dependencies": {
"@braintree/sanitize-url": "^3.1.0",
"crypto-random-string": "^3.0.1",
"d3": "^5.7.0",
"dagre": "^0.8.4",
"dagre-d3": "^0.6.4",
"entity-decode": "^2.0.2",
"graphlib": "^2.1.7",
"he": "^1.2.0",
"khroma": "^1.1.0",
"minify": "^4.1.1",
"moment-mini": "^2.22.1",
"scope-css": "^1.2.1"
"stylis": "^3.5.2"
},
"devDependencies": {
"@babel/core": "^7.2.2",
@ -106,5 +105,10 @@
"sideEffects": [
"**/*.css",
"**/*.scss"
]
],
"husky": {
"hooks": {
"pre-push": "yarn test"
}
}
}

View File

@ -1,6 +1,14 @@
import { assignWithDepth } from './utils';
import { logger } from './logger';
// import themeVariables from './theme-default';
// import themeForestVariables from './theme-forest';
// import themeNeutralVariables from './theme-neutral';
const themes = {};
for (const themeName of ['default', 'forest', 'dark', 'neutral', 'base']) {
themes[themeName] = require(`./themes/theme-${themeName}.js`);
}
/**
* **Configuration methods in Mermaid version 8.6.0 have been updated, to learn more[[click here](8.6.0_docs.md)].**
*
@ -51,6 +59,7 @@ const config = {
* </pre>
*/
theme: 'default',
themeVariables: themes['default'].getThemeVariables(),
themeCSS: undefined,
/* **maxTextSize** - The maximum allowed size of the users text diamgram */
maxTextSize: 50000,
@ -82,11 +91,12 @@ const config = {
/**
*| Parameter | Description |Type | Required | Values|
*| --- | --- | --- | --- | --- |
*| securitylevel | Level of trust for parsed diagram|String | Required | Strict, Loose |
*| securitylevel | Level of trust for parsed diagram|String | Required | Strict, Loose, antiscript |
*
***Notes:
*- **strict**: (**default**) tags in text are encoded, click functionality is disabeled
*- **loose**: tags in text are allowed, click functionality is enabled
*- **antiscript**: html tags in text are allowed, (only script element is removed), click functionality is enabled
*/
securityLevel: 'strict',
@ -123,6 +133,16 @@ const config = {
* The object containing configurations specific for flowcharts
*/
flowchart: {
/**
*| Parameter | Description |Type | Required | Values|
*| --- | --- | --- | --- | --- |
*| diagramPadding | amount of padding around the diagram as a whole | Integer | Required | Any Positive Value |
*
***Notes:**The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels
***Default value: 8**.
*/
diagramPadding: 8,
/**
*| Parameter | Description |Type | Required | Values|
*| --- | --- | --- | --- | --- |
@ -806,12 +826,27 @@ const config = {
*| --- | --- | --- | --- | --- |
*| fontSize| Font Size in pixels| Integer | | Any Positive Value |
*
***Notes:**Font size (expressed as an integer representing a number of pixels)
***Notes:**Font size (expressed as an integer representing a number of pixels)
***Default value: 12 **
*/
fontSize: 12
fontSize: 12,
/**
*| Parameter | Description |Type | Required | Values|
*| --- | --- | --- | --- | --- |
*| useMaxWidth | See Notes | Boolean | Required | true, false |
*
***Notes:**
*When this flag is set to true, the diagram width is locked to 100% and
*scaled based on available space. If set to false, the diagram reserves its
*absolute width.
***Default value: true**.
*/
useMaxWidth: true
}
};
// debugger;
config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute;
config.git.arrowMarkerAbsolute = config.arrowMarkerAbsolute;
export const defaultConfig = Object.freeze(config);
@ -823,27 +858,29 @@ const currentConfig = assignWithDepth({}, defaultConfig);
*| Function | Description | Type | Values |
*| --------- | ------------------- | ------- | ------------------ |
*| setSiteConfig|Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array|
***Notes:**
*Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset
*the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig
*to the defaultConfig
*Note: currentConfig is set in this function
**Default value: At default, will mirror Global Config**
* @param conf - the base currentConfig to use as siteConfig
* @returns {*} - the siteConfig
*/
export const setSiteConfig = conf => {
assignWithDepth(currentConfig, conf, { clobber: true });
// Set theme variables if user has set the theme option
assignWithDepth(siteConfig, conf);
return getSiteConfig();
};
/**
*| Function | Description | Type | Values |
*| --------- | ------------------- | ------- | ------------------ |
*| setSiteConfig|Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig|
***Notes**:
*Returns **any** values in siteConfig.
* @returns {*}
@ -855,8 +892,8 @@ export const getSiteConfig = () => {
*| Function | Description | Type | Values |
*| --------- | ------------------- | ------- | ------------------ |
*| setSiteConfig|Sets the siteConfig to desired values | Put Request| Any Values, except ones in secure array|
***Notes**:
*Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any
*values found in conf with key found in siteConfig.secure will be replaced with the corresponding
@ -866,6 +903,7 @@ export const getSiteConfig = () => {
*/
export const setConfig = conf => {
sanitize(conf);
assignWithDepth(currentConfig, conf);
return getConfig();
};
@ -873,7 +911,7 @@ export const setConfig = conf => {
*| Function | Description | Type | Return Values |
*| --------- | ------------------- | ------- | ------------------ |
*| getConfig |Obtains the currentConfig | Get Request | Any Values from currentConfig|
***Notes**:
*Returns **any** the currentConfig
* @returns {*} - the currentConfig
@ -885,7 +923,7 @@ export const getConfig = () => {
*| Function | Description | Type | Values |
*| --------- | ------------------- | ------- | ------------------ |
*| sanitize |Sets the siteConfig to desired values. | Put Request |None|
*Ensures options parameter does not attempt to override siteConfig secure keys
*Note: modifies options in-place
* @param options - the potential setConfig parameter

View File

@ -0,0 +1,63 @@
const getStyles = options =>
`g.classGroup text {
fill: ${options.nodeBorder};
fill: ${options.classText};
stroke: none;
font-family: ${options.fontFamily};
font-size: 10px;
.title {
font-weight: bolder;
}
}
g.clickable {
cursor: pointer;
}
g.classGroup rect {
fill: ${options.nodeBkg};
stroke: ${options.nodeBorder};
}
g.classGroup line {
stroke: ${options.nodeBorder};
stroke-width: 1;
}
.classLabel .box {
stroke: none;
stroke-width: 0;
fill: ${options.nodeBkg};
opacity: 0.5;
}
.classLabel .label {
fill: ${options.nodeBorder};
font-size: 10px;
}
.relation {
stroke: ${options.lineColor};
stroke-width: 1;
fill: none;
}
.dashed-line{
stroke-dasharray: 3;
}
#compositionStart, #compositionEnd, #dependencyStart, #dependencyEnd, #extensionStart, #extensionEnd {
fill: ${options.lineColor};
stroke: ${options.lineColor};
stroke-width: 1;
}
#aggregationStart, #aggregationEnd {
fill: ${options.nodeBkg};
stroke: ${options.lineColor};
stroke-width: 1;
}
`;
export default getStyles;

View File

@ -5,6 +5,30 @@ export const getRows = s => {
return str.split('#br#');
};
export const removeScript = txt => {
var rs = '';
var idx = 0;
while (idx >= 0) {
idx = txt.indexOf('<script');
if (idx >= 0) {
rs += txt.substr(0, idx);
txt = txt.substr(idx + 1);
idx = txt.indexOf('</script>');
if (idx >= 0) {
idx += 9;
txt = txt.substr(idx);
}
} else {
rs += txt;
idx = -1;
break;
}
}
return rs;
};
export const sanitizeText = (text, config) => {
let txt = text;
let htmlLabels = true;
@ -14,12 +38,18 @@ export const sanitizeText = (text, config) => {
)
htmlLabels = false;
if (config.securityLevel !== 'loose' && htmlLabels) {
// eslint-disable-line
txt = breakToPlaceholder(txt);
txt = txt.replace(/</g, '&lt;').replace(/>/g, '&gt;');
txt = txt.replace(/=/g, '&equals;');
txt = placeholderToBreak(txt);
if (htmlLabels) {
var level = config.securityLevel;
if (level == 'antiscript') {
txt = removeScript(txt);
} else if (level !== 'loose') {
// eslint-disable-line
txt = breakToPlaceholder(txt);
txt = txt.replace(/</g, '&lt;').replace(/>/g, '&gt;');
txt = txt.replace(/=/g, '&equals;');
txt = placeholderToBreak(txt);
}
}
return txt;
@ -48,5 +78,6 @@ export default {
sanitizeText,
hasBreaks,
splitBreaks,
lineBreakRegex
lineBreakRegex,
removeScript
};

View File

@ -0,0 +1,26 @@
import { removeScript } from './common';
describe('when securityLevel is antiscript, all script must be removed', function() {
it('should remove all script block, script inline.', function() {
const labelString = `1
Act1: Hello 1<script src="http://abc.com/script1.js"></script>1
<b>Act2</b>:
1<script>
alert('script run......');
</script>1
1`;
const result = removeScript(labelString);
const hasScript = (result.indexOf("script") >= 0);
expect(hasScript).toEqual(false);
const exactlyString = `1
Act1: Hello 11
<b>Act2</b>:
11
1`;
const isEqual = (result == exactlyString);
expect(isEqual).toEqual(true);
});
});

View File

@ -43,6 +43,7 @@ const drawEntities = function(svgNode, entities, graph) {
const textId = 'entity-' + id;
const textNode = groupNode
.append('text')
.attr('class', 'er entityLabel')
.attr('id', textId)
.attr('x', 0)
.attr('y', 0)
@ -65,6 +66,7 @@ const drawEntities = function(svgNode, entities, graph) {
// Draw the rectangle - insert it before the text so that the text is not obscured
const rectNode = groupNode
.insert('rect', '#' + textId)
.attr('class', 'er entityBox')
.attr('fill', conf.fill)
.attr('fill-opacity', '100%')
.attr('stroke', conf.stroke)
@ -148,6 +150,7 @@ const drawRelationshipFromLayout = function(svg, rel, g, insert) {
// Insert the line at the right place
const svgPath = svg
.insert('path', '#' + insert)
.attr('class', 'er relationshipLine')
.attr('d', lineFunction(edge.points))
.attr('stroke', conf.stroke)
.attr('fill', 'none');
@ -224,6 +227,7 @@ const drawRelationshipFromLayout = function(svg, rel, g, insert) {
const labelNode = svg
.append('text')
.attr('class', 'er relationshipLabel')
.attr('id', labelId)
.attr('x', labelPoint.x)
.attr('y', labelPoint.y)
@ -241,6 +245,7 @@ const drawRelationshipFromLayout = function(svg, rel, g, insert) {
// Insert the opaque rectangle before the text label
svg
.insert('rect', '#' + labelId)
.attr('class', 'er relationshipLabelBox')
.attr('x', labelPoint.x - labelBBox.width / 2)
.attr('y', labelPoint.y - labelBBox.height / 2)
.attr('width', labelBBox.width)
@ -339,9 +344,14 @@ export const draw = function(text, id) {
const width = svgBounds.width + padding * 2;
const height = svgBounds.height + padding * 2;
svg.attr('height', height);
svg.attr('width', '100%');
svg.attr('style', `max-width: ${width}px;`);
if (conf.useMaxWidth) {
svg.attr('width', '100%');
svg.attr('style', `max-width: ${width}px;`);
} else {
svg.attr('height', height);
svg.attr('width', width);
}
svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`);
}; // draw

22
src/diagrams/er/styles.js Normal file
View File

@ -0,0 +1,22 @@
const getStyles = options =>
`
.entityBox {
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
}
.relationshipLabelBox {
fill: ${options.edgeLabelBackground};
fillopactity: 0;
background-color: ${options.edgeLabelBackground};
rect {
opacity: 0.5;
}
}
.relationshipLine {
stroke: ${options.lineColor};
}
`;
export default getStyles;

View File

@ -381,7 +381,7 @@ export const draw = function(text, id) {
return flowDb.getTooltip(this.id);
});
const padding = 8;
const padding = conf.diagramPadding;
const svgBounds = svg.node().getBBox();
const width = svgBounds.width + padding * 2;
const height = svgBounds.height + padding * 2;

View File

@ -394,7 +394,7 @@ export const draw = function(text, id) {
return flowDb.getTooltip(this.id);
});
const padding = 8;
const padding = conf.diagramPadding;
const svgBounds = svg.node().getBBox();
const width = svgBounds.width + padding * 2;
const height = svgBounds.height + padding * 2;

View File

@ -0,0 +1,75 @@
const getStyles = options =>
`.label {
font-family: ${options.fontFamily};
color: ${options.textColor};
}
.label text {
fill: ${options.textColor};
}
.node rect,
.node circle,
.node ellipse,
.node polygon,
.node path {
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
stroke-width: 1px;
}
.node .label {
text-align: center;
}
.node.clickable {
cursor: pointer;
}
.arrowheadPath {
fill: ${options.arrowheadColor};
}
.edgePath .path {
stroke: ${options.lineColor};
stroke-width: 1.5px;
}
.flowchart-link {
stroke: ${options.lineColor};
fill: none;
}
.edgeLabel {
background-color: ${options.edgeLabelBackground};
rect {
opacity: 0.5;
}
text-align: center;
}
.cluster rect {
fill: ${options.secondBkg};
stroke: ${options.clusterBorder};
stroke-width: 1px;
}
.cluster text {
fill: ${options.titleColor};
}
div.mermaidTooltip {
position: absolute;
text-align: center;
max-width: 200px;
padding: 2px;
font-family: ${options.fontFamily};
font-size: 12px;
background: ${options.secondBkg};
border: 1px solid ${options.border2};
border-radius: 2px;
pointer-events: none;
z-index: 100;
}
`;
export default getStyles;

View File

@ -0,0 +1,261 @@
const getStyles = options =>
`
.mermaid-main-font {
font-family: "trebuchet ms", verdana, arial;
font-family: var(--mermaid-font-family);
}
.section {
stroke: none;
opacity: 0.2;
}
.section0 {
fill: ${options.sectionBkgColor};
}
.section2 {
fill: ${options.sectionBkgColor2};
}
.section1,
.section3 {
fill: ${options.altSectionBkgColor};
opacity: 0.2;
}
.sectionTitle0 {
fill: ${options.titleColor};
}
.sectionTitle1 {
fill: ${options.titleColor};
}
.sectionTitle2 {
fill: ${options.titleColor};
}
.sectionTitle3 {
fill: ${options.titleColor};
}
.sectionTitle {
text-anchor: start;
font-size: 11px;
text-height: 14px;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
}
/* Grid and axis */
.grid .tick {
stroke: ${options.gridColor};
opacity: 0.8;
shape-rendering: crispEdges;
text {
font-family: ${options.fontFamily};
fill: ${options.textColor};
}
}
.grid path {
stroke-width: 0;
}
/* Today line */
.today {
fill: none;
stroke: ${options.todayLineColor};
stroke-width: 2px;
}
/* Task styling */
/* Default task */
.task {
stroke-width: 2;
}
.taskText {
text-anchor: middle;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
}
.taskText:not([font-size]) {
font-size: 11px;
}
.taskTextOutsideRight {
fill: ${options.taskTextDarkColor};
text-anchor: start;
font-size: 11px;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
}
.taskTextOutsideLeft {
fill: ${options.taskTextDarkColor};
text-anchor: end;
font-size: 11px;
}
/* Special case clickable */
.task.clickable {
cursor: pointer;
}
.taskText.clickable {
cursor: pointer;
fill: ${options.taskTextClickableColor} !important;
font-weight: bold;
}
.taskTextOutsideLeft.clickable {
cursor: pointer;
fill: ${options.taskTextClickableColor} !important;
font-weight: bold;
}
.taskTextOutsideRight.clickable {
cursor: pointer;
fill: ${options.taskTextClickableColor} !important;
font-weight: bold;
}
/* Specific task settings for the sections*/
.taskText0,
.taskText1,
.taskText2,
.taskText3 {
fill: ${options.taskTextColor};
}
.task0,
.task1,
.task2,
.task3 {
fill: ${options.taskBkgColor};
stroke: ${options.taskBorderColor};
}
.taskTextOutside0,
.taskTextOutside2
{
fill: ${options.taskTextOutsideColor};
}
.taskTextOutside1,
.taskTextOutside3 {
fill: ${options.taskTextOutsideColor};
}
/* Active task */
.active0,
.active1,
.active2,
.active3 {
fill: ${options.activeTaskBkgColor};
stroke: ${options.activeTaskBorderColor};
}
.activeText0,
.activeText1,
.activeText2,
.activeText3 {
fill: ${options.taskTextDarkColor} !important;
}
/* Completed task */
.done0,
.done1,
.done2,
.done3 {
stroke: ${options.doneTaskBorderColor};
fill: ${options.doneTaskBkgColor};
stroke-width: 2;
}
.doneText0,
.doneText1,
.doneText2,
.doneText3 {
fill: ${options.taskTextDarkColor} !important;
}
/* Tasks on the critical line */
.crit0,
.crit1,
.crit2,
.crit3 {
stroke: ${options.critBorderColor};
fill: ${options.critBkgColor};
stroke-width: 2;
}
.activeCrit0,
.activeCrit1,
.activeCrit2,
.activeCrit3 {
stroke: ${options.critBorderColor};
fill: ${options.activeTaskBkgColor};
stroke-width: 2;
}
.doneCrit0,
.doneCrit1,
.doneCrit2,
.doneCrit3 {
stroke: ${options.critBorderColor};
fill: ${options.doneTaskBkgColor};
stroke-width: 2;
cursor: pointer;
shape-rendering: crispEdges;
}
.milestone {
transform: rotate(45deg) scale(0.8,0.8);
}
.milestoneText {
font-style: italic;
}
.doneCritText0,
.doneCritText1,
.doneCritText2,
.doneCritText3 {
fill: ${options.taskTextDarkColor} !important;
}
.activeCritText0,
.activeCritText1,
.activeCritText2,
.activeCritText3 {
fill: ${options.taskTextDarkColor} !important;
}
.titleText {
text-anchor: middle;
font-size: 18px;
fill: ${options.taskTextDarkColor} ;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
}
`;
export default getStyles;

View File

@ -1,5 +1,5 @@
import { logger } from '../../logger';
import { random } from '../../utils';
let commits = {};
let head = null;
let branches = { master: head };
@ -7,18 +7,8 @@ let curBranch = 'master';
let direction = 'LR';
let seq = 0;
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function getId() {
return makeid(7);
return random({ length: 7 });
}
function isfastforwardable(currentCommit, otherCommit) {

View File

@ -0,0 +1,13 @@
const getStyles = () =>
`
.commit-id,
.commit-msg,
.branch-label {
fill: lightgrey;
color: lightgrey;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
}
`;
export default getStyles;

View File

@ -0,0 +1,3 @@
const getStyles = () => ``;
export default getStyles;

View File

@ -0,0 +1,20 @@
const getStyles = options =>
`.pieTitleText {
text-anchor: middle;
font-size: 25px;
fill: ${options.taskTextDarkColor};
font-family: ${options.fontFamily};
}
.slice {
font-family: ${options.fontFamily};
fill: ${options.textColor};
// fill: white;
}
.legend text {
fill: ${options.taskTextDarkColor};
font-family: ${options.fontFamily};
font-size: 17px;
}
`;
export default getStyles;

View File

@ -0,0 +1,100 @@
const getStyles = options =>
`.actor {
stroke: ${options.actorBorder};
fill: ${options.actorBkg};
}
text.actor > tspan {
fill: ${options.actorTextColor};
stroke: none;
}
.actor-line {
stroke: ${options.actorLineColor};
}
.messageLine0 {
stroke-width: 1.5;
stroke-dasharray: none;
stroke: ${options.signalColor};
}
.messageLine1 {
stroke-width: 1.5;
stroke-dasharray: 2, 2;
stroke: ${options.signalColor};
}
#arrowhead path {
fill: ${options.signalColor};
stroke: ${options.signalColor};
}
.sequenceNumber {
fill: ${options.sequenceNumberColor};
}
#sequencenumber {
fill: ${options.signalColor};
}
#crosshead path {
fill: ${options.signalColor};
stroke: ${options.signalColor};
}
.messageText {
fill: ${options.signalTextColor};
stroke: ${options.signalTextColor};
}
.labelBox {
stroke: ${options.labelBoxBorderColor};
fill: ${options.labelBoxBkgColor};
}
.labelText, .labelText > tspan {
fill: ${options.labelTextColor};
stroke: none;
}
.loopText, .loopText > tspan {
fill: ${options.loopTextColor};
stroke: none;
}
.loopLine {
stroke-width: 2px;
stroke-dasharray: 2, 2;
stroke: ${options.labelBoxBorderColor};
fill: ${options.labelBoxBorderColor};
}
.note {
//stroke: #decc93;
stroke: ${options.noteBorderColor};
fill: ${options.noteBkgColor};
}
.noteText, .noteText > tspan {
fill: ${options.noteTextColor};
stroke: none;
}
.activation0 {
fill: ${options.activationBkgColor};
stroke: ${options.activationBorderColor};
}
.activation1 {
fill: ${options.activationBkgColor};
stroke: ${options.activationBorderColor};
}
.activation2 {
fill: ${options.activationBkgColor};
stroke: ${options.activationBorderColor};
}
`;
export default getStyles;

View File

@ -0,0 +1,164 @@
const getStyles = options =>
`g.stateGroup text {
fill: ${options.nodeBorder};
stroke: none;
font-size: 10px;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
}
g.stateGroup text {
fill: ${options.textColor};
stroke: none;
font-size: 10px;
}
g.stateGroup .state-title {
font-weight: bolder;
fill: ${options.labelColor};
}
g.stateGroup rect {
fill: ${options.nodeBkg};
stroke: ${options.nodeBorder};
}
g.stateGroup line {
stroke: ${options.lineColor};
stroke-width: 1;
}
.transition {
stroke: ${options.lineColor};
stroke-width: 1;
fill: none;
}
.stateGroup .composit {
fill: ${options.background};
border-bottom: 1px
}
.stateGroup .alt-composit {
fill: #e0e0e0;
border-bottom: 1px
}
.state-note {
stroke: ${options.noteBorderColor};
fill: ${options.noteBkgColor};
text {
fill: black;
stroke: none;
font-size: 10px;
}
}
.stateLabel .box {
stroke: none;
stroke-width: 0;
fill: ${options.nodeBkg};
opacity: 0.5;
}
.stateLabel text {
fill: ${options.labelColor};
font-size: 10px;
font-weight: bold;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
}
.node circle.state-start {
fill: black;
stroke: black;
}
.node circle.state-end {
fill: black;
stroke: white;
stroke-width: 1.5
}
.node rect {
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
stroke-width: 1px;
}
#statediagram-barbEnd {
fill: ${options.lineColor};
}
.statediagram-cluster rect {
fill: ${options.nodeBkg};
stroke: ${options.nodeBorder};
stroke-width: 1px;
}
.cluster-label, .nodeLabel {
color: ${options.textColor};
}
.statediagram-cluster rect.outer {
rx: 5px;
ry: 5px;
}
.statediagram-state .divider {
stroke: ${options.nodeBorder};
}
.statediagram-state .title-state {
rx: 5px;
ry: 5px;
}
.statediagram-cluster.statediagram-cluster .inner {
fill: ${options.background};
}
.statediagram-cluster.statediagram-cluster-alt .inner {
fill: #e0e0e0;
}
.statediagram-cluster .inner {
rx:0;
ry:0;
}
.statediagram-state rect.basic {
rx: 5px;
ry: 5px;
}
.statediagram-state rect.divider {
stroke-dasharray: 10,10;
fill: ${options.altBackground ? options.altBackground : '#efefef'};
}
.note-edge {
stroke-dasharray: 5;
}
.statediagram-note rect {
fill: ${options.noteBkgColor};
stroke: ${options.noteBorderColor};
stroke-width: 1px;
rx: 0;
ry: 0;
}
.statediagram-note rect {
fill: ${options.noteBkgColor};
stroke: ${options.noteBorderColor};
stroke-width: 1px;
rx: 0;
ry: 0;
}
.statediagram-note .nodeLabel {
color: ${options.noteTextColor};
}
#dependencyStart, #dependencyEnd {
fill: ${options.lineColor};
stroke: ${options.lineColor};
stroke-width: 1;
}
`;
export default getStyles;

View File

@ -232,12 +232,14 @@ export const drawTasks = function(diagram, tasks, verticalPos) {
let sectionNumber = 0;
let fill = '#CCC';
let colour = 'black';
let num = 0;
// Draw the tasks
for (let i = 0; i < tasks.length; i++) {
let task = tasks[i];
if (lastSection !== task.section) {
fill = fills[sectionNumber % fills.length];
num = sectionNumber % fills.length;
colour = textColours[sectionNumber % textColours.length];
const section = {
@ -245,6 +247,7 @@ export const drawTasks = function(diagram, tasks, verticalPos) {
y: 50,
text: task.section,
fill,
num,
colour
};
@ -269,6 +272,7 @@ export const drawTasks = function(diagram, tasks, verticalPos) {
task.height = conf.diagramMarginY;
task.colour = colour;
task.fill = fill;
task.num = num;
task.actors = taskActors;
// Draw the box with the attached line

View File

@ -0,0 +1,121 @@
const getStyles = options =>
`.label {
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
color: ${options.textColor};
}
.mouth {
stroke: #666;
}
line {
stroke: ${options.textColor}
}
.legend {
fill: ${options.textColor};
}
.label text {
fill: #333;
}
.label {
color: ${options.textColor}
}
.face {
fill: #FFF8DC;
stroke: #999;
}
.node rect,
.node circle,
.node ellipse,
.node polygon,
.node path {
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
stroke-width: 1px;
}
.node .label {
text-align: center;
}
.node.clickable {
cursor: pointer;
}
.arrowheadPath {
fill: ${options.arrowheadColor};
}
.edgePath .path {
stroke: ${options.lineColor};
stroke-width: 1.5px;
}
.flowchart-link {
stroke: ${options.lineColor};
fill: none;
}
.edgeLabel {
background-color: ${options.edgeLabelBackground};
rect {
opacity: 0.5;
}
text-align: center;
}
.cluster rect {
fill: ${options.secondBkg};
stroke: ${options.clusterBorder};
stroke-width: 1px;
}
.cluster text {
fill: ${options.titleColor};
}
div.mermaidTooltip {
position: absolute;
text-align: center;
max-width: 200px;
padding: 2px;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
font-size: 12px;
background: ${options.secondBkg};
border: 1px solid ${options.border2};
border-radius: 2px;
pointer-events: none;
z-index: 100;
}
.task-type-0, .section-type-0 {
${options.fillType0 ? `fill: ${options.fillType0}` : ''};
}
.task-type-1, .section-type-1 {
${options.fillType0 ? `fill: ${options.fillType1}` : ''};
}
.task-type-2, .section-type-2 {
${options.fillType0 ? `fill: ${options.fillType2}` : ''};
}
.task-type-3, .section-type-3 {
${options.fillType0 ? `fill: ${options.fillType3}` : ''};
}
.task-type-4, .section-type-4 {
${options.fillType0 ? `fill: ${options.fillType4}` : ''};
}
.task-type-5, .section-type-5 {
${options.fillType0 ? `fill: ${options.fillType5}` : ''};
}
.task-type-6, .section-type-6 {
${options.fillType0 ? `fill: ${options.fillType6}` : ''};
}
.task-type-7, .section-type-7 {
${options.fillType0 ? `fill: ${options.fillType7}` : ''};
}
`;
export default getStyles;

View File

@ -24,8 +24,7 @@ export const drawFace = function(element, faceData) {
.append('circle')
.attr('cx', faceData.cx)
.attr('cy', faceData.cy)
.attr('fill', '#FFF8DC')
.attr('stroke', '#999')
.attr('class', 'face')
.attr('r', radius)
.attr('stroke-width', 2)
.attr('overflow', 'visible');
@ -61,6 +60,7 @@ export const drawFace = function(element, faceData) {
//mouth
face
.append('path')
.attr('class', 'mouth')
.attr('d', arc)
.attr('transform', 'translate(' + faceData.cx + ',' + (faceData.cy + 2) + ')');
}
@ -74,6 +74,7 @@ export const drawFace = function(element, faceData) {
//mouth
face
.append('path')
.attr('class', 'mouth')
.attr('d', arc)
.attr('transform', 'translate(' + faceData.cx + ',' + (faceData.cy + 7) + ')');
}
@ -81,12 +82,13 @@ export const drawFace = function(element, faceData) {
function ambivalent(face) {
face
.append('line')
.attr('class', 'mouth')
.attr('stroke', 2)
.attr('x1', faceData.cx - 5)
.attr('y1', faceData.cy + 7)
.attr('x2', faceData.cx + 5)
.attr('y2', faceData.cy + 7)
.attr('class', 'task-line')
.attr('class', 'mouth')
.attr('stroke-width', '1px')
.attr('stroke', '#666');
}
@ -128,7 +130,8 @@ export const drawText = function(elem, textData) {
const textElem = elem.append('text');
textElem.attr('x', textData.x);
textElem.attr('y', textData.y);
textElem.attr('fill', textData.fill);
textElem.attr('class', 'legend');
textElem.style('text-anchor', textData.anchor);
if (typeof textData.class !== 'undefined') {
@ -184,7 +187,7 @@ export const drawSection = function(elem, section, conf) {
rect.fill = section.fill;
rect.width = conf.width;
rect.height = conf.height;
rect.class = 'journey-section';
rect.class = 'journey-section section-type-' + section.num;
rect.rx = 3;
rect.ry = 3;
drawRect(g, rect);
@ -196,7 +199,7 @@ export const drawSection = function(elem, section, conf) {
rect.y,
rect.width,
rect.height,
{ class: 'journey-section' },
{ class: 'journey-section section-type-' + section.num },
conf,
section.colour
);
@ -237,7 +240,7 @@ export const drawTask = function(elem, task, conf) {
rect.fill = task.fill;
rect.width = conf.width;
rect.height = conf.height;
rect.class = 'task';
rect.class = 'task task-type-' + task.num;
rect.rx = 3;
rect.ry = 3;
drawRect(g, rect);
@ -356,7 +359,7 @@ const _drawTextCandidateFunc = (function() {
}
}
function byFo(content, g, x, y, width, height, textAttrs, conf, colour) {
function byFo(content, g, x, y, width, height, textAttrs, conf) {
const body = g.append('switch');
const f = body
.append('foreignObject')
@ -374,10 +377,11 @@ const _drawTextCandidateFunc = (function() {
text
.append('div')
.attr('class', 'label')
.style('display', 'table-cell')
.style('text-align', 'center')
.style('vertical-align', 'middle')
.style('color', colour)
// .style('color', colour)
.text(content);
byTspan(content, body, x, y, width, height, textAttrs, conf);

View File

@ -139,6 +139,7 @@ const initialize = function(config) {
}
}
mermaidAPI.initialize(config);
// mermaidAPI.reset();
};
/**

View File

@ -10,8 +10,8 @@
*
* @name mermaidAPI
*/
import Stylis from 'stylis';
import { select } from 'd3';
import scope from 'scope-css';
import pkg from '../package.json';
import { setConfig, getConfig, setSiteConfig, getSiteConfig } from './config';
import { logger, setLogLevel } from './logger';
@ -50,11 +50,11 @@ import journeyParser from './diagrams/user-journey/parser/journey';
import journeyDb from './diagrams/user-journey/journeyDb';
import journeyRenderer from './diagrams/user-journey/journeyRenderer';
import configApi from './config';
import getStyles from './styles';
const themes = {};
for (const themeName of ['default', 'forest', 'dark', 'neutral']) {
themes[themeName] = require(`./themes/${themeName}/index.scss`);
for (const themeName of ['default', 'forest', 'dark', 'neutral', 'base']) {
themes[themeName] = require(`./themes/theme-${themeName}.js`);
}
function parse(text) {
@ -197,16 +197,20 @@ export const decodeEntities = function(text) {
* completed.
*/
const render = function(id, _txt, cb, container) {
const cnf = getConfig();
// Check the maximum allowed text size
let txt = _txt;
if (_txt.length > cnf.maxTextSize) {
txt = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
}
const graphInit = utils.detectInit(txt);
if (graphInit) {
reinitialize(graphInit);
assignWithDepth(cnf, getConfig());
} else {
configApi.reset();
const siteConfig = getSiteConfig();
updateRendererConfigs(siteConfig);
}
const cnf = getConfig();
// Check the maximum allowed text size
if (_txt.length > cnf.maxTextSize) {
txt = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
}
if (typeof container !== 'undefined') {
@ -251,51 +255,52 @@ const render = function(id, _txt, cb, container) {
const svg = element.firstChild;
const firstChild = svg.firstChild;
// pre-defined theme
let style = themes[cnf.theme];
if (style === undefined) {
style = '';
}
let userStyles = '';
// user provided theme CSS
if (cnf.themeCSS !== undefined) {
style += `\n${cnf.themeCSS}`;
userStyles += `\n${cnf.themeCSS}`;
}
// user provided theme CSS
if (cnf.fontFamily !== undefined) {
style += `\n:root { --mermaid-font-family: ${cnf.fontFamily}}`;
userStyles += `\n:root { --mermaid-font-family: ${cnf.fontFamily}}`;
}
// user provided theme CSS
if (cnf.altFontFamily !== undefined) {
style += `\n:root { --mermaid-alt-font-family: ${cnf.altFontFamily}}`;
userStyles += `\n:root { --mermaid-alt-font-family: ${cnf.altFontFamily}}`;
}
// classDef
if (graphType === 'flowchart' || graphType === 'flowchart-v2') {
if (graphType === 'flowchart' || graphType === 'flowchart-v2' || graphType === 'graph') {
const classes = flowRenderer.getClasses(txt);
for (const className in classes) {
style += `\n.${className} > * { ${classes[className].styles.join(
userStyles += `\n.${className} > * { ${classes[className].styles.join(
' !important; '
)} !important; }`;
if (classes[className].textStyles) {
style += `\n.${className} tspan { ${classes[className].textStyles.join(
userStyles += `\n.${className} tspan { ${classes[className].textStyles.join(
' !important; '
)} !important; }`;
}
}
}
const stylis = new Stylis();
const rules = stylis(`#${id}`, getStyles(graphType, userStyles, cnf.themeVariables));
const style1 = document.createElement('style');
style1.innerHTML = scope(style, `#${id}`);
style1.innerHTML = rules;
svg.insertBefore(style1, firstChild);
const style2 = document.createElement('style');
const cs = window.getComputedStyle(svg);
style2.innerHTML = `#${id} {
color: ${cs.color};
font: ${cs.font};
}`;
svg.insertBefore(style2, firstChild);
// Verify that the generated svgs are ok before removing this
// const style2 = document.createElement('style');
// const cs = window.getComputedStyle(svg);
// style2.innerHTML = `#d${id} * {
// color: ${cs.color};
// // font: ${cs.font};
// // font-family: Arial;
// // font-size: 24px;
// }`;
// svg.insertBefore(style2, firstChild);
try {
switch (graphType) {
@ -518,7 +523,12 @@ function updateRendererConfigs(conf) {
}
function reinitialize(options) {
console.log(`mermaidAPI.reinitialize: v${pkg.version}`, options);
console.warn(`mermaidAPI.reinitialize: v${pkg.version}`, options);
if (options.theme && themes[options.theme]) {
// Todo merge with user options
options.themeVariables = themes[options.theme].getThemeVariables(options.themeVariables);
}
// Set default options
const config = typeof options === 'object' ? setConfig(options) : getSiteConfig();
updateRendererConfigs(config);
@ -527,9 +537,18 @@ function reinitialize(options) {
}
function initialize(options) {
// console.log(`mermaidAPI.initialize: v${pkg.version}`);
console.log(`mermaidAPI.initialize: v${pkg.version} ${options}`);
// Set default options
if (options && options.theme && themes[options.theme]) {
// Todo merge with user options
options.themeVariables = themes[options.theme].getThemeVariables(options.themeVariables);
} else {
if (options) options.themeVariables = themes.default;
}
const config = typeof options === 'object' ? setSiteConfig(options) : getSiteConfig();
updateRendererConfigs(config);
setLogLevel(config.logLevel);
logger.debug('mermaidAPI.initialize: ', config);
@ -576,7 +595,19 @@ export default mermaidAPI;
* startOnLoad:true,
* arrowMarkerAbsolute:false,
*
* er:{
* diagramPadding:20,
* layoutDirection:'TB',
* minEntityWidth:100,
* minEntityHeight:75,
* entityPadding:15,
* stroke:'gray',
* fill:'honeydew',
* fontSize:12,
* useMaxWidth:true,
* },
* flowchart:{
* diagramPadding:8,
* htmlLabels:true,
* curve:'linear',
* },

83
src/styles.js Normal file
View File

@ -0,0 +1,83 @@
import classDiagram from './diagrams/class/styles';
import er from './diagrams/er/styles';
import flowchart from './diagrams/flowchart/styles';
import gantt from './diagrams/gantt/styles';
import git from './diagrams/git/styles';
import info from './diagrams/info/styles';
import pie from './diagrams/pie/styles';
import sequence from './diagrams/sequence/styles';
import stateDiagram from './diagrams/state/styles';
import journey from './diagrams/user-journey/styles';
const themes = {
flowchart,
'flowchart-v2': flowchart,
sequence,
gantt,
class: classDiagram,
stateDiagram,
state: stateDiagram,
git,
info,
pie,
er,
journey
};
export const calcThemeVariables = (theme, userOverRides) => theme.calcColors(userOverRides);
const getStyles = (type, userStyles, options) => {
return ` {
font-family: ${options.fontFamily};
font-size: ${options.fontSize};
fill: ${options.textColor}
}
/* Classes common for multiple diagrams */
.error-icon {
fill: ${options.errorBkgColor};
}
.error-text {
fill: ${options.errorTextColor};
stroke: ${options.errorTextColor};
}
.edge-thickness-normal {
stroke-width: 2px;
}
.edge-thickness-thick {
stroke-width: 3.5px
}
.edge-pattern-solid {
stroke-dasharray: 0;
}
.edge-pattern-dashed{
stroke-dasharray: 3;
}
.edge-pattern-dotted {
stroke-dasharray: 2;
}
.marker {
fill: ${options.lineColor};
}
.marker.cross {
stroke: ${options.lineColor};
}
svg {
font-family: ${options.fontFamily};
font-size: ${options.fontSize};
}
${themes[type](options)}
${userStyles}
${type} { fill: apa;}
`;
};
export default getStyles;

View File

@ -1,4 +1,4 @@
@import 'flowchart';
// @import 'flowchart';
@import 'sequence';
@import 'gantt';
@import 'class';
@ -13,8 +13,9 @@
:root {
--mermaid-font-family: '"trebuchet ms", verdana, arial';
--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
// --mermaid-alt-font-family: '"Lucida Console", Monaco, monospace';
font-family: '"trebuchet ms", verdana, arial';
font-family: var(--mermaid-font-family);
font-size: 16px;
}
/* Classes common for multiple diagrams */
@ -52,3 +53,8 @@
.marker.cross {
stroke: $lineColor;
}
svg {
font-family: var(--mermaid-font-family);
font-size: 24px;
}

View File

@ -9,3 +9,8 @@
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
}
.legend text {
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
font-size: 17px;
}

View File

@ -82,7 +82,7 @@ g.stateGroup line {
}
.statediagram-cluster rect {
fill: $nodeBkg;
// fill: $nodeBkg;
stroke: $nodeBorder;
stroke-width: 1px;
}

136
src/themes/theme-base.js Normal file
View File

@ -0,0 +1,136 @@
import { darken, lighten, adjust } from 'khroma';
class Theme {
constructor() {
/* Base variables */
this.primaryColor = '#039fbe';
this.secondaryColor = '#b20238';
this.tertiaryColor = lighten('#e8d21d', 30);
this.relationColor = '#000';
this.primaryColor = '#fa255e';
this.secondaryColor = '#c39ea0';
this.tertiaryColor = '#f8e5e5';
this.primaryColor = '#ECECFF';
this.secondaryColor = '#ffffde';
this.tertiaryColor = '#ffffde';
this.background = 'white';
this.lineColor = '#333333';
this.border1 = '#9370DB';
this.arrowheadColor = '#333333';
this.fontFamily = '"trebuchet ms", verdana, arial';
this.fontSize = '16px';
this.labelBackground = '#e8e8e8';
this.textColor = '#333';
this.noteBkgColor = '#fff5ad';
this.noteBorderColor = '#aaaa33';
this.updateColors();
}
updateColors() {
this.secondBkg = this.tertiaryColor;
/* Flowchart variables */
this.nodeBkg = this.primaryColor;
this.mainBkg = this.primaryColor;
this.nodeBorder = darken(this.primaryColor, 23); // border 1
this.clusterBkg = this.tertiaryColor;
this.clusterBorder = darken(this.tertiaryColor, 10);
this.defaultLinkColor = this.lineColor;
this.titleColor = this.textColor;
this.edgeLabelBackground = this.labelBackground;
/* Sequence Diagram variables */
// this.actorBorder = lighten(this.border1, 0.5);
this.actorBorder = lighten(this.border1, 23);
this.actorBkg = this.mainBkg;
this.actorTextColor = 'black';
this.actorLineColor = 'grey';
this.labelBoxBkgColor = this.actorBkg;
this.signalColor = this.textColor;
this.signalTextColor = this.textColor;
this.labelBoxBorderColor = this.actorBorder;
this.labelTextColor = this.actorTextColor;
this.loopTextColor = this.actorTextColor;
this.noteBorderColor = this.border2;
this.noteTextColor = this.actorTextColor;
this.activationBorderColor = darken(this.secondaryColor, 10);
this.activationBkgColor = this.secondaryColor;
this.sequenceNumberColor = 'white';
/* Gantt chart variables */
this.taskTextColor = this.taskTextLightColor;
this.taskTextOutsideColor = this.taskTextDarkColor;
this.sectionBkgColor = this.tertiaryColor;
this.altSectionBkgColor = 'white';
this.sectionBkgColor = this.secondaryColor;
this.sectionBkgColor2 = this.tertiaryColor;
this.altSectionBkgColor = 'white';
this.sectionBkgColor2 = this.primaryColor;
this.taskBorderColor = lighten(this.primaryColor, 23);
this.taskBkgColor = this.primaryColor;
this.taskTextLightColor = 'white';
this.taskTextColor = 'calculated';
this.taskTextDarkColor = 'black';
this.taskTextOutsideColor = 'calculated';
this.taskTextClickableColor = '#003163';
this.activeTaskBorderColor = this.primaryColor;
this.activeTaskBkgColor = lighten(this.primaryColor, 23);
this.gridColor = 'lightgrey';
this.doneTaskBkgColor = 'lightgrey';
this.doneTaskBorderColor = 'grey';
this.critBorderColor = '#ff8888';
this.critBkgColor = 'red';
this.todayLineColor = 'red';
/* state colors */
this.labelColor = 'black';
this.errorBkgColor = '#552222';
this.errorTextColor = '#552222';
/* state colors */
/* class */
this.classText = this.textColor;
/* user-journey */
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;
this.fillType2 = adjust(this.primaryColor, { h: 64 });
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
this.fillType4 = adjust(this.primaryColor, { h: -64 });
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
}
calculate(overrides) {
if (typeof overrides !== 'object') {
// Calculate colors form base colors
this.updateColors();
return;
}
const keys = Object.keys(overrides);
// Copy values from overrides, this is mainly for base colors
keys.forEach(k => {
this[k] = overrides[k];
});
// Calculate colors form base colors
this.updateColors();
// Copy values from overrides again in case of an override of derived value
keys.forEach(k => {
this[k] = overrides[k];
});
}
}
export const getThemeVariables = userOverrides => {
const theme = new Theme();
theme.calculate(userOverrides);
return theme;
};

159
src/themes/theme-dark.js Normal file
View File

@ -0,0 +1,159 @@
import { invert, lighten, darken, rgba, adjust } from 'khroma';
class Theme {
constructor() {
this.background = '#333';
this.primaryColor = '#1f2020';
this.secondaryColor = lighten(this.primaryColor, 16);
this.mainBkg = '#1f2020';
this.secondBkg = 'calculated';
this.mainContrastColor = 'lightgrey';
this.darkTextColor = lighten(invert('#323D47'), 10);
this.lineColor = 'calculated';
this.border1 = '#81B1DB';
this.border2 = rgba(255, 255, 255, 0.25);
this.arrowheadColor = 'calculated';
this.fontFamily = '"trebuchet ms", verdana, arial';
this.fontSize = '16px';
this.labelBackground = '#181818';
this.textColor = '#ccc';
/* Flowchart variables */
this.nodeBkg = 'calculated';
this.nodeBorder = 'calculated';
this.clusterBkg = 'calculated';
this.clusterBorder = 'calculated';
this.defaultLinkColor = 'calculated';
this.titleColor = '#F9FFFE';
this.edgeLabelBackground = 'calculated';
/* Sequence Diagram variables */
this.actorBorder = 'calculated';
this.actorBkg = 'calculated';
this.actorTextColor = 'calculated';
this.actorLineColor = 'calculated';
this.signalColor = 'calculated';
this.signalTextColor = 'calculated';
this.labelBoxBkgColor = 'calculated';
this.labelBoxBorderColor = 'calculated';
this.labelTextColor = 'calculated';
this.loopTextColor = 'calculated';
this.noteBorderColor = 'calculated';
this.noteBkgColor = '#fff5ad';
this.noteTextColor = 'calculated';
this.activationBorderColor = 'calculated';
this.activationBkgColor = 'calculated';
this.sequenceNumberColor = 'black';
/* Gantt chart variables */
this.sectionBkgColor = darken('#EAE8D9', 30);
this.altSectionBkgColor = 'calculated';
this.sectionBkgColor2 = '#EAE8D9';
this.taskBorderColor = rgba(255, 255, 255, 70);
this.taskBkgColor = 'calculated';
this.taskTextColor = 'calculated';
this.taskTextLightColor = 'calculated';
this.taskTextOutsideColor = 'calculated';
this.taskTextClickableColor = '#003163';
this.activeTaskBorderColor = rgba(255, 255, 255, 50);
this.activeTaskBkgColor = '#81B1DB';
this.gridColor = 'calculated';
this.doneTaskBkgColor = 'calculated';
this.doneTaskBorderColor = 'grey';
this.critBorderColor = '#E83737';
this.critBkgColor = '#E83737';
this.taskTextDarkColor = 'calculated';
this.todayLineColor = '#DB5757';
/* state colors */
this.labelColor = 'calculated';
this.errorBkgColor = '#a44141';
this.errorTextColor = '#ddd';
}
updateColors() {
this.secondBkg = lighten(this.mainBkg, 16);
this.lineColor = this.mainContrastColor;
this.arrowheadColor = this.mainContrastColor;
/* Flowchart variables */
this.nodeBkg = this.mainBkg;
this.nodeBorder = this.border1;
this.clusterBkg = this.secondBkg;
this.clusterBorder = this.border2;
this.defaultLinkColor = this.lineColor;
this.edgeLabelBackground = lighten(this.labelBackground, 25);
/* Sequence Diagram variables */
this.actorBorder = this.border1;
this.actorBkg = this.mainBkg;
this.actorTextColor = this.mainContrastColor;
this.actorLineColor = this.mainContrastColor;
this.signalColor = this.mainContrastColor;
this.signalTextColor = this.mainContrastColor;
this.labelBoxBkgColor = this.actorBkg;
this.labelBoxBorderColor = this.actorBorder;
this.labelTextColor = this.mainContrastColor;
this.loopTextColor = this.mainContrastColor;
this.noteBorderColor = this.border2;
this.noteTextColor = this.mainBkg;
this.activationBorderColor = this.border1;
this.activationBkgColor = this.secondBkg;
/* Gantt chart variables */
this.altSectionBkgColor = this.background;
this.taskBkgColor = lighten(this.mainBkg, 23);
this.taskTextColor = this.darkTextColor;
this.taskTextLightColor = this.mainContrastColor;
this.taskTextOutsideColor = this.taskTextLightColor;
this.gridColor = this.mainContrastColor;
this.doneTaskBkgColor = this.mainContrastColor;
this.taskTextDarkColor = this.darkTextColor;
/* state colors */
this.labelColor = this.textColor;
this.altBackground = lighten(this.background, 20);
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;
this.fillType2 = adjust(this.primaryColor, { h: 64 });
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
this.fillType4 = adjust(this.primaryColor, { h: -64 });
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* class */
this.classText = this.nodeBorder;
}
calculate(overrides) {
if (typeof overrides !== 'object') {
// Calculate colors form base colors
this.updateColors();
return;
}
const keys = Object.keys(overrides);
// Copy values from overrides, this is mainly for base colors
keys.forEach(k => {
this[k] = overrides[k];
});
// Calculate colors form base colors
this.updateColors();
// Copy values from overrides again in case of an override of derived value
keys.forEach(k => {
this[k] = overrides[k];
});
}
}
export const getThemeVariables = userOverrides => {
const theme = new Theme();
theme.calculate(userOverrides);
return theme;
};

165
src/themes/theme-default.js Normal file
View File

@ -0,0 +1,165 @@
import { lighten, rgba, adjust } from 'khroma';
class Theme {
constructor() {
/* Base variables */
this.primaryColor = '#ECECFF';
this.secondaryColor = '#ffffde';
this.background = 'white';
this.mainBkg = '#ECECFF';
this.secondBkg = '#ffffde';
this.lineColor = '#333333';
this.border1 = '#9370DB';
this.border2 = '#aaaa33';
this.arrowheadColor = '#333333';
this.fontFamily = '"trebuchet ms", verdana, arial';
this.fontSize = '16px';
this.labelBackground = '#e8e8e8';
this.textColor = '#333';
/* Flowchart variables */
this.nodeBkg = 'calculated';
this.nodeBorder = 'calculated';
this.clusterBkg = 'calculated';
this.clusterBorder = 'calculated';
this.defaultLinkColor = 'calculated';
this.titleColor = 'calculated';
this.edgeLabelBackground = 'calculated';
/* Sequence Diagram variables */
this.actorBorder = 'calculated';
this.actorBkg = 'calculated';
this.actorTextColor = 'black';
this.actorLineColor = 'grey';
this.signalColor = 'calculated';
this.signalTextColor = 'calculated';
this.labelBoxBkgColor = 'calculated';
this.labelBoxBorderColor = 'calculated';
this.labelTextColor = 'calculated';
this.loopTextColor = 'calculated';
this.noteBorderColor = 'calculated';
this.noteBkgColor = '#fff5ad';
this.noteTextColor = 'calculated';
this.activationBorderColor = '#666';
this.activationBkgColor = '#f4f4f4';
this.sequenceNumberColor = 'white';
/* Gantt chart variables */
this.sectionBkgColor = 'calculated';
this.altSectionBkgColor = 'calculated';
this.sectionBkgColor2 = 'calculated';
this.taskBorderColor = 'calculated';
this.taskBkgColor = 'calculated';
this.taskTextLightColor = 'calculated';
this.taskTextColor = this.taskTextLightColor;
this.taskTextDarkColor = 'calculated';
this.taskTextOutsideColor = this.taskTextDarkColor;
this.taskTextClickableColor = 'calculated';
this.activeTaskBorderColor = 'calculated';
this.activeTaskBkgColor = 'calculated';
this.gridColor = 'calculated';
this.doneTaskBkgColor = 'calculated';
this.doneTaskBorderColor = 'calculated';
this.critBorderColor = 'calculated';
this.critBkgColor = 'calculated';
this.todayLineColor = 'calculated';
this.sectionBkgColor = rgba(102, 102, 255, 0.49);
this.altSectionBkgColor = 'white';
this.sectionBkgColor2 = '#fff400';
this.taskBorderColor = '#534fbc';
this.taskBkgColor = '#8a90dd';
this.taskTextLightColor = 'white';
this.taskTextColor = 'calculated';
this.taskTextDarkColor = 'black';
this.taskTextOutsideColor = 'calculated';
this.taskTextClickableColor = '#003163';
this.activeTaskBorderColor = '#534fbc';
this.activeTaskBkgColor = '#bfc7ff';
this.gridColor = 'lightgrey';
this.doneTaskBkgColor = 'lightgrey';
this.doneTaskBorderColor = 'grey';
this.critBorderColor = '#ff8888';
this.critBkgColor = 'red';
this.todayLineColor = 'red';
/* state colors */
this.labelColor = 'black';
this.errorBkgColor = '#552222';
this.errorTextColor = '#552222';
this.updateColors();
}
updateColors() {
/* Flowchart variables */
this.nodeBkg = this.mainBkg;
this.nodeBorder = this.border1; // border 1
this.clusterBkg = this.secondBkg;
this.clusterBorder = this.border2;
this.defaultLinkColor = this.lineColor;
this.titleColor = this.textColor;
this.edgeLabelBackground = this.labelBackground;
/* Sequence Diagram variables */
// this.actorBorder = lighten(this.border1, 0.5);
this.actorBorder = lighten(this.border1, 23);
this.actorBkg = this.mainBkg;
this.labelBoxBkgColor = this.actorBkg;
this.signalColor = this.textColor;
this.signalTextColor = this.textColor;
this.labelBoxBorderColor = this.actorBorder;
this.labelTextColor = this.actorTextColor;
this.loopTextColor = this.actorTextColor;
this.noteBorderColor = this.border2;
this.noteTextColor = this.actorTextColor;
/* Gantt chart variables */
this.taskTextColor = this.taskTextLightColor;
this.taskTextOutsideColor = this.taskTextDarkColor;
/* state colors */
/* class */
this.classText = this.nodeBorder;
/* journey */
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;
this.fillType2 = adjust(this.primaryColor, { h: 64 });
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
this.fillType4 = adjust(this.primaryColor, { h: -64 });
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
}
calculate(overrides) {
if (typeof overrides !== 'object') {
// Calculate colors form base colors
this.updateColors();
return;
}
const keys = Object.keys(overrides);
// Copy values from overrides, this is mainly for base colors
keys.forEach(k => {
this[k] = overrides[k];
});
// Calculate colors form base colors
this.updateColors();
// Copy values from overrides again in case of an override of derived value
keys.forEach(k => {
this[k] = overrides[k];
});
}
}
export const getThemeVariables = userOverrides => {
const theme = new Theme();
theme.calculate(userOverrides);
return theme;
};

140
src/themes/theme-forest.js Normal file
View File

@ -0,0 +1,140 @@
import { darken, adjust } from 'khroma';
class Theme {
constructor() {
/* Base vales */
this.primaryColor = '#cde498';
this.secondaryColor = '#cdffb2';
this.background = 'white';
this.mainBkg = '#cde498';
this.secondBkg = '#cdffb2';
this.lineColor = 'green';
this.border1 = '#13540c';
this.border2 = '#6eaa49';
this.arrowheadColor = 'green';
this.fontFamily = '"trebuchet ms", verdana, arial';
this.fontSize = '16px';
/* Flowchart variables */
this.nodeBkg = 'calculated';
this.nodeBorder = 'calculated';
this.clusterBkg = 'calculated';
this.clusterBorder = 'calculated';
this.defaultLinkColor = 'calculated';
this.titleColor = '#333';
this.edgeLabelBackground = '#e8e8e8';
/* Sequence Diagram variables */
this.actorBorder = 'calculated';
this.actorBkg = 'calculated';
this.actorTextColor = 'black';
this.actorLineColor = 'grey';
this.signalColor = '#333';
this.signalTextColor = '#333';
this.labelBoxBkgColor = 'calculated';
this.labelBoxBorderColor = '#326932';
this.labelTextColor = 'calculated';
this.loopTextColor = 'calculated';
this.noteBorderColor = 'calculated';
this.noteBkgColor = '#fff5ad';
this.noteTextColor = 'calculated';
this.activationBorderColor = '#666';
this.activationBkgColor = '#f4f4f4';
this.sequenceNumberColor = 'white';
/* Gantt chart variables */
this.sectionBkgColor = '#6eaa49';
this.altSectionBkgColor = 'white';
this.sectionBkgColor2 = '#6eaa49';
this.taskBorderColor = 'calculated';
this.taskBkgColor = '#487e3a';
this.taskTextLightColor = 'white';
this.taskTextColor = 'calculated';
this.taskTextDarkColor = 'black';
this.taskTextOutsideColor = 'calculated';
this.taskTextClickableColor = '#003163';
this.activeTaskBorderColor = 'calculated';
this.activeTaskBkgColor = 'calculated';
this.gridColor = 'lightgrey';
this.doneTaskBkgColor = 'lightgrey';
this.doneTaskBorderColor = 'grey';
this.critBorderColor = '#ff8888';
this.critBkgColor = 'red';
this.todayLineColor = 'red';
/* state colors */
this.labelColor = 'black';
this.errorBkgColor = '#552222';
this.errorTextColor = '#552222';
}
updateColors() {
/* Flowchart variables */
this.nodeBkg = this.mainBkg;
this.nodeBorder = this.border1;
this.clusterBkg = this.secondBkg;
this.clusterBorder = this.border2;
this.defaultLinkColor = this.lineColor;
/* Sequence Diagram variables */
this.actorBorder = darken(this.mainBkg, 20);
this.actorBkg = this.mainBkg;
this.labelBoxBkgColor = this.actorBkg;
this.labelTextColor = this.actorTextColor;
this.loopTextColor = this.actorTextColor;
this.noteBorderColor = this.border2;
this.noteTextColor = this.actorTextColor;
/* Gantt chart variables */
this.taskBorderColor = this.border1;
this.taskTextColor = this.taskTextLightColor;
this.taskTextOutsideColor = this.taskTextDarkColor;
this.activeTaskBorderColor = this.taskBorderColor;
this.activeTaskBkgColor = this.mainBkg;
/* state colors */
/* class */
this.classText = this.nodeBorder;
/* journey */
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;
this.fillType2 = adjust(this.primaryColor, { h: 64 });
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
this.fillType4 = adjust(this.primaryColor, { h: -64 });
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
}
calculate(overrides) {
if (typeof overrides !== 'object') {
// Calculate colors form base colors
this.updateColors();
return;
}
const keys = Object.keys(overrides);
// Copy values from overrides, this is mainly for base colors
keys.forEach(k => {
this[k] = overrides[k];
});
// Calculate colors form base colors
this.updateColors();
// Copy values from overrides again in case of an override of derived value
keys.forEach(k => {
this[k] = overrides[k];
});
}
}
export const getThemeVariables = userOverrides => {
const theme = new Theme();
theme.calculate(userOverrides);
return theme;
};

173
src/themes/theme-neutral.js Normal file
View File

@ -0,0 +1,173 @@
import { darken, lighten, adjust } from 'khroma';
// const Color = require ( 'khroma/dist/color' ).default
// Color.format.hex.stringify(Color.parse('hsl(210, 66.6666666667%, 95%)')); // => "#EAF2FB"
class Theme {
constructor() {
this.primaryColor = '#eee';
this.contrast = '#26a';
this.secondaryColor = lighten(this.contrast, 55);
this.background = 'white';
this.mainBkg = '#eee';
this.secondBkg = 'calculated';
this.lineColor = '#666';
this.border1 = '#999';
this.border2 = 'calculated';
this.note = '#ffa';
this.text = '#333';
this.critical = '#d42';
this.done = '#bbb';
this.arrowheadColor = '#333333';
this.fontFamily = '"trebuchet ms", verdana, arial';
this.fontSize = '16px';
/* Flowchart variables */
this.nodeBkg = 'calculated';
this.nodeBorder = 'calculated';
this.clusterBkg = 'calculated';
this.clusterBorder = 'calculated';
this.defaultLinkColor = 'calculated';
this.titleColor = 'calculated';
this.edgeLabelBackground = 'white';
/* Sequence Diagram variables */
this.actorBorder = 'calculated';
this.actorBkg = 'calculated';
this.actorTextColor = 'calculated';
this.actorLineColor = 'calculated';
this.signalColor = 'calculated';
this.signalTextColor = 'calculated';
this.labelBoxBkgColor = 'calculated';
this.labelBoxBorderColor = 'calculated';
this.labelTextColor = 'calculated';
this.loopTextColor = 'calculated';
this.noteBorderColor = 'calculated';
this.noteBkgColor = 'calculated';
this.noteTextColor = 'calculated';
this.activationBorderColor = '#666';
this.activationBkgColor = '#f4f4f4';
this.sequenceNumberColor = 'white';
/* Gantt chart variables */
this.sectionBkgColor = 'calculated';
this.altSectionBkgColor = 'white';
this.sectionBkgColor2 = 'calculated';
this.taskBorderColor = 'calculated';
this.taskBkgColor = 'calculated';
this.taskTextLightColor = 'white';
this.taskTextColor = 'calculated';
this.taskTextDarkColor = 'calculated';
this.taskTextOutsideColor = 'calculated';
this.taskTextClickableColor = '#003163';
this.activeTaskBorderColor = 'calculated';
this.activeTaskBkgColor = 'calculated';
this.gridColor = 'calculated';
this.doneTaskBkgColor = 'calculated';
this.doneTaskBorderColor = 'calculated';
this.critBkgColor = 'calculated';
this.critBorderColor = 'calculated';
this.todayLineColor = 'calculated';
/* state colors */
this.labelColor = 'black';
this.errorBkgColor = '#552222';
this.errorTextColor = '#552222';
}
updateColors() {
this.secondBkg = lighten(this.contrast, 55);
this.border2 = this.contrast;
/* Flowchart variables */
this.nodeBkg = this.mainBkg;
this.nodeBorder = this.border1;
this.clusterBkg = this.secondBkg;
this.clusterBorder = this.border2;
this.defaultLinkColor = this.lineColor;
this.titleColor = this.text;
/* Sequence Diagram variables */
this.actorBorder = lighten(this.border1, 23);
this.actorBkg = this.mainBkg;
this.actorTextColor = this.text;
this.actorLineColor = this.lineColor;
this.signalColor = this.text;
this.signalTextColor = this.text;
this.labelBoxBkgColor = this.actorBkg;
this.labelBoxBorderColor = this.actorBorder;
this.labelTextColor = this.text;
this.loopTextColor = this.text;
this.noteBorderColor = darken(this.note, 60);
this.noteBkgColor = this.note;
this.noteTextColor = this.actorTextColor;
/* Gantt chart variables */
this.sectionBkgColor = lighten(this.contrast, 30);
this.sectionBkgColor2 = lighten(this.contrast, 30);
this.taskBorderColor = darken(this.contrast, 10);
this.taskBkgColor = this.contrast;
this.taskTextColor = this.taskTextLightColor;
this.taskTextDarkColor = this.text;
this.taskTextOutsideColor = this.taskTextDarkColor;
this.activeTaskBorderColor = this.taskBorderColor;
this.activeTaskBkgColor = this.mainBkg;
this.gridColor = lighten(this.border1, 30);
this.doneTaskBkgColor = this.done;
this.doneTaskBorderColor = this.lineColor;
this.critBkgColor = this.critical;
this.critBorderColor = darken(this.critBkgColor, 10);
this.todayLineColor = this.critBkgColor;
/* state colors */
/* class */
this.classText = this.nodeBorder;
/* journey */
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;
this.fillType2 = adjust(this.primaryColor, { h: 64 });
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
this.fillType4 = adjust(this.primaryColor, { h: -64 });
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
}
calculate(overrides) {
if (typeof overrides !== 'object') {
// Calculate colors form base colors
this.updateColors();
return;
}
const keys = Object.keys(overrides);
// Copy values from overrides, this is mainly for base colors
keys.forEach(k => {
this[k] = overrides[k];
});
// Calculate colors form base colors
this.updateColors();
// Copy values from overrides again in case of an override of derived value
keys.forEach(k => {
this[k] = overrides[k];
});
}
}
export const getThemeVariables = userOverrides => {
const theme = new Theme();
theme.calculate(userOverrides);
console.info('Theme', userOverrides, theme);
return theme;
};

View File

@ -15,7 +15,7 @@ import {
import { logger } from './logger';
import { sanitizeUrl } from '@braintree/sanitize-url';
import common from './diagrams/common/common';
import cryptoRandomString from 'crypto-random-string';
// import cryptoRandomString from 'crypto-random-string';
// Effectively an enum of the supported curve types, accessible by name
const d3CurveTypes = {
@ -408,8 +408,18 @@ export const generateId = () => {
);
};
function makeid(length) {
var result = '';
var characters = '0123456789abcdef';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
export const random = options => {
return cryptoRandomString(options);
return makeid(options.length);
};
/**

308795
stats.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -2890,6 +2890,14 @@ color@3.0.x:
color-convert "^1.9.1"
color-string "^1.5.2"
color@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10"
integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==
dependencies:
color-convert "^1.9.1"
color-string "^1.5.2"
colornames@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96"
@ -3188,13 +3196,6 @@ crypto-browserify@^3.11.0:
randombytes "^2.0.0"
randomfill "^1.0.3"
crypto-random-string@^3.0.1:
version "3.1.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-3.1.0.tgz#0368382de82e914179ad2ca9c7a788e260184bae"
integrity sha512-Tip3yGB+bA7B0W8E4K4mNf2rZhu5r2G5Tb89/utEl5tP1QuLjTF/S9a1b8ifDrR4ORc9Utf6tscpSEtBY3YcPQ==
dependencies:
type-fest "^0.8.1"
css-b64-images@~0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/css-b64-images/-/css-b64-images-0.2.5.tgz#42005d83204b2b4a5d93b6b1a5644133b5927a02"
@ -4125,11 +4126,6 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
escaper@^2.5.3:
version "2.5.3"
resolved "https://registry.yarnpkg.com/escaper/-/escaper-2.5.3.tgz#8b8fe90ba364054151ab7eff18b4ce43b1e13ab5"
integrity sha512-QGb9sFxBVpbzMggrKTX0ry1oiI4CSDAl9vIL702hzl1jGW8VZs7qfqTRX7WDOjoNDoEVGcEtu1ZOQgReSfT2kQ==
escodegen@1.3.x:
version "1.3.3"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23"
@ -6039,11 +6035,6 @@ is-regex@^1.0.4, is-regex@^1.0.5:
dependencies:
has "^1.0.3"
is-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk=
is-relative@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
@ -6722,6 +6713,11 @@ jssha@^2.1.0:
resolved "https://registry.yarnpkg.com/jssha/-/jssha-2.3.1.tgz#147b2125369035ca4b2f7d210dc539f009b3de9a"
integrity sha1-FHshJTaQNcpLL30hDcU58Amz3po=
khroma@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/khroma/-/khroma-1.1.0.tgz#cc17723eb719c5245ea66d23dd577d5695452db5"
integrity sha512-aTO+YX22tYOLEQJYFiatAj1lc5QZ+H5sHWFRBWNCiKwc5NWNUJZyeSeiHEPeURJ2a1GEVYcmyMUwGjjLe5ec5A==
killable@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
@ -9347,15 +9343,6 @@ schema-utils@^2.6.4:
ajv "^6.10.2"
ajv-keywords "^3.4.1"
scope-css@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/scope-css/-/scope-css-1.2.1.tgz#c35768bc900cad030a3e0d663a818c0f6a57f40e"
integrity sha512-UjLRmyEYaDNiOS673xlVkZFlVCtckJR/dKgr434VMm7Lb+AOOqXKdAcY7PpGlJYErjXXJzKN7HWo4uRPiZZG0Q==
dependencies:
escaper "^2.5.3"
slugify "^1.3.1"
strip-css-comments "^3.0.0"
scss-tokenizer@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
@ -9563,11 +9550,6 @@ slice-ansi@^2.1.0:
astral-regex "^1.0.0"
is-fullwidth-code-point "^2.0.0"
slugify@^1.3.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.6.tgz#ba5fd6159b570fe4811d02ea9b1f4906677638c3"
integrity sha512-wA9XS475ZmGNlEnYYLPReSfuz/c3VQsEMoU43mi6OnKMCdbnFXd4/Yg7J0lBv8jkPolacMpOrWEaoYxuE1+hoQ==
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@ -10019,13 +10001,6 @@ strip-bom@^3.0.0:
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
strip-css-comments@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-css-comments/-/strip-css-comments-3.0.0.tgz#7a5625eff8a2b226cf8947a11254da96e13dae89"
integrity sha1-elYl7/iisibPiUehElTaluE9rok=
dependencies:
is-regexp "^1.0.0"
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
@ -10053,6 +10028,11 @@ strip-json-comments@^3.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==
stylis@^3.5.2:
version "3.5.4"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
subarg@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2"