D3.js
Much more like a library like jQuery, than a framework like angular.js
Focused od data Visualisation
D3.js uses "document traversal" aka. DOM traversal
you can chain all the methods toogether
to use it in node.js (where lacking DOM) you can require some DOM implementations
like JSDOM
npm install d3
<script src="http://d3js.org/d3.v3.min.js"; charset="utf-8"></script>
SVG
scalable vector graphics
xml format
positioning
(positiveX, positiveY)
(negative X, negative Y)
figures
circle
attributes
r
cx
cy
line
x1, y1
x2, y2
stroke
color
stroke-width
g element
Is a contianer used to group objects
Transformations applied to the g element are performed on all of its child elements.
you can use it to attach style or events to multiple elements (children of g element)
ex.
geometry
is changed by .attr
aestetic
is changed by .style
text element
do not support margins and paddings
dy
is used to center it verticaly
JSON
Data Format of a modern web browser :)
JavaScript Object Notation
Objects
Array of values
Keys:Values
Primitive Ojbects/Nested Objects
selecting
dot notation
objectName.nestedObjectName.keyName
from array (0 based notation)
test.phones[0]
braces
objectName['keyName']
to check array lenght
arrayName.lenght
steps
Load
Select & Bind
Enter and Append
Transform & Translate
Transistion
Exit
charts functions
d3.layout.pie()
selections
adding functions
.each(function)
The .each() method calls the function argument for each element inside the
Selection
ex.
selection.call(function[, arguments…])
you can call function that you have declared with arguments
ex.
methods
.classed()
return true of false depending on class attached to element
d3.select('#tree').classed('house')
it return false, becouse element (#tree) don't have class ('hosue')
d3.select('div').classed('house')
return false becouse non all div has calss ('.hosue')
we can also give and deleted class of selected documents by this method
d3.selectAll('div').classed('house',true)
all divs will have calss="house"
it will return a selection
d3.selectAll('div').classed('hosue', false)
none of the divs will have class="house"
request()
asynchronius of course
non-blocking
D3 Data Formats
data binding
methods of binding data to selected element
core of D3
ghost selection | empty selection
you can select element that not exist yet
also...after selecting DOM element you have access to the data that is bind to selected element
.data(values[, key])
for binding data from file to choosen element
it returns the number of elements = number of data records
key is additional parameter
you can call a function there, that interacts with every data item
enter()
ex.
Using dynamic properties in Selections
circles.attr('r', function(d, i) { return d; });
you can also access data from the array of objects
circles.attr('r', function(d, i) { return d.r; });
.attr('fill', function(d, i) { return d.color; })
Set the fill color
depending of the bound object
we can also set the properties depending on index i value
circles.style('stroke-width', function(d, i) { return i*2; }) ;
.append()
it will append svg element to the current selections
.append returns a new selection
svg
.append('svg').attr('width', 200px).attr('height', 200px)
figure
.append('circle')
.attr('attribute', 'value')
gives HTML attribute to the selected svg element
for example takes one piece of data, and bind it to "r" attr of a circle
ex.
value is offten a function
it can takes 2 parameters
d - data or datum
i - index value of the data
optional
math
Math.abs()
return a absolute value (when you dealing with nagative numbers)
Math.max(0, 10)
gives you maximum value from equation
=== 10
ex.
text()
debbuger in chrome dev tools
to explore what data is bind to where
by accessing d in the console
Sources tab are really helpful with debbuging
You can open any files, and set break points to run your code to a specyfic line
and later access the variable or function in the given time
you can write "debugger" into your code, and app will stop there
styling
Events
Converting visualisation into angular app
Creating directive with chart code
make an app
link to angular libarary of course
var app = angular.module("myApp", []);
connect app into html <body>
<body ng-app= "myApp" ng-controller="chartNameController">
make an chart element inside html <chart-name data="chart" ng-reapat="chart in charts"></chart-name>
Subtopic
make an derective (inside an app) where code for a chart goes
app = directive('chartName', function() { })
function link (scope, el) { //d3 code inside, el is an element }
you can pull the data out the chart function
var data = scope.data;
it reference to the <chart-name data=[21,5,9]></chart-name> in html
it should return an link
return { link:link, restrict: 'E', scope: {data: '=' } };
write css on the element not a class of the element
creating controller for the chart
<body ng-app="myApp" ng-controller="chartNameController">
app.controller("ChartNameController", function($scope) { //code inside })
$scope.charts = d3.range(10).map(function() { return d3.range(10).map(Math.random) })
random data with 10 values for 10 charts
making visualisation responsive
inside chart element ng-style="{width: 100 / charts.length + '%' }"
with: 100%;
height: 100%;
inside chart code
scope.$watch(function() { return el.clientWidth * el.clientHeight}, function() { width = el.clientWidth height = el.clientHeight })
all the variables that depends on with and height goes inside secon function
inside controller we have to tell angular to watch the widow changes
angular.element($window).on('resize', function(){ $scope.$apply() })
how to design it
every visualisation element should be write as a custom derective
ex.
app.directive('d3ChordDiagram', function(){ ... });
<d3-chord-diagram data="data"></d3-chord-diagram>
in HTML
we can alter the visualisation by writing a custom filters
ex.
app.filter('startDate', function(){ ... });
<d3-line-chart data="timeData | startDate:'01.01.2015'"></d3-
line-chart>
in HTML