How To Guide:
Intro to Visualizations

Bar Graph

Tutorial Steps taken from interactive demo here: https://www.rtfmanual.io/d3garden

Step 1: The SVG Canvas

D3 uses SVG (Scalable Vector Graphics) to draw its elements.
Create an area to create the visualization in.
<div class="canvas"><div>

Step 2: Declare SVG

Define the canvas.

This can be done with the following statement:

var svg = d3.select('div.canvas').append('svg').attr('width', '648px').attr('height', '452px');

This takes advantage of D3’s chaining. Breaking the statement down:
1. Select the canvas. var svg = d3.select('div.class')
2. Append the svg. .append('svg')
3. Set width and height. .attr('width', '648px') .attr('height', '452px')

Step 3: selectAll() Statement

selectAll() declares a more specific group where you will be adding elements.

What It Does

selectAll() creates an empty set that will later be filled with elements.

Step 4: selectAll() in action

How to use selectAll()

svg.selectAll('rect.colorBar')

This statement looks for all rect elements (SVG) with class 'colorBar'. If there are none, it creates an empty set.

Step 5: data() Statement

data() declares the object or array you will use for the visualization. Your actual dataset is passed to it.

What It Does

data() and its argument sets the data that will be iterated through. This creates a series of elements, one for each item in the dataset.

Step 6: Add data()

Check out the properties of each element. These are what can be assigned to attributes of the SVG elements for your graph.

var tomatoes = [
  {"width":25,"height":86,"color":"red"},
  {"width":25,"height":84,"color":"red"},
  {"width":25,"height":98,"color":"red"},
  {"width":25,"height":93,"color":"red"},
  {"width":25,"height":68,"color":"red"},
  {"width":25,"height":70,"color":"red"},
  {"width":25,"height":76,"color":"red"},
  {"width":25,"height":77,"color":"red"},
  {"width":25,"height":95,"color":"red"},
  {"width":25,"height":100,"color":"red"},
  {"width":25,"height":90,"color":"red"},
  {"width":25,"height":75,"color":"red"},
  {"width":25,"height":65,"color":"red"},
  {"width":25,"height":80,"color":"red"},
  {"width":25,"height":78,"color":"red"},
  {"width":25,"height":76,"color":"red"},
  {"width":25,"height":94,"color":"red"},
  {"width":25,"height":78,"color":"red"},
  {"width":25,"height":69,"color":"red"},
  {"width":25,"height":93,"color":"red"},
  ]
How to use data()

svg.selectAll('rect.colorBar').data(tomatoes)

data() declares the object or array for iteration.

Step 7: enter() the data

enter() performs the data join and returns the subset of new entries.

 svg.selectAll('rect.colorBar').data(tomatoes).enter()  

What It Does

enter() combines your data with the empty set from selectAll() and creates a set of elements that can then be accessed one by one in D3

Step 8: append() the element

append() determines the type of visualization based on what it's passed.

What It Does

append() allows you to choose from the 7 basic SVG elements or a 'g' element. A 'g' element groups SVG shapes together.

In this case, we want a 'rect' element to build a bar graph.

 svg.selectAll('rect.colorBar').data(tomatoes)
    .enter().append('rect')   

Step 9: Quick Review

We are close to building the bar graph! So far, we've defined data, selected the empty set of rect elements of class bar, added the dataset, joined the data with the empty set, and added a rect element for each item in the data.

var tomatoes = [
  {"width":25,"height":86,"color":"red"},
  {"width":25,"height":84,"color":"red"},
  {"width":25,"height":98,"color":"red"},
  {"width":25,"height":93,"color":"red"},
  {"width":25,"height":68,"color":"red"},
  {"width":25,"height":70,"color":"red"},
  {"width":25,"height":76,"color":"red"},
  {"width":25,"height":77,"color":"red"},
  {"width":25,"height":95,"color":"red"},
  {"width":25,"height":100,"color":"red"},
  {"width":25,"height":90,"color":"red"},
  {"width":25,"height":75,"color":"red"},
  {"width":25,"height":65,"color":"red"},
  {"width":25,"height":80,"color":"red"},
  {"width":25,"height":78,"color":"red"},
  {"width":25,"height":76,"color":"red"},
  {"width":25,"height":94,"color":"red"},
  {"width":25,"height":78,"color":"red"},
  {"width":25,"height":69,"color":"red"},
  {"width":25,"height":93,"color":"red"},
  ]
  
How to define each bar
 svg.selectAll('rect.bar').data(data)
    .enter().append('rect') 
    

svg.selectAll('rect.bar') = Creates an empty set of rect elements with class 'bar'
.data(data) = Adds object or array of data to be turned into elements in the DOM
.enter() = Join your data with the empty set defined in selectAll, can iterate through this set
.append('rect') = Append a 'rect' element for every item in data

Step 10: Define Bar Width

attr() statements define the properties of each bar. The attributes specific to each type of SVG element can be reviewed here.

What It Does

 .attr('width' , function (d,i) { return d.width }) 

attr() statements define how you want your bars to appear. Specifically, they can be assigned properties of data points.

Step 11: Define Bar Height

