Drawing diagrams with JavaScript

Tags:

Opera was holding another widget competition, this time for more desktop application type of widgets.

I was working on a widget as well, but sadly did not have enough time to complete it. Part of this was due to problems that I ran into in development.

The widget was going to be an easy to use diagram editor. I managed to get as far as having basic diagram editing parts implemented.

Read on for some more details of how it was going to work and what sort of problems there were.

The idea

As mentioned, I wanted to create a tool for drawing diagrams.

Initially it was going to have the ability to do flowcharts, and maybe later allow different types of diagrams, such as mindmaps.

The main problem with existing diagram tools I’ve used is that they’re either heavy (for example Microsoft Visio) or not very intuitive to use (for example Dia).

I wanted to make an editor which was not very heavy, but was still more intuitive to use.

User interface ideas

I wanted to make the UI work as smoothly as possible, not being very distractive. The main reason I’d use an application instead of pen and paper for drawing diagrams is that it should be easy to use and not get in my way.

So towards that goal, I wanted to have something like this:

  • To create new objects in the diagram, just click on empty space
  • This would pop up a box where you could choose the type. It would appear about where you clicked, so that you wouldn’t need to move the mouse much
  • To move an object, you’d just drag it
  • To connect objects to others, you’d use drag and drop
  • Changing text in an object would be a matter of just typing (assuming the object was selected)
  • You could also create new, automatically connected, objects by selecting an object and clicking on one of its handles

If you’ve used Visio, you may notice some similarities in the above descriptions.

So how do you implement this in a browser?

I decided to use Dojo for this, as it already provides a lot of functinality I could extend to suit the purposes.

The main thing I wanted from Dojo was its great drag and drop feature. I’ve used it before and it’s pretty easy to change it for different use cases.

For displaying the different objects, I planned to use a combination of HTML and SVG. HTML could be used to display simple boxy shapes, and SVG could be used to display triangles, circles and connector lines.

An important feature I wanted to have was also being able to save the diagram as an image. This proved to be quite challenging however, as it basically meant that in addition to HTML and SVG, I would have to create code to render the exact same diagram using canvas.

Issues during development

Expanding input box

One of the most immediate problems was making a text field expand based on what you’ve typed into it.

The solution to this is pretty hacky:

Have a hidden element, where the text is copied. The size of the element is then assumed to be how much space the text would take in the text field. Then it’s a matter of copying the width as the width of the text field.

This solves the problem, assuming you set your font sizes etc. correctly.

Creating SVG drawings

This is not so much a single problem, but caused by certain side-effects of the libraries chosen.

As I mentioned, I needed to be able to use canvas to store the diagrams into images. Dojo has a useful dojox.gfx library for drawing on canvas or SVG – Note here the use of word or – dojox.gfx can only draw on one sort of surface per page.

I decided to use Raphael to display SVG and dojox.gfx to draw canvas.

But why do I need two libraries for this? The reason is because SVG is not exactly very fun to do purely with DOM stuff, so having an abstraction such as Raphael’s made development faster. The same applies to canvas.

Dragging elements

This turned out to be the biggest problem of them all.

SVG and HTML elements mixed together with absolute positioning just did not seem to play nice. Sometimes events did not get to the elements I expected, requiring me to work around them. This just built on and on and made the code more complex than I had wanted to.

The lesson

The lesson learned here is that someone really needs to create a library that allows you to have SVG shapes and HTML textboxes inside those shapes and other stuff like that. Raphael and dojox.gfx can ease working with SVG, but it gets pretty tricky when you have to put a textbox on top of an SVG shape and so on.

I don’t know whether I will continue on this project, as I’m already looking forwards to working on something else. This is the same fate that most of my projects have – incomplete and lost interest :D

Try the diagram tool, note that it may load slowly due to uncompressed Dojo code. It’s not much to look at though.

It should work okay’ish in at least Chrome. You can click on the upper left area to create boxes. Click a box to allow typing text into it, drag it to move, click one of the black handle boxes to auto-connect new boxes. You can also drag from one of the handles on top of an unconnected box to connect it to this.