mirror of
				https://github.com/gonum/gonum.git
				synced 2025-10-31 02:26:59 +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}
 | |
| }
 | 
