gonum.org/v1/gonum@v0.14.0/graph/formats/sigmajs/sigmajs.go (about) 1 // Copyright ©2018 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 sigmajs implements marshaling and unmarshaling of Sigma.js JSON documents. 6 // 7 // See http://sigmajs.org/ for Sigma.js documentation. 8 package sigmajs // import "gonum.org/v1/gonum/graph/formats/sigmajs" 9 10 import ( 11 "encoding/json" 12 "errors" 13 "fmt" 14 ) 15 16 // Graph is a Sigma.js graph. 17 type Graph struct { 18 Nodes []Node `json:"nodes"` 19 Edges []Edge `json:"edges"` 20 } 21 22 // Node is a Sigma.js node. 23 type Node struct { 24 ID string 25 Attributes map[string]interface{} 26 } 27 28 var ( 29 _ json.Marshaler = (*Node)(nil) 30 _ json.Unmarshaler = (*Node)(nil) 31 ) 32 33 // MarshalJSON implements the json.Marshaler interface. 34 func (n *Node) MarshalJSON() ([]byte, error) { 35 if n.Attributes == nil { 36 type node struct { 37 ID string `json:"id"` 38 } 39 return json.Marshal(node{ID: n.ID}) 40 } 41 n.Attributes["id"] = n.ID 42 b, err := json.Marshal(n.Attributes) 43 delete(n.Attributes, "id") 44 return b, err 45 } 46 47 // UnmarshalJSON implements the json.Unmarshaler interface. 48 func (n *Node) UnmarshalJSON(data []byte) error { 49 var attrs map[string]interface{} 50 err := json.Unmarshal(data, &attrs) 51 if err != nil { 52 return err 53 } 54 id, ok := attrs["id"] 55 if !ok { 56 return errors.New("sigmajs: no ID") 57 } 58 n.ID = fmt.Sprint(id) 59 delete(attrs, "id") 60 if len(attrs) != 0 { 61 n.Attributes = attrs 62 } 63 return nil 64 } 65 66 // Edge is a Sigma.js edge. 67 type Edge struct { 68 ID string 69 Source string 70 Target string 71 Attributes map[string]interface{} 72 } 73 74 var ( 75 _ json.Marshaler = (*Edge)(nil) 76 _ json.Unmarshaler = (*Edge)(nil) 77 ) 78 79 // MarshalJSON implements the json.Marshaler interface. 80 func (e *Edge) MarshalJSON() ([]byte, error) { 81 if e.Attributes == nil { 82 type edge struct { 83 ID string `json:"id"` 84 Source string `json:"source"` 85 Target string `json:"target"` 86 } 87 return json.Marshal(edge{ID: e.ID, Source: e.Source, Target: e.Target}) 88 } 89 e.Attributes["id"] = e.ID 90 e.Attributes["source"] = e.Source 91 e.Attributes["target"] = e.Target 92 b, err := json.Marshal(e.Attributes) 93 delete(e.Attributes, "id") 94 delete(e.Attributes, "source") 95 delete(e.Attributes, "target") 96 return b, err 97 } 98 99 // UnmarshalJSON implements the json.Unmarshaler interface. 100 func (e *Edge) UnmarshalJSON(data []byte) error { 101 var attrs map[string]interface{} 102 err := json.Unmarshal(data, &attrs) 103 if err != nil { 104 return err 105 } 106 id, ok := attrs["id"] 107 if !ok { 108 return errors.New("sigmajs: no ID") 109 } 110 source, ok := attrs["source"] 111 if !ok { 112 return errors.New("sigmajs: no source") 113 } 114 target, ok := attrs["target"] 115 if !ok { 116 return errors.New("sigmajs: no target") 117 } 118 e.ID = fmt.Sprint(id) 119 e.Source = fmt.Sprint(source) 120 e.Target = fmt.Sprint(target) 121 delete(attrs, "id") 122 delete(attrs, "source") 123 delete(attrs, "target") 124 if len(attrs) != 0 { 125 e.Attributes = attrs 126 } 127 return nil 128 }