diff --git a/graph.go b/graph.go index 6af2bd0..18c7720 100644 --- a/graph.go +++ b/graph.go @@ -1,8 +1,12 @@ package main import ( + "encoding/json" + "errors" + "io" "runtime" + "github.com/divan/graphx/graph" "github.com/gopherjs/vecty" ) @@ -37,3 +41,44 @@ func (p *Page) ApplyForces() { p.webgl.updatePositions() p.webgl.rt.Disable() } + +// GraphFromJSON is a custom version of graphx JSON importer, as we want to use +// some additional fields (Description). +// TODO(divan): that's probably can be done better within the limits of graphx library. +func GraphFromJSON(r io.Reader) (*graph.Graph, string, error) { + // decode into temporary struct to process + var res struct { + Description string `json:"description"` + Nodes []*graph.BasicNode `json:"nodes"` + Links []*struct { + Source string `json:"source"` + Target string `json:"target"` + } `json:"links"` + } + err := json.NewDecoder(r).Decode(&res) + if err != nil { + return nil, "", err + } + + if len(res.Nodes) == 0 { + return nil, "", errors.New("empty graph") + } + + // convert links IDs into indices + g := graph.NewGraphMN(len(res.Nodes), len(res.Links)) + + for _, node := range res.Nodes { + g.AddNode(node) + } + + for _, link := range res.Links { + err := g.AddLink(link.Source, link.Target) + if err != nil { + return nil, "", err + } + } + + g.UpdateCache() + + return g, res.Description, nil +} diff --git a/network.go b/network.go index 2aa8b2b..fcfc311 100644 --- a/network.go +++ b/network.go @@ -6,7 +6,6 @@ import ( "fmt" "io" - "github.com/divan/graphx/formats" "github.com/divan/graphx/graph" ) @@ -38,12 +37,11 @@ func LoadNetwork(file string) (*Network, error) { // LoadNetworkFromReader loads network information from the io.Reader. func LoadNetworkFromReader(r io.Reader) (*Network, error) { - g, err := formats.FromD3JSONReader(r) + g, desc, err := GraphFromJSON(r) if err != nil { return nil, fmt.Errorf("parse JSON: %v", err) } - desc := "TBD" return &Network{ Description: desc, Data: g, diff --git a/network_selector.go b/network_selector.go index 7a38dfd..cc15491 100644 --- a/network_selector.go +++ b/network_selector.go @@ -16,6 +16,7 @@ const DefaultNetwork = "grid25.json" // NetworkSelector represents widget for choosing or uploading network topology // to be used for visualization. +// TODO: move to widgets package type NetworkSelector struct { vecty.Core