mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-22 01:36:43 +02:00
Added support for a new link syntax per recommendation:
link <actor>: <label> @ <link-url> Removed documentation for class/icon definitions until we can finalize the design for this. Fixed prettier errors.
This commit is contained in:
@@ -564,6 +564,7 @@ context('Sequence diagram', () => {
|
|||||||
links a: {"Repo": "https://www.contoso.com/repo", "Swagger": "https://www.contoso.com/swagger"}
|
links a: {"Repo": "https://www.contoso.com/repo", "Swagger": "https://www.contoso.com/swagger"}
|
||||||
links j: {"Repo": "https://www.contoso.com/repo"}
|
links j: {"Repo": "https://www.contoso.com/repo"}
|
||||||
links a: {"Dashboard": "https://www.contoso.com/dashboard", "On-Call": "https://www.contoso.com/oncall"}
|
links a: {"Dashboard": "https://www.contoso.com/dashboard", "On-Call": "https://www.contoso.com/oncall"}
|
||||||
|
link a: Contacts @ https://contacts.contoso.com/?contact=alice@contoso.com
|
||||||
a->>j: Hello John, how are you?
|
a->>j: Hello John, how are you?
|
||||||
j-->>a: Great!
|
j-->>a: Great!
|
||||||
`,
|
`,
|
||||||
|
@@ -409,6 +409,27 @@ sequenceDiagram
|
|||||||
## Actor Menus
|
## Actor Menus
|
||||||
|
|
||||||
Actors can have popup-menus containing individualized links to external pages. For example, if an actor represented a web service, useful links might include a link to the service health dashboard, repo containing the code for the service, or a wiki page describing the service.
|
Actors can have popup-menus containing individualized links to external pages. For example, if an actor represented a web service, useful links might include a link to the service health dashboard, repo containing the code for the service, or a wiki page describing the service.
|
||||||
|
|
||||||
|
This can be configured by adding one or more link lines with the format:
|
||||||
|
|
||||||
|
link <actor>: <link-label> @ <link-url>
|
||||||
|
|
||||||
|
```
|
||||||
|
sequenceDiagram
|
||||||
|
participant Alice
|
||||||
|
participant John
|
||||||
|
link Alice: Dashboard @ https://dashboard.contoso.com/alice
|
||||||
|
link Alice: Wiki @ https://wiki.contoso.com/alice
|
||||||
|
link John: Dashboard @ https://dashboard.contoso.com/john
|
||||||
|
link John: Wiki @ https://wiki.contoso.com/john
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
John-->>Alice: Great!
|
||||||
|
Alice-)John: See you later!
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Advanced Menu Syntax
|
||||||
|
There is an advanced syntax that relies on JSON formatting. If you are comfortable with JSON format, then this exists as well.
|
||||||
|
|
||||||
This can be configured by adding the links lines with the format:
|
This can be configured by adding the links lines with the format:
|
||||||
|
|
||||||
links <actor>: <json-formatted link-name link-url pairs>
|
links <actor>: <json-formatted link-name link-url pairs>
|
||||||
@@ -426,38 +447,6 @@ sequenceDiagram
|
|||||||
Alice-)John: See you later!
|
Alice-)John: See you later!
|
||||||
```
|
```
|
||||||
|
|
||||||
## Actor Individualized Styles & Icons
|
|
||||||
|
|
||||||
Actors can have individualized styling including an embedded icon.
|
|
||||||
This can be configured by adding the properties lines with this format:
|
|
||||||
|
|
||||||
properties <actor>: { "class": "<css className>", "icon": @<built-in-icon-name> -or- <url to an image file>
|
|
||||||
>
|
|
||||||
|
|
||||||
```
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice
|
|
||||||
participant John
|
|
||||||
properties Alice: {"class": "scheduled-job-actor", "icon": "@clock"}
|
|
||||||
properties John: {"class": "database-service-actor", "icon": "https://icons.contoso.com/database.svg"}
|
|
||||||
Alice->>John: Hello John, how are you?
|
|
||||||
John-->>Alice: Great!
|
|
||||||
Alice-)John: See you later!
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice
|
|
||||||
participant John
|
|
||||||
properties Alice: {"icon": "@clock"}
|
|
||||||
properties John: {"icon": "@database"}
|
|
||||||
Alice->>John: Hello John, how are you?
|
|
||||||
John-->>Alice: Great!
|
|
||||||
Alice-)John: See you later!
|
|
||||||
```
|
|
||||||
|
|
||||||
Built-in icon names include @clock, @database, @computer.
|
|
||||||
|
|
||||||
## Styling
|
## Styling
|
||||||
|
|
||||||
Styling of a sequence diagram is done by defining a number of css classes. During rendering these classes are extracted from the file located at src/themes/sequence.scss
|
Styling of a sequence diagram is done by defining a number of css classes. During rendering these classes are extracted from the file located at src/themes/sequence.scss
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
"left of" return 'left_of';
|
"left of" return 'left_of';
|
||||||
"right of" return 'right_of';
|
"right of" return 'right_of';
|
||||||
"links" return 'links';
|
"links" return 'links';
|
||||||
|
"link" return 'link';
|
||||||
"properties" return 'properties';
|
"properties" return 'properties';
|
||||||
"details" return 'details';
|
"details" return 'details';
|
||||||
"over" return 'over';
|
"over" return 'over';
|
||||||
@@ -114,6 +115,7 @@ statement
|
|||||||
| 'deactivate' actor 'NEWLINE' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2};}
|
| 'deactivate' actor 'NEWLINE' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2};}
|
||||||
| note_statement 'NEWLINE'
|
| note_statement 'NEWLINE'
|
||||||
| links_statement 'NEWLINE'
|
| links_statement 'NEWLINE'
|
||||||
|
| link_statement 'NEWLINE'
|
||||||
| properties_statement 'NEWLINE'
|
| properties_statement 'NEWLINE'
|
||||||
| details_statement 'NEWLINE'
|
| details_statement 'NEWLINE'
|
||||||
| title text2 'NEWLINE' {$$=[{type:'setTitle', text:$2}]}
|
| title text2 'NEWLINE' {$$=[{type:'setTitle', text:$2}]}
|
||||||
@@ -183,6 +185,13 @@ links_statement
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
link_statement
|
||||||
|
: 'link' actor text2
|
||||||
|
{
|
||||||
|
$$ = [$2, {type:'addALink', actor:$2.actor, text:$3}];
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
properties_statement
|
properties_statement
|
||||||
: 'properties' actor text2
|
: 'properties' actor text2
|
||||||
{
|
{
|
||||||
|
@@ -218,8 +218,24 @@ export const addLinks = function (actorId, text) {
|
|||||||
const links = JSON.parse(text.text);
|
const links = JSON.parse(text.text);
|
||||||
// add the deserialized text to the actor's links field.
|
// add the deserialized text to the actor's links field.
|
||||||
insertLinks(actor, links);
|
insertLinks(actor, links);
|
||||||
|
} catch (e) {
|
||||||
|
log.error('error while parsing actor link text', e);
|
||||||
}
|
}
|
||||||
catch (e) {
|
};
|
||||||
|
|
||||||
|
export const addALink = function (actorId, text) {
|
||||||
|
// find the actor
|
||||||
|
const actor = getActor(actorId);
|
||||||
|
try {
|
||||||
|
const links = {};
|
||||||
|
var sep = text.text.indexOf('@');
|
||||||
|
var label = text.text.slice(0, sep - 1).trim();
|
||||||
|
var link = text.text.slice(sep + 1).trim();
|
||||||
|
|
||||||
|
links[label] = link;
|
||||||
|
// add the deserialized text to the actor's links field.
|
||||||
|
insertLinks(actor, links);
|
||||||
|
} catch (e) {
|
||||||
log.error('error while parsing actor link text', e);
|
log.error('error while parsing actor link text', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -227,8 +243,7 @@ export const addLinks = function (actorId, text) {
|
|||||||
function insertLinks(actor, links) {
|
function insertLinks(actor, links) {
|
||||||
if (actor.links == null) {
|
if (actor.links == null) {
|
||||||
actor.links = links;
|
actor.links = links;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (let key in links) {
|
for (let key in links) {
|
||||||
actor.links[key] = links[key];
|
actor.links[key] = links[key];
|
||||||
}
|
}
|
||||||
@@ -243,8 +258,7 @@ export const addProperties = function (actorId, text) {
|
|||||||
const properties = JSON.parse(text.text);
|
const properties = JSON.parse(text.text);
|
||||||
// add the deserialized text to the actor's property field.
|
// add the deserialized text to the actor's property field.
|
||||||
insertProperties(actor, properties);
|
insertProperties(actor, properties);
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
log.error('error while parsing actor properties text', e);
|
log.error('error while parsing actor properties text', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -252,8 +266,7 @@ export const addProperties = function (actorId, text) {
|
|||||||
function insertProperties(actor, properties) {
|
function insertProperties(actor, properties) {
|
||||||
if (actor.properties == null) {
|
if (actor.properties == null) {
|
||||||
actor.properties = properties;
|
actor.properties = properties;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (let key in properties) {
|
for (let key in properties) {
|
||||||
actor.properties[key] = properties[key];
|
actor.properties[key] = properties[key];
|
||||||
}
|
}
|
||||||
@@ -270,15 +283,14 @@ export const addDetails = function (actorId, text) {
|
|||||||
const text = elem.innerHTML;
|
const text = elem.innerHTML;
|
||||||
const details = JSON.parse(text);
|
const details = JSON.parse(text);
|
||||||
// add the deserialized text to the actor's property field.
|
// add the deserialized text to the actor's property field.
|
||||||
if (details["properties"]) {
|
if (details['properties']) {
|
||||||
insertProperties(actor, details["properties"]);
|
insertProperties(actor, details['properties']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details["links"]) {
|
if (details['links']) {
|
||||||
insertLinks(actor, details["links"]);
|
insertLinks(actor, details['links']);
|
||||||
}
|
}
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
log.error('error while parsing actor details text', e);
|
log.error('error while parsing actor details text', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -318,6 +330,9 @@ export const apply = function (param) {
|
|||||||
case 'addLinks':
|
case 'addLinks':
|
||||||
addLinks(param.actor, param.text);
|
addLinks(param.actor, param.text);
|
||||||
break;
|
break;
|
||||||
|
case 'addALink':
|
||||||
|
addALink(param.actor, param.text);
|
||||||
|
break;
|
||||||
case 'addProperties':
|
case 'addProperties':
|
||||||
addProperties(param.actor, param.text);
|
addProperties(param.actor, param.text);
|
||||||
break;
|
break;
|
||||||
|
@@ -908,6 +908,9 @@ participant c as Charlie
|
|||||||
links a: { "Repo": "https://repo.contoso.com/", "Dashboard": "https://dashboard.contoso.com/" }
|
links a: { "Repo": "https://repo.contoso.com/", "Dashboard": "https://dashboard.contoso.com/" }
|
||||||
links b: { "Dashboard": "https://dashboard.contoso.com/" }
|
links b: { "Dashboard": "https://dashboard.contoso.com/" }
|
||||||
links a: { "On-Call": "https://oncall.contoso.com/?svc=alice" }
|
links a: { "On-Call": "https://oncall.contoso.com/?svc=alice" }
|
||||||
|
link a: Endpoint @ https://alice.contoso.com
|
||||||
|
link a: Swagger @ https://swagger.contoso.com
|
||||||
|
link a: Tests @ https://tests.contoso.com/?svc=alice@contoso.com
|
||||||
`;
|
`;
|
||||||
console.log(str);
|
console.log(str);
|
||||||
|
|
||||||
@@ -919,6 +922,9 @@ links a: { "On-Call": "https://oncall.contoso.com/?svc=alice" }
|
|||||||
expect(actors.b.links["Dashboard"]).toBe("https://dashboard.contoso.com/");
|
expect(actors.b.links["Dashboard"]).toBe("https://dashboard.contoso.com/");
|
||||||
expect(actors.a.links["On-Call"]).toBe("https://oncall.contoso.com/?svc=alice");
|
expect(actors.a.links["On-Call"]).toBe("https://oncall.contoso.com/?svc=alice");
|
||||||
expect(actors.c.links["Dashboard"]).toBe(undefined);
|
expect(actors.c.links["Dashboard"]).toBe(undefined);
|
||||||
|
expect(actors.a.links["Endpoint"]).toBe("https://alice.contoso.com");
|
||||||
|
expect(actors.a.links["Swagger"]).toBe("https://swagger.contoso.com");
|
||||||
|
expect(actors.a.links["Tests"]).toBe("https://tests.contoso.com/?svc=alice@contoso.com");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should handle properties', function () {
|
it('it should handle properties', function () {
|
||||||
|
@@ -446,7 +446,7 @@ export const drawActors = function (diagram, actors, actorKeys, verticalPos) {
|
|||||||
bounds.bumpVerticalPos(conf.height);
|
bounds.bumpVerticalPos(conf.height);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const drawActorsPopup = function(diagram, actors, actorKeys) {
|
export const drawActorsPopup = function (diagram, actors, actorKeys) {
|
||||||
var maxHeight = 0;
|
var maxHeight = 0;
|
||||||
var maxWidth = 0;
|
var maxWidth = 0;
|
||||||
for (let i = 0; i < actorKeys.length; i++) {
|
for (let i = 0; i < actorKeys.length; i++) {
|
||||||
@@ -870,7 +870,7 @@ const getMaxMessageWidthPerActor = function (actors, messages) {
|
|||||||
return maxMessageWidthPerActor;
|
return maxMessageWidthPerActor;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRequiredPopupWidth = function(actor) {
|
const getRequiredPopupWidth = function (actor) {
|
||||||
let requiredPopupWidth = 0;
|
let requiredPopupWidth = 0;
|
||||||
const textFont = actorFont(conf);
|
const textFont = actorFont(conf);
|
||||||
for (let key in actor.links) {
|
for (let key in actor.links) {
|
||||||
@@ -882,7 +882,7 @@ const getRequiredPopupWidth = function(actor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return requiredPopupWidth;
|
return requiredPopupWidth;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will calculate the optimal margin for each given actor, for a given
|
* This will calculate the optimal margin for each given actor, for a given
|
||||||
|
@@ -95,6 +95,17 @@ const getStyles = (options) =>
|
|||||||
fill: ${options.activationBkgColor};
|
fill: ${options.activationBkgColor};
|
||||||
stroke: ${options.activationBorderColor};
|
stroke: ${options.activationBorderColor};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.actorPopupMenu {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actorPopupMenuPanel {
|
||||||
|
position: absolute;
|
||||||
|
fill: ${options.actorBkg};
|
||||||
|
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||||
|
filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default getStyles;
|
export default getStyles;
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -94,14 +94,3 @@ text.actor > tspan {
|
|||||||
fill: $activationBkgColor;
|
fill: $activationBkgColor;
|
||||||
stroke: $activationBorderColor;
|
stroke: $activationBorderColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actorPopupMenu {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actorPopupMenuPanel {
|
|
||||||
position: absolute;
|
|
||||||
fill: $actorBkg;
|
|
||||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
|
||||||
filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user