O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
I M P R O V I N G D 3 P E R F O R M A N C E W I T H
C A N VA S A N D O T H E R H A C K S
WebTechCon 2015
2015-10-27
Philip Tellis
@bluesmoon
https://github.com/lognormal/boomerang
http://www.soasta.com/mpulse/
D 3 I S …
• A JavaScript library that maps Data to DOM Nodes
• Extended via layouts & plugins for rich data
visualisations...
H T T P S : / / G I T H U B . C O M / M B O S T O C K / D 3 /
W I K I / G A L L E RY
G E T S TA R T E D W I T H D 3
B A S I C D 3 T U T O R I A L
• Adding nodes
• Mapping data to nodes
• Data Driven Documents
• Examples 01-06 at http://so...
A N I M AT E D D 3 C H A R T S
• Force Directed Layout
• Reacting to user interaction
• Reacting to changing data
F O R C E D I R E C T E D L AY O U T
U S I N G P H Y S I C S
F O R C E D I R E C T E D L AY O U T
• http://bl.ocks.org/mbostock/4062045
• Took basic Force Directed Layout and added
en...
F O R C E D I R E C T E D L AY O U T —
P R O B L E M S
• Rendering is O(n) based on number of SVG nodes
• Calculations are...
F O R C E D I R E C T E D L AY O U T —
S O L U T I O N S
• Reduce number of links by using a Minimum Spanning
Tree
• Ident...
F O R C E D I R E C T E D L AY O U T —
A D D I T I O N A L O P T I O N S
• We could use CANVAS to get rid of SVG nodes
• C...
E D G E B U N D L E D L AY O U T
U S E R I N T E R A C T I O N
E D G E B U N D L E D L AY O U T
• http://bl.ocks.org/mbostock/7607999
• We added many more links
• Links colored based on...
E D G E B U N D L E D L AY O U T — P R O B L E M S
• Default behaviour is to iterate through every link on
mouseover and c...
E D G E B U N D L E D L AY O U T — S O L U T I O N S
• First we tried to not iterate, just use CSS class
cascades
• This w...
E D G E B U N D L E D L AY O U T — S O L U T I O N S
• The second attempt was to use CANVAS to draw
everything
• The probl...
E D G E B U N D L E D L AY O U T — S O L U T I O N S
• The third attempt was to use CANVAS to draw links
and SVG for nodes...
C A N VA S D O E S N O T
S U P P O R T B E Z I E R C U R V E S ! ! !
E X C E P T …
D 3 W I T H C A N VA S
• There are some great examples online…
• https://bocoup.com/weblog/d3js-and-canvas
• https://gist....
D 3 W I T H C A N VA S
• Create a Custom XML NameSpace
• Map dummy nodes from this namespace for each link
• Each dummy no...
d3.ns.prefix.custom = "https://foo-bar.com/edge_bundling.html";
d3.select("body").append("custom:sketch")
.classed("link-c...
var pathAttrs =
["strokeStyle", "lineCap", "lineJoin", "lineWidth"];
ctx.beginPath();
pathAttrs.forEach(function(a) {
var ...
var path = node.attr("d"), m;
while((m = path.match(/^ *([MLCQ])([d.,e-]+) */))) {
var cmd = m[1];
var coords = m[2].split...
B U T I T S T I L L WA S N ’ T
FA S T E N O U G H !
E N H A N C E M E N T S
• Use 2 CANVAS elements,
• one to hold the background (ie, all links),
• the second to show the cu...
S U M M A RY
• Number of DOM nodes is very significant
• Reduce calculations on in-memory objects
• Show approximate data,...
Thank You
Próximos SlideShares
Carregando em…5
×

Improving D3 Performance with CANVAS and other Hacks

Talk about D3 Performance from WebTechConf 2015 in Munich

  • Entre para ver os comentários

Improving D3 Performance with CANVAS and other Hacks

  1. 1. I M P R O V I N G D 3 P E R F O R M A N C E W I T H C A N VA S A N D O T H E R H A C K S WebTechCon 2015 2015-10-27
  2. 2. Philip Tellis @bluesmoon https://github.com/lognormal/boomerang http://www.soasta.com/mpulse/
  3. 3. D 3 I S … • A JavaScript library that maps Data to DOM Nodes • Extended via layouts & plugins for rich data visualisations • You still need to write code to draw things • Fast on its own, but you can easily make it sluggish • BSD Licensed — http://d3js.org/
  4. 4. H T T P S : / / G I T H U B . C O M / M B O S T O C K / D 3 / W I K I / G A L L E RY G E T S TA R T E D W I T H D 3
  5. 5. B A S I C D 3 T U T O R I A L • Adding nodes • Mapping data to nodes • Data Driven Documents • Examples 01-06 at http://soasta.github.io/improving- d3-performance/d3/
  6. 6. A N I M AT E D D 3 C H A R T S • Force Directed Layout • Reacting to user interaction • Reacting to changing data
  7. 7. F O R C E D I R E C T E D L AY O U T U S I N G P H Y S I C S
  8. 8. F O R C E D I R E C T E D L AY O U T • http://bl.ocks.org/mbostock/4062045 • Took basic Force Directed Layout and added enhancements: • Convex hulls • Labels • Mouseovers • Variable sized points
  9. 9. F O R C E D I R E C T E D L AY O U T — P R O B L E M S • Rendering is O(n) based on number of SVG nodes • Calculations are O(n2 ) based on number of links • Drawing the hull is expensive as nodes move around a lot
  10. 10. F O R C E D I R E C T E D L AY O U T — S O L U T I O N S • Reduce number of links by using a Minimum Spanning Tree • Identify clusters and only link one node from each cluster • Visually reduce nodes within the cluster using approximation • Add decorators later as the animation stabilizes
  11. 11. F O R C E D I R E C T E D L AY O U T — A D D I T I O N A L O P T I O N S • We could use CANVAS to get rid of SVG nodes • Create subgroups within each group to further reduce links • Get rid of some of our visual enhancements
  12. 12. E D G E B U N D L E D L AY O U T U S E R I N T E R A C T I O N
  13. 13. E D G E B U N D L E D L AY O U T • http://bl.ocks.org/mbostock/7607999 • We added many more links • Links colored based on performance • Links sized based on volume of data flow • Mouseover should highlight connected links • Nodes sized based on volume within that node
  14. 14. E D G E B U N D L E D L AY O U T — P R O B L E M S • Default behaviour is to iterate through every link on mouseover and change colour — this is slooooow! • Using CSS class to change colour causes major re- render • Quickly cycling through nodes has noticeable lag
  15. 15. E D G E B U N D L E D L AY O U T — S O L U T I O N S • First we tried to not iterate, just use CSS class cascades • This was a trade off because we ended up adding a large number of classes, two per node and one per link
  16. 16. E D G E B U N D L E D L AY O U T — S O L U T I O N S • The second attempt was to use CANVAS to draw everything • The problem here is that CANVAS is not great for text, and mouseovers no longer worked
  17. 17. E D G E B U N D L E D L AY O U T — S O L U T I O N S • The third attempt was to use CANVAS to draw links and SVG for nodes • The biggest problem was to make sure they overlapped perfectly, ie, it was a small problem.
  18. 18. C A N VA S D O E S N O T S U P P O R T B E Z I E R C U R V E S ! ! ! E X C E P T …
  19. 19. D 3 W I T H C A N VA S • There are some great examples online… • https://bocoup.com/weblog/d3js-and-canvas • https://gist.github.com/mbostock/1276463 • But not quite what we wanted
  20. 20. D 3 W I T H C A N VA S • Create a Custom XML NameSpace • Map dummy nodes from this namespace for each link • Each dummy node contains the SVG path required to draw the curve as well as other attributes • After all nodes have been mapped, call a renderer to convert this to CANVAS
  21. 21. d3.ns.prefix.custom = "https://foo-bar.com/edge_bundling.html"; d3.select("body").append("custom:sketch") .classed("link-container", true); … linkBinding.enter() .append("custom:path") .attr("lineCap", "round") .attr("lineJoin", "round") .attr("lineWidth", .2) .attr("opacity", 0.1) .attr("selected-opacity", 0.3); linkBinding .attr("selected-lineWidth", function(d) { return weightScale(d.weight); }) .attr("d", function(d) { return line(d.path); }); C R E AT I N G N O D E S
  22. 22. var pathAttrs = ["strokeStyle", "lineCap", "lineJoin", "lineWidth"]; ctx.beginPath(); pathAttrs.forEach(function(a) { var val = node.attr(selected + a) || node.attr(a); if(a === "strokeStyle") { var color = d3.rgb(val); val = "rgba(" + color.r + "," + color.g + "," + color.b + "," + node.attr(selected + "opacity") + ")"; } ctx[a] = val; }); A P P LY I N G S T Y L E S
  23. 23. var path = node.attr("d"), m; while((m = path.match(/^ *([MLCQ])([d.,e-]+) */))) { var cmd = m[1]; var coords = m[2].split(",").map(pathToCoords); path = path.replace(/^ *([MLCQ])([d.,e-]+) */, ""); switch(cmd) { case "M": ctx.moveTo(coords[0], coords[1]); break; case "L": ctx.lineTo(coords[0], coords[1]); break; case "C": ctx.bezierCurveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); break; case "Q": ctx.quadraticCurveTo(coords[0], coords[1], coords[2], coords[3]); break; } } D R A W I N G C U R V E S
  24. 24. B U T I T S T I L L WA S N ’ T FA S T E N O U G H !
  25. 25. E N H A N C E M E N T S • Use 2 CANVAS elements, • one to hold the background (ie, all links), • the second to show the currently selected links • Change opacity on the background to darken it • If mouse pointer returns to last selected node, just redisplay
  26. 26. S U M M A RY • Number of DOM nodes is very significant • Reduce calculations on in-memory objects • Show approximate data, based on available pixels and power • Use CANVAS when mouse interaction is not required • Cache repeated states rather than redrawing them
  27. 27. Thank You

×