113 lines
2.8 KiB
Go
113 lines
2.8 KiB
Go
//go:build !noelk
|
||
|
||
package d2plugin
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
|
||
"oss.terrastruct.com/d2/d2graph"
|
||
"oss.terrastruct.com/d2/d2layouts/d2elklayout"
|
||
"oss.terrastruct.com/util-go/xmain"
|
||
)
|
||
|
||
var ELKPlugin = elkPlugin{}
|
||
|
||
func init() {
|
||
plugins = append(plugins, &ELKPlugin)
|
||
}
|
||
|
||
type elkPlugin struct {
|
||
opts *d2elklayout.ConfigurableOpts
|
||
}
|
||
|
||
func (p elkPlugin) Flags(context.Context) ([]PluginSpecificFlag, error) {
|
||
return []PluginSpecificFlag{
|
||
{
|
||
Name: "elk-algorithm",
|
||
Type: "string",
|
||
Default: d2elklayout.DefaultOpts.Algorithm,
|
||
Usage: "layout algorithm",
|
||
Tag: "elk.algorithm",
|
||
},
|
||
{
|
||
Name: "elk-nodeNodeBetweenLayers",
|
||
Type: "int64",
|
||
Default: int64(d2elklayout.DefaultOpts.NodeSpacing),
|
||
Usage: "the spacing to be preserved between any pair of nodes of two adjacent layers",
|
||
Tag: "spacing.nodeNodeBetweenLayers",
|
||
},
|
||
{
|
||
Name: "elk-padding",
|
||
Type: "string",
|
||
Default: d2elklayout.DefaultOpts.Padding,
|
||
Usage: "the padding to be left to a parent element’s border when placing child elements",
|
||
Tag: "elk.padding",
|
||
},
|
||
{
|
||
Name: "elk-edgeNodeBetweenLayers",
|
||
Type: "int64",
|
||
Default: int64(d2elklayout.DefaultOpts.EdgeNodeSpacing),
|
||
Usage: "the spacing to be preserved between nodes and edges that are routed next to the node’s layer",
|
||
Tag: "spacing.edgeNodeBetweenLayers",
|
||
},
|
||
{
|
||
Name: "elk-nodeSelfLoop",
|
||
Type: "int64",
|
||
Default: int64(d2elklayout.DefaultOpts.SelfLoopSpacing),
|
||
Usage: "spacing to be preserved between a node and its self loops",
|
||
Tag: "elk.spacing.nodeSelfLoop",
|
||
},
|
||
}, nil
|
||
}
|
||
|
||
func (p *elkPlugin) HydrateOpts(opts []byte) error {
|
||
if opts != nil {
|
||
var elkOpts d2elklayout.ConfigurableOpts
|
||
err := json.Unmarshal(opts, &elkOpts)
|
||
if err != nil {
|
||
return xmain.UsageErrorf("non-ELK layout options given for ELK")
|
||
}
|
||
|
||
p.opts = &elkOpts
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) {
|
||
opts := xmain.NewOpts(nil, nil)
|
||
flags, err := p.Flags(ctx)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
for _, f := range flags {
|
||
f.AddToOpts(opts)
|
||
}
|
||
return &PluginInfo{
|
||
Name: "elk",
|
||
Type: "bundled",
|
||
Features: []PluginFeature{
|
||
CONTAINER_DIMENSIONS,
|
||
DESCENDANT_EDGES,
|
||
},
|
||
ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.",
|
||
LongHelp: fmt.Sprintf(`ELK is a layout engine offered by Eclipse.
|
||
Originally written in Java, it has been ported to Javascript and cross-compiled into D2.
|
||
See https://d2lang.com/tour/elk for more.
|
||
|
||
Flags correspond to ones found at https://www.eclipse.org/elk/reference.html.
|
||
|
||
Flags:
|
||
%s
|
||
`, opts.Defaults()),
|
||
}, nil
|
||
}
|
||
|
||
func (p elkPlugin) Layout(ctx context.Context, g *d2graph.Graph) error {
|
||
return d2elklayout.Layout(ctx, g, p.opts)
|
||
}
|
||
|
||
func (p elkPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) {
|
||
return in, nil
|
||
}
|