@@ -1021,6 +1021,335 @@ The following sample code demonstrates how to bind data to the Diagram component
10211021```
10221022You can download a complete working sample from [GitHub ](https :// github.com/SyncfusionExamples/Blazor-Diagram-Examples/tree/master/UG-Samples/DataBinding/RemoteData/URLAdaptor)
10231023
1024+ ### How to bind custom data
1025+ The custom data binding can be performed in the diagram component by providing the custom adaptor class and overriding the Read or ReadAsync method of the DataAdaptor abstract class .
1026+
1027+ The following sample code demonstrates implementing custom data binding using custom adaptor ,
1028+
1029+ ```cshtml
1030+ @using Syncfusion .Blazor
1031+ @using Syncfusion .Blazor .Diagram
1032+ @using Syncfusion .Blazor .Data
1033+
1034+ < div class = " row" id = " diagram" >
1035+ < div class = " col-md-10" >
1036+ < div id = " diagram-space" class = " content-wrapper" >
1037+ < SfDiagramComponent ID = " diagramControl" @ref = " @diagram" Width = " 100%" Height = " 690px" ConnectorCreating = " @ConnectorCreating" NodeCreating = " @NodeCreating" >
1038+ < DataSourceSettings ID = " EmployeeID" ParentID = " ReportsTo" >
1039+ < SfDataManager AdaptorInstance = " @typeof(CustomAdaptor)" Adaptor = " Adaptors.CustomAdaptor" >< / SfDataManager >
1040+ < / DataSourceSettings >
1041+ < Layout Type = " Syncfusion.Blazor.Diagram.LayoutType.HierarchicalTree" VerticalSpacing = " 75" HorizontalSpacing = " 75" >< / Layout >
1042+ < / SfDiagramComponent >
1043+ < / div >
1044+ < / div >
1045+ < / div >
1046+ @functions {
1047+ SfDiagramComponent ? diagram ;
1048+ public static List < EmployeeDetails > employeeDetails { get ; set ; }
1049+ Layout LayoutValue = new Layout () { };
1050+ private TreeInfo GetLayoutInfo (IDiagramObject obj , TreeInfo options )
1051+ {
1052+ options .EnableSubTree = true ;
1053+ options .Orientation = Orientation .Horizontal ;
1054+ return options ;
1055+ }
1056+ private void NodeCreating (IDiagramObject obj )
1057+ {
1058+ Node ? node = obj as Node ;
1059+ node ! .Style = new ShapeStyle () { Fill = " #659be5" , StrokeColor = " none" , StrokeWidth = 2 , };
1060+ node .BackgroundColor = " #659be5" ;
1061+ node .Width = 200 ;
1062+ node .Height = 100 ;
1063+ EmployeeDetails data = node .Data as EmployeeDetails ;
1064+ if (data != null )
1065+ {
1066+ // node.ID = data.FirstName + data.EmployeeID;
1067+ node .Annotations = new DiagramObjectCollection <ShapeAnnotation >()
1068+ {
1069+ new ShapeAnnotation ()
1070+ {
1071+ ID = data .FirstName ,
1072+ Content = $" Name:{data .FirstName }\n ReportsTo:{data .ReportsTo }\n Designation:{data .Designation }\n Country:{data .Country }" ,
1073+ Style = new TextStyle (){FontSize = 15 , Color = " white" }
1074+ }
1075+ };
1076+ node .Style = new ShapeStyle () { Fill = data .Color , StrokeColor = " none" , StrokeWidth = 2 , };
1077+ }
1078+ }
1079+ private void ConnectorCreating (IDiagramObject connector )
1080+ {
1081+ Connector ? newConnector = connector as Connector ;
1082+ newConnector ! .TargetDecorator = new DecoratorSettings () { Shape = DecoratorShape .None };
1083+ newConnector .Type = ConnectorSegmentType .Orthogonal ;
1084+ newConnector .Style = new ShapeStyle () { StrokeColor = " #6d6d6d" };
1085+ newConnector .Constraints = ConnectorConstraints .None ;
1086+ newConnector .CornerRadius = 5 ;
1087+ }
1088+
1089+
1090+ public class EmployeeDetails
1091+ {
1092+ public string EmployeeID { get ; set ; }
1093+
1094+ public string ReportsTo { get ; set ; }
1095+
1096+ public string FirstName { get ; set ; }
1097+
1098+ public string Designation { get ; set ; }
1099+
1100+ public string Country { get ; set ; }
1101+
1102+ public string Color { get ; set ; }
1103+ }
1104+
1105+
1106+ // Implementing custom adaptor by extending the DataAdaptor class
1107+ public class CustomAdaptor : DataAdaptor
1108+ {
1109+ // Performs data Read operation
1110+ public override object Read (DataManagerRequest dm , string key = null )
1111+ {
1112+ IEnumerable < EmployeeDetails > DataSource = employeeDetails ;
1113+ if (dm .Search != null && dm .Search .Count > 0 )
1114+ {
1115+ // Searching
1116+ DataSource = DataOperations .PerformSearching (DataSource , dm .Search );
1117+ }
1118+ if (dm .Sorted != null && dm .Sorted .Count > 0 )
1119+ {
1120+ // Sorting
1121+ DataSource = DataOperations .PerformSorting (DataSource , dm .Sorted );
1122+ }
1123+ if (dm .Where != null && dm .Where .Count > 0 )
1124+ {
1125+ // Filtering
1126+ DataSource = DataOperations .PerformFiltering (DataSource , dm .Where , dm .Where [0 ].Operator );
1127+ }
1128+ int count = DataSource .Cast <EmployeeDetails >().Count ();
1129+ if (dm .Skip != 0 )
1130+ {
1131+ // Paging
1132+ DataSource = DataOperations .PerformSkip (DataSource , dm .Skip );
1133+ }
1134+ if (dm .Take != 0 )
1135+ {
1136+ DataSource = DataOperations .PerformTake (DataSource , dm .Take );
1137+ }
1138+ return dm .RequiresCounts ? new DataResult () { Result = DataSource , Count = count } : (object )DataSource ;
1139+ }
1140+ }
1141+ }
1142+ ```
1143+
1144+ ### CRUD operation
1145+
1146+ The CRUD operations for the custom bounded data in the diagram component can be implemented by overriding the following CRUD methods of the ** DataAdaptor ** abstract class ,
1147+
1148+ * ** Insert / InsertAsync **
1149+ * ** Remove / RemoveAsync **
1150+ * ** Update / UpdateAsync **
1151+ * ** Read / ReadAsync **
1152+
1153+ The following sample code demonstrates implementing CRUD operations for the custom bounded data ,
1154+ ```cshtml
1155+ @using Syncfusion .Blazor
1156+ @using Syncfusion .Blazor .Diagram
1157+ @using Syncfusion .Blazor .Data
1158+
1159+ @* buttons to perform crud support * @
1160+ < div class = " row" style = " margin-bottom:20px" >
1161+ < div class = " col-md-12" >
1162+ < div class = " row" >
1163+ < div class = " col-md-3" >
1164+ < button class = " btn btn-primary" @onclick = " Read" > Read < / button >
1165+ < / div >
1166+ < div class = " col-md-3" >
1167+ < button class = " btn btn-primary" @onclick = " Update" > Update < / button >
1168+ < / div >
1169+ < div class = " col-md-3" >
1170+ < button class = " btn btn-primary" @onclick = " Insert" > Insert < / button >
1171+ < / div >
1172+ < div class = " col-md-3" >
1173+ < button class = " btn btn-primary" @onclick = " Delete" > Delete < / button >
1174+ < / div >
1175+ < / div >
1176+ < / div >
1177+ < / div >
1178+ < div class = " row" id = " diagram" >
1179+ < div class = " col-md-10" >
1180+ < div id = " diagram-space" class = " content-wrapper" >
1181+ < SfDiagramComponent ID = " diagramControl" @ref = " @diagram" Width = " 100%" Height = " 690px" ConnectorCreating = " @ConnectorCreating" NodeCreating = " @NodeCreating" >
1182+ < DataSourceSettings ID = " EmployeeID" ParentID = " ReportsTo" >
1183+ < SfDataManager AdaptorInstance = " @typeof(CustomAdaptor)" Adaptor = " Adaptors.CustomAdaptor" >< / SfDataManager >
1184+ < / DataSourceSettings >
1185+ < Layout Type = " Syncfusion.Blazor.Diagram.LayoutType.HierarchicalTree" VerticalSpacing = " 75" HorizontalSpacing = " 75" >< / Layout >
1186+ < / SfDiagramComponent >
1187+ < / div >
1188+ < / div >
1189+ < / div >
1190+ @functions {
1191+ SfDiagramComponent ? diagram ;
1192+ public static List < EmployeeDetails > employeeDetails { get ; set ; }
1193+ public static List < EmployeeDetails > Details { get ; set ; } = new List <EmployeeDetails >();
1194+
1195+ Layout LayoutValue = new Layout () { };
1196+ private TreeInfo GetLayoutInfo (IDiagramObject obj , TreeInfo options )
1197+ {
1198+ options .EnableSubTree = true ;
1199+ options .Orientation = Orientation .Horizontal ;
1200+ return options ;
1201+ }
1202+ private void NodeCreating (IDiagramObject obj )
1203+ {
1204+ Node ? node = obj as Node ;
1205+ node ! .Style = new ShapeStyle () { Fill = " #659be5" , StrokeColor = " none" , StrokeWidth = 2 , };
1206+ node .BackgroundColor = " #659be5" ;
1207+ node .Width = 200 ;
1208+ node .Height = 100 ;
1209+ EmployeeDetails data = node .Data as EmployeeDetails ;
1210+ if (data != null )
1211+ {
1212+ // node.ID = data.FirstName + data.EmployeeID;
1213+ node .Annotations = new DiagramObjectCollection <ShapeAnnotation >()
1214+ {
1215+ new ShapeAnnotation ()
1216+ {
1217+ ID = data .FirstName ,
1218+ Content = $" Name:{data .FirstName }\n ReportsTo:{data .ReportsTo }\n Designation:{data .Designation }\n Country:{data .Country }" ,
1219+ Style = new TextStyle (){FontSize = 15 , Color = " white" }
1220+ }
1221+ };
1222+ node .Style = new ShapeStyle () { Fill = data .Color , StrokeColor = " none" , StrokeWidth = 2 , };
1223+ }
1224+ }
1225+ private void ConnectorCreating (IDiagramObject connector )
1226+ {
1227+ Connector ? newConnector = connector as Connector ;
1228+ newConnector ! .TargetDecorator = new DecoratorSettings () { Shape = DecoratorShape .None };
1229+ newConnector .Type = ConnectorSegmentType .Orthogonal ;
1230+ newConnector .Style = new ShapeStyle () { StrokeColor = " #6d6d6d" };
1231+ newConnector .Constraints = ConnectorConstraints .None ;
1232+ newConnector .CornerRadius = 5 ;
1233+ }
1234+
1235+
1236+ public class EmployeeDetails
1237+ {
1238+ public string EmployeeID { get ; set ; }
1239+
1240+ public string ReportsTo { get ; set ; }
1241+
1242+ public string FirstName { get ; set ; }
1243+
1244+ public string Designation { get ; set ; }
1245+
1246+ public string Country { get ; set ; }
1247+
1248+ public string Color { get ; set ; }
1249+ }
1250+
1251+
1252+ // Implementing custom adaptor by extending the DataAdaptor class
1253+ public class CustomAdaptor : DataAdaptor
1254+ {
1255+ // Performs data Read operation
1256+ public override object Read (DataManagerRequest dm , string key = null )
1257+ {
1258+ IEnumerable < EmployeeDetails > DataSource = employeeDetails ;
1259+ if (dm .Search != null && dm .Search .Count > 0 )
1260+ {
1261+ // Searching
1262+ DataSource = DataOperations .PerformSearching (DataSource , dm .Search );
1263+ }
1264+ if (dm .Sorted != null && dm .Sorted .Count > 0 )
1265+ {
1266+ // Sorting
1267+ DataSource = DataOperations .PerformSorting (DataSource , dm .Sorted );
1268+ }
1269+ if (dm .Where != null && dm .Where .Count > 0 )
1270+ {
1271+ // Filtering
1272+ DataSource = DataOperations .PerformFiltering (DataSource , dm .Where , dm .Where [0 ].Operator );
1273+ }
1274+ int count = DataSource .Cast <EmployeeDetails >().Count ();
1275+ if (dm .Skip != 0 )
1276+ {
1277+ // Paging
1278+ DataSource = DataOperations .PerformSkip (DataSource , dm .Skip );
1279+ }
1280+ if (dm .Take != 0 )
1281+ {
1282+ DataSource = DataOperations .PerformTake (DataSource , dm .Take );
1283+ }
1284+ return dm .RequiresCounts ? new DataResult () { Result = DataSource , Count = count } : (object )DataSource ;
1285+ }
1286+
1287+ // Performs Insert operation
1288+ public override object Insert (DataManager dm , object value , string key )
1289+ {
1290+ employeeDetails .Insert (employeeDetails .Count , value as EmployeeDetails );
1291+ return value ;
1292+ }
1293+
1294+ // Performs Remove operation
1295+ public override object Remove (DataManager dm , object value , string keyField , string key )
1296+ {
1297+ employeeDetails .Remove (employeeDetails .Where (or => or .EmployeeID == value .ToString ()).FirstOrDefault ());
1298+ return value ;
1299+ }
1300+
1301+ // Performs Update operation
1302+ public override object Update (DataManager dm , object value , string keyField , string key )
1303+ {
1304+ var data = employeeDetails .Where (or => or .EmployeeID == (value as EmployeeDetails ).EmployeeID ).FirstOrDefault ();
1305+ if (data != null )
1306+ {
1307+ data .EmployeeID = (value as EmployeeDetails ).EmployeeID ;
1308+ data .ReportsTo = (value as EmployeeDetails ).ReportsTo ;
1309+ data .FirstName = (value as EmployeeDetails ).FirstName ;
1310+ data .Designation = (value as EmployeeDetails ).Designation ;
1311+ data .Country = (value as EmployeeDetails ).Country ;
1312+ data .Color = (value as EmployeeDetails ).Color ;
1313+ }
1314+ return value ;
1315+ }
1316+ }
1317+
1318+ public void Read ()
1319+ {
1320+ Details = new List <EmployeeDetails >();
1321+ Details = diagram .ReadDataAsync ().Result as List <EmployeeDetails >;
1322+ }
1323+
1324+ public async void Update ()
1325+ {
1326+ EmployeeDetails employeeDetails = new EmployeeDetails { EmployeeID = " 1" , FirstName = " AndrewSimonds" , Designation = " CEO" , Country = " Australia" , ReportsTo = " " , Color = " Red" };
1327+ await diagram .UpdateDataAsync (" EmployeeID" , employeeDetails );
1328+ }
1329+
1330+ public async void Insert ()
1331+ {
1332+ EmployeeDetails employeeDetails = new EmployeeDetails ()
1333+ {
1334+ EmployeeID = " 10" ,
1335+ FirstName = " Alan" ,
1336+ Designation = " HR assistant" ,
1337+ Country = " USA" ,
1338+ ReportsTo = " 6" ,
1339+ Color = " Purple"
1340+ };
1341+ await diagram .InsertDataAsync (employeeDetails );
1342+
1343+ }
1344+
1345+ public async void Delete ()
1346+ {
1347+ await diagram .DeleteDataAsync (" EmployeeID" , " 6" );
1348+ }
1349+ }
1350+ ```
1351+ You can download a complete working sample from [GitHub ](https :// github.com/SyncfusionExamples/Blazor-Diagram-Examples/tree/master/UG-Samples/DataBinding/RemoteData/URLAdaptor)
1352+
10241353### Binding with GraphQL service
10251354GraphQL is a query language for APIs with which you can get exactly what you need and nothing more . The GraphQLAdaptor provides an option to retrieve data from the GraphQL server . For more details on GraphQL service , refer to the [GraphQL documentation ](.. / data / adaptors #graphql - service - binding ).
10261355
@@ -1339,7 +1668,7 @@ Now, you can configure the diagram using the **'SfDataManager'** to interact wit
13391668```
13401669
13411670### CRUD
1342- The SfDiagramComponent supports CRUD (Create , Read , Update , Delete ) operations using SfDataManager for remote data management . By making API calls to update data , the diagram automatically rerenders , ensuring real - time synchronization between the front - end diagram and the backend . This allows users to manage and manipulate diagram data from remote databases or APIs using methods like ReadData , UpdateData , InsertData , and DeleteData .
1671+ The SfDiagramComponent supports CRUD (Create , Read , Update , Delete ) operations using SfDataManager for remote data management . By making API calls to update data , the diagram automatically re - renders , ensuring real - time synchronization between the front - end diagram and the back - end . This allows users to manage and manipulate diagram data from remote databases or APIs using methods like ReadData , UpdateData , InsertData , and DeleteData .
13431672
13441673### Read DataSource
13451674The SfDiagramComponent can fetch and display data from remote sources using the ReadDataAsync method . This method retrieves data from the server that we visualized as nodes and connectors in the diagram . This method is invoked when the user wants to load the raw data from the server.
@@ -1398,6 +1727,7 @@ The DeleteDataAsync method removes data from the remote server. Once the data is
13981727```
13991728
14001729You can find the fully working sample here .
1730+
14011731## See Also
14021732
14031733* [How to arrange the diagram nodes and connectors using varies layout ](./ layout / automatic - layout )
0 commit comments