mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
fixed BT with parallel commits and added more unit tests
This commit is contained in:
parent
aba306b685
commit
d73a090875
@ -76,12 +76,11 @@ const drawText = (txt: string | string[]) => {
|
|||||||
return svgLabel;
|
return svgLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
const findClosestParent = (parents: string[], useBTLogic = false): string | undefined => {
|
const findClosestParent = (parents: string[]): string | undefined => {
|
||||||
let closestParent: string | undefined;
|
let closestParent: string | undefined;
|
||||||
let comparisonFunc;
|
let comparisonFunc;
|
||||||
let targetPosition: number;
|
let targetPosition: number;
|
||||||
|
if (dir === 'BT') {
|
||||||
if (dir === 'BT' || useBTLogic) {
|
|
||||||
comparisonFunc = (a: number, b: number) => a <= b;
|
comparisonFunc = (a: number, b: number) => a <= b;
|
||||||
targetPosition = Infinity;
|
targetPosition = Infinity;
|
||||||
} else {
|
} else {
|
||||||
@ -91,9 +90,7 @@ const findClosestParent = (parents: string[], useBTLogic = false): string | unde
|
|||||||
|
|
||||||
parents.forEach((parent) => {
|
parents.forEach((parent) => {
|
||||||
const parentPosition =
|
const parentPosition =
|
||||||
dir === 'TB' || dir == 'BT' || useBTLogic
|
dir === 'TB' || dir == 'BT' ? commitPos.get(parent)?.y : commitPos.get(parent)?.x;
|
||||||
? commitPos.get(parent)?.y
|
|
||||||
: commitPos.get(parent)?.x;
|
|
||||||
|
|
||||||
if (parentPosition !== undefined && comparisonFunc(parentPosition, targetPosition)) {
|
if (parentPosition !== undefined && comparisonFunc(parentPosition, targetPosition)) {
|
||||||
closestParent = parent;
|
closestParent = parent;
|
||||||
@ -104,6 +101,20 @@ const findClosestParent = (parents: string[], useBTLogic = false): string | unde
|
|||||||
return closestParent;
|
return closestParent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const findClosestParentBT = (parents: string[]) => {
|
||||||
|
let closestParent = '';
|
||||||
|
let maxPosition = Infinity;
|
||||||
|
|
||||||
|
parents.forEach((parent) => {
|
||||||
|
const parentPosition = commitPos.get(parent)!.y;
|
||||||
|
if (parentPosition <= maxPosition) {
|
||||||
|
closestParent = parent;
|
||||||
|
maxPosition = parentPosition;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return closestParent || undefined;
|
||||||
|
};
|
||||||
|
|
||||||
const setParallelBTPos = (
|
const setParallelBTPos = (
|
||||||
sortedKeys: string[],
|
sortedKeys: string[],
|
||||||
commits: Map<string, Commit>,
|
commits: Map<string, Commit>,
|
||||||
@ -119,7 +130,7 @@ const setParallelBTPos = (
|
|||||||
throw new Error(`Commit not found for key ${key}`);
|
throw new Error(`Commit not found for key ${key}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParents(commit)) {
|
if (commit.parents.length) {
|
||||||
curPos = calculateCommitPosition(commit);
|
curPos = calculateCommitPosition(commit);
|
||||||
maxPosition = Math.max(curPos, maxPosition);
|
maxPosition = Math.max(curPos, maxPosition);
|
||||||
} else {
|
} else {
|
||||||
@ -132,9 +143,21 @@ const setParallelBTPos = (
|
|||||||
roots.forEach((commit) => {
|
roots.forEach((commit) => {
|
||||||
setRootPosition(commit, curPos, defaultPos);
|
setRootPosition(commit, curPos, defaultPos);
|
||||||
});
|
});
|
||||||
};
|
sortedKeys.forEach((key) => {
|
||||||
|
const commit = commits.get(key);
|
||||||
|
|
||||||
const hasParents = (commit: Commit): boolean => commit.parents?.length > 0;
|
if (commit?.parents.length) {
|
||||||
|
const closestParent = findClosestParentBT(commit.parents)!;
|
||||||
|
curPos = commitPos.get(closestParent)!.y - COMMIT_STEP;
|
||||||
|
if (curPos <= maxPosition) {
|
||||||
|
maxPosition = curPos;
|
||||||
|
}
|
||||||
|
const x = branchPos.get(commit.branch)!.pos;
|
||||||
|
const y = curPos - LAYOUT_OFFSET;
|
||||||
|
commitPos.set(commit.id, { x: x, y: y });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const findClosestParentPos = (commit: Commit): number => {
|
const findClosestParentPos = (commit: Commit): number => {
|
||||||
const closestParent = findClosestParent(commit.parents.filter((p) => p !== null));
|
const closestParent = findClosestParent(commit.parents.filter((p) => p !== null));
|
||||||
@ -154,8 +177,9 @@ const calculateCommitPosition = (commit: Commit): number => {
|
|||||||
return closestParentPos + COMMIT_STEP;
|
return closestParentPos + COMMIT_STEP;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setCommitPosition = (commit: Commit, curPos: number) => {
|
const setCommitPosition = (commit: Commit, curPos: number): CommitPosition => {
|
||||||
const branch = branchPos.get(commit.branch);
|
const branch = branchPos.get(commit.branch);
|
||||||
|
|
||||||
if (!branch) {
|
if (!branch) {
|
||||||
throw new Error(`Branch not found for commit ${commit.id}`);
|
throw new Error(`Branch not found for commit ${commit.id}`);
|
||||||
}
|
}
|
||||||
@ -163,6 +187,7 @@ const setCommitPosition = (commit: Commit, curPos: number) => {
|
|||||||
const x = branch.pos;
|
const x = branch.pos;
|
||||||
const y = curPos + LAYOUT_OFFSET;
|
const y = curPos + LAYOUT_OFFSET;
|
||||||
commitPos.set(commit.id, { x, y });
|
commitPos.set(commit.id, { x, y });
|
||||||
|
return { x, y };
|
||||||
};
|
};
|
||||||
|
|
||||||
const setRootPosition = (commit: Commit, curPos: number, defaultPos: number) => {
|
const setRootPosition = (commit: Commit, curPos: number, defaultPos: number) => {
|
||||||
@ -266,7 +291,6 @@ const drawCommitBullet = (
|
|||||||
`M ${commitPosition.x - 5},${commitPosition.y - 5}L${commitPosition.x + 5},${commitPosition.y + 5}M${commitPosition.x - 5},${commitPosition.y + 5}L${commitPosition.x + 5},${commitPosition.y - 5}`
|
`M ${commitPosition.x - 5},${commitPosition.y - 5}L${commitPosition.x + 5},${commitPosition.y + 5}M${commitPosition.x - 5},${commitPosition.y + 5}L${commitPosition.x + 5},${commitPosition.y - 5}`
|
||||||
)
|
)
|
||||||
.attr('class', `commit ${typeClass} ${commit.id} commit${branchIndex % THEME_COLOR_LIMIT}`);
|
.attr('class', `commit ${typeClass} ${commit.id} commit${branchIndex % THEME_COLOR_LIMIT}`);
|
||||||
log.info();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -522,12 +546,13 @@ const drawCommits = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
let sortedKeys = keys.sort(sortKeys);
|
let sortedKeys = keys.sort(sortKeys);
|
||||||
|
|
||||||
if (dir === 'BT') {
|
if (dir === 'BT') {
|
||||||
if (isParallelCommits) {
|
if (isParallelCommits) {
|
||||||
setParallelBTPos(sortedKeys, commits, pos);
|
setParallelBTPos(sortedKeys, commits, pos);
|
||||||
|
sortedKeys = sortedKeys.reverse();
|
||||||
|
} else {
|
||||||
|
sortedKeys = sortedKeys.reverse();
|
||||||
}
|
}
|
||||||
sortedKeys = sortedKeys.reverse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sortedKeys.forEach((key) => {
|
sortedKeys.forEach((key) => {
|
||||||
@ -544,7 +569,6 @@ const drawCommits = (
|
|||||||
if (modifyGraph) {
|
if (modifyGraph) {
|
||||||
const typeClass = getCommitClassType(commit);
|
const typeClass = getCommitClassType(commit);
|
||||||
const commitSymbolType = commit.customType ?? commit.type;
|
const commitSymbolType = commit.customType ?? commit.type;
|
||||||
log.info('commitSymbolType', commitSymbolType);
|
|
||||||
const branchIndex = branchPos.get(commit.branch)?.index ?? 0;
|
const branchIndex = branchPos.get(commit.branch)?.index ?? 0;
|
||||||
drawCommitBullet(gBullets, commit, commitPosition, typeClass, branchIndex, commitSymbolType);
|
drawCommitBullet(gBullets, commit, commitPosition, typeClass, branchIndex, commitSymbolType);
|
||||||
drawCommitLabel(gLabels, commit, commitPosition, pos, gitGraphConfig);
|
drawCommitLabel(gLabels, commit, commitPosition, pos, gitGraphConfig);
|
||||||
@ -885,9 +909,6 @@ const setBranchPosition = function (
|
|||||||
): number {
|
): number {
|
||||||
branchPos.set(name, { pos, index });
|
branchPos.set(name, { pos, index });
|
||||||
pos += 50 + (rotateCommitLabel ? 40 : 0) + (dir === 'TB' || dir === 'BT' ? bbox.width / 2 : 0);
|
pos += 50 + (rotateCommitLabel ? 40 : 0) + (dir === 'TB' || dir === 'BT' ? bbox.width / 2 : 0);
|
||||||
log.info('bbox.width', bbox.width);
|
|
||||||
log.info('setBranchPosition', name, pos, index, bbox);
|
|
||||||
log.info('branchPos', branchPos);
|
|
||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1160,6 +1181,175 @@ if (import.meta.vitest) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('building BT parallel commit diagram', () => {
|
||||||
|
const commits = new Map<string, Commit>([
|
||||||
|
[
|
||||||
|
'1-abcdefg',
|
||||||
|
{
|
||||||
|
id: '1-abcdefg',
|
||||||
|
message: '',
|
||||||
|
seq: 0,
|
||||||
|
type: 0,
|
||||||
|
tags: [],
|
||||||
|
parents: [],
|
||||||
|
branch: 'main',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'2-abcdefg',
|
||||||
|
{
|
||||||
|
id: '2-abcdefg',
|
||||||
|
message: '',
|
||||||
|
seq: 1,
|
||||||
|
type: 0,
|
||||||
|
tags: [],
|
||||||
|
parents: ['1-abcdefg'],
|
||||||
|
branch: 'main',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'3-abcdefg',
|
||||||
|
{
|
||||||
|
id: '3-abcdefg',
|
||||||
|
message: '',
|
||||||
|
seq: 2,
|
||||||
|
type: 0,
|
||||||
|
tags: [],
|
||||||
|
parents: ['2-abcdefg'],
|
||||||
|
branch: 'develop',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'4-abcdefg',
|
||||||
|
{
|
||||||
|
id: '4-abcdefg',
|
||||||
|
message: '',
|
||||||
|
seq: 3,
|
||||||
|
type: 0,
|
||||||
|
tags: [],
|
||||||
|
parents: ['3-abcdefg'],
|
||||||
|
branch: 'develop',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'5-abcdefg',
|
||||||
|
{
|
||||||
|
id: '5-abcdefg',
|
||||||
|
message: '',
|
||||||
|
seq: 4,
|
||||||
|
type: 0,
|
||||||
|
tags: [],
|
||||||
|
parents: ['2-abcdefg'],
|
||||||
|
branch: 'feature',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'6-abcdefg',
|
||||||
|
{
|
||||||
|
id: '6-abcdefg',
|
||||||
|
message: '',
|
||||||
|
seq: 5,
|
||||||
|
type: 0,
|
||||||
|
tags: [],
|
||||||
|
parents: ['5-abcdefg'],
|
||||||
|
branch: 'feature',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'7-abcdefg',
|
||||||
|
{
|
||||||
|
id: '7-abcdefg',
|
||||||
|
message: '',
|
||||||
|
seq: 6,
|
||||||
|
type: 0,
|
||||||
|
tags: [],
|
||||||
|
parents: ['2-abcdefg'],
|
||||||
|
branch: 'main',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'8-abcdefg',
|
||||||
|
{
|
||||||
|
id: '8-abcdefg',
|
||||||
|
message: '',
|
||||||
|
seq: 7,
|
||||||
|
type: 0,
|
||||||
|
tags: [],
|
||||||
|
parents: ['7-abcdefg'],
|
||||||
|
branch: 'main',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
const expectedCommitPosition = new Map<string, CommitPosition>([
|
||||||
|
['1-abcdefg', { x: 0, y: 40 }],
|
||||||
|
['2-abcdefg', { x: 0, y: 90 }],
|
||||||
|
['3-abcdefg', { x: 107.49609375, y: 140 }],
|
||||||
|
['4-abcdefg', { x: 107.49609375, y: 190 }],
|
||||||
|
['5-abcdefg', { x: 225.70703125, y: 140 }],
|
||||||
|
['6-abcdefg', { x: 225.70703125, y: 190 }],
|
||||||
|
['7-abcdefg', { x: 0, y: 140 }],
|
||||||
|
['8-abcdefg', { x: 0, y: 190 }],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const expectedCommitPositionAfterParallel = new Map<string, CommitPosition>([
|
||||||
|
['1-abcdefg', { x: 0, y: 210 }],
|
||||||
|
['2-abcdefg', { x: 0, y: 160 }],
|
||||||
|
['3-abcdefg', { x: 107.49609375, y: 110 }],
|
||||||
|
['4-abcdefg', { x: 107.49609375, y: 60 }],
|
||||||
|
['5-abcdefg', { x: 225.70703125, y: 110 }],
|
||||||
|
['6-abcdefg', { x: 225.70703125, y: 60 }],
|
||||||
|
['7-abcdefg', { x: 0, y: 110 }],
|
||||||
|
['8-abcdefg', { x: 0, y: 60 }],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const expectedCommitCurrentPosition = new Map<string, number>([
|
||||||
|
['1-abcdefg', 30],
|
||||||
|
['2-abcdefg', 80],
|
||||||
|
['3-abcdefg', 130],
|
||||||
|
['4-abcdefg', 180],
|
||||||
|
['5-abcdefg', 130],
|
||||||
|
['6-abcdefg', 180],
|
||||||
|
['7-abcdefg', 130],
|
||||||
|
['8-abcdefg', 180],
|
||||||
|
]);
|
||||||
|
const sortedKeys = [...expectedCommitPosition.keys()];
|
||||||
|
it('should get the correct commit position and current position', () => {
|
||||||
|
dir = 'BT';
|
||||||
|
let curPos = 30;
|
||||||
|
commitPos.clear();
|
||||||
|
branchPos.clear();
|
||||||
|
branchPos.set('main', { pos: 0, index: 0 });
|
||||||
|
branchPos.set('develop', { pos: 107.49609375, index: 1 });
|
||||||
|
branchPos.set('feature', { pos: 225.70703125, index: 2 });
|
||||||
|
//TODO: need to make sure you set the parallel commits to true
|
||||||
|
|
||||||
|
commits.forEach((commit, key) => {
|
||||||
|
if (commit.parents.length > 0) {
|
||||||
|
curPos = calculateCommitPosition(commit);
|
||||||
|
}
|
||||||
|
const position = setCommitPosition(commit, curPos);
|
||||||
|
expect(position).toEqual(expectedCommitPosition.get(key));
|
||||||
|
expect(curPos).toEqual(expectedCommitCurrentPosition.get(key));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get the correct commit position after parallel commits', () => {
|
||||||
|
commitPos.clear();
|
||||||
|
branchPos.clear();
|
||||||
|
dir = 'BT';
|
||||||
|
const curPos = 30;
|
||||||
|
commitPos.clear();
|
||||||
|
branchPos.clear();
|
||||||
|
branchPos.set('main', { pos: 0, index: 0 });
|
||||||
|
branchPos.set('develop', { pos: 107.49609375, index: 1 });
|
||||||
|
branchPos.set('feature', { pos: 225.70703125, index: 2 });
|
||||||
|
setParallelBTPos(sortedKeys, commits, curPos);
|
||||||
|
sortedKeys.forEach((commit) => {
|
||||||
|
const position = commitPos.get(commit);
|
||||||
|
expect(position).toEqual(expectedCommitPositionAfterParallel.get(commit));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('add', () => {
|
it('add', () => {
|
||||||
commitPos.set('parent1', { x: 1, y: 1 });
|
commitPos.set('parent1', { x: 1, y: 1 });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user