gonum.org/v1/gonum@v0.14.0/graph/encoding/dot/weighted_example_test.go (about) 1 // Copyright ©2019 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package dot_test 6 7 import ( 8 "fmt" 9 "log" 10 "math" 11 "strconv" 12 13 "gonum.org/v1/gonum/graph" 14 "gonum.org/v1/gonum/graph/encoding" 15 "gonum.org/v1/gonum/graph/encoding/dot" 16 "gonum.org/v1/gonum/graph/simple" 17 ) 18 19 // dotGraph provides a shim for interaction between the DOT 20 // unmarshaler and a simple.WeightedUndirectedGraph. 21 type dotGraph struct { 22 *simple.WeightedUndirectedGraph 23 } 24 25 func newDotGraph() *dotGraph { 26 return &dotGraph{WeightedUndirectedGraph: simple.NewWeightedUndirectedGraph(0, 0)} 27 } 28 29 // NewEdge returns a DOT-aware edge. 30 func (g *dotGraph) NewEdge(from, to graph.Node) graph.Edge { 31 e := g.WeightedUndirectedGraph.NewWeightedEdge(from, to, math.NaN()).(simple.WeightedEdge) 32 return &weightedEdge{WeightedEdge: e} 33 } 34 35 // NewNode returns a DOT-aware node. 36 func (g *dotGraph) NewNode() graph.Node { 37 return &node{Node: g.WeightedUndirectedGraph.NewNode()} 38 } 39 40 // SetEdge is a shim to allow the DOT unmarshaler to 41 // add weighted edges to a graph. 42 func (g *dotGraph) SetEdge(e graph.Edge) { 43 g.WeightedUndirectedGraph.SetWeightedEdge(e.(*weightedEdge)) 44 } 45 46 // weightedEdge is a DOT-aware weighted edge. 47 type weightedEdge struct { 48 simple.WeightedEdge 49 } 50 51 // SetAttribute sets the weight of the receiver. 52 func (e *weightedEdge) SetAttribute(attr encoding.Attribute) error { 53 if attr.Key != "weight" { 54 return fmt.Errorf("unable to unmarshal node DOT attribute with key %q", attr.Key) 55 } 56 var err error 57 e.W, err = strconv.ParseFloat(attr.Value, 64) 58 return err 59 } 60 61 // node is a DOT-aware node. 62 type node struct { 63 graph.Node 64 dotID string 65 } 66 67 // SetDOTID sets the DOT ID of the node. 68 func (n *node) SetDOTID(id string) { n.dotID = id } 69 70 func (n *node) String() string { return n.dotID } 71 72 const ug = ` 73 graph { 74 a 75 b 76 c 77 a--b ["weight"=0.5] 78 a--c ["weight"=1] 79 } 80 ` 81 82 func ExampleUnmarshal_weighted() { 83 dst := newDotGraph() 84 err := dot.Unmarshal([]byte(ug), dst) 85 if err != nil { 86 log.Fatal(err) 87 } 88 for _, e := range graph.EdgesOf(dst.Edges()) { 89 fmt.Printf("%+v\n", e.(*weightedEdge).WeightedEdge) 90 } 91 92 // Unordered output: 93 // {F:a T:b W:0.5} 94 // {F:a T:c W:1} 95 }