...

Source file src/oss.terrastruct.com/d2/d2plugin/plugin_elk.go

Documentation: oss.terrastruct.com/d2/d2plugin

     1  //go:build !noelk
     2  
     3  package d2plugin
     4  
     5  import (
     6  	"context"
     7  	"encoding/json"
     8  	"fmt"
     9  
    10  	"oss.terrastruct.com/d2/d2graph"
    11  	"oss.terrastruct.com/d2/d2layouts/d2elklayout"
    12  	"oss.terrastruct.com/util-go/xmain"
    13  )
    14  
    15  var ELKPlugin = elkPlugin{}
    16  
    17  func init() {
    18  	plugins = append(plugins, &ELKPlugin)
    19  }
    20  
    21  type elkPlugin struct {
    22  	opts *d2elklayout.ConfigurableOpts
    23  }
    24  
    25  func (p elkPlugin) Flags(context.Context) ([]PluginSpecificFlag, error) {
    26  	return []PluginSpecificFlag{
    27  		{
    28  			Name:    "elk-algorithm",
    29  			Type:    "string",
    30  			Default: d2elklayout.DefaultOpts.Algorithm,
    31  			Usage:   "layout algorithm",
    32  			Tag:     "elk.algorithm",
    33  		},
    34  		{
    35  			Name:    "elk-nodeNodeBetweenLayers",
    36  			Type:    "int64",
    37  			Default: int64(d2elklayout.DefaultOpts.NodeSpacing),
    38  			Usage:   "the spacing to be preserved between any pair of nodes of two adjacent layers",
    39  			Tag:     "spacing.nodeNodeBetweenLayers",
    40  		},
    41  		{
    42  			Name:    "elk-padding",
    43  			Type:    "string",
    44  			Default: d2elklayout.DefaultOpts.Padding,
    45  			Usage:   "the padding to be left to a parent element’s border when placing child elements",
    46  			Tag:     "elk.padding",
    47  		},
    48  		{
    49  			Name:    "elk-edgeNodeBetweenLayers",
    50  			Type:    "int64",
    51  			Default: int64(d2elklayout.DefaultOpts.EdgeNodeSpacing),
    52  			Usage:   "the spacing to be preserved between nodes and edges that are routed next to the node’s layer",
    53  			Tag:     "spacing.edgeNodeBetweenLayers",
    54  		},
    55  		{
    56  			Name:    "elk-nodeSelfLoop",
    57  			Type:    "int64",
    58  			Default: int64(d2elklayout.DefaultOpts.SelfLoopSpacing),
    59  			Usage:   "spacing to be preserved between a node and its self loops",
    60  			Tag:     "elk.spacing.nodeSelfLoop",
    61  		},
    62  	}, nil
    63  }
    64  
    65  func (p *elkPlugin) HydrateOpts(opts []byte) error {
    66  	if opts != nil {
    67  		var elkOpts d2elklayout.ConfigurableOpts
    68  		err := json.Unmarshal(opts, &elkOpts)
    69  		if err != nil {
    70  			return xmain.UsageErrorf("non-ELK layout options given for ELK")
    71  		}
    72  
    73  		p.opts = &elkOpts
    74  	}
    75  	return nil
    76  }
    77  
    78  func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) {
    79  	opts := xmain.NewOpts(nil, nil)
    80  	flags, err := p.Flags(ctx)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	for _, f := range flags {
    85  		f.AddToOpts(opts)
    86  	}
    87  	return &PluginInfo{
    88  		Name: "elk",
    89  		Type: "bundled",
    90  		Features: []PluginFeature{
    91  			CONTAINER_DIMENSIONS,
    92  			DESCENDANT_EDGES,
    93  		},
    94  		ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.",
    95  		LongHelp: fmt.Sprintf(`ELK is a layout engine offered by Eclipse.
    96  Originally written in Java, it has been ported to Javascript and cross-compiled into D2.
    97  See https://d2lang.com/tour/elk for more.
    98  
    99  Flags correspond to ones found at https://www.eclipse.org/elk/reference.html.
   100  
   101  Flags:
   102  %s
   103  `, opts.Defaults()),
   104  	}, nil
   105  }
   106  
   107  func (p elkPlugin) Layout(ctx context.Context, g *d2graph.Graph) error {
   108  	return d2elklayout.Layout(ctx, g, p.opts)
   109  }
   110  
   111  func (p elkPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) {
   112  	return in, nil
   113  }
   114  

View as plain text