How can you load diagrams with SfDiagramComponent LoadDiagram?

Hi,

I am running Blazor WebAssembly and I am trying to load diagrams from a drop down list of previously saved diagrams. However, I cannot seem to replace the current diagram just using loadDiagram. What am I missing?


// Diagram
publicSfDiagramComponent diagram;
// Diagram nodes collection
publicDiagramObjectCollection nodes =newDiagramObjectCollection();
// Diagram connectors collection
publicDiagramObjectCollection connectors =newDiagramObjectCollection();
//Palette
publicSfSymbolPaletteComponent symbolpalette;
//Define palattes collection
publicDiagramObjectCollectionPalettes=newDiagramObjectCollection();
// Defines palette's flow-shape collection
publicDiagramObjectCollectionPaletteNodes=newDiagramObjectCollection();
// Defines palette's group collection
publicDiagramObjectCollectionPaletteGroup=newDiagramObjectCollection();
// Defines palette's connector collection
publicDiagramObjectCollectionPaletteConnectors=newDiagramObjectCollection();


publicSymbolMarginSymbolMargin=newSymbolMargin{Left=15,Right=15,Top=15,Bottom=15};


protectedoverrideasyncTaskOnAfterRenderAsync(bool firstRender)
{
symbolpalette.DiagramInstances=newDiagramObjectCollection(){};
symbolpalette.DiagramInstances.Add(diagram);
}


protectedvoidInitPaletteModel()
{
CreatePaletteNode(FlowShapes.Terminator,"Terminator");
CreatePaletteConnector("Link1",Segments.Orthogonal,DecoratorShapes.Arrow);
CreatePaletteGroup();
Palettes=newDiagramObjectCollection()
{
newPalette(){Symbols=PaletteNodes,Title="Flow Shapes",Id="Flow Shapes"},
newPalette(){Symbols=PaletteConnectors,Title="Connectors",Expanded=true},
newPalette(){Symbols=PaletteGroup,Title="Group Shapes",Expanded=true}
};
}


protectedvoidCreatePaletteNode(FlowShapes flowShape,string id)
{
Node node =newNode()
{
ID = id,
Shape=newFlowShape(){Type=Shapes.Flow,Shape= flowShape },
Style=newShapeStyle(){Fill="#6495ED",StrokeColor="#6495ED"},
};
PaletteNodes.Add(node);
}


protectedvoidCreatePaletteConnector(string id,Segments type,DecoratorShapes decoratorShape)
{
Connector connector =newConnector()
{
ID = id,
Type= type,
SourcePoint=newSyncfusion.Blazor.Diagram.Point(){ X =0, Y =0},
TargetPoint=newSyncfusion.Blazor.Diagram.Point(){ X =60, Y =60},
Style=newShapeStyle(){StrokeWidth=1,StrokeColor="#757575"},
TargetDecorator=newDecorator()
{
Shape= decoratorShape,
Style=newShapeStyle(){StrokeColor="#757575",Fill="#757575"}
}
};
PaletteConnectors.Add(connector);
}


protectedvoidCreatePaletteGroup()
{
Node node1 =newNode()
{
ID ="node1",
Width=50,
Height=50,
OffsetX=100,
OffsetY=100,
Shape=newBasicShape(){Type=Shapes.Basic,Shape=BasicShapes.Rectangle},
Style=newShapeStyle(){Fill="#6495ed"},
};
Node node2 =newNode()
{
ID ="node2",
Width=50,
Height=50,
OffsetX=100,
OffsetY=200,
Shape=newBasicShape(){Type=Shapes.Basic,Shape=BasicShapes.Ellipse},
Style=newShapeStyle(){Fill="#6495ed"},
};
PaletteGroup.Add(node1);
PaletteGroup.Add(node2);
Syncfusion.Blazor.Diagram.Groupgroup=newSyncfusion.Blazor.Diagram.Group()
{
ID ="group1",
Children=newstring[]{"node1","node2"}
};
PaletteGroup.Add(group);
}


