Peter Stuifzand
243c5df043
All checks were successful
continuous-integration/drone/push Build is passing
152 lines
2.8 KiB
Go
152 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
type graphBuilder struct {
|
|
refs Refs
|
|
nodeMap NodeMap
|
|
nodeCount int
|
|
nodes []Node
|
|
edges []Edge
|
|
}
|
|
|
|
type NodeMap map[string]Node
|
|
|
|
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
|
|
}
|
|
|
|
gb := &graphBuilder{
|
|
refs: refs,
|
|
nodeMap: make(NodeMap),
|
|
nodes: nil,
|
|
edges: nil,
|
|
}
|
|
gb.nodeMap["Daily_Notes"] = Node{Id: -1}
|
|
gb.nodeMap["TODO"] = Node{Id: -1}
|
|
gb.nodeMap["DONE"] = Node{Id: -1}
|
|
gb.nodeMap["Projects"] = Node{Id: -1}
|
|
return gb, nil
|
|
}
|
|
|
|
func (gb *graphBuilder) prepareGraph() error {
|
|
gb.nodes = prepareNodes(gb.nodeMap, func(node Node) Node {
|
|
if node.Id == 0 {
|
|
var green string
|
|
green = "#f57900"
|
|
node.Color = &green
|
|
}
|
|
return node
|
|
})
|
|
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 (gb *graphBuilder) buildFromCenter(name string) error {
|
|
id := gb.addNode(name, "#ef2929")
|
|
if id < 0 {
|
|
return nil
|
|
}
|
|
|
|
if ref, e := gb.refs[name]; e {
|
|
for _, item := range ref {
|
|
gb.addNode(item.Name, "#fce94f")
|
|
}
|
|
}
|
|
|
|
for key, references := range gb.refs {
|
|
for _, item := range references {
|
|
if name == item.Name {
|
|
gb.addNode(key, "#ad7fa8")
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func prepareEdges(refs Refs, nodeMap NodeMap) []Edge {
|
|
var edges []Edge
|
|
edgeSet := make(map[Edge]bool)
|
|
for key, references := range refs {
|
|
if to, e := nodeMap[key]; e && to.Id >= 0 {
|
|
for _, item := range references {
|
|
if from, e := nodeMap[item.Name]; e && from.Id >= 0 {
|
|
edge := Edge{
|
|
From: from.Id,
|
|
To: to.Id,
|
|
}
|
|
if _, e := edgeSet[edge]; !e {
|
|
edgeSet[edge] = true
|
|
edges = append(edges, edge)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return edges
|
|
}
|
|
|
|
func prepareNodes(nodeMap NodeMap, apply func(node Node) Node) []Node {
|
|
var nodes []Node
|
|
for _, node := range nodeMap {
|
|
if node.Id < 0 {
|
|
continue
|
|
}
|
|
nodes = append(nodes, apply(Node{
|
|
Id: node.Id,
|
|
Label: node.Label,
|
|
Color: node.Color,
|
|
Opacity: node.Opacity,
|
|
}))
|
|
}
|
|
return nodes
|
|
}
|
|
|
|
func (gb *graphBuilder) prepareNodeMap() {
|
|
for key, references := range gb.refs {
|
|
gb.addNode(key, "#5e8")
|
|
for _, item := range references {
|
|
gb.addNode(item.Name, "#403")
|
|
}
|
|
}
|
|
}
|
|
|
|
func (gb *graphBuilder) addNode(key string, color string) int {
|
|
if _, e := gb.nodeMap[key]; !e {
|
|
color := color
|
|
gb.nodeMap[key] = Node{gb.nodeCount, key, &color, 1}
|
|
gb.nodeCount += 1
|
|
}
|
|
|
|
return gb.nodeMap[key].Id
|
|
}
|