1
+ < html >
2
+ < head >
3
+ < title > Basic Priestley-style timeline</ title >
4
+ < style >
5
+ /*some basic CSS*/
6
+ .axis path {fill : none;stroke : none}
7
+ .axis line {fill : none;stroke : gray;stroke-width : 1px ;}
8
+ .axis text {fill : gray;stroke : none;}
9
+ text {text-anchor : middle}
10
+ </ style >
11
+ </ head >
12
+ < body >
13
+ < h1 > A Specimen of a Priestley-style Timeline</ h1 >
14
+ < script src ="js/d3.min.js "> </ script >
15
+ < script >
16
+
17
+ var file = "composers.csv"
18
+ var width = 600 , height = 400 ;
19
+ var margin = { top :50 , bottom :30 , left :20 , right :20 }
20
+
21
+ //create svg element to hold graphics
22
+ var svg = d3 . select ( "body" ) . append ( "svg" )
23
+ . attr ( "width" , width )
24
+ . attr ( "height" , height )
25
+
26
+ //load the data
27
+ d3 . csv ( file , function ( data ) {
28
+
29
+ //define the date format used in the data
30
+ var parseDate = d3 . time . format ( "%d/%m/%Y" ) ;
31
+ //parse the date information in the data
32
+ data . forEach ( function ( d ) {
33
+ d . born = parseDate . parse ( d . born )
34
+ d . died = parseDate . parse ( d . died )
35
+ } ) ;
36
+
37
+ //sort the lifespans into date-of-birth order - we will use this for the drawing order of the chart
38
+ data . sort ( function ( a , b ) {
39
+ return a . born - b . born ;
40
+ } ) ;
41
+
42
+ //find out the range of the dates
43
+ //first birth
44
+ var minDate = d3 . min ( data , function ( d ) {
45
+ return d . born ;
46
+ } )
47
+
48
+ //last death
49
+ var maxDate = d3 . max ( data , function ( d ) {
50
+ return d . died ;
51
+ } )
52
+
53
+ //calculate plot dimensions
54
+ var plotWidth = width - ( margin . left + margin . right )
55
+ var plotHeight = height - ( margin . top + margin . bottom )
56
+
57
+ //create a scale for the timeline
58
+ var xScale = d3 . time . scale ( )
59
+ . domain ( [ minDate , maxDate ] )
60
+ . range ( [ 0 , plotWidth ] )
61
+
62
+ //a scale for vertical arrangement of each lifespan
63
+ var yScale = d3 . scale . ordinal ( )
64
+ . domain ( data . map ( function ( d ) {
65
+ return d . name ;
66
+ } ) )
67
+ . rangeRoundBands ( [ 0 , plotHeight ] , 0.6 ) ;
68
+
69
+ //define the chart's time axes
70
+ //primary axis - these will be labelled
71
+ var xAxis = d3 . svg . axis ( )
72
+ . scale ( xScale )
73
+ . orient ( "bottom" )
74
+ . ticks ( 4 )
75
+ . tickSize ( - plotHeight )
76
+
77
+ //secondary axis - more ticks but no labels
78
+ var xAxis2 = d3 . svg . axis ( )
79
+ . scale ( xScale )
80
+ . orient ( "bottom" )
81
+ . tickFormat ( d3 . time . format ( "" ) )
82
+ . ticks ( 20 )
83
+
84
+ //draw the axes
85
+ svg . append ( "g" )
86
+ . attr ( "class" , "axis" )
87
+ . attr ( "transform" , "translate(" + margin . left + "," + ( margin . top + plotHeight ) + ")" )
88
+ . call ( xAxis )
89
+ svg . append ( "g" )
90
+ . attr ( "class" , "axis" )
91
+ . attr ( "transform" , "translate(" + margin . left + "," + ( margin . top + plotHeight ) + ")" )
92
+ . call ( xAxis2 )
93
+
94
+ //offset the textlabels
95
+ svg . selectAll ( ".axis text" )
96
+ . attr ( "dy" , 20 )
97
+
98
+ //create chart geometry
99
+ //chart group
100
+ var chart = svg . append ( "g" )
101
+ . attr ( "id" , "chart" )
102
+ . attr ( "transform" , "translate(" + margin . left + "," + margin . top + ")" )
103
+
104
+ //a row for each lifespan
105
+ var rowGroups = chart . append ( "g" )
106
+ . attr ( "id" , "chart_rows" )
107
+ . selectAll ( "g" )
108
+ . data ( data )
109
+ . enter ( )
110
+ . append ( "g" )
111
+ . attr ( "transform" , function ( d , i ) {
112
+ return "translate(0," + yScale ( d . name ) + ")"
113
+ } )
114
+
115
+ rowGroups . each ( function ( d , i ) {
116
+ //create a rectangle to show time between birth and and death
117
+ d3 . select ( this ) . append ( "rect" )
118
+ . attr ( "x" , function ( d ) {
119
+ return xScale ( d . born )
120
+ } )
121
+ . attr ( "width" , function ( d ) {
122
+ return xScale ( d . died ) - xScale ( d . born )
123
+ } )
124
+ . attr ( "height" , yScale . rangeBand )
125
+ . attr ( "fill" , "black" )
126
+ . attr ( "fill-opacity" , 0.8 )
127
+
128
+ //create a label with each composer's name on it - put it in middle of lifespan
129
+ d3 . select ( this ) . append ( "text" )
130
+ . attr ( "x" , function ( d ) {
131
+ //calculate mid point of composer's life
132
+ var midPoint = new Date ( ( d . born . getTime ( ) + d . died . getTime ( ) ) / 2 ) ;
133
+ return xScale ( midPoint )
134
+ } )
135
+ . attr ( "y" , function ( d ) {
136
+ return - 1 ;
137
+ } )
138
+ . text ( function ( d ) {
139
+ return d . name
140
+ } )
141
+
142
+ //label the first row with a key
143
+ if ( i == 0 ) {
144
+ var key = d3 . select ( this ) . append ( "g" )
145
+ . attr ( "class" , "axis" )
146
+ key . append ( "text" )
147
+ . attr ( "x" , function ( d ) {
148
+ return xScale ( d . born ) ;
149
+ } )
150
+ . attr ( "y" , function ( d ) {
151
+ return - 5 ;
152
+ } )
153
+ . text ( "born" )
154
+ key . append ( "text" )
155
+ . attr ( "x" , function ( d ) {
156
+ return xScale ( d . died ) ;
157
+ } )
158
+ . attr ( "y" , function ( d ) {
159
+ return - 5 ;
160
+ } )
161
+ . text ( "died" )
162
+ }
163
+ } ) //end each row
164
+
165
+ } ) //end
166
+
167
+ </ script >
168
+ </ body >
169
+ </ html >
0 commit comments