Add support for unbordered text content, add convenience for placing notes/text on left/right of entire diagram
This commit is contained in:
parent
912c9dbb64
commit
cd949d6f38
|
@ -75,6 +75,8 @@ note over Foo, Bar: "Foo and Bar
|
|||
on multiple lines"
|
||||
note between Foo, Bar: Link
|
||||
|
||||
text right: 'Comments\nOver here!'
|
||||
|
||||
state over Foo: Foo is ponderous
|
||||
```
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 29 KiB |
|
@ -11,6 +11,12 @@ define(['core/ArrayUtilities'], (array) => {
|
|||
const LOCKED_AGENT = new AgentState(false, true);
|
||||
const DEFAULT_AGENT = new AgentState(false);
|
||||
|
||||
const NOTE_DEFAULT_AGENTS = {
|
||||
'note over': ['[', ']'],
|
||||
'note left': ['['],
|
||||
'note right': [']'],
|
||||
};
|
||||
|
||||
return class Generator {
|
||||
constructor() {
|
||||
this.agentStates = new Map();
|
||||
|
@ -24,6 +30,9 @@ define(['core/ArrayUtilities'], (array) => {
|
|||
this.stageHandlers = {
|
||||
'mark': this.handleMark.bind(this),
|
||||
'async': this.handleAsync.bind(this),
|
||||
'note over': this.handleNote.bind(this),
|
||||
'note left': this.handleNote.bind(this),
|
||||
'note right': this.handleNote.bind(this),
|
||||
'agent define': this.handleAgentDefine.bind(this),
|
||||
'agent begin': this.handleAgentBegin.bind(this),
|
||||
'agent end': this.handleAgentEnd.bind(this),
|
||||
|
@ -131,6 +140,16 @@ define(['core/ArrayUtilities'], (array) => {
|
|||
this.currentSection.stages.push(stage);
|
||||
}
|
||||
|
||||
handleNote(stage) {
|
||||
if(stage.agents.length === 0) {
|
||||
this.handleUnknownStage(Object.assign({}, stage, {
|
||||
agents: NOTE_DEFAULT_AGENTS[stage.type] || [],
|
||||
}));
|
||||
} else {
|
||||
this.handleUnknownStage(stage);
|
||||
}
|
||||
}
|
||||
|
||||
handleAgentDefine({agents}) {
|
||||
array.mergeSets(this.currentNest.agents, agents);
|
||||
array.mergeSets(this.agents, agents);
|
||||
|
|
|
@ -481,6 +481,21 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
|||
]})).toThrow();
|
||||
});
|
||||
|
||||
it('defaults to showing notes around the entire diagram', () => {
|
||||
const sequence = generator.generate({stages: [
|
||||
{type: 'note right', agents: [], foo: 'bar'},
|
||||
{type: 'note left', agents: [], foo: 'bar'},
|
||||
{type: 'note over', agents: [], foo: 'bar'},
|
||||
{type: 'note right', agents: ['[']},
|
||||
]});
|
||||
expect(sequence.stages).toEqual([
|
||||
{type: 'note right', agents: [']'], foo: 'bar'},
|
||||
{type: 'note left', agents: ['['], foo: 'bar'},
|
||||
{type: 'note over', agents: ['[', ']'], foo: 'bar'},
|
||||
{type: 'note right', agents: ['[']},
|
||||
]);
|
||||
});
|
||||
|
||||
it('rejects attempts to change implicit agents', () => {
|
||||
expect(() => generator.generate({stages: [
|
||||
{type: AGENT_BEGIN, agents: ['['], mode: 'box'},
|
||||
|
|
|
@ -49,12 +49,19 @@ define(['core/ArrayUtilities'], (array) => {
|
|||
];
|
||||
|
||||
const NOTE_TYPES = {
|
||||
'text': {
|
||||
mode: 'text',
|
||||
types: {
|
||||
'left': {type: 'note left', skip: ['of'], min: 0, max: null},
|
||||
'right': {type: 'note right', skip: ['of'], min: 0, max: null},
|
||||
},
|
||||
},
|
||||
'note': {
|
||||
mode: 'note',
|
||||
types: {
|
||||
'over': {type: 'note over', skip: [], min: 1, max: null},
|
||||
'left': {type: 'note left', skip: ['of'], min: 1, max: null},
|
||||
'right': {type: 'note right', skip: ['of'], min: 1, max: null},
|
||||
'over': {type: 'note over', skip: [], min: 0, max: null},
|
||||
'left': {type: 'note left', skip: ['of'], min: 0, max: null},
|
||||
'right': {type: 'note right', skip: ['of'], min: 0, max: null},
|
||||
'between': {type: 'note between', skip: [], min: 2, max: null},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -325,7 +325,7 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
|
|||
});
|
||||
|
||||
it('rejects note between for a single agent', () => {
|
||||
expect(() => parser.parse('state between A: hi')).toThrow();
|
||||
expect(() => parser.parse('note between A: hi')).toThrow();
|
||||
});
|
||||
|
||||
it('converts state', () => {
|
||||
|
@ -342,6 +342,16 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
|
|||
expect(() => parser.parse('state over A, B: hi')).toThrow();
|
||||
});
|
||||
|
||||
it('converts text blocks', () => {
|
||||
const parsed = parser.parse('text right of A: doing stuff');
|
||||
expect(parsed.stages).toEqual([{
|
||||
type: 'note right',
|
||||
agents: ['A'],
|
||||
mode: 'text',
|
||||
label: 'doing stuff',
|
||||
}]);
|
||||
});
|
||||
|
||||
it('converts agent commands', () => {
|
||||
const parsed = parser.parse(
|
||||
'define A, B\n' +
|
||||
|
|
|
@ -170,6 +170,8 @@ define([
|
|||
agents.forEach((agentR) => {
|
||||
const infoR = this.agentInfos.get(agentR);
|
||||
const sepR = agentSpaces.get(agentR) || SEP_ZERO;
|
||||
infoR.maxRPad = Math.max(infoR.maxRPad, sepR.right);
|
||||
infoR.maxLPad = Math.max(infoR.maxLPad, sepR.left);
|
||||
agents.forEach((agentL) => {
|
||||
const infoL = this.agentInfos.get(agentL);
|
||||
if(infoL.index >= infoR.index) {
|
||||
|
@ -853,8 +855,6 @@ define([
|
|||
}
|
||||
});
|
||||
agentInfo.x = currentX;
|
||||
this.minX = Math.min(this.minX, currentX);
|
||||
this.maxX = Math.max(this.maxX, currentX);
|
||||
orderedInfos.push(agentInfo);
|
||||
});
|
||||
|
||||
|
@ -873,6 +873,11 @@ define([
|
|||
});
|
||||
agentInfo.x = currentX;
|
||||
});
|
||||
|
||||
this.agentInfos.forEach(({label, x, maxRPad, maxLPad}) => {
|
||||
this.minX = Math.min(this.minX, x - maxLPad);
|
||||
this.maxX = Math.max(this.maxX, x + maxRPad);
|
||||
});
|
||||
}
|
||||
|
||||
buildAgentInfos(agents, stages) {
|
||||
|
@ -885,6 +890,8 @@ define([
|
|||
x: null,
|
||||
latestYStart: null,
|
||||
latestY: 0,
|
||||
maxRPad: 0,
|
||||
maxLPad: 0,
|
||||
separations: new Map(),
|
||||
});
|
||||
});
|
||||
|
|
|
@ -178,6 +178,19 @@ define([
|
|||
},
|
||||
|
||||
note: {
|
||||
'text': {
|
||||
margin: {top: 0, left: 2, right: 2, bottom: 0},
|
||||
padding: {top: 2, left: 2, right: 2, bottom: 2},
|
||||
overlap: {left: 10, right: 10},
|
||||
boxRenderer: SVGShapes.renderBox.bind(null, {
|
||||
'fill': '#FFFFFF',
|
||||
}),
|
||||
labelAttrs: {
|
||||
'font-family': 'sans-serif',
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT,
|
||||
},
|
||||
},
|
||||
'note': {
|
||||
margin: {top: 0, left: 5, right: 5, bottom: 0},
|
||||
padding: {top: 5, left: 5, right: 10, bottom: 5},
|
||||
|
|
Loading…
Reference in New Issue