Skip to content

Commit

Permalink
Moved types to different file - working on making paired links (mutua…
Browse files Browse the repository at this point in the history
…l links) much faster and better.
  • Loading branch information
natefrisch01 committed Jan 11, 2024
1 parent f6a1f8b commit 521278d
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 57 deletions.
71 changes: 71 additions & 0 deletions linkManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@

import { CustomLink, LinkStatus } from 'types';


// Create a mapping from numeric values to string values
const LinkStatusStringMap: Record<LinkStatus, 'first' | 'second' | 'none'> = {
[LinkStatus.First]: 'first',
[LinkStatus.Second]: 'second',
[LinkStatus.None]: 'none',
};

export class LinkManager {
linksMap: Map<string, CustomLink>;
linkStatus: Map<string, LinkStatus>;

constructor() {
this.linksMap = new Map<string, CustomLink>();
this.linkStatus = new Map<string, LinkStatus>();
}

generateKey(sourceId: string, targetId: string): string {
return `${sourceId}-${targetId}`;
}

addLink(link: CustomLink): void {
const key = this.generateKey(link.source.id, link.target.id);
const reverseKey = this.generateKey(link.target.id, link.source.id);

// Add the new link
this.linksMap.set(key, link);

// Manage the pair statuses
if (this.linksMap.has(reverseKey)) {
// If the reverse link is already present, set the statuses accordingly
this.linkStatus.set(key, LinkStatus.Second);
this.linkStatus.set(reverseKey, LinkStatus.First);
} else {
// If it's a standalone link (no pair yet), do not assign a pair status
// This will be managed when the reverse link is added (if it happens)
}
}

removeLink(link: CustomLink): void {
const key = this.generateKey(link.source.id, link.target.id);
const reverseKey = this.generateKey(link.target.id, link.source.id);

this.linksMap.delete(key);
if (this.linkStatus.has(key)) {
this.linkStatus.delete(key);
}
if (this.linkStatus.get(reverseKey) === LinkStatus.Second) {
this.linkStatus.delete(reverseKey);
}
}

updateLinks(currentLinks: CustomLink[]): void {
const currentKeys = new Set(currentLinks.map(link => this.generateKey(link.source.id, link.target.id)));
for (const key of this.linksMap.keys()) {
if (!currentKeys.has(key)) {
const link = this.linksMap.get(key);
if (link) {
this.removeLink(link);
}
}
}
}

getLinkStatus(key: string): 'first' | 'second' | 'none' {
return LinkStatusStringMap[this.linkStatus.get(key) || LinkStatus.None];
}
}
136 changes: 79 additions & 57 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Plugin, WorkspaceLeaf, Notice} from 'obsidian';
import { getAPI, Page } from 'obsidian-dataview';
import { CustomRenderer, CustomLink, DataviewLinkType} from 'types';
import { LinkManager } from 'linkManager';
import * as PIXI from 'pixi.js';
import extractLinks from 'markdown-link-extractor';

Expand Down Expand Up @@ -29,12 +31,73 @@ export default class GraphLinkTypesPlugin extends Plugin {
id: 'print-link-type',
name: 'Print Link Type',
callback: () => {
this.checkAndUpdateRenderer();
this.startUpdateLoop(1);
this.toyLinks();
}
});
}

