diff --git a/packages/mermaid/src/diagrams/context-map/contextMapDb.js b/packages/mermaid/src/diagrams/context-map/contextMapDb.ts similarity index 51% rename from packages/mermaid/src/diagrams/context-map/contextMapDb.js rename to packages/mermaid/src/diagrams/context-map/contextMapDb.ts index 546fc07b217..a0d496f1bc3 100644 --- a/packages/mermaid/src/diagrams/context-map/contextMapDb.js +++ b/packages/mermaid/src/diagrams/context-map/contextMapDb.ts @@ -1,37 +1,25 @@ -let contextMap = undefined; -let nodes = []; -let edges = []; +import { type RawLink } from './contextMap.js'; -/** - * - * @param name - */ -export function setContextMapName(name) { +let contextMap: string | undefined = undefined; +let nodes: { id: string }[] = []; +let edges: RawLink[] = []; + +export function setContextMapName(name: string) { contextMap = name; } -/** - * - * @param name - */ -export function addNode(name) { + +export function addNode(name: string) { nodes.push({ id: name }); } -/** - * - * @param obj - */ -export function addEdge(obj) { + +export function addEdge(obj: RawLink) { edges.push(obj); } -/** - * - */ + export function getGraph() { return { contextMap, nodes, edges }; } -/** - * - */ + export function clear() { nodes = []; edges = []; diff --git a/packages/mermaid/src/diagrams/context-map/drawSvg.spec.ts b/packages/mermaid/src/diagrams/context-map/drawSvg.spec.ts index 0518f03fb90..d55270bda89 100644 --- a/packages/mermaid/src/diagrams/context-map/drawSvg.spec.ts +++ b/packages/mermaid/src/diagrams/context-map/drawSvg.spec.ts @@ -2,32 +2,14 @@ import * as d3 from 'd3'; import { Configuration, ContextMap, ContextMapLink, ContextMapNode } from './drawSvg.js'; import { describe, test, expect } from 'vitest'; +import { JSDOM } from 'jsdom'; describe('graph construction', () => { const fakeFont = { fontSize: 0, fontFamily: 'any', fontWeight: 0 }; - test('svg size', () => { - const svg = d3.create('svg'); - const config = new Configuration( - 500, - 500, - fakeFont, - () => 0, - () => 0, - { rx: 0, ry: 0 }, - { horizontal: 0, vertical: 0 } - ); - const contextMap = new ContextMap(config); - - contextMap.create(svg, [], []); - - expect(svg.attr('viewBox')).toBe('-250,-250,500,500'); - }); - test('node size', () => { - const svg = d3.create('svg'); const nodeId = 'CustomerSelfServiceContext'; - const nodes = [{ id: nodeId }]; + const node = { id: nodeId }; const calculateTextWidth = (text?: string): number => text?.length ?? 0; const textHeight = 15; const fontSize = 10; @@ -44,26 +26,16 @@ describe('graph construction', () => { { horizontal: 0, vertical: 0 } ); - const contextMap = new ContextMap(config); - - contextMap.create(svg, [], nodes); + const contextMapNode = ContextMapNode.createContextMapNode(node, config); - const d3Nodes = svg.selectAll('g').nodes(); - expect(d3.select(d3Nodes[0]).attr('transform')).toBe('translate(0,0)'); - - const ellipses = svg.selectAll('ellipse').nodes(); - expect(d3.select(ellipses[0]).attr('rx')).toBe( - ((ellipseSize.rx + calculateTextWidth(nodeId)) / 2).toString() - ); - expect(d3.select(ellipses[0]).attr('ry')).toBe(((ellipseSize.ry + textHeight) / 2).toString()); - - const texts = svg.selectAll('text').nodes(); - expect(d3.select(texts[0]).text()).toBe('CustomerSelfServiceContext'); - expect(d3.select(texts[0]).attr('font-size')).toBe(fontSize.toString()); - expect(d3.select(texts[0]).attr('font-weight')).toBe(fontWeight.toString()); - expect(d3.select(texts[0]).attr('font-family')).toBe(fontFamily); - expect(d3.select(texts[0]).attr('x')).toBe((-calculateTextWidth(nodeId) / 2).toString()); - expect(d3.select(texts[0]).attr('y')).toBe((textHeight / 4).toString()); + expect(contextMapNode.position).toStrictEqual({ x: 0, y: 0 }); + expect(contextMapNode.width).toBe(ellipseSize.rx + calculateTextWidth(nodeId)); + expect(contextMapNode.height).toBe(ellipseSize.ry + textHeight); + expect(contextMapNode.id).toBe('CustomerSelfServiceContext'); + expect(contextMapNode.textPosition).toStrictEqual({ + x: -calculateTextWidth(nodeId) / 2, + y: textHeight / 4, + }); }); // const textWidth = configuration.calculateTextWidth(node.id) @@ -72,16 +44,21 @@ describe('graph construction', () => { // const height = configuration.ellipseSize.ry+textHeight // const textX = -(textWidth/2) // const textY = textHeight/4 + // const targetNode = ContextMapNode.createContextMapNode(node, config) + // const link = { + // source: { id: 'CustomerSelfServiceContext', boxText: undefined, bodyText: undefined }, + // target: { id: 'PrintingContext', boxText: undefined, bodyText: undefined }, + // middleText: 'Shared Kernel', + // } + + // const contextMapLink = ContextMapLink.createContextMapLink( + // sourceNode, + // targetNode, + // link, + // config + // ) test('distribute nodes in the plane', () => { - const svg = d3.create('svg'); - const nodes = [ - { id: 'CustomerSelfServiceContext' }, - { id: 'CustomerSelfServiceContext' }, - { id: 'CustomerManagementContext' }, - { id: 'PrintingContext' }, - ]; - const config = new Configuration( 500, 500, @@ -92,15 +69,22 @@ describe('graph construction', () => { { horizontal: 0, vertical: 0 } ); - const contextMap = new ContextMap(config); + const contextMapNodes = [ + new ContextMapNode(100, 20, 0, 0, fakeFont, 'any'), + new ContextMapNode(100, 20, 0, 0, fakeFont, 'any'), + new ContextMapNode(100, 20, 0, 0, fakeFont, 'any'), + new ContextMapNode(100, 20, 0, 0, fakeFont, 'any'), + ]; - contextMap.create(svg, [], nodes); + const disposedNodes = ContextMapNode.disposeNodesInThePlane(contextMapNodes, { + width: 500, + height: 500, + }); - const d3Nodes = svg.selectAll('g').nodes(); - const [topLeftNodeX, topLeftNodeY] = pickD3TransformTranslatePos(d3Nodes[0]); - const [topRightNodeX, topRightNodeY] = pickD3TransformTranslatePos(d3Nodes[1]); - const [botLeftNodeX, botLeftNodeY] = pickD3TransformTranslatePos(d3Nodes[2]); - const [botRightNodeX, botRightNodeY] = pickD3TransformTranslatePos(d3Nodes[3]); + const { x: topLeftNodeX, y: topLeftNodeY } = disposedNodes[0].position; + const { x: topRightNodeX, y: topRightNodeY } = disposedNodes[1].position; + const { x: botLeftNodeX, y: botLeftNodeY } = disposedNodes[2].position; + const { x: botRightNodeX, y: botRightNodeY } = disposedNodes[3].position; expect(topLeftNodeX + topRightNodeX).toBe(0); expect(topLeftNodeY).toBe(topRightNodeY); @@ -108,38 +92,7 @@ describe('graph construction', () => { expect(botLeftNodeY).toBe(botRightNodeY); }); - test('position a link in the plane', () => { - const svg = d3.create('svg'); - const links = [ - { - source: { id: 'CustomerSelfServiceContext', boxText: undefined, bodyText: undefined }, - target: { id: 'PrintingContext', boxText: undefined, bodyText: undefined }, - middleText: 'Shared Kernel', - }, - ]; - const nodes = [{ id: 'CustomerSelfServiceContext' }, { id: 'PrintingContext' }]; - - const config = new Configuration( - 500, - 500, - fakeFont, - (text?: string): number => text?.length ?? 0, - (_) => 15, - { rx: 50, ry: 10 }, - { horizontal: 0, vertical: 0 } - ); - - const contextMap = new ContextMap(config); - - contextMap.create(svg, links, nodes); - - const d3Nodes = svg.selectAll('g').nodes(); - // expect(d3.select(d3Nodes[0]).attr("transform")).toBe("translate(-57.5,0)") - // expect(d3.select(d3Nodes[1]).attr("transform")).toBe("translate(63,0)") - - // const paths = svg.selectAll("path").nodes() - // expect(d3.select(paths[0]).attr("d")).toBe("M-57.5,0A0,0 0 0,1 63,0") - }); + test('position a link in the plane', () => {}); test('distribute 2 nodes in the plane', () => { const nodes = [ @@ -251,13 +204,4 @@ describe('graph construction', () => { expect(contextMapLinks[1].link.source.id).toBe('A'); expect(contextMapLinks[1].link.target.id).toBe('C'); }); - - function parseTranslate(translate: string): [number, number] { - const [_text, x, y] = translate.split(/[(),]/); - return [parseInt(x), parseInt(y)]; - } - - function pickD3TransformTranslatePos(d3Node: d3.BaseType): [number, number] { - return parseTranslate(d3.select(d3Node).attr('transform')); - } }); diff --git a/packages/mermaid/src/diagrams/context-map/drawSvg.ts b/packages/mermaid/src/diagrams/context-map/drawSvg.ts index c92c12372fb..bf83ee5b705 100644 --- a/packages/mermaid/src/diagrams/context-map/drawSvg.ts +++ b/packages/mermaid/src/diagrams/context-map/drawSvg.ts @@ -315,7 +315,7 @@ export class ContextMapNode { const perRowTotalWidth: number[] = []; const perRowTotalHeight: number[] = []; - let totalHeight: number = 0; + let totalHeight = 0; let counter = 0; let row = 0; diff --git a/packages/mermaid/src/diagrams/context-map/parser/contextMap.spec.js b/packages/mermaid/src/diagrams/context-map/parser/contextMap.spec.ts similarity index 98% rename from packages/mermaid/src/diagrams/context-map/parser/contextMap.spec.js rename to packages/mermaid/src/diagrams/context-map/parser/contextMap.spec.ts index 43256165f00..5f360323d17 100644 --- a/packages/mermaid/src/diagrams/context-map/parser/contextMap.spec.js +++ b/packages/mermaid/src/diagrams/context-map/parser/contextMap.spec.ts @@ -1,5 +1,7 @@ +// @ts-ignore: JISON doesn't support types import parser from './contextMap.jison'; import contextMapDb from '../contextMapDb.js'; +import { describe, it, beforeEach, expect } from 'vitest'; describe('check context map syntax', function () { beforeEach(() => { diff --git a/packages/mermaid/src/schemas/config.schema.yaml b/packages/mermaid/src/schemas/config.schema.yaml index 8f1ffac5727..b0ef5a1b4a3 100644 --- a/packages/mermaid/src/schemas/config.schema.yaml +++ b/packages/mermaid/src/schemas/config.schema.yaml @@ -890,11 +890,11 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file) properties: width: type: number - default: 600 + default: 600 height: type: number - default: 600 - nodeMargin: + default: 600 + nodeMargin: title: Context Map Node Margin description: margins of nodes type: object @@ -902,12 +902,12 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file) properties: horizontal: type: number - vertical: + vertical: type: number - default: + default: horizontal: 20 vertical: 30 - nodePadding: + nodePadding: title: Context Map Node Padding description: padding of nodes type: object @@ -915,7 +915,7 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file) properties: horizontal: type: number - vertical: + vertical: type: number default: horizontal: 100 @@ -928,15 +928,15 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file) properties: fontFamily: type: string - fontSize: + fontSize: type: number - fontWeight: + fontWeight: type: number default: - fontFamily: "Arial" - fontSize: 12 - fontWeight: 400 - + fontFamily: 'Arial' + fontSize: 12 + fontWeight: 400 + PieDiagramConfig: title: Pie Diagram Config allOf: [{ $ref: '#/$defs/BaseDiagramConfig' }]