diff --git a/graph.go b/graph.go new file mode 100644 index 0000000..a19250c --- /dev/null +++ b/graph.go @@ -0,0 +1,112 @@ +package main + +import ( + "encoding/json" + "os" + "path/filepath" + "strings" +) + +type graphBuilder struct { + refs Refs + nodeMap NodeMap + nodes []Node + edges []Edge +} + +type NodeMap map[string]int + +func NewGraphBuilder(mp PagesRepository) (*graphBuilder, error) { + refs := make(Refs) + + f, err := os.Open(filepath.Join(mp.(*FilePages).dirname, "backrefs.json")) + if err != nil { + return nil, err + } + + defer f.Close() + + err = json.NewDecoder(f).Decode(&refs) + if err != nil { + return nil, err + } + + nodeMap := prepareNodeMap(refs) + return &graphBuilder{ + refs: refs, + nodeMap: nodeMap, + nodes: nil, + edges: nil, + }, nil +} + +func (gb *graphBuilder) prepareGraph() error { + gb.nodes = prepareNodes(gb.nodeMap) + gb.edges = prepareEdges(gb.refs, gb.nodeMap) + return nil +} + +func (gb *graphBuilder) RemoveNode(name string) { + delete(gb.nodeMap, name) +} + +func (gb *graphBuilder) RemoveNodeWithSuffix(suffix string) { + for k, _ := range gb.nodeMap { + if strings.HasSuffix(k, suffix) { + delete(gb.nodeMap, k) + } + } +} + +func prepareEdges(refs Refs, nodeMap NodeMap) []Edge { + var edges []Edge + edgeSet := make(map[Edge]bool) + for key, references := range refs { + if toID, e := nodeMap[key]; e { + for _, item := range references { + if fromID, e := nodeMap[item.Name]; e { + edge := Edge{ + From: fromID, + To: toID, + } + if _, e := edgeSet[edge]; !e { + edgeSet[edge] = true + edges = append(edges, edge) + } + } + } + } + } + return edges +} + +func prepareNodes(nodeMap NodeMap) []Node { + var nodes []Node + for name, id := range nodeMap { + nodes = append(nodes, Node{ + Id: id, + Label: name, + }) + } + return nodes +} + +func prepareNodeMap(refs Refs) NodeMap { + nodeCount := 1 + nodeMap := make(NodeMap) + + for key, references := range refs { + if _, e := nodeMap[key]; !e { + nodeMap[key] = nodeCount + nodeCount += 1 + } + for _, item := range references { + if _, e := nodeMap[item.Name]; !e { + nodeMap[item.Name] = nodeCount + nodeCount += 1 + } + } + } + + return nodeMap +} diff --git a/main.go b/main.go index 7cef2c7..40dd5b4 100644 --- a/main.go +++ b/main.go @@ -114,7 +114,6 @@ type graphPage struct { Session *Session Title string Name string - References Refs Nodes template.JS Edges template.JS } @@ -478,17 +477,23 @@ func (h *graphHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - refs := make(Refs) - - f, err := os.Open(filepath.Join(mp.(*FilePages).dirname, "backrefs.json")) + gb, err := NewGraphBuilder(mp) if err != nil { http.Error(w, err.Error(), 500) return } - defer f.Close() + gb.RemoveNode("DONE") + gb.RemoveNode("TODO") + gb.RemoveNode("Home") + gb.RemoveNode("Projects") + gb.RemoveNode("Notes") + gb.RemoveNode("Books") + gb.RemoveNode("Daily_Notes") + gb.RemoveNode("NewJsonTest") + gb.RemoveNodeWithSuffix("_2020") - err = json.NewDecoder(f).Decode(&refs) + err = gb.prepareGraph() if err != nil { http.Error(w, err.Error(), 500) return @@ -497,85 +502,13 @@ func (h *graphHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { var nodesBuf bytes.Buffer var edgesBuf bytes.Buffer - var nodes []Node - var edges []Edge - - nodeCount := 1 - nodeMap := make(map[string]int) - - for key, references := range refs { - if strings.HasSuffix(key, "_2020") { - continue - } - if _, e := nodeMap[key]; !e { - nodeMap[key] = nodeCount - nodeCount += 1 - } - for _, item := range references { - if strings.HasSuffix(item.Name, "_2020") { - continue - } - if _, e := nodeMap[item.Name]; !e { - nodeMap[item.Name] = nodeCount - nodeCount += 1 - } - } - } - - delete(nodeMap, "DONE") - delete(nodeMap, "TODO") - delete(nodeMap, "Home") - delete(nodeMap, "Projects") - delete(nodeMap, "Notes") - delete(nodeMap, "Books") - delete(nodeMap, "Daily_Notes") - delete(nodeMap, "NewJsonTest") - - for name, id := range nodeMap { - nodes = append(nodes, Node{ - Id: id, - Label: name, - }) - } - - edgeSet := make(map[Edge]bool) - for key, references := range refs { - if key == "DONE" { - continue - } - if strings.HasSuffix(key, "_2020") { - continue - } - if toID, e := nodeMap[key]; e { - for _, item := range references { - if strings.HasSuffix(item.Name, "_2020") { - continue - } - if fromID, e := nodeMap[item.Name]; e { - if fromID == toID { - continue - } - edge := Edge{ - From: fromID, - To: toID, - } - - if _, e := edgeSet[edge]; !e { - edgeSet[edge] = true - edges = append(edges, edge) - } - } - } - } - } - - err = json.NewEncoder(&nodesBuf).Encode(&nodes) + err = json.NewEncoder(&nodesBuf).Encode(&gb.nodes) if err != nil { http.Error(w, err.Error(), 500) return } - err = json.NewEncoder(&edgesBuf).Encode(&edges) + err = json.NewEncoder(&edgesBuf).Encode(&gb.edges) if err != nil { http.Error(w, err.Error(), 500) return @@ -587,7 +520,6 @@ func (h *graphHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { Session: sess, Title: "Graph", Name: "Graph", - References: refs, Nodes: template.JS(nodesBuf.String()), Edges: template.JS(edgesBuf.String()), }