@@ -1436,7 +1436,19 @@ export function useOntologyGraph({
14361436
14371437 if ( canPatchInPlace ) {
14381438 try {
1439- graph . updateNodeData ( graphData . nodes ?? [ ] ) ;
1439+ let nodesToUpdate = graphData . nodes ?? [ ] ;
1440+ if ( isDataMode ) {
1441+ nodesToUpdate = nodesToUpdate . map ( ( node ) => {
1442+ const style = node . style as Record < string , unknown > | undefined ;
1443+ if ( ! style || ( ! ( 'x' in style ) && ! ( 'y' in style ) ) ) {
1444+ return node ;
1445+ }
1446+ const { x : _x , y : _y , ...restStyle } = style ;
1447+
1448+ return { ...node , style : restStyle } ;
1449+ } ) ;
1450+ }
1451+ graph . updateNodeData ( nodesToUpdate ) ;
14401452 graph . updateEdgeData ( graphData . edges ?? [ ] ) ;
14411453 graph . draw ( ) ;
14421454
@@ -1612,7 +1624,19 @@ export function useOntologyGraph({
16121624 if ( assetFingerprintChanged && ! termFingerprintChanged && topologySynced ) {
16131625 assetFingerprintRef . current = newAssetFingerprint ;
16141626 try {
1615- graph . updateNodeData ( graphData . nodes ?? [ ] ) ;
1627+ let nodesToUpdate = graphData . nodes ?? [ ] ;
1628+ if ( isDataMode ) {
1629+ nodesToUpdate = nodesToUpdate . map ( ( node ) => {
1630+ const style = node . style as Record < string , unknown > | undefined ;
1631+ if ( ! style || ( ! ( 'x' in style ) && ! ( 'y' in style ) ) ) {
1632+ return node ;
1633+ }
1634+ const { x : _x , y : _y , ...restStyle } = style ;
1635+
1636+ return { ...node , style : restStyle } ;
1637+ } ) ;
1638+ }
1639+ graph . updateNodeData ( nodesToUpdate ) ;
16161640 graph . updateEdgeData ( graphData . edges ?? [ ] ) ;
16171641 graph . draw ( ) ;
16181642 } catch {
@@ -1657,6 +1681,25 @@ export function useOntologyGraph({
16571681
16581682 setClickedEdgeIdRef . current ( null ) ;
16591683
1684+ const preUpdateTermPositions : Record < string , [ number , number ] > = { } ;
1685+ if ( isDataMode && ! termFingerprintChanged ) {
1686+ const termIds = new Set (
1687+ inputNodesRef . current
1688+ . filter ( ( n ) => n . type !== 'dataAsset' && n . type !== 'metric' )
1689+ . map ( ( n ) => n . id )
1690+ ) ;
1691+ termIds . forEach ( ( id ) => {
1692+ try {
1693+ const pos = graph . getElementPosition ( id ) ;
1694+ if ( pos ) {
1695+ preUpdateTermPositions [ id ] = [ pos [ 0 ] , pos [ 1 ] ] ;
1696+ }
1697+ } catch {
1698+ // not yet positioned
1699+ }
1700+ } ) ;
1701+ }
1702+
16601703 graph . setData ( graphData ) ;
16611704
16621705 if (
@@ -1667,7 +1710,34 @@ export function useOntologyGraph({
16671710 } else if ( isModelViewLocal && layoutType === LayoutEngine . Circular ) {
16681711 positionCircularNodes ( graph ) ;
16691712 } else if ( hasBakedPositions ) {
1670- applyBakedPositions ( graph , graphData . nodes ?? [ ] ) ;
1713+ if (
1714+ isDataMode &&
1715+ ! termFingerprintChanged &&
1716+ Object . keys ( preUpdateTermPositions ) . length > 0
1717+ ) {
1718+ const updates = ( graphData . nodes ?? [ ] )
1719+ . map ( ( node ) => {
1720+ const snapshotPos = preUpdateTermPositions [ String ( node . id ) ] ;
1721+ if ( ! snapshotPos ) {
1722+ return null ;
1723+ }
1724+
1725+ return {
1726+ id : node . id ,
1727+ style : {
1728+ ...( ( node . style as Record < string , unknown > ) ?? { } ) ,
1729+ x : snapshotPos [ 0 ] ,
1730+ y : snapshotPos [ 1 ] ,
1731+ } ,
1732+ } ;
1733+ } )
1734+ . filter ( ( u ) : u is NonNullable < typeof u > => u !== null ) ;
1735+ if ( updates . length > 0 ) {
1736+ graph . updateNodeData ( updates ) ;
1737+ }
1738+ } else {
1739+ applyBakedPositions ( graph , graphData . nodes ?? [ ] ) ;
1740+ }
16711741 } else {
16721742 graph . setLayout ( layoutOptions ) ;
16731743 try {
0 commit comments