12

1.) I found a canvas API called EaselJS, it does an amazing job of creating a display list for each elements you draw. They essentially become individually recognizable objects on the canvas (on one single canvas)

2.) Then I saw on http://simonsarris.com/ about this tutorial that can do drag and drop, it makes use of a hidden canvas concept for selection.

3.) And the third approach, a working approach, http://www.lucidchart.com/ , which is exactly what I'm trying to achieve, basically have every single shape on a different canvas, and use to position them. There's a huge amount of canvas.

The question is, what is the easiest way to achieve interactive network diagram as seen on http://www.lucidchart.com/

A side question is, is it better to get text input through positioning on canvas or using multiple canvas (one for rendering text) as in LucidChart

VividD
  • 10,456
  • 6
  • 64
  • 111
William Sham
  • 12,849
  • 11
  • 50
  • 67
  • What about [SVG with raphael](http://raphaeljs.com/) and [charting with gRaphael](http://g.raphaeljs.com/) – Raynos Jun 17 '11 at 13:48
  • @William Sham Hello Actually I am also doing some thing similer to your work and trying to make an interactive diagram application using easelJs Can you guid me how have connect two images one the canvasThanks – mainajaved Apr 06 '12 at 08:07

2 Answers2

12

I'm the person who made the tutorials in 2. There's a lot going on here, so I'll try to explain a bit.

I use a hidden canvas for selection simply because it is easy to learn and will work for ANY kind of object (text, complex paths, rectangles, semi-transparent images). In the real diagramming library that I am writing, I don't do anything of the sort, instead I use a lot of math to determine selection. The hidden-canvas method is fine for less than 1000 objects, but eventually performance starts to suffer.

Lucidchart actually uses more than one canvas per object. And it doesn't just have them in memory, they are all there the DOM. This is an organizational choice on their part, a pretty weird one in my opinion. SVG might have made their work a lot easier if thats what they are going to do, as if seems they are doing a lot of footwork just to be able to emulate how SVG works a bit. There aren't too many good reasons to have so many canvases in the DOM if you can avoid it.

It seems to me that the advantage of them doing it that way is that if they have 10,000 objects, when you click, you only have to look at the one (small) canvas that is clicked for selection testing, instead of the entire canvas. So they did it to make their selection code a little shorter. I'd much rather only have one canvas in the DOM; their way seems needlessly messy. The point of canvas is to have a fast rendering surface instead of a thousand divs representing objects. But they just made a thousand canvases.

Anyway, to answer your question, the "easiest" way to achieve interactive network diagrams like lucidchart is to either use a library or use SVG (or an SVG library). Unfortunately there aren't too many yet. Getting all the functionality yourself in Canvas is hard but certainly doable, and will afford you better performance than SVG, especially if you plan on having more than 5,000 objects in your diagrams. Starting with EaselJS for now isn't too bad of an idea, though you'll probably find yourself modifying more and more of it as you get deeper into your project.

I am making one such interactive canvas diagramming library for Northwoods Software, but it won't be done for a few more months.

To answer the question that is sort-of in your title: The fastest method of doing interactiveness such as hit-testing is using math. Any high-performance canvas library with the features to support a lot of different types of objects will end up implementing functions like getNearestIntersectionPoint, getIntersectionsOnRect, pathContainsPoint, and so on.

As for your side question, it is my opinion that creating a text field on top of the canvas when a user wants to change text and then destroying it when the user is done entering text is the most intuitive-feeling way to get text input. Of course you need to make sure the field is positioned correctly over the text you are editing and that the font and font sizes are the same for a consistent feel.

Best of luck with your project. Let me know how it goes.

Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
  • Thanks for the long response. I was hoping to get in contact with you somehow. It's nice talking to an expert. I agree the way Lucidchart organizes it is messy. And now think I think about it, I can't seem to find a convincing reason for myself to not use SVG instead of canvas, given SVG put everything as an item in the DOM. So why do you choose to implement canvas for your client? Some info on my project, the network diagram is a part of it, in which each shape on the diagram represents data fed from a DB. It would also need to work on a ipad in the future, if that might affect svg vs canvas – William Sham Jun 17 '11 at 22:00
  • The reason why one might choose canvas over SVG is performance. It seems that canvas scales better with increasing number of objects. for more infos: [canvas-svg-div](http://stackoverflow.com/questions/5882716/html5-canvas-vs-svg-vs-div/) – Ümit Jun 20 '11 at 08:42
2

Using SVG (and maybe libraries as Raphael)!!

Then any element can receive mouse events.

Bakaburg
  • 3,165
  • 4
  • 32
  • 64
  • 1
    You can do the same if you use easelJS. Additionally with easelJS you get better performance. – basarat Nov 18 '12 at 06:53