You are on page 1of 103

D3 Tips and Tricks

Because Life's too Short to Learn All the Things


www.d3noob.org/
Subscribe to the blog to know when
updates to this document occur.
ver .3.c
3 !anuar" #$3
d3noob.org 1
Table of Contents
Introduction..........................................................................................................................................4
What do you need to get started?.........................................................................................................5
HTML..............................................................................................................................................5
JavaScrit.........................................................................................................................................5
!ascading Sty"e Sheets #!SS$.........................................................................................................%
Web Servers.....................................................................................................................................%
&ther 'se(u" Stu((............................................................................................................................)
Te*t +ditor...................................................................................................................................)
,etting -3...................................................................................................................................)
Starting .ith a basic grah.................................................................................................................../
HTML............................................................................................................................................10
!SS................................................................................................................................................13
-3 JavaScrit.................................................................................................................................1%
Setting u the 1argins and the grah area................................................................................1)
,etting the -ata........................................................................................................................12
3or1atting the -ate 4 Ti1e.......................................................................................................01
Setting Sca"es -o1ains and 5anges.........................................................................................04
Setting u the 6*es...................................................................................................................0/
6dding data to the "ine (unction................................................................................................33
6dding the S7, !anvas...........................................................................................................34
6ctua""y -ra.ing So1ething8..................................................................................................35
Wra '....................................................................................................................................3)
Things you can do .ith the basic grah.............................................................................................32
6dding 6*is Labe"s.......................................................................................................................32
Ho. to add a tit"e to your grah....................................................................................................44
S1oothing out grah "ines.............................................................................................................45
6dding grid "ines to a grah..........................................................................................................51
The grid "ine !SS......................................................................................................................51
-e(ine the grid "ine (unctions....................................................................................................50
-ra. the "ines...........................................................................................................................54
Ma9e a dashed "ine........................................................................................................................55
3i""ing an area under the grah......................................................................................................5)
!SS (or an area (i""....................................................................................................................52
-e(ine the area (unction............................................................................................................52
-ra. the area............................................................................................................................5/
3i""ing an area above the "ine....................................................................................................%:
6dding a dro shado. to a""o. te*t to stand out on grahics.......................................................%1
!SS (or .hite shado.y bac9ground.........................................................................................%0
-ra.ing the .hite shado.y bac9ground..................................................................................%3
6dding 1ore than one "ine to a grah............................................................................................%4
Mu"ti"e a*es (or a grah ..............................................................................................................%)
Ho. to rotate the te*t "abe"s (or the * 6*is...................................................................................):
3or1at a date 4 ti1e a*is .ith seci(ied va"ues.............................................................................)0
!hange a "ine chart into a scatter "ot.................................................................................................)5
6dding too"tis...................................................................................................................................))
Transitions......................................................................................................................................)2
+vents.............................................................................................................................................)2
,et tiing.....................................................................................................................................)2
d3noob.org 0
on.1ouseover............................................................................................................................2:
on.1ouseout..............................................................................................................................21
What are the rede(ined; na1ed co"ours?..........................................................................................21
Se"ecting 4 (i"tering a subset o( ob<ects...............................................................................................2%
Se"ect ite1s .ith an I3 state1ent.......................................................................................................2)
6"ying a co"our gradient to a "ine based on va"ue..........................................................................2/
7arying an area (i"" .ith a gradient..................................................................................................../0
'sing ="un9er (or deve"o1ent and hosting your -3 creations........................................................./4
Loading a thu1bnai" into ,ist (or b".oc9s.org d3 grahs.................................................................../2
Setting the scene>.........................................................................................................................../2
+nough o( the scene setting. Let?s git going >@$...........................................................................1::
Wra u........................................................................................................................................1:0
3au"t (inding using !hro1e..............................................................................................................1:3
6nother .ay to do 6*is "abe" rotation?............................................................................................1:3
Thresho"d encoding to sho. high 4 "o. "ines on a grah.................................................................1:3
'sing a custo1 ti1e (or1at (or an a*is............................................................................................1:3
6dding a hyer"in9 to an ob<ect.......................................................................................................1:5
Ho. San9ey -iagra1s .ant their data (or1atted............................................................................1:5
=attern o( Li(e ana"ysis (or +arthAua9es..........................................................................................1:%
Saving a d3.<s i1age as an svg (or inc"usion in a docu1ent............................................................1:%
Setting (i*ed ranges (or date 4 ti1e in the range ..............................................................................1:)
Hosting data using ,oog"e -ocs......................................................................................................1:)
6dding a "egend................................................................................................................................1:)
6ccessing a MySBL database as a source o( data............................................................................1:)
'sing Cootstra .ith -3..................................................................................................................1:)
6dd a date@ti1e ic9er......................................................................................................................1:2
!reate a 1u"ti@series "ine chart .ith series (or each uniAue ite1 in 1st co"u1n..............................1:2
Ho. to run a articu"ar (unction every 5 1inutes............................................................................1:2
Wor9ing .ith ,itHub; ,ist and b".oc9s.org #this shou"d be a chater in itse"($..............................1:/
Ho. to set u and use a github account.......................................................................................1:/
Ma9ing data avai"ab"e (ro1 ,itHub............................................................................................1:/
'sing Mar9u .ith ,ists.............................................................................................................1:/
Insta""ing the "ug@in (or b".oc9s.org (or easy b"oc9 vie.ing......................................................1:/
d3noob.org 3
Introduction
&D; .eird sensation...
I never set out to .rite treatise on -3.
I a1 a si1"e user o( this e*traordinary (ra1e.or9 and .hen I say si1"e; I rea""y 1ean I had no
idea ho. to get it to do anything .hen I started and I needed to do a "ot o( searching and tria""ing by
error #e1hasis on the errors .hich .ere entire"y 1ine$. The one thing that I did 9no. .as that the
e*a1"e grahics sho.n by Mi9e Costoc9 and others .ere the sort o( grahica" goodness that I
.anted to "ay .ith.
So to get to the oint o( having no s9i""s .hatsoever to the oint .here I cou"d begin to code u
so1ething to dis"ay data in a .ay I .anted; I had to cature the in(or1ation as I .ent.
The rea""y coo" thing about this sort o( rocess is that it doesn?t need to occur a"" at once. Eou can
start .ith no 9no."edge .hatsoever #or retty c"ose$ and by standing on the shou"ders o( others
good .or9; you can add bui"ding b"oc9s to i1rove .hat you?re seeing and then change the b"oc9s
to adat and i1rove.
3or e*a1"e #and this is retty 1uch ho. it started$. I .anted to dra. a "ine grah; so I i1orted an
e*a1"e and then got it running "oca""y on 1y co1uter. Then I .or9ed out ho. to change the
e*a1"e data (or 1y data. The I .or9ed out ho. to 1ove the E a*is (ro1 the right to the "e(t. Then
ho. to 1a9e the a*is "abe"s "arger; change the tic9 siFe; 1a9e the "ines (atter; change the co"our; add
a "abe"; (i"" the area under the grah; ut the grah in the centre o( the age; add a g"o. to the te*t to
he" it stand out; ut it in a (ra1e.or9 #bootstra$; add buttons to change data sets; ani1ate the
transitions bet.een data sets; udate the data auto1atica""y .hen it changed; add a an and Foo1
(eature; turn arts o( the grah into hyer@"in9s to 1ove to other grahs... 6nd then I started on bar
grahs >@$.
The oint to ta9e a.ay (ro1 a"" o( this is that any one grah is <ust a co""ection o( "ots o( b"oc9s o(
code. +ach b"oc9 designed to carry out a (unction. =ic9 the b"oc9s you .ant and i1"e1ent the1.
I (ound it .as 1uch si1"er to .or9 on one thing #b"oc9$ at a ti1e and this he"ed great"y to reduce
the uncertainty (actor .hen things didn?t .or9 as anticiated.
I?1 not going to retend that everything I?ve done .hi"e trying to bui"d grahs e1"oys the 1ost
e"egant or e((icient 1echanis1; but in so1e cases the return on the invest1ent o( the training that
.ou"d reAuire 1e to do things in a articu"ar #erhas best ractices$ .ay .asn?t <usti(ied. 6nd in
the end; i( it a"" .or9s on the screen; I .a"9 a.ay hay >@$. That?s not to say I have de"iberate"y
ignored any best ractices. I <ust never 9ne. .hat they .ere. Li9e.ise; .herever ossib"e I have
tried to 1a9e things as e*tensib"e as ossib"e.
Eou .i"" (ind that I have tyica""y esche.ed a si1"e G-o this aroachH (or 1ore o( a story te""ing
e*ercise. This 1eans that so1e e*"anations are "onger and ("o.erier that 1ight be to everyoneIs
"i9ing; but there you go; try to be brave >@$

d3noob.org 4
What do you need to get started?
Let?s be (ran9; 1y ,rand1other .i"" never ut together a grahic using -3.
Ho.ever; that doesn?t 1ean that it?s beyond those .ith a "itt"e co1uter savy and a .i""ingness to
have a "ay. 5e1e1ber (ai"ure is your (riend #I a1 (air"y sure that I a1 a"so re"ated by b"ood$. Just
"earn (ro1 your 1ista9es and it?"" a"" .or9 out.
So; here in no articu"ar order is a "ist o( good things to 9no.. Jone o( .hich are essentia"; but any
one #or 1ore$ o( .hich .i"" 1a9e your "i(e s"ight"y easier.
HTML
JavaScrit
!ascading Sty"e Sheets #!SS$
Web Servers
3irst things (irst DON'T FREAK OUT8 This isn?t roc9et science. It?s <ust the inter@.ebs.
Let?s ta9e it gent"y and I?"" be a "itt"e 1ore seci(ic.
HTML
This stands (or HyerTe*t Mar9u Language and is the stu(( that .eb ages are 1ade
o(. !hec9 out the de(inition and other stu(( on Wi9iedia
1
(or a great overvie.. Just
re1e1ber... 6"" you?re going to use HTML (or is to ho"d the code that you .i"" use to
resent your in(or1ation. This .i"" be as a .ht1" #or .ht1$ (i"e and they can be retty
si1"e #.e?"" "oo9 at so1e in a 1o1ent$.
JavaScript
JavaScrit
0
is .hat?s ca""ed a ?scriting "anguage?. It is the code that .i"" be contained inside the
HTML (i"e that .i"" 1a9e -3 do a"" it?s (anciness. In (act; -3 is a JavaScrit Library; so that?s "i9e
the native "anguage (or using -3.
Dno.ing a "itt"e bit about this .ou"d be rea""y good; but to be er(ect"y honest; I didn?t 9no.
anything about it be(ore I started. I read a boo9 a"ong the .ay #JavaScrit> The Missing Manua"
3

(ro1 &I5ei""y$ and that he"ed .ith conte*t; but the e*a1"es that are avai"ab"e (or -3 grahics are
understandab"e; and .ith a bit o( tria" and error; you can (igure out .hat?s going on.
In (act; 1ost o( .hat this co""ection o( in(or1ation?s about is roviding e*a1"es and e*"anations
(or the JavaScrit co1onents o( -3.
1 htt>44en..i9iedia.org4.i9i4HTML
0 htt>44en..i9iedia.org4.i9i4JavaScrit
3 JavaScrit> The Missing Manua"; htt>44sho.orei""y.co14roduct4/)2:5/%5152/2.do
d3noob.org 5
Cascading Style Sheets (CSS)
!ascading Sty"e Sheets
4
#everyone aears to ca"" the1 ?Sty"e Sheets?
or ?!SS?$ is .hat?s 9no.n as a ?Mar9u? "anguage. The <ob o( !SS is to
1a9e the resentation o( the co1onents you .i"" dra. .ith -3
si1"er by assigning seci(ic sty"es to seci(ic ob<ects. &ne o( the coo"
things about !SS is that it is an enor1ous"y ("e*ib"e and e((icient
1ethod (or 1a9ing everything on the screen "oo9 1ore consistent and .hen you .ant to change the
(or1at o( so1ething you can <ust change the !SS co1onent and the .ho"e "oo9 and (ee" o( your
grahics .i"" change.
3u"" disc"osure> I 9no. !SS is a ridicu"ous"y o.er(u" too" that .ou"d 1a9e 1y "i(e easier; but I use
it in a very basic #and robab"y ain(u"$ .ay. -on?t <udge 1e; <ust accet that the .ay I?ve "earnt
.as .hat I needed to get the <ob done #this robab"y 1eans that noob?s "i9e 1yse"( .i"" (ind it
easier; but .here ossib"e try and use e*a1"es that inc"ude .hat "oo9 "i9e "ogica" !SS structures$
Web Servers
&9; this can go one o( t.o .ays. I( you have access to a .eb server and 9no. .here to ut the
(i"es so that you can access the1 .ith your bro.ser; you?re on (ire. I( you?re not Auite sure; read
on...
6 .eb server .i"" a""o. you to access your HTML (i"es and .i"" rovide the structure that a""o.s it
to be dis"ayed on a .eb bro.ser. There are so1e si1"e instructions on the 1ain -3 .i9i age
5
(or
setting u a "oca" server. &r you 1ight have access to a re1ote one and be ab"e to u"oad your (i"es.
Ho.ever; (or a "itt"e 1ore (unctiona"ity and a .ho"e "ot o( ease o( use; I can thorough"y reco11end
Wa1Server as a (ree and si1"e .ay to set u a "oca" .eb server that inc"udes =H= and a MySBL
database #1ore on those "ater$. ,o to the Wa1Server .eb age #htt>44.....a1server.co14en4$
and see i( it suits you.
Throughout this docu1ent I .i"" be describing the (i"es and ho. they?re "aid
out in a .ay that has suited 1y e((orts .hi"e using W6M=; but they .i""
.or9 eAua""y .e"" on a re1ote server. I .i"" e*"ain a "itt"e 1ore about ho.
I arrange the (i"es "ater in the ?,etting -3? section.
There are other otions o( course. Eou cou"d host code on ,itHub
%
and
resent the resu"ting grahics on b".oc9s.org
)
. This is a great .ay to 1a9e
sure that your code is avai"ab"e (or eer revie. and sharing .ith the .ider
co11unity.
&ne such a"ternative otion that I have recent"y started "aying .ith is ="un9er #htt>44"n9r.co4$
This is a "ight.eight co""aborative on"ine editing too". It?s so coo" I .rote a secia" section (or it
.hich you can (ind "ater in this docu1ent. This is de(inite"y .orth trying i( you .ant to use
so1ething si1"e .ithout a great dea" o( overhead. I( you "i9e .hat you see; erhas consider an
a"ternative that rovides a greater degree o( caabi"ity i( you go on to greater d3.<s things.
4 htt>44en..i9iedia.org4.i9i4!ss
5 htts>44github.co141bostoc94d34.i9i
% htts>44github.co14about
) htt>44b".oc9s.org4
d3noob.org %
Other Useful Stuff
Text Editor
6 good te*t editor (or .riting u your code .i"" be a rea" boost. -on?t 1a9e the (ata" 1ista9e o(
using an o((ice .ord rocessor or si1i"ar. TH+E WILL -&&M E&' T& 6 LI3+ &3 MIS+5E.
They add in craFy stu(( that you can?t even see and never save the (i"es in a .ay that can be used
roer"y.
=re(erab"y; you shou"d get an editor that .i"" rovide so1e assistance in the (or1 o( synta*
high"ighting .hich is .here the editor 9no.s .hat "anguage you are .riting in #JavaScrit (or
e*a1"e$ and high"ights the te*t in a .ay that he"s you read it.
3or e*a1"e; it .i"" change te*t that 1ight aear as thisK
44 ,et the data
d3.tsv#Ldata4data.tsvL; (unction#error; data$ M
data.(or+ach#(unction#d$ M
d.date N arse-ate#d.date$K
d.c"ose N Od.c"oseK
P$K
Into so1ething "i9e thisK
// Get the data
d3.tsv#Ldata4data.tsvL; function#error; data$ M
data.(or+ach#function#d$ M
d.date N arse-ate#d.date$K
d.c"ose N Od.c"oseK
P$K
In(inity easier to use. Trust 1e.
There are "enty o( editors that .i"" do the tric9. I have a re(erence (or ,eany
2
; 1ain"y
because it?s .hat I started .ith and it gre. on 1e >@$.
Getting D3
Luc9i"y this is retty easy.
Just go to the -3 reository on github
/
and you can
do.n"oad the entire reository <ust by c"ic9ing on the ?QI=?
button.
What you do .ith it (ro1 here is deendant on ho. you?re getting your grahs to run. I( you?re
.or9ing on the1 on your "oca" =!; then you .i"" .ant to have the d3.<s (i"e in the ath that can be
seen by the bro.ser. 6gain; I .ou"d reco11end W6M= #a "oca" .eb server$ to access your (i"es
"oca""y. I( you?re using W6M=; then you <ust have to 1a9e sure that it 9no.s to use a directory that
.i"" contain the d3 directory and you .i"" be a.ay.
The (o""o.ing i1age is intended to rovide a very crude overvie. o( a .ay you can set u the
directories.
2 htt>44....geany.org4
/ htts>44github.co141bostoc94d3
d3noob.org )
.ebserver> 'se this as your ?base? directory .here you ut your (i"es that you create. That
.ay .hen you oen your bro.ser you oint to this directory and it a""o.s you to access the
(i"es "i9e a nor1a" .eb site.
d3> this .ou"d be your unFied d3 directory. It contains a"" the e*a1"es and 1ore
i1ortant"y the d3.v3.<s (i"e that you need to get things going. Eou .i"" notice in the code
e*a1"es that (o""o. there is a "ine "i9e the (o""o.ingK
Rscript tyeNLte*t4<avascritL srcNLd34d3.v3.<sLSR4scriptS
This te""s your bro.ser that (ro1 the (i"e it it running #one o( the grah ht1" (i"es$ i( it goes
into the ?d3? (o"der it .i"" (ind the ?d3.v3.<s? (i"e that it can "oad.
data> I use this directory to ho"d any data (i"es that I .ou"d use (or rocessing. 3or e*a1"e;
you .i"" see the (o""o.ing "ine in the code e*a1"es that (o""o.K
d3.tsv#Ldata4data.tsvL; (unction#error; data$ M
6gain; that?s te""ing the bro.ser to go into the ?data? directory and to "oad the ?data.tsv? (i"e.
<s> &(ten you .i"" (ind that you .i"" .ant to inc"ude other JavaScrit "ibraries to "oad. This is
a good "ace to ut the1.
d3noob.org 2
Starting ith a basic graph
Ho. I?"" 1a9e a start is to rovide the (u"" code (or a si1"e grah and then .e can e*"ain it iece
by iece.
Here?s .hat the basic grah "oo9s "i9eK
6nd here?s the code that 1a9e it haenK
R8-&!TE=+ htmlS
Rmeta charsetNLut(@2LS
Rsty"eS
body M font> 10* 6ria"KP
ath M
stro9e> stee"b"ueK
stro9e@.idth> 0K
(i""> noneK
P
.a*is ath;
.a*is "ine M
(i""> noneK
stro9e> greyK
stro9e@.idth> 1K
shae@rendering> cris+dgesK
P
R4sty"eS
RbodyS
Rscript tyeNLte*t4<avascritL srcNLd34d3.v3.<sLSR4scriptS
RscriptS
var 1argin N Mto> 3:; right> 0:; botto1> 3:; "e(t> 5:P;
d3noob.org /
.idth N %:: @ 1argin."e(t @ 1argin.right;
height N 0): @ 1argin.to @ 1argin.botto1K
var arse-ate N d3.ti1e.(or1at#LTd@Tb@TyL$.arseK
var * N d3.ti1e.sca"e#$.range#U:; .idthV$K
var y N d3.sca"e."inear#$.range#Uheight; :V$K
var *6*is N d3.svg.a*is#$.sca"e#*$
.orient#Lbotto1L$.tic9s#5$K
var y6*is N d3.svg.a*is#$.sca"e#y$
.orient#L"e(tL$.tic9s#5$K
var va"ue"ine N d3.svg."ine#$
.*#(unction#d$ M return *#d.date$K P$
.y#(unction#d$ M return y#d.c"ose$K P$K

var svg N d3.select#LbodyL$
.aend#LsvgL$
.attr#L.idthL; .idth O 1argin."e(t O 1argin.right$
.attr#LheightL; height O 1argin.to O 1argin.botto1$
.aend#LgL$
.attr#Ltrans(or1L; Ltrans"ate#L O 1argin."e(t O L;L O 1argin.to O L$L$K
44 ,et the data
d3.tsv#Ldata4data.tsvL; (unction#error; data$ M
data.(or+ach#(unction#d$ M
d.date N arse-ate#d.date$K
d.c"ose N Od.c"oseK
P$K
44 Sca"e the range o( the data
*.do1ain#d3.e*tent#data; (unction#d$ M return d.dateK P$$K
y.do1ain#U:; d3.1a*#data; (unction#d$ M return d.c"oseK P$V$K
svg.aend#LathL$ 44 6dd the va"ue"ine ath.
.attr#LdL; va"ue"ine#data$$K
svg.aend#LgL$ 44 6dd the W 6*is
.attr#Lc"assL; L* a*isL$
.attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$
.ca""#*6*is$K
svg.aend#LgL$ 44 6dd the E 6*is
.attr#Lc"assL; Ly a*isL$
.ca""#y6*is$K
P$K
d3noob.org 1:
R4scriptS
R4bodyS
&nce .e?ve (inished e*"aining these arts; .e?"" start "oo9ing at .hat .e need to add in and ad<ust
so that .e can incororate other use(u" (unctions that are co1"ete"y reusab"e in other diagra1s as
.e"".
The end oint being so1ething hideous "i9e the (o""o.ingK
I say hideous since the grah is not intended to .in any beauty riFes; but there are severa"
co1onents to it .hich so1e eo"e 1ay (ind use(u" #grid"ines; area (i""; a*is "abe"; dro shado.
(or te*t; tit"e; te*t (or1atting$.
So; .e can brea9 the (i"e do.n into co1onent arts. I?1 going to "ay 9ind o( (ast and "oose here;
but never (ear; it?"" a"" 1a9e sense.
d3noob.org 11
HTML
Here?s the HTML ortions o( the codeK
R8-&!TE=+ htmlS
Rmeta charsetNLut(@2LS
Rsty"eS
The CSS is in here
R4sty"eS
RbodyS
Rscript tyeNLte*t4<avascritL srcNLd34d3.v3.<sLSR4scriptS
RscriptS
The D3 JavaScript code is here
R4scriptS
R4bodyS
!o1are it .ith the (u"" code. I 9ind o( "oo9s "i9e a .raing (or the !SS and JavaScrit. Eou can
see that it rea""y doesn?t boi" do.n to 1uch at a"" #that doesn?t 1ean it?s not i1ortant$.
There are "enty o( good otions (or adding additiona" HTML stu(( into this very basic art (or the
(i"e; but (or .hat .e?re going to be doing; .e rea""y don?t need to bother too 1uch.
&ne thing robab"y .orth 1entioning is the "ineK
Rscript tyeNLte*t4<avascritL srcNLd34d3.v3.<sLSR4scriptS
That?s the "ine that identi(ies the (i"e that needs to be "oaded to get -3 u and running. In this case
the (i"e is stored in a (o"der ca""ed d3 .hich itse"( is in the sa1e directory as the 1ain ht1" (i"e. The
-3 (i"e is actua""y ca""ed d3.v3.<s .hich 1ay co1e as a bit o( a surrise. That te""s us that this is
version 3 o( the d3.<s (i"e #the .v3. art$ and .hi"e that .on?t be the re"ease nu1ber #you .ou"d .ant
to chec9 that in the Fi (i"e you do.n"oaded ear"ier$; it is an indication that it is searate (ro1 the v0
re"ease; .hich; as I .rite is the 1ain re"ease; but the v3 version is being reared (or genera" use; so
I thought it .ou"d be better to .or9 .ith a re re"ease version o( the (i"e.
Later .hen doing things "i9e i1"e1enting integration .ith bootstra #a retty "ayout (ra1e.or9$
.e .i"" be doing a great dea" 1ore; but (or no.; that?s the basics done.
The t.o arts that .e "e(t out are the !SS and the -3 JavaScrit.
d3noob.org 10
CSS
The !SS is as (o""o.s
body M font> 10* 6ria"KP
ath M
stro9e> stee"b"ueK
stro9e@idth> 0K
(i""> noneK
P
.a*is ath;
.a*is "ine M
(i""> noneK
stro9e> greyK
stro9e@idth> 1K
shae@rendering> cris+dgesK
P
So !ascading Sty"e Sheets give you contro" over the "oo9 4 (ee" 4 resentation o( the content. The
idea is to de(ine a set o( roerties to ob<ects in the .eb age.
They are 1ade u o( ?5u"es?. +ach ru"e has a ?se"ector? and a ?dec"aration? and each ?dec"aration? has a
roerty and a va"ue #or a grou o( roerties and va"ues$.
3or instance in the e*a1"e code (or this .eb age .e have the (o""o.ing ru"eK
body M font> 10* 6ria"KP
?body? is the se"ector. This te""s you that on the .eb age; this ru"e .i"" a"y to the ?body? o( the
age. This actua""y a"ies to a"" the ortions o( the .eb age that are contained in the ?body? ortion
o( the HTML code #everything bet.een RbodyS and R4bodyS in the HTML bit$.
M font> 10* 6ria"KP is the se"ector ortion o( the ru"e. It on"y has the one dec"aration .hich is the
bit that is in bet.een the cur"y braces.
So font> 10* 6ria"K is the dec"aration. The roerty is ?(ont>? and the va"ue is ?10* 6ria"K?. This te""s
the .eb age that the (ont that aears in the body o( the .eb age .i"" be in 10 * 6ria".
Sure enough i( .e "oo9 at the a*es o( the grah...
We see that the (ont 1ight actually be 10 * 6ria"8
Let?s try a test. I .i"" change the 5u"e to the (o""o.ingK
body M font> 1%* 6ria"KP
and the resu"t is...
6hh.... 1%* o( goodness8
d3noob.org 13
6nd no. .e change it to...
body M font> 1%* ti1esKP
and .e get...
H11... Ti1es (ont.... I thin9 .e can sa(e"y say that this has had the desired e((ect.
So .hat e"se is there?
What about the bit that?s "i9eK
ath M
stro9e> stee"b"ueK
stro9e@idth> 0K
(i""> noneK
P
We""; the .ho"e thing is one ru"e; ?ath? is the se"ector. In this case; ?ath? is re(erring to a "ine in the
-3 dra.ing no1enc"ature.
3or that se"ector .e have three dec"arations. They give va"ues (or the roerties o( ?stro9e? #in this
case co"our$; ?stro9e@.idth? #the .idth o( the "ine$ and ?(i""? #.e can (i"" a ath .ith a b"oc9 o(
co"our$.
So "et?s change things >@$
ath M
stro9e> redK
stro9e@idth> 5K
(i""> yesK
P
Wo.8 So the "ine is no. red; it "oo9s about 5 i*e"s .ide and it?s tried to (i"" the areas rough"y
de(ined by the curve .ith a b"ac9 co"our.
It ain?t retty; but it certain"y did change. In (act i( .e goK
(i""> b"ueK
d3noob.org 14
We?"" get...
So the ?(i""? roerty "oo9s retty ("e*ib"e. 6nd so does !SS.
d3noob.org 15
! JavaScript
5ight; the -3 JavaScrit art is as (o""o.sK
var 1argin N Mto> 3:; right> 0:; botto1> 3:; "e(t> 5:P;
.idth N %:: @ 1argin."e(t @ 1argin.right;
height N 0): @ 1argin.to @ 1argin.botto1K
var arse-ate N d3.ti1e.(or1at#LTd@Tb@TyL$.arseK
var * N d3.ti1e.sca"e#$.range#U:; .idthV$K
var y N d3.sca"e."inear#$.range#Uheight; :V$K
var *6*is N d3.svg.a*is#$.sca"e#*$
.orient#Lbotto1L$.tic9s#5$K
var y6*is N d3.svg.a*is#$.sca"e#y$
.orient#L"e(tL$.tic9s#5$K
var va"ue"ine N d3.svg."ine#$
.*#function#d$ M return *#d.date$K P$
.y#function#d$ M return y#d.c"ose$K P$K

var svg N d3.se"ect#LbodyL$
.aend#LsvgL$
.attr#L.idthL; .idth O 1argin."e(t O 1argin.right$
.attr#LheightL; height O 1argin.to O 1argin.botto1$
.aend#LgL$
.attr#Ltrans(or1L; Ltrans"ate#L O 1argin."e(t O L;L O 1argin.to O L$L$K
// Get the data
d3.tsv#Ldata4data.tsvL; function#error; data$ M
data.(or+ach#function#d$ M
d.date N arse-ate#d.date$K
d.c"ose N Od.c"oseK
P$K
// Scale the range of the data
*.do1ain#d3.e*tent#data; function#d$ M return d.dateK P$$K
y.do1ain#U:; d3.1a*#data; function#d$ M return d.c"oseK P$V$K
svg.aend#LathL$ // Add the valueline path.
.attr#Lc"assL; L"ineL$
.attr#LdL; va"ue"ine#data$$K
svg.aend#LgL$ // Add the X Axis
.attr#Lc"assL; L* a*isL$
.attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$
.ca""#*6*is$K
d3noob.org 1%
svg.aend#LgL$ // Add the Y Axis
.attr#Lc"assL; Ly a*isL$
.ca""#y6*is$K
P$K
6gain there?s Auite a bit o( detai" in the code; but it?s not so "ong that you can?t .or9 out .hat?s
doing .hat.
Let?s e*a1ine the b"oc9s bit by bit to get a (ee" (or it.
Setting up the !argins and the graph area"
The art o( the code resonsib"e (or de(ining the canvas #or the area .here the grah and associated
bits and ieces is "aced $ is this art.
var 1argin N Mto> 3:; right> 0:; botto1> 3:; "e(t> 5:P;
.idth N %:: @ 1argin."e(t @ 1argin.right;
height N 0): @ 1argin.to @ 1argin.botto1K
This is rea""y #really$ .e"" e*"ained on Mi9e Costoc9?s age on 1argin conventions here
?htt>44b".oc9s.org43:1/5%3?; but at the ris9 o( con(using you here?s 1y crude ta9e on it.
The (irst "ine de(ines the (our 1argins that surround the b"oc9 .here the grah roer .i"" be.
var 1argin N Mto> 3:; right> 0:; botto1> 3:; "e(t> 5:P;
So there .i"" be a border o( 3: i*e"s at the to; 0: at the right and 3: and 5: at the botto1 and "e(t
resective"y. Jo. the coo" thing about ho. these are set u is that they use an array to de(ine
everything. That 1eans i( you .ant to do ca"cu"ations in the JavaScrit "ater; you don?t need to ut
the nu1bers in; you <ust use the variab"e that has been set u. In this case 1argin.right N 0:8
So .hen .e go to the ne*t "ineK
.idth N %:: @ 1argin."e(t @ 1argin.right;
the .idth o( the inner b"oc9 o( the canvas .here the grah .i"" be dra.n is %:: i*e"s X 1argin."e(t
X 1argin.right or %::@5:@0: or 53: i*e"s .ide. &( course no. you have another variab"e ?.idth?
that .e can use "ater in the code.
&bvious"y the sa1e treat1ent is given to height.
6nother coo" thing about a"" o( this is that <ust because you aear to have de(ined searate areas (or
the grah and the 1argins; the .ho"e area in there is avai"ab"e (or use. It <ust 1a9es it rea""y use(u"
to have areas set aside (or the a*is "abe"s and grah "abe"s to go .ithout having to <ugg"e the1 and
the grah roer at the sa1e ti1e.
So; "et?s have a "ay and change so1e va"ues.
var 1argin N Mto> !"; right> 0:; botto1> !"; "e(t> 5:P;
.idth N #"" @ 1argin."e(t @ 1argin.right;
height N 0): @ 1argin.to X 1argin.botto1K
d3noob.org 1)
Here .e?ve 1ade the grah narro.er #4:: i*e"s$ but retained the "e(t 4 right 1argins and increased
the to botto1 1argins .hi"e 1aintaining the overa"" height o( the canvas. The rea""y coo" thing that
you can te"" (ro1 this is that .hi"e .e shran9 the di1ensions o( the area that .e had to dra. the
grah in; it .as sti"" ab"e to dyna1ica""y adat the a*es and "ine to (it roer"y. That is the rea""y
coo" art o( this .ho"e business. -3 is running the in the bac9ground "oo9ing a(ter the dra.ing o(
the ob<ects; .hi"e you get to concentrate on ho. the data "oo9s .ithout too 1uch 1aths8
Getting the Data
We?re going to <u1 (or.ard a "itt"e bit here to the bit o( the JavaScrit code that "oads the data (or
the grah.
I?1 going to go out o( the seAuence o( the code here; because i( you 9no. .hat the data is that
you?re using; it .i"" 1a9e e*"aining so1e o( the other (unctions that are co1ing u 1uch easier.
So the iece that grabs the data is this bit.
d3.tsv#Ldata4data.tsvL; function#error; data$ M
data.(or+ach#function#d$ M
d.date N arse-ate#d.date$K
d.c"ose N Od.c"oseK
P$K
6nd in (act it?s a co1bination o( a (e. bits and another bit that isn?t sho.n8; Cut "et?s ta9e it one ste
at a ti1e >@$
&9... There?s "ots o( di((erent .ays that .e can get data into our .eb age to turn into grahics. 6nd
the .ay that you?"" .ant to use .i"" robab"y deend 1ore on the (or1at that it is in than the
1echanis1 you .ant to use (or i1orting.
3or instance; i( it?s on"y a (e. oints o( data .e cou"d inc"ude the in(or1ation direct"y in the
JavaScrit.
That .ou"d 1a9e it "oo9 so1ething "i9eK
var data N U
Mdate>L1@May@10L;c"ose>H52.13HP;
Mdate>L3:@6r@10L;c"ose>H53./2HP;
Mdate>L0)@6r@10L;c"ose>H%).::HP;
Mdate>L0%@6r@10L;c"ose>H2/.):HP;
Mdate>L05@6r@10L;c"ose>H//.::HP
d3noob.org 12
VK
The (or1at o( the data sho.n above is ca""ed JS&J #JavaScrit &b<ect Jotation$ and it?s a great
.ay to inc"ude data since it?s easy (or hu1ans to read .hat?s in there and it?s easy (or co1uters to
arse the data out.
Cut i( you?ve got a (air bit o( data or i( the data you .ant to inc"ude is dyna1ic and cou"d be
changing (ro1 one 1o1ent to the ne*t; you?"" .ant to "oad it (ro1 an e*terna" source. That?s .hen
.e ca"" on -3?s ?5eAuest? (unctions.
6 ?5eAuest? is a (unction that instructs the bro.ser to reach out and grab so1e data (ro1
so1e.here. It cou"d be stored "oca""y #on the .eb server$ or so1e.here out in the internet.
There are di((erent tyes o( reAuests deending on the tye o( data you .ant to ingest. +ach tye o(
data is (or1atted .ith di((erent ru"es; so the di((erent reAuests interret those ru"es to 1a9e sure that
the data is returned to the -3 rocessing in a (or1at that it understands. Eou cou"d there(ore thin9 o(
the di((erent ?5eAuests? as trans"ators and the di((erent data (or1ats as being (oreign "anguages.
The di((erent tyes o( data that can be reAuested by -3 areK
te*t
6 "ain o"d iece o( te*t that can otiona""y be encoded in a articu"ar .ay #see the -3
6=I
1:
$.
<son
This is the a(ore 1entioned JavaScrit &b<ect Jotation.
*1"
+*tensib"e Mar9u Language is a "anguage that is .ide"y used (or encoding docu1ents in a
hu1an readab"e (orr1.
ht1"
HyerTe*t Mar9u Language is the "anguage used (or dis"aying .eb ages.
csv
!o11a Searated 7a"ues is a .ide"y used (or1at (or storing data .here "ain te*t
in(or1ation is searated by #.ait (or it$ co11as.
tsv
Tab Searated 7a"ues is a .ide"y used (or1at (or storing data .here "ain te*t in(or1ation is
searated by a tab@sto character.
-etai"s on these ingestion 1ethods and the (or1ats (or the reAuests are e*"ained .e"" on the -3
Wi9i age here @ htts>44github.co141bostoc94d34.i9i45eAuests. In this articu"ar scrit .e .i""
"oo9 at the tsv reAuest 1ethod.
Jo.; it is i1ortant to note here that this is not an e*c"usive "ist o( .hat can be ingested. I( you?ve
got so1e (un9y data in a .eird (or1at; you can sti"" get it in; but you .i"" 1ost "i9e"y need to stand
u a s1a"" a1ount o( code so1e.here e"se in your age to do the conversion #.e .i"" "oo9 at this
rocess .hen describing getting data (ro1 a MySBL database$.
So; bac9 to our reAuest...
d3.tsv#Ldata4data.tsvL; function#error; data$ M
data.(or+ach#function#d$ M
d.date N arse-ate#d.date$K
1: htts>44github.co141bostoc94d34.i9i45eAuests
d3noob.org 1/
d.c"ose N Od.c"oseK
P$K
The (irst "ine o( that iece o( code invo9es the d3.tsv reAuest #d3.tsv$ and then the (unction is
ointed to the data (i"e that shou"d be "oaded #Ldata4data.tsvL$. This is re(erred to as the ?ur"? #uniAue
resource "ocator$ o( the (i"e. In this case the (i"e is stored "oca""y; but the ur" cou"d <ust as easi"y
oint to a (i"e so1e.here on the Internet.
The (or1at o( the data in the data.tsv (i"e "oo9s a bit "i9e thisK
date c"ose
1@May@10 52.13
3:@6r@10 53./2
0)@6r@10 %).::
0%@6r@10 2/.):
05@6r@10 //.::
#a"though the (i"e is "onger #about 0% data oints$$. The ?date? and the ?c"ose? heading "abe"s are
searated by a tab as are each subseAuent dates and nu1bers. Hence the ?tab searated va"ues? >@$.
The ne*t art is art o( the coo"ness o( JavaScrit. With the reAuest 1ade and the (i"e reAuested the
scrit is to"d to carry out a (unction on the data #.hich .i"" no. be ca""ed ?data?$.
function#error; data$ M
Jo.; there are actua""y 1ore things that get acted on as art o( the (unction ca""; but the one .e .i""
consider here are the (o""o.ing "inesK
data.(or+ach#function#d$ M
d.date N arse-ate#d.date$K
d.c"ose N Od.c"oseK
P$K
This b"oc9 o( code si1"y ensures that a"" the nu1eric va"ues that are u""ed out o( the tsv (i"e are
set and (or1atted correct"y. The (irst "ine sets the data variab"e that is being dea"t .ith #ca""ed
s"ight"y con(using"y ?data?$ and te""s the b"oc9 o( code that (or each grou .ithin the ?data? array it
shou"d carry out a (unction on the1. That (unction is designated ?d?.
data.(or+ach#function#d$ M
The in(or1ation in the array can be considered as being stored in ro.s .ith each ro. consisting o(
t.o va"ues. &ne va"ue (or ?date? and another va"ue (or ?c"ose?.
So the (unction is u""ing out va"ues o( ?date? and ?c"ose? one ro. at a ti1e.
+ach ti1e it gets a va"ue o( ?data? and ?c"ose it carries out the (o""o.ing oerationsK
d.date N arse-ate#d.date$K
This the seci(ic va"ue o( date being "oo9ed at # d.date$ into a date (or1at that -3 can rocess and
do stu(( .ith via a searate (unction ?arse-ate?. Jo.; the ?arse-ate? (unction is de(ined in a
searate art o( the scrit; and .e .i"" e*a1ine that "ater. So (or the 1o1ent; <ust be satis(ied that it
ta9es the ra. date in(or1ation (ro1 the tsv (i"e in a seci(ic cro. and converts it into a (or1at that
-3 can then rocess. That va"ue is then re@saved in the sa1e variab"e sace.
The ne*t "ine then sets the ?c"ose? va"ue to a nu1eric va"ue #i( it isn?t a"ready$ using the ?O? oerator.
d.c"ose N Od.c"oseK
d3noob.org 0:
This aears to be good ractice .hen the (or1at o( the nu1ber being u""ed out o( the data 1ay
not 1ean that it is auto1agica""y recognised as a nu1ber. This .i"" ensure that it is.
So; at the end o( that section o( code; .e have gone out and ic9ed u a (i"e .ith data in it o( a
articu"ar tye #tab searated va"ues$ and ensured that it is (or1atted in a .ay that the rest o( the
scrit can use it correct"y.
Jo.; the astute a1ongst you .i"" have noticed that in the (irst "ine o( that b"oc9 o( code
#d3.tsv#Ldata4data.tsvL; function#error; data$ M$ .e oened a nor1a" brac9et # # $ and a cur"y brac9et
# M $; but .e never c"osed the1. That?s because they stay oen unti" the very end o( the (i"e. That
1eans that a"" those b"oc9s that occur a(ter the d3.tsv bit are re(erenced to the ?data? array. &r ut
another .ay; it uses ?data? to dra. stu((8
Cut any.ay; "et?s get bac9 to (iguring .hat the code is doing by <u1ing bac9 to the end o( the
1argins b"oc9.
#or!atting the Date $ Ti!e"
&ne o( the g"orious things about the Wor"d is that .e a"" do things a bit di((erent"y. &ne o( those
things is ho. .e re(er to dates and ti1e
11
.
In 1y nec9 o( the .oods; it?s custo1ary to .rite the date as day @ 1onth X year. +.g 03@10@0:10.
Cut in the 'nited States the 1ore co11on (or1at .ou"d be 10@03@0:10. Li9e.ise; the data 1ay be
in (or1ats that na1e the 1onths or .ee9days #+.g. January; Tuesday$ or co1bine dates and ti1e
together #+.g. 0:10@10@03 15>45>30$. So; i( .e .ere to atte1t to try to "oad in so1e data and to try
and get -3 to recognise it as date 4 ti1e in(or1ation; .e rea""y need to te"" it .hat (or1at the date 4
ti1e is in.
Jo.; you 1ight be as9ing yourse"( .hat?s the oint? 6"" you .ant to do is give it a nu1ber and it
can sort it out so1eho.. We""; that is true; but i( you .ant to rea""y bring out the best in your data
and to 9ee 1a*i1u1 ("e*ibi"ity in reresenting it on the screen; you .i"" .ant to -3 to "ay to it?s
strengths. 6nd one o( those is being ab"e to ad<ust dyna1ica""y .ith variab"e ti1e va"ues.
Ti1e (or a "itt"e de1onstration.
I .i"" change our data.tsv (i"e that .e use to "oad data to grah so that it on"y inc"udes t.o oints.
The (irst one and the "ast one .ith a searation o( a 1onth and a bit.
date c"ose
1@May@10 52.13
0%@Mar@10 %:%./2
The grah no. "oo9s "i9e thisK
11 htt>44en..i9iedia.org4.i9i4-ateY(or1atYbyYcountry
d3noob.org 01
So; nothing too surrising here; a very si1"e grah #note the ti1e sca"e on the * a*is$.
Cut no. I .i"" change the "ater date in the data.tsv (i"e so that it is a "ot c"oser to the starting dateK
date c"ose
0/@Mar@10 52.13
0%@Mar@10 %:%./2
So; <ust a three day di((erence. Let?s see .hat haens.
6hh.... Jot on"y did .e not have to 1a9e any changes to our JavaScrit code; but it .as ab"e to
recognise the dates .ere c"oser and (i""ed in the intervening gas .ith aroriate ti1e 4 day va"ues.
Jo.; one 1ore ti1e (or gigg"es.
This ti1e .e?"" stretch the interva" out by a (e. years.
date c"ose
0/@Mar@01 52.13
0%@Mar@10 %:%./2
and the resu"t is...
d3noob.org 00
Hoe(u""y that?s enough encourage1ent to i1ress uon you that (or1atting the ti1e is a 5+6LLE
good thing to get right and trust 1e; it .i"" never (ai" to i1ress >@$.
So; bac9 to (or1atting.
The "ine in the JavaScrit that arses the ti1e is the (o""o.ingK
var arse-ate N d3.ti1e.(or1at#LTd@Tb@TyL$.arseK
This "ine is used .hen the data.(or+ach#function#d$ ortion o( the code that .e "oo9ed at a cou"e
o( ages bac9 used d.date N arse-ate#d.date$ as a .ay to ta9e a date in a seci(ic (or1at and to get
it recognised by -3. In e((ect it said ta9e this va"ue that is suosed"y a date and 1a9e it into a
va"ue I can understand.
The (unction used is the d3.ti1e.(or1at#seci(ier$ (unction .here the seci(ier in this case is the
1ysterious co1bination o( characters ?Td@Tb@Ty?. The good ne.s is that these are <ust a
co1bination o( directives seci(ic (or the tye o( date .e are resenting.
The ?T? signs are used as re(i*es to each searate (or1at tye and the ?@? signs are "itera"s (or the
actua" ?@? signs that aear in the date to be arsed.
The ?d? re(ers to a Fero@added day o( the 1onth as a deci1a" nu1ber U:1;31V.
The ?b? re(ers to an abbreviated 1onth na1e.
6nd the ?y? re(ers to the year .ith century as a deci1a" nu1ber.
I( .e "oo9 at a subset o( the data (ro1 the data.tsv (i"e .e see that indeed; the dates therein are
(or1atted in this .ay.
1@May@10 52.13
3:@6r@10 53./2
0)@6r@10 %).::
0%@6r@10 2/.):
05@6r@10 //.::
So that?s a"" .e"" and good; but .hat i( your data isn?t (or1atted e*act"y "i9e that?
,ood ne.s. There area a hea o( di((erent (or1atters (or di((erent .ays o( te""ing ti1e and you get
to ic9 and choose .hat you .ant. !hec9 out the Ti1e 3or1atting age
10
on the -3 Wi9i (or a the
authoritative "ist and so1e great detai"; but the (o""o.ing is the "ist o( current"y avai"ab"e (or1atters
#(ro1 the d3 .i9i$K
10 htts>44github.co141bostoc94d34.i9i4Ti1e@3or1atting
d3noob.org 03
Ta @ abbreviated .ee9day na1e.
T6 @ (u"" .ee9day na1e.
Tb @ abbreviated 1onth na1e.
TC @ (u"" 1onth na1e.
Tc @ date and ti1e; as LTa Tb Te TH>TM>TS TEL.
Td @ Fero@added day o( the 1onth as a deci1a" nu1ber U:1;31V.
Te @ sace@added day o( the 1onth as a deci1a" nu1ber U 1;31V.
TH @ hour #04@hour c"oc9$ as a deci1a" nu1ber U::;03V.
TI @ hour #10@hour c"oc9$ as a deci1a" nu1ber U:1;10V.
T< @ day o( the year as a deci1a" nu1ber U::1;3%%V.
T1 @ 1onth as a deci1a" nu1ber U:1;10V.
TM @ 1inute as a deci1a" nu1ber U::;5/V.
T @ either 6M or =M.
TS @ second as a deci1a" nu1ber U::;%1V.
T' @ .ee9 nu1ber o( the year #Sunday as the (irst day o( the .ee9$ as a deci1a" nu1ber
U::;53V.
T. @ .ee9day as a deci1a" nu1ber U:#Sunday$;%V.
TW @ .ee9 nu1ber o( the year #Monday as the (irst day o( the .ee9$ as a deci1a" nu1ber
U::;53V.
T* @ date; as LT14Td4TyL.
TW @ ti1e; as LTH>TM>TSL.
Ty @ year .ithout century as a deci1a" nu1ber U::;//V.
TE @ year .ith century as a deci1a" nu1ber.
TQ @ ti1e Fone o((set; such as L@:)::L.
TT @ a "itera" LTL character.
6s an e*a1"e; i( you .anted to inut date 4 ti1e (or1atted as a generic MySBL ?EEEE@MM@--
HH>MM>SS? TIM+ST6M= (or1at the -3 arse scrit .ou"d "oo9 "i9eK
arse-ate N d3.ti1e.(or1at#LTE@T1@Td TH>TM>TSL$.arseK
Setting Scales Do!ains and %anges
This is another e*a1"e .here i( you set it u right; -3 .i"" "oo9 a(ter you (orever.
The G6h Ha8H 1o1ent (or 1e in understanding ranges and sca"es .as a(ter reading Jero1e !u9ier?s
great age on ?d3>sca"es and co"or?.
13
I thorough"y reco11end you read it #and "enty 1ore o( the
great .or9 by Jero1e$ as he rea""y does nai" the descrition in 1y hu1b"e oinion. I .i"" ut 1y
o.n descrition do.n here; but i( it doesn?t see1 c"ear; head on over to Jero1e?s age.
3ro1 our basic .eb age .e have no. 1oved to the section that inc"udes the (o""o.ing "inesK
13 htt>44....<ero1ecu9ier.net4b"og40:114:24114d3@sca"es@and@co"or4
d3noob.org 04
var * N d3.ti1e.sca"e#$.range#U:; .idthV$K
var y N d3.sca"e."inear#$.range#Uheight; :V$K
The urose o( these ortions o( the scrit is to ensure that the data .e ingest (its onto our grah
correct"y. Since .e have t.o di((erent tyes o( data #date4ti1e and nu1eric va"ues$ they need to be
treated searate"y #but they do essentia""y the sa1e <ob$. To e*a1ine this .ho"e concet o( sca"es;
do1ains and ranges roer"y; .e .i"" a"so 1ove s"ight"y out o( seAuence and #in con<unction .ith
the ear"ier sca"e state1ents$ ta9e a "oo9 at the "ines o( scrit that occur "ater and set the do1ain.
They are as (o""o.sK
*.do1ain#d3.e*tent#data; function#d$ M return d.dateK P$$K
y.do1ain#U:; d3.1a*#data; function#d$ M return d.c"oseK P$V$K
So; the idea o( sca"ing is to ta9e the va"ues o( data that .e have and to (it the1 into the sace .e
have avai"ab"e.
I( .e have data that goes (ro1 53./2 to %3%.03 #as the data .e have (or ?c"ose? in our tsv (i"e does$;
but .e have a grah that is 01: i*e"s high #height N 0): @ 1argin.to X 1argin.botto1K$ .e c"ear"y
need to 1a9e an ad<ust1ent.
Jot on"y that. +ven though our data goes (ro1 53./2 to %3%.03; that .ou"d "oo9 s"ight"y 1is"eading
on the grah and it shou"d rea""y go (ro1 : to a bit over %3%.03.
It sound?s rea""y co1"icated; but "et?s si1"e it u a bit.
3irst .e 1a9e sure that any Auantity .e seci(y on the * a*is (its onto our grah.
var * N d3.ti1e.sca"e#$.range#U:; .idthV$K
Here .e set our variab"e that .i"" te"" -3 .here to dra. so1ething on the * a*is. Cy using the
d3.ti1e.sca"e#$ (unction .e 1a9e sure that -3 9no.s to treat the va"ues as date 4 ti1e entities #.ith
a"" their ingrained ecu"iarities$. Then .e seci(y the range that those va"ues .i"" cover #.range$ and
.e seci(y the range as being (ro1 : to the .idth o( our grahing area #See8 Setting those variab"es
(or 1argins and .idths are starting to ay o(( no.8$.
Then .e do the sa1e (or the E a*is.
var y N d3.sca"e."inear#$.range#Uheight; :V$K
There?s a di((erent (unction ca"" #d3.sca"e."inear#$$ but the .range setting is sti"" there. In the interests
o( dra.ing a #se1i$ retty icture to try and e*"ain; hoe(u""y this .i"" assistK
d3noob.org 05
I 9no.; I 9no.; it?s a "itt"e 1is"eading because no.here have .e atua""y said to -3 this is our data
(ro1 53./2 to %3%.03. 6"" .e?ve said is .hen .e get the data; .e?"" be sca"ing it into this sace.
Jo. hang on; .hat?s going on .ith the Uheight; :V art in y a*is sca"e state1ent? The astute
a1ongst you .i"" note that (or the ti1e sca"e .e set the range as U:; .idthV but (or this one #Uheight;
:V$ the va"ues "oo9 bac9.ards.
We"" sotted.
This is a"" to do .ith ho. the screen is "aid out and re(erenced. Ta9e a "oo9 at the (o""o.ing diagra1
sho.ing ho. the coordinates (or dra.ing on your screen .or9K
The to "e(t hand o( the screen is the origin or :;: oint and as .e go "e(t or do.n the corresonding
* and y va"ues increase to the (u"" va"ues de(ined by height and .idth.
So that?s a"" .e"" and good (or the ti1e va"ues on the * a*is that .i"" start at "o.er va"ues and
increase; but (or the va"ues on the y a*is .e?re trying to go against the ("o.. We .ant the "o. va"ues
to be at the botto1 and the high va"ues to be at the to.
d3noob.org 0%
Jo rob"e1. We <ust te"" -3 via the state1ent y N d3.sca"e."inear#$.range#Uheight; :V$K that the "arger
va"ues #height$ are at the "o. end o( the screen #at the to$ and the "o. va"ues are at the botto1 #as
you 1ost robab"y .i"" have guessed by this stage; the .range state1ent uses the (or1at
.range#Uc"oserYtoYtheYorigin; (urtherY(ro1YtheYoriginV$. So .hen .e ut the height variab"e (irst;
that is no. associated at the to o( the screen.
&D; so .e?ve sca"ed our data to the grah siFe and ensured that the range o( va"ues is set
aroriate"y; so .hat?s .ith the do1ain art that .as in the tit"e (or this section?
!o1e on; you re1e1ber this "itt"e iece o( scrit don?t you?
*.do1ain#d3.e*tent#data; function#d$ M return d.dateK P$$K
y.do1ain#U:; d3.1a*#data; function#d$ M return d.c"oseK P$V$K
Whi"e it e*ists in a searate art o( the (i"e (ro1 the sca"e 4 range art; it is certain"y "in9ed.
That?s because there?s so1ething 1issing (ro1 .hat .e have been describing so (ar .ith the set u
o( the data ranges (or the grahs. We haven?t actua""y to"d -3 .hat the range o( the data is. That?s
a"so the reason this art o( the scrit occurs .here it does. It is .ithin the ortion .here the data.tsv
(i"e has been "oaded as ?data? and it?s there(ore ready to act on it.
So; the .do1ain (unction is designed to "et -3 9no. .hat the scoe o( the data .i"" be this is .hat
is then assed to the sca"e (unction.
Loo9ing at the (irst art that is setting u the * a*is va"ues; it is saying that the do1ain (or the * a*is
va"ues .i"" be deter1ined by the d3.e*tent (unction .hich in turn is acting on a searate (unction
.hich "oo9s through a"" the ?date? va"ues that occur in the ?data? array. In thins case the .e*tent
(unction returns the 1ini1u1 and 1a*i1u1 va"ue in the given array.
So function#d$ M return d.dateK P returns a"" the ?date? va"ues in ?data?. This is then assed
to...
The .e*tent (unction that (inds the 1a*i1u1 and 1ini1u1 va"ues in the array and then...
The .do1ain (unction .hich returns those 1a*i1u1 and 1ini1u1 va"ues to -3 as the
range (or the * a*is.
=retty neat rea""y. 6t (irst you 1ight thin9 it .as s"ight"y over"y co1"e*; but brea9ing the (unction
do.n into these co1onents; a""o.s additiona" (unctiona"ity .ith di((ering sca"es; va"ues and
Auantities. In short; don?t s.eat it. It?s a good thing.
Jo.; the * a*is va"ues are dates; so the do1ain (or the1 is basica""y (ro1 the 0%
th
o( March 0:10
ti"" 1
st
o( May 0:10. The y a*is is done s"ight"y di((erent"y
d3noob.org 0)
y.do1ain#U:; d3.1a*#data; function#d$ M return d.c"oseK P$V$K
Cecause the range o( va"ues desired on the y a*is goes (ro1 : to the 1a*i1u1 in the data range;
that?s e*act"y .hat .e te"" -3. The ?:? in the .do1ain (unction is the starting oint and the (inishing
oint is (ound by e1"oying a searate (unction that sorts through a"" the ?c"ose? va"ues in the ?data?
array and returns the "argest one. There(ore the do1ain is (ro1 : to %3%.03.
Let?s try a s1a"" e*eri1ent. Let?s change the y a*is do1ain to use the .e*tent (unction #the sa1e
.ay the * a*is does$ to see .hat it roduces.
So the JavaScrit (or the y do1ain .i"" beK
y.do1ain#d3.e*tent#data; function#d$ M return d.c"oseK P$$K
Eou can see aart (ro1 a Auic9 coy aste o( the interna"s; a"" I had to change .as the re(erence to
?c"ose? rather than ?date?.
6nd the resu"t is...
Loo9 at that. The starting oint (or the y a*is "oo9s "i9e it?s retty 1uch on the 53./2 1ar9 and the
grah itse"( certain"y touches the * a*is .here the data .ou"d indicate it shou"d.
Jo.; I?1 not rea""y advocating 1a9ing a grah "i9e this since I thin9 it "oo9s a bit nasty #and a
casua" observer 1ight be (oo"ed into thin9ing that the * a*is .as at :$. Ho.ever; this .ou"d be a
use(u" thing to do i( the data .as concentrated in a narro. range o( va"ues that are Auite distant
(ro1 Fero.
3or instance; i( I change the data.tsv (i"e so that the va"ues are reresented "i9e the (o""o.ingK
d3noob.org 02
Then it 9ind o( "ooses the abi"ity to distinguish bet.een va"ues around the 1edian o( the data.
Cut; i( I ut in our 1agic .e*tent (unction (or the y a*is and redra. the grah...
Ho. about that?
The sa1e data as the revious grah; but .ith one si1"e iece o( the scrit changed and -3 ta9es
care o( the detai"s.
Setting up the &xes
So .e co1e to our ne*t iece o( codeK
var *6*is N d3.svg.a*is#$.sca"e#*$
.orient#Lbotto1L$.tic9s#5$K
var y6*is N d3.svg.a*is#$.sca"e#y$
.orient#L"e(tL$.tic9s#5$K
I?ve inc"uded both the * and y a*es because they carry out the (or1atting in very si1i"ar .ays. 6nd
it?s .orth noting that this is not the oint .here the a*es get dra.n. That occurs "ater in the iece
.here the data.tsv (i"e has been "oaded as ?data?.
-3 has it?s o.n a*is co1onent that ai1s to ta9e the (uss out o( setting u and dis"aying the a*es.
So it inc"udes a nu1ber o( con(igurab"e otions.
d3noob.org 0/
Loo9ing (irst at the * a*isK
var *6*is N d3.svg.a*is#$.sca"e#*$
.orient#Lbotto1L$.tic9s#5$K
The a*is (unction is ca""ed .ith d3.svg.a*is#$ and then the sca"e is set using the * va"ues that .e
setu in the sca"es; ranges and do1ains section using .sca"e#*$. Then a curious thing haens; .e
te"" the grah to orientate itse"( to the botto1 o( the grah .orient#Lbotto1L$. Jo. i( I te"" you that
Lbotto1L is the de(au"t setting; then you cou"d be (orgiven (or thin9ing that technica""y; .e don?t
need to seci(y this since it .i"" go there any.ay; but it does give us an oortunity to change it to
to GtoH to see .hat haensK
We""; I hoe you didn?t see that co1ing; because I didn?t. So; it .ou"d transire that .hat .e?re
ta"9ing about there is the orientation o( the va"ues and tic9s about the a*is "ine itse"(. 6hh... &9. So;
use(u" i( your * a*is is at the to o( your grah; but (or this one; not so use(u".
6"" right; he ne*t art #.tic9s#5$$ sets the nu1ber o( tic9s on the a*is. Hoe(u""y you <ust did a Auic9
count across the botto1 o( the revious grah and .ent GEe; (ive tic9s. Sot onH. We"" done i( you
did; but there?s a "itt"e bit o( a snea9y tric9 u -3?s s"eeve .ith the nu1ber o( tic9s on a grah a*is.
3or instance; here?s .hat the grah "oo9s "i9e .hen the .tic9s#5$ va"ue is changed to .tic9s#4$.
+h? Hang on. Isn?t that so1e 9ind o( 1ista9e? There?s sti"" (ive tic9s. Ee sure is. Cut .ait... .e can
9ee droing the tic9s va"ue ti"" .e get to t.o and it .i"" sti"" be the sa1e. 6t .tic9s#0$ though; .e
(ina""y see a change.
d3noob.org 3:
Ho. about that? 6t (irst g"ance that <ust doesn?t see1 right; then you have a bit o( a thin9 about it
and you go GH11... When there .ere 5 tic9s; they .ere searated by a .ee9 each; and that stayed
that .ay ti"" .e got to a oint .here it cou"d sho. a searation o( a 1onth.H.
So; .hat?s going on here is that -3 is 1a9ing a co11and decision (or you as to ho. your tic9s
shou"d be best dis"ayed. This is great (or si1"e grahs and indeed (or the vast 1a<ority o( grahs.
6nd "i9e a"" things -3; i( you rea""y need to do so1ething beso9e and (ancy; it?"" "et you i( you
9no. enough.
The (o""o.ing is the "ist
14
o( ti1e interva"s that -3 .i"" consider .hen setting auto1atic tic9s on a
ti1e based a*isK
1@; 5@; 15@ and 3:@second.
1@; 5@; 15@ and 3:@1inute.
1@; 3@; %@ and 10@hour.
1@ and 0@day.
1@.ee9.
1@ and 3@1onth.
1@year.
Just (or gigg"es have a thin9 about .hat va"ue o( tic9s you .i"" need to increase to unti" you get -3
to sho. 1ore than (ive tic9s.
Hoe(u""y you .on?t snea9 a g"ance at the (o""o.ing grah be(ore you co1e u .ith the right
ans.er.
14 htts>44github.co141bostoc94d34.i9i4Ti1e@Sca"es
d3noob.org 31
Ei9es8 The ans.er is 1:8 6nd then .hen it does; the nu1ber o( tic9s is so great that they <u1b"e a""
over each other. Jot "oo9ing to good there. Ho.ever; you cou"d rotate the te*t #or erhas s"ant it$
and it cou"d (it in #that 1ust be the toic o( a (uture ho.@to$. Eou cou"d a"so 1a9e the grah "onger
i( you .anted; but o( course that is robab"y going to create other "ayout rob"e1s. So thin9 about
your data and resentation as a sing"e entity.
The code that (or1ats the y a*is is retty si1i"arK
var y6*is N d3.svg.a*is#$.sca"e#y$
.orient#L"e(tL$.tic9s#5$K
We can change the orientation to LrightL i( .e .ant; but it .on?t be .inning any beauty riFes.
Joe. Jot a retty sight.
So .hat about the u1ber o( tic9s? We"" this sca"e is Auite di((erent to the * a*is. 3or1atting the
dates using "ogica" searators #.ee9s; 1onths$ .as tric9y; but .ith standard nu1bers; it shou"d be a
"itt"e easier. In (act; there?s a better than even chance that you?ve a"ready had a "oo9 at the y a*is and
seen that there are % tic9s there a"ready .hen the scrit is as9ing (or 5 >@$
6nd .ithout too 1uch (ussing around; .e can "o.er the tic9 nu1ber to 4 and .e get a "ogica"
resu"t.
d3noob.org 30
Cut .e need to raise the count to 1: be(ore .e get 1ore than %.
&dding data to the line function
We?re getting to.ards the end o( our <ourney through the scrit no.. The ne*t ste is to get the
in(or1ation (ro1 the array ?data? and to "ace it in a ne. array that consists o( a set o( coordinated
that corresond to the oints .e are going to "ot.
var va"ue"ine N d3.svg."ine#$
.*#function#d$ M return *#d.date$K P$
.y#function#d$ M return y#d.c"ose$K P$K
Jo. I?1 a.are that the state1ent above 1ay be so1e.hat a1biguous. Eou .ou"d be <usti(ied in
thin9ing that .e a"ready had the data stored and ready to go. Cut that?s not strictly correct.
What .e have is data in a ra. (or1at; .e have added ieces o( code that .i"" a""o. the data to be
ad<usted (or sca"e and range to (it in the area that .e .ant to dra.; but .e haven?t actua""y ta9en our
ra. data and ad<usted it (or our desired coordinates. That?s .hat the code above does.
d3noob.org 33
The 1ain (unction that gets used here is the d3.svg."ine#$ (unction
15
. This (unction uses assessor
(unctions to store the aroriate in(or1ation in the right area and in the case above they use the *
and y assessors #that .ou"d be the bits that are ?.*? and ?.y?$. The d3.svg."ine#$ (unction is ca""ed a
?ath generator? and this is an indication that it can carry our so1e retty c"ever things on its o.n
accord. Cut in essence its <ob is to assign a set o( coordinates in a (or1 that can be used to dra. a
"ine.
So each ti1e this "ine (unction is ca""ed on; it .i"" go through the data it is ointed to and it .i""
assign coordinates to ?date? and ?c"ose? airs using the ?*? and ?y? (unctions that .e set u ear"ier
#.hich o( course are resonsib"e (or sca"ing and setting the correct range 4 do1ain$.
&( course; it doesn?t get the data a"" by itse"(; .e sti"" need to actua""y ca"" the va"u"ine (unction .ith
?data? as the source to act on. Cut never (ear; that?s co1ing u soon.
&dding the S'G Can(as"
6s the tit"e states; the ne*t iece o( scrit (or1s and adds the canvas that -3 .i"" then use to dra.
on.
var svg N d3.select#LbodyL$
.aend#LsvgL$
.attr#L.idthL; .idth O 1argin."e(t O 1argin.right$
.attr#LheightL; height O 1argin.to O 1argin.botto1$
.aend#LgL$
.attr#Ltrans(or1L; Ltrans"ate#L O 1argin."e(t O L;L O 1argin.to O L$L$K
So .hat e*act"y does that a"" 1ean?
We"" -3 need to be ab"e to have a sace de(ined (or it to dra. things. 6nd .hen you de(ine the
sace it?s going to use; you can a"so give the sace you?re going to use a na1e; attributes and
ositions .ithin that sace a designation.
In the e*a1"e .e?re using here; .e are ?aending? an S7, e"e1ent #a canvas that .e are going to
dra. things on$ to the ?RbodyS? e"e1ent o( the HTML age.
In hu1an ta"9 that 1eans that on the .eb age and bounded by the RbodyS tag that .e sa. in the
HTML art; .e .i"" have an area to dra. on. That area .i"" be ?.idth? "us the "e(t and right
1argins .ide and ?height? "us the to and botto1 1argins .ide.
We a"so add an e"e1ent ?g? that is re(erenced to the to "e(t corner o( the actua" grah area on the
canvas. ?g? is actua""y a grouing e"e1ent in the sense that it is nor1a""y used (or grouing together
severa" re"ated e"e1ents. So in this case those groued e"e1ents .i"" have a co11on re(erence.
15 htts>44github.co141bostoc94d34.i9i4S7,@ShaesZ.i9i@"ine
d3noob.org 34
#the i1age above is de(inite"y not to sca"e; but I hoe you get the genera" idea$
Interesting things to note about the code. The .attr#Gstuff in hereH$ arts are attributes o( the
aended e"e1ents they are art o(.
3or instanceK
.aend#LsvgL$
.attr#L.idthL; .idth O 1argin."e(t O 1argin.right$
.attr#LheightL; height O 1argin.to O 1argin.botto1$
te""s us that the ?svg? e"e1ent has a L.idthL o( .idth O 1argin."e(t O 1argin.right and the LheightL
o( height O 1argin.to O 1argin.botto1.
Li9e.ise...
.aend#LgL$
.attr#Ltrans(or1L; Ltrans"ate#L O 1argin."e(t O L;L O 1argin.to O L$L$K
te""s us that the e"e1ent LgL has been trans(or1ed by 1oving#trans"ating$ to the oint 1argin."e(t;
1argin.to. &r to the to "e(t o( the grah sace roer. This .ay .hen .e te"" so1ething to be
dra.n on our canvas; .e can use the re(erence oint LgL to 1a9e sure everything is in the right
"ace.
&ctually Draing So!ething)
' unti" no. .e have sent a "ot o( ti1e de(ining; "oading and setting u. ,ood ne.s8 We?re about
to (ina""y dra. so1ething8
We <u1 "ight"y over so1e o( the code that .e have a"ready e*"ained and "and on the art that
dra.s the "ine.
svg.aend#LathL$ // Add the valueline path.
.attr#LdL; va"ue"ine#data$$K
d3noob.org 35
This area occurs in the art o( the code that has the data "oaded and ready (or action.
The svg.aend#LathL$ ortion adds a ne. ath e"e1ent . 6 ath e"e1ent reresents a shae that
can be 1aniu"ated in "ots o( di((erent .ays #see 1ore here>
htt>44.....3.org4T54S7,4aths.ht1"$. In this case it inherits the ?ath? sty"es (ro1 the !SS
section and on the (o""o.ing "ine #.attr#LdL; va"ue"ine#data$$K$ .e add the attribute GdH.
This is an attributer that stands (or ?ath data? and sure enough the va"ue"ine#data$ ortion o( the
scrit asses the ?va"ue"ine? array #.ith its * and y coordinates$ to the ath e"e1ent. This then creates
a svg e"e1ent .hich is a ath going (ro1 one set o( ?va"ue"ine? coordinates to another.
Then .e get to dra. in the a*esK
svg.aend#LgL$ // Add the X Axis
.attr#Lc"assL; L* a*isL$
.attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$
.ca""#*6*is$K
svg.aend#LgL$ // Add the Y Axis
.attr#Lc"assL; Ly a*isL$
.ca""#y6*is$K
We have covered the (or1atting o( the a*is co1onents ear"ier. So this art is actua""y <ust about
getting those co1onents dra.n onto our canvas.
So both a*es start by being aended to the GgH grou. Then each has its o.n c"asses a"ied (or
sty"ing via !SS. I( you reca"" (ro1 ear"ier; they "oo9 a "itt"e "i9e thisK
.a*is ath;
.a*is "ine M
(i""> noneK
stro9e> greyK
stro9e@idth> 1K
shae@rendering> cris+dgesK
P
3ee" (ree to 1ess about .ith these to change the aearance o( your a*es.
&n the * a*is; .e have a trans(or1 state1ent #.attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$$. I(
you reca""; our oint o( origin (or dra.ing is in the to "e(t hand corner. There(ore i( .e .ant our *
a*is to be on the botto1 o( the grah; .e need to 1ove #trans(or1$ it to the botto1 by a set a1ount.
The set a1ount in this case is the height o( the grah roer #height$. So; (or the oint o(
de1onstration .e .i"" re1ove the trans(or1 "ine and see .hat haensK
d3noob.org 3%
Ee; retty 1uch as anticiated.
The "ast art o( the t.o sections o( scrit # .ca""#*6*is$K and .ca""#y6*is$K $ca"" the * and y a*is
(unctions and initiate the dra.ing action.
Wrap *p
We"" that?s it. In theory; you shou"d no. be a co1"ete -3 nin<a.
&D; erhas a s"ight e*aggeration. In (act there is a strong ossibi"ity that the in(or1ation I have
"aid out here is at best border"ine use(u" and at .orst "aden .ith evi" ractices and gross
inaccuracies.
Cut "oo9 on the bright side. Irresective o( the nastiness o( the .ay that any o( it .as acco1"ished
or the ine"egance o( the code; i( the icture dra.n on the screen is retty; you can .a"9 a.ay .ith a
s1i"e. >@$
I?ve said it be(ore and I?"" say it again. This is not a ho.@to (or "earning -3. This is ho. I have
1anaged to 1udd"e through in a bu1b"ing .ay to try and achieve .hat I .anted to do. I( so1e
s1a"" art o( it he"s you. 6"" good. Those .ith a s1attering o( 9no."edge o( any o( the toics I
have butchered above # or be"o.$ are (u""y <usti(ied in (ee"ing a "arge degree o( righteous
indignation. To those I say; "ease (ee" (ree to a1end .here ractica" and ossib"e; but "ease bear
in 1ind this .as .ritten (ro1 the oint o( vie. o( so1eone .ith no e*erience in the toic and
there(ore try to 9ee any instructions at a "eve" .here a ne. entrant can ste in.
d3noob.org 3)
Things you can do ith the basic graph
The (o""o.ing headings in this section are intended to be a "ist o( re"ative"y si1"e ?b"oc9? tye
i1rove1ents that you can do to your grah to add (unctiona"ity. The idea is to be ab"e to use the
si1"e grah that .as used (or the e*"anation o( ho. -3 .or9ed and <ust s"ot in code to add
(unctiona"ity #"et?s hoe it .or9s (or you >@$.
"dding "#is Labels
What?s the (irst thing you get to"d at schoo" .hen dra.ing a grah?
G6".ays "abe" your a*es8H
So; ti1e to add a cou"e o( "abe"s8
3irst things (irst #because they?re done s"ight"y di((erent"y$; the * a*is. I( .e begin by describing
.hat .e .ant to achieve; it 1ay 1a9e the rocess o( i1"e1enting a so"ution a "itt"e 1ore "ogica"
What .e .ant to do is to add a si1"e iece o( te*t under the * a*is and in the centre o( the tota"
san. Wo.; that does sound easy.
6nd it is; but there are di((erent .ays o( acco1"ishing it; and I thin9 I shou"d ta9e an oortunity
to de1onstrate the1. +secia""y since one o( those .ays is a C6- idea.
Lets start .ith the bad idea (irst >@$.
This is the code .e?re going to add to the si1"e "ine grah scritK
svg.aend#Lte*tL$ // text label for the x axis
.attr#L*L; 0%5 $
.attr#LyL; 04: $
.sty"e#Lte*t@anchorL; L1idd"eL$
.te*t#L-ateL$K
We .i"" ut it in bet.een the b"oc9s o( scrit that add the * a*is and the y a*is.
svg.aend#LgL$ // Add the X Axis
.attr#Lc"assL; L* a*isL$
.attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$
.ca""#*6*is$K
44 $UT T%E NE& 'ODE %ERE(
svg.aend#LgL$ // Add the Y Axis
.attr#Lc"assL; Ly a*isL$
.ca""#y6*is$K
Ce(ore .e describe .hat?s haening; "et?s ta9e a "oo9 at the resu"tK
d3noob.org 32
We""; it certain"y did .hat it .as as9ed to do. There?s a ?-ate? "abe" as advertised8 #Ees; I 9no. it?s
not retty.$ Let?s describe the code and then .or9 out .hy there?s a better .ay to do it.
svg.aend#Lte*tL$ // text label for the x axis
.attr#L*L; 0%5 $
.attr#LyL; 04: $
.sty"e#Lte*t@anchorL; L1idd"eL$
.te*t#L-ateL$K
The (irst "ine aends a Lte*tL e"e1ent to our canvas. There is a "ot 1ore to "earn about Lte*tL
e"e1ents hereK htt>44.....3.org4T54S7,4te*t.ht1"ZTe*t+"e1ent.
The ne*t t.o "ines # .attr#L*L; 0%5 $ and .attr#LyL; 04: $ $ set the attributes (or the * and y coordinates
to osition the te*t on the canvas.
The second "ast "ine #.sty"e#Lte*t@anchorL; L1idd"eL$$ ensures that the te*t ?sty"e? is such that the te*t
is centre a"igned and there(ore re1ains nice"y centred on the *;y coordinates that .e send it to.
The (ina" "ine #.te*t#L-ateL$K$ adds the actua" te*t that .e are going to "ace.
That see1s rea""y si1"e and e((ective and it is. Ho.ever; the bad art about it is that .e have hard
coded the "ocation (or the date into the code. This 1eans i( .e change any o( the hysica" asects o(
the grah; .e .i"" end u having to re@ca"cu"ate and edit our code. 6nd .e don?t .ant to do that.
Here?s an e*a1"e. I( I decide that I .ou"d re(er to increase the height o( the grah by editing the
"ine hereK
height N 0): @ 1argin.to @ 1argin.botto1K

and 1a9ing the height 35: i*e"sK
height N 35: @ 1argin.to @ 1argin.botto1K
The resu"t is as (o""o.sK
d3noob.org 3/
EVERY!"#G about the grah has ad<usted itse"(; e*cet our nasty; hard coded ?-ate? "abe". This is
(ar (ro1 idea" and can be easi"y (i*ed by using the variab"es that .e set u ever so care(u""y ear"ier.
So; instead o(K
.attr#L*L; 0%5 $
.attr#LyL; 04: $
"ets "et our variab"es do the .a"9ing and useK
.attr#L*L; .idth 4 0 $
.attr#LyL; height O 1argin.botto1$
So .ith this code .e te"" the scrit that the ?-ate? "abe" .i"" a".ays be ha"(.ay across the .idth o(
the grah #no 1atter ho. .ide it is$ and at the botto1 o( the grah .ith resect to it?s height and the
botto1 1argin #re1e1ber it uses a coordinates syste1 that increases (ro1 the to do.n$.
The end resu"t o( using variab"es is that i( I go to an e*tre1e o( changing the height and .idth o(
1y grah toK
.idth N 4:: @ 1argin."e(t @ 1argin.right;
height N 0:: @ 1argin.to @ 1argin.botto1K
We sti"" get an accetab"e resu"tK
We""; (or the "abe" osition at "east >@$.
d3noob.org 4:
So the changes to using variab"es is <ust a use(u" "esson that variab"es roc9 and 1ean that you don?t
have to .orry about your grah staying in re"ative shae .hi"e you change the di1ensions. The
astute readers a1ongst you .i"" have "earned this "esson very ear"y on in your rogra11ing careers;
but it?s never a bad idea to 1a9e sure that users that are un(a1i"iar .ith the concet have an
indicator o( .hy it?s a good idea.
Jo. the third 1ethod that I 1entioned at the start o( our * a*is odyssey. This is not 1entioned
because its any better or .orse .ay to i1"e1ent your scrit #The reason that I say this is because
I?1 not sure i( it?s better or .orse.$ but because it?s su((icient"y di((erent to 1a9e it "oo9 con(using i(
you didn?t thin9 o( it in the (irst "ace.
So; .e?"" ta9e our 1arve""ous coordinates codeK
.attr#L*L; .idth 4 0 $
.attr#LyL; height O 1argin.botto1$
6nd re"ace it .ith a sing"e #"onger$ "ineK
.attr#Ltrans(or1L; Ltrans"ate#L O #.idth 4 0$ O L ;L O #height O 1argin.botto1$ O L$L$
This uses the Ltrans(or1L attribute to 1ove #trans"ate$ the oint to "ace the ?-ate? "abe" to e*act"y
the sa1e sot that .e?ve been using (or the other t.o e*a1"es #using variab"es o( course$.
Things to note about this iece o( codeK
The Ltrans"ateH (unction is done in a ?trans"ate#*;y$? sty"e but it is ut on the age in such a .ay that
the verbati1 ieces that get assed bac9 are in seech 1ar9s and the variab"es are in the c"ear #in a
1anner o( sea9ing$. That?s .hy the co11a is in seech 1ar9s.
6dditiona""y; the variab"es are contained .ithin "us signs. I 1a9e the assu1tion that this is a
designator (or ?areas .here there is variab"e action going on?. The end resu"t is that i( you try to do
so1e 1aths in that area .ith a "us sign; it does not aear to .or9 #or at "east it didn?t (or 1e$.
That?s .hy I ut the variab"e (or # O #height O 1argin.botto1$ O $ in arenthesis #then I thought I
shou"d 1a9e the O #.idth 4 0$ O art "oo9 the sa1e; but actua""y you can get a.ay .ithout the1
there$.
So; that?s the * a*is "abe". Ti1e to do the y a*is. The code .e?re going to use "oo9s "i9e thisK
svg.aend#Lte*tL$
.attr#Ltrans(or1L; Lrotate#@/:$L$
.attr#LyL; : X 1argin."e(t$
.attr#L*L;: @ #height 4 0$$
.attr#LdyL; L1e1L$
.sty"e#Lte*t@anchorL; L1idd"eL$
.te*t#L7a"ueL$K
3or the sa9e o( neatness .e .i"" ut the iece o( code in a nice "ogica" sot and this .ou"d be
(o""o.ing the b"oc9 o( code that added the y a*is #but be(ore the c"osing cur"y brac9et$
svg.aend#LgL$ 44 6dd the E 6*is
.attr#Lc"assL; Ly a*isL$
.ca""#y6*is$K
)) $UT T%E NE& 'ODE %ERE(
P$K
6nd the resu"t "oo9s "i9e thisK
d3noob.org 41
There .e go; a "abe" (or the y a*is that is nice"y centred and #gas8$ rotated by /: degrees8 Woah;
does the "eetness never end8 #Jo. Jo it does not.$
So; ho. do .e get to this incredib"e resu"t?
The (irst thing .e do is the sa1e as (or the * a*is and aend a test e"e1ent to our canvas
#svg.aend#Lte*tL$$.
Then things get interesting.
.attr#Ltrans(or1L; Lrotate#@/:$L$
Cecause that "ine rotates everything by @/: degrees. Whi"e it?s obvious that the te*t "abe" ?7a"ue? has
been rotated by @/: degrees #(ro1 the icture$; the (o""o.ing "ines o( code sho. that .e a"so rotated
our re(erence oint #.hich can be a "itt"e con(using$.
.attr#LyL; : X 1argin."e(t$
.attr#L*L;: @ #height 4 0$$
Let?s get grahica" to i""ustrate ho. this .or9sK
Here?s our starting osition; .ith *;y in the :;: coordinate o( the grah dra.ing area surrounded by
the 1argins.
When .e a"y a @/: degrees trans(or1 .e get the eAuiva"ent o( thisK
d3noob.org 40
Here the :;: coordinate has been shi(ted by @/: degrees and the *;y designations are ("ied so that
.e no. need to te"" the scrit that .e?re 1oving a ?y? coordinate .hen .e .ou"d have other.ise
been 1oving ?*?.
Hence; .hen the scrit runs...
.attr#LyL; : X 1argin."e(t$
[ .e can see that this is 1oving the * osition to the "e(t (ro1 the ne. : coordinate by the
1argin."e(t va"ue.
Li9e.ise .hen the scrit runs...
.attr#L*L;: @ #height 4 0$$
[ this is actua""y 1oving the y osition (ro1 the ne. : coordinate ha"(.ay u the height o( the
grah area.
Jo.; I .i"" be the (irst to ad1it that this does see1 a "itt"e con(using; but here?s the good art. Eou
rea""y don?t need to understand it co1"ete"y. Si1"y do .hat I did .hen I sa. the code. ="ay .ith
is a bit ti"" you get the resu"t you .ere "oo9ing (or. I( that 1eans utting in so1e hard coded
nu1bers and incre1enting the1 to see .hich .ay is the ne. ?u?. ,ood8 &nce you .or9 it out; then
.or9 out ho. to get the right variab"e e*ression in there and you?re set.
In the .orst case scenario; si1"y use the code b"oc9s as sho.n here and "eave .e"" enough
a"one >@$
5ight; .e?re not Auite done yet. The (o""o.ing "ine has the e((ect o( shi(ting the te*t s"ight"y to the
right.
.attr#LdyL; L1e1L$
3irst"y the reason .e do this is that our revious trans"ation o( coordinates 1eans that .hen .e
"ace our te*t "abe" it sits e*act"y on the "ine o( : X 1argin."e(t. Cut in this case that ta9es the te*t to
the other side o( the "ine; so it actua""y sits <ust outside the boundary o( the overa"" canvas.
d3noob.org 43
'%'
"%&
margin.top
margin.left
margin.bottom
margin.right
'( degrees
rotation
The LdyL attribute is another coordinate ad<ust1ent 1ove; but this ti1e a re"ative ad<ust1ent and
the L1e1L is a unit o( 1easure that eAua"s e*act"y one unit o( the current"y seci(ied te*t oint
siFe
1%
. So .hat ends u haening is that the ?7a"ue? "abe" gets shi(ted to the right by e*act"y the
height o( the te*t; .hich neat"y "aces it e*act"y on the edge o( the canvas.
The t.o (ina" "ines o( this art o( the scrit are the sa1e as (or the * a*is and they 1a9e sure
re(erence oint is a"igned to the centre o( the te*t #.sty"e#Lte*t@anchorL; L1idd"eL$$ and then it rints
the te*t #.te*t#L7a"ueL$K$. There; that .asn?t too ain(u".
H$% t$ add a title t$ y$ur graph
I( you?ve read through the adding the a*is "abe"s section 1ost o( this .i"" co1e as no surrise.
What .e .ant to do to add a tit"e to the grah is to add a te*t e"e1ent #<ust a (e. .ords$ that .i""
aear above the grah and centred "e(t to right.
The code b"oc9 .e .i"" use .i"" "oo9s "i9e thisK
svg.aend#Lte*tL$
.attr#L*L; #.idth 4 0$$
.attr#LyL; : @ #1argin.to 4 0$$
.attr#Lte*t@anchorL; L1idd"eL$
.sty"e#L(ont@siFeL; L1%*L$
.sty"e#Lte*t@decorationL; Lunder"ineL$
.te*t#L7a"ue vs -ate ,rahL$K
6nd the end resu"t .i"" "oo9 "i9e thisK
6 nice "ogica" "ace to ut the b"oc9 o( code .ou"d be to.ards the end o( the JavaScrit. In (act I
.ou"d ut it as the "ast e"e1ent .e add. So hereK
svg.aend#LgL$ 44 6dd the E 6*is
.attr#Lc"assL; Ly a*isL$
.ca""#y6*is$K
)) $UT T%E NE& 'ODE %ERE(
P$K
1% htt>44en..i9iedia.org4.i9i4+1Y#tyograhy$
d3noob.org 44
Jo. since the vast 1a<ority o( the code (or this b"oc9 is a regurgitation o( the a*is "abe"s code; I
don?t .ant to revisit that and b"oat u this docu1ent even 1ore; so I .i"" direct you bac9 to that
section i( you need to re(resh yourse"( on any articu"ar "ine. Cut..... There are a cou"e o( ne. ones
in there .hich cou"d bene(it (ro1 a "itt"e e*"anation.
Coth o( the1 are sty"e descritors and as such their <ob is to a"y a very seci(ic sty"e to this
e"e1ent.
.sty"e#L(ont@siFeL; L1%*L$
.sty"e#Lte*t@decorationL; Lunder"ineL$
What they do is retty se"( e*"anatory. Ma9e the te*t a seci(ic siFe and under"ine it. Cut .hat is
erhas s"ight"y 1ore interesting is that .e have this dec"aration in the JavaScrit code and not in
the !SS ortion o( the (i"e.
Cecause strict"y sea9ing; this is the sort o( thing that .ou"d be "aced in the Rsty"eS section o( the
HTML code; but in this case since it is on"y going to be used the once; .e shou"dn?t (ee" too bad
utting it here.
S&$$thing $ut graph lines
When you dra. a "ine grah; .hat you?re doing is ta9ing t.o #or 1ore$ sets o( coordinates and
connecting the1 .ith a "ine #or "ines$. I 9no. that sounds si1"istic; but bear .ith 1e. When you
connect these oints; you?re te""ing the vie.er o( the grah that in bet.een the individua" oints;
you e*ect the va"ue to vary in 9eeing .ith the oints that the "ine asses through. So in a .ay;
you?re trying to interret the change in va"ues that are not sho.n.
Jo. this is not strict"y true (or a"" grah tyes; but it does ho"d (or a "ot o( "ine grahs.
So... .hen connecting these 9no.n coordinated together; you .ant to 1a9e the best esti1ate o(
ho. the va"ues .ou"d be reresented. In this resect; so1eti1es a straight "ine bet.een oints is not
the best reresentation.
3or instance. +ar"ier; .hen de1onstrating the e*tent (unction (or grahing .e sho.ed a grah o(
the varying va"ues .ith the y a*is sho.ing a narro. range.
The resu"ting variation o( the grah sho.s a (air a1ount o( e*tre1es and you cou"d be (orgiven (or
thin9ing that i( this reresented a s1ooth"y ("o.ing ana"og syste1 o( so1e 9ind then so1e o( those
shar ea9s and troughs .ou"d not be a true reresentation o( ho. the syste1 or (igures varied.
d3noob.org 45
So ho. shou"d it "oo9? 6hh... The \%4;::: Auestion. I don?t 9no. >@$. Eou .i"" have a better idea
since you are the erson .ho .i"" 9no. your data best. Ho.ever; .hat I do 9no. is that -3 has
so1e tric9s u its s"eeve to he".
We can easi"y change .hat .e see above intoK
Ho. about that? 6nd the 1assive a1ount o( code reAuired to carry out .hat 1ust be a ridicu"ous"y
di((icu"t set o( ca"cu"ations?
.intero"ate#LbasisL$
Jo.; that is s"ight"y un(air because that?s the code that E&' need to ut in your scrit; but Mi9e
Costoc9 robab"y had to do the 1enta" eAuiva"ent o( .a"9ing across hot coa"s to get it to .or9 so
nice"y.
So .here does this neat iece o( code go? HereK
var va"ue"ine N d3.svg."ine#$
.intero"ate#LbasisL$ 44 *+++ T%ERE ,T ,-(
.*#function#d$ M return *#d.date$K P$
.y#function#d$ M return y#d.c"ose$K P$K
So is that it? Jooooo........ There?s 1ore8 This is one (or1 o( intero"ation e((ect that can be a"ied
to your data; but there is a range and deending on your data you can se"ect the one that is
aroriate.
Here?s the "ist o( avai"ab"e otions and (or 1ore about the1 head on over to the -3 .i9i
1)
and "oo9
(or ?"ine.intero"ate?.
"inear X Jor1a" "ine #<agged$.
ste@be(ore X a steing grah a"ternating bet.een vertica" and horiFonta" seg1ents.
ste@a(ter @ a steing grah a"ternating bet.een horiFonta" and vertica" seg1ents.
basis @ a C@s"ine; .ith contro" oint du"ication on the ends #that?s the one above$.
basis@oen @ an oen C@s"ineK 1ay not intersect the start or end.
basis@c"osed @ a c"osed C@s"ine; .ith the start and the end c"osed in a "oo.
1) htts>44github.co141bostoc94d34.i9i4S7,@ShaesZ.i9i@"ineYintero"ate
d3noob.org 4%
bund"e @ eAuiva"ent to basis; e*cet a searate tension ara1eter is used to straighten the
s"ine. This cou"d be rea""y coo" .ith varying tension.
cardina" @ a !ardina" s"ine; .ith contro" oint du"ication on the ends. It "oo9s s"ight"y 1ore
?<agged? than basis.
cardina"@oen @ an oen !ardina" s"ineK 1ay not intersect the start or end; but .i"" intersect
other contro" oints. So 9ind o( shorter than ?cardina"?.
cardina"@c"osed @ a c"osed !ardina" s"ine; "ooed bac9 on itse"(.
1onotone @ cubic intero"ation that 1a9es the grah on"y s"ight"y s1oother.
Cecause in the course o( .riting this I too9 an oortunity to "ay .ith each o( the1; I .as
"easant"y surrised to see so1e o( the e((ects and it see1s "i9e a sha1e to derive the reader o( the
sa1e <oy >@$. So at the ris9 o( de(oresting the "anet #so I hoe you are reading this in e"ectronic
(or1at$ here is each o( the above intero"ation tyes a"ied to the sa1e data.
"inear
ste@be(ore
d3noob.org 4)
ste@a(ter
basis
basis@oen
d3noob.org 42
basis@c"osed
bund"e
cardina"
d3noob.org 4/
cardina"@oen
cardina"@c"osed
1onotone
So; over to you to decide .hich (or1at o( intero"ation is going to suit your data best>@$.
d3noob.org 5:
"dding grid lines t$ a graph
,rid "ines are an i1ortant (eature (or so1e grahs as they a""o. the eye to associate three ana"ogue
sca"es #the * and y a*is and the dis"ayed "ine$.
There is current"y a tendency to use grahs .ithout grid "ines on"ine as it gives the aearance o( a
?c"eaner? inter(ace; but they are sti"" .ide"y used and a necessary co1onent (or grahing.
This is .hat .e?re going to dra.K
Li9e retty 1uch everything in this docu1ent; the c"ever arts o( this are not 1y .or9. I?ve si1"y
used other eo"es c"everness to so"ve 1y rob"e1s. In this case I thin9 the source o( this so"ution
ca1e (ro1 the good .or9 o( Justin =a"1er in his e*ce""ent descrition o( the design o( a "ine grah
here htt>44dea""oc.1e40:114:%4044d3@is@not@a@grahing@"ibrary.ht1". Ho.ever; in retrosect .hen
I?ve "oo9ed bac9; I?1 not sure i( I got this right #as I did this Auite a .hi"e ago .hen I .as "ess
(astidious about noting 1y sources$. In any case; Justin?s .or9 is e*ce""ent and I hearti"y
reco11end it; and here is 1y i1"e1entation o( .hat I thin9 is his .or9 >@$
So; ho. to bui"d grid "ines?
We"" .hat .e?re going to do is to use the a*is (unction to generate t.o 1ore a*is e"e1ents #one (or
* and one (or y$ but (or these ones instead o( dra.ing the 1ain "ines and the "abe"s; .e?re <ust going
to dra. the tic9 "ines. 5ea""y "ong tic9"ines.
To create then .e have to add in 3 searate b"oc9s o( code.
1. &ne in the !SS section to de(ine .hat sty"e the grid "ines .i"" have.
0. &ne to de(ine the (unctions that generate the grid "ines. 6nd...
3. &ne to dra. the "ines.
The grid line CSS
This is the tota" sty"ing that .e need to add (or the tic9 "inesK
.grid .tic9 M
stro9e> "ightgreyK
oacity> :.)K
P
.grid ath M
stro9e@idth> :K
P
d3noob.org 51
Just add this b"oc9 o( code at the end o( the current !SS that is in the si1"e grah te1"ate #<ust
be(ore the R4sty"eS tag$.
The !SS here is done in t.o arts.
The (irst ortion sets the "ine co"our #stro9e$ and the oacity #transarency$ o( the "ines.
stro9e> "ightgreyK
oacity> :.)K
The co"our is retty standard; but in using the oacity sty"e .e give ourse"ves the oortunity to use
a good shade o( co"our #i( grey actua""y is a co"our$ and to <ugg"e the degree to .hich it stands out a
"itt"e better.
The second art is the stro9e .idth.
stro9e@idth> :K
Jo. it 1ight see1 a "itt"e .eird to be setting the stro9e .idth to Fero; but i( you don?t #and .e
re1ove the sty"e$ this is .hat haensK
I( you "oo9 c"ose"y #co1are .ith the revious icture i( necessary$ the 1ain "ines (or the a*is have
turned thic9er. The stro9e .idth sty"e is obvious"y adding in ne. #thic9er$ a*is "ines and .e?re not
interested in the1 at the 1o1ent. There(ore; i( .e set the stro9e .idth to Fero; .e get rid o( the
rob"e1.
Define the grid line functions
We .i"" need to de(ine t.o (unctions to generate the grid "ines and they "oo9 a "itt"e "i9e thisK
d3noob.org 50
function 1a9eY*Ya*is#$ M
return d$.svg.a*is#$
.sca"e#x$
.orient#Lbotto1L$
.tic9s#5$
P
function 1a9eYyYa*is#$ M
return d$.svg.a*is#$
.sca"e#y$
.orient#L"e(tL$
.tic9s#5$
P
+ach (unction .i"" carry out it?s con(iguration .hen ca""ed (ro1 the "ater art o( the scrit #the
dra.ing art$.
6 good sot to "ace the code is <ust be(ore .e "oad the data .ith the d3.tsv
44 *++ $ut the functions here(
44 ,et the data
d3.tsv#Ldata4data.tsvL; (unction#error; data$ M
data.(or+ach#(unction#d$ M
d.date N arse-ate#d.date$K
d.c"ose N Od.c"oseK
P$K
Coth (unctions are a"1ost identica". They give the (unction a na1e #1a9eY*Ya*is and
1a9eYyYa*is$ .hich .i"" be used "ater .hen the iece o( code that dra.s the "ines ca""s out to the1.
Coth (unctions a"so sho. .hich ara1eters each .i"" be (ed bac9 to the dra.ing rocess .hen
ca""ed. Coth 1a9e sure that is uses the d3.svg.a*is (unction and then they set individua" attributes
.hich 1a9e sense.
The 1a9e sure they?ve got the right a*is #.sca"e#x$ and .sca"e#y$$.
They set the orientation o( the a*es to 1atch the incu1bent a*es #.orient#Lbotto1L$ and
.orient#L"e(tL$$.
6nd they set the nu1ber o( tic9s to 1atch the nu1ber o( tic9s in the 1ain a*is #.tic9s#5$ and
.tic9s#5$$. Eou have the oortunity here to do so1ething s"ight"y di((erent i( you .ant. 3or
instance; i( .e thin9 bac9 to .hen .e .ere setting u the a*is (or the basic grah and .e 1esses
about .ith seeing ho. 1any .e cou"d get to aear. I( .e increase the nu1ber o( tic9s that aear
in the grid #"ets say to .tic9s#3:$ and .tic9s#1:$$$ .e get the (o""o.ingK
d3noob.org 53
So the grid "ines can no. sho. divisions o( 5: on the y a*is and er day on the * a*is >@$
Dra the lines
The (ina" b"oc9 o( code .e need is the bit that dra.s the "ines.
svg.aend#LgL$
.attr#Lc"assL; LgridL$
.attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$
.ca""#1a9eY*Ya*is#$
.tic9SiFe#@height; :; :$
.tic93or1at#LL$
$
svg.aend#LgL$
.attr#Lc"assL; LgridL$
.ca""#1a9eYyYa*is#$
.tic9SiFe#@.idth; :; :$
.tic93or1at#LL$
$
The (irst t.o "ines o( both the * and y a*is grid "ines code above shou"d be retty (a1i"iar by no..
The (irst one aends the e"e1ent to be dra.n to the grou LgL. the second "ine #.attr#Lc"assL;
LgridL$$ 1a9es sure that the sty"e in(or1ation set out in the !SS is a"ied.
The * a*is grid "ines ortion 1a9es a s"ight deviation (ro1 con(or1ity here to ad<ust its ositioning
to ta9e into account the coordinates syste1 .attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$.
Then both ortions ca"" their resective 1a9e a*is (unctions #.ca""#1a9eY*Ya*is#$ and
.ca""#1a9eYyYa*is#$$.
Jo. co1es the rea""y interesting bit.
What you .i"" see i( you go to the -3 6=I .i9i
12
is that (or the .tic9SiFe (unction; the (o""o.ing is
the (or1at.
a*is.tic9SiFe#U1a<orUU; 1inorV; endVV$
12 htts>44github.co141bostoc94d34.i9i4S7,@6*esZ.i9i@tic9SiFe
d3noob.org 54
That te""s us that you get to seci(y the siFe o( the tic9s on the a*es; by the 1a<or tic9s; the 1inor
tic9s and the end tic9s #that is to say the "ines on the very end o( the grah .hich in the case o( the
e*a1"e .e are "oo9ing at aren?t there8$.
So in our e*a1"e .e are setting our 1a<or tic9s to a "ength that corresonds to the (u"" height or
.idth o( the grah. Which o( course 1eans that they e*tend across the grah and have the
aearance o( grid "ines8 What a neat tric9.
So1ething I haven?t done be(ore is to see .hat .ou"d haen i( I inc"uded the tic9 "ines (or the
1inor and end tic9s. So here .e go >@$
-arn8 -isaoint1ent. We can see a 1inor tic9 "ine (or the y a*is; but nothing (or the * a*is and
nothing on the ends. !"ear"y I .i"" have to run so1e e*eri1ents to see .hat?s going on there
#"ater$.
The "ast thing that is inc"uded in the code to dra. the grid "ines is the instruction to suress
rinting any "abe" (or the tic9sK
.tic93or1at#LL$
6(ter a""; that .ou"d beco1e a bit con(using to have t.o sets o( "abe"s. +ven i( one .as on to o(
the other. They do tend to beco1e obvious i( that occurs #they 9ind o( bu"9 out a bit "i9e bo"d te*t$.
6nd that?s it. ,rid "ines8
Ma'e a dashed line
-ashed "ines tota""y roc98
&D; there 1ay be an e"e1ent o( e*aggeration there; but I certain"y (ound it interesting that there
didn?t see1 to be a "ot o( e*"anation (or a si1"e b"o9e "i9e 1yse"( to 1a9e a dashed "ine in -3. So
(or 1e they roc9ed >@$
&ne o( the best arts about it is that they?re so si1"e to do8
Litera""y one "ine8888
So "ets i1agine that .e .ant to 1a9e the "ine on our si1"e grah dashed. 6"" .e have to do is
insert the (o""o.ing "ine in our JavaScrit code hereK
svg.aend#LathL$
.attr#Lc"assL; L"ineL$
.sty"e#Lstro9e@dasharrayL; #L3; 3L$$ 44 *++ This line here((
.attr#LdL; va"ue"ine#data$$K
d3noob.org 55
6nd our grah ends u "i9e thisK
Hey8 It?s dashtastic8
So ho. does it .or9?
We""; obvious"y Lstro9e@dasharrayL is a sty"e (or the ath e"e1ent; but the 1agic is in the nu1bers.
+ssentia""y they describe the on "ength and o(( "ength o( the "ine. So L3; 3L trans"ates to 3 i*e"s #or
.hatever they are$ on and 3 i*e"s o((. Then it reeats. Si1"e eh?
So; e*eri1ent ti1e >@$
What .ou"d the (o""o.ing reresent?
G5; 5; 5; 5; 5; 5; 1:; 5; 1:; 5; 1:; 5H
Try not to cheat...
6hh yes; Mr Morse .ou"d be roud.
6nd you can ut the1 any.here. Here?s our a*es erverted .ith dashesK
d3noob.org 5%
svg.aend#LgL$
.attr#Lc"assL; L* a*isL$
.attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$
.sty"e#Lstro9e@dasharrayL; #L3; 3L$$
.ca""#*6*is$K
svg.aend#LgL$
.attr#Lc"assL; Ly a*isL$
.sty"e#Lstro9e@dasharrayL; #L3; 3L$$
.ca""#y6*is$K
We""... I suose you can have too 1uch o( a good thing. With great o.er co1es great
resonsibi"ity. 'se your dash s9i""s .ise"y and on"y (or good.
(illing an area under the graph)
Lines are a"" very .e"" and good; but that?s not the .ho"e story (or grahs. So1e ti1es you?ve <ust
got to go .ith a (i"".
3i""ing an area .ith a so"id co"our isn?t too hard. I 1ean .e did it by 1ista9e bac9 a (e. ages .hen
.e .ere trying to dra. a "ine.
Cut to do it in a nice coherent .ay is (air"y straight (or.ard.
It ta9es three sections o( code in 1uch the sa1e .ay that .e dre. our grid "ines ear"ier it is done in
three sectionsK
1. &ne in the !SS section to de(ine .hat sty"e the area .i"" have.
0. &ne to de(ine the (unctions that generate the area. 6nd...
3. &ne to dra. the area.
The end resu"t .i"" "oo9s a bit "i9e thisK
d3noob.org 5)
CSS for an area fill
This is retty straight (or.ard and on"y consists o( t.o ru"esK
.area M
(i""> "ightstee"b"ueK
stro9e@idth> :K
P
=ut the1 at the botto1 o( your Rsty"eS section.
The (irst one #(i""> "ightstee"b"ueK$ sets the co"our o( our (i"" #and in this case .e have chosen a
"ighter shade o( the sa1e co"our as our "ine to 1atch it$ and the second one #stro9e@idth> :K$ sets
the .idth o( the "ine that surrounds the area to Fero. This "ast ru"e is 9ind o( i1ortant in 1a9ing a
(i""ed area .or9 .e"". The .ho"e idea is that the grah is 1ade u o( searate e"e1ents that .i""
co1"i1ent each other. There?s the a*es; the "ine and the (i"". I( .e don?t te"" the code that there is no
"ine surrounding the (i""ed area; it .i"" assu1e that there is one and add it in "i9e this.
So .hat has haened here is that the area e"e1ent has inherited the "ine roerty (ro1 the ath
e"e1ent and surrounding the area is a 0* .ide stee"b"ue "ine. Jot too retty. Let?s not go there.
Define the area function
We need a (unction that .i"" te"" the area .hat sace to (i"". This is accessed (ro1 the d3.svg.area
(unction
1/
.
1/ htts>44github.co141bostoc94d34.i9i4S7,@ShaesZ.i9i@area
d3noob.org 52
The code that .e .i"" use is as (o""o.sK
var area N d3.svg.area#$
.*#function#d$ M return *#d.date$K P$
.y:#height$
.y1#function#d$ M return y#d.c"ose$K P$K
I have "aced it in bet.een the a*is variab"e de(initions and the "ine de(initions hereK
var y6*is N d3.svg.a*is#$.sca"e#y$
.orient#L"e(tL$.tic9s#5$K
*++++ $ut the ne code here(
var va"ue"ine N d3.svg."ine#$
.*#(unction#d$ M return *#d.date$K P$
.y#(unction#d$ M return y#d.c"ose$K P$K
Eou .i"" notice it "oo9s "#%RE&"'(Y si1i"ar to the va"ue"ine (unction de(inition. That?s because
.hi"e the "ine de(inition describes dra.ing a "ine the connects a set o( coordinates; I i1agine the
area de(inition describes dra.ing t.o "ines that share the sa1e * coordinates; but si1u"taneous"y
dra.s t.o y coordinates; y: and y1. Then .hen it?s (inished dra.ing the resu"tant shae; it (i""s it
.ith the co"our o( your choosing.
So the on"y changes to the code are the addition o( the ?y:? "ine and the rena1ing o( the ?y? "ine ?y1?.
Here?s a icture that 1ight he" e*"ainK
6s shou"d be aarent; the to "ine #y1$ (o""o.s the va"ue"ine "ine and the botto1 "ine is at the
constant ?height? va"ue. +verything in bet.een these "ines is .hat gets (i""ed. The (unction in this
section describes the area.
Dra the area
Jo. to the 1oney 1a9er.
The (ina" section o( code in the area (i""ing odyssey is as (o""o.sK
svg.aend#LathL$
.datu1#data$
.attr#Lc"assL; LareaL$
.attr#LdL; area$K
d3noob.org 5/
We shou"d "ace this b"oc9 direct"y a(ter the do1ain (unctions but be(ore the dra.ing o( the
va"ue"ine athK
*.do1ain#d3.e*tent#data; function#d$ M return d.dateK P$$K
y.do1ain#U:; d3.1a*#data; function#d$ M return d.c"oseK P$V$K
44 *++ Area drain. code here(
svg.aend#LathL$
.attr#Lc"assL; L"ineL$
.attr#LdL; va"ue"ine#data$$K
This is actua""y a retty good idea to ut it there since the various bits and ieces that are dra.n in
the grah are done so one a(ter the other. This 1eans that the (i""ed area co1es (irst; then the
va"ue"ine is "ayered on to and then the a*es co1e "ast. This is a retty good seAuence since i( there
are areas .here t.o or 1ore e"e1ents over"a; it 1ight cause the grah to "oo9 ?.rong?.
3or instance; here is the grah dra.n .ith the area added "ast.
Eou shou"d be ab"e to notice that art o( the va"ue"ine "ine has been obscured and the "ine (or the y
a*is .here it coincides .ith the area is obscured a"so.
Loo9ing at the code .e are adding here; the (irst "ine aends a ath e"e1ent #svg.aend#LathL$$
1uch "i9e the scrit that dra.s the "ine.
The second "ine #.datu1#data$$ dec"ares the data .e .i"" be uti"ising (or describing the area and the
third "ine #.attr#Lc"assL; LareaL$$ 1a9es sure that the sty"e .e a"y to it is as de(ined in the !SS
section #under ?area?$.
The (ina" "ine #.attr#LdL; area$K$ dec"ares GdH as the attributer (or ath data and ca""s the ?area?
(unction to do the dra.ing.
6nd that?s it8
#illing an area abo(e the line
$op /ui01
Ho. .ou"d you go about (i""ing the area A')VE the grah?
Jo. it 1ight sound a "itt"e trite; but be"ieve it or not; this cou"d co1e in handy. 3or instance; .hat i(
you .ant to high"ight an area that .as too high and an area that .as too "o. (or a "ine o( data on a
grah .ith an area in the centre .here a ro<ected ?nor1a"? set o( va"ues shou"d be resent?
d3noob.org %:
In this instance; you cou"d (i"" the "o.er area as has been de1onstrated here; and .ith a s1a""
change you can (i"" another area .ith a so"id co"our above another "ine.
Ho. is this incredib"e (eat achieved?
We""; re1e1ber the code that de(ined the area?
var area N d3.svg.area#$
.*#function#d$ M return *#d.date$K P$
.y:#height$
.y1#function#d$ M return y#d.c"ose$K P$K
6"" .e have to do is te"" it that instead o( setting the y: constant va"ue to the height o( the grah
#re1e1ber; this is the botto1 o( the grah$ .e .i"" set it to the constant va"ue that is at the to o(
the grah. In other .ords Fero #:$.
.y:#:$
That?s it.
Jo.; I?1 not going to go over the rocess o( dra.ing t.o "ines and (i""ing each in di((erent
directions to de1onstrate the e*a1"e I described; but this rovides a ger1 o( an idea that you
1ight be ab"e to ("esh out >@$
"dding a dr$p shad$% t$ all$% te#t t$ stand $ut $n graphics)
I?ve de"iberate"y ositioned this articu"ar ti to (o""o. the ?(i""ing an area? descrition because it
rovides an oortunity to de1onstrate the rinci"e to s"ight"y better e((ect.
There have been severa" oortunities .here I have .anted to "ace te*t over"aid on grahs (or
convenience sa9e on"y to have it "oo9 over"y 1essy as the te*t inter(eres .ith the grah.
Jo.; I?"" be the (irst to say that the rinci"e o( over"aying te*t on a grah is robab"y not best
ractice; but so1eti1es youIve got to do .hat you?ve got to do. Cesides. So1eti1es it?s a va"id
idea. I( I re1e1ber right"y; the (irst ti1e I ca1e across this idea; it .as being used to high"ight te*t
.hen ositioned on bars o( a bar grah. So it?s not a".ays an evi" ractice >@$.
6ny.ay; .hat .e?"" do is "eave the (i"" in "ace and "ace the tit"e bac9 on the grah; but osition the
tit"e so that it "ays on to o( the (i"" "i9e soK
d3noob.org %1
The additiona" code (or the tit"e is the (o""o.ing and aears <ust a(ter the dra.ing o( the a*es.
svg.aend#Lte*tL$
.attr#L*L; #.idth 4 0$$
.attr#LyL; 05 $
.attr#Lte*t@anchorL; L1idd"eL$
.sty"e#L(ont@siFeL; L1%*L$
.sty"e#Lte*t@decorationL; Lunder"ineL$
.te*t#L7a"ue vs -ate ,rahL$K
#the on"y change (ro1 the revious tit"e e*a1"e is the ?y? attribute .hich has been hard coded to 05
to "ace it inconvenient"y on the (i""ed area.$
So; .hat .e .ant to end u .ith is so1ething "i9e the (o""o.ing...
In 1y hu1b"e oinion; it?s <ust enough to 1a9e the te*t accetab"e >@$.
The 1ethod that I?"" describe to carry this out is designed so that the dro shado. e((ect can be
a"ied to any o( the te*t in a grah; not the iso"ated e*a1"e that .e .i"" use here. In order to
i1"e1ent this 1arve" o( uti"ity .e .i"" need to 1a9e changes in t.o areas. &ne in the !SS .here
.e .i"" de(ine a sty"e (or .hite shado.y bac9grounds and the second to dra. it.
CSS for hite shadoy background
The code to add to the !SS section is as (o""o.sK
d3noob.org %0
te*t.shado. M
stro9e> .hiteK
stro9e@idth> 0.5*K
oacity> :./K
P
The (irst "ine designates that the sty"e a"ies to te*t .ith a ?shado.? "abe". The stro9e is set to .hite.
the .idth o( the "ine is set to 0.5* and it is 1ade to be s"ight"y see@through. So by setting the "ine
that surrounds the te*t to be thic9; .hite and see@through gives it a s"ight"y ?c"oudy? e((ect. I( .e
re1ove the b"ac9 te*t (ro1 over the to .e get a s"ight"y better "oo9K
&( course i( you .ant to have a "ay .ith any o( these settings; you shou"d have a go and see .hat
.or9s best (or your grah.
Draing the hite shadoy background"
Jo. that .e?ve set the sty"e (or our bac9ground; .e need to dra. it in.
The code (or this shou"d be e*tre1e"y (a1i"iarK
svg.aend#Lte*tL$
.attr#L*L; #.idth 4 0$$
.attr#LyL; 05 $
.attr#Lte*t@anchorL; L1idd"eL$
.sty"e#L(ont@siFeL; L1%*L$
.sty"e#Lte*t@decorationL; Lunder"ineL$
.attr#Lc"assL; Lshado.L$ 44 *+++ %ere's the different line
.te*t#L7a"ue vs -ate ,rahL$K
That?s because it?s identica" to the iece o( code that .as used to dra. the tit"e e*cet (or the one
"ine that is indicated above. The reason that it?s identica" is that .hat .e are doing is "acing a .hite
shado. on the grah and then the te*t on to o( it; i( it deviated by a signi(icant a1ount it .i"" <ust
"oo9 si""y. &( course a s"ight a1ount cou"d "oo9 e((ective; in .hich case ad<ust the ?*? or ?y?
attributes.
&ne o( the things I ointed out in the revious aragrah .as e*tre1e"y i1ortant. That?s the bit
that te""s you that .e needed to "ace the shado. be(ore .e "aced the b"ac9 te*t. 3or the sa1e
reason that .e "aced the area (i"" on (irst in the area (i"" e*a1"e; I( b"ac9 te*t goes on be(ore the
shado.; it .i"" "oo9 retty si""y. So "ace this b"oc9 o( code <ust be(ore the b"oc9 that dra.s the tit"e.
So the "ine that has been added in is the one that te""s -3 that the te*t that is being dra.n .i"" have
the .hite c"oudy e((ect. 6nd at the ris9 o( reeating 1yse"(; i( you have severa" te*t e"e1ents that
cou"d bene(it (ro1 this e((ect; once you have the !SS code in "ace; a"" you need to do is du"icate
the b"oc9 that adds the te*t and add in that sing"e "ine and vio"a8
d3noob.org %3
"dding &$re than $ne line t$ a graph
6"" right; .e?re starting to get serious no.. T.o "ines on a grah is a bit o( a ste into a di((erent
.or"d in one resect. I 1ean that in the sense that there?s 1ore than one .ay to carry out the tas9;
and I tend to do it one .ay and not the other 1ain"y because I don?t (u""y understand the other
.ay >@#.
I shou"d stress that that?s not because it?s 1ore co1"e*; or that it?s a bad .ay; it?s <ust that once I
started doing things one .ay; I haven?t co1e across a need to do things another .ay. There?s a good
chance I .i"" have to revisit this decision in the (uture; but (or no. I?"" 9ee 1oving.
So; ho. are .e going to do this? I thin9 that the best .ay .i"" be to 1a9e the e*ecutive decision
that .e have sudden"y co1e across 1ore data and that it is a"so in our data.tsv (i"e. In (act it "oo9s a
"itt"e "i9e this #ao"ogies in advance (or the big ug"y b"oc9 o( data$K
date c"ose oen
1@May@10 52.13 34.10
3:@6r@10 53./2 45.5%
0)@6r@10 %).:: %).2/
0%@6r@10 2/.): )2.54
05@6r@10 //.:: 2/.03
04@6r@10 13:.02 //.03
03@6r@10 1%%.): 1:1.34
0:@6r@10 034./2 100.34
1/@6r@10 345.44 134.5%
12@6r@10 443.34 1%:.45
1)@6r@10 543.): 12:.34
1%@6r@10 52:.13 01:.03
13@6r@10 %:5.03 003.45
10@6r@10 %00.)) 0:1.5%
11@6r@10 %0%.0: 010.%)
1:@6r@10 %02.44 31:.45
/@6r@10 %3%.03 35:.45
5@6r@10 %33.%2 41:.03
4@6r@10 %04.31 43:.5%
3@6r@10 %0/.30 4%:.34
0@6r@10 %12.%3 51:.34
3:@Mar@10 5//.55 534.03
0/@Mar@10 %:/.2% 5)2.03
02@Mar@10 %1).%0 5/:.10
0)@Mar@10 %14.42 5%:.34
0%@Mar@10 %:%./2 52:.10
Three co"u1ns; date oen and c"ose. The (irst t.o are e*act"y .hat .e have been dea"ing .ith a""
a"ong and the "ast #oen$ is our ne. 1ade u data. +ach co"u1n is searated by a tab #hence .tsv
#Tab Searated 7a"ues$$; .hich is the (or1at .e?re current"y using to i1ort data.
We shou"d save this as a ne. (i"e so .e don?t 1ess u our revious data; so "et?s ca"" it data0.tsv.
We .i"" be using our si1"e grah te1"ate to start .ith; so the i11ediate conseAuence o( this is
that .e need to edit the "ine that .as "oo9ing (or ?data.tsv. To re("ect the ne. na1e.
d3.tsv#Ldata4data0.tsvL; function#error; data$ M
d3noob.org %4
So .hen you bro.se to our ne. grah ht1" (i"e; .e don?t see any changes. It sti"" hai"y "oads the
ne. data; but because it hasn?t been to"d to do anything .ith it; nothing ne. haens.
What .e need to do no. it to essentia""y du"icate the code b"oc9s that dre. the (irst "ine (or the
second "ine.
The good ne.s is that in the si1"est .ay ossib"e that?s <ust t.o code b"oc9s.
The (irst sets u the (unction that de(ines the ne. "ineK
var va"ue"ine0 N d3.svg."ine#$
.*#function#d$ M return *#d.date$K P$
.y#function#d$ M return y#d.oen$K P$K
Eou shou"d notice that this b"oc9 is identica" to the b"oc9 that sets u the (unction (or the (irst "ine;
e*cet this one is ca""ed #i1aginative"y$ va"ue"ine0. We shou"d ut it direct"y a(ter the b"oc9 that
sets u the (unction (or va"ue"ine.
The second b"oc9 dra.s our ne. "ineK
svg.aend#LathL$ // Add the valueline* path.
.attr#Lc"assL; L"ineL$
.attr#LdL; va"ue"ine0#data$$K
6gain; this is identica" to the b"oc9 that dra.s the (irst "ine; e*cet this one is ca""ed va"ue"ine0. We
shou"d ut it direct"y a(ter the b"oc9 that dra.s va"ue"ine.
6(ter those three s1a"" changes; chec9 out your ne. grahK
Hey8 T.o "ines8 H11.... Coth being the sa1e co"our is a bit con(using. ,ood ne.s. We can change
the co"our o( the second "ine by inserting a "ine that ad<usts it?s stro9e #co"our$ very si1"y.
So here?s .hat our ne. dra.ing b"oc9 "oo9s "i9eK
svg.aend#LathL$ // Add the valueline* path.
.attr#Lc"assL; L"ineL$
.sty"e#Lstro9eL; LredL$
.attr#LdL; va"ue"ine0#data$$K
6nd as i( by 1agic; here?s our ne. grahK
d3noob.org %5
Wo.. 5ight about no.; .e?re thin9ing ourse"ves retty c"ever. Cut there?s t.o "aces .here .e?re
not doing things right. We too9 a si1"e .ay; but .e too9 so1e short cuts that 1ight bite us in the
osterior.
The (irst 1ista9e .e 1ade .as not ensuring that our variab"e Gd.oenH is being treated as a nu1ber
or a string. We?re (ortunate in this case that it is; but this can?t a".ays be assu1ed. So; this is an easy
(i* and .e <ust need to ut the (o""o.ing #indicated "ine$ in our codeK
// Get the data
d3.tsv#Ldata4data.tsvL; function#error; data$ M
data.(or+ach#function#d$ M
d.date N arse-ate#d.date$K
d.c"ose N Od.c"oseK
d.oen N Od.oenK 44 *+++ Add this line in(
P$K
The second and otentia""y 1ore (ata" ("a. is that no.here in our code do .e 1a9e a""o.ance (or
our second set o( data #the second "ine?s va"ues$ e*ceeding our (irst "ines va"ues.
Jo. that 1ight not sound too nor1a" straight a.ay; but consider this. What i( .hen .e 1ade u
our data ear"ier; so1e o( the ne. data e*ceeded our 1a*i1u1 va"ue in our origina" data? 6s a
1eans o( de1onstration; here?s .hat haens .hen our second "ine o( data has va"ues higher than
the (irst "inesK
6hh.... We?re not too c"ever no..
d3noob.org %%
,ood ne.s though; .e can (i* it8
The rob"e1 co1es about because .hen .e set the do1ain (or the y a*is this is .hat .e ut in the
codeK
y.do1ain#U:; d3.1a*#data; function#d$ M return d.c"oseK P$V$K
So that on"y considers d.c"ose .hen estab"ishing the do1ain. With d.oen e*ceeding our do1ain; it
<ust 9ees dra.ing o(( the grah8
The good ne.s is that ?Ci""? has rovided a so"ution (or <ust this rob"e1 hereK
htt>44stac9over("o..co14Auestions410)3042)4d3@<s@dataset@array@.@1u"ti"e@y@a*is@va"ues
So a"" you need to re"ace the y.do1ain "ine .ith is thisK
y.do1ain#U:; d3.1a*#data; function#d$ M return Math.1a*#d.c"ose; d.oen$K P$V$K
It does 1uch the sa1e thing; but this ti1e it returns the 1a*i1u1 o( d.c"ose and d.oen #.hichever
is "argest$. ,ood .or9 Ci"".
I( .e ut that code into the grah .ith the higher va"ues (or our second "ine .e are no. resented
.ith thisK
6nd it doesn?t 1atter .hich o( the t.o sets o( data is "argest; the grah .i"" a".ays ad<ust >@$
Eou .i"" a"so have noticed that our y a*is has auto ad<usted again to coe. !"ever eh?
Multiple a#es f$r a graph
6"righty... Let?s i1agine that .e .ant to sho. our .onder(u" grah .ith t.o "ines on it 1uch "i9e
.e a"ready have; but that the data that the "ines is 1ade (ro1 is signi(icant"y di((erent in 1agnitude
(ro1 the origina" data #in the e*a1"e be"o.; the data (or the second "ine has been reduced by
aro*i1ate"y a (actor o( 1: (ro1 our origina" data$.
d3noob.org %)
date c"ose oen
1@May@10 52.13 3.41
3:@6r@10 53./2 4.55
0)@6r@10 %).:: %.)2
0%@6r@10 2/.): ).25
05@6r@10 //.:: 2./0
04@6r@10 13:.02 /./0
03@6r@10 1%%.): 1:.13
0:@6r@10 034./2 10.03
1/@6r@10 345.44 13.45
12@6r@10 443.34 1%.:4
1)@6r@10 543.): 12.:3
1%@6r@10 52:.13 01.:0
13@6r@10 %:5.03 00.34
10@6r@10 %00.)) 0:.15
11@6r@10 %0%.0: 01.0%
1:@6r@10 %02.44 31.:4
/@6r@10 %3%.03 35.:4
5@6r@10 %33.%2 41.:0
4@6r@10 %04.31 43.:5
3@6r@10 %0/.30 4%.:3
0@6r@10 %12.%3 51.:3
3:@Mar@10 5//.55 53.40
0/@Mar@10 %:/.2% 5).20
02@Mar@10 %1).%0 5/.:1
0)@Mar@10 %14.42 5%.:3
0%@Mar@10 %:%./2 52.:1
Jo. this isn?t a rob"e1 in itse"(. -3 .i"" sti"" 1a9e a reasonab"e grah o( the data; but because o(
the di((erence in range; the detai" o( the second "ine .i"" be "ost.
So .hat I?1 roosing is that .e have a second y a*is on the right hand side o( the grah that
re"ates to the red "ine.
The adotion I?ve done here is based on the great e*a1"es ut (or.ard by Cen !hristensen here>
htt>44ben<christensen.co140:104:54:04"ine@grahs@using@d3@<s4.
Jo.... Eou?"" .ant to concentrate a bit here since there are Auite a (e. di((erent bits to change and
adat; but don?t desair; they?re a"" Auite "ogica" and 1a9e sense.
d3noob.org %2
3irst things (irst; there .on?t be sace on the right hand side o( or grah to sho. the e*tra a*is; so
.e shou"d 1a9e our right hand 1argin a "itt"e "arger.
var 1argin N Mto> 3:; right> 4:; botto1> 3:; "e(t> 5:P;
I .ent (or 4: and it see1s to (it retty .e"".
Then #and here?s .here the 1ain oint o( di((erence (or this grah co1es in$ you .ant to a1end the
code to searate out the t.o sca"es (or the t.o "ines in the grah. This is actua""y a "ot easier than it
sounds; since it consists 1ain"y o( (inding any.here that 1entions ?y? and re"acing it .ith ?y:? and
then adding in a reciroca" iece o( code (or ?y1?.
The idea here is that .e .i"" be creating t.o re(erences (or the y a*is. &ne (or each co"u1n o( data.
Then .hen .e dra. the "ines the sca"es .i"" auto1atica""y sca"e the data correct"y #and searate"y$
to our canvas and .e .i"" dra. t.o di((erent y a*es .ith the di((erent sca"es. Ce"ieve it or not; it?s
sounds a "ot harder than it is.
Let?s get started.
3irst"y; change the variab"e dec"aration (or ?y? to ?y:? and add in ?y1?.
var * N d3.ti1e.sca"e#$.range#U:; .idthV$K
var y: N d3.sca"e."inear#$.range#Uheight; :V$K
var y1 N d3.sca"e."inear#$.range#Uheight; :V$K
Then change our y6*is dec"aration to be seci(ic (or ?y:? and seci(ica""y ?"e(t?. 6nd add in a
dec"aration (or the right hand a*isK
var y6*isLe(t N d3.svg.a*is#$.sca"e#y:$ 44 *++ Add in '2eft' and 'y"'
.orient#L"e(tL$.tic9s#5$K
var y6*is5ight N d3.svg.a*is#$.sca"e#y1$ 44 This is the ne declaration for the 'Ri.ht'3 'y4'
.orient#LrightL$.tic9s#5$K 44 and includes orientation of the a5is to the ri.ht6
Jote the orientation change (or the right hand a*is.
Jo. change our va"ue"ine dec"arations so that they re(er to the ?y:? and ?y1? sca"es.
var va"ue"ine N d3.svg."ine#$
.*#function#d$ M return *#d.date$K P$
.y#function#d$ M return y:#d.c"ose$K P$K )) *++ y"
var va"ue"ine0 N d3.svg."ine#$
.*#function#d$ M return *#d.date$K P$
.y#function#d$ M return y1#d.oen$K P$K )) *++ y4
There are a (e. di((erent .ays (or the sca"ing to .or9; but .e?"" stic9 .ith the (ancy 1a* 1ethod
.e used in the dua" "ine e*a1"e #a"though technica""y it?s not reAuired$.
y:.do1ain#U:; d3.1a*#data; function#d$ M return Math.1a*#d.c"ose$K P$V$K
y1.do1ain#U:; d3.1a*#data; function#d$ M return Math.1a*#d.oen$K P$V$K
6gain; here?s the ?y:? and ?y1? changed and added and the 1a*i1u1s (or ?d.c"ose? and ?d.oen? are
searated out$.
The (ina" iece o( the uFF"e is to dra. the ne. a*is; but .e a"so .ant to 1a9e a s"ight change to
the origina" y a*is. Since .e have t.o "ines and t.o a*es; .e need to 9no. .hich be"ongs to .hich;
so .e can co"our code the te*t in the a*es to 1atch the "inesK
d3noob.org %/
svg.aend#LgL$
.attr#Lc"assL; Ly a*isL$
.sty"e#L(i""L; Lstee"b"ueL$
.ca""#y6*isLe(t$K
svg.aend#LgL$
.attr#Lc"assL; Ly a*isL$
.attr#Ltrans(or1L; Ltrans"ate#L O .idth O L ;:$L$
.sty"e#L(i""L; LredL$
.ca""#y6*is5ight$K
In the above code you can see .here .e have added in a ?sty"e? change (or the y6*isLe(t to 1a9e it
?stee"b"ue? and a co1"e1entary change in the ne. section (or y6*is5ight to 1a9e that te*t red.
The y6*is5ight section obvious"y needs to be added in; but the on"y signi(icant di((erence is the
trans(or1 4 trans"ate attribute that 1oves the a*is to the right hand side o( the grah.
6nd a(ter a"" that; here?s the resu"t...
Jo.; "et?s not 9id ourse"ves that it?s a thing o( beauty; but .e shou"d conso"e our aesthetic concerns
.ith the .ar1 g"o. o( understanding ho. the (unction .or9s >@$.
H$% t$ r$tate the te#t labels f$r the # "#is)
The observant reader .i"" reca"" the rob"e1 .e had observed ear"ier .hen increasing the nu1ber
o( tic9s on our * a*is to 1:. The e((ect had been to roduce a "arge nu1ber o( * a*is tic9s #actua""y
1/$ but they had run together and beco1e unreadab"e.
d3noob.org ):
We ostu"ated at the ti1e that an ans.er to the rob"e1 1ight be to rotate the te*t to rovide 1ore
sace. We""; it?s about ti1e .e so"ved that rob"e1.
The ans.er I (ound 1ost usab"e .as rovided by 6aron Ward on ,oog"e ,rous
#htts>44grous.goog"e.co14(oru14Z81sg4d3@<s4!5"W:ISb&y441sgr+5uS5ysJ$
Jo.; I?"" ut a bit o( a caveat on this so"ution to the rotating a*is "abe" rob"e1. It "oo9s "i9e it?s
.or9ed .e""; but I?ve on"y carried out this investigation to the oint .here I?ve got so1ething that
"oo9s "i9e it?s a so"ution. There 1ay be better or 1ore e"egant .ays o( carrying out the sa1e tas9; so
"et ,oog"e be your (riend i( it doesn?t aear to be .or9ing out (or you.
So; starting out .ith our si1"e grah e*a1"e; .e shou"d increase the nu1ber o( tic9s on the *
a*is to 1: to get it to high"ight our rob"e1 as it aears in the revious i1age.
The (irst substantive change .ou"d be a "itt"e house9eeing. Cecause .e are going to be rotating the
te*t at the botto1 o( the grah; .e are going to need so1e e*tra sace to (it in our "abe"s. So .e
shou"d change our botto1 1argin aroriate"y.
var 1argin N Mto> 3:; right> 4:; botto1> 5:; "e(t> 5:P;
I (ound that 5: i*e"s .as su((icient.
The re1ainder o( our changes occur in the b"oc9 that dra.s the * a*is.
svg.aend#LgL$
.attr#Lc"assL; L* a*isL$
.attr#Ltrans(or1L; Ltrans"ate#:;L O height O L$L$
.ca""#*6*is$
.se"ect6""#Lte*tL$
.sty"e#Lte*t@anchorL; LendL$
.attr#Ld*L; L@.2e1L$
.attr#LdyL; L.15e1L$
.attr#Ltrans(or1L; function#d$ M
return Lrotate#@%5$L
P$K
It?s retty standard unti" the .ca""#*6*is$ ortion o( the code. Here .e re1ove the se1ico"on that
.as there so that the b"oc9 continues .ith its (unction.
Then .e se"ect a"" the te*t e"e1ents that co1rise the * avis .ith the .se"ect6""#Lte*tL$. 3ro1 this
oint .e are oerating on the te*t e"e1ents associated .ith the * a*is. So in e((ect the (o""o.ing 4
?actions? ta9en are a"ied to the te*t "abe"s.
d3noob.org )1
The .sty"e#Lte*t@anchorL; LendL$ "ine ensures that the te*t "abe" has the end o( the "abe" ?attached to
the a*is tic9. This has the e((ect o( 1a9ing sure that the te*t rotates about the end o( the date. This
1a9es sure that the te*t a"" ends u a uni(or1 distance (ro1 the a*is tic9s.
The ?d*? and ?dy? attribute "ines 1ove the end o( the te*t <ust (ar enough a.ay (ro1 the a*is tic9 so
that they don?t cro.d it and not too (ar a.ay so that it aears disassociated. This too9 a "itt"e bit o(
(idd"ing to get right and you .i"" notice that I?ve used the ?e1? units to get an ad<ust1ent i( the siFe
o( the (ont di((ers.
The (ina" action is 9ind o( the 1oney shot.
The trans(or1 attribute a"ies itse"( to each te*t "abe" and rotates each "ine by @%5 degrees. I
se"ected @%5 degrees <ust because it "oo9ed &D. There .as no deeer reason.
The end resu"t then "oo9s "i9e the (o""o.ingK
This .as a surrising"y di((icu"t rob"e1 to (ind a so"ution to that I cou"d easi"y understand #.e""
done 6aron$. So that 1a9es 1e thin9 that there are so1e (ar deeer 1ysteries to it that I don?t (u""y
areciate that cou"d tri this so"ution u. Cut in "ieu o( that; en<oy8
($r&at a date * ti&e a#is %ith specified values
&D then. We?ve been very c"ever in rotating our te*t; but you .i"" notice that -3 has used it?s o.n
good <udge1ent as to .hat (or1at the days 4 date .i"" be reresented as.
Jot that there?s anything .rong .ith it; but .hat i( .e .ant to ut a seci(ic (or1at o( date 4 ti1e
no1enc"ature as a*is "abe"s?
Jo rob"e1. -3 has your bac9.
This is actua""y a retty easy thing to do; but there are "enty o( otions (or the (or1atting; so the
on"y rea""y tric9y art is deciding .hat to ut .here.
Cut be(ore .e start doing anything .e are going to have to e*and our botto1 1argin even 1ore
than .e did .ith the rotate the a*is "abe"s (eature.
var 1argin N Mto> 3:; right> 4:; botto1> ):; "e(t> 5:P;
That shou"d see us right.
5ight; no. the si1"e art >@$. changing the (or1at o( the "abe" is as si1"e as inserting the
tic93or1at co11and into the *6*is dec"aration a "itt"e "i9e thisK
d3noob.org )0
var *6*is N d3.svg.a*is#$.sca"e#*$
.orient#Lbotto1L$.tic9s#1:$
.tic93or1at#d3.ti1e.(or1at#LTE@T1@TdL$$K 44 *++ insert the tic7Format function
So; .hat the tic93or1at is a""o.ing the setting o( (or1atting (or the tic9 "abe"s. The d3.ti1e.(or1at
ortion o( the code is seci(ying the e*act (or1at o( those tic9s. This (or1atting is described using
the sa1e argu1ents that .ere e*"ained in the section on (or1atting date ti1e va"ues starting on
age 01 #or o( course the source hereK htts>44github.co141bostoc94d34.i9i4Ti1e@3or1atting$. That
1eans that the e*a1"es .e see here #TE@T1@Td$ shou"d dis"ay the year as a (our digit nu1ber
then a hyhen then the 1onth as a t.o digit nu1ber; then another hyhen; then a t.o digit nu1ber
corresonding to the day.
Let?s ta9e a "oo9 at the resu"tK
There .e go8 Eou shou"d be ab"e to see this (i"e in the do.n"oads section on d3noob.org .ith the
genera" e*a1"es as (or1atted@date@ti1e@a*is@"abe"s.ht1".
So ho. about .e try so1ething a "itt"e out o( the ordinary #e*tre1e$?
Ho. about the (u"" .ee9day na1e #T6$; the day #Td$; the (u"" 1onth na1e #TC$ and the year
#TE$ as a (our digit nu1ber?
.tic93or1at#d3.ti1e.(or1at#LT6 Td TC TEL$$K
We .i"" a"so need so1e e*tra sace (or the botto1 1argin; so ho. about 14:?
var 1argin N Mto> 3:; right> 4:; botto1> 14:; "e(t> 5:P;
and....
d3noob.org )3
&h yeah... When a*is tic9s go bad...
Cut serious"y; that does .or9 as a retty good e*a1"e o( the ("e*ibi"ity avai"ab"e.
d3noob.org )4
Change a line chart into a scatter plot
!on(ession ti1e.
I didn?t actua""y intend to add in a section .ith a scatter "ot in it (or its o.n sa9e because I thought
it .ou"d beK
a$ tric9y
b$ not use(u"
c$ a"" o( the above
I .as .rong on a"" counts.
I did .ant to have a scatter "ot; because I .anted to dis"ay too" tis; but this is too neat to ignore.
It .as "itera""y a 5 1inute <ob; 3 1inutes o( .hich .as ta9en u by going to the d3 ga""ery on the
.i9i #htts>44github.co141bostoc94d34.i9i4,a""ery$ and og"ing at the coo" stu(( there be(ore
snaing out o( it and going to the scatter "ot e*a1"e #htt>44b".oc9s.org4322)112$.
6"" you need to so is ta9e the si1"e grah e*a1"e (i"e and s"ot the (o""o.ing b"oc9 in bet.een the
?6dd the va"ue"ine ath? and the ?add the * a*is? b"oc9s.
svg.se"ect6""#LdotL$
.data#data$
.enter#$.aend#Lcirc"eL$
.attr#LrL; 3.5$
.attr#Lc*L; function#d$ M return *#d.date$K P$
.attr#LcyL; function#d$ M return y#d.c"ose$K P$K
6nd you .i"" get...
Jo. I de"iberate"y ut the dots a(ter the "ine in the dra.ing section; because I thought they .ou"d
"oo9 better; but you cou"d ut the b"oc9 o( code be(ore the "ine dra.ing b"oc9 to get the (o""o.ing
e((ectK
d3noob.org )5
#<ust trying to rein(orce the concet that ?order? 1atters .hen dra.ing ob<ects >@$$.
Eou cou"d o( course <ust re1ove the "ine b"oc9 a"" together...
Cut in 1y hu1b"e oinion it "ooses so1ething.
So .hat do the individua" "ines in the scatter "ot b"oc9 o( JavaScrit do?
The (irst "ine #svg.se"ect6""#LdotL$$ essentia""y rovides a suitab"e grouing "abe" (or the svg circ"e
e"e1ents that .i"" be added. The ne*t "ine associates the range o( data that .e have to the grou o(
e"e1ents .e are about to add in.
Then .e add a circ"e (or each data oint #.enter#$.aend#Lcirc"eL$$ .ith a radius o( 3.5 i*e"s
#.attr#LrL; 3.5$$ and aroriate * #.attr#Lc*L; function#d$ M return *#d.date$K P$$ and y #.attr#LcyL;
function#d$ M return y#d.c"ose$K P$K$ coordinates.
There is "ots 1ore that .e cou"d be doing .ith this iece o( code #chec9 out the scatter "ot e*a1"e
#htt>44b".oc9s.org4322)112$$ inc"uding varying the co"our or siFe or oacity o( the circ"es deending
on the data and a"" sorts o( rea""y neat things; but (or the 1ean ti1e; there .e go. scatter "ot8
I?ve "aced a coy o( the (i"e (or dra.ing the scatter "ot into the do.n"oads section on d3noob.org
.ith the genera" e*a1"es as si1"e@scatter"ot.ht1".
d3noob.org )%
&dding tooltips"
Too"tis have a 1arve""ous dua"ity. They are on one hand a retty darned use(u" thing that aids in
giving conte*t and in(or1ation .here reAuired and on the other hand; i( done .ith a bit o( care; they
can "oo9 very sty"ish >@$.
Technica""y; they reresent a s"ight 1ove (ro1 .hat .e have been "aying .ith so (ar into a 1i"d"y
1ore co1"e* arena o( ?transitions? and ?events?. Eou can ta9e this one o( t.o .ays. +ither accet
that it <ust .or9s and i1"e1ent it as sho.n; or you .i"" 9no. .hat s going on and (ee" (ree to
deride 1y e((orts as those o( a ran9 a1ateur >@$.
The source (or the i1"e1entation .as ta9en (ro1 Mi9e Costoc9?s e*a1"e hereK
htt>44b".oc9s.org41:2)::1. This .as co1bined .ith a (e. other bit?s and ieces #the tric9iest being
.or9ing out ho. to (or1at the dis"ayed date correct"y and inserting a "ine brea9 in the too"ti
#.hich I (ound hereK htts>44grous.goog"e.co14(oru14?(ro1grousNZ8toic4d3@<s4,g3T(04"t<c
#.e"" done to a"" those articiating in that discussion$$. I 1a9e the assu1tion that any or a"" errors
that occur in the i1"e1entation .i"" be 1ine; .hereas; any successes .i"" be do.n to the origina"
contributors.
So; <ust in case there is so1e degree o( con(usion; a too"ti #one .ord or t.o?$ is a discrete iece o(
in(or1ation that .i"" o into vie. .hen the 1ouse is hovered over so1e.here seci(ic. Most o( us
have seen and used the1; but I suose .e a"" tend to ca"" the1 di((erent things such as ?in(oti?;
?hint? or ?hover bo*? I don?t 9no. i( there?s a right na1e (or the1; but here?s an e*a1"e o( .hat
.e?re trying to achieveK
Eou can see the 1ouse has hovered over one o( the scatter "ot circ"es and a ti has aeared that
rovides the user .ith the e*act date and va"ue (or that oint.
Jo.; you 1ay a"so notice that there?s a certain degree o( ?(ancy? here as the in(or1ation is bound by
a rectangu"ar shae .hit rounded corners and a s"ight oacity. The other iece o( ?(ancy? .hich you
don?t see in a d( is that .hen these too" tis aear and disaear; they do so in an e"egant (ade@in;
(ade@out .ay. =urty.
Jo.; be(ore .e get started describing ho. the code goes together; "et?s ta9e a Auic9 "oo9 at the t.o
techniAue seci(ics that I 1entioned ear"ier; ?transitions? and ?events?.
d3noob.org ))
Transiti$ns
3ro1 the 1ain d3.<s .eb age #d3<s.org$ transitions are described as gradua""y intero"ating sty"es
and attributes over ti1e. So .hat I ta9e that to 1ean is that i( you .ant to change an ob<ect; you can
do so be si1"y seci(ying the attribute 4 sty"e end oint that you .ant it to end u .ith and the ti1e
you .ant it to ta9e and go8
&( course; it?s not Auite that si1"e; but "uc9i"y; s1arter eo"e than I have done so1e (antastic
.or9 describing di((erent asects o( transitions so "ease see the (o""o.ing (or a 1ore co1"ete
descrition o( the toicK
Mi9e Costoc9?s Car chart tutoria" #htt>441bostoc9.github.co14d34tutoria"4bar@0.ht1"$
!hristohe 7iau?s ?Try -3 Jo.8? tutoria" #htt>44christoheviau.co14d3Ytutoria"4$
Hoe(u""y observing the 1ouseover and 1ouseout transitions in the too"tis e*a1"e .i"" .het your
aetite (or 1ore8
+vents
The other techniAue is re"ated to 1ouse ?events?. This describes the bro.ser .atching (or .hen
?so1ething? haens .ith the 1ouse on the screen and .hen it does; it ta9es a seci(ied action. 6
#robab"y non@co1rehensive$ "ist o( the tyes o( events are the (o""o.ingK
1ousedo.n> Triggered by an e"e1ent .hen a 1ouse button is ressed do.n over it
1ouseu> Triggered by an e"e1ent .hen a 1ouse button is re"eased over it
1ouseover> Triggered by an e"e1ent .hen the 1ouse co1es over it
1ouseout> Triggered by an e"e1ent .hen the 1ouse goes out o( it
1ouse1ove> Triggered by an e"e1ent on every 1ouse 1ove over it.
c"ic9> Triggered by a 1ouse c"ic9> 1ousedo.n and then 1ouseu over an e"e1ent
conte*t1enu> Triggered by a right@button 1ouse c"ic9 over an e"e1ent.
db"c"ic9> Triggered by t.o c"ic9s .ithin a short ti1e over an e"e1ent
Ho. 1any o( these are va"id to use .ithin d3 I?1 not sure; but I?1 .i""ing to bet that there are
robab"y 1ore than those here as .e"". ="ease go to htt>44<avascrit.in(o4tutoria"41ouse@events (or a
(ar better descrition o( the toic i( reAuired.
,et tipping
So; bo"stered .ith a cou"e o( ne. concets to consider; "et?s see ho. they are enacted in ractice.
I( .e start .ith our si1"e@scatter "ot grah there are 4 areas in it that .e .i"" .ant to 1odi(y #it
1ay be easier to chec9 the too"tis.ht1" (i"e in the e*a1"e (i"es in the do.n"oads section on
d3noob.org$.
The (irst area is the !SS. The (o""o.ing code shou"d be added <ust be(ore the R4sty"eS tagK
d3noob.org )2
div.too"ti M
position> abso"uteK
te5t8ali.n> centerK
idth> %:*K
hei.ht> 02*K
paddin.> 0*K
font> 10* sans@seri(K
bac7.round> "ightstee"b"ueK
border> :*K
border8radius1 2*K
pointer8events1 noneK
P
These sty"es are de(ining ho. our too"ti .i"" aear . Most o( the1 are (air"y straight (or.ard. The
osition o( the too"ti is done in abso"ute 1easure1ents; not re"ative. The te*t is centre a"igned; the
height; .idth and co"our o( the rectang"e is 02*; %:* and "ightstee"b"ue resective"y. The ?adding?
is an interesting (eature that rovides a neat .ay to gro. a shae by a (i*ed a1ount (ro1 a seci(ied
siFe.
We set the boarder to :* so that it doesn?t sho. u and a neat sty"e #attribute?$ ca""ed border@radius
rovides the nice rounded corners on the rectang"e.
Last"y; but by no 1eans "east; the ?ointer@events> none? "ine is in "ace to instruct the 1ouse event
to go LthroughL the e"e1ent and target .hatever is LunderneathL that e"e1ent instead #5ead 1ore
hereK htts>44deve"oer.1oFi""a.org4en@'S4docs4!SS4ointer@events$. That 1eans that even i( the
too"ti art"y obscures the circ"e; the code .i"" st"" act as i( the 1ouse is over on"y the circ"e.
The second addition is a si1"e one@"iner that shou"d #(or (or1s sa9e$ be "aced under the
?arse-ata? variab"e dec"arationK
var (or1atTi1e N d3.ti1e.(or1at#LTe TCL$K
This "ine (or1ats the date .hen it aears in our too"ti. Without it; the ti1e .ou"d de(au"t to a
disturbing"y "ong co1bination o( te1ora" detai"s. In the case here .e have dec"ared that .e .ant
to see the day o( the 1onth #Te$ and the (u"" 1onth na1e#TC$.
The third b"oc9 o( code is the (unction dec"aration (or ?div?.
var div N d3.se"ect#LbodyL$.aend#LdivL$
.attr#Lc"assL; Ltoo"tiL$
.sty"e#LoacityL; :$K
We can "ace that <ust a(ter the ?va"ue"ine? de(inition in the JavaScrit. 6gain there?s not too 1uch
here that?s surrising. We te"" it to attach ?div? to the body e"e1ent; .e set the c"ass to the too"ti
c"ass #(ro1 the !SS$ and .e set the oacity to Fero. It 1ight sound strange to have the oacity set to
Fero; but re1e1ber; that?s the natura" state o( a too"ti. It .i"" "ive unseen unti" it?s 1o1ent o(
reve"ation arrives and it os u8
The (ina" b"oc9 o( code is s"ight"y 1ore co1"e* and cou"d be described as a 1utant version o( the
neat "itt"e bit o( code that .e used to do the dra.ing o( the dots (or the scatter "ot. That?s because
the too"tis are a"" about the scatter "ot circ"es. Without a circ"e to ?1ouseover?; the too"ti never
aears >@$.
So here?s the code that inc"udes the scatter "ot dra.ing #it?s inc"uded since it?s retty 1uch
integra"$K
d3noob.org )/
svg.se"ect6""#LdotL$
.data#data$
.enter#$.aend#Lcirc"eL$
.attr#LrL; 5$
.attr#Lc*L; function#d$ M return *#d.date$K P$
.attr#LcyL; function#d$ M return y#d.c"ose$K P$
.on#L1ouseoverL; function#d$ M
div.transition#$
.duration#0::$
.sty"e#LoacityL; ./$K
div .ht1"#(or1atTi1e#d.date$ O LRbr4SL O d.c"ose$
.sty"e#L"e(tL; #d3.event.ageW$ O L*L$
.sty"e#LtoL; #d3.event.ageE @ 02$ O L*L$K
P$
.on#L1ouseoutL; function#d$ M
div.transition#$
.duration#5::$
.sty"e#LoacityL; :$K
P$K
Ce(ore .e start going through the code; the e*a1"e (i"e (or too"tis that is on d3noob.org inc"udes
a brie( series o( co11ents (or the "ines that are added or changed (ro1 the scatter "ot; so i( you
.ant to co1are .hat is going on in conte*t; that is an otion.
The (irst si* "ines o( the code are a reeat o( the scatter "ot dra.ing scrit. The on"y changes are
that .e?ve increased the radius o( the circ"e (ro1 3.5 to 5 #<ust to 1a9e it easier to 1ouse over the
ob<ect$ and .e?ve re1oved the se1ico"on (ro1 the ?cy? attribute "ine since the code no. has to carry
on.
So the additions are bro9en into to areas that corresond to the t.o events. ?1ouseover? and
?1ouseout?. When the 1ouse 1oves over any o( the circ"es in the scatter "ot; the 1ouseover code is
e*ecuted on the ?div? e"e1ent. When the 1ouse is 1oved o(( the circ"e a di((erent set o( instructions
are e*ecuted.
It .ou"d be a 1ista9e to thin9 o( too"tis in the "ura" because there aren?t a .ho"e series o(
individua" too"tis <ust .aiting to aear (or their seci(ic circ"e. There is on"y one too"ti that .i""
aear .hen the 1ouse 1oves over a circ"e. 6nd deending on .hat circ"e it?s over; the roerties
o( the too"ti .i"" a"ter s"ight"y #in ter1s o( its osition and contents$.
on"!ouseo(er
The .on#L1ouseoverL "ine initiates the introduction o( the too"ti. Then .e dec"are the e"e1ent .e
.i"" be introducing #?div?$ and that .e .i"" be a"ying a transition to it?s introduction #.transition#$$.
The ne*t t.o "ines describe the transition. It .i"" ta9e 0:: 1i""iseconds #.duration#0::$$ and .i""
resu"t in changing the e"e1ents oacity to ./ #.sty"e#LoacityL; ./$K$. ,iven that the natura" state o(
our too"ti is an oacity o( :; this 1a9e sense (or so1ething aearing; but it doesn?t go a"" the .ay
to a so"id ob<ect and it retains a s"ight transarency <ust to 1a9e it "oo9 "ess er1anent.
d3noob.org 2:
The (o""o.ing three "ines (or1at our too"ti. The (irst one adds an ht1" e"e1ent that contains our *
and y in(or1ation #the date and the d.c"ose va"ue$. Jo. this is done in a s"ight"y strange .ay. &ther
too"tis that I have seen have used a ?.te*t? e"e1ent instead o( a ?.ht1"? one; but I have used ?.ht1"? in
this case because I .anted to inc"ude the "ine brea9 tag GRbr4SH to searate the date and va"ue. I?1
sure there are other .ays to do it; but this .or9ed (or 1e. The other interesting art o( this "ine is
that this is .here .e ca"" our ti1e (or1atting (unction that .e described ear"ier. The ne*t t.o "ines
osition the too"ti on the screen and to do this they grab the * and y coordinates o( the 1ouse .hen
the event ta9es "ace #.ith the d3.event.ageW and d3.event.ageE sniets$ and a"y a correction
in the case o( the y coordinate to raise the too"ti u by the sa1e a1ount as its height #02 i*e"s$.
on"!ouseout
The .on#L1ouseoutL section is s"ight"y si1"er in that it doesn?t have to do any (ancy te*t 4 ht1" 4
coordinate stu((. 6"" it has to do is to (ade out the ?div? e"e1ent. 6nd that is done by si1"y reversing
the oacity bac9 to : and setting the duration (or the transition to 5:: 1i""iseconds #being s"ight"y
"onger than the (ade@in 1a9es it "oo9 s"ight"y coo"er IMH&$.
5ight; there you go. 6s a descrition it?s ended u being a bit o( a .a"" o( te*t I?1 a(raid. Cut
hoe(u""y bet.een the e*"anation and the e*a1"e code you .i"" get the idea. ="ease ta9e the ti1e
to (idd"e .ith the settings described here to (ind the ones that .or9 (or you and in the rocess you
.i"" rein(orce so1e o( the rinci"es that he" -3 do it?s thing.
I?ve "aced a coy o( the (i"e (or dra.ing the too"tis into the do.n"oads section on d3noob.org .ith
the genera" e*a1"es as too"tis.ht1".
What are the predefined+ na!ed colours?
Throughout this docu1ent I have been using co"ours de(ined by na1e. This is 1ain"y because I can
and not (or any other reason. In (act there severa" di((erent .ays to de(ine co"ours used in -3 4
JavaScrit 4 !SS and HTML. I have no idea .hat the "i1itations (or use are and 4 or ho. their use
in di((erent bro.sers i1acts on correct reresentation. Cut I do 9no. that they?re used .ide"y.
Cut; I .as rea""y interested in .hat the na1es .ere (or the co"ours. 6(ter a cursory search I .as ab"e
to (ind the (o""o.ing "ist on about.co1
#htt>44.ebdesign.about.co14od4co"orcharts4"4b"Yna1edco"ors.ht1$.
The overriding oint o( a"" this is that there?s 1ore than one .ay to de(ine co"ours in your grahs.
It 1eans that
.sty"e#L(i""L; Lstee"b"ueL$
and...
.sty"e#L(i""L; LZ4%20b4L$
and...
.sty"e#L(i""L; Lrgb#):;13:;12:$L$
6"" resu"t in the sa1e co"our being a"ied.
Jo.; so1e 1ay #<usti(iab"y$ Auestion the .isdo1 o( utting <ust over 5 ages o( co"ours into a
docu1ent. I rea""y "i9e the1 and I "i9e to be ab"e to re(er to the1 easi"y. This .or9s (or 1e. I?1 sure
it .or9s (or so1e others as .e"" >@$.
d3noob.org 21
'olour 'olour Name %e5adecimal R9:
a"iceb"ue Z(:(2(( 04:;042;055
antiAue.hite Z(aebd) 05:;035;015
aAua Z::(((( :;055;055
aAua1arine Z)(((d4 10);055;010
aFure Z(:(((( 04:;055;055
beige Z(5(5dc 045;045;00:
bisAue Z((e4c4 055;002;1/%
b"ac9 Z:::::: :;:;:
b"ancheda"1ond Z((ebcd 055;035;0:5
b"ue Z::::(( :;:;055
b"uevio"et Z2a0be0 132;43;00%
bro.n Za50a0a 1%5;40;40
bur"y.ood Zdeb22) 000;124;135
cadetb"ue Z5(/ea: /5;152;1%:
chartreuse Z)(((:: 10);055;:
choco"ate Zd0%/1e 01:;1:5;3:
cora" Z(()(5: 055;10);2:
corn("o.erb"ue Z%4/5ed 1::;14/;03)
cornsi"9 Z(((2dc 055;042;00:
cri1son Zdc143c 00:;0:;%:
cyan Z::(((( :;055;055
dar9b"ue Z::::2b :;:;13/
dar9cyan Z::2b2b :;13/;13/
dar9go"denrod Zb22%:b 124;134;11
dar9gray Za/a/a/ 1%/;1%/;1%/
dar9green Z::%4:: :;1::;:
dar9grey Za/a/a/ 1%/;1%/;1%/
dar99ha9i Zbdb)%b 12/;123;1:)
dar91agenta Z2b::2b 13/;:;13/
dar9o"ivegreen Z55%b0( 25;1:);4)
dar9orange Z((2c:: 055;14:;:
d3noob.org 20
'olour 'olour Name %e5adecimal R9:
dar9orchid Z//30cc 153;5:;0:4
dar9red Z2b:::: 13/;:;:
dar9sa"1on Ze//%)a 033;15:;100
dar9seagreen Z2(bc2( 143;122;143
dar9s"ateb"ue Z423d2b )0;%1;13/
dar9s"ategray Z0(4(4( 4);)/;)/
dar9s"ategrey Z0(4(4( 4);)/;)/
dar9turAuoise Z::ced1 :;0:%;0:/
dar9vio"et Z/4::d3 142;:;011
deein9 Z((14/3 055;0:;14)
dees9yb"ue Z::b((( :;1/1;055
di1gray Z%/%/%/ 1:5;1:5;1:5
di1grey Z%/%/%/ 1:5;1:5;1:5
dodgerb"ue Z1e/:(( 3:;144;055
(irebric9 Zb00000 1)2;34;34
("ora".hite Z(((a(: 055;05:;04:
(orestgreen Z002b00 34;13/;34
(uchsia Z((::(( 055;:;055
gainsboro Zdcdcdc 00:;00:;00:
ghost.hite Z(2(2(( 042;042;055
go"d Z((d):: 055;015;:
go"denrod Zdaa50: 012;1%5;30
gray Z2:2:2: 102;102;102
green Z::2::: :;102;:
greenye""o. Zad((0( 1)3;055;4)
grey Z2:2:2: 102;102;102
honeyde. Z(:(((: 04:;055;04:
hotin9 Z((%/b4 055;1:5;12:
indianred Zcd5c5c 0:5;/0;/0
indigo Z4b::20 )5;:;13:
ivory Z(((((: 055;055;04:
d3noob.org 23
'olour 'olour Name %e5adecimal R9:
9ha9i Z(:e%2c 04:;03:;14:
"avender Ze%e%(a 03:;03:;05:
"avenderb"ush Z(((:(5 055;04:;045
"a.ngreen Z)c(c:: 104;050;:
"e1onchi((on Z(((acd 055;05:;0:5
"ightb"ue Zadd2e% 1)3;01%;03:
"ightcora" Z(:2:2: 04:;102;102
"ightcyan Ze:(((( 004;055;055
"ightgo"denrodye""o. Z(a(ad0 05:;05:;01:
"ightgray Zd3d3d3 011;011;011
"ightgreen Z/:ee/: 144;032;144
"ightgrey Zd3d3d3 011;011;011
"ightin9 Z((b%c1 055;120;1/3
"ightsa"1on Z((a:)a 055;1%:;100
"ightseagreen Z0:b0aa 30;1)2;1):
"ights9yb"ue Z2)ce(a 135;0:%;05:
"ights"ategray Z))22// 11/;13%;153
"ights"ategrey Z))22// 11/;13%;153
"ightstee"b"ue Zb:c4de 1)%;1/%;000
"ightye""o. Z((((e: 055;055;004
"i1e Z::((:: :;055;:
"i1egreen Z30cd30 5:;0:5;5:
"inen Z(a(:e% 05:;04:;03:
1agenta Z((::(( 055;:;055
1aroon Z2::::: 102;:;:
1ediu1aAua1arine Z%%cdaa 1:0;0:5;1):
1ediu1b"ue Z::::cd :;:;0:5
1ediu1orchid Zba55d3 12%;25;011
1ediu1ur"e Z/3):db 14);110;01/
1ediu1seagreen Z3cb3)1 %:;1)/;113
1ediu1s"ateb"ue Z)b%2ee 103;1:4;032
d3noob.org 24
'olour 'olour Name %e5adecimal R9:
1ediu1sringgreen Z::(a/a :;05:;154
1ediu1turAuoise Z42d1cc )0;0:/;0:4
1ediu1vio"etred Zc)1525 1//;01;133
1idnightb"ue Z1/1/): 05;05;110
1intcrea1 Z(5(((a 045;055;05:
1istyrose Z((e4e1 055;002;005
1occasin Z((e4b5 055;002;121
nava<o.hite Z((dead 055;000;1)3
navy Z::::2: :;:;102
o"d"ace Z(d(5e% 053;045;03:
o"ive Z2:2::: 102;102;:
o"ivedrab Z%b2e03 1:);140;35
orange Z((a5:: 055;1%5;:
orangered Z((45:: 055;%/;:
orchid Zda):d% 012;110;014
a"ego"denrod Zeee2aa 032;030;1):
a"egreen Z/2(b/2 150;051;150
a"eturAuoise Za(eeee 1)5;032;032
a"evio"etred Zdb):/3 01/;110;14)
aaya.hi Z((e(d5 055;03/;013
eachu(( Z((dab/ 055;012;125
eru Zcd253( 0:5;133;%3
in9 Z((c:cb 055;1/0;0:3
"u1 Zdda:dd 001;1%:;001
o.derb"ue Zb:e:e% 1)%;004;03:
ur"e Z2:::2: 102;:;102
red Z((:::: 055;:;:
rosybro.n Zbc2(2( 122;143;143
roya"b"ue Z41%/e1 %5;1:5;005
sadd"ebro.n Z2b4513 13/;%/;1/
sa"1on Z(a2:)0 05:;102;114
d3noob.org 25
'olour 'olour Name %e5adecimal R9:
sandybro.n Z(4a4%: 044;1%4;/%
seagreen Z0e2b5) 4%;13/;2)
seashe"" Z(((5ee 055;045;032
sienna Za:500d 1%:;20;45
si"ver Zc:c:c: 1/0;1/0;1/0
s9yb"ue Z2)ceeb 135;0:%;035
s"ateb"ue Z%a5acd 1:%;/:;0:5
s"ategray Z):2:/: 110;102;144
s"ategrey Z):2:/: 110;102;144
sno. Z(((a(a 055;05:;05:
sringgreen Z::(()( :;055;10)
stee"b"ue Z4%20b4 ):;13:;12:
tan Zd0b42c 01:;12:;14:
tea" Z::2:2: :;102;102
thist"e Zd2b(d2 01%;1/1;01%
to1ato Z((%34) 055;//;)1
turAuoise Z4:e:d: %4;004;0:2
vio"et Zee20ee 032;13:;032
.heat Z(5deb3 045;000;1)/
.hite Z(((((( 055;055;055
.hites1o9e Z(5(5(5 045;045;045
ye""o. Z((((:: 055;055;:
ye""o.green Z/acd30 154;0:5;5:
Selecting $ filtering a subset of ob,ects
&D; I1agine a scenario .here you .ant to se"ect #or shou"d .e say (i"ter$ a articu"ar range o(
ob<ects (ro1 a "arger set (or dis"ay in so1e .ay.
3or e*a1"e; .hat i( .e .anted to use our scatter "ot e*a1"e to sho. the "ine as nor1a"; but .e
are articu"ar"y interested in the oints .here the va"ues o( the oints (a"" be"o. 4::. 6nd .hen it
does .e .ant the1 high"ighted .ith a circ"e as .e have done .ith a"" the oint revious"y.
So that .e end u .ith so1ething that "oo9s a "itt"e "i9e this...
d3noob.org 2%
+rr... Ees; (or those a1ong you .ho are o( the observant ersuasion; I have de"iberate"y co"oured
the1 red as .e"" #red (or -6J,+58$.
This is a (air"y si1"e e*a1"e; but serves to i""ustrate the rinci"e adeAuate"y.
3ro1 our si1"e scatter "ot e*a1"e .e on"y need to add in t.o "ines to the b"oc9 o( code that
dra.s the circ"es as (o""o.sK
svg.se"ect6""#LdotL$
.data#data$
.enter#$.aend#Lcirc"eL$
.(i"ter#function#d$ M return d.c"ose R 4:: P$ 44 *++ This line
.sty"e#L(i""L; LredL$ 44 *++ and this one
.attr#LrL; 3.5$
.attr#Lc*L; function#d$ M return *#d.date$K P$
.attr#LcyL; function#d$ M return y#d.c"ose$K P$K
The (irst added "ine uses the ?.(i"ter? (unction to act on the data oints and according to the
argu1ents assed to it in this case; on"y return those .here the va"ue o( d.c"ose is "ess than 4::
#return d.c"ose R 4::$.
The second added "ine is our "ine that si1"y co"ours the circ"es red #.sty"e#L(i""L; LredL$$.
That?s a"" there is to it. =retty si1"e; but the (i"ter (unction can be very o.er(u" .hen used .ise"y.
I?ve "aced a coy o( the (i"e (or se"ecting 4 (i"tering into the do.n"oads section on d3noob.org .ith
the genera" e*a1"es as (i"ter@se"ection.ht1".
Select ite!s ith an I# state!ent"
The (i"tering X se"ection section above is a good .ay to adat .hat you see on a grah; but so is a
1ore (a1i"iar (riend the ?i(? state1ent.
6n i( state1ent .i"" act to carry out a tas9 in a articu"ar .ay deendant on a condition that you
seci(y.
Here?s an e*a1"e; .hat i( .e .anted to sho. our scatter "ot as nor1a"; but a"" those .ith a ?c"ose?
va"ue "ess than 4:: shou"d be co"oured red. Sound (a1i"iar? Ees; I 9no. it?s si1i"ar to the e*a1"e
above; .ith the subt"e di((erence that it is "eaving the circ"es above 4:: in "ace #1ore on that to
(o""o.$.
d3noob.org 2)
So; starting .ith the si1"e scatter "ot e*a1"e a"" .e have to do is inc"ude the i( state1ent in the
b"oc9 o( code that dra.s the circ"es. Here?s the entire b"oc9 .ith the additions high"ightedK
svg.se"ect6""#LdotL$
.data#data$
.enter#$.aend#Lcirc"eL$
.attr#LrL; 3.5$
.sty"e#L(i""L; function#d$ M 44 *++ Add these
if #d.c"ose RN 4::$ Mreturn LredLP 44 *++ Add these
else M return Lb"ac9L P 44 *++ Add these
KP$ 44 *++ Add these
.attr#Lc*L; function#d$ M return *#d.date$K P$
.attr#LcyL; function#d$ M return y#d.c"ose$K P$K
&ur (irst added "ine introduces the sty"e 1odi(ier and the rest o( the code acts to rovide a return (or
the ?(i""? attribute.
The second "ine introduces our i( state1ent. They?re a"" retty easy to (o""o. bet.een "anguages.
Just "oo9 out (or 1aintaining the correct synta* and you shou"d be (ine. In this case .e?re as9ing i(
the va"ue o( d.c"ose is "ess than or eAua" to 4:: and i( it is it .i"" return the GredH state1ent (or our
(i"".
The third "ine covers our rear and 1a9e sure that i( the co"our isn?t going to be red; it?s going to be
b"ac9. The "ast "ine <ust c"oses the sty"e and (unction state1ents.
The resu"t?
6....... nice.
I?ve "aced a coy o( the (i"e that uses the i( state1ent into the do.n"oads section on d3noob.org
.ith the genera" e*a1"es as i(@state1ent.ht1".
!ou"d it be any coo"er? I?1 g"ad you as9ed.
What i( .e .anted to have a"" the oints .here c"ose .as "ess than 4:: red and a"" those .here
c"ose .as greater than %0: green? &h yeah8 Jo. .e?re ta"9ing.
So .ith one s1a"" change to the i( state1entK
d3noob.org 22
.sty"e#L(i""L; function#d$ M
if #d.c"ose RN 4::$ Mreturn LredLP
else if #d.c"ose SN %0:$ Mreturn L"a.ngreenLP )) *++ Ri.ht here
else M return Lb"ac9L P
KP$
!hec9 it out...
Jice.
&pplying a colour gradient to a line based on (alue"
I <ust 9no. that you .ere i1ressed .ith the changing dots in a scatter "ot based on the va"ue. Cut
cou"d .e cou"d one better?
Ho. about .e try to reroduce the sa1e e((ect but by varying the co"our o( the "otted "ine.
This is a neat (eature and a use(u" e*a1"e o( the ("e*ibi"ity o( d3.<s and svg in genera".
I used the aroriate bits o( code (ro1 Mi9e Costoc9?s Thresho"d +ncoding e*a1"e here
htt>44b".oc9s.org43/):223. 6nd I shou"d ta9e the oortunity to hearti"y reco11end bro.sing
through his co""ection o( e*a1"es on b".oc9s.org #htt>44b".oc9s.org41bostoc9$.
Here then is a "otted "ine that is red be"o. 4::; green above %0: and b"ac9 in bet.een.
Ho. coo" is that?
+nough beating around the bush; ho. is the 1agic "ine roduced?
d3noob.org 2/
We"" starting .ith our si1"e "ine grah there are on"y t.o b"oc9s o( code to go in. &ne is !SS in
the Rsty"eS area and the second is a tric9y "itt"e iece o( code that dea"s .ith gradients.
So; (irst the !SS.
."ine M
(i""> noneK
stro9e> ur"#Z"ine@gradient$K
stro9e@idth> 0*K
P
This b"oc9 can go in the Rsty"eS area to.ards the end.
There?s the (air"y standard (i"" o( none and a stro9e .idth o( 0 i*e"s; but the stro9e> ur"#Z"ine@
gradient$K is so1ething di((erent.
In this case the stro9e #.hich .e re1e1ber is the co"our o( the "ine$ us being set at a "in9 .ithin the
age .hich is set by the anchor Z"ine@gradient. 6s .e .i"" see short"y this is in our second b"oc9 o(
code; so the co"our is being de(ined in a searate ortion o( the scrit.
6nd no. the JavaScrit ,radient codeK
svg.aend#L"inear,radientL$
.attr#LidL; L"ine@gradientL$
.attr#Lgradient'nitsL; LuserSace&n'seL$
.attr#L*1L; :$.attr#Ly1L; y#:$$
.attr#L*0L; :$.attr#Ly0L; y#1:::$$
.se"ect6""#LstoL$
.data#U
Mo((set> L:TL; co"or> LredLP;
Mo((set> L4:TL; co"or> LredLP;
Mo((set> L4:TL; co"or> Lb"ac9LP;
Mo((set> L%0TL; co"or> Lb"ac9LP;
Mo((set> L%0TL; co"or> L"a.ngreenLP;
Mo((set> L1::TL; co"or> L"a.ngreenLP
V$
.enter#$.aend#LstoL$
.attr#Lo((setL; function#d$ M return d.o((setK P$
.attr#Lsto@co"orL; function#d$ M return d.co"orK P$K
There?s our anchor on the second "ine8
Cut "et?s not get ahead o( ourse"ves. This b"oc9 shou"d be "aced a(ter the * and y do1ains are set;
but be(ore the "ine is dra.n.
See1s a bit strange doesn?t it? This b"oc9 is a"" about de(ining the actions o( an e"e1ent; but the
e"e1ent in this case is a gradient and the gradient acts on the "ine.
So; our (irst "ine adds our "inear gradient. ,radients consist o( continuous"y s1ooth co"our
transitions a"ong a vector (ro1 one co"our to another We can have a "inear one or a radia" one and
deending on .hich you se"ect; there are a (e. otions to de(ine. There is so1e great in(or1ation
on gradients here htt>44.....3.org4T54S7,4servers.ht1" #1ore than I ever thought e*isted$.
The second "ine #.attr#LidL; L"ine@gradientL$$ sets our anchor (or the !SS that .e sa. ear"ier.
d3noob.org /:
The third (ourth and (i(th "ines de(ine the bounds o( the area over .hich the gradient .i"" act. Since
the coordinates *1; y1; *0; y0 .i"" describe an area. The va"ues (or y1 #:$ and y0 #1:::$ are used
1ore (ore convenience to a"ign .ith our data #.hich has a 1a*i1u1 va"ue around %3: or so. 3or
1ore in(or1ation on the gradient'nits attribute I (ound this age use(u"
htts>44deve"oer.1oFi""a.org4en@'S4docs4S7,46ttribute4gradient'nits. We?"" co1e bac9 to the
coordinates in a 1o1ent.
The ne*t b"oc9 se"ects a"" the ?sto? e"e1ents (or the gradients. These sto e"e1ents de(ine .here on
the range covered by our coordinates the co"ours start and sto. These have to be de(ined as either
ercentages or nu1bers #.here the nu1bers are rea""y <ust ercentages in disguise #i.e. 45T
N:.43$$.
The best .ay to consider the sto e"e1ents is in con<unction .ith the gradient'nits. The i1age
(o""o.ing 1ay he".
In this case our coordinated describe a vertica" "ine (ro1 : to 1:::. &ur co"ours transition (ro1 red
#:$ to red #4::$ at .hich oint they change to b"ac9 #4::$ and this .i"" continue unti" it gets to b"ac9
#%0:$. Then this changes to green #%0:$ and (ro1 there; any va"ue above that .i"" be green.
Jo.; it 1ight see1 a "itt"e convo"uted to be doub"ing u on the co"ours and va"ues; but the reason is
that the gradient (unctions are have a "ot 1ore to the1 than .e?re using and .e?"" have a "oo9 at the
ossibi"ities once the e*"anation o( the code is done.
So a(ter de(ining the sto e"e1ents; .e enter and aend the e"e1ents to the gradient
#.enter#$.aend#LstoL$$
.ith attributes (or o((set and co"or that .e de(ined in the sto e"e1ents area.
Jo.; the "S coo"; but by no.; I hoe that you have ic9ed that a gradient (unction rea""y does 1ean
a gradient; and not <ust a straight change (ro1 one co"our to another.
So; "et?s try changing the sto e"e1ent o((sets to the (o""o.ing #and 1a9ing the stro9e@.idth s"ight"y
"arger to see 1ore c"ear"y .hat?s going on$K
d3noob.org /1
.data#U
Mo((set> L:TL; co"or> LredLP;
Mo((set> L3:TL; co"or> LredLP;
Mo((set> L45TL; co"or> Lb"ac9LP;
Mo((set> L55TL; co"or> Lb"ac9LP;
Mo((set> L%:TL; co"or> L"a.ngreenLP;
Mo((set> L1::TL; co"or> L"a.ngreenLP
V$
6nd here .e go...
6hh... 6 rea" gradient.
I have tended to (ind that I need to have a good thin9 about ho. I set the o((sets and bounds .hen
doing this sort o( thing since it can get Auite co1"icated Auite Auic9"y >@$
&pplying a colour gradient to an area fill"
The revious e*a1"e o( a varying gradient on a "ine is neat; but hoe(u""y you?re a"ready thin9ing
GHang on; can?t that sa1e thing be a"ied to an area (i""?H.
-a1n8 Eou?re catching on.
To do this there?s on"y a (e. things .e need to changeK
3irst o( a"" the !SS (or the "ine needs to be a1ended to re(er to the area. So this...
."ine M
(i""> noneK
stro9e> ur"#Z"ine@gradient$K
stro9e@idth> 0*K
P
[gets changed to this...
.area M
(i""> ur"#Zarea@gradient$K
stro9e@idth> :*K
P
d3noob.org /0
We?ve de(ined the sty"es (or the area this ti1e; but instead o( the stro9e being de(ined by the
searate scrit; no. it?s the area. Whi"e .e?ve changed the ur" na1e; it?s actua""y the sa1e iece o(
code; .ith a di((erent id #because it see1ed .rong to be ta"9ing about an area .hen the "abe" said
"ine$. We?ve a"so set the stro9e .idth to Fero; because .e don?t .ant any "ines around our (i""ed area.
Jo. .e .ant to ta9e the b"oc9 o( code that de(ined our "ine...
var va"ue"ine N d3.svg."ine#$
.*#function#d$ M return *#d.date$K P$
.y#function#d$ M return y#d.c"ose$K P$K
[ and .e need to re"ace it .ith the standard b"oc9 that de(ined an area (i"".
var area N d3.svg.area#$
.*#function#d$ M return *#d.date$K P$
.y:#height$
.y1#function#d$ M return y#d.c"ose$K P$K
So .e?re not going to be dra.ing a "ine at a"". Just the area (i"".
Je*t as I 1entioned ear"ier; .e change the id (or the "inear,radient b"oc9 (ro1 G"ine@gradientH to
Garea@gradientH
.attr#LidL; Larea@gradientL$
6nd "ast"y; .e re1ove the b"oc9 o( code that dre. the "ine and re"ace it .ith a b"oc9 that dra.s an
area. So change this....
svg.aend#LathL$
.attr#Lc"assL; L"ineL$
.attr#LdL; va"ue"ine#data$$K
[ (or thisK
svg.aend#LathL$
.datu1#data$
.attr#Lc"assL; LareaL$
.attr#LdL; area$K
6nd then sit bac9 and 1arve" at your creationK
3or a s"ight"y ?nicer? "oo9ing e*a1"e; you cou"d chec9 out a variation o( one o( Mi9e Costoc9s
origina"s hereK htt>44b".oc9s.org44433:2).
d3noob.org /3
*sing -lunker for de(elop!ent and hosting your D3 creations"
5ecent"y Mi9e Costoc9 reco11ended ?="un9er? #htt>44"n9r.co4$ as a too" (or saving .or9 on"ine
(or co""aboration and sharing. 6"though I had a Auic9 "oo9; I didn?t Auite ?get it? and a"though it
"oo9ed "i9e so1ething that I shou"d be interested in; I #(oo"ish"y$ 1oved on to other things.
Buite (ran9"y I shou"d have ersevered.
="un9er is a.eso1e.
So .hat can it do (or you?
We""; in short; this gives you a "ace to ut your grahs on the .eb .ithout the hass"e o( needing a
.eb server as .e"" as a""o.ing others to vie. and co""aborate8 There are so1e "i1itations to hosting
grahs in this environ1ent; but there?s no denying that (or ease o( use and visibi"ity to the outside
.or"d; it?s outstanding8
Ti1e (or an e*a1"e. I?"" try to go through the rocess o( i1"e1enting the si1"e grah e*a1"e
on ="un9er.
So it?s as si1"e as going to htt>44"n9r.co4edit4
What you?re seeing here is an area .here you can "ace your entire HTML code. So "et?s re"ace the
11 "ines o( the "ace ho"der code .ith the si1"e grah e*a1"e #<ust coy and aste it in there over
the to o( the current 11 "ines$K
Jo.; there are t.o i1ortant things .e have to do be(ore it .i"" .or9.
1. We need to te"" he scrit .here to (ind d3.<s
0. We need to 1a9e our data accessib"e
He"ing the scrit (ind d3.<s is nice and easy. Just re"ace this "ine in your "un9K
Rscript tyeNLte*t4<avascritL srcNLd34d3.v3.<sLSR4scriptS
....ith this "ine...
d3noob.org /4
Rscript srcNLhtt>44d3<s.org4d3.v3.1in.<sLSR4scriptS
That .i"" a""o. your "un9 to use the version o( d3.<s that is hosted on d3<s.org #it uses the
1ini1ised version #.hich is .hy it has the ?1in? in it$; but never (ear; it?s sti"" d3; <ust disti""ed to
enhance the ("avour >@$$.
Ma9ing our data avai"ab"e is on"y s"ight"y 1ore di((icu"t.
In e*eri1enting .ith ="un9er; I (ound that there aears to be so1ething ?odd? about accessing the
tab searated va"ues that .e have been using thus (ar #in the data.tsv (i"e$; ho.ever; -3 to the
rescue8 We can si1"y use !o11a Searated 7a"ues #csv$ instead.
So in rearation (or this e*ercise; "ease edit your data.tsv (i"e to have the tabs searating the
va"ues re"aced by co11as and rena1e it data.csv.
We .i"" host our data.csv (i"e on "un9er as .e"" and there is bui"t in (unctiona"ity to "et us do it.
In the to "e(t hand corner; beside the ?3IL+S? note; there is a ?OJ+W...? section. !"ic9ing on this .i""
a""o. you to create another (i"e that .i"" e*ist .ith your "un9 (or its use; so "et?s do that.
This .i"" oen a dia"ogue bo* that .i"" as9 you to na1e your ne. (i"e.
+nter the na1e data.csv.
Jo. another (i"e has aeared under the ?3i"es? heading ca""ed data.csv. !"ic9 on it.
This no. sho.s us a b"an9 (i"e ca""ed data.csv; so no. oen u your data.csv (i"e in .hatever editor
you?re using #I don?t thin9 a sreadsheet rogra1 is going to be a good idea since I doubt that it .i""
1aintain the in(or1ation in a te*tua" (or1 as .e?re .anting it to do. So it?s ,eany (or 1e$. !oy the
contents o( your "oca" data.csv (i"e and ast it into the ne. "un9er data.csv (i"e.
d3noob.org /5
So no. .e have our data in there .e need to te"" our JavaScrit .here it is. So go bac9 to the
?inde*.ht1"? (i"e #.hich is our si1"e grah code$ and edit the "ine .hich (inds the data.tsv (i"e (ro1
this
d3.tsv#Ldata4data.tsvL; function#error; data$ M
[ to this ...
d3.csv#Ldata.csvL; function#error; data$ M
Cecause .e?re using re"ative addressing; and "un9er stores the (i"es (or the grahing scrit and the
data side by side; .e <ust re1oved the ortion o( the address that to"d our origina" code to "oo9 in
the ?data? directory and to"d it to "oo9 in the current directory.
6nd that shou"d be that8
Jo. i( you "oo9 on the right hand side o( the screen; there is a "itt"e eye icon. I( you c"ic9 on it; it
oens u a revie. .indo. o( your (i"e in action and vio"a8
I( the grah doesn?t aear; go through the stes out"ined above and <ust chec9 that the edits are
1ade correct"y. 'n(ortunate"y I haven?t (ound a nice 1echanis1 (or troub"eshooting inside ="un9er
yet #not "i9e using 310 on !hro1e$.
Cut .ait8 There?s 1ore8
I( you no. c"ic9 on the ?Save? button at the to o( the screen; you .i"" get so1e ne. button otions.
&ne o( the1 is the orange one (or sho.ing o(( your .or9.
I( you c"ic9 on this; it .i"" resent you .ith severa" di((erent otions.
d3noob.org /%
The (irst one is a "in9 that .i"" give others the otion to co""aborate on the scrit.
The second is a "in9 that .i"" a""o. others to revie. the .or9K
htt>44e1bed."n9r.co4BS!9,25(0A3gr!AA)7(n
The "ast .i"" a""o. you to e1bed your grah in a searate .eb age so1e.here. Which I?ve tested
.ith b"ogger and see1s to .or9 rea""y .e""8 #see i1age be"o.$.
So; I?1 i1ressed; Jice .or9 by ="un9er and it?s creator ,eo(( ,ood1an.
d3noob.org /)
.oading a thu!bnail into Gist for bl"ocks"org d3 graphs
This descrition .i"" start on the assu1tion that the user a"ready has a ,itHub 4 ,ist account set u
and running. It?s urose is to de1onstrate ho. to u"oad an i1age as a (i"e na1ed thu1bnai".ng
to a ,ist so that .hen vie.ing the users ho1e age on b".oc9s.org you see a nice "itt"e revie. o(
.hat a visitor can anticiate .hen they go toy "oo9 at your .or9 >@$
This descrition is a ("eshed out version o( the one rovided by !hristohe 7iau on ,oog"e ,rous
#htts>44grous.goog"e.co14(oru14?(ro1grousNZ8toic4d3@<s43CosWiTC/=c$.
Setting the scene-
There you are a (resh (aced d3.<s user 9een to share your .or9 .ith the .or"d. Eou set yourse"( u a
,itHub 4 ,ist account and ut your code into a gist.
Eour grah is a thing o( rare beauty and the co11unity needs to 1arve" at your bri""iance. &(
course this is a breeFe .ith b".oc9s.org. &nce you have a"" the code sorted and any data (i"es
accessib"e; b".oc9s.org can dis"ay the grah .ith the code and can even oen the grah in its o.n
.indo.. The erson resonsib"e (or b".oc9s.org? Mi9e Costoc9 o( course #.herever does he get the
ti1e?$.
So c"ic9ing on the b".oc9s.org button on the gist age #"oad the e*tension avai"ab"e (ro1 the 1ain
age o( b".oc9s.org$ ta9es you to see your grah.
d3noob.org /2
Wo.8 I1ressive.
So you thin9 that .i"" 1a9e a (ine addition to your co""ection o( a.eso1e grahs and i( you c"ic9 on
your ,itHub user na1e that is in the to "e(t o( the screen you go to a age that "ays out a"" your
grahs .ith a thu1bnai" giving a snea9 revie. o( .hat the user can e*ect.
6..... 5ats8 There?s a nice "ace ho"der; but no retty icture.
Hang on; .hat had Mi9e said on the b".oc9s.org 1ain age?
GThe main source code for your example should be named index.html. You can also
include a README.md using Markdown, and a thumbnail.png for preview.H
6hh.. you need to inc"ude a thu1bnai".ng (i"e in your ,ist8
So ho. to get it there? We"" ,ist is a reository; so .hat you need to do is to ut the code in there
so1eho.. Jo. (ro1 the ,ist .eb age this doesn?t aear to be a nice #gui$ .ay to do this. So
(ro1 here you .i"" need to susend your noob status and hit the co11and "ine.
The good ne.s #i( you?re a .indo.s user #and sorry; I haven?t done this in Linu* or on a Mac$$ is
that as art o( the ,itHub (or .indo.s insta""ation a co11and "ine too" .as insta""ed as .e""8 So
you?re going to use the ,it She"".
d3noob.org //
+n$ugh $f the scene setting) Let.s git g$ing -/))
5ight; I?1 going to describe the stes here in a retty verbose (ashion .ith retty ictures and
everything; but at the end I .i"" ut a si1"e set o( stes in the (or1 that !hristohe 7iau out"ined
on ,oog"e ,rous
0:
.
3irst you .i"" .ant to have your i1age ready. It needs to be a ng .ith di1ensions o( 03: * 10:
i*e"s. It shou"d a"so be "ess than 5:9C in siFe.
Jo. go to your ub"ic ,ist that you have a"ready set u and coy the "in9 in the G!"one this gistH
bo*.
#this shou"d "oo9 so1ething "i9e htts>44gist.github.co14441443%.git$
Jo. you?re going to c"one this gist to a "oca" reository using the ,it She"". &en it u (ro1 the
des9to icon and you shou"d see so1ething "i9e the (o""o.ingK

So you can c"one the gist to a "oca" (o"der .ith the co11andK
git clone https://gist.github.com/4414436.git
#The ur" is the one coied (ro1 the ?!"one this gist? bo*.$
0: htts>44grous.goog"e.co14(oru14?(ro1grousNZ8toic4d3@<s43CosWiTC/=c
d3noob.org 1::
This .i"" create a (o"der .ith the id #the nu1ber$ o( the gist in your "oca" ,itHub .or9ing directory.
6nd there it is #&oo... Loo9 a"1ost Je. Eears8$.
!oy your thu1bnai".ng (i"e into this directory.
Cac9 to the ,it She"" and change into the directory #441443%$ . We can no. add the thu1bnai".ng
(i"e to the gist .ith the co11andK
git add thumbnail.png
6nd no. co11it it to your gist .ith the (o""o.ing co11and in the ,it She""K
git commit -m !humbnail image added
Jo. .e need to ush the co11it to the re1ote gist #you 1ay be as9ed (or your ,itHub user na1e
and ass.ord i( you haven?t done this be(ore$ .ith the (o""o.ing co11andK
git push
&D; no. you can go bac9 to the .eb age (or your gist and re(resh it and scro"" on do.n...
d3noob.org 1:1
Woo Hoo8
#I 9no. it doesn?t "oo9 "i9e 1uch; but this is a 7+5E si1"e grah >@$$.
Jo. (or the rea" test. ,o bac9 to your ho1e age (or your b"oc9s on b".oc9s.org and re(resh the
age.
&h yes. Eou 1ay no. bas9 in the s.eet g"o. o( victory. 6nd as a "itt"e bit o( e*tra (ancy; i( you
1ove your 1ouse over the i1age it trans"ates u s"ight"y8
Wrap up)
The stes to get your thu1bnai" into the gist aren?t e*act"y oint and c"ic9; but the stes you need to
ta9e are (air"y easy to (o""o.. 6s ro1ised; here is the abridged "ist o( stes that .i"" avoid you
going through the severa" revious ages.
1. !reate your ub"ic gist on htts>44gist.github.co14
0. ,et an i1age ready #03: * 10: i*e"s; na1ed thu1bnai".ng$
3. 'nder L!"one this gistL; coy the "in9 #i.e.; htts>44gist.github.co14441443%.git$
4. I( you have the co11and "ine git too"s #,it She""$; c"one this gist to a "oca" (o"der>
git clone https://gist.github.com/4414436.git
It .i"" add a (o"der .ith the gist id as a na1e #i.e.; 441443%$ under the current .or9ing
directory.
5. Javigate to this (o"der via the co11and "ine in ,it She""> cd 4414436 #dir 441443% on
.indo.s$
%. Javigate to this (o"der in (i"e e*"orer and add your i1age #i.e.; thu1bnai".ng$
). 6dd it to git (ro1 the co11and "ine> git add test.png
d3noob.org 1:0
2. !o11it it to git> git commit -m !humbnail added
/. =ush this co11it to your re1ote gist #you 1ay need your ,ithub user na1e and ass.ord$>
git push
1:. ,o bac9 and re(resh your ,ist on htts>44gist.github.co14 to con(ir1 that it .or9ed
11. !hec9 your b"oc9s ho1e age and see i( it?s there too. htt>44b".oc9s.org4+youruserna,e-
Just to (inish o((. 6 big than9s to !hristohe 7iau (or the hard .or9 on (inding out ho. it a"" goes
together and i( there are any errors in the above descrition I have no doubt they .i"" be 1ine.
d3noob.org 1:3

You might also like