Code Monkey home page Code Monkey logo

juggl's Introduction

I'm a PostDoc student at the University of Edinburgh. My research focuses on combining symbolic reasoning and machine learning, or "Neuro-Symbolic Learning". I'm also interested in Personal Knowledge Management and developed some plugins for Obsidian. I obtained my PhD at the VU Amsterdam in 2024.

juggl's People

Contributors

hemile avatar kim-lindhard avatar mearman avatar ooker777 avatar peterkaminski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

juggl's Issues

Port frontend to Cytoscape

To do

  • Expand interaction, double click
  • Other key interactions
    • Hide
    • invert and select all
  • modal hovers

"Folgezettel" ID as a layout option

A more intriguing idea is not to implement the "date" merely but the user-specified "Folgezettel" ID. By relying on the date only, most note-taking systems are not utilizing the full combination of logical (semantic) argument (flow of ideas in a specific direction) and temporal creation (date). I see your Juggle package to be the closest to this missing link!

Add a depth slider to the local mode

The local mode does not have a depth slider like Obsidian does, which is something many people use.

As a temporary workaround, people can use the workspace mode, select all nodes, and then expand everything.

Subtags aren't properly recognized

As reported on Discord: "I have 2 tags: tag:#Outline/Chapter and tag:#Outline/Scene and whichever is at the bottom is the one that gets the color/shape."

Workaround: Use content:"#Outline/Chapter" and content:"#Outline/Scene".

Resolve header and block links

