d3.js - maintain interaction with use of canvas - javascript

As far as I read about this topic d3.js uses for the main part SVG and not HTML5's Canvas. The advantages and disadvantages of SVG and Canvas are clear and already discussed. Now I found out that it is possible to use Canvas instead or in combination with SVG in d3.js. The main reason should be to get a better performance for large datasets (like cubism.js does for realtime data visualization). My question is: When I do use Canvas over SVG to get a better performance, do I have still the possibilities of interaction? I know that Canvas itself allows manipulation, but it is much harder to implement than it is for SVG. So can I maintain the interaction of SVGs when I use the d3.js Canvas approach?

First of all, D3 doesn't require any specific rendering technology as such. It is mostly (except for some specialised helpers) agnostic of whether you use HTML, SVG, Canvas or something completely different for rendering.
One of the main differences between SVG and Canvas, as you've pointed out, is that SVG has the interaction "built in", i.e. it provides facilities for event listeners and such. Canvas has none of this.
You can however get the same kind of interactivity as in SVG in Canvas. The trick is to use Javascript to monitor what the user does in relation to the various elements. For an introduction to this, see e.g. here.
Note that, depending on what kind of interaction you want exactly, there may be significant implementation effort to achieve the same as SVG already provides. Also note that this incurs a performance penalty which may negate some of the benefits of Canvas over SVG.

Related

SVG filterRes alternative/replacement strategy

When you create an SVG with a shadow, then zoom in/out on your SVG you'll get some serious performance issues due to re-computing the shadows.
In the past, you could use filterRes='' to get around this. However, filterres has been deprecated and removed from the SVG spec.
I'm seeking an alternative to filterRes='', which will allow me to work with things like SVG shadows in a performant way when doing things like zooming in/out which causes shadows to be re-computed.
Does anyone have any experience overcoming performance obstacle that surfaced once filterres was deprecated? Any examples of strategies for replacing the functionality that filterres use to provide?
The easiest thing to do, is to render the shadow to an image an include that in your svg. Starting from that there could be solutions which generate that shadow in different resolutions and pull in the appropriate size on demand. You could as well use a <canvas> to create the shadow client side and hand it over to the svg as base64 encoded image source.
It strongly depends on your application and the performances requirements, so it can be sufficient to have three or for "steps of resultion" pre rendered, or something more complicated needs to be applied...
Btw. You can also reference the <filter> element with Javascript and manipulate the filter attributes directly...
If you can convince the browser to do scaling on the GPU rather than the CPU, this will make things far more performant, so using CSS 3D Transforms rather than JavaScript or viewBox animation to zoom in and out on SVG may do the trick.

What is the best approach to producing graphical charts in a browser?

I've started a new open source project aimed at providing a quality project management experience. To do this, I need access to a set of chart tools (Flash is off the table), and very specifically one that includes a Gantt chart. I've done my homework and shopped around the web and I've more or less come to the conclusion that what I want doesn't exist, at least not for free. So chances are I'm going to have to write this from scratch.
If I was going to create a Gantt chart with which people could interact with (which I'm assuming means having excellent DOM support), then what technology would I use? Should I go with SVG? Or HTML5 Canvas? Something else? Your suggestions are much appreciated.
Also, a requirement would be that whatever library I use needs to be actively supported in the community (i.e. no dead projects).
I would not think there would be many free options as this is a niche-need.
JS Option:
http://www.jsgantt.com/
http://code.google.com/p/flot/
Promising Perl modules:
http://cpansearch.perl.org/src/DARNOLD/DBD-Chart-0.82/dbdchart.html
http://search.cpan.org/~awestholm/Project-Gantt-1.03/Gantt.pm
Update:
There's been amazing advancements in terms of interactive/web charts in the past few years. Shortly before your question was asked, D3.js was created, which has become a generally accepted library, which uses SVG to implement visualizations. Here's a basic example and a more advanced implementation using D3. Note; Gantt charting is still in its infancy; D3 will most likely revisit it in the future.
The argument of Canvas vs SVG is one that has been considered many times. You should read this article by Microsoft; How to Choose Between Canvas and SVG for your Site. Basically, if you have many elements you have to display, Canvas will perform much better. If accessibility is a priority, SVG is better.
In terms of working with Canvas vs SVG, canvas feels more fluid and it is certainly more capable with WebGL, but SVG is more transportable. They both have their merits.
If you're going to make your own, I'd recommend the SVG library Raphaël, which allows you to draw things using SVG fairly easily. It's also simple to make mouse event handlers and other things, which you could use to make it interactive.
I haven't had much experience creating interactive graphics with canvas, but my instinct is that it would be hard to handle mouse events since you don't have "elements" to add event listeners to.

Approach comparison: EaselJS vs Multiple Canvases vs Hidden Canvas for interactiveness

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
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.
Using SVG (and maybe libraries as Raphael)!!
Then any element can receive mouse events.

selectable and movable shapes in html5

I am creating a dynamic, interactive network diagram with php, javascript and either Canvas or SVG
However, with canvas, I don't know how to make each object selectable. i don't want to use the hidden canvas and to detect if a mouse is on an object, because I will have lots of intersecting objects and having lots of layers of canvas will be messy.
I don't know anything about SVG.
Would SVG serves the purpose better? or what is a canvas solution to this.
One advantage of SVG is that it has concrete DOM objects representing the shapes in the drawing, so you automatically get a lot of mouse event handling and event bubbling.
Alternatively, you could use EaselJS, which provides a pretty robust display-list, freeing you from managing hidden canvases.
There are some projects for building diagrams and graphics already. You could try Raphaël which is svg based, so it should be ie compatible as well.
I assume by "the hidden canvas" you mean my tutorial. It will still work with multiple objects and multiple layers, you just need to paint them in the proper z-order.
There are of course much faster (but more sophisticated) ways.
If you don't want to deal with it, SVG has all the object selection built in. Give Raphael a try as Zlatev suggests. If the performance gets too bad (Too many objects) you will have to switch to canvas, so it really depends on your number of nodes/links in your diagrams.
You will have to take care of sending data to your server (in whatever way you prefer) yourself though. There's nothing built into SVG/Canvas/Raphael that will do it for you.

Which technology would you use for Physics Simulations SVG or Canvas?

I'm starting a new project converting physics simulations(created in Adobe Director)
to a more current platform namely html5 canvas or SVG. I would like to avoid Flash for a few reasons. I'm looking for recommendations and reasons why either canvas or SVG would fit this project best. I have read that SVG is better for interactivity which in this case is important but that it is not the best with animation. Canvas is better at animations but it struggles with interaction so I have heard. Does anyone have experience with the interaction side of canvas, is it really that difficult? Please advise. Thanks
See this question for discussion of canvas frameworks and libraries:
What is the current state of the art in HTML canvas JavaScript libraries and frameworks?
A few of the canvas libraries listed replicate SVG in terms of object interaction to a fairly high standard. fabric.js looks particularly nice and is currently being actively developed.
Interactivity in canvas doesn't have to be all that difficult (there are quite a few js libraries out there to help you). And animation in svg is quite possible to do, see e.g svg-wow.org. Remember that you can mix and match svg and canvas as you see fit in order to use the strengths of each of these technolgies, as demonstrated here.

Categories