mirror of
https://github.com/gonum/gonum.git
synced 2025-10-06 07:37:03 +08:00
96 lines
2.2 KiB
Go
96 lines
2.2 KiB
Go
// Copyright ©2019 The Gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package dot_test
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"math"
|
|
"strconv"
|
|
|
|
"gonum.org/v1/gonum/graph"
|
|
"gonum.org/v1/gonum/graph/encoding"
|
|
"gonum.org/v1/gonum/graph/encoding/dot"
|
|
"gonum.org/v1/gonum/graph/simple"
|
|
)
|
|
|
|
// dotGraph provides a shim for interaction between the DOT
|
|
// unmarshaler and a simple.WeightedUndirectedGraph.
|
|
type dotGraph struct {
|
|
*simple.WeightedUndirectedGraph
|
|
}
|
|
|
|
func newDotGraph() *dotGraph {
|
|
return &dotGraph{WeightedUndirectedGraph: simple.NewWeightedUndirectedGraph(0, 0)}
|
|
}
|
|
|
|
// NewEdge returns a DOT-aware edge.
|
|
func (g *dotGraph) NewEdge(from, to graph.Node) graph.Edge {
|
|
e := g.WeightedUndirectedGraph.NewWeightedEdge(from, to, math.NaN()).(simple.WeightedEdge)
|
|
return &weightedEdge{WeightedEdge: e}
|
|
}
|
|
|
|
// NewNode returns a DOT-aware node.
|
|
func (g *dotGraph) NewNode() graph.Node {
|
|
return &node{Node: g.WeightedUndirectedGraph.NewNode()}
|
|
}
|
|
|
|
// SetEdge is a shim to allow the DOT unmarshaler to
|
|
// add weighted edges to a graph.
|
|
func (g *dotGraph) SetEdge(e graph.Edge) {
|
|
g.WeightedUndirectedGraph.SetWeightedEdge(e.(*weightedEdge))
|
|
}
|
|
|
|
// weightedEdge is a DOT-aware weighted edge.
|
|
type weightedEdge struct {
|
|
simple.WeightedEdge
|
|
}
|
|
|
|
// SetAttribute sets the weight of the receiver.
|
|
func (e *weightedEdge) SetAttribute(attr encoding.Attribute) error {
|
|
if attr.Key != "weight" {
|
|
return fmt.Errorf("unable to unmarshal node DOT attribute with key %q", attr.Key)
|
|
}
|
|
var err error
|
|
e.W, err = strconv.ParseFloat(attr.Value, 64)
|
|
return err
|
|
}
|
|
|
|
// node is a DOT-aware node.
|
|
type node struct {
|
|
graph.Node
|
|
dotID string
|
|
}
|
|
|
|
// SetDOTID sets the DOT ID of the node.
|
|
func (n *node) SetDOTID(id string) { n.dotID = id }
|
|
|
|
func (n *node) String() string { return n.dotID }
|
|
|
|
const ug = `
|
|
graph {
|
|
a
|
|
b
|
|
c
|
|
a--b ["weight"=0.5]
|
|
a--c ["weight"=1]
|
|
}
|
|
`
|
|
|
|
func ExampleUnmarshal_weighted() {
|
|
dst := newDotGraph()
|
|
err := dot.Unmarshal([]byte(ug), dst)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
for _, e := range graph.EdgesOf(dst.Edges()) {
|
|
fmt.Printf("%+v\n", e.(*weightedEdge).WeightedEdge)
|
|
}
|
|
|
|
// Unordered output:
|
|
// {F:a T:b W:0.5}
|
|
// {F:a T:c W:1}
|
|
}
|