Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pushing D3.js output through fabric.js for IE8 support?

I'm evaluating Fabric.js as an alternative to Raphael.js for creating interactive visualisations that are compatible with IE8, which doesn't support SVG or canvas (IE8 support is non-negotiable unfortunately).

Raphael can be made to work with the visualisation library D3.js - which outputs SVG and is incompatible with IE8 - via the bridging library D34Raphael, a fork of D3 adapted for use with Raphael. D34Raphael adapts some (but not all) D3 features to output into Raphael's abstracted objects instead of the DOM, so that, on IE8, Raphael can interpret D3's output as VML.

(edit Feb 2014 - D34Raphael seems to be dead now, but there's an awesomely named alternative R2D3 that seems to be under active development)

Fabric can output Canvas on IE8 (using excanvas to convert to VML), and can convert SVG to interactive Canvas elements. So, it seems theoretically possible that Fabric could replace Raphael in bridging D3 and IE8. Doing so would bring the added flexibility of also supporting Canvas functionality as well as SVG.


I've not found any Fabric equivalent to D34Raphael - the closest I can find is this demo page which doesn't work in IE8.

From what I've seen of the Fabric docs, it looks like something like D34Raphael could be attempted for Fabric: it supports converting SVG path, circle, polygon, polyline, ellipse, rect, line, and image elements, and works with abstracted objects that allow for ongoing interactivity. The benchmarks comparing performance of Fabric handling vector paths compared to Raphael handling the same are impressive (although no comparison benchmarks are given that involve interaction or animation).

A couple of typical D3 projects as examples:

  • Force directed graphs
  • Radial node-link tree diagrams

I'm sure I'm not the first to have looked into this. I don't much like the idea of launching into trying to implement something like this, only to find there's some unavoidable problem that anyone more experienced with Fabric, Canvas and/or D3 could have pointed out from the start.

  • Are there any existing projects that allow D3 output to be rendered using fabric.js, similar to D34Raphael?
  • Is there anything about how D3 works with SVG that simply couldn't be piped through Fabric's SVG to Canvas conversion and object model?
  • Is there any simpler way to push D3 output through Fabric than the D34Raphael approach of forking the D3 project and adapting its output?

What I've tried: Some issues I've already looked into:

  • Fabric will have a similar problem as D34Raphael in being very limited in its ability to adapt D3's DOM querying tools (since it works with abstracted objects, not DOM elements) - but that's something that can be worked around with a well-organised object structure.
  • Both Raphael and Fabric use VML in IE8, but through different engines, so there may be differences in what features Raphael and Fabric's excanvas have managed to implement in VML. In my testing so far, both have poor performance with animation and interactivity in IE8, but features seem comparable, and Fabric seems to be much better than Raphael for rendering VML text in IE8.
  • Fabric's performance with shapes converted from SVG seems great, and it seems as if redraws, interactivity and animation based on D3 should be smooth since these require similar processes to the initial draw (but there may be something I've not thought of here).
  • It appears that Fabric's groups are more like the native SVG groups worked with by D3 than Raphael's sets (but I may have overlooked something here).

like image 302
user56reinstatemonica8 Avatar asked Jul 23 '13 18:07

user56reinstatemonica8


1 Answers

Disclaimer: I'm the author of Fabric.js

Very interesting question. To address your points:

Are there any existing projects that allow D3 output to be rendered using fabric.js, similar to D34Raphael?

Not that I know of. But from what I can see, D3.js has SVG output. And Fabric has SVG parser, so it seems pretty straightforward to feed D3's markup to Fabric for rendering.

Is there anything about how D3 works with SVG that simply couldn't be piped through Fabric's SVG to Canvas conversion and object model?

I'm not really familiar with D3, but looking at one of the examples you linked to, I see some compatibility issues indeed. I copied entire SVG markup of "force directed graphs" and loaded it in kitchensink

enter image description here

Circles are rendered properly-ish, but something is off with lines. Curiously, all the lines are parsed and loaded onto canvas correctly. But they're not visible. Why? Because their styles in D3.js are defined via ".line" class and we don't support stylesheet parsing in Fabric.

.link {
  stroke: #999;
  stroke-opacity: .6;
}

If we were to "unroll" those styles unto each line (either via "stroke" and "stroke-opacity" attributes or style="stroke: ...; stroke-opacity: ...;") it would work as expected.

I imagine the problem with white outlines around circles has the same roots.

Is there any simpler way to push D3 output through Fabric than the D34Raphael approach of forking the D3 project and adapting its output?

Can't think of anything really.

like image 145
kangax Avatar answered Oct 21 '22 18:10

kangax