Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3.js : orthographic rotation optimization

I made a map using an orthographic projection and I try to improve performance because the rotation is not smooth (around 6-7FPS).

It's a map of the world built with a topojson file (world-100m). I need to interact with country and colorized them so there is as many svg:path as there are countries.

After the loading I have an automatic rotation function launched using d3.timer :

autoRotate = () =>
  @start_time = Date.now()     # Store the current time (used by automatic rotation)

  d3.timer () =>
    dt = Date.now() - @start_time

    if @stopRotation or dt > @config.autoRotationDuration
      true
    else
      @currentRotation[0] = @currentRotation[0] - @config.autoRotationSpeed
      @projection.rotate @currentRotation
      redrawPathsOnRotationOrScale(@currentRotation, @projection.scale())
      false

redrawPathsOnRotationOrScale = (rotation, scale, duration = 1) =>
  @currentRotation = rotation

  @projection
    .rotate(@currentRotation)
    .scale(scale)

  @groupPaths.selectAll("path")
    .attr("d", path)

To understand why it was so slow, I made a profile record in Chrome and here is the result :

Chrome profiling 1/2Chrome profiling 2/2

It seems the Animation Frame Fired is the slow part but I don't really know what it is. And when I open it, there is 2 GC Event (garbage collector ?) but nothing around... Do you have an idea what is happening during this 90ms ?

Any tips to improve the performance is more than welcome :-)

Thanks by advance !

By the way, it looks like this : Map overview

like image 945
John Smith Avatar asked Jul 10 '13 07:07

John Smith


2 Answers

Try reducing the complexity of the SVG paths by adjusting the --simplify-proportion, -s or --quantization topojson flags. Browsers still have fairly poor SVG rendering performance, and with maps it really helps to reduce the number and precision of the points.

like image 96
Yuri Feldman Avatar answered Nov 01 '22 01:11

Yuri Feldman


D3.js uses Request Animation Frames to perform timers.

From D3 documentation:

If your browser supports it, the timer queue will use requestAnimationFrame for fluid and efficient animation.

As I know it's the best approach to perform animations in modern browsers and I don't think you can directly optimize this part. Otherwise it seems that you call stack use selection_each that could probably be cached into a variable.

like image 2
Pirhoo Avatar answered Nov 01 '22 01:11

Pirhoo