-
Notifications
You must be signed in to change notification settings - Fork 9
[nad-viewer] Add edge info components in SVG creation from metadata #418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: integration/nad_create_svg
Are you sure you want to change the base?
Changes from all commits
1a0d31e
6ce58d0
a5a6cbc
3c13172
6717503
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,6 +14,9 @@ import * as MetadataUtils from './metadata-utils'; | |||||||||||||||||||||||
| import { EdgeRouter } from './edge-router'; | ||||||||||||||||||||||||
| import { EdgeType } from './diagram-types'; | ||||||||||||||||||||||||
| import * as SvgUtils from './svg-utils'; | ||||||||||||||||||||||||
| import { LibraryComponent } from './library-component'; | ||||||||||||||||||||||||
| import DefaultLibraryComponents from '../resources/default-library/components.json'; | ||||||||||||||||||||||||
| import * as ComponentUtils from './component-utils'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export class SvgWriter { | ||||||||||||||||||||||||
| static readonly NODES_CLASS = 'nad-vl-nodes'; | ||||||||||||||||||||||||
|
|
@@ -44,20 +47,54 @@ export class SvgWriter { | |||||||||||||||||||||||
| 2: 'TWO', | ||||||||||||||||||||||||
| 3: 'THREE', | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| componentLibrary: LibraryComponent[] = DefaultLibraryComponents; | ||||||||||||||||||||||||
| urlResolver: ((fileName: string) => string) | undefined = undefined; | ||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
add
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The getComponentPath method in component-utils.ts should change to: export async function getComponentPath(
componentFilename: string,
svgUrlResolver?: (fileName: string) => string,
signal?: AbortSignal
): Promise<SVGPathElement> {
const url = svgUrlResolver ? svgUrlResolver(componentFilename) : DefaultComponentSvgMapping[componentFilename];
if (!url) throw new Error(`Unknown component file: ${componentFilename}`);
const response = await fetch(url, { signal });
const svgContent = await response.text();
const path = SVG().svg(svgContent).node.firstElementChild?.firstElementChild;
if (!path) throw new Error(`No path found in component SVG: ${componentFilename}`);
return path as SVGPathElement;
}
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I understood, the |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| constructor(diagramMetadata: DiagramMetadata) { | ||||||||||||||||||||||||
| constructor( | ||||||||||||||||||||||||
| diagramMetadata: DiagramMetadata, | ||||||||||||||||||||||||
| componentLibrary?: LibraryComponent[], | ||||||||||||||||||||||||
| urlResolver?: (fileName: string) => string | ||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||
| this.diagramMetadata = diagramMetadata; | ||||||||||||||||||||||||
| this.svgParameters = new SvgParameters(this.diagramMetadata.svgParameters); | ||||||||||||||||||||||||
| if (componentLibrary) { | ||||||||||||||||||||||||
| this.componentLibrary = componentLibrary; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| if (urlResolver) { | ||||||||||||||||||||||||
| this.urlResolver = urlResolver; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| // get edge router, for computing edges points | ||||||||||||||||||||||||
| this.edgeRouter = new EdgeRouter(this.diagramMetadata); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| public getSvg(textBoxSize?: { width: number; height: number }): string { | ||||||||||||||||||||||||
| // get edge router, for computing edges points | ||||||||||||||||||||||||
| this.edgeRouter = new EdgeRouter(this.diagramMetadata); | ||||||||||||||||||||||||
| const baseSvg = this.createBaseSvg(textBoxSize); | ||||||||||||||||||||||||
| this.addSvgContent(baseSvg.svg); | ||||||||||||||||||||||||
| return new XMLSerializer().serializeToString(baseSvg.xmlDoc); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| public getEmptySvg(): string { | ||||||||||||||||||||||||
| const vb = MetadataUtils.getViewBox( | ||||||||||||||||||||||||
| this.diagramMetadata.nodes, | ||||||||||||||||||||||||
| this.diagramMetadata.textNodes, | ||||||||||||||||||||||||
| this.svgParameters | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${vb.x} ${vb.y} ${vb.width} ${vb.height}"></svg>`; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private createBaseSvg(textBoxSize?: { width: number; height: number }): { | ||||||||||||||||||||||||
| xmlDoc: XMLDocument; | ||||||||||||||||||||||||
| svg: SVGSVGElement; | ||||||||||||||||||||||||
| } { | ||||||||||||||||||||||||
| // create XML doc | ||||||||||||||||||||||||
| const xmlDoc = this.getXmlDoc(); | ||||||||||||||||||||||||
| // add SVG root element | ||||||||||||||||||||||||
| const svg = this.getSvgRootElement(textBoxSize); | ||||||||||||||||||||||||
| xmlDoc.appendChild(svg); | ||||||||||||||||||||||||
| return { xmlDoc, svg }; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| public addSvgContent(svg: SVGSVGElement) { | ||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
reset the arrays to not duplicate 3WT nodes |
||||||||||||||||||||||||
| // add nodes | ||||||||||||||||||||||||
| svg.appendChild(this.getNodes()); | ||||||||||||||||||||||||
| // add edges and infos | ||||||||||||||||||||||||
|
|
@@ -76,7 +113,6 @@ export class SvgWriter { | |||||||||||||||||||||||
| const textNodeAndEdges = this.getTextNodesAndEdges(); | ||||||||||||||||||||||||
| svg.appendChild(textNodeAndEdges.textEdges); | ||||||||||||||||||||||||
| svg.appendChild(textNodeAndEdges.textNodes); | ||||||||||||||||||||||||
| return new XMLSerializer().serializeToString(xmlDoc); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private getXmlDoc(): XMLDocument { | ||||||||||||||||||||||||
|
|
@@ -469,8 +505,12 @@ export class SvgWriter { | |||||||||||||||||||||||
| if (infoPoint) { | ||||||||||||||||||||||||
| gEdgeInfoElement.setAttribute('transform', 'translate(' + DiagramUtils.getFormattedPoint(infoPoint) + ')'); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| // add arrows | ||||||||||||||||||||||||
| this.addEdgeInfoArrows(gEdgeInfoElement, info, this.edgeRouter?.getEdgeSideInfoAngle(edge.svgId, side)); | ||||||||||||||||||||||||
| if (info.componentType) { | ||||||||||||||||||||||||
| gEdgeInfoElement.appendChild(this.getEdgeInfoComponent(info.componentType)); | ||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||
| // add arrows | ||||||||||||||||||||||||
| this.addEdgeInfoArrows(gEdgeInfoElement, info, this.edgeRouter?.getEdgeSideInfoAngle(edge.svgId, side)); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| // add labels | ||||||||||||||||||||||||
| const labelData = this.edgeRouter?.getEdgeSideLabelData(edge.svgId, side); | ||||||||||||||||||||||||
| if (labelData === undefined) return gEdgeInfoElement; | ||||||||||||||||||||||||
|
|
@@ -503,6 +543,22 @@ export class SvgWriter { | |||||||||||||||||||||||
| return gEdgeInfoElement; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private getEdgeInfoComponent(componentType: string): SVGGElement { | ||||||||||||||||||||||||
| const component = ComponentUtils.getComponent(this.componentLibrary, componentType); | ||||||||||||||||||||||||
| const edgeInfoComponent = document.createElementNS('http://www.w3.org/2000/svg', 'g'); | ||||||||||||||||||||||||
| if (component) { | ||||||||||||||||||||||||
| const trans = new Point(-component.size.width / 2, -component.size.height / 2); | ||||||||||||||||||||||||
| edgeInfoComponent.setAttribute('transform', 'translate(' + DiagramUtils.getFormattedPoint(trans) + ')'); | ||||||||||||||||||||||||
| edgeInfoComponent.classList.add(component.styleClass); | ||||||||||||||||||||||||
| component.subComponents.forEach((subComponent) => { | ||||||||||||||||||||||||
| void ComponentUtils.getComponentPath(subComponent.fileName, this.urlResolver).then((path) => { | ||||||||||||||||||||||||
| edgeInfoComponent.appendChild(path); | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
|
Comment on lines
+554
to
+556
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
AbortError is silently ignored while other errors log to console |
||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| return edgeInfoComponent; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private addEdgeInfoArrows( | ||||||||||||||||||||||||
| gEdgeInfoElement: SVGGElement, | ||||||||||||||||||||||||
| info: EdgeInfoMetadata, | ||||||||||||||||||||||||
|
|
@@ -584,8 +640,12 @@ export class SvgWriter { | |||||||||||||||||||||||
| 'translate(' + DiagramUtils.getFormattedPoint(middleInfoPoint) + ')' | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| // add arrows | ||||||||||||||||||||||||
| this.addEdgeInfoArrows(gEdgeMiddleInfoElement, info, this.edgeRouter?.getEdgeMiddleInfoAngle(edge.svgId)); | ||||||||||||||||||||||||
| if (info.componentType) { | ||||||||||||||||||||||||
| gEdgeMiddleInfoElement.appendChild(this.getEdgeInfoComponent(info.componentType)); | ||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||
| // add arrows | ||||||||||||||||||||||||
| this.addEdgeInfoArrows(gEdgeMiddleInfoElement, info, this.edgeRouter?.getEdgeMiddleInfoAngle(edge.svgId)); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| // add labels | ||||||||||||||||||||||||
| let x = 0; | ||||||||||||||||||||||||
| let style: string | undefined = 'text-anchor:middle'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.