d2/d2plugin/plugin_elk.go

114 lines
2.8 KiB
Go
Raw Normal View History

2022-12-03 20:15:54 +00:00
//go:build !noelk
2022-11-11 19:43:56 +00:00
package d2plugin
import (
"context"
2022-12-30 08:09:28 +00:00
"encoding/json"
2022-12-30 21:19:48 +00:00
"fmt"
2022-11-11 19:43:56 +00:00
"oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2layouts/d2elklayout"
2022-12-30 05:09:53 +00:00
"oss.terrastruct.com/util-go/xmain"
2022-11-11 19:43:56 +00:00
)
var ELKPlugin = elkPlugin{}
func init() {
2022-12-30 06:43:01 +00:00
plugins = append(plugins, &ELKPlugin)
2022-11-11 19:43:56 +00:00
}
2022-12-30 05:09:53 +00:00
type elkPlugin struct {
2022-12-30 06:43:01 +00:00
opts *d2elklayout.ConfigurableOpts
2022-12-30 05:09:53 +00:00
}
2022-12-30 19:33:32 +00:00
func (p elkPlugin) Flags(context.Context) ([]PluginSpecificFlag, error) {
2022-12-30 08:09:28 +00:00
return []PluginSpecificFlag{
{
Name: "elk-algorithm",
Type: "string",
Default: d2elklayout.DefaultOpts.Algorithm,
2022-12-30 21:19:48 +00:00
Usage: "layout algorithm",
2022-12-30 08:09:28 +00:00
Tag: "elk.algorithm",
},
2022-12-30 20:34:25 +00:00
{
Name: "elk-nodeNodeBetweenLayers",
Type: "int64",
2022-12-30 20:40:52 +00:00
Default: int64(d2elklayout.DefaultOpts.NodeSpacing),
2022-12-30 21:19:48 +00:00
Usage: "the spacing to be preserved between any pair of nodes of two adjacent layers",
2022-12-30 20:34:25 +00:00
Tag: "spacing.nodeNodeBetweenLayers",
},
{
Name: "elk-padding",
Type: "string",
Default: d2elklayout.DefaultOpts.Padding,
2022-12-30 21:19:48 +00:00
Usage: "the padding to be left to a parent elements border when placing child elements",
2022-12-30 20:34:25 +00:00
Tag: "elk.padding",
},
{
Name: "elk-edgeNodeBetweenLayers",
Type: "int64",
2022-12-30 20:40:52 +00:00
Default: int64(d2elklayout.DefaultOpts.EdgeNodeSpacing),
2022-12-30 21:19:48 +00:00
Usage: "the spacing to be preserved between nodes and edges that are routed next to the nodes layer",
2022-12-30 20:34:25 +00:00
Tag: "spacing.edgeNodeBetweenLayers",
},
{
Name: "elk-nodeSelfLoop",
Type: "int64",
2022-12-30 20:40:52 +00:00
Default: int64(d2elklayout.DefaultOpts.SelfLoopSpacing),
2022-12-30 21:19:48 +00:00
Usage: "spacing to be preserved between a node and its self loops",
2022-12-30 20:34:25 +00:00
Tag: "elk.spacing.nodeSelfLoop",
},
2022-12-30 19:33:32 +00:00
}, nil
2022-12-30 08:09:28 +00:00
}
func (p *elkPlugin) HydrateOpts(opts []byte) error {
2022-12-30 05:09:53 +00:00
if opts != nil {
2022-12-30 08:09:28 +00:00
var elkOpts d2elklayout.ConfigurableOpts
err := json.Unmarshal(opts, &elkOpts)
if err != nil {
2022-12-30 21:39:21 +00:00
return xmain.UsageErrorf("non-ELK layout options given for ELK")
2022-12-30 05:09:53 +00:00
}
p.opts = &elkOpts
}
return nil
}
2022-11-11 19:43:56 +00:00
2022-12-30 21:19:48 +00:00
func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) {
2023-10-31 22:52:48 +00:00
opts := xmain.NewOpts(nil, nil)
2022-12-30 21:19:48 +00:00
flags, err := p.Flags(ctx)
if err != nil {
return nil, err
}
for _, f := range flags {
f.AddToOpts(opts)
}
2022-11-11 19:43:56 +00:00
return &PluginInfo{
2023-02-19 05:51:55 +00:00
Name: "elk",
Type: "bundled",
2023-02-20 17:05:00 +00:00
Features: []PluginFeature{
CONTAINER_DIMENSIONS,
DESCENDANT_EDGES,
2023-02-19 05:51:55 +00:00
},
2022-11-11 19:43:56 +00:00
ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.",
2022-12-30 21:19:48 +00:00
LongHelp: fmt.Sprintf(`ELK is a layout engine offered by Eclipse.
2022-11-11 19:43:56 +00:00
Originally written in Java, it has been ported to Javascript and cross-compiled into D2.
2023-02-05 08:41:00 +00:00
See https://d2lang.com/tour/elk for more.
2022-12-30 21:19:48 +00:00
2023-02-05 08:41:00 +00:00
Flags correspond to ones found at https://www.eclipse.org/elk/reference.html.
2022-12-30 21:19:48 +00:00
Flags:
%s
`, opts.Defaults()),
2022-11-11 19:43:56 +00:00
}, nil
}
2022-12-30 08:09:28 +00:00
func (p elkPlugin) Layout(ctx context.Context, g *d2graph.Graph) error {
2022-12-30 05:09:53 +00:00
return d2elklayout.Layout(ctx, g, p.opts)
2022-11-11 19:43:56 +00:00
}
2022-12-30 08:09:28 +00:00
func (p elkPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) {
2022-11-11 19:43:56 +00:00
return in, nil
}