// Save the diagram
publicasyncvoidSaveDiagram()
{
varMyDiagram=newStDiagram()
{
tenant_id =TenantId,
id =DiagramId,
diagram_name =DiagramName,
diagram_json = diagram.SaveDiagram()
};
if(DiagramId=="")
{
MyDiagram.id = idGen();
awaitSchools01Db.CreateStDiagram(MyDiagram);
}
else
{
awaitSchools01Db.UpdateStDiagram(TenantId,DiagramId,MyDiagram);
}


}


// Load the diagram
publicasyncTaskLoadDiagram(string diagramId ="")
{
if(diagramId !="")
{
symbolpalette.DiagramInstances.Clear();
var mydiagram=DiagramList.Where(i => i.id.Equals(diagramId)).SingleOrDefault();
await diagram.LoadDiagram(mydiagram.diagram_json);
DiagramName= mydiagram.diagram_name;
symbolpalette.DiagramInstances.Add(diagram);
}
}

Update: I changed the code to just use a string but still have an issue where the saved diagram is loaded into the diagram component but the display is not updated.

        // Save the diagram
public async void SaveDiagram()
{
SavedDiagram = diagram.SaveDiagram();
}


// Load the diagram
public async Task LoadDiagram(string diagramId = "")
{
await diagram.LoadDiagram(SavedDiagram);
}

More investigations seem to show that the Width (Get) always returns null even though width is 145. Also connectors with labels do not work. In short, I cannot successfully use save/load diagram or any process that serializes/deserializes the diagram. 

Copying the node and connector collections to lists then later refreshing the visible collections from the saved lists works fine. I assume that I am doing something grossly wrong or there are fundamental issues with the diagram save/load in Blazor WebAssembly. Any assistance is greatly appreciated. I am looking for sample code that shows how to save a diagram to the database and load from the database with all objects being immediately visible in Blazor WebAssembly. 


11 Replies

GG Gowtham Gunashekar Syncfusion Team September 7, 2021 03:20 AM UTC

 
Hi Simon, 
 
We will check and update the further details in one business day (September  8, 2021). We appreciate your patience until then.  
   
Regards, 
Gowtham 



AM Arunkumar Manoharan Syncfusion Team September 7, 2021 12:07 PM UTC

Hi Simon, 
 
On further analysis of the shared code, we created a sample on Save and Load and checked it by having a drop-down list.  By selecting any one from the list the diagram is loaded by loadDiagram().by doing this we couldn’t be able to replicate or find the error. So please share the video or replicate the issue in the attached sample along with replication steps, that will help us to serve you better. 
 
Sample link:  
  
Regards, 
Arun. 



SI Simon replied to Gowtham Gunashekar September 7, 2021 12:07 PM UTC

Thank you.



SI Simon replied to Arunkumar Manoharan September 8, 2021 12:02 AM UTC

 I am using SaveDiagram to create the string to load which does not create escape characters or formatting

Here is my c# code:


public partial class TestComponent
{
public SfDiagramComponent diagram;
//public int connectorCount = 0;
public DiagramObjectCollection nodes = new DiagramObjectCollection();
//public DiagramObjectCollection connectors = new DiagramObjectCollection();
public List savedNodes = new List();
//public List savedConnectors = new List();
public string nodesJson;


protected override void OnInitialized()
{
InitDiagramModel();
}


private void InitDiagramModel()
{
CreateNode("Start", 300, 50, FlowShapes.Terminator, "Start");
CreateNode("Init", 300, 140, FlowShapes.Process, "var i = 0");
CreateNode("Condition", 300, 230, FlowShapes.Decision, "i < 10?");
CreateNode("Print", 300, 320, FlowShapes.PreDefinedProcess, "print(\'Hello!!\');");
CreateNode("Increment", 300, 410, FlowShapes.Process, "i++;");
CreateNode("End", 300, 500, FlowShapes.Terminator, "End");
}


private void CreateNode(string id, double x, double y, FlowShapes shape, string label)
{
Node diagramNode = new Node()
{
ID = id,
OffsetX = x,
OffsetY = y,
Width = 145,
Height = 60,
Style = new ShapeStyle { Fill = "#357BD2", StrokeColor = "White" },
Shape = new FlowShape() { Type = Shapes.Flow, Shape = shape },
Annotations = new DiagramObjectCollection
{
new ShapeAnnotation
{
Content = label,
Style = new TextShapeStyle()
{
Color="White",
Fill = "transparent"
}
}
}
};
nodes.Add(diagramNode);
}
public string SavedDiagram;
// Save the diagram
public void SaveDiagram()
{
SavedDiagram = diagram.SaveDiagram();
savedNodes = new List(nodes.Select(i => (Node)i.Clone()).ToList());
}


// Load the diagram
public async Task DiagramLoad(string diagramId = "")
{
nodes.Clear();
nodes = new DiagramObjectCollection(savedNodes.Select(i => (Node)i.Clone()));
}
public async Task DiagramLoadJson(string diagramId = "")
{
await diagram.LoadDiagram(SavedDiagram);
}
}


