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