Wikilinks like [[Note#Header]] currently don't resolve to [[Note]] (and similar to block-links, [[Note#^blockLink]]).
Particularly, note [[#header]].

Can probably be solved by splitting the title on #, and then resolving empty links to the current note.

Perhaps using pypher?

Hello,

I'm trying to load the data generated from a small vault but I get a syntax error. I imagine it is because of some strange character in my Vault.

Invalid input ')': expected an identifier character, whitespace or NodeLabel (line 2, column 20 (offset: 53))
"IF NOT EXISTS ON (n) ASSERT n.name IS UNIQUE;"
                    ^

Perhaps using something like https://neo4j.com/blog/express-cypher-queries-pure-python-pypher/ to write the Cypher statements would be 'safer'?

Layout options

There are many layout options in Cytoscape. Create a modal that allows people to play with the layout settings.

Add notes to juggle from search results

Juggle works great when a navigable structure accross notes already exists. I use graphs (also the Obsidian one) very often to evaluate where I want to make connections - that means when there are many orphan notes, or notes that are at the moment far away from each other in the graph.

Such a situation is not well supported yet by juggle. The only solution I see is to open each note that I want to lay down in juggle one by one while juggle is open and until all are in. This is very much handwork if you want to place 20-30 notes.

A marvelous solution would be to be able to open/place the search results from an Obsidian search in a Juggle. Would that be difficult to implement?

Sidebar panes added repeatedly

First things first, this is an awesome plugin, thanks for making this!

I've just got one issue: When Juggl is enabled, I get two extra right sidebar tabs for nodes and style. When I close Obsidian and reopen it, these two tabs become blank "No file is open" tabs, and two new nodes and style tabs appear. This means when opening/closing Obsidian a number of times, I end up with dozens of blank sidebar panels.

Here's an example after reopening Obsidian twice:

image

After a few days it becomes tricky to use the right sidebar, as you can't scroll the tab view.

I think the old tabs should be re-used instead of becoming blank. Also, if the nodes and style tabs aren't there, I don't think Juggl should bring them up automatically - I personally don't use them, and would prefer they were hidden. Alternately, having an option to stop them automatically appearing would be nice.

Use '~' instead of '-'?

Using - relationshipTo [[random page]] means that certain things get picked up as relationships which I don't like e.g. a todo in the format - [x] [[page of a task]].

Thus, it might be better to use something not used for lists/other things in general such as '~' i.e. ~ relationshipTo [[random page]]

N.B. Your plugin has sold obsidian to me! I think I'm never leaving.

Delay mouseover preview

Mouseover preview like the content preview should be shown only when hovering over a node for a while.

Allow combining edges between nodes

Currently, it's possible for two nodes to be connected through multiple edges (in either direction). This can clutter the visualization quite a bit. It might look more intuitive if they can be merged together. Styling can be annoying though, if there are multiple contexts and types.

Feature to define the neo4j Database

Can you add a feature to type in what database to connect to and port number for the connections?

As it is now the plugin try to connect to the default database, but I have multiple databases on my system, and the default one is not the one I wish to use for this...

That way it would also be possible to use different neo4j databases for different vaults

Second thing, that's more of a question in regard to your comment in your roadmap about the installation of nei4j desktop...

  • Would it be possible for you to use the neo4j embedded for this project?
    I don't know anything about this, or if it's free or not, I just saw there was an embedded version of neo4j...

Add the ability to create compound nodes

Add the ability to define compound nodes. This can be done using a parent attribute in YAML, or with a typed link of type parent.

This could be done in the Edge Styling Pane, see #40

Statement syntax error when running the plugin

I tried the plugin on one of my vaults and it worked perfectly, but on this vault there seems to be a problem.

Here is the short version - I've included the entire error below if you need.

Traceback (most recent call last):
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\client\__init__.py", line 450, in acquire
    cx = self._free_list.popleft()
IndexError: pop from an empty deque

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Aviral\AppData\Local\Temp\pythonShellFile8233150079.py", line 1, in <module>
    from smdc.stream import main;main();
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\smdc\stream.py", line 164, in main
    graph, tags = convert(args)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\smdc\convert.py", line 9, in convert
    return FORMAT_TYPES[args.output_format].write(notes, args)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\smdc\format\neo4j.py", line 61, in write
    raise e

# lot more lines here

py2neo.database.work.ClientError: [Statement.SyntaxError] Invalid input ')': expected whitespace, comment or a label name (line 3, column 1 (offset: 48))

") ON (n.name)"

long version:

ncaught Error: 
  0%|          | 0/424 [00:00<?, ?it/s]
 32%|###1      | 134/424 [00:00<00:00, 1339.73it/s]
 54%|#####3    | 227/424 [00:00<00:00, 1174.47it/s]
 99%|#########9| 421/424 [00:00<00:00, 1329.44it/s]
100%|##########| 424/424 [00:00<00:00, 1394.74it/s]

  0%|          | 0/422 [00:00<?, ?it/s]
100%|##########| 422/422 [00:00<00:00, 13188.26it/s]

  0%|          | 0/422 [00:00<?, ?it/s]
 51%|#####1    | 216/422 [00:01<00:01, 158.94it/s]
100%|##########| 422/422 [00:01<00:00, 300.36it/s]

  0%|          | 0/70 [00:00<?, ?it/s]
  1%|1         | 1/70 [00:00<01:05,  1.06it/s]
  3%|2         | 2/70 [00:01<00:47,  1.44it/s]
  4%|4         | 3/70 [00:01<00:36,  1.81it/s]
  7%|7         | 5/70 [00:01<00:26,  2.47it/s]
 10%|#         | 7/70 [00:01<00:20,  3.09it/s]
 13%|#2        | 9/70 [00:01<00:15,  3.98it/s]
 17%|#7        | 12/70 [00:02<00:11,  5.16it/s]
 20%|##        | 14/70 [00:02<00:09,  5.92it/s]
 23%|##2       | 16/70 [00:02<00:07,  6.95it/s]
 26%|##5       | 18/70 [00:02<00:06,  7.69it/s]
 29%|##8       | 20/70 [00:02<00:05,  9.08it/s]
 31%|###1      | 22/70 [00:02<00:04, 10.71it/s]
 34%|###4      | 24/70 [00:02<00:03, 12.17it/s]
 37%|###7      | 26/70 [00:03<00:03, 13.40it/s]
 40%|####      | 28/70 [00:03<00:03, 13.77it/s]
 43%|####2     | 30/70 [00:03<00:02, 14.15it/s]
 46%|####5     | 32/70 [00:03<00:02, 14.38it/s]
 49%|####8     | 34/70 [00:03<00:02, 14.51it/s]
 51%|#####1    | 36/70 [00:03<00:02, 15.16it/s]
 54%|#####4    | 38/70 [00:03<00:01, 16.35it/s]
 59%|#####8    | 41/70 [00:03<00:01, 17.09it/s]
 61%|######1   | 43/70 [00:04<00:01, 15.18it/s]
 64%|######4   | 45/70 [00:04<00:01, 12.99it/s]
 69%|######8   | 48/70 [00:04<00:01, 14.58it/s]
 73%|#######2  | 51/70 [00:04<00:01, 14.79it/s]
 76%|#######5  | 53/70 [00:04<00:01, 15.00it/s]
 79%|#######8  | 55/70 [00:04<00:01, 14.61it/s]
 81%|########1 | 57/70 [00:05<00:00, 15.38it/s]
 81%|########1 | 57/70 [00:05<00:01, 11.11it/s]
Traceback (most recent call last):
  File "C:\Users\Aviral\AppData\Local\Temp\pythonShellFile4767339406.py", line 1, in <module>
    from smdc.stream import main;main();
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\smdc\stream.py", line 164, in main
    graph, tags = convert(args)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\smdc\convert.py", line 9, in convert
    return FORMAT_TYPES[args.output_format].write(notes, args)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\smdc\format\neo4j.py", line 110, in write
    create_index(g, tag)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\smdc\format\neo4j.py", line 42, in create_index
    graph.run(f"CREATE INDEX index_{prop}_{tag} IF NOT EXISTS FOR (n:{tag}) ON (n.{prop})")
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\database\__init__.py", line 709, in run
    return self.auto().run(cypher, parameters, **kwparameters)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\database\work.py", line 127, in run
    result = self._connector.auto_run(self.graph.name, cypher, parameters,
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\client\__init__.py", line 936, in auto_run
    result = cx.auto_run(graph_name, cypher, parameters, readonly=readonly)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\client\bolt.py", line 673, in auto_run
    result.buffer()
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\client\bolt.py", line 949, in buffer
    self.__cx.sync(self)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\client\bolt.py", line 516, in sync
    self._audit(result)
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\client\bolt.py", line 626, in _audit
    task.audit()
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\client\bolt.py", line 883, in audit
    item.audit()
  File "C:\Users\Aviral\AppData\Roaming\Python\Python39\site-packages\py2neo\client\bolt.py", line 1062, in audit
    raise self._failure
py2neo.database.work.ClientError: [Statement.SyntaxError] Invalid input ')': expected whitespace, comment or a label name (line 3, column 1 (offset: 48))

") ON (n.name)"

 ^

    at PythonShell.parseError (eval at <anonymous> (app.js:1), <anonymous>:492:21)
    at terminateIfNeeded (eval at <anonymous> (app.js:1), <anonymous>:368:32)
    at ChildProcess.eval (eval at <anonymous> (app.js:1), <anonymous>:360:13)
    at ChildProcess.emit (events.js:315)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:275)
PythonShellError @ index.js:49
parseError @ index.js:271
terminateIfNeeded @ index.js:146
eval @ index.js:138
emit @ events.js:315
ChildProcess._handle.onexit @ internal/child_process.js:275

Windows firewall doesn't like the image server

The image server requires opening a port to redirect images. We should remove this server, possibly by using data urls instead of resource urls.

This gives a Windows Firewall error. Not allowing it will remove the ability of displaying images in the graph and could cause other issues.

Handle nested tags

The new insider release of Obsidian supports nested tags like #tag/subtag. This could probably be supported by giving respective nodes both the label #tag and #subtag

Ignore .trash folder

The .trash folder is used in obsidian as a trash folder. It should be ignored. Moving a file to this folder should also delete it.

Recognize YAML attributes in filters

YAML attributes are currently not recognized in the filter keywordskeywords: ['file', 'name', 'content', 'tag', 'path', 'raw', 'match-case', 'ignore-case', 'class'],

"Date" as a layout

Regarding the layout. It would be nice to have a directed layout based on the date. In that way, one could follow the development of an idea. The easiest would be to take the user-specified date (e.g. from a Zettlekasten note or YAML metadata). Or, if possible, to take the system date from when the file was created

Degree options

Currently, the 'degree' data is computed simply using the total amount of edges in and out. Other options could be PageRank, centrality and connectedness. See cytoscape docs.

Provide possibility for user-configurable stylesheet

User should be able to style the graph with something like graph.css. However, it should also be possible to do the following

  • Provide a default stylesheet
    • This stylesheet should use the theme defaults
      • There should be a stylesheet for both light and dark modes
    • Default stylesheet should always get lower priority than graph.css
    • Default stylesheet should be able to be updated by the plugin

Maybe this is possible by manually creating a string for the default style, where it looks up the themes css settings.

Add context menu for nodes

Add a context menu (right-click menu) for nodes in the graph. Liam @ Discord provided this method:

const fileMenu = new Menu(); // Creates empty file menu
this.app.workspace.trigger("file-menu", fileMenu, file, "my-context-menu", null); // hook for plugins to populate menu with "file-aware" menu items
fileMenu.showAtPosition({ x: event.pageX, y: event.pageY }); // Actually open the menu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.