Tuesday, October 6, 2015
Fullscreen D3 graphs
What are we going to tackle?
When creating D3 graphs, the more graphs you put in your page, the less readable it tends to be. A friend of mine advise me to set my graphs in fullscreen. I immediately loved the idea. That would definitely help users to focus.What do we need to solve?
- Our graphs need to be responsive: when they will be toggled on fullscreen, they need to expand and take as much space as possible.
- When setting up fullscreen, the viewport is black despite all your already setup styles.
- Tooltips on your graphs needs to be included in the fullscreen's viewport.
- As your viewport is changing so are the references on where your tooltips needs to be displayed.
Piece by piece solution
First, let's setup our markup in Jade. figure is our SVG container, the div, .svg-content, is where D3 will place our SVG content and the div, .tip, is our tooltip for this graph:
figureNow, we need to setup our style so that our SVG content takes the available width of its container or the width of the viewport when it will be set on fullscreen. Note that we also need to set the background color of the container so that we don't end up with a black viewport. Here is the relevant extract of the Sylus file:
.svg-content
.tip
span Point
.arrow
// Container for responsive SVGFor the tooltip, we use a fixed position that will be modified using our logic. The style is pretty straightforward in Stylus:
// Mixin for creating SVG container with specific aspect ratio
svgContainer()
display inline-block
position relative
width 100%
vertical-align middle
overflow hidden
figure
display inline-block
absolute top left
height 100%
margin 0
// This container targets 1:1 SVG
svgContainer()
.svg-content
// Here are the properties for the fullscreen content
&:fullscreen
size 100%
background white
.tipNow, for creating a responsive D3 graph, we need to use the preserveAspectRatio and the viewBox attributes on the graph instead of the regular width and height on the SVG tag. This is what is done by the following logic in Coffee on a 100x100 graph:
fixed top left
svgWidth = svgHeight = 100Setting the graph in fullscreen is eased thanks to screenfull.js. This library provide a cross browser API of the vanilla JavaScript Fullscreen API:
svg = d3.select '.svg-content'
.append 'svg:svg'
.attr 'preserveAspectRatio', 'xMinYMin meet'
.attr 'viewBox', "0 0 #{svgWidth} #{svgHeight}"
Template.home.rendered = ->Now, we need to adjust the tooltips so that they are positioned properly. In our example, we are using a Voronoï diagram. Hovering on the path elements of the Voronoï is triggering the tooltip of its points modeled by circle elements. Getting the position is achieved thank to the DOM API getBoundingClientRect:
@fullscreen = ->
return screenfull.exit() if screenfull.isFullscreen
target = (@$ '.svg-content')[0]
screenfull.request target
Template.home.events
'click button': (e, t) ->
$button = t.$ e.target
role = $button.attr 'data-role'
t.fullscreen() if role is 'fullscreen'
tip = @$ '.tip'
@positionSetTip = (circle) ->
rect = circle[0].getBoundingClientRect()
tip.css 'transform', "translate3d(\
#{rect.left + .5 * (rect.width - tip.width())}px,\
#{rect.top - tip.height()}px, 0)"
@showHideTip = -> tip.toggleClass 'show'
@showTip = -> Meteor.setTimeout (-> tip.addClass 'show'), 300
# A debouncing function is used for transitioning over path
@lazyShowHideTip = _.debounce @showHideTip, 300
path = svg.append 'g'
.selectAll 'path'
svg.append 'g'
.selectAll 'circle'
.data vertice
.enter()
.append 'circle'
.attr 'transform', (d) -> "translate(#{d.toString()})"
.attr 'r', 1
data = path.data (voronoi vertice)
data
.enter()
.append 'path'
.attr 'd', polygon
.order()
.on 'mouseover', (d, i) =>
circle = $ "circle:nth-child(#{i + 1})"
@positionSetTip circle, i
@showTip()
.on 'mouseleave', =>
@lazyShowHideTip()
data.exit().remove()
Some links
- Demo of a Voronoï diagram set in fullscreen.
- Source of the demo is available on Github.
- The library used for easing the cross browser setup of the Fullscreen API: screenfull.js.
- Creative & Pure is the used CSS framework for this little demo.
Bonus
On the demo, I've also added some features like:
- An animated tooltip: when entering or leaving a small animation is done.
- The Voronoï graph is animated using a simple random function.
- Key events are handle to let you set the graph in fullscreen or to animate it.
Happy coding!
Location:
Paris, France
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment