You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
3.6 KiB
170 lines
3.6 KiB
/* |
|
* Wiki - A wiki with editor |
|
* Copyright (c) 2021-2021 Peter Stuifzand |
|
* |
|
* This program is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
*/ |
|
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, |
|
Title: node.Title, |
|
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 |
|
title:= strings.Replace(key, "_", " ", -1) |
|
gb.nodeMap[key] = Node{gb.nodeCount, key, title, &color, 1} |
|
gb.nodeCount += 1 |
|
} |
|
|
|
return gb.nodeMap[key].Id |
|
}
|
|
|