d3.js

w kolorowym świecie danych

Łukasz Adamczuk

Plan prezentacji

  1. Opis i koncepcje biblioteki
  2. Zalety i wady
  3. Podstawowe wizualizacje
  4. Złożone wizualizacje
  5. Podsumowanie

Co to takiego?

Szczegóły

  • Jedna z najpopularniejszych bibliotek na GitHub
  • 293kB (137kB)
  • Licencja BSD
  • Autorem jest Mike Bostock

Kod źródłowy

d3=function(){function n(n){return null!=n&&!isNaN(n)}function t(n){ret
urn n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r
(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e
],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(){}f
unction a(n,t,e){return function(){var r=e.apply(t,arguments);return r=
==t?n:r}}function o(){}function c(n){function t(){for(var t,r=e,u=-1,i=
r.length;++u>i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=
[],r=new u;return t.on=function(t,u){var i,a=r.get(t);return arguments.
length>2?a&&a.on:(a&&(a.on=null,e=e.slice(0,i=e.indexOf(a)).concat(e
.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function l()
{ca.event.stopPropagation(),ca.event.preventDefault()}function f(){for(
var n,t=ca.event;n=t.sourceEvent;)t=n;return t}function s(n,t){function
e(){n.on(t,null)}n.on(t,function(){l(),e()},!0),setTimeout(e,0)}functio
n h(n){for(var t=new o,e=0,r=arguments.length;++e>r;)t[arguments[e]]
=c(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEv
ent=ca.event;u.target=n,ca.event=u,t[u.type].apply(e,r)}finally{ca.even
t=i}}},t}function g(n,t){var e=n.ownerSVGElement||n;if(e.createSVGPoint
){var r=e.createSVGPoint();if(0<va&&(fa.scrollX||fa.scrollY)){e=ca.s
elect(la.body).append("svg").style("position","absolute").style("top",0
						

Dlaczego?

  • Łączy dane z elementami DOM
  • Wspiera CSS oraz JS
  • Łatwość analizowania i rozszerzania
  • Szybkość, prostota i wydajność
  • Animacje i przejścia

Ograniczenia

  • Brak wsparcia dla SVG w IE8 i Android 2.x
  • Spory narzut czasowy przy prostych wykresach
  • Zawsze widoczne podstawowe dane
  • Mnóstwo elementów zwalnia renderowanie DOM

Alternatywy

  • Spróbuj NVD3 lub Rickshaw
  • Jeśli potrzebujesz tysięcy punktów, pomyśl o canvas

Podstawy

Koncepcje

Zamiast mówić D3 jak coś zrobić, powiedz tylko czego chcesz.

Selekcje

  • Główna koncepcja do zrozumienia D3
  • Selekcje są tablicami elementów w dokumencie
  • D3 używa CSS3 do znalezienia elementów

Wiązanie danych

  • data() łączy określone dane z elementami
  • Metody po data() są uruchamiane dla każdego elementu

Selekcje poboczne

  • enter() tworzy nowe węzły
  • exit() usuwa istniejące węzły

API

  • attr() pobiera lub ustawia atrybut
  • style() pobiera lub ustawia CSS
  • property() pobiera lub ustawia właściwość
  • text() pobiera lub ustawia węzeł tekstowy textContent
  • html() pobiera lub ustawia zawartość innerHTML

Konfiguracja

var dataset = [15, 70, 30, 50, 20];

var width = 960,
    height = 500;

var svg = d3.select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

Tworzymy koła

svg.selectAll('circle')
  .data(dataset)
  .enter()
  .append('circle')
    .attr('cx', function(d) { return d * 2; })
    .attr('cy', 100)
    .attr('r', function(d) { return d; });

Skale

Funkcje, które odwzorowują wartości zbioru na zewnętrzny zakres.

Mapowanie danych

var map = dataset.map(function(d, i) {
  return {'key': i, 'value': d};
});

Koła proporcjonalnie

var xScale = d3.scale.linear()
  .domain([0, 4])
  .range([0, width]);
  .attr('cx', function(d) { return xScale(d.key); })
  .attr('cy', 100)
  .attr('r', function(d) { return d.value; });

Przejścia

Specjalne selekcje, w których działanie operatorów następuje płynnie, a nie natychmiast.

API

  • transition() rozpoczyna nowe przejście
  • delay() ustawia opóźnienie w milisekundach
  • duration() ustawia czas trwania w milisekundach

Pokaż koła

.attr('r', 0)
  .transition()
  .duration(1000)
    .attr('r', function(d) { return d.value; })

Wolniej!

.attr('r', 0)
  .transition()
  .duration(function(d) { return d.value * 100; })
    .attr('r', function(d) { return d.value; })
  .transition()
  .delay(function(d) { return d.value * 100; })

Kolory

Bezcenna wartość twojej wizualizacji.

Czerwono i zielono

.style('fill', 'red')
  .transition()
  .duration(function(d) { return d.value * 100; })
    .style('fill', 'green')

Skala kolorów

var colors = d3.scale.category10();

.style('fill', function(d) { return colors(d.value); });

.duration(2000)

.delay(2000)

Interpolacja

var colors = d3.scale.linear()
.domain([0, 4])
.range(['white', 'black']);

.style('stroke', function(d) {
  return d3.rgb(colors(d.key)).darker();
});

Osie

D3 wpiera tworzenie etykiet i osi.

Oś pozioma

var xAxis = d3.svg.axis()
  .scale(xScale).orient("bottom").ticks(5);

svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0, " + (height) + ")")
  .call(xAxis);

Tablice

Podstawowym typem danych w D3 jest tablica.

Metody JS

D3 udostępnia szereg metod dla tablic, ale zanim z nich skorzystasz, zapoznaj się z metodami wbudowanymi w JavaScript.

Metody d3

  • min() zwraca minimalną wartość podanej tablicy
  • max() zwraca maksymalną wartość podanej tablicy
  • mean() zwraca średnią z wartości podanej tablicy
  • sum() zwraca sumę z wartości podanej tablicy
  • extent() zwraca wartości minimalną i maksymalną
  • shuffle() zmienia losowo kolejność wartości podanej tablicy

Tabice asocjacyjne

  • Powszechny typ danych w JavaScript
  • Pamiętaj, że porządek iteracji nie jest zdefiniowany!
  • D3 oferuje konkretne metody do konwersji tablic asocjacyjnych do klasycznych tablic.

Mapy i zbiory


	var arr = [10, 20, 30];
	
	> arr; // [10, 20, 30]
	
	> d3.map(arr); // u {0: 10, 1: 20, 2: 30}
	
	> d3.set(arr); // i {10: true, 20: true, 30: true}
						

Ładowanie danych

  • Wiele sposobów dostarczenia danych do przeglądarki
  • Asynchroniczne żądania dla określonych adresów
  • Większość przeglądarek nie zezwala na żądania do innych domen

API

  • json() wysyła żądanie dla pliku JSON
  • xml() wysyła żądanie dla pliku XML
  • html() wysyła żądanie dla pliku HTML
  • csv() wysyła żądanie dla pliku CSV
  • tsv() wysyła żądanie dla pliku TSV

Przetwarzanie

D3 oferuje wbudowane wsparcie dla formatów CSV i TSV

Pliki CSV i TSV są często o wiele lżejsze niż JSON, co zmniejsza czas ładowania dużych zestawów danych.

CSV czy JSON?

sample.json (4 212 bytes)

[{"date":"Jun 2000","price":1454.6},
{"date":"Jul 2000","price":1430.83},
{"date":"Aug 2000","price":1517.68},
{"date":"Sep 2000","price":1436.51},
{"date":"Oct 2000","price":1429.4},
...

sample.csv (2 007 bytes)

date,price
Jan 2000,1394.46
Feb 2000,1366.42
Mar 2000,1498.58
Apr 2000,1452.43
...

Kształty

D3 oferuje szereg generatorów dla podstawowych kszałtów.

Linie, obszary, łuki czy symbole wykorzystuje się w wizualizacjach.

Generator liniowy

var line = d3.svg.line()
    .x(function(d, i) { return xScale(i); })
    .y(function(d) { return yScale(d); });

svg.append('path')
    .data(dataset)
    .attr('d', line(dataset));

Generator obszarowy

var area = d3.svg.area()
    .x(function(d, i) { return xScale(i); })
    .y0(height + margin.top)
    .y1(function(d) { return yScale(d); });

svg.append('path')
    .data(dataset)
    .attr('d', area(dataset));

Układy

D3 nie wyświetla gotowych wizualizacji, ale znacząco manipuluje danymi.

Możliwości

Bundle, Chord, Cluster, Force, Hierarchy, Histogram, Pack, Partition, Pie, Stack, Tree, Treemap

Pie chart

Partition

Treemap

Pack

Geografia

Modele map i odwzorowań kartograficznych dają szerokie pole do wizualizacji.

Zachowanie

Interaktywna wizualizacja przekazuje więcej informacji.

Przykłady

Arc Clock

Build own graph!

Wiele więcej

Podsumowanie

Koniec

Łukasz Adamczuk

Pytania