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  }