@@ -277,6 +277,117 @@ private NodeModel NewNode(double x, double y)
277277 </p >
278278 </div >
279279 </section >
280+ <section id =" custom-groups" class =" doc-section" >
281+ <h2 class =" section-title" >Custom groups</h2 >
282+ <p >
283+ Creating custom groups is almost the same as creating custom nodes, except for some specifics.
284+ </p >
285+ <div id =" create-group-model" class =" section-block" >
286+ <h3 class =" block-title" >Creating a model</h3 >
287+ <p >
288+ First, we'll create a new model for our group.
289+ </p >
290+ <pre ><code class =" language-csharp line-numbers" >public class CustomGroupModel : GroupModel
291+ {
292+ public CustomGroupModel (DiagramManager diagramManager , NodeModel [] children , string title , byte padding = 30 )
293+ : base (diagramManager , children , padding )
294+ {
295+ Title = title ;
296+ }
297+
298+ public string Title { get ; }
299+ } </code ></pre >
300+ <p >
301+ You can add whatever properties you might need. You can also change the value of the padding, which is used when calculating the position/size of the group.
302+ </p >
303+ </div >
304+ <div id =" create-group-component" class =" section-block" >
305+ <h3 class =" block-title" >Creating a component</h3 >
306+ <p >
307+ Second, we'll create a component <code >CustomGroupWidget</code > that handles our new type of links.
308+ </p >
309+ <pre ><code class =" language-markup line-numbers" >< ; GroupContainer Group=" ; Group" ; Class=" ; custom" ;> ;
310+ < ; span class=" ; title" ;> ; @@Group.Title< ; /span> ;
311+ < ; GroupLinks> ;< ; /GroupLinks> ;
312+ < ; GroupNodes> ;< ; /GroupNodes> ;
313+
314+ @@foreach ( var port in Group .Ports )
315+ {
316+ < ; PortRenderer Port = & quot ;port " ; Class = & quot ;group - port " ;> ;< ; / PortRenderer > ;
317+ }
318+ < ; /GroupContainer> ;
319+
320+ @@code {
321+ [Parameter ] public CustomGroupModel Group { get ; set ; }
322+ } </code ></pre >
323+ <ul >
324+ <li >It is mandatory to wrap everything in a <code >GroupContainer</code > component so that everything works properly, such as the group's position, moving it, etc..</li >
325+ <li >
326+ It is mandatory to add both <code >GroupLinks</code > and <code >GroupNodes</code > as direct children of the container.
327+ This will render the appropriate layers and populate/configure them properly.
328+ </li >
329+ <li >As with custom nodes, you are in charge of rendering the ports.</li >
330+ </ul >
331+
332+ For any custom content, you can add it wherever you want, as long as it's inside the container like our title <code >span</code >.<br />
333+ As with everything else , the component can be styled using CSS . Here is the styling of the custom group in the demos :
334+ <pre ><code class = "language -css line -numbers ">.group .custom {
335+ outline : 2px solid black ;
336+ background-color: #6fbb6e;
337+ }
338+
339+ .group.custom > span.title {
340+ padding : 20px ;
341+ position : absolute ;
342+ left : 50 % ;
343+ transform : translate (- 50 % , - 50 % );
344+ background : #eee ;
345+ border : 2px solid black ;
346+ border - radius : 50 % ;
347+ background - color : #6fbb6e ;
348+ font - weight : bold ;
349+ text - transform : uppercase ;
350+ } </code ></pre >
351+ </div >
352+ <div id =" register-custom-group" class =" section-block" >
353+ <h3 class =" block-title" >Registering the custom group</h3 >
354+ <p >
355+ Lastly, we'll register the custom link and its component in the <code >DiagramManager</code >:
356+ </p >
357+ <pre ><code class =" language-csharp line-numbers" >protected override void OnInitialized()
358+ {
359+ base .OnInitialized ();
360+
361+ _diagramManager .RegisterModelComponent < ; CustomGroupModel , CustomGroupWidget > ; ();
362+
363+ var node1 = NewNode (50 , 50 );
364+ var node2 = NewNode (300 , 300 );
365+ var node3 = NewNode (500 , 100 );
366+
367+ _diagramManager .AddNode (node1 );
368+ // You can create your own group directly and add it
369+ // You don't have to add its children to the diagram
370+ _diagramManager .AddGroup (new CustomGroupModel (_diagramManager , new [] { node2 , node3 }, & quot ;Group 1 & quot ;));
371+
372+ _diagramManager .AddLink (node1 .GetPort (PortAlignment .Right ), node2 .GetPort (PortAlignment .Left ));
373+ _diagramManager .AddLink (node2 .GetPort (PortAlignment .Right ), node3 .GetPort (PortAlignment .Bottom ));
374+ }
375+
376+ private NodeModel NewNode(double x, double y)
377+ {
378+ var node = new NodeModel (new Point (x , y ));
379+ node .AddPort (PortAlignment .Bottom );
380+ node .AddPort (PortAlignment .Top );
381+ node .AddPort (PortAlignment .Left );
382+ node .AddPort (PortAlignment .Right );
383+ return node ;
384+ } </code ></pre >
385+ </div >
386+ <p >
387+ Here's how it would look like:
388+ </p >
389+ <img src =" _content/SharedDemo/img/CustomGroupDisplay.png" alt =" Custom Group Display" />
390+ </section >
280391 </div >
281392</div >
282393
@@ -301,6 +412,12 @@ private NodeModel NewNode(double x, double y)
301412 <a class =" nav-link scrollto" href =" #create-link-component" >Creating a component</a >
302413 <a class =" nav-link scrollto" href =" #register-custom-link" >Registering the custom link</a >
303414 </nav >
415+ <a class =" nav-link scrollto" href =" #custom-groups" >Custom groups</a >
416+ <nav class =" doc-sub-menu nav flex-column" >
417+ <a class =" nav-link scrollto" href =" #create-group-model" >Creating a model</a >
418+ <a class =" nav-link scrollto" href =" #create-group-component" >Creating a component</a >
419+ <a class =" nav-link scrollto" href =" #register-custom-group" >Registering the custom group</a >
420+ </nav >
304421 </nav >
305422 </div >
306423</div >
0 commit comments