File: sigmajs.go

package info (click to toggle)
golang-gonum-v1-gonum 0.15.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 18,792 kB
  • sloc: asm: 6,252; fortran: 5,271; sh: 377; ruby: 211; makefile: 98
file content (128 lines) | stat: -rw-r--r-- 2,915 bytes parent folder | download
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
}