resolved merge conflict

This commit is contained in:
Vojtěch Fošnár 2023-01-15 21:36:43 +01:00
commit 66dc978418
No known key found for this signature in database
GPG key ID: 657727E71C40859A
54 changed files with 5146 additions and 196 deletions

View file

@ -1,8 +1,18 @@
#### Features 🚀
- `animated` keyword implemented for connections. [#652](https://github.com/terrastruct/d2/pull/652)
#### Improvements 🧹
- ELK layouts tuned to have better defaults. [#627](https://github.com/terrastruct/d2/pull/627)
- Code snippets of unrecognized languages will render (just without syntax highlighting). [#650](https://github.com/terrastruct/d2/pull/650)
- Adds sketched versions of arrowheads. [#656](https://github.com/terrastruct/d2/pull/656)
#### Bugfixes ⛑️
- Fixes arrowheads sometimes appearing broken in dagre layouts. [#649](https://github.com/terrastruct/d2/pull/649)
- Fixes attributes being ignored for `sql_table` to `sql_table` connections. [#658](https://github.com/terrastruct/d2/pull/658)
- Fixes tooltip/link attributes being ignored for `sql_table` and `class`. [#658](https://github.com/terrastruct/d2/pull/658)
- Fixes arrowheads sometimes appearing broken with sketch on. [#656](https://github.com/terrastruct/d2/pull/656)
- Fixes code snippets not being tall enough with leading newlines. [#664](https://github.com/terrastruct/d2/pull/664)
- Icon URLs that needed escaping (e.g. with ampersands) are handled correctly by CLI. [#666](https://github.com/terrastruct/d2/pull/666)

View file

@ -757,13 +757,15 @@ func flattenContainer(g *d2graph.Graph, obj *d2graph.Object) {
// TODO more attributes
if e.SrcTableColumnIndex != nil {
newEdge.SrcTableColumnIndex = new(int)
newEdge.SrcArrowhead = e.SrcArrowhead
*newEdge.SrcTableColumnIndex = *e.SrcTableColumnIndex
}
if e.DstTableColumnIndex != nil {
newEdge.DstTableColumnIndex = new(int)
newEdge.DstArrowhead = e.DstArrowhead
*newEdge.DstTableColumnIndex = *e.DstTableColumnIndex
}
newEdge.Attributes.Label = e.Attributes.Label
newEdge.Attributes = e.Attributes
newEdge.References = e.References
}
updatedEdges := []*d2graph.Edge{}

View file

@ -1597,6 +1597,25 @@ b`, g.Objects[0].Attributes.Label.Value)
}
},
},
{
name: "table_connection_attr",
text: `x: {
shape: sql_table
y
}
a: {
shape: sql_table
b
}
x.y -> a.b: {
style.animated: true
}
`,
assertions: func(t *testing.T, g *d2graph.Graph) {
tassert.Equal(t, "true", g.Edges[0].Attributes.Style.Animated.Value)
},
},
{
name: "class_paren",

View file

@ -1027,6 +1027,27 @@ func GetTextDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler, t *d2
var h int
if t.Language != "" {
w, h = ruler.Measure(d2fonts.SourceCodePro.Font(t.FontSize, d2fonts.FONT_STYLE_REGULAR), t.Text)
// count empty leading and trailing lines since ruler will not be able to measure it
lines := strings.Split(t.Text, "\n")
leadingLines := 0
for _, line := range lines {
if strings.TrimSpace(line) == "" {
leadingLines++
} else {
break
}
}
trailingLines := 0
for i := len(lines) - 1; i >= 0; i-- {
if strings.TrimSpace(lines[i]) == "" {
trailingLines++
} else {
break
}
}
h += t.FontSize * (leadingLines + trailingLines)
// padding
w += 12
h += 12

View file

@ -30,6 +30,8 @@ var setupJS string
//go:embed dagre.js
var dagreJS string
const MIN_SEGMENT_LEN = 10
type ConfigurableOpts struct {
NodeSep int `json:"nodesep"`
EdgeSep int `json:"edgesep"`
@ -247,6 +249,47 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
}
}
// arrowheads can appear broken if segments are very short from dagre routing a point just outside the shape
// to fix this, we try extending the previous segment into the shape instead of having a very short segment
if !start.Equals(points[0]) && startIndex+2 < len(points) {
newStartingSegment := *geo.NewSegment(start, points[startIndex+1])
if newStartingSegment.Length() < MIN_SEGMENT_LEN {
// we don't want a very short segment right next to the source because it will mess up the arrowhead
// instead we want to extend the next segment into the shape border if possible
nextStart := points[startIndex+1]
nextEnd := points[startIndex+2]
// Note: in other direction to extend towards source
nextSegment := *geo.NewSegment(nextStart, nextEnd)
v := nextSegment.ToVector()
extendedStart := nextEnd.ToVector().Add(v.AddLength(MIN_SEGMENT_LEN)).ToPoint()
extended := *geo.NewSegment(nextEnd, extendedStart)
if intersections := edge.Src.Box.Intersections(extended); len(intersections) > 0 {
start = intersections[0]
startIndex += 1
}
}
}
if !end.Equals(points[len(points)-1]) && endIndex-2 >= 0 {
newEndingSegment := *geo.NewSegment(end, points[endIndex-1])
if newEndingSegment.Length() < MIN_SEGMENT_LEN {
// extend the prev segment into the shape border if possible
prevStart := points[endIndex-2]
prevEnd := points[endIndex-1]
prevSegment := *geo.NewSegment(prevStart, prevEnd)
v := prevSegment.ToVector()
extendedEnd := prevStart.ToVector().Add(v.AddLength(MIN_SEGMENT_LEN)).ToPoint()
extended := *geo.NewSegment(prevStart, extendedEnd)
if intersections := edge.Dst.Box.Intersections(extended); len(intersections) > 0 {
end = intersections[0]
endIndex -= 1
}
}
}
srcShape := shape.NewShape(d2target.DSL_SHAPE_TO_SHAPE_TYPE[strings.ToLower(edge.Src.Attributes.Shape.Value)], edge.Src.Box)
dstShape := shape.NewShape(d2target.DSL_SHAPE_TO_SHAPE_TYPE[strings.ToLower(edge.Dst.Attributes.Shape.Value)], edge.Dst.Box)
@ -263,18 +306,20 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
path := make([]*geo.Point, 0)
path = append(path, points[0])
path = append(path, points[0].AddVector(vectors[0].Multiply(.8)))
for i := 1; i < len(vectors)-2; i++ {
p := points[i]
v := vectors[i]
path = append(path, p.AddVector(v.Multiply(.2)))
path = append(path, p.AddVector(v.Multiply(.5)))
path = append(path, p.AddVector(v.Multiply(.8)))
if len(vectors) > 1 {
path = append(path, points[0].AddVector(vectors[0].Multiply(.8)))
for i := 1; i < len(vectors)-2; i++ {
p := points[i]
v := vectors[i]
path = append(path, p.AddVector(v.Multiply(.2)))
path = append(path, p.AddVector(v.Multiply(.5)))
path = append(path, p.AddVector(v.Multiply(.8)))
}
path = append(path, points[len(points)-2].AddVector(vectors[len(vectors)-1].Multiply(.2)))
edge.IsCurve = true
}
path = append(path, points[len(points)-2].AddVector(vectors[len(vectors)-1].Multiply(.2)))
path = append(path, points[len(points)-1])
edge.IsCurve = true
edge.Route = path
// compile needs to assign edge label positions
if edge.Attributes.Label.Value != "" {

View file

@ -3,6 +3,8 @@ package d2sketch
import (
"encoding/json"
"fmt"
"regexp"
"strings"
_ "embed"
@ -31,6 +33,8 @@ fillStyle: "solid",
bowing: 2,
seed: 1,`
var floatRE = regexp.MustCompile(`(\d+)\.(\d+)`)
func (r *Runner) run(js string) (goja.Value, error) {
vm := (*goja.Runtime)(r)
return vm.RunString(js)
@ -74,7 +78,7 @@ func Rect(r *Runner, shape d2target.Shape) (string, error) {
strokeWidth: %d,
%s
});`, shape.Width, shape.Height, shape.StrokeWidth, baseRoughProps)
paths, err := computeRoughPaths(r, js)
paths, err := computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -83,7 +87,7 @@ func Rect(r *Runner, shape d2target.Shape) (string, error) {
pathEl.Transform = fmt.Sprintf("translate(%d %d)", shape.Pos.X, shape.Pos.Y)
pathEl.Fill, pathEl.Stroke = svg_style.ShapeTheme(shape)
pathEl.Class = "shape"
pathEl.Style = svg_style.ShapeStyle(shape)
pathEl.Style = shape.CSSStyle()
for _, p := range paths {
pathEl.D = p
output += pathEl.Render()
@ -109,7 +113,7 @@ func Oval(r *Runner, shape d2target.Shape) (string, error) {
strokeWidth: %d,
%s
});`, shape.Width/2, shape.Height/2, shape.Width, shape.Height, shape.StrokeWidth, baseRoughProps)
paths, err := computeRoughPaths(r, js)
paths, err := computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -118,7 +122,7 @@ func Oval(r *Runner, shape d2target.Shape) (string, error) {
pathEl.Transform = fmt.Sprintf("translate(%d %d)", shape.Pos.X, shape.Pos.Y)
pathEl.Fill, pathEl.Stroke = svg_style.ShapeTheme(shape)
pathEl.Class = "shape"
pathEl.Style = svg_style.ShapeStyle(shape)
pathEl.Style = shape.CSSStyle()
for _, p := range paths {
pathEl.D = p
output += pathEl.Render()
@ -150,14 +154,14 @@ func Paths(r *Runner, shape d2target.Shape, paths []string) (string, error) {
strokeWidth: %d,
%s
});`, path, shape.StrokeWidth, baseRoughProps)
sketchPaths, err := computeRoughPaths(r, js)
sketchPaths, err := computeRoughPathData(r, js)
if err != nil {
return "", err
}
pathEl := svg_style.NewThemableElement("path")
pathEl.Fill, pathEl.Stroke = svg_style.ShapeTheme(shape)
pathEl.Class = "shape"
pathEl.Style = svg_style.ShapeStyle(shape)
pathEl.Style = shape.CSSStyle()
for _, p := range sketchPaths {
pathEl.D = p
output += pathEl.Render()
@ -182,7 +186,7 @@ func Paths(r *Runner, shape d2target.Shape, paths []string) (string, error) {
func Connection(r *Runner, connection d2target.Connection, path, attrs string) (string, error) {
roughness := 1.0
js := fmt.Sprintf(`node = rc.path("%s", {roughness: %f, seed: 1});`, path, roughness)
paths, err := computeRoughPaths(r, js)
paths, err := computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -191,7 +195,7 @@ func Connection(r *Runner, connection d2target.Connection, path, attrs string) (
pathEl.Fill = color.None
pathEl.Stroke = svg_style.ConnectionTheme(connection)
pathEl.Class = "connection"
pathEl.Style = svg_style.ConnectionStyle(connection)
pathEl.Style = connection.CSSStyle()
pathEl.Attributes = attrs
for _, p := range paths {
pathEl.D = p
@ -209,7 +213,7 @@ func Table(r *Runner, shape d2target.Shape) (string, error) {
strokeWidth: %d,
%s
});`, shape.Width, shape.Height, shape.StrokeWidth, baseRoughProps)
paths, err := computeRoughPaths(r, js)
paths, err := computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -217,7 +221,7 @@ func Table(r *Runner, shape d2target.Shape) (string, error) {
pathEl.Transform = fmt.Sprintf("translate(%d %d)", shape.Pos.X, shape.Pos.Y)
pathEl.Fill, pathEl.Stroke = svg_style.ShapeTheme(shape)
pathEl.Class = "shape"
pathEl.Style = svg_style.ShapeStyle(shape)
pathEl.Style = shape.CSSStyle()
for _, p := range paths {
pathEl.D = p
output += pathEl.Render()
@ -235,7 +239,7 @@ func Table(r *Runner, shape d2target.Shape) (string, error) {
fill: "#000",
%s
});`, shape.Width, rowHeight, baseRoughProps)
paths, err = computeRoughPaths(r, js)
paths, err = computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -315,7 +319,7 @@ func Table(r *Runner, shape d2target.Shape) (string, error) {
js = fmt.Sprintf(`node = rc.line(%f, %f, %f, %f, {
%s
});`, rowBox.TopLeft.X, rowBox.TopLeft.Y, rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y, baseRoughProps)
paths, err = computeRoughPaths(r, js)
paths, err = computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -348,7 +352,7 @@ func Class(r *Runner, shape d2target.Shape) (string, error) {
strokeWidth: %d,
%s
});`, shape.Width, shape.Height, shape.StrokeWidth, baseRoughProps)
paths, err := computeRoughPaths(r, js)
paths, err := computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -356,6 +360,7 @@ func Class(r *Runner, shape d2target.Shape) (string, error) {
pathEl.Transform = fmt.Sprintf("translate(%d %d)", shape.Pos.X, shape.Pos.Y)
pathEl.Fill, pathEl.Stroke = svg_style.ShapeTheme(shape)
pathEl.Class = "shape"
pathEl.Style = shape.CSSStyle()
for _, p := range paths {
pathEl.D = p
output += pathEl.Render()
@ -374,7 +379,7 @@ func Class(r *Runner, shape d2target.Shape) (string, error) {
fill: "#000",
%s
});`, shape.Width, headerBox.Height, baseRoughProps)
paths, err = computeRoughPaths(r, js)
paths, err = computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -428,7 +433,7 @@ func Class(r *Runner, shape d2target.Shape) (string, error) {
js = fmt.Sprintf(`node = rc.line(%f, %f, %f, %f, {
%s
});`, rowBox.TopLeft.X, rowBox.TopLeft.Y, rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y, baseRoughProps)
paths, err = computeRoughPaths(r, js)
paths, err = computeRoughPathData(r, js)
if err != nil {
return "", err
}
@ -487,38 +492,242 @@ func classRow(shape d2target.Shape, box *geo.Box, prefix, nameText, typeText str
return output
}
func computeRoughPaths(r *Runner, js string) ([]string, error) {
func computeRoughPathData(r *Runner, js string) ([]string, error) {
if _, err := r.run(js); err != nil {
return nil, err
}
return extractPaths(r)
roughPaths, err := extractRoughPaths(r)
if err != nil {
return nil, err
}
return extractPathData(roughPaths)
}
func computeRoughPaths(r *Runner, js string) ([]roughPath, error) {
if _, err := r.run(js); err != nil {
return nil, err
}
return extractRoughPaths(r)
}
type attrs struct {
D string `json:"d"`
}
type node struct {
Attrs attrs `json:"attrs"`
type style struct {
Stroke string `json:"stroke,omitempty"`
StrokeWidth string `json:"strokeWidth,omitempty"`
Fill string `json:"fill,omitempty"`
}
func extractPaths(r *Runner) ([]string, error) {
val, err := r.run("JSON.stringify(node.children)")
type roughPath struct {
Attrs attrs `json:"attrs"`
Style style `json:"style"`
}
func (rp roughPath) StyleCSS() string {
style := ""
if rp.Style.Fill != "" {
style += fmt.Sprintf("fill:%s;", rp.Style.Fill)
}
if rp.Style.Stroke != "" {
style += fmt.Sprintf("stroke:%s;", rp.Style.Stroke)
}
if rp.Style.StrokeWidth != "" {
style += fmt.Sprintf("stroke-width:%s;", rp.Style.StrokeWidth)
}
return style
}
func extractRoughPaths(r *Runner) ([]roughPath, error) {
val, err := r.run("JSON.stringify(node.children, null, ' ')")
if err != nil {
return nil, err
}
var nodes []node
err = json.Unmarshal([]byte(val.String()), &nodes)
var roughPaths []roughPath
err = json.Unmarshal([]byte(val.String()), &roughPaths)
if err != nil {
return nil, err
}
// we want to have a fixed precision to the decimals in the path data
for i := range roughPaths {
// truncate all floats in path to only use up to 6 decimal places
roughPaths[i].Attrs.D = floatRE.ReplaceAllStringFunc(roughPaths[i].Attrs.D, func(floatStr string) string {
i := strings.Index(floatStr, ".")
decimalLen := len(floatStr) - i - 1
end := i + go2.Min(decimalLen, 6)
return floatStr[:end+1]
})
}
return roughPaths, nil
}
func extractPathData(roughPaths []roughPath) ([]string, error) {
var paths []string
for _, n := range nodes {
paths = append(paths, n.Attrs.D)
for _, rp := range roughPaths {
paths = append(paths, rp.Attrs.D)
}
return paths, nil
}
func ArrowheadJS(r *Runner, arrowhead d2target.Arrowhead, stroke string, strokeWidth int) (arrowJS, extraJS string) {
// Note: selected each seed that looks the good for consistent renders
switch arrowhead {
case d2target.ArrowArrowhead:
arrowJS = fmt.Sprintf(
`node = rc.linearPath(%s, { strokeWidth: %d, stroke: "%s", seed: 3 })`,
`[[-10, -4], [0, 0], [-10, 4]]`,
strokeWidth,
stroke,
)
case d2target.TriangleArrowhead:
arrowJS = fmt.Sprintf(
`node = rc.polygon(%s, { strokeWidth: %d, stroke: "%s", fill: "%s", fillStyle: "solid", seed: 2 })`,
`[[-10, -4], [0, 0], [-10, 4]]`,
strokeWidth,
stroke,
stroke,
)
case d2target.DiamondArrowhead:
arrowJS = fmt.Sprintf(
`node = rc.polygon(%s, { strokeWidth: %d, stroke: "%s", fill: "white", fillStyle: "solid", seed: 1 })`,
`[[-20, 0], [-10, 5], [0, 0], [-10, -5], [-20, 0]]`,
strokeWidth,
stroke,
)
case d2target.FilledDiamondArrowhead:
arrowJS = fmt.Sprintf(
`node = rc.polygon(%s, { strokeWidth: %d, stroke: "%s", fill: "%s", fillStyle: "zigzag", fillWeight: 4, seed: 1 })`,
`[[-20, 0], [-10, 5], [0, 0], [-10, -5], [-20, 0]]`,
strokeWidth,
stroke,
stroke,
)
case d2target.CfManyRequired:
arrowJS = fmt.Sprintf(
// TODO why does fillStyle: "zigzag" error with path
`node = rc.path(%s, { strokeWidth: %d, stroke: "%s", fill: "%s", fillStyle: "solid", fillWeight: 4, seed: 2 })`,
`"M-15,-10 -15,10 M0,10 -15,0 M0,-10 -15,0"`,
strokeWidth,
stroke,
stroke,
)
case d2target.CfMany:
arrowJS = fmt.Sprintf(
`node = rc.path(%s, { strokeWidth: %d, stroke: "%s", fill: "%s", fillStyle: "solid", fillWeight: 4, seed: 8 })`,
`"M0,10 -15,0 M0,-10 -15,0"`,
strokeWidth,
stroke,
stroke,
)
extraJS = fmt.Sprintf(
`node = rc.circle(-20, 0, 8, { strokeWidth: %d, stroke: "%s", fill: "white", fillStyle: "solid", fillWeight: 1, seed: 4 })`,
strokeWidth,
stroke,
)
case d2target.CfOneRequired:
arrowJS = fmt.Sprintf(
`node = rc.path(%s, { strokeWidth: %d, stroke: "%s", fill: "%s", fillStyle: "solid", fillWeight: 4, seed: 2 })`,
`"M-15,-10 -15,10 M-10,-10 -10,10"`,
strokeWidth,
stroke,
stroke,
)
case d2target.CfOne:
arrowJS = fmt.Sprintf(
`node = rc.path(%s, { strokeWidth: %d, stroke: "%s", fill: "%s", fillStyle: "solid", fillWeight: 4, seed: 3 })`,
`"M-10,-10 -10,10"`,
strokeWidth,
stroke,
stroke,
)
extraJS = fmt.Sprintf(
`node = rc.circle(-20, 0, 8, { strokeWidth: %d, stroke: "%s", fill: "white", fillStyle: "solid", fillWeight: 1, seed: 5 })`,
strokeWidth,
stroke,
)
}
return
}
func Arrowheads(r *Runner, connection d2target.Connection, srcAdj, dstAdj *geo.Point) (string, error) {
arrowPaths := []string{}
if connection.SrcArrow != d2target.NoArrowhead {
arrowJS, extraJS := ArrowheadJS(r, connection.SrcArrow, connection.Stroke, connection.StrokeWidth)
if arrowJS == "" {
return "", nil
}
startingSegment := geo.NewSegment(connection.Route[0], connection.Route[1])
startingVector := startingSegment.ToVector().Reverse()
angle := startingVector.Degrees()
transform := fmt.Sprintf(`transform="translate(%f %f) rotate(%v)"`,
startingSegment.Start.X+srcAdj.X, startingSegment.Start.Y+srcAdj.Y, angle,
)
roughPaths, err := computeRoughPaths(r, arrowJS)
if err != nil {
return "", err
}
if extraJS != "" {
extraPaths, err := computeRoughPaths(r, extraJS)
if err != nil {
return "", err
}
roughPaths = append(roughPaths, extraPaths...)
}
for _, rp := range roughPaths {
pathStr := fmt.Sprintf(`<path class="connection" d="%s" style="%s" %s/>`,
rp.Attrs.D,
rp.StyleCSS(),
transform,
)
arrowPaths = append(arrowPaths, pathStr)
}
}
if connection.DstArrow != d2target.NoArrowhead {
arrowJS, extraJS := ArrowheadJS(r, connection.DstArrow, connection.Stroke, connection.StrokeWidth)
if arrowJS == "" {
return "", nil
}
length := len(connection.Route)
endingSegment := geo.NewSegment(connection.Route[length-2], connection.Route[length-1])
endingVector := endingSegment.ToVector()
angle := endingVector.Degrees()
transform := fmt.Sprintf(`transform="translate(%f %f) rotate(%v)"`,
endingSegment.End.X+dstAdj.X, endingSegment.End.Y+dstAdj.Y, angle,
)
roughPaths, err := computeRoughPaths(r, arrowJS)
if err != nil {
return "", err
}
if extraJS != "" {
extraPaths, err := computeRoughPaths(r, extraJS)
if err != nil {
return "", err
}
roughPaths = append(roughPaths, extraPaths...)
}
for _, rp := range roughPaths {
pathStr := fmt.Sprintf(`<path class="connection" d="%s" style="%s" %s/>`,
rp.Attrs.D,
rp.StyleCSS(),
transform,
)
arrowPaths = append(arrowPaths, pathStr)
}
}
return strings.Join(arrowPaths, " "), nil
}

View file

@ -39,6 +39,11 @@ func TestSketch(t *testing.T) {
script: `winter.snow -> summer.sun
`,
},
{
name: "animated",
script: `winter.snow -> summer.sun -> trees -> winter.snow: { style.animated: true }
`,
},
{
name: "connection label",
script: `a -> b: hello
@ -275,6 +280,52 @@ shipments.order_id <-> orders.id`,
+getJobs(): "Job[]"
+setTimeout(seconds int)
}
`,
},
{
name: "arrowheads",
script: `
a: ""
b: ""
a.1 -- b.1: none
a.2 <-> b.2: arrow {
source-arrowhead.shape: arrow
target-arrowhead.shape: arrow
}
a.3 <-> b.3: triangle {
source-arrowhead.shape: triangle
target-arrowhead.shape: triangle
}
a.4 <-> b.4: diamond {
source-arrowhead.shape: diamond
target-arrowhead.shape: diamond
}
a.5 <-> b.5: diamond filled {
source-arrowhead: {
shape: diamond
style.filled: true
}
target-arrowhead: {
shape: diamond
style.filled: true
}
}
a.6 <-> b.6: cf-many {
source-arrowhead.shape: cf-many
target-arrowhead.shape: cf-many
}
a.7 <-> b.7: cf-many-required {
source-arrowhead.shape: cf-many-required
target-arrowhead.shape: cf-many-required
}
a.8 <-> b.8: cf-one {
source-arrowhead.shape: cf-one
target-arrowhead.shape: cf-one
}
a.9 <-> b.9: cf-one-required {
source-arrowhead.shape: cf-one-required
target-arrowhead.shape: cf-one-required
}
`,
},
{

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 299 KiB

After

Width:  |  Height:  |  Size: 272 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 253 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 304 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 196 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 248 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 196 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 84 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 385 KiB

After

Width:  |  Height:  |  Size: 389 KiB

View file

@ -88,7 +88,7 @@ func drawClass(writer io.Writer, targetShape d2target.Shape) {
el.Width = float64(targetShape.Width)
el.Height = float64(targetShape.Height)
el.Fill, el.Stroke = svg_style.ShapeTheme(targetShape)
el.Style = svg_style.ShapeStyle(targetShape)
el.Style = targetShape.CSSStyle()
fmt.Fprint(writer, el.Render())
box := geo.NewBox(

View file

@ -328,17 +328,25 @@ func arrowheadAdjustment(start, end *geo.Point, arrowhead d2target.Arrowhead, ed
return v.Unit().Multiply(-distance).ToPoint()
}
// returns the path's d attribute for the given connection
func pathData(connection d2target.Connection, idToShape map[string]d2target.Shape) string {
var path []string
func getArrowheadAdjustments(connection d2target.Connection, idToShape map[string]d2target.Shape) (srcAdj, dstAdj *geo.Point) {
route := connection.Route
srcShape := idToShape[connection.Src]
dstShape := idToShape[connection.Dst]
sourceAdjustment := arrowheadAdjustment(route[0], route[1], connection.SrcArrow, connection.StrokeWidth, srcShape.StrokeWidth)
sourceAdjustment := arrowheadAdjustment(route[1], route[0], connection.SrcArrow, connection.StrokeWidth, srcShape.StrokeWidth)
targetAdjustment := arrowheadAdjustment(route[len(route)-2], route[len(route)-1], connection.DstArrow, connection.StrokeWidth, dstShape.StrokeWidth)
return sourceAdjustment, targetAdjustment
}
// returns the path's d attribute for the given connection
func pathData(connection d2target.Connection, srcAdj, dstAdj *geo.Point) string {
var path []string
route := connection.Route
path = append(path, fmt.Sprintf("M %f %f",
route[0].X-sourceAdjustment.X,
route[0].Y-sourceAdjustment.Y,
route[0].X+srcAdj.X,
route[0].Y+srcAdj.Y,
))
if connection.IsCurve {
@ -351,12 +359,11 @@ func pathData(connection d2target.Connection, idToShape map[string]d2target.Shap
))
}
// final curve target adjustment
targetAdjustment := arrowheadAdjustment(route[i+1], route[i+2], connection.DstArrow, connection.StrokeWidth, dstShape.StrokeWidth)
path = append(path, fmt.Sprintf("C %f %f %f %f %f %f",
route[i].X, route[i].Y,
route[i+1].X, route[i+1].Y,
route[i+2].X+targetAdjustment.X,
route[i+2].Y+targetAdjustment.Y,
route[i+2].X+dstAdj.X,
route[i+2].Y+dstAdj.Y,
))
} else {
for i := 1; i < len(route)-1; i++ {
@ -408,12 +415,9 @@ func pathData(connection d2target.Connection, idToShape map[string]d2target.Shap
}
lastPoint := route[len(route)-1]
secondToLastPoint := route[len(route)-2]
targetAdjustment := arrowheadAdjustment(secondToLastPoint, lastPoint, connection.DstArrow, connection.StrokeWidth, dstShape.StrokeWidth)
path = append(path, fmt.Sprintf("L %f %f",
lastPoint.X+targetAdjustment.X,
lastPoint.Y+targetAdjustment.Y,
lastPoint.X+dstAdj.X,
lastPoint.Y+dstAdj.Y,
))
}
@ -469,26 +473,30 @@ func drawConnection(writer io.Writer, bgColor string, fgColor string, labelMaskI
}
}
path := pathData(connection, idToShape)
attrs := fmt.Sprintf(`%s%smask="url(#%s)"`,
markerStart,
markerEnd,
labelMaskID,
)
srcAdj, dstAdj := getArrowheadAdjustments(connection, idToShape)
path := pathData(connection, srcAdj, dstAdj)
mask := fmt.Sprintf(`mask="url(#%s)"`, labelMaskID)
if sketchRunner != nil {
out, err := d2sketch.Connection(sketchRunner, connection, path, attrs)
out, err := d2sketch.Connection(sketchRunner, connection, path, mask)
if err != nil {
return "", err
}
fmt.Fprint(writer, out)
// render sketch arrowheads separately
arrowPaths, err := d2sketch.Arrowheads(sketchRunner, connection, srcAdj, dstAdj)
if err != nil {
return "", err
}
fmt.Fprint(writer, arrowPaths)
} else {
pathEl := svg_style.NewThemableElement("path")
pathEl.D = path
pathEl.Fill = color.None
pathEl.Stroke = svg_style.ConnectionTheme(connection)
pathEl.Class = "connection"
pathEl.Style = svg_style.ConnectionStyle(connection)
pathEl.Attributes = attrs
pathEl.Class = "connection animated-connection"
pathEl.Style = connection.CSSStyle()
pathEl.Attributes = fmt.Sprintf("%s%s%s", markerStart, markerEnd, mask)
fmt.Fprint(writer, pathEl.Render())
}
@ -618,7 +626,7 @@ func render3dRect(targetShape d2target.Shape) string {
border.Fill = color.None
_, borderStroke := svg_style.ShapeTheme(targetShape)
border.Stroke = borderStroke
borderStyle := svg_style.ShapeStyle(targetShape)
borderStyle := targetShape.CSSStyle()
border.Style = borderStyle
renderedBorder := border.Render()
@ -645,7 +653,7 @@ func render3dRect(targetShape d2target.Shape) string {
mainShapeFill, _ := svg_style.ShapeTheme(targetShape)
mainShape.Fill = mainShapeFill
mainShape.Stroke = color.None
mainShape.Style = svg_style.ShapeStyle(targetShape)
mainShape.Style = targetShape.CSSStyle()
mainShapeRendered := mainShape.Render()
// render the side shapes in the darkened color without stroke and the border mask
@ -671,7 +679,7 @@ func render3dRect(targetShape d2target.Shape) string {
sideShape.Fill = darkerColor
sideShape.Points = strings.Join(sidePoints, " ")
sideShape.Mask = fmt.Sprintf("url(#%s)", maskID)
sideShape.Style = svg_style.ShapeStyle(targetShape)
sideShape.Style = targetShape.CSSStyle()
renderedSides := sideShape.Render()
return borderMask + mainShapeRendered + renderedSides + renderedBorder
@ -688,7 +696,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
width := float64(targetShape.Width)
height := float64(targetShape.Height)
fill, stroke := svg_style.ShapeTheme(targetShape)
style := svg_style.ShapeStyle(targetShape)
style := targetShape.CSSStyle()
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[targetShape.Type]
s := shape.NewShape(shapeType, geo.NewBox(tl, width, height))
@ -728,6 +736,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
} else {
drawClass(writer, targetShape)
}
addAppendixItems(writer, targetShape)
fmt.Fprintf(writer, `</g>`)
fmt.Fprint(writer, closingTag)
return labelMask, nil
@ -741,6 +750,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
} else {
drawTable(writer, targetShape)
}
addAppendixItems(writer, targetShape)
fmt.Fprintf(writer, `</g>`)
fmt.Fprint(writer, closingTag)
return labelMask, nil
@ -972,27 +982,31 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
}
}
addAppendixItems(writer, targetShape)
fmt.Fprintf(writer, closingTag)
return labelMask, nil
}
func addAppendixItems(writer io.Writer, shape d2target.Shape) {
rightPadForTooltip := 0
if targetShape.Tooltip != "" {
if shape.Tooltip != "" {
rightPadForTooltip = 2 * appendixIconRadius
fmt.Fprintf(writer, `<g transform="translate(%d %d)" class="appendix-icon">%s</g>`,
targetShape.Pos.X+targetShape.Width-appendixIconRadius,
targetShape.Pos.Y-appendixIconRadius,
shape.Pos.X+shape.Width-appendixIconRadius,
shape.Pos.Y-appendixIconRadius,
TooltipIcon,
)
fmt.Fprintf(writer, `<title>%s</title>`, targetShape.Tooltip)
fmt.Fprintf(writer, `<title>%s</title>`, shape.Tooltip)
}
if targetShape.Link != "" {
if shape.Link != "" {
fmt.Fprintf(writer, `<g transform="translate(%d %d)" class="appendix-icon">%s</g>`,
targetShape.Pos.X+targetShape.Width-appendixIconRadius-rightPadForTooltip,
targetShape.Pos.Y-appendixIconRadius,
shape.Pos.X+shape.Width-appendixIconRadius-rightPadForTooltip,
shape.Pos.Y-appendixIconRadius,
LinkIcon,
)
}
fmt.Fprint(writer, closingTag)
return labelMask, nil
}
func RenderText(text string, x, height float64) string {
@ -1055,6 +1069,23 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
}
}
triggers = []string{
`animated-connection`,
}
for _, t := range triggers {
if strings.Contains(content, t) {
out += `
@keyframes dashdraw {
from {
stroke-dashoffset: 0;
}
}
`
break
}
}
triggers = []string{
`appendix-icon`,
}

View file

@ -90,7 +90,7 @@ func drawTable(writer io.Writer, targetShape d2target.Shape) {
rectEl.Height = float64(targetShape.Height)
rectEl.Fill, rectEl.Stroke = svg_style.ShapeTheme(targetShape)
rectEl.Class = "shape"
rectEl.Style = svg_style.ShapeStyle(targetShape)
rectEl.Style = targetShape.CSSStyle()
fmt.Fprint(writer, rectEl.Render())
box := geo.NewBox(

View file

@ -15,6 +15,7 @@ import (
"oss.terrastruct.com/d2/lib/geo"
"oss.terrastruct.com/d2/lib/label"
"oss.terrastruct.com/d2/lib/shape"
"oss.terrastruct.com/d2/lib/svg"
)
const (
@ -159,6 +160,29 @@ type Shape struct {
NeutralAccentColor string `json:"neutralAccentColor,omitempty"`
}
func (s Shape) CSSStyle() string {
out := ""
if s.Type == ShapeSQLTable || s.Type == ShapeClass {
// Fill is used for header fill in these types
// This fill property is just background of rows
out += fmt.Sprintf(`fill:%s;`, s.Stroke)
// Stroke (border) of these shapes should match the header fill
out += fmt.Sprintf(`stroke:%s;`, s.Fill)
} else {
out += fmt.Sprintf(`fill:%s;`, s.Fill)
out += fmt.Sprintf(`stroke:%s;`, s.Stroke)
}
out += fmt.Sprintf(`opacity:%f;`, s.Opacity)
out += fmt.Sprintf(`stroke-width:%d;`, s.StrokeWidth)
if s.StrokeDash != 0 {
dashSize, gapSize := svg.GetStrokeDashAttributes(float64(s.StrokeWidth), s.StrokeDash)
out += fmt.Sprintf(`stroke-dasharray:%f,%f;`, dashSize, gapSize)
}
return out
}
func (s *Shape) SetType(t string) {
// Some types are synonyms of other types, but with hinting for autolayout
// They should only have one representation in the final export
@ -251,6 +275,32 @@ func BaseConnection() *Connection {
}
}
func (c Connection) CSSStyle() string {
out := ""
out += fmt.Sprintf(`stroke:%s;`, c.Stroke)
out += fmt.Sprintf(`opacity:%f;`, c.Opacity)
out += fmt.Sprintf(`stroke-width:%d;`, c.StrokeWidth)
strokeDash := c.StrokeDash
if strokeDash == 0 && c.Animated {
strokeDash = 5
}
if strokeDash != 0 {
dashSize, gapSize := svg.GetStrokeDashAttributes(float64(c.StrokeWidth), strokeDash)
out += fmt.Sprintf(`stroke-dasharray:%f,%f;`, dashSize, gapSize)
if c.Animated {
dashOffset := -10
if c.SrcArrow != NoArrowhead && c.DstArrow == NoArrowhead {
dashOffset = 10
}
out += fmt.Sprintf(`stroke-dashoffset:%f;`, float64(dashOffset)*(dashSize+gapSize))
out += fmt.Sprintf(`animation: dashdraw %fs linear infinite;`, gapSize*0.5)
}
}
return out
}
func (c *Connection) GetLabelTopLeft() *geo.Point {
return label.Position(c.LabelPosition).GetPointOnRoute(
c.Route,

View file

@ -308,6 +308,59 @@ k8s -> osvc: vault
name: "no-lexer",
script: `x: |d2
x -> y
|
`,
},
{
name: "dagre_broken_arrowhead",
script: `
a.b -> a.c: "line 1\nline 2\nline 3\nline 4" {
style: {
font-color: red
stroke: red
}
target-arrowhead: {
shape: diamond
}
}
a.1 -> a.c
a.2 <-> a.c
a.c {
style.stroke: white
d
}
`,
},
{
name: "code_leading_trailing_newlines",
script: `
hello world: |python
# 2 leading, 2 trailing
def hello():
print "world"
|
no trailing: |python
# 2 leading
def hello():
print "world"
|
no leading: |python
# 2 trailing
def hello():
print "world"
|
`,
},

View file

@ -1764,6 +1764,59 @@ e <--> f: {
}
}`,
},
{
name: "animated",
script: `
your love life will be -> happy: { style.animated: true }
your love life will be -> harmonious: { style.animated: true }
boredom <- immortality: { style.animated: true }
Friday <-> Monday: { style.animated: true }
Insomnia -- Sleep: { style.animated: true }
Insomnia -- Wake: {
style: {
animated: true
stroke-width: 2
}
}
Insomnia -- Dream: {
style: {
animated: true
stroke-width: 8
}
}
Listen <-> Talk: {
style.animated: true
source-arrowhead.shape: cf-one
target-arrowhead.shape: diamond
label: hear
}
`,
},
{
name: "sql_table_tooltip_animated",
script: `
x: {
shape: sql_table
y
tooltip: I like turtles
}
a: {
shape: sql_table
b
}
x.y -> a.b: {
style.animated: true
target-arrowhead.shape: cf-many
}
`,
},
}
runa(t, tcs)

View file

@ -0,0 +1,124 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "hello world",
"type": "code",
"pos": {
"x": 0,
"y": 0
},
"width": 239,
"height": 150,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "\n\n# 2 leading, 2 trailing\ndef hello():\n\n print \"world\"\n\n",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "python",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 239,
"labelHeight": 150,
"zIndex": 0,
"level": 1
},
{
"id": "no trailing",
"type": "code",
"pos": {
"x": 299,
"y": 16
},
"width": 160,
"height": 118,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "\n\n# 2 leading\ndef hello():\n\n print \"world\"",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "python",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 160,
"labelHeight": 118,
"zIndex": 0,
"level": 1
},
{
"id": "no leading",
"type": "code",
"pos": {
"x": 519,
"y": 16
},
"width": 160,
"height": 118,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "# 2 trailing\ndef hello():\n\n print \"world\"\n\n",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "python",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 160,
"labelHeight": 118,
"zIndex": 0,
"level": 1
}
],
"connections": []
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 185 KiB

View file

@ -0,0 +1,124 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "hello world",
"type": "code",
"pos": {
"x": 12,
"y": 12
},
"width": 239,
"height": 150,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "\n\n# 2 leading, 2 trailing\ndef hello():\n\n print \"world\"\n\n",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "python",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 239,
"labelHeight": 150,
"zIndex": 0,
"level": 1
},
{
"id": "no trailing",
"type": "code",
"pos": {
"x": 271,
"y": 28
},
"width": 160,
"height": 118,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "\n\n# 2 leading\ndef hello():\n\n print \"world\"",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "python",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 160,
"labelHeight": 118,
"zIndex": 0,
"level": 1
},
{
"id": "no leading",
"type": "code",
"pos": {
"x": 451,
"y": 28
},
"width": 160,
"height": 118,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "# 2 trailing\ndef hello():\n\n print \"world\"\n\n",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "python",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 160,
"labelHeight": 118,
"zIndex": 0,
"level": 1
}
],
"connections": []
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 185 KiB

View file

@ -0,0 +1,392 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "a",
"type": "",
"pos": {
"x": 0,
"y": 0
},
"width": 571,
"height": 648,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#E3E9FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "a",
"fontSize": 28,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 17,
"labelHeight": 41,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "a.c",
"type": "",
"pos": {
"x": 40,
"y": 359
},
"width": 478,
"height": 235,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "white",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "c",
"fontSize": 24,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 15,
"labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "a.c.d",
"type": "",
"pos": {
"x": 236,
"y": 413
},
"width": 114,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "d",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 14,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 3
},
{
"id": "a.b",
"type": "",
"pos": {
"x": 64,
"y": 55
},
"width": 113,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "b",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 13,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "a.1",
"type": "",
"pos": {
"x": 237,
"y": 55
},
"width": 112,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "1",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 12,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "a.2",
"type": "",
"pos": {
"x": 409,
"y": 55
},
"width": 113,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "2",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 13,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
}
],
"connections": [
{
"id": "a.(b -> c)[0]",
"src": "a.b",
"srcArrow": "none",
"srcLabel": "",
"dst": "a.c",
"dstArrow": "diamond",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "red",
"label": "line 1\nline 2\nline 3\nline 4",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "red",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 36,
"labelHeight": 69,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 120,
"y": 181.5
},
{
"x": 120,
"y": 251.9
},
{
"x": 120,
"y": 287.5
},
{
"x": 120,
"y": 359.5
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "a.(1 -> c)[0]",
"src": "a.1",
"srcArrow": "none",
"srcLabel": "",
"dst": "a.c",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 292.5,
"y": 181.5
},
{
"x": 292.5,
"y": 251.9
},
{
"x": 292.5,
"y": 287.5
},
{
"x": 292.5,
"y": 359.5
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "a.(2 <-> c)[0]",
"src": "a.2",
"srcArrow": "triangle",
"srcLabel": "",
"dst": "a.c",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 465,
"y": 181.5
},
{
"x": 465,
"y": 251.9
},
{
"x": 465,
"y": 287.5
},
{
"x": 465,
"y": 359.5
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
}
]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 794 KiB

View file

@ -0,0 +1,381 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "a",
"type": "",
"pos": {
"x": 12,
"y": 12
},
"width": 490,
"height": 878,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#E3E9FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "a",
"fontSize": 28,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 17,
"labelHeight": 41,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "a.c",
"type": "",
"pos": {
"x": 106,
"y": 539
},
"width": 264,
"height": 276,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "white",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "c",
"fontSize": 24,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 15,
"labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "a.c.d",
"type": "",
"pos": {
"x": 181,
"y": 614
},
"width": 114,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "d",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 14,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 3
},
{
"id": "a.b",
"type": "",
"pos": {
"x": 87,
"y": 87
},
"width": 113,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "b",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 13,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "a.1",
"type": "",
"pos": {
"x": 182,
"y": 313
},
"width": 112,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "1",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 12,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "a.2",
"type": "",
"pos": {
"x": 314,
"y": 313
},
"width": 113,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "2",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 13,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
}
],
"connections": [
{
"id": "a.(b -> c)[0]",
"src": "a.b",
"srcArrow": "none",
"srcLabel": "",
"dst": "a.c",
"dstArrow": "diamond",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "red",
"label": "line 1\nline 2\nline 3\nline 4",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "red",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 36,
"labelHeight": 69,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 143.5,
"y": 213
},
{
"x": 143.5,
"y": 489
},
{
"x": 172.5,
"y": 489
},
{
"x": 172.5,
"y": 539
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "a.(1 -> c)[0]",
"src": "a.1",
"srcArrow": "none",
"srcLabel": "",
"dst": "a.c",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 238.5,
"y": 439
},
{
"x": 238.5,
"y": 539
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "a.(2 <-> c)[0]",
"src": "a.2",
"srcArrow": "triangle",
"srcLabel": "",
"dst": "a.c",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 371,
"y": 439
},
{
"x": 371,
"y": 489
},
{
"x": 304.5,
"y": 489
},
{
"x": 304.5,
"y": 539
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
}
]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 795 KiB

912
e2etests/testdata/stable/animated/dagre/board.exp.json generated vendored Normal file
View file

@ -0,0 +1,912 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "your love life will be",
"type": "",
"pos": {
"x": 58,
"y": 0
},
"width": 247,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "your love life will be",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 147,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "happy",
"type": "",
"pos": {
"x": 0,
"y": 247
},
"width": 149,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "happy",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 49,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "harmonious",
"type": "",
"pos": {
"x": 209,
"y": 247
},
"width": 190,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "harmonious",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 90,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "boredom",
"type": "",
"pos": {
"x": 471,
"y": 247
},
"width": 168,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "boredom",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 68,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "immortality",
"type": "",
"pos": {
"x": 460,
"y": 0
},
"width": 191,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "immortality",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 91,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Friday",
"type": "",
"pos": {
"x": 711,
"y": 0
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Friday",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 50,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Monday",
"type": "",
"pos": {
"x": 705,
"y": 247
},
"width": 161,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Monday",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 61,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Insomnia",
"type": "",
"pos": {
"x": 1126,
"y": 0
},
"width": 170,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Insomnia",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 70,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Sleep",
"type": "",
"pos": {
"x": 930,
"y": 247
},
"width": 145,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Sleep",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 45,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Wake",
"type": "",
"pos": {
"x": 1135,
"y": 247
},
"width": 144,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Wake",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 44,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Dream",
"type": "",
"pos": {
"x": 1339,
"y": 247
},
"width": 151,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Dream",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 51,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Listen",
"type": "",
"pos": {
"x": 1552,
"y": 0
},
"width": 148,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Listen",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 48,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Talk",
"type": "",
"pos": {
"x": 1558,
"y": 247
},
"width": 136,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Talk",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 36,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
}
],
"connections": [
{
"id": "(your love life will be -> happy)[0]",
"src": "your love life will be",
"srcArrow": "none",
"srcLabel": "",
"dst": "happy",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 126.917004048583,
"y": 126
},
{
"x": 84.9834008097166,
"y": 174.4
},
{
"x": 74.5,
"y": 198.7
},
{
"x": 74.5,
"y": 247.5
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(your love life will be -> harmonious)[0]",
"src": "your love life will be",
"srcArrow": "none",
"srcLabel": "",
"dst": "harmonious",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 243.98987854251013,
"y": 126
},
{
"x": 291.99797570850205,
"y": 174.4
},
{
"x": 304,
"y": 198.7
},
{
"x": 304,
"y": 247.5
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(boredom <- immortality)[0]",
"src": "boredom",
"srcArrow": "triangle",
"srcLabel": "",
"dst": "immortality",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 555.25,
"y": 247
},
{
"x": 555.25,
"y": 198.6
},
{
"x": 555.25,
"y": 174.3
},
{
"x": 555.25,
"y": 125.5
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Friday <-> Monday)[0]",
"src": "Friday",
"srcArrow": "triangle",
"srcLabel": "",
"dst": "Monday",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 785.75,
"y": 126
},
{
"x": 785.75,
"y": 174.4
},
{
"x": 785.75,
"y": 198.7
},
{
"x": 785.75,
"y": 247.5
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Insomnia -- Sleep)[0]",
"src": "Insomnia",
"srcArrow": "none",
"srcLabel": "",
"dst": "Sleep",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 1126,
"y": 113.2874251497006
},
{
"x": 1027,
"y": 171.8574850299401
},
{
"x": 1002.25,
"y": 198.7
},
{
"x": 1002.25,
"y": 247.5
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Insomnia -- Wake)[0]",
"src": "Insomnia",
"srcArrow": "none",
"srcLabel": "",
"dst": "Wake",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 1208.831983805668,
"y": 126
},
{
"x": 1207.1663967611337,
"y": 174.4
},
{
"x": 1206.75,
"y": 198.7
},
{
"x": 1206.75,
"y": 247.5
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Insomnia -- Dream)[0]",
"src": "Insomnia",
"srcArrow": "none",
"srcLabel": "",
"dst": "Dream",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 8,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 1296,
"y": 114.64821648216483
},
{
"x": 1390.6,
"y": 172.12964329643296
},
{
"x": 1414.25,
"y": 198.7
},
{
"x": 1414.25,
"y": 247.5
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Listen <-> Talk)[0]",
"src": "Listen",
"srcArrow": "cf-one",
"srcLabel": "",
"dst": "Talk",
"dstArrow": "diamond",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "hear",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 32,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 1625.5,
"y": 126
},
{
"x": 1625.5,
"y": 174.4
},
{
"x": 1625.5,
"y": 198.7
},
{
"x": 1625.5,
"y": 247.5
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
}
]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 476 KiB

864
e2etests/testdata/stable/animated/elk/board.exp.json generated vendored Normal file
View file

@ -0,0 +1,864 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "your love life will be",
"type": "",
"pos": {
"x": 111,
"y": 12
},
"width": 247,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "your love life will be",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 147,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "happy",
"type": "",
"pos": {
"x": 12,
"y": 238
},
"width": 149,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "happy",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 49,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "harmonious",
"type": "",
"pos": {
"x": 181,
"y": 238
},
"width": 190,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "harmonious",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 90,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "boredom",
"type": "",
"pos": {
"x": 402,
"y": 12
},
"width": 168,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "boredom",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 68,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "immortality",
"type": "",
"pos": {
"x": 391,
"y": 238
},
"width": 191,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "immortality",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 91,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Friday",
"type": "",
"pos": {
"x": 607,
"y": 12
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Friday",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 50,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Monday",
"type": "",
"pos": {
"x": 602,
"y": 238
},
"width": 161,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Monday",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 61,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Insomnia",
"type": "",
"pos": {
"x": 935,
"y": 12
},
"width": 170,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Insomnia",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 70,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Sleep",
"type": "",
"pos": {
"x": 783,
"y": 238
},
"width": 145,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Sleep",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 45,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Wake",
"type": "",
"pos": {
"x": 948,
"y": 238
},
"width": 144,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Wake",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 44,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Dream",
"type": "",
"pos": {
"x": 1112,
"y": 238
},
"width": 151,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Dream",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 51,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Listen",
"type": "",
"pos": {
"x": 1225,
"y": 12
},
"width": 148,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Listen",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 48,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Talk",
"type": "",
"pos": {
"x": 1231,
"y": 464
},
"width": 136,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Talk",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 36,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
}
],
"connections": [
{
"id": "(your love life will be -> happy)[0]",
"src": "your love life will be",
"srcArrow": "none",
"srcLabel": "",
"dst": "happy",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 193.66666666666652,
"y": 138
},
{
"x": 193.66666666666652,
"y": 188
},
{
"x": 86.5,
"y": 188
},
{
"x": 86.5,
"y": 238
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(your love life will be -> harmonious)[0]",
"src": "your love life will be",
"srcArrow": "none",
"srcLabel": "",
"dst": "harmonious",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 275.9999999999999,
"y": 138
},
{
"x": 276,
"y": 238
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(boredom <- immortality)[0]",
"src": "boredom",
"srcArrow": "triangle",
"srcLabel": "",
"dst": "immortality",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 486.5,
"y": 138
},
{
"x": 486.5,
"y": 238
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Friday <-> Monday)[0]",
"src": "Friday",
"srcArrow": "triangle",
"srcLabel": "",
"dst": "Monday",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 682.5,
"y": 138
},
{
"x": 682.5,
"y": 238
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Insomnia -- Sleep)[0]",
"src": "Insomnia",
"srcArrow": "none",
"srcLabel": "",
"dst": "Sleep",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 977.5,
"y": 138
},
{
"x": 977.5,
"y": 188
},
{
"x": 855.5,
"y": 188
},
{
"x": 855.5,
"y": 238
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Insomnia -- Wake)[0]",
"src": "Insomnia",
"srcArrow": "none",
"srcLabel": "",
"dst": "Wake",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 1020,
"y": 138
},
{
"x": 1020,
"y": 238
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Insomnia -- Dream)[0]",
"src": "Insomnia",
"srcArrow": "none",
"srcLabel": "",
"dst": "Dream",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 8,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 1062.5,
"y": 138
},
{
"x": 1062.5,
"y": 188
},
{
"x": 1187.5,
"y": 188
},
{
"x": 1187.5,
"y": 238
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(Listen <-> Talk)[0]",
"src": "Listen",
"srcArrow": "cf-one",
"srcLabel": "",
"dst": "Talk",
"dstArrow": "diamond",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "hear",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 32,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 1299,
"y": 138
},
{
"x": 1299,
"y": 464
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
}
]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 476 KiB

View file

@ -822,20 +822,11 @@
"x": 925,
"y": 745.597137014315
},
{
"x": 847.4,
"y": 758.3971370143149
},
{
"x": 905.6,
"y": 748.797137014315
},
{
"x": 828,
"y": 761.597137014315
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
@ -978,20 +969,11 @@
"x": 912,
"y": 522
},
{
"x": 845,
"y": 533.8777110844337
},
{
"x": 895.25,
"y": 524.9694277711085
},
{
"x": 828.25,
"y": 536.8471388555422
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 812 KiB

After

Width:  |  Height:  |  Size: 812 KiB

View file

@ -361,20 +361,11 @@
"x": 243.66666666666669,
"y": 238
},
{
"x": 243.93333333333334,
"y": 237.99628770301624
},
{
"x": 243.73333333333335,
"y": 237.99907192575407
},
{
"x": 244,
"y": 237.9953596287703
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,

View file

@ -39,7 +39,7 @@ width="698" height="630" viewBox="-102 -102 698 630"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16);
}
});
]]></script><g id="a"><g class="shape" ><rect x="0" y="0" width="494" height="426" style="fill:#E3E9FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="247.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">a</text></g><g id="a.b"><g class="shape" ><rect x="40" y="50" width="414" height="326" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="247.000000" y="79.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">b</text></g><g id="a.b.c"><g class="shape" ><rect x="80" y="100" width="334" height="226" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="247.000000" y="125.000000" style="text-anchor:middle;font-size:20px;fill:#0A0F25">c</text></g><g id="a.b.c.d"><g class="shape" ><rect x="130" y="150" width="114" height="126" style="fill:#FFFFFF;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="187.000000" y="216.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="(a.b -&gt; a)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 245.640452 172.103153 C 270.666667 154.649446 279.000000 150.000000 281.500000 150.000000 C 284.000000 150.000000 287.333333 162.600000 289.833333 181.500000 C 292.333333 200.400000 292.333333 225.600000 289.833333 244.500000 C 287.333333 263.400000 270.666667 271.350554 247.280904 255.040926" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3168013246)"/></g><g id="a.(b -&gt; b.c)[0]"><path d="M 245.760942 181.359493 C 292.000000 156.461538 307.000000 150.000000 311.500000 150.000000 C 316.000000 150.000000 322.000000 162.600000 326.500000 181.500000 C 331.000000 200.400000 331.000000 225.600000 326.500000 244.500000 C 322.000000 263.400000 292.000000 269.538462 247.521884 245.588707" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3168013246)"/></g><g id="a.(b.c.d -&gt; b)[0]"><path d="M 245.666473 237.972160 C 243.933333 237.996288 243.733333 237.999072 240.000388 238.051039" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3168013246)"/></g><mask id="3168013246" maskUnits="userSpaceOnUse" x="-100" y="-100" width="698" height="630">
]]></script><g id="a"><g class="shape" ><rect x="0" y="0" width="494" height="426" style="fill:#E3E9FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="247.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">a</text></g><g id="a.b"><g class="shape" ><rect x="40" y="50" width="414" height="326" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="247.000000" y="79.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">b</text></g><g id="a.b.c"><g class="shape" ><rect x="80" y="100" width="334" height="226" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="247.000000" y="125.000000" style="text-anchor:middle;font-size:20px;fill:#0A0F25">c</text></g><g id="a.b.c.d"><g class="shape" ><rect x="130" y="150" width="114" height="126" style="fill:#FFFFFF;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="187.000000" y="216.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="(a.b -&gt; a)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 245.640452 172.103153 C 270.666667 154.649446 279.000000 150.000000 281.500000 150.000000 C 284.000000 150.000000 287.333333 162.600000 289.833333 181.500000 C 292.333333 200.400000 292.333333 225.600000 289.833333 244.500000 C 287.333333 263.400000 270.666667 271.350554 247.280904 255.040926" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4293364358)"/></g><g id="a.(b -&gt; b.c)[0]"><path d="M 245.760942 181.359493 C 292.000000 156.461538 307.000000 150.000000 311.500000 150.000000 C 316.000000 150.000000 322.000000 162.600000 326.500000 181.500000 C 331.000000 200.400000 331.000000 225.600000 326.500000 244.500000 C 322.000000 263.400000 292.000000 269.538462 247.521884 245.588707" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4293364358)"/></g><g id="a.(b.c.d -&gt; b)[0]"><path d="M 245.666473 237.972160 L 240.000388 238.051039" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4293364358)"/></g><mask id="4293364358" maskUnits="userSpaceOnUse" x="-100" y="-100" width="698" height="630">
<rect x="-100" y="-100" width="698" height="630" fill="white"></rect>
</mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 650 KiB

After

Width:  |  Height:  |  Size: 650 KiB

View file

@ -605,20 +605,11 @@
"x": 332.5,
"y": 598
},
{
"x": 268.5,
"y": 621.2
},
{
"x": 316.5,
"y": 603.8
},
{
"x": 252.5,
"y": 627
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,

View file

@ -39,7 +39,7 @@ width="790" height="1534" viewBox="-102 -102 790 1534"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16);
}
});
]]></script><g id="a"><g class="shape" ><rect x="416" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="472.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="g"><g class="shape" ><rect x="333" y="226" width="253" height="878" style="fill:#E3E9FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="459.500000" y="259.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">g</text></g><g id="d"><g class="shape" ><rect x="0" y="502" width="293" height="326" style="fill:#E3E9FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="146.500000" y="535.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">d</text></g><g id="f"><g class="shape" ><rect x="404" y="1204" width="111" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="459.500000" y="1270.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">f</text></g><g id="g.b"><g class="shape" ><rect x="416" y="276" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="472.500000" y="342.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="d.h"><g class="shape" ><rect x="40" y="552" width="213" height="226" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="146.500000" y="581.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">h</text></g><g id="g.e"><g class="shape" ><rect x="383" y="928" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="439.500000" y="994.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">e</text></g><g id="d.h.c"><g class="shape" ><rect x="90" y="602" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="146.500000" y="668.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">c</text></g><g id="(a -&gt; g.b)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 472.750000 128.000000 C 472.750000 166.000000 472.750000 236.000000 472.750000 272.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3377918310)"/></g><g id="(g.b -&gt; d.h.c)[0]"><path d="M 434.660405 403.723672 C 412.134956 442.000000 406.250000 462.000000 406.250000 477.000000 C 406.250000 492.000000 365.650000 569.600000 206.920003 638.409063" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3377918310)"/></g><g id="(d -&gt; g.e)[0]"><path d="M 148.471500 828.336433 C 380.900000 868.000000 439.500000 888.000000 439.500000 924.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3377918310)"/></g><g id="(g.e -&gt; f)[0]"><path d="M 439.500000 1056.000000 C 439.500000 1094.000000 441.300000 1164.000000 447.791388 1200.063267" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3377918310)"/></g><g id="(f -&gt; g)[0]"><path d="M 508.941346 1202.411883 C 538.345133 1164.000000 546.000000 1144.000000 546.000000 1108.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3377918310)"/></g><g id="(g -&gt; d.h)[0]"><path d="M 330.619728 598.681599 C 268.500000 621.200000 316.500000 603.800000 256.260544 625.636803" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3377918310)"/></g><mask id="3377918310" maskUnits="userSpaceOnUse" x="-100" y="-100" width="790" height="1534">
]]></script><g id="a"><g class="shape" ><rect x="416" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="472.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="g"><g class="shape" ><rect x="333" y="226" width="253" height="878" style="fill:#E3E9FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="459.500000" y="259.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">g</text></g><g id="d"><g class="shape" ><rect x="0" y="502" width="293" height="326" style="fill:#E3E9FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="146.500000" y="535.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">d</text></g><g id="f"><g class="shape" ><rect x="404" y="1204" width="111" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="459.500000" y="1270.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">f</text></g><g id="g.b"><g class="shape" ><rect x="416" y="276" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="472.500000" y="342.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="d.h"><g class="shape" ><rect x="40" y="552" width="213" height="226" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text" x="146.500000" y="581.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">h</text></g><g id="g.e"><g class="shape" ><rect x="383" y="928" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="439.500000" y="994.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">e</text></g><g id="d.h.c"><g class="shape" ><rect x="90" y="602" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="146.500000" y="668.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">c</text></g><g id="(a -&gt; g.b)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 472.750000 128.000000 C 472.750000 166.000000 472.750000 236.000000 472.750000 272.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3062149661)"/></g><g id="(g.b -&gt; d.h.c)[0]"><path d="M 434.660405 403.723672 C 412.134956 442.000000 406.250000 462.000000 406.250000 477.000000 C 406.250000 492.000000 365.650000 569.600000 206.920003 638.409063" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3062149661)"/></g><g id="(d -&gt; g.e)[0]"><path d="M 148.471500 828.336433 C 380.900000 868.000000 439.500000 888.000000 439.500000 924.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3062149661)"/></g><g id="(g.e -&gt; f)[0]"><path d="M 439.500000 1056.000000 C 439.500000 1094.000000 441.300000 1164.000000 447.791388 1200.063267" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3062149661)"/></g><g id="(f -&gt; g)[0]"><path d="M 508.941346 1202.411883 C 538.345133 1164.000000 546.000000 1144.000000 546.000000 1108.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3062149661)"/></g><g id="(g -&gt; d.h)[0]"><path d="M 330.619728 598.681599 L 256.260544 625.636803" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3062149661)"/></g><mask id="3062149661" maskUnits="userSpaceOnUse" x="-100" y="-100" width="790" height="1534">
<rect x="-100" y="-100" width="790" height="1534" fill="white"></rect>
</mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 652 KiB

After

Width:  |  Height:  |  Size: 652 KiB

View file

@ -1393,20 +1393,11 @@
"x": 213,
"y": 488
},
{
"x": 173,
"y": 511.2
},
{
"x": 203,
"y": 493.8
},
{
"x": 163,
"y": 517
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
@ -1537,20 +1528,11 @@
"x": 679,
"y": 511
},
{
"x": 887,
"y": 544.6
},
{
"x": 731,
"y": 519.4
},
{
"x": 939,
"y": 553
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 659 KiB

After

Width:  |  Height:  |  Size: 659 KiB

View file

@ -633,20 +633,11 @@
"x": 113,
"y": 139.60208333333333
},
{
"x": 153,
"y": 158.80208333333331
},
{
"x": 123,
"y": 144.40208333333334
},
{
"x": 163,
"y": 163.60208333333333
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
@ -681,20 +672,11 @@
"x": 657,
"y": 583
},
{
"x": 697.6,
"y": 594.9524382097528
},
{
"x": 667.15,
"y": 585.9881095524382
},
{
"x": 707.75,
"y": 597.940547762191
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
@ -873,20 +855,11 @@
"x": 443,
"y": 555
},
{
"x": 483.6,
"y": 577.4938826466916
},
{
"x": 453.15,
"y": 560.6234706616729
},
{
"x": 493.75,
"y": 583.1173533083645
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 655 KiB

After

Width:  |  Height:  |  Size: 655 KiB

View file

@ -0,0 +1,198 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "x",
"type": "sql_table",
"pos": {
"x": 0,
"y": 0
},
"width": 60,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#0A0F25",
"stroke": "#FFFFFF",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "I like turtles",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": [
{
"name": {
"label": "y",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 10,
"labelHeight": 26
},
"type": {
"label": "",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0
},
"constraint": "",
"reference": "a.b"
}
],
"label": "x",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 17,
"labelHeight": 36,
"zIndex": 0,
"level": 1,
"primaryAccentColor": "#0D32B2",
"secondaryAccentColor": "#4A6FF3",
"neutralAccentColor": "#676C7E"
},
{
"id": "a",
"type": "sql_table",
"pos": {
"x": 0,
"y": 172
},
"width": 60,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#0A0F25",
"stroke": "#FFFFFF",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": [
{
"name": {
"label": "b",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 10,
"labelHeight": 26
},
"type": {
"label": "",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0
},
"constraint": "",
"reference": ""
}
],
"label": "a",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 16,
"labelHeight": 36,
"zIndex": 0,
"level": 1,
"primaryAccentColor": "#0D32B2",
"secondaryAccentColor": "#4A6FF3",
"neutralAccentColor": "#676C7E"
}
],
"connections": [
{
"id": "(x -> a)[0]",
"src": "x",
"srcArrow": "none",
"srcLabel": "",
"dst": "a",
"dstArrow": "cf-many",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 30,
"y": 72
},
{
"x": 30,
"y": 112
},
{
"x": 30,
"y": 132
},
{
"x": 30,
"y": 172
}
],
"isCurve": true,
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
}
]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 329 KiB

View file

@ -0,0 +1,189 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "x",
"type": "sql_table",
"pos": {
"x": 12,
"y": 12
},
"width": 60,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#0A0F25",
"stroke": "#FFFFFF",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "I like turtles",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": [
{
"name": {
"label": "y",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 10,
"labelHeight": 26
},
"type": {
"label": "",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0
},
"constraint": "",
"reference": "a.b"
}
],
"label": "x",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 17,
"labelHeight": 36,
"zIndex": 0,
"level": 1,
"primaryAccentColor": "#0D32B2",
"secondaryAccentColor": "#4A6FF3",
"neutralAccentColor": "#676C7E"
},
{
"id": "a",
"type": "sql_table",
"pos": {
"x": 12,
"y": 184
},
"width": 60,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#0A0F25",
"stroke": "#FFFFFF",
"shadow": false,
"3d": false,
"multiple": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": [
{
"name": {
"label": "b",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 10,
"labelHeight": 26
},
"type": {
"label": "",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0
},
"constraint": "",
"reference": ""
}
],
"label": "a",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 16,
"labelHeight": 36,
"zIndex": 0,
"level": 1,
"primaryAccentColor": "#0D32B2",
"secondaryAccentColor": "#4A6FF3",
"neutralAccentColor": "#676C7E"
}
],
"connections": [
{
"id": "(x -> a)[0]",
"src": "x",
"srcArrow": "none",
"srcLabel": "",
"dst": "a",
"dstArrow": "cf-many",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 42,
"y": 84
},
{
"x": 42,
"y": 184
}
],
"animated": true,
"tooltip": "",
"icon": null,
"zIndex": 0
}
]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 329 KiB

View file

@ -187,12 +187,12 @@ func (p *Point) DistanceToLine(p1, p2 *Point) float64 {
// Moves the given point by Vector
func (start *Point) AddVector(v Vector) *Point {
return start.toVector().Add(v).ToPoint()
return start.ToVector().Add(v).ToPoint()
}
// Creates a Vector of the size between start and endpoint, pointing to endpoint
func (start *Point) VectorTo(endpoint *Point) Vector {
return endpoint.toVector().Minus(start.toVector())
return endpoint.ToVector().Minus(start.ToVector())
}
func (p *Point) FormattedCoordinates() string {
@ -205,7 +205,7 @@ func (q *Point) OnSegment(p, r *Point) bool {
}
// Creates a Vector pointing to point
func (endpoint *Point) toVector() Vector {
func (endpoint *Point) ToVector() Vector {
return []float64{endpoint.X, endpoint.Y}
}

View file

@ -29,7 +29,7 @@ func TestAddVector(t *testing.T) {
func TestToVector(t *testing.T) {
p := &Point{3.5, 6.7}
v := p.toVector()
v := p.ToVector()
if v[0] != p.X || v[1] != p.Y {
t.Fatalf("Expected Vector (%v) coordinates to match the point (%v)", p, v)

View file

@ -114,3 +114,11 @@ func (segment *Segment) GetBounds(segments []*Segment, buffer float64) (float64,
}
return floor, ceil
}
func (segment Segment) Length() float64 {
return EuclideanDistance(segment.Start.X, segment.Start.Y, segment.End.X, segment.End.Y)
}
func (segment Segment) ToVector() Vector {
return NewVector(segment.End.X-segment.Start.X, segment.End.Y-segment.Start.Y)
}

View file

@ -76,3 +76,15 @@ func GetUnitNormalVector(x1, y1, x2, y2 float64) (float64, float64) {
length := EuclideanDistance(x1, y1, x2, y2)
return normalX / length, normalY / length
}
func (a Vector) Radians() float64 {
return math.Atan2(a[1], a[0])
}
func (a Vector) Degrees() float64 {
return a.Radians() * 180 / math.Pi
}
func (a Vector) Reverse() Vector {
return a.Multiply(-1)
}

View file

@ -5,6 +5,7 @@ import (
"context"
"encoding/base64"
"fmt"
"html"
"io/ioutil"
"mime"
"net/http"
@ -66,7 +67,7 @@ func filterImageElements(imgs [][][]byte, isRemote bool) [][][]byte {
continue
}
u, err := url.Parse(href)
u, err := url.Parse(html.UnescapeString(href))
isRemoteImg := err == nil && strings.HasPrefix(u.Scheme, "http")
if isRemoteImg == isRemote {
@ -147,9 +148,9 @@ func worker(ctx context.Context, href []byte, isRemote bool) ([]byte, error) {
var mimeType string
var err error
if isRemote {
buf, mimeType, err = httpGet(ctx, string(href))
buf, mimeType, err = httpGet(ctx, html.UnescapeString(string(href)))
} else {
buf, err = os.ReadFile(string(href))
buf, err = os.ReadFile(html.UnescapeString(string(href)))
}
if err != nil {
return nil, err
@ -194,7 +195,7 @@ func httpGet(ctx context.Context, href string) ([]byte, string, error) {
func sniffMimeType(href, buf []byte, isRemote bool) string {
p := string(href)
if isRemote {
u, err := url.Parse(p)
u, err := url.Parse(html.UnescapeString(p))
if err != nil {
p = ""
} else {

View file

@ -0,0 +1,570 @@
{
"graph": {
"ast": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,0:0:0-11:0:99",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,0:0:0-3:1:29",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,0:0:0-0:1:1",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,0:0:0-0:1:1",
"value": [
{
"string": "x",
"raw_string": "x"
}
]
}
}
]
},
"primary": {},
"value": {
"map": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,0:3:3-3:0:28",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,1:2:7-1:18:23",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,1:2:7-1:7:12",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,1:2:7-1:7:12",
"value": [
{
"string": "shape",
"raw_string": "shape"
}
]
}
}
]
},
"primary": {},
"value": {
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,1:9:14-1:18:23",
"value": [
{
"string": "sql_table",
"raw_string": "sql_table"
}
]
}
}
}
},
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,2:2:26-2:3:27",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,2:2:26-2:3:27",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,2:2:26-2:3:27",
"value": [
{
"string": "y",
"raw_string": "y"
}
]
}
}
]
},
"primary": {},
"value": {}
}
}
]
}
}
}
},
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,4:0:30-7:1:59",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,4:0:30-4:1:31",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,4:0:30-4:1:31",
"value": [
{
"string": "a",
"raw_string": "a"
}
]
}
}
]
},
"primary": {},
"value": {
"map": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,4:3:33-7:0:58",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,5:2:37-5:18:53",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,5:2:37-5:7:42",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,5:2:37-5:7:42",
"value": [
{
"string": "shape",
"raw_string": "shape"
}
]
}
}
]
},
"primary": {},
"value": {
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,5:9:44-5:18:53",
"value": [
{
"string": "sql_table",
"raw_string": "sql_table"
}
]
}
}
}
},
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,6:2:56-6:3:57",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,6:2:56-6:3:57",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,6:2:56-6:3:57",
"value": [
{
"string": "b",
"raw_string": "b"
}
]
}
}
]
},
"primary": {},
"value": {}
}
}
]
}
}
}
},
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:0:60-10:1:98",
"edges": [
{
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:0:60-8:10:70",
"src": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:0:60-8:4:64",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:0:60-8:1:61",
"value": [
{
"string": "x",
"raw_string": "x"
}
]
}
},
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:2:62-8:3:63",
"value": [
{
"string": "y",
"raw_string": "y"
}
]
}
}
]
},
"src_arrow": "",
"dst": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:6:66-8:10:70",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:7:67-8:8:68",
"value": [
{
"string": "a",
"raw_string": "a"
}
]
}
},
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:9:69-8:10:70",
"value": [
{
"string": "b",
"raw_string": "b"
}
]
}
}
]
},
"dst_arrow": ">"
}
],
"primary": {},
"value": {
"map": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:12:72-10:0:97",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,9:2:76-9:22:96",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,9:2:76-9:16:90",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,9:2:76-9:7:81",
"value": [
{
"string": "style",
"raw_string": "style"
}
]
}
},
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,9:8:82-9:16:90",
"value": [
{
"string": "animated",
"raw_string": "animated"
}
]
}
}
]
},
"primary": {},
"value": {
"boolean": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,9:18:92-9:22:96",
"value": true
}
}
}
}
]
}
}
}
}
]
},
"root": {
"id": "",
"id_val": "",
"label_dimensions": {
"width": 0,
"height": 0
},
"attributes": {
"label": {
"value": ""
},
"style": {},
"near_key": null,
"shape": {
"value": ""
},
"direction": {
"value": ""
}
},
"zIndex": 0
},
"edges": [
{
"index": 0,
"minWidth": 0,
"minHeight": 0,
"srcTableColumnIndex": 0,
"dstTableColumnIndex": 0,
"label_dimensions": {
"width": 0,
"height": 0
},
"isCurve": false,
"src_arrow": false,
"dst_arrow": true,
"references": [
{
"map_key_edge_index": 0
}
],
"attributes": {
"label": {
"value": ""
},
"style": {
"animated": {
"value": "true"
}
},
"near_key": null,
"shape": {
"value": ""
},
"direction": {
"value": ""
}
},
"zIndex": 0
}
],
"objects": [
{
"id": "x",
"id_val": "x",
"label_dimensions": {
"width": 0,
"height": 0
},
"references": [
{
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,0:0:0-0:1:1",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,0:0:0-0:1:1",
"value": [
{
"string": "x",
"raw_string": "x"
}
]
}
}
]
},
"key_path_index": 0,
"map_key_edge_index": 0
},
{
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:0:60-8:4:64",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:0:60-8:1:61",
"value": [
{
"string": "x",
"raw_string": "x"
}
]
}
},
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:2:62-8:3:63",
"value": [
{
"string": "y",
"raw_string": "y"
}
]
}
}
]
},
"key_path_index": 0,
"map_key_edge_index": 0
}
],
"sql_table": {
"columns": [
{
"name": {
"label": "y",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0
},
"type": {
"label": "",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0
},
"constraint": "",
"reference": "a.b"
}
]
},
"attributes": {
"label": {
"value": "x"
},
"style": {},
"near_key": null,
"shape": {
"value": "sql_table"
},
"direction": {
"value": ""
}
},
"zIndex": 0
},
{
"id": "a",
"id_val": "a",
"label_dimensions": {
"width": 0,
"height": 0
},
"references": [
{
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,4:0:30-4:1:31",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,4:0:30-4:1:31",
"value": [
{
"string": "a",
"raw_string": "a"
}
]
}
}
]
},
"key_path_index": 0,
"map_key_edge_index": 0
},
{
"key": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:6:66-8:10:70",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:7:67-8:8:68",
"value": [
{
"string": "a",
"raw_string": "a"
}
]
}
},
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/table_connection_attr.d2,8:9:69-8:10:70",
"value": [
{
"string": "b",
"raw_string": "b"
}
]
}
}
]
},
"key_path_index": 0,
"map_key_edge_index": 0
}
],
"sql_table": {
"columns": [
{
"name": {
"label": "b",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0
},
"type": {
"label": "",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0
},
"constraint": "",
"reference": ""
}
]
},
"attributes": {
"label": {
"value": "a"
},
"style": {},
"near_key": null,
"shape": {
"value": "sql_table"
},
"direction": {
"value": ""
}
},
"zIndex": 0
}
]
},
"err": null
}