And the html snippet:




The DiagramLoad method succeeds in recreating the nodes from a list in memory but the DiagramLoadJson method fails to produce any results in trying to recreate from a Json string created by saveDiagram.

Can you get this to work in Blazor webassembly?



AM Arunkumar Manoharan Syncfusion Team September 8, 2021 12:59 PM UTC

Hi Simon,  
 
Reported Issue: Save and Load the SfDiagramComponent. 
We can reproduce the issue and confirmed this as a defect. We have logged a defect report for this issue. We will fix this issue and provide the patch on 28th September ,2021 weekly patch release.  
 
 
Regards,   
Arun. 



SI Simon replied to Arunkumar Manoharan September 8, 2021 02:51 PM UTC

Meanwhile, is there a work around please? I need to get this project delivered in 2 weeks.



AM Arunkumar Manoharan Syncfusion Team September 9, 2021 11:59 AM UTC

Hi Simon,  
 
On further analysis, the JSON generated from our side in sfdiagramcomponent is fine which is different as compared with your JSON data and we can able to load the JSON by diagram.load(). We suspect that the JSON generated from your end machine has some issues. And, we have attached the JSON file which has been created from our side. 
 
 
Regards,   
Arun. 



SI Simon replied to Arunkumar Manoharan September 9, 2021 07:20 PM UTC

Sorry, I do not understand why my json generated would be different.

I am using SaveDiagram(), should I be doing something else?



SI Simon replied to Arunkumar Manoharan September 10, 2021 03:05 AM UTC

Hi,

I tried using your json string but only a connector gets generated. After many attempts, I still cannot get savediagram to a string with a subsequent loaddiagram to work. Any other ides that can help will be much appreciated.



SI Simon replied to Simon September 10, 2021 12:43 PM UTC

I have a work around but it's not a one liner. Here it is for nodes only:

        // Save the diagram
public void SaveDiagram()
{
nodesJson = new string(JsonSerializer.Serialize(savedNodes.Select(i => (Node)i.Clone())));
}


// Load the diagram
public async Task DiagramLoadJson(string diagramId = "")
{
nodes.Clear();
nodes = new DiagramObjectCollection(JsonSerializer.Deserialize>(nodesJson));
foreach (Node vnode in nodes)
{
var origAnnotation = new DiagramObjectCollection(vnode.Annotations.Select(i => (ShapeAnnotation)i.Clone()));
vnode.Annotations.Clear();
vnode.Annotations = new DiagramObjectCollection(origAnnotation);
}
}





GG Gowtham Gunashekar Syncfusion Team September 13, 2021 06:25 AM UTC

 
Hi Simon, 
 
On the further analysis of the shared detail, we suspect that you have not used the two way bind in nodes and connector collection that leads to the reported issue. In your shared code snippets, we could not find the tag level code which you have used. We suggest you use the following code for the nodes and connectors collection to make it two-way binding, then only the saved diagram will load properly. 
 
Code snippet: 
<SfDiagramComponent @ref="diagram" Width="600px" Height="500px" @bind-Nodes="NodeCollection" @bind-Connectors="ConnectorCollection"> 
</SfDiagramComponent> 
 
 
We have added the following sample for your reference. 
 
 
 
 
If still the reported issue persists, please confirm your availability tomorrow (14th September 2021) at 3.00 PM IST so that we can schedule a meeting and send you the invite accordingly.     
 
Regards, 
Gowtham 


Loader.
Up arrow icon