diff --git a/src/Components/JugglButton.svelte b/src/Components/JugglButton.svelte index 0469dc16..d0f76a72 100644 --- a/src/Components/JugglButton.svelte +++ b/src/Components/JugglButton.svelte @@ -1,5 +1,6 @@ + +{#if visible} +
+ {depth -= 1; onUpdateDepth(depth);}} > + + + + + + = maxDepth} onClick={() => {depth += 1; onUpdateDepth(depth);}} > + +
+{/if} \ No newline at end of file diff --git a/src/Visualisations/Juggl.ts b/src/Visualisations/Juggl.ts index cc32cc75..7a50400e 100644 --- a/src/Visualisations/Juggl.ts +++ b/src/Visualisations/Juggl.ts @@ -22,6 +22,7 @@ import { getReflexiveClosure, getSubInDirs, } from "../Utils/graphUtils"; +import JugglDepth from "../Components/JugglDepth.svelte"; const STORE_ID = "core"; class BCStoreEvents extends Events implements DataStoreEvents {} @@ -30,15 +31,18 @@ class BCStore extends Component implements ICoreDataStore { graph: MultiGraph; cache: MetadataCache; plugin: IJugglPlugin; + depthMap: {[value: string]: number} constructor( graph: MultiGraph, metadata: MetadataCache, - plugin: IJugglPlugin + plugin: IJugglPlugin, + depthMap: {[value: string]: number} ) { super(); this.graph = graph; this.cache = metadata; this.plugin = plugin; + this.depthMap = depthMap } asString(node: NodeSingular): string { @@ -100,10 +104,14 @@ class BCStore extends Component implements ICoreDataStore { get(nodeId: VizId, view: IJuggl): Promise { const file = this.getFile(nodeId); + let depth = 0; + if (this.depthMap && nodeId.id in this.depthMap) { + depth = this.depthMap[nodeId.id] + } if (file === null) { const dangling = nodeDangling(nodeId.id); - console.log({ dangling }); - return Promise.resolve(nodeDangling(nodeId.id)); + dangling.data.depth = depth; + return Promise.resolve(dangling); } const cache = this.cache.getFileCache(file); if (cache === null) { @@ -111,9 +119,10 @@ class BCStore extends Component implements ICoreDataStore { return Promise.resolve(nodeDangling(nodeId.id)); } - return Promise.resolve( - nodeFromFile(file, this.plugin, view.settings, nodeId.toId()) - ); + return nodeFromFile(file, this.plugin, view.settings, nodeId.toId()).then(node => { + node.data.depth = depth; + return node; + }); } } @@ -121,7 +130,8 @@ export function createJuggl( plugin: BCPlugin, target: HTMLElement, initialNodes: string[], - args: IJugglSettings + args: IJugglSettings, + depthMap: {[value: string]: number}=null ): IJuggl { try { const jugglPlugin = getPlugin(plugin.app); @@ -138,17 +148,16 @@ export function createJuggl( const bcStore = new BCStore( plugin.mainG, plugin.app.metadataCache, - jugglPlugin + jugglPlugin, + depthMap ); const stores: IJugglStores = { coreStore: bcStore, dataStores: [bcStore], }; - console.log({ args }, { initialNodes }); const juggl = jugglPlugin.createJuggl(target, args, stores, initialNodes); plugin.addChild(juggl); - // juggl.load(); console.log({ juggl }); return juggl; } catch (error) { @@ -178,6 +187,30 @@ function zoomToSource(juggl: IJuggl, source: string) { }); } +function createDepthMap(paths: string[][], source: string, offset=0): {[name: string]: number} { + // TODO: Is there a BC function for this already? + let depthMap: {[value: string]: number} = {}; + depthMap[source + ".md"] = 0; + paths.forEach((path) => { + for (let i=0; i < path.length; i++) { + const name = path[i] + ".md"; + const depth = path.length - i - 1 + offset; + if (name in depthMap) { + depthMap[name] = Math.min(depthMap[name], depth); + } + else { + depthMap[name] = depth; + } + } + }); + return depthMap +} + +function updateDepth(juggl: IJuggl, depth: number) { + juggl.viz.$(`[depth>${depth}]`).addClass('filtered'); + juggl.viz.$(`[depth<=${depth}]`).removeClass('filtered'); +} + export function createJugglTrail( plugin: BCPlugin, target: HTMLElement, @@ -205,15 +238,18 @@ export function createJugglTrail( onClick: () => { if (jugglUp) { target.children[amtChildren].classList.remove("juggl-hide"); + depthUp.$set({visible: true}); } if (jugglDown) { target.children[amtChildren + 1].classList.add("juggl-hide"); + depthDown.$set({visible: false}); } }, disabled: false, title: "Show up graph", }, }); + new JugglButton({ target: sectDiv, props: { @@ -221,8 +257,10 @@ export function createJugglTrail( onClick: () => { if (jugglDown) { target.children[amtChildren + 1].classList.remove("juggl-hide"); + depthUp.$set({visible: false}); if (jugglUp) { target.children[amtChildren].classList.add("juggl-hide"); + depthDown.$set({visible: true}); } return; } @@ -236,19 +274,29 @@ export function createJugglTrail( .split("\n") .map((line) => { const pair = line.split("- "); - console.log({ pair }); return pair[1]; }) .filter((pair) => pair && pair !== ""); + let depthMapDown = createDepthMap(allPaths, source); + const maxDepthDown = Math.max(...Object.values(depthMapDown)) + + depthDown = new JugglDepth({ + target: toolbarDiv, + props: { + maxDepth: maxDepthDown, + onUpdateDepth: (d) => { + updateDepth(jugglDown, d); + } + } + }); let nodesS = new Set(lines); nodesS.add(source); const nodes = Array.from(nodesS).map((s) => s + ".md"); - console.log({ nodes }); - - jugglDown = createJuggl(plugin, target, nodes, args); + jugglDown = createJuggl(plugin, target, nodes, args, depthMapDown); if (jugglUp) { target.children[amtChildren].addClass("juggl-hide"); + depthUp.$set({visible: false}); } zoomToSource(jugglDown, source); }, @@ -256,6 +304,21 @@ export function createJugglTrail( title: "Show down graph", }, }); + const depthMapUp = createDepthMap(paths, source, 1); + const maxDepthUp = Math.max(...Object.values(depthMapUp)) + + let depthDown: JugglDepth; + const depthUp = new JugglDepth({ + target: toolbarDiv, + props: { + maxDepth: maxDepthUp, + onUpdateDepth: (d) => { + updateDepth(jugglUp, d); + } + } + }); + + // new JugglButton({ // target: sectDiv, // props: { @@ -272,10 +335,11 @@ export function createJugglTrail( let nodes = Array.from( new Set(paths.reduce((prev, curr) => prev.concat(curr), [])) ); + nodes.push(source); nodes = nodes.map((s) => s + ".md"); - jugglUp = createJuggl(plugin, target, nodes, args); + jugglUp = createJuggl(plugin, target, nodes, args, depthMapUp); zoomToSource(jugglUp, source); }