toyLinks() {
// Example frames: Each frame is an array of links
const frames: CustomLink[][] = [
// Frame 1: Simple links, some will form pairs later
[
{ source: { id: "A", x: 0, y: 0 }, target: { id: "B", x: 0, y: 0 } },
{ source: { id: "C", x: 0, y: 0 }, target: { id: "D", x: 0, y: 0 } },
],

// Frame 2: Adding reverse links to form pairs and keeping existing links
[
{ source: { id: "A", x: 0, y: 0 }, target: { id: "B", x: 0, y: 0 } }, // Existing link
{ source: { id: "B", x: 0, y: 0 }, target: { id: "A", x: 0, y: 0 } }, // Forms a pair with Frame 1's A-B
{ source: { id: "C", x: 0, y: 0 }, target: { id: "D", x: 0, y: 0 } }, // Existing link
{ source: { id: "E", x: 0, y: 0 }, target: { id: "F", x: 0, y: 0 } }, // New link
],

// Frame 3: Keeping a pair, removing a single link, adding a new link
[
{ source: { id: "A", x: 0, y: 0 }, target: { id: "B", x: 0, y: 0 } }, // Existing link
{ source: { id: "B", x: 0, y: 0 }, target: { id: "A", x: 0, y: 0 } }, // Existing pair
{ source: { id: "G", x: 0, y: 0 }, target: { id: "H", x: 0, y: 0 } }, // New link
],

// Frame 4:
[
{ source: { id: "B", x: 0, y: 0 }, target: { id: "A", x: 0, y: 0 } },
{ source: { id: "G", x: 0, y: 0 }, target: { id: "H", x: 0, y: 0 } }, // New link
],
];

const linkManager = new LinkManager();

frames.forEach((frame, frameIndex) => {
console.log(`Frame ${frameIndex + 1}:`);

// Update link manager with the current frame's links
linkManager.updateLinks(frame);

// Process links
frame.forEach(link => {
const key = linkManager.generateKey(link.source.id, link.target.id);
if (!linkManager.linksMap.has(key)) {
linkManager.addLink(link);
}
const status = linkManager.getLinkStatus(key);

// Print link status
if (status === 'first') {
console.log('first: ' + key);
} else if (status === 'second') {
console.log('second: ' + key);
} else {
console.log(key); // Not part of a pair
}
});
});

}



