mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-12-29 15:46:23 +01:00
Compare commits
6 Commits
fix/7210-g
...
refactor/s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7eb14f09bf | ||
|
|
b7c66a220a | ||
|
|
87e2d819bf | ||
|
|
93aa657578 | ||
|
|
43b7db9d6a | ||
|
|
df46b617d4 |
5
.changeset/late-bears-chew.md
Normal file
5
.changeset/late-bears-chew.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
revert: restore original hexagon and roundedRect implementations
|
||||
5
.changeset/restore-hexagon-roundedrect.md
Normal file
5
.changeset/restore-hexagon-roundedrect.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
chore: restore original hexagon and roundedRect implementations
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
fix(gitgraph): pass gitGraphConfig to renderer functions for applying directives properly.
|
||||
@@ -1569,514 +1569,4 @@ gitGraph TB:
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
describe('showBranches and showCommitLabel directives', () => {
|
||||
it('77: should show branch lines when showBranches is true (default)', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('78: should hide branch lines when showBranches is false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: false
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('79: should show commit labels when showCommitLabel is true (default)', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('80: should hide commit labels when showCommitLabel is false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: false
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('81: should show both branches and commit labels when both directives are true (default)', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('82: should hide both branches and commit labels when both directives are false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: false
|
||||
showCommitLabel: false
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('83: should show branch lines with merge commits when showBranches is true', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
merge develop
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('84: should hide branch lines with merge commits when showBranches is false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: false
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
merge develop
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('85: should show commit labels with tags when showCommitLabel is true', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1" tag: "v1.0"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3" tag: "v1.1"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
merge develop tag: "v2.0"
|
||||
commit id: "5"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('86: should hide commit labels with tags when showCommitLabel is false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: false
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1" tag: "v1.0"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3" tag: "v1.1"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
merge develop tag: "v2.0"
|
||||
commit id: "5"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('87: should show branches with TB orientation when showBranches is true', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph TB:
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('88: should hide branches with TB orientation when showBranches is false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: false
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph TB:
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('89: should show commit labels with BT orientation when showCommitLabel is true', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph BT:
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('90: should hide commit labels with BT orientation when showCommitLabel is false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: false
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph BT:
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('91: should render with rotateCommitLabel set to true', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: true
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "Alpha"
|
||||
commit id: "Beta"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "Gamma"
|
||||
commit id: "Delta"
|
||||
checkout main
|
||||
commit id: "Epsilon"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('92: should render with rotateCommitLabel set to false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "Alpha"
|
||||
commit id: "Beta"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "Gamma"
|
||||
commit id: "Delta"
|
||||
checkout main
|
||||
commit id: "Epsilon"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('93: should render with parallelCommits set to true', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: true
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
branch feature
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
checkout feature
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
checkout develop
|
||||
commit id: "6"
|
||||
checkout feature
|
||||
commit id: "7"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('94: should render with parallelCommits set to false', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
branch feature
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
checkout feature
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
checkout develop
|
||||
commit id: "6"
|
||||
checkout feature
|
||||
commit id: "7"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('95: should render with custom mainBranchName', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
mainBranchName: 'trunk'
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout trunk
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('96: should render with custom mainBranchOrder', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
gitGraph:
|
||||
showBranches: true
|
||||
showCommitLabel: true
|
||||
rotateCommitLabel: false
|
||||
parallelCommits: false
|
||||
mainBranchOrder: 2
|
||||
---
|
||||
gitGraph
|
||||
commit id: "1"
|
||||
branch feature1
|
||||
branch feature2
|
||||
checkout feature1
|
||||
commit id: "2"
|
||||
checkout feature2
|
||||
commit id: "3"
|
||||
checkout main
|
||||
commit id: "4"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1357,35 +1357,4 @@ describe('when parsing a gitGraph', function () {
|
||||
|
||||
logWarnSpy.mockRestore();
|
||||
});
|
||||
|
||||
describe('gitGraph config directives', () => {
|
||||
it('should expose getConfig method', () => {
|
||||
expect(db.getConfig).toBeDefined();
|
||||
expect(typeof db.getConfig).toBe('function');
|
||||
});
|
||||
|
||||
it('should return config with showBranches property', () => {
|
||||
const config = db.getConfig();
|
||||
expect(config).toBeDefined();
|
||||
expect(config).toHaveProperty('showBranches');
|
||||
});
|
||||
|
||||
it('should return config with showCommitLabel property', () => {
|
||||
const config = db.getConfig();
|
||||
expect(config).toBeDefined();
|
||||
expect(config).toHaveProperty('showCommitLabel');
|
||||
});
|
||||
|
||||
it('should return config with rotateCommitLabel property', () => {
|
||||
const config = db.getConfig();
|
||||
expect(config).toBeDefined();
|
||||
expect(config).toHaveProperty('rotateCommitLabel');
|
||||
});
|
||||
|
||||
it('should return config with parallelCommits property', () => {
|
||||
const config = db.getConfig();
|
||||
expect(config).toBeDefined();
|
||||
expect(config).toHaveProperty('parallelCommits');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { select } from 'd3';
|
||||
import { setupGraphViewbox } from '../../diagram-api/diagramAPI.js';
|
||||
import { getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI.js';
|
||||
import { log } from '../../logger.js';
|
||||
import utils from '../../utils.js';
|
||||
import type { DrawDefinition } from '../../diagram-api/types.js';
|
||||
import type d3 from 'd3';
|
||||
import type { Commit, GitGraphDBRenderProvider, DiagramOrientation } from './gitGraphTypes.js';
|
||||
import { commitType } from './gitGraphTypes.js';
|
||||
import type { GitGraphDiagramConfig } from '../../config.type.js';
|
||||
|
||||
interface BranchPosition {
|
||||
pos: number;
|
||||
@@ -22,6 +21,8 @@ interface CommitPositionOffset extends CommitPosition {
|
||||
posWithOffset: number;
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG = getConfig();
|
||||
const DEFAULT_GITGRAPH_CONFIG = DEFAULT_CONFIG?.gitGraph;
|
||||
const LAYOUT_OFFSET = 10;
|
||||
const COMMIT_STEP = 40;
|
||||
const PX = 4;
|
||||
@@ -286,13 +287,12 @@ const drawCommitLabel = (
|
||||
gLabels: d3.Selection<SVGGElement, unknown, HTMLElement, any>,
|
||||
commit: Commit,
|
||||
commitPosition: CommitPositionOffset,
|
||||
pos: number,
|
||||
gitGraphConfig: GitGraphDiagramConfig
|
||||
pos: number
|
||||
) => {
|
||||
if (
|
||||
commit.type !== commitType.CHERRY_PICK &&
|
||||
((commit.customId && commit.type === commitType.MERGE) || commit.type !== commitType.MERGE) &&
|
||||
gitGraphConfig.showCommitLabel
|
||||
DEFAULT_GITGRAPH_CONFIG?.showCommitLabel
|
||||
) {
|
||||
const wrapper = gLabels.append('g');
|
||||
const labelBkg = wrapper.insert('rect').attr('class', 'commit-label-bkg');
|
||||
@@ -322,7 +322,7 @@ const drawCommitLabel = (
|
||||
text.attr('x', commitPosition.posWithOffset - bbox.width / 2);
|
||||
}
|
||||
|
||||
if (gitGraphConfig.rotateCommitLabel) {
|
||||
if (DEFAULT_GITGRAPH_CONFIG.rotateCommitLabel) {
|
||||
if (dir === 'TB' || dir === 'BT') {
|
||||
text.attr(
|
||||
'transform',
|
||||
@@ -514,14 +514,16 @@ const getCommitPosition = (
|
||||
const drawCommits = (
|
||||
svg: d3.Selection<d3.BaseType, unknown, HTMLElement, any>,
|
||||
commits: Map<string, Commit>,
|
||||
modifyGraph: boolean,
|
||||
gitGraphConfig: GitGraphDiagramConfig
|
||||
modifyGraph: boolean
|
||||
) => {
|
||||
if (!DEFAULT_GITGRAPH_CONFIG) {
|
||||
throw new Error('GitGraph config not found');
|
||||
}
|
||||
const gBullets = svg.append('g').attr('class', 'commit-bullets');
|
||||
const gLabels = svg.append('g').attr('class', 'commit-labels');
|
||||
let pos = dir === 'TB' || dir === 'BT' ? defaultPos : 0;
|
||||
const keys = [...commits.keys()];
|
||||
const isParallelCommits = gitGraphConfig.parallelCommits ?? false;
|
||||
const isParallelCommits = DEFAULT_GITGRAPH_CONFIG?.parallelCommits ?? false;
|
||||
|
||||
const sortKeys = (a: string, b: string) => {
|
||||
const seqA = commits.get(a)?.seq;
|
||||
@@ -553,7 +555,7 @@ const drawCommits = (
|
||||
const commitSymbolType = commit.customType ?? commit.type;
|
||||
const branchIndex = branchPos.get(commit.branch)?.index ?? 0;
|
||||
drawCommitBullet(gBullets, commit, commitPosition, typeClass, branchIndex, commitSymbolType);
|
||||
drawCommitLabel(gLabels, commit, commitPosition, pos, gitGraphConfig);
|
||||
drawCommitLabel(gLabels, commit, commitPosition, pos);
|
||||
drawCommitTags(gLabels, commit, commitPosition, pos);
|
||||
}
|
||||
if (dir === 'TB' || dir === 'BT') {
|
||||
@@ -810,8 +812,7 @@ const drawArrows = (
|
||||
|
||||
const drawBranches = (
|
||||
svg: d3.Selection<d3.BaseType, unknown, HTMLElement, any>,
|
||||
branches: { name: string }[],
|
||||
gitGraphConfig: GitGraphDiagramConfig
|
||||
branches: { name: string }[]
|
||||
) => {
|
||||
const g = svg.append('g');
|
||||
branches.forEach((branch, index) => {
|
||||
@@ -858,14 +859,14 @@ const drawBranches = (
|
||||
.attr('class', 'branchLabelBkg label' + adjustIndexForTheme)
|
||||
.attr('rx', 4)
|
||||
.attr('ry', 4)
|
||||
.attr('x', -bbox.width - 4 - (gitGraphConfig.rotateCommitLabel === true ? 30 : 0))
|
||||
.attr('x', -bbox.width - 4 - (DEFAULT_GITGRAPH_CONFIG?.rotateCommitLabel === true ? 30 : 0))
|
||||
.attr('y', -bbox.height / 2 + 8)
|
||||
.attr('width', bbox.width + 18)
|
||||
.attr('height', bbox.height + 4);
|
||||
label.attr(
|
||||
'transform',
|
||||
'translate(' +
|
||||
(-bbox.width - 14 - (gitGraphConfig.rotateCommitLabel === true ? 30 : 0)) +
|
||||
(-bbox.width - 14 - (DEFAULT_GITGRAPH_CONFIG?.rotateCommitLabel === true ? 30 : 0)) +
|
||||
', ' +
|
||||
(pos - bbox.height / 2 - 1) +
|
||||
')'
|
||||
@@ -898,13 +899,11 @@ export const draw: DrawDefinition = function (txt, id, ver, diagObj) {
|
||||
clear();
|
||||
|
||||
log.debug('in gitgraph renderer', txt + '\n', 'id:', id, ver);
|
||||
const db = diagObj.db as GitGraphDBRenderProvider;
|
||||
if (!db.getConfig) {
|
||||
log.error('getConfig method is not available on db');
|
||||
return;
|
||||
if (!DEFAULT_GITGRAPH_CONFIG) {
|
||||
throw new Error('GitGraph config not found');
|
||||
}
|
||||
const gitGraphConfig = db.getConfig();
|
||||
const rotateCommitLabel = gitGraphConfig.rotateCommitLabel ?? false;
|
||||
const rotateCommitLabel = DEFAULT_GITGRAPH_CONFIG.rotateCommitLabel ?? false;
|
||||
const db = diagObj.db as GitGraphDBRenderProvider;
|
||||
allCommitsDict = db.getCommits();
|
||||
const branches = db.getBranchesAsObjArray();
|
||||
dir = db.getDirection();
|
||||
@@ -925,22 +924,27 @@ export const draw: DrawDefinition = function (txt, id, ver, diagObj) {
|
||||
g.remove();
|
||||
});
|
||||
|
||||
drawCommits(diagram, allCommitsDict, false, gitGraphConfig);
|
||||
if (gitGraphConfig.showBranches) {
|
||||
drawBranches(diagram, branches, gitGraphConfig);
|
||||
drawCommits(diagram, allCommitsDict, false);
|
||||
if (DEFAULT_GITGRAPH_CONFIG.showBranches) {
|
||||
drawBranches(diagram, branches);
|
||||
}
|
||||
drawArrows(diagram, allCommitsDict);
|
||||
drawCommits(diagram, allCommitsDict, true, gitGraphConfig);
|
||||
drawCommits(diagram, allCommitsDict, true);
|
||||
|
||||
utils.insertTitle(
|
||||
diagram,
|
||||
'gitTitleText',
|
||||
gitGraphConfig.titleTopMargin ?? 0,
|
||||
DEFAULT_GITGRAPH_CONFIG.titleTopMargin ?? 0,
|
||||
db.getDiagramTitle()
|
||||
);
|
||||
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, diagram, gitGraphConfig.diagramPadding, gitGraphConfig.useMaxWidth);
|
||||
setupGraphViewbox(
|
||||
undefined,
|
||||
diagram,
|
||||
DEFAULT_GITGRAPH_CONFIG.diagramPadding,
|
||||
DEFAULT_GITGRAPH_CONFIG.useMaxWidth
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
@@ -1303,6 +1307,7 @@ if (import.meta.vitest) {
|
||||
branchPos.set('main', { pos: 0, index: 0 });
|
||||
branchPos.set('develop', { pos: 107.49609375, index: 1 });
|
||||
branchPos.set('feature', { pos: 225.70703125, index: 2 });
|
||||
DEFAULT_GITGRAPH_CONFIG!.parallelCommits = true;
|
||||
commits.forEach((commit, key) => {
|
||||
if (commit.parents.length > 0) {
|
||||
curPos = calculateCommitPosition(commit);
|
||||
@@ -1330,6 +1335,7 @@ if (import.meta.vitest) {
|
||||
});
|
||||
});
|
||||
});
|
||||
DEFAULT_GITGRAPH_CONFIG!.parallelCommits = false;
|
||||
it('add', () => {
|
||||
commitPos.set('parent1', { x: 1, y: 1 });
|
||||
commitPos.set('parent2', { x: 2, y: 2 });
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js';
|
||||
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import type { Node } from '../../types.js';
|
||||
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { insertPolygonShape } from './insertPolygonShape.js';
|
||||
import type { D3Selection } from '../../../types.js';
|
||||
|
||||
export const createHexagonPathD = (
|
||||
@@ -28,50 +29,42 @@ export async function hexagon<T extends SVGGraphicsElement>(parent: D3Selection<
|
||||
node.labelStyle = labelStyles;
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const h = bbox.height + (node.padding ?? 0);
|
||||
const w = bbox.width + (node.padding ?? 0) * 2.5;
|
||||
const { cssStyles } = node;
|
||||
// @ts-expect-error -- Passing a D3.Selection seems to work for some reason
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {});
|
||||
|
||||
if (node.look !== 'handDrawn') {
|
||||
options.roughness = 0;
|
||||
options.fillStyle = 'solid';
|
||||
}
|
||||
|
||||
let halfWidth = w / 2;
|
||||
const m = halfWidth / 6; // Margin for label
|
||||
halfWidth = halfWidth + m; // Adjusted half width for hexagon
|
||||
|
||||
const halfHeight = h / 2;
|
||||
|
||||
const fixedLength = halfHeight / 2;
|
||||
const deducedWidth = halfWidth - fixedLength;
|
||||
|
||||
const f = 4;
|
||||
const h = bbox.height + node.padding;
|
||||
const m = h / f;
|
||||
const w = bbox.width + 2 * m + node.padding;
|
||||
const points = [
|
||||
{ x: -deducedWidth, y: -halfHeight },
|
||||
{ x: 0, y: -halfHeight },
|
||||
{ x: deducedWidth, y: -halfHeight },
|
||||
{ x: halfWidth, y: 0 },
|
||||
{ x: deducedWidth, y: halfHeight },
|
||||
{ x: 0, y: halfHeight },
|
||||
{ x: -deducedWidth, y: halfHeight },
|
||||
{ x: -halfWidth, y: 0 },
|
||||
{ x: m, y: 0 },
|
||||
{ x: w - m, y: 0 },
|
||||
{ x: w, y: -h / 2 },
|
||||
{ x: w - m, y: -h },
|
||||
{ x: m, y: -h },
|
||||
{ x: 0, y: -h / 2 },
|
||||
];
|
||||
|
||||
const pathData = createPathFromPoints(points);
|
||||
const shapeNode = rc.path(pathData, options);
|
||||
let polygon: D3Selection<SVGGElement> | Awaited<ReturnType<typeof insertPolygonShape>>;
|
||||
const { cssStyles } = node;
|
||||
|
||||
const polygon = shapeSvg.insert(() => shapeNode, ':first-child');
|
||||
polygon.attr('class', 'basic label-container');
|
||||
if (node.look === 'handDrawn') {
|
||||
// @ts-expect-error -- Passing a D3.Selection seems to work for some reason
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {});
|
||||
const pathData = createHexagonPathD(0, 0, w, h, m);
|
||||
const roughNode = rc.path(pathData, options);
|
||||
|
||||
if (cssStyles && node.look !== 'handDrawn') {
|
||||
polygon.selectChildren('path').attr('style', cssStyles);
|
||||
polygon = shapeSvg
|
||||
.insert(() => roughNode, ':first-child')
|
||||
.attr('transform', `translate(${-w / 2}, ${h / 2})`);
|
||||
|
||||
if (cssStyles) {
|
||||
polygon.attr('style', cssStyles);
|
||||
}
|
||||
} else {
|
||||
polygon = insertPolygonShape(shapeSvg, w, h, points);
|
||||
}
|
||||
|
||||
if (nodeStyles && node.look !== 'handDrawn') {
|
||||
polygon.selectChildren('path').attr('style', nodeStyles);
|
||||
if (nodeStyles) {
|
||||
polygon.attr('style', nodeStyles);
|
||||
}
|
||||
|
||||
node.width = w;
|
||||
|
||||
@@ -1,161 +1,18 @@
|
||||
import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import type { Node } from '../../types.js';
|
||||
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import type { Node, RectOptions } from '../../types.js';
|
||||
import type { D3Selection } from '../../../types.js';
|
||||
|
||||
/**
|
||||
* Generates evenly spaced points along an elliptical arc connecting two points.
|
||||
*
|
||||
* @param x1 - x-coordinate of the start point of the arc
|
||||
* @param y1 - y-coordinate of the start point of the arc
|
||||
* @param x2 - x-coordinate of the end point of the arc
|
||||
* @param y2 - y-coordinate of the end point of the arc
|
||||
* @param rx - horizontal radius of the ellipse
|
||||
* @param ry - vertical radius of the ellipse
|
||||
* @param clockwise - direction of the arc; true for clockwise, false for counterclockwise
|
||||
* @returns Array of points `{ x, y }` along the elliptical arc
|
||||
*
|
||||
* @throws Error if the given radii are too small to draw an arc between the points
|
||||
*/
|
||||
export function generateArcPoints(
|
||||
x1: number,
|
||||
y1: number,
|
||||
x2: number,
|
||||
y2: number,
|
||||
rx: number,
|
||||
ry: number,
|
||||
clockwise: boolean
|
||||
) {
|
||||
const numPoints = 20;
|
||||
// Calculate midpoint
|
||||
const midX = (x1 + x2) / 2;
|
||||
const midY = (y1 + y2) / 2;
|
||||
|
||||
// Calculate the angle of the line connecting the points
|
||||
const angle = Math.atan2(y2 - y1, x2 - x1);
|
||||
|
||||
// Calculate transformed coordinates for the ellipse
|
||||
const dx = (x2 - x1) / 2;
|
||||
const dy = (y2 - y1) / 2;
|
||||
|
||||
// Scale to unit circle
|
||||
const transformedX = dx / rx;
|
||||
const transformedY = dy / ry;
|
||||
|
||||
// Calculate the distance between points on the unit circle
|
||||
const distance = Math.sqrt(transformedX ** 2 + transformedY ** 2);
|
||||
|
||||
// Check if the ellipse can be drawn with the given radii
|
||||
if (distance > 1) {
|
||||
throw new Error('The given radii are too small to create an arc between the points.');
|
||||
}
|
||||
|
||||
// Calculate the distance from the midpoint to the center of the ellipse
|
||||
const scaledCenterDistance = Math.sqrt(1 - distance ** 2);
|
||||
|
||||
// Calculate the center of the ellipse
|
||||
const centerX = midX + scaledCenterDistance * ry * Math.sin(angle) * (clockwise ? -1 : 1);
|
||||
const centerY = midY - scaledCenterDistance * rx * Math.cos(angle) * (clockwise ? -1 : 1);
|
||||
|
||||
// Calculate the start and end angles on the ellipse
|
||||
const startAngle = Math.atan2((y1 - centerY) / ry, (x1 - centerX) / rx);
|
||||
const endAngle = Math.atan2((y2 - centerY) / ry, (x2 - centerX) / rx);
|
||||
|
||||
// Adjust angles for clockwise/counterclockwise
|
||||
let angleRange = endAngle - startAngle;
|
||||
if (clockwise && angleRange < 0) {
|
||||
angleRange += 2 * Math.PI;
|
||||
}
|
||||
if (!clockwise && angleRange > 0) {
|
||||
angleRange -= 2 * Math.PI;
|
||||
}
|
||||
|
||||
// Generate points
|
||||
const points = [];
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
const t = i / (numPoints - 1);
|
||||
const angle = startAngle + t * angleRange;
|
||||
const x = centerX + rx * Math.cos(angle);
|
||||
const y = centerY + ry * Math.sin(angle);
|
||||
points.push({ x, y });
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
import { drawRect } from './drawRect.js';
|
||||
|
||||
export async function roundedRect<T extends SVGGraphicsElement>(
|
||||
parent: D3Selection<T>,
|
||||
node: Node
|
||||
) {
|
||||
const { labelStyles, nodeStyles } = styles2String(node);
|
||||
node.labelStyle = labelStyles;
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
const options = {
|
||||
rx: 5,
|
||||
ry: 5,
|
||||
classes: '',
|
||||
labelPaddingX: (node?.padding || 0) * 1,
|
||||
labelPaddingY: (node?.padding || 0) * 1,
|
||||
} as RectOptions;
|
||||
|
||||
const labelPaddingX = node?.padding ?? 0;
|
||||
const labelPaddingY = node?.padding ?? 0;
|
||||
|
||||
const w = (node?.width ? node?.width : bbox.width) + labelPaddingX * 2;
|
||||
const h = (node?.height ? node?.height : bbox.height) + labelPaddingY * 2;
|
||||
const radius = node.radius || 5;
|
||||
const taper = node.taper || 5; // Taper width for the rounded corners
|
||||
const { cssStyles } = node;
|
||||
// @ts-expect-error -- Passing a D3.Selection seems to work for some reason
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {});
|
||||
if (node.stroke) {
|
||||
options.stroke = node.stroke;
|
||||
}
|
||||
if (node.look !== 'handDrawn') {
|
||||
options.roughness = 0;
|
||||
options.fillStyle = 'solid';
|
||||
}
|
||||
const points = [
|
||||
// Top edge (left to right)
|
||||
{ x: -w / 2 + taper, y: -h / 2 }, // Top-left corner start (1)
|
||||
{ x: w / 2 - taper, y: -h / 2 }, // Top-right corner start (2)
|
||||
|
||||
...generateArcPoints(w / 2 - taper, -h / 2, w / 2, -h / 2 + taper, radius, radius, true), // Top-left arc (2 to 3)
|
||||
|
||||
// Right edge (top to bottom)
|
||||
{ x: w / 2, y: -h / 2 + taper }, // Top-right taper point (3)
|
||||
{ x: w / 2, y: h / 2 - taper }, // Bottom-right taper point (4)
|
||||
|
||||
...generateArcPoints(w / 2, h / 2 - taper, w / 2 - taper, h / 2, radius, radius, true), // Top-left arc (4 to 5)
|
||||
|
||||
// Bottom edge (right to left)
|
||||
{ x: w / 2 - taper, y: h / 2 }, // Bottom-right corner start (5)
|
||||
{ x: -w / 2 + taper, y: h / 2 }, // Bottom-left corner start (6)
|
||||
|
||||
...generateArcPoints(-w / 2 + taper, h / 2, -w / 2, h / 2 - taper, radius, radius, true), // Top-left arc (4 to 5)
|
||||
|
||||
// Left edge (bottom to top)
|
||||
{ x: -w / 2, y: h / 2 - taper }, // Bottom-left taper point (7)
|
||||
{ x: -w / 2, y: -h / 2 + taper }, // Top-left taper point (8)
|
||||
...generateArcPoints(-w / 2, -h / 2 + taper, -w / 2 + taper, -h / 2, radius, radius, true), // Top-left arc (4 to 5)
|
||||
];
|
||||
|
||||
const pathData = createPathFromPoints(points);
|
||||
const shapeNode = rc.path(pathData, options);
|
||||
|
||||
const polygon = shapeSvg.insert(() => shapeNode, ':first-child');
|
||||
polygon.attr('class', 'basic label-container outer-path');
|
||||
|
||||
if (cssStyles && node.look !== 'handDrawn') {
|
||||
polygon.selectChildren('path').attr('style', cssStyles);
|
||||
}
|
||||
|
||||
if (nodeStyles && node.look !== 'handDrawn') {
|
||||
polygon.selectChildren('path').attr('style', nodeStyles);
|
||||
}
|
||||
|
||||
updateNodeBounds(node, polygon);
|
||||
|
||||
node.intersect = function (point) {
|
||||
const pos = intersect.polygon(node, points, point);
|
||||
return pos;
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
return drawRect(parent, node, options);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user