github.com/gopherd/gonum@v0.0.4/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 "github.com/gopherd/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  }