// Find the first valid graph renderer in the workspace
findRenderer(): CustomRenderer | null {
let graphLeaves = this.app.workspace.getLeavesOfType('graph');
Expand Down Expand Up @@ -243,17 +306,17 @@ export default class GraphLinkTypesPlugin extends Plugin {
}

// Method to determine the type of a value, now a class method
private determineLinkType(value: any): LinkType {
private determineDataviewLinkType(value: any): DataviewLinkType {
if (typeof value === 'object' && value !== null && 'path' in value) {
return LinkType.DataviewLink;
return DataviewLinkType.WikiLink;
} else if (typeof value === 'string' && value.includes('](')) {
return LinkType.MarkdownLink;
return DataviewLinkType.MarkdownLink;
} else if (typeof value === 'string') {
return LinkType.String;
return DataviewLinkType.String;
} else if (Array.isArray(value)) {
return LinkType.Array;
return DataviewLinkType.Array;
} else {
return LinkType.Other;
return DataviewLinkType.Other;
}
}

Expand All @@ -263,27 +326,25 @@ export default class GraphLinkTypesPlugin extends Plugin {
if (!sourcePage) return null;

for (const [key, value] of Object.entries(sourcePage)) {
const valueType = this.determineLinkType(value);
const valueType = this.determineDataviewLinkType(value);

switch (valueType) {
case LinkType.DataviewLink:
case DataviewLinkType.WikiLink:
if (value.path === targetId) {
return key;
}
break;
case LinkType.MarkdownLink:
case DataviewLinkType.MarkdownLink:
if (this.extractPathFromMarkdownLink(value) === targetId) {
console.log(targetId);
return key;
}
break;
case LinkType.Array:
case DataviewLinkType.Array:
for (const item of value) {
if (this.determineLinkType(item) === LinkType.DataviewLink && item.path === targetId) {
if (this.determineDataviewLinkType(item) === DataviewLinkType.WikiLink && item.path === targetId) {
return key;
}
if (this.determineLinkType(item) === LinkType.MarkdownLink && this.extractPathFromMarkdownLink(item) === targetId) {
console.log(targetId);
if (this.determineDataviewLinkType(item) === DataviewLinkType.MarkdownLink && this.extractPathFromMarkdownLink(item) === targetId) {
return key;
}
}
Expand All @@ -295,9 +356,8 @@ export default class GraphLinkTypesPlugin extends Plugin {
}

// Utility function to extract the file path from a Markdown link
private extractPathFromMarkdownLink(markdownLink: string): string {
private extractPathFromMarkdownLink(markdownLink: string | unknown): string {
const links = extractLinks(markdownLink).links;
console.log(links[0]);
// The package returns an array of links. Assuming you want the first link.
return links.length > 0 ? links[0] : '';
}
Expand All @@ -313,7 +373,7 @@ export default class GraphLinkTypesPlugin extends Plugin {
}

// Utility function to check if a value is a link
isDataviewLink(value: any): boolean {
isWikiLink(value: any): boolean {
return typeof value === 'object' && value.hasOwnProperty('path');
}

Expand Down Expand Up @@ -358,41 +418,3 @@ export default class GraphLinkTypesPlugin extends Plugin {

}


interface CustomRenderer {
px: {
stage: {
addChild: (child: any) => void;
removeChild: (child: any) => void;
children: any[];
};
};
links: any[];
nodeScale: number;
panX: number;
panY: number;
scale: number;
}

interface CustomLink {
source: {
id: string;
x: number;
y: number;
};
target: {
id: string;
x: number;
y: number;
};
}

// Define the enum outside the class
enum LinkType {
DataviewLink,
MarkdownLink,
String,
Array,
Other
}

112 changes: 112 additions & 0 deletions scratchpad.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@

import { CustomLink } from './types';

class LinkManager {
private linksMap: Map<string, CustomLink>;
private linkStatus: Map<string, 'first' | 'second'>;

constructor() {
this.linksMap = new Map<string, CustomLink>();
this.linkStatus = new Map<string, 'first' | 'second'>();
}

private generateKey(sourceId: string, targetId: string): string {
return `${sourceId}-${targetId}`;
}

addLink(link: Link): void {
const key = this.generateKey(link.source.id, link.target.id);
const reverseKey = this.generateKey(link.target.id, link.source.id);

// Add the new link
this.linksMap.set(key, link);

// Manage the pair statuses
if (this.linksMap.has(reverseKey)) {
// If the reverse link is already present, set the statuses accordingly
this.linkStatus.set(key, 'second');
this.linkStatus.set(reverseKey, 'first');
} else {
// If it's a standalone link (no pair yet), do not assign a pair status
// This will be managed when the reverse link is added (if it happens)
}
}

removeLink(link: Link): void {
const key = this.generateKey(link.source.id, link.target.id);
const reverseKey = this.generateKey(link.target.id, link.source.id);

this.linksMap.delete(key);
if (this.linkStatus.has(key)) {
this.linkStatus.delete(key);
}
if (this.linkStatus.get(reverseKey) === 'second') {
this.linkStatus.delete(reverseKey);
}
}

updateLinks(currentLinks: Link[]): void {
const currentKeys = new Set(currentLinks.map(link => this.generateKey(link.source.id, link.target.id)));
for (const key of this.linksMap.keys()) {
if (!currentKeys.has(key)) {
const link = this.linksMap.get(key);
if (link) {
this.removeLink(link);
}
}
}
}

getLinkStatus(key: string): 'first' | 'second' | 'none' {
return this.linkStatus.get(key) || 'none';
}
}

// Example frames: Each frame is an array of links
const frames: Link[][] = [
// Frame 1: Simple links, some will form pairs later
[{ source: { id: "A" }, target: { id: "B" } },
{ source: { id: "C" }, target: { id: "D" } }],

// Frame 2: Adding reverse links to form pairs and keeping existing links
[{ source: { id: "A" }, target: { id: "B" } }, // Existing link
{ source: { id: "B" }, target: { id: "A" } }, // Forms a pair with Frame 1's A-B
{ source: { id: "C" }, target: { id: "D" } }, // Existing link
{ source: { id: "E" }, target: { id: "F" } }], // New link

// Frame 3: Keeping a pair, removing a single link, adding a new link
[{ source: { id: "A" }, target: { id: "B" } }, // Existing link
{ source: { id: "B" }, target: { id: "A" } }, // Existing pair
{ source: { id: "G" }, target: { id: "H" } }], // New link

// Frame 4:
[{ source: { id: "B" }, target: { id: "A" } },
{ source: { id: "G" }, target: { id: "H" } }], // New link
];

const linkManager = new LinkManager();

frames.forEach((frame, frameIndex) => {
console.log(`Frame ${frameIndex + 1}:`);

// Update link manager with the current frame's links
linkManager.updateLinks(frame);

// Process links
frame.forEach(link => {
const key = linkManager.generateKey(link.source.id, link.target.id);
if (!linkManager.linksMap.has(key)) {
linkManager.addLink(link);
}
const status = linkManager.getLinkStatus(key);

// Print link status
if (status === 'first') {
console.log('\n' + key);
} else if (status === 'second') {
console.log(key + '\n');
} else {
console.log(key); // Not part of a pair
}
});
});
Loading

0 comments on commit 521278d

Please sign in to comment.