You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5.9 KiB

D3.js

Basics

Selection

d3.select('css selector') //like document.querySelector()
d3.selectAll() //like document.querySelectorAll()
d3.select('main').selectAll('span'); //can chain to select ancestors

.style()

d3.select('div').style('color', 'orange'); //sets the style for an element
d3.select('div').style({'color': 'blue', 'font-size': '40px'}); //can pass an object
d3.select('div').style('color', 'orange').style({'color': 'blue', 'font-size': '40px'}); //will return the selection for chaining

.attr()

d3.select('div').attr('anExampleAttribute', 'someValue'); //adds/changes an attribute on an selection

.classed()

d3.selectAll('.house').classed('house'); // returns true if all elements in selection contain the chosen class
d3.selectAll('div').classed('frog', true); //adds the class and returns the selection
d3.selectAll('div').classed('frog', false); //removes the class and returns the selection

.append()

d3.selectAll('div').append('span'); //append html to a selection and return appended element

.html()

d3.selectAll('div').html('<span>hi</span>'); //change the inner html of an element

.text()

d3.selectAll('div').html('hi'); //set the content of the selection to the exact text (no html)

Request

AJAX funcions look

  • d3.json('path', function(error, data){});
  • d3.csv('path', function(error, data){});
  • d3.text('path', function(error, data){});
  • d3.html('path', function(error, data){});
  • d3.tsv('path', function(error, data){});
  • d3.xml('path', function(error, data){});

Data binding

  • make a "ghost call" to all circles, even if there are none already
    • d3.selectAll('circle').data(dataArray).enter().append('circle');
    • .data(dataArray) joins each element in dataArray to an element in the selection
    • .enter() returns the sub section of dataArray that has not been matched with DOM elements
    • .append() - creates a DOM element for each of the remaining dataArray elements
    • once data has been bound to elements, you can call something like selection.attr('r', function(d,i){ }) or selection.style('fill', function(d,i){ })
      • callback will be executed for each DOM element
      • d is data for the current element
      • i is the index of that element in the array
    • .exit().remove() examines visual elements that are not bound to data and removes them

Linear Scale

A scale will map a data value to a visual value.

  1. Create a scale. There are many types. Here we'll use a linear scale

    var yScale = d3.scale.linear();
    
  2. Set up a visual range

    yScale.range([height,0]);
    
  3. Find maximum and minimum of the data set (called the "domain" of the data set)

    var yMax = d3.max(data, function(element){
    	return parseInt(element.TMAX);
    })
    var yMin = d3.min(data, function(element){
    	return parseInt(element.TMAX);
    })
    
    var yDomain = [yMin, yMax];
    
    • Can combine this into one call if max/min come from same element:
    var yDomain = d3.extent(data, function(element){
    	return parseInt(element.TMAX);
    });
    
  4. Add the domain

    yScale.domain(yDomain);
    
  5. Can check range and domain after initialization

    yScale.range();
    yScale.domain();
    
  6. Can now pass a data value into the scale to get a visual value

    yScale(361); //returns the visual value that maps to this data value
    
  7. Can go the opposite way

    yScale.invert(800); //returns the data value that maps to this visual value
    

Time Scale

  1. Create the scale

    var xScale = d3.time.scale();
    
  2. Set up the visual range

    xScale.range([0, width]);
    
  3. Set up the date format

    var dateParser = d3.time.format("%Y%m%d");
    
    • you can now parse strings of this format into dates

      dateParser.parse('20010101');//returns a date object
      
    • can get a formatted string from a date object

      dateParser(new Date());
      

Axes

  • Create the x axis

    var xAxis = d3.svg.axis();
    
  • Associate the scale with the axis

    xAxis.scale(xScale);
    
  • Set where on the graph the axis should appear

    xAxis.orient('bottom');
    
  • Set the number of ticks

    xAxis.ticks(8);
    
  • Append a group containing the axis after data has populated the scale

    viz.append('g').call(yAxis);
    

Events

select.on('mouseenter', function(data, index){
	d3.select(this); //select just element that was hovered
	console.log(d3.event); //the event object
})

click, mouseenter and mouseleave are common

use d3.event.sourceEvent.stopPropagation(); when events conflict

Behaviors

Zooming

//generator for a behavior
//scale from 1 - 10
//.on function says, when there's an event of type 'zoom', call the 'zoomed' function.  Could be any event
var zoom = d3.behavior.zoom().scaleExtent([1,10]).on('zoom', zoomed);
var svg = d3.select('#viz-wrapper').append('svg').call(zoom);
function zoomed(){
	console.log(d3.event.translate);//get mouse position
	console.log(d3.event.scale);//bounded by 1,10 as set up above
	viz.attr('transform', 'translate(' + d3.event.translate + ')' + 'scale(' + d3.event.scale + ')');
}

Dragging

var drag = d3.behavior.drag()
	.on('dragstart', dragStart)
	.on('drag', drag)
	.on('dragend', dragEnd);
//....
dotsGroup.call(drag);
//....
function dragStart(d){ //d is the data for the dragged object
	d3.select(this); //the visual object
	d3.event.x; //x position of cursor
	d3.event.y; //y position of cursor
}

You can use the xScale.invert and yScale.invert to get data from d3.event.x and d3.event.y

Basic Layouts