diff --git a/package.json b/package.json index 792f6146..a2291438 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "dependencies": { "@tsconfig/svelte": "^2.0.1", "graphlib": "^2.1.8", + "hierarchy-js": "^1.0.4", "juggl-api": "git+https://github.com/HEmile/juggl-api.git", "svelte": "3.35.0" } diff --git a/src/MatrixView.ts b/src/MatrixView.ts index 405613d7..9caa6401 100644 --- a/src/MatrixView.ts +++ b/src/MatrixView.ts @@ -1,5 +1,6 @@ import type { Graph } from "graphlib"; import { cloneDeep } from "lodash"; +import { createTreeHierarchy } from "hierarchy-js"; import { ItemView, Notice, TFile, WorkspaceLeaf } from "obsidian"; import { DATAVIEW_INDEX_DELAY, @@ -7,6 +8,7 @@ import { VIEW_TYPE_BREADCRUMBS_MATRIX, } from "src/constants"; import type { + AdjListItem, BreadcrumbsSettings, internalLinkObj, SquareProps, @@ -179,6 +181,26 @@ export default class MatrixView extends ItemView { return pathsArr; } + dfsAdjList(g: Graph, startNode: string): AdjListItem[] { + const queue: string[] = [startNode]; + const adjList: AdjListItem[] = []; + + let i = 0; + while (queue.length && i < 1000) { + i++; + + const currNode = queue.shift(); + const newNodes = (g.successors(currNode) ?? []) as string[]; + + newNodes.forEach((succ) => { + const next: AdjListItem = { name: currNode, parentId: succ }; + queue.unshift(succ); + adjList.push(next); + }); + } + return adjList; + } + createIndex( // Gotta give it a starting index. This allows it to work for the global index feat index: string, @@ -244,6 +266,40 @@ export default class MatrixView extends ItemView { const currFile = this.app.workspace.getActiveFile(); const settings = this.plugin.settings; + const closedParents = closeImpliedLinks(gParents, gChildren); + // const dijkstraPaths = graphlib.alg.dijkstra( + // closedParents, + // currFile.basename + // ); + + const adjList: AdjListItem[] = this.dfsAdjList( + closedParents, + currFile.basename + ); + console.log({ adjList }); + + const noDoubles = adjList.filter( + (thing, index, self) => + index === + self.findIndex( + (t) => t.name === thing.name && t?.parentId === thing?.parentId + ) + ); + console.log({ noDoubles }); + console.time("tree"); + const tree = createTreeHierarchy(noDoubles, { excludeParent: true }); + console.timeEnd("tree"); + console.log({ tree }); + + // for (const [node, path] of Object.entries(dijkstraPaths)) { + // const item: AdjListItem = { id: node }; + // const predecessor: string | undefined = path.predecessor; + // if (predecessor) { + // item.parentId = predecessor; + // } + // adjList.push(item); + // } + const viewToggleButton = this.contentEl.createEl("button", { text: this.matrixQ ? "List" : "Matrix", }); diff --git a/src/VisView.ts b/src/VisView.ts new file mode 100644 index 00000000..bf8973e5 --- /dev/null +++ b/src/VisView.ts @@ -0,0 +1,98 @@ +import * as d3 from "d3"; +import { createTreeHierarchy } from "hierarchy-js"; + +import type { Graph } from "graphlib"; +import { ItemView, WorkspaceLeaf } from "obsidian"; +import type { d3Tree } from "src/interfaces"; +import { + DATAVIEW_INDEX_DELAY, + VIEW_TYPE_BREADCRUMBS_STATS, +} from "src/constants"; +import type BreadcrumbsPlugin from "src/main"; +import Stats from "./Components/Stats.svelte"; + +export default class StatsView extends ItemView { + private plugin: BreadcrumbsPlugin; + + constructor(leaf: WorkspaceLeaf, plugin: BreadcrumbsPlugin) { + super(leaf); + this.plugin = plugin; + } + + async onload(): Promise { + super.onload(); + await this.plugin.saveSettings(); + this.app.workspace.onLayoutReady(async () => { + setTimeout(async () => await this.draw(), DATAVIEW_INDEX_DELAY); + }); + } + + getViewType() { + return VIEW_TYPE_BREADCRUMBS_VIS; + } + getDisplayText() { + return "Breadcrumbs Visualisations"; + } + + icon = "graph"; + + async onOpen(): Promise { + await this.plugin.saveSettings(); + } + + onClose(): Promise { + if (this.containerEl) { + this.containerEl.remove(); + } + return Promise.resolve(); + } + + dfsAllPaths(g: Graph, startNode: string): string[][] { + const queue: { node: string; path: string[] }[] = [ + { node: startNode, path: [] }, + ]; + const pathsArr: string[][] = []; + + let i = 0; + while (queue.length && i < 1000) { + i++; + const currPath = queue.shift(); + + const newNodes = (g.successors(currPath.node) ?? []) as string[]; + const extPath = [currPath.node, ...currPath.path]; + queue.unshift( + ...newNodes.map((n: string) => { + return { node: n, path: extPath }; + }) + ); + + if (newNodes.length === 0) { + pathsArr.push(extPath); + } + } + return pathsArr; + } + + + + toTree(g: Graph): d3Tree { + const topLevelNodes = g.sinks(); + + const tree: d3Tree = { name: "top", children: [] }; + if (topLevelNodes.length) { + topLevelNodes.forEach((node) => { + const dfsPaths = this.dfsAllPaths(g, node); + dfsPaths.forEach((path) => { + path.forEach((step) => { + const child: d3Tree = { name: step }; + tree.children.push(); + }); + }); + }); + } + } + + async draw(): Promise { + this.contentEl.empty(); + } +} diff --git a/src/interfaces.ts b/src/interfaces.ts index 0ea5142b..34c0df72 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -79,3 +79,14 @@ export interface allGraphs { gSiblings: Graph; gChildren: Graph; } + +export interface d3Tree { + name: string; + children?: d3Tree[]; + value?: string | number; +} + +export interface AdjListItem { + name: string; + parentId?: string; +}