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
// Diagram connectors collection
publicDiagramObjectCollection
//Palette
publicSfSymbolPaletteComponent symbolpalette;
//Define palattes collection
publicDiagramObjectCollection
// Defines palette's flow-shape collection
publicDiagramObjectCollection
// Defines palette's group collection
publicDiagramObjectCollection
// Defines palette's connector collection
publicDiagramObjectCollection
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.
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 DiagramObjectCollectionnodes = new DiagramObjectCollection ();
//public DiagramObjectCollectionconnectors = new DiagramObjectCollection ();
public ListsavedNodes = new List ();
//public ListsavedConnectors = 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?
Meanwhile, is there a work around please? I need to get this project delivered in 2 weeks.
Sorry, I do not understand why my json generated would be different.
I am using SaveDiagram(), should I be doing something else?
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.
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);
}
}
<SfDiagramComponent @ref="diagram" Width="600px" Height="500px" @bind-Nodes="NodeCollection" @bind-Connectors="ConnectorCollection">
</SfDiagramComponent> |