Continue defining each element’s attributes with height.

What It Does

.attr(‘height’ , function (d,i) { return d.height })

In the statement function(d,i), d represents items in the data and i is the index of elements, beginning at 0.

Step 12: Put Bars In A Row

Separate bars from each other. When new bars are created from a dataset they are set to coordinates of (0, 0) so we have to set some attributes to separate them. You will likely want your bar graph data already ordered by your x-axis values.

What It Does

 .attr('x' , function (d,i) { return i * d.width }) 

The last statement created a bunch of bars stacked on top of each other. This is because of the default values for the attributes. We have to define x values for this type of bar chart for them to be spaced out appropriately. To space them out we can multiply the index of each bar by the width of the bars to spread them out.

Step 13: Bar Orientation

The origin is the top left corner so the bars are likely upside down.

What It Does

 .attr('y' , function (d,i) { return divHeight - d.height }) 

Since the start point (origin) for D3 is the top left corner of the div, bar charts will come down from the top of the div. So, how do we fix this?
We need to set a new starting point. To do this, we subtract the bar height from the overall height. This fixes the problem!

Final Code for the Internal Portion of the Bar Graph

var w= 535;
var h= 250;
var svg= d3.select('.gardenDiv')
    .append('svg')
    .attr('width', w)
    .attr('height', h);

svg.selectAll('rect.colorBar')
    .data(data)
    .enter()
    .append('rect')
    .attr('width', function(d,i){
        return d.width
    })
    .attr('height', function(d,i){
        return d.height*2
    })
    .attr('x', function(d,i){
        return i * (d.width+2)
    })
    .attr('y', function(d,i){
        return h - d.height*2
    })
    .attr('fill', 'white')

This is not the code that creates the bar chart at the top of the page.

Add X and Y Axis

Step 14: Scale on X Axis

Before we add an axis to the graph, we need to define the start and end point of the graph.

How to define a scale
var xScale = d3.scale.linear()
.domain( [0, data.length] )
.range( [0, width] ); 

d3.scale.linear() = Indicates your scale will be linear across the range specified, as opposed to exponential etc.
.domain( [0, data.length] ) = Specifies that the scale ranges from 0 to the count of total number of items in the array.
.range( [0, width] ) = Maps the specified domain to corresponding spots on the SVG. In this case, extends the full width of the SVG.

Step 15: Scale on Y Axis

Before we add an axis to the graph, we need to define the start and end point.

How to define a scale
 var yScale = d3.scale.linear()
.domain( [0, d3.max(data, function(d) { return d.height; })] )
.range( [0, height] ); 

d3.scale.linear() = Indicates your scale will be linear across the range specified, as opposed to exponential etc.
.domain( [0, d3.max(data, function(d) { return d.height; })] ) = Specifies that the scale ranges from 0 to the tallest bar, which d3.max will find based on the height attribute
.range( [0, height] ) = Maps the specified domain to corresponding spots on the SVG. In this case, extends the full height of the SVG.

Step 16: Create X Axis, Pt 1

Now that we have scales, we can append() them as elements in the DOM.

How to define an axis
 var xAxis = d3.svg.axis().scale(xScale) 

d3.svg.axis() = Indicates that we want to create an element with the characteristics of an axis i.e. can have labels and tick marks.
.scale(xScale) = Specifies that we want to use the xScale we already specified.

Step 17: Create X Axis, Pt 2

Now we can use an append() statement to get this axis on the graph.

How to append an axis
 svg.append("g").call(xAxis); 

.append("g") = An axis isn't just a line; it can also have text for labels and tick marks. Since it has multiple elements to it, this would be a 'g' element in SVG.
.call(xAxis) = This will define the axis based on what's in the xAxis function.

Step 18: Create Y Axis, Pt 1

Now that we have scales, we can turn them into elements in the DOM.

How to define an axis
 var yAxis = d3.svg.axis().scale(yScale)
.orient("left") 

d3.svg.axis() = Indicates that we want to create an element with the characteristics of an axis i.e. can have labels and tick marks.
.scale(yScale) = Specifies that we want to use the xScale we already specified.
.orient("left") = Specifies that this will be a vertical axis, from bottom to top.

Step 19: Create Y Axis, Pt 2

Now we can use an append() statement to get this axis on the graph.

How to append an axis
 svg.append("g").call(yAxis); 

.append("g") = An axis isn't just a line; it can also have text for labels and tick marks. Since it has multiple elements to it, this would be a 'g' element in SVG.
.call(yAxis) = This will define the axis based on what's in the xAxis function.

More information about axes, graphs, and D3 in general:

http://alignedleft.com/tutorials/d3/axes
http://alignedleft.com/tutorials/d3

Why do I care about D3?

This guide was written as an assignment for Oregon State's CS 290 course. I selected this topic because I am a business intelligence developer working with SAP's platforms including BOBJ (BusinessObjects). My team is fairly new within the company and we are quickly learning our limitations for graphical representations. I plan to leverage what I learned from researching and writing this in development of extensions for use with Design Studio. For those who are unfamiliar, Design Studio makes heavy use of CSS and JavaScript.

Image