Skip to content

Instantly share code, notes, and snippets.

@bpluly
Last active October 31, 2023 16:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bpluly/dc2981bad8bd9e319964927c2fddb05f to your computer and use it in GitHub Desktop.
Save bpluly/dc2981bad8bd9e319964927c2fddb05f to your computer and use it in GitHub Desktop.
SVG Drag n Drop

In creating the graph view in Zettel.io of notes in a kasten I wanted to maintain the general method of not relying upon frameworks. For the Card and Strips view in the Kasten I used Canvas for the linking lines layer between notes. On the graph I wanted to show it as a kind of entity graph, ellipses with links, and later tags, connecting the notes.

I did not want a force graph as in d3 because that's very stiff the user can kind of change the view of the graph but it's hard to place them easily.

The graph page is the same kind of structure as the Card and Strip views but I separated it out as its own template. Within each Node set of DIVs there's an SVG viewBox with an ellipse and a text element inside, the text is just the summary or title of the Note. At the moment that's only 20 characters long.

I thought it would be as simple as the original Drag n Drop to move elements around as it orginally was for Cards and Strips before I refactored it to have ordering on the notes. But (after the travail to understand how to draw lines in one space between ellipses in another), zero Drag or drop, not even the dragStart event firing. I was then sucked down the rabbit hole of how you couldn't DnD SVG in HTML and it would need handling mouse events and copying data in various icky ways.

Then I discovered I had to set an explicit position on the DIV (position: relative), and then all the dragging happened. It would drop on existing other notes, swapping location which was what happened before. To get dropping into empty space I created the same number of empty DIVs of the same class and attributes as the notes in the Kasten and voila (I have to fix the sizes of the empty DIVs but heh. So you can drag n drop SVG in HTML, the drop handler is as follows:

      function handleDragDrop(element){
        element.stopPropagation();
        if (dragSrcEl !== this) {
          dragSrcEl.id = this.id
          dragSrcEl.innerHTML = this.innerHTML;
          dragSrcEl.style.backgroundColor = this.style.backgroundColor
          this.id = element.dataTransfer.getData('text');
          this.innerHTML = element.dataTransfer.getData('text/html');
          this.style.backgroundColor = element.dataTransfer.getData('colour');
        }
        element.preventDefault();
        return false;
      }
      function handleDragEnd(){
        this.style.opacity = '1';
        if (graphicsInUse == true){
          drawLinks(currentContent);
        }
      }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment