From d258b8ea66230003b03380fd46e28fc6dae08f61 Mon Sep 17 00:00:00 2001 From: Doug Martin Date: Mon, 8 Apr 2024 14:07:57 -0400 Subject: [PATCH] Added translation of the top/left origin to the center on old file loads --- src/components/app.tsx | 41 +++++++++++++++++++++++++++++++++++--- src/components/dataset.tsx | 1 + src/components/drawing.tsx | 4 ++++ src/hooks/use-codap.ts | 7 ++++--- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/components/app.tsx b/src/components/app.tsx index 14cc921..f97195a 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -94,9 +94,37 @@ export const App = () => { updateGraph(values); setFitViewAt(Date.now()); }; - const onSetGraph = (data: GraphData) => { - setGraph(data); - setFitViewAt(Date.now()); + const widthRef = useRef(0); + const heightRef = useRef(0); + const onSetGraph = (data: GraphData, version: number) => { + + const done = () => { + setGraph(data); + setFitViewAt(Date.now()); + }; + + const translateOrigin = () => { + if (!widthRef.current || !heightRef.current) { + setTimeout(translateOrigin, 1); + } else { + // the original data was stored with the origin at the top left + // but now data is stored with the origin in the center + // so we need to translate the points on load to the center + const xOffset = -widthRef.current / 2; + const yOffset = -heightRef.current / 2; + data.nodes.forEach(n => { + n.x = (n.x ?? 0) + xOffset; + n.y = (n.y ?? 0) + yOffset; + }); + done(); + } + }; + + if (version < 2) { + translateOrigin(); + } else { + done(); + } }; const { dragging, outputToDataset, viewMode, setViewMode, notifyStateIsDirty, loadState } = useCODAP({ onCODAPDataChanged, @@ -109,6 +137,11 @@ export const App = () => { const [fastSimulation, setFastSimulation] = useState(false); const fastSimulationRef = useRef(false); + const handleDimensionChange = ({width, height}: {width: number, height: number}) => { + widthRef.current = width; + heightRef.current = height; + }; + const animating = useMemo(() => { return generationMode !== "ready"; }, [generationMode]); @@ -501,6 +534,7 @@ export const App = () => { onRecenterView={handleRecenterView} fitViewAt={fitViewAt} recenterViewAt={recenterViewAt} + onDimensions={handleDimensionChange} /> : { onRecenterView={handleRecenterView} fitViewAt={fitViewAt} recenterViewAt={recenterViewAt} + onDimensions={handleDimensionChange} /> } diff --git a/src/components/dataset.tsx b/src/components/dataset.tsx index d54810e..80f8769 100644 --- a/src/components/dataset.tsx +++ b/src/components/dataset.tsx @@ -21,6 +21,7 @@ interface Props { onReturnToMainMenu: () => void; onFitView: () => void; onRecenterView: () => void; + onDimensions?: (dimensions: {width: number, height: number}) => void; } export const Dataset = (props: Props) => { diff --git a/src/components/drawing.tsx b/src/components/drawing.tsx index da75a8a..19c4a66 100644 --- a/src/components/drawing.tsx +++ b/src/components/drawing.tsx @@ -30,6 +30,7 @@ interface Props { onReturnToMainMenu: () => void; onFitView: () => void; onRecenterView: () => void; + onDimensions?: (dimensions: {width: number, height: number}) => void; } export const Drawing = (props: Props) => { @@ -54,6 +55,9 @@ export const Drawing = (props: Props) => { const handleDimensionChange = ({width, height}: {width: number, height: number}) => { widthRef.current = width; heightRef.current = height; + + // also tell the app so that it can translate the origin of any loaded data if needed + props.onDimensions?.({width, height}); }; const handleTransformed = (transform: Transform) => { diff --git a/src/hooks/use-codap.ts b/src/hooks/use-codap.ts index 00c6781..fbceed9 100644 --- a/src/hooks/use-codap.ts +++ b/src/hooks/use-codap.ts @@ -33,7 +33,7 @@ export type OutputTextMode = "replace"|"append"; export type UseCODAPOptions = { onCODAPDataChanged: OnCODAPDataChanged; getGraph: GetGraphCallback; - setGraph: (data: GraphData) => void; + setGraph: (data: GraphData, version: number) => void; setInitialGraph: React.Dispatch> }; @@ -58,6 +58,7 @@ export const useCODAP = ({onCODAPDataChanged, getGraph, setGraph, setInitialGrap const {nodes, edges} = getGraph(); state.values.nodes = nodes; state.values.edges = edges; + state.values.version = 2; // there was no version 1 but set graph returns 1 if there is no version } return state; @@ -87,9 +88,9 @@ export const useCODAP = ({onCODAPDataChanged, getGraph, setGraph, setInitialGrap setViewMode(values.viewMode); if (values.viewMode === "drawing") { - const {nodes, edges} = values; + const {nodes, edges, version} = values; if (nodes !== undefined && edges !== undefined) { - setGraph({nodes, edges}); + setGraph({nodes, edges}, version ?? 1); // save a copy of the graph setInitialGraph({nodes: nodes.map((n: Node) => ({...n})), edges: edges.map((e: Edge) => ({...e}))}); }