regenerate ids when needed via programmatic api, this makes sure for mermaid diagrams ids are regenerated

This commit is contained in:
Aakansha Doshi 2023-08-30 20:28:13 +05:30
parent 10a5d18fa2
commit b47d46699a
2 changed files with 31 additions and 4 deletions

View File

@ -140,7 +140,7 @@ const MermaidToExcalidraw = ({
mermaidToExcalidrawLib.current.graphToExcalidraw(mermaidGraphData); mermaidToExcalidrawLib.current.graphToExcalidraw(mermaidGraphData);
data.current = { data.current = {
elements: convertToExcalidrawElements(elements), elements: convertToExcalidrawElements(elements, true),
files, files,
}; };
const parent = canvasNode.parentElement!; const parent = canvasNode.parentElement!;

View File

@ -40,6 +40,7 @@ import {
import { MarkOptional } from "../utility-types"; import { MarkOptional } from "../utility-types";
import { assertNever, getFontString } from "../utils"; import { assertNever, getFontString } from "../utils";
import { getSizeFromPoints } from "../points"; import { getSizeFromPoints } from "../points";
import { nanoid } from "nanoid";
export type ValidLinearElement = { export type ValidLinearElement = {
type: "arrow" | "line"; type: "arrow" | "line";
@ -368,7 +369,7 @@ const bindLinearElementToElement = (
class ElementStore { class ElementStore {
excalidrawElements = new Map<string, ExcalidrawElement>(); excalidrawElements = new Map<string, ExcalidrawElement>();
add = (ele?: ExcalidrawElement) => { add = (ele?: ExcalidrawElement, originalId?: string) => {
if (!ele) { if (!ele) {
return; return;
} }
@ -386,6 +387,7 @@ class ElementStore {
export const convertToExcalidrawElements = ( export const convertToExcalidrawElements = (
elements: ExcalidrawElementSkeleton[] | null, elements: ExcalidrawElementSkeleton[] | null,
regenerateIds = false,
) => { ) => {
if (!elements) { if (!elements) {
return []; return [];
@ -393,10 +395,15 @@ export const convertToExcalidrawElements = (
const elementStore = new ElementStore(); const elementStore = new ElementStore();
const elementsWithIds = new Map<string, ExcalidrawElementSkeleton>(); const elementsWithIds = new Map<string, ExcalidrawElementSkeleton>();
const oldToNewElementIdMap = new Map<string, string>();
// Create individual elements // Create individual elements
for (const element of elements) { for (const element of elements) {
let excalidrawElement: ExcalidrawElement; let excalidrawElement: ExcalidrawElement;
const originalId = element.id;
if (regenerateIds) {
Object.assign(element, { id: nanoid() });
}
switch (element.type) { switch (element.type) {
case "rectangle": case "rectangle":
case "ellipse": case "ellipse":
@ -505,6 +512,9 @@ export const convertToExcalidrawElements = (
} else { } else {
elementStore.add(excalidrawElement); elementStore.add(excalidrawElement);
elementsWithIds.set(excalidrawElement.id, element); elementsWithIds.set(excalidrawElement.id, element);
if (originalId) {
oldToNewElementIdMap.set(originalId, excalidrawElement.id);
}
} }
} }
@ -530,6 +540,14 @@ export const convertToExcalidrawElements = (
element.type === "arrow" ? element?.start : undefined; element.type === "arrow" ? element?.start : undefined;
const originalEnd = const originalEnd =
element.type === "arrow" ? element?.end : undefined; element.type === "arrow" ? element?.end : undefined;
if (originalStart && originalStart.id) {
const newStartId = oldToNewElementIdMap.get(originalStart.id);
Object.assign(originalStart, { id: newStartId });
}
if (originalEnd && originalEnd.id) {
const newEndId = oldToNewElementIdMap.get(originalEnd.id);
Object.assign(originalEnd, { id: newEndId });
}
const { linearElement, startBoundElement, endBoundElement } = const { linearElement, startBoundElement, endBoundElement } =
bindLinearElementToElement( bindLinearElementToElement(
container as ExcalidrawArrowElement, container as ExcalidrawArrowElement,
@ -545,11 +563,20 @@ export const convertToExcalidrawElements = (
} else { } else {
switch (element.type) { switch (element.type) {
case "arrow": { case "arrow": {
const { start, end } = element;
if (start && start.id) {
const newStartId = oldToNewElementIdMap.get(start.id);
Object.assign(start, { id: newStartId });
}
if (end && end.id) {
const newEndId = oldToNewElementIdMap.get(end.id);
Object.assign(end, { id: newEndId });
}
const { linearElement, startBoundElement, endBoundElement } = const { linearElement, startBoundElement, endBoundElement } =
bindLinearElementToElement( bindLinearElementToElement(
excalidrawElement as ExcalidrawArrowElement, excalidrawElement as ExcalidrawArrowElement,
element.start, start,
element.end, end,
elementStore, elementStore,
); );
elementStore.add(linearElement); elementStore.add(linearElement);