├── .gitmodules ├── .nojekyll ├── LICENSE ├── README.md ├── blank.js ├── build_a_chart ├── countries.csv ├── countries.json ├── d3.min.js ├── index.html ├── main.css └── main.js ├── d3-01.html ├── d3-02.html ├── d3.html ├── example ├── barley.json ├── html-link.html ├── html-marked.html ├── html0.txt └── plain.html ├── frame.css ├── frame.scss ├── frame └── selection.html ├── fundamental.html ├── img ├── __data__.png ├── box-model.gif ├── bundle.png ├── d3.png ├── d3ordinalRange.png ├── d3scale1.png ├── grid-crop.png ├── pack.png ├── partition.png ├── range-bands.png ├── range-point.png ├── the-grid.png ├── tree.png ├── treemap.png └── voronoi.png ├── index.html ├── js ├── chart.js ├── d3.js ├── jquery.js └── selection.js ├── live.zip ├── live ├── 1-begin.html ├── 10-transitions.html ├── 11-csv.html ├── 12-exit.html ├── 13-final.html ├── 2-svg.html ├── 3-selection.html ├── 4-binding.html ├── 5-scales1.html ├── 6-scales2.html ├── 7-axes.html ├── 8-legends.html ├── 9-events.html ├── index.html ├── info.js ├── titanic passenger list.csv └── viewer.html ├── other resources └── d3 Cheat Sheet.pdf ├── sass.css ├── sass.scss └── style.css /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "reveal.js"] 2 | path = reveal.js 3 | url = https://github.com/hakimel/reveal.js.git 4 | 5 | [submodule "highlight.js"] 6 | path = highlight.js 7 | url = https://github.com/isagalaev/highlight.js.git 8 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/.nojekyll -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Interactive Data Lab, University of Washington 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # d3-tutorials 2 | 3 | D3 Tutorials for CSE512 Data Visualization Course at University of Washington by [@kanitw](https://twitter.com/kanitw) and [@domoritz](https://twitter.com/domoritz) at [@uwdata](https://twitter.com/uwdata). 4 | 5 | Our [wiki](https://github.com/uwdata/d3-tutorials/wiki) also lists a number of useful resources for visualization design and development. 6 | Feel free to use them for your classes or workshops and send us [feedback](https://github.com/uwdata/d3-tutorials/issues/new) and [improvements](https://github.com/uwdata/d3-tutorials/pulls). If you find these tutorial useful, please tweet to us at [@uwdata](https://twitter.com/uwdata) and write in our [Testimonials](https://github.com/uwdata/d3-tutorials/wiki/Testimonials) page. 7 | -------------------------------------------------------------------------------- /blank.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | function main() { 4 | return "Hello, World!"; 5 | } -------------------------------------------------------------------------------- /build_a_chart/countries.csv: -------------------------------------------------------------------------------- 1 | year,fertility,life_expect,country 2 | 1955,7.7,30.332,Afghanistan 3 | 1960,7.7,31.997,Afghanistan 4 | 1965,7.7,34.02,Afghanistan 5 | 1970,7.7,36.088,Afghanistan 6 | 1975,7.7,38.438,Afghanistan 7 | 1980,7.8,39.854,Afghanistan 8 | 1985,7.9,40.822,Afghanistan 9 | 1990,8,41.674,Afghanistan 10 | 1995,8,41.763,Afghanistan 11 | 2000,7.4792,42.129,Afghanistan 12 | 1955,3.1265,64.399,Argentina 13 | 1960,3.0895,65.142,Argentina 14 | 1965,3.049,65.634,Argentina 15 | 1970,3.1455,67.065,Argentina 16 | 1975,3.44,68.481,Argentina 17 | 1980,3.15,69.942,Argentina 18 | 1985,3.053,70.774,Argentina 19 | 1990,2.9,71.868,Argentina 20 | 1995,2.63,73.275,Argentina 21 | 2000,2.35,74.34,Argentina 22 | 1955,5.15,64.381,Aruba 23 | 1960,4.399,66.606,Aruba 24 | 1965,3.301,68.336,Aruba 25 | 1970,2.651,70.941,Aruba 26 | 1975,2.45,71.83,Aruba 27 | 1980,2.358,74.116,Aruba 28 | 1985,2.3,74.494,Aruba 29 | 1990,2.28,74.108,Aruba 30 | 1995,2.208,73.011,Aruba 31 | 2000,2.124,73.451,Aruba 32 | 1955,3.406,70.33,Australia 33 | 1960,3.274,70.93,Australia 34 | 1965,2.871,71.1,Australia 35 | 1970,2.535,71.93,Australia 36 | 1975,1.989,73.49,Australia 37 | 1980,1.907,74.74,Australia 38 | 1985,1.859,76.32,Australia 39 | 1990,1.86,77.56,Australia 40 | 1995,1.776,78.83,Australia 41 | 2000,1.756,80.37,Australia 42 | 1955,2.52,67.48,Austria 43 | 1960,2.78,69.54,Austria 44 | 1965,2.53,70.14,Austria 45 | 1970,2.02,70.63,Austria 46 | 1975,1.64,72.17,Austria 47 | 1980,1.62,73.18,Austria 48 | 1985,1.45,74.94,Austria 49 | 1990,1.47,76.04,Austria 50 | 1995,1.388,77.51,Austria 51 | 2000,1.382,78.98,Austria 52 | 1955,4.305,62.405,Bahamas 53 | 1960,4.503,64.209,Bahamas 54 | 1965,3.794,65.795,Bahamas 55 | 1970,3.444,66.515,Bahamas 56 | 1975,3.221,67.199,Bahamas 57 | 1980,3.16,67.874,Bahamas 58 | 1985,2.62,69.524,Bahamas 59 | 1990,2.6,69.171,Bahamas 60 | 1995,2.4,68.472,Bahamas 61 | 2000,2.1111,71.068,Bahamas 62 | 1955,6.76,39.348,Bangladesh 63 | 1960,6.85,41.216,Bangladesh 64 | 1965,6.6,43.453,Bangladesh 65 | 1970,6.15,45.252,Bangladesh 66 | 1975,5.6,46.923,Bangladesh 67 | 1980,5.25,50.009,Bangladesh 68 | 1985,4.629,52.819,Bangladesh 69 | 1990,4.117,56.018,Bangladesh 70 | 1995,3.5043,59.412,Bangladesh 71 | 2000,3.224,62.013,Bangladesh 72 | 1955,4.67,62.57,Barbados 73 | 1960,4.26,65.87,Barbados 74 | 1965,3.45,67.62,Barbados 75 | 1970,2.74,69.42,Barbados 76 | 1975,2.19,71.27,Barbados 77 | 1980,1.92,72.695,Barbados 78 | 1985,1.75,74.027,Barbados 79 | 1990,1.6,74.894,Barbados 80 | 1995,1.5,74.912,Barbados 81 | 2000,1.5,75.97,Barbados 82 | 1955,2.496,69.24,Belgium 83 | 1960,2.644,70.25,Belgium 84 | 1965,2.392,70.94,Belgium 85 | 1970,2.015,71.44,Belgium 86 | 1975,1.705,72.8,Belgium 87 | 1980,1.595,73.93,Belgium 88 | 1985,1.559,75.35,Belgium 89 | 1990,1.613,76.46,Belgium 90 | 1995,1.604,77.53,Belgium 91 | 2000,1.638,78.32,Belgium 92 | 1955,6.75,41.89,Bolivia 93 | 1960,6.63,43.428,Bolivia 94 | 1965,6.56,45.032,Bolivia 95 | 1970,6.5,46.714,Bolivia 96 | 1975,5.8,50.023,Bolivia 97 | 1980,5.2995,53.859,Bolivia 98 | 1985,5,57.251,Bolivia 99 | 1990,4.8,59.957,Bolivia 100 | 1995,4.324,62.05,Bolivia 101 | 2000,3.9585,63.883,Bolivia 102 | 1955,6.1501,53.285,Brazil 103 | 1960,6.1501,55.665,Brazil 104 | 1965,5.38,57.632,Brazil 105 | 1970,4.7175,59.504,Brazil 106 | 1975,4.305,61.489,Brazil 107 | 1980,3.8,63.336,Brazil 108 | 1985,3.1,65.205,Brazil 109 | 1990,2.6,67.057,Brazil 110 | 1995,2.45,69.388,Brazil 111 | 2000,2.345,71.006,Brazil 112 | 1955,3.882,69.96,Canada 113 | 1960,3.675,71.3,Canada 114 | 1965,2.61,72.13,Canada 115 | 1970,1.976,72.88,Canada 116 | 1975,1.734,74.21,Canada 117 | 1980,1.634,75.76,Canada 118 | 1985,1.616,76.86,Canada 119 | 1990,1.694,77.95,Canada 120 | 1995,1.564,78.61,Canada 121 | 2000,1.522,79.77,Canada 122 | 1955,5.486,56.074,Chile 123 | 1960,5.4385,57.924,Chile 124 | 1965,4.4405,60.523,Chile 125 | 1970,3.63,63.441,Chile 126 | 1975,2.803,67.052,Chile 127 | 1980,2.671,70.565,Chile 128 | 1985,2.65,72.492,Chile 129 | 1990,2.55,74.126,Chile 130 | 1995,2.21,75.816,Chile 131 | 2000,2,77.86,Chile 132 | 1955,5.59,50.54896,China 133 | 1960,5.72,44.50136,China 134 | 1965,6.06,58.38112,China 135 | 1970,4.86,63.11888,China 136 | 1975,3.32,63.96736,China 137 | 1980,2.55,65.525,China 138 | 1985,2.46,67.274,China 139 | 1990,1.92,68.69,China 140 | 1995,1.781,70.426,China 141 | 2000,1.7,72.028,China 142 | 1955,6.76,55.118,Colombia 143 | 1960,6.76,57.863,Colombia 144 | 1965,6.18,59.963,Colombia 145 | 1970,5.0005,61.623,Colombia 146 | 1975,4.3385,63.837,Colombia 147 | 1980,3.685,66.653,Colombia 148 | 1985,3.172,67.768,Colombia 149 | 1990,2.93005,68.421,Colombia 150 | 1995,2.7,70.313,Colombia 151 | 2000,2.4705,71.682,Colombia 152 | 1955,7.1135,60.026,Costa Rica 153 | 1960,7.2245,62.842,Costa Rica 154 | 1965,5.801,65.424,Costa Rica 155 | 1970,4.346,67.849,Costa Rica 156 | 1975,3.7755,70.75,Costa Rica 157 | 1980,3.527,73.45,Costa Rica 158 | 1985,3.374,74.752,Costa Rica 159 | 1990,2.945,75.713,Costa Rica 160 | 1995,2.5835,77.26,Costa Rica 161 | 2000,2.2815,78.123,Costa Rica 162 | 1955,2.42,64.77,Croatia 163 | 1960,2.27,67.13,Croatia 164 | 1965,2.09,68.5,Croatia 165 | 1970,1.96,69.61,Croatia 166 | 1975,2.02,70.64,Croatia 167 | 1980,1.96,70.46,Croatia 168 | 1985,1.84,71.52,Croatia 169 | 1990,1.52,72.527,Croatia 170 | 1995,1.537,73.68,Croatia 171 | 2000,1.348,74.876,Croatia 172 | 1955,3.6995,62.325,Cuba 173 | 1960,4.6805,65.246,Cuba 174 | 1965,4.3,68.29,Cuba 175 | 1970,3.6,70.723,Cuba 176 | 1975,2.15,72.649,Cuba 177 | 1980,1.8495,73.717,Cuba 178 | 1985,1.8495,74.174,Cuba 179 | 1990,1.6505,74.414,Cuba 180 | 1995,1.6095,76.151,Cuba 181 | 2000,1.63,77.158,Cuba 182 | 1955,7.6405,49.828,Dominican Republic 183 | 1960,7.3505,53.459,Dominican Republic 184 | 1965,6.6495,56.751,Dominican Republic 185 | 1970,5.71,59.631,Dominican Republic 186 | 1975,4.76,61.788,Dominican Republic 187 | 1980,4,63.727,Dominican Republic 188 | 1985,3.47,66.046,Dominican Republic 189 | 1990,3.1995,68.457,Dominican Republic 190 | 1995,3.05,69.957,Dominican Republic 191 | 2000,2.95,70.847,Dominican Republic 192 | 1955,6.7,51.356,Ecuador 193 | 1960,6.7,54.64,Ecuador 194 | 1965,6.5,56.678,Ecuador 195 | 1970,6.0005,58.796,Ecuador 196 | 1975,5.4005,61.31,Ecuador 197 | 1980,4.7005,64.342,Ecuador 198 | 1985,4,67.231,Ecuador 199 | 1990,3.4005,69.613,Ecuador 200 | 1995,3.1,72.312,Ecuador 201 | 2000,2.8175,74.173,Ecuador 202 | 1955,6.97,44.444,Egypt 203 | 1960,7.073,46.992,Egypt 204 | 1965,6.56,49.293,Egypt 205 | 1970,5.855,51.137,Egypt 206 | 1975,5.609,53.319,Egypt 207 | 1980,5.332,56.006,Egypt 208 | 1985,4.833,59.797,Egypt 209 | 1990,3.908,63.674,Egypt 210 | 1995,3.5,67.217,Egypt 211 | 2000,3.174,69.806,Egypt 212 | 1955,6.8065,48.57,El Salvador 213 | 1960,6.847,52.307,El Salvador 214 | 1965,6.621,55.855,El Salvador 215 | 1970,6.0995,58.207,El Salvador 216 | 1975,5.5996,56.696,El Salvador 217 | 1980,4.5,56.604,El Salvador 218 | 1985,3.901,63.154,El Salvador 219 | 1990,3.52,66.798,El Salvador 220 | 1995,3.17,69.535,El Salvador 221 | 2000,2.883,70.734,El Salvador 222 | 1955,2.769,67.49,Finland 223 | 1960,2.66,68.75,Finland 224 | 1965,2.191,69.83,Finland 225 | 1970,1.623,70.87,Finland 226 | 1975,1.663,72.52,Finland 227 | 1980,1.685,74.55,Finland 228 | 1985,1.66,74.83,Finland 229 | 1990,1.819,75.7,Finland 230 | 1995,1.743,77.13,Finland 231 | 2000,1.754,78.37,Finland 232 | 1955,2.712,68.93,France 233 | 1960,2.85,70.51,France 234 | 1965,2.607,71.55,France 235 | 1970,2.31,72.38,France 236 | 1975,1.862,73.83,France 237 | 1980,1.866,74.89,France 238 | 1985,1.805,76.34,France 239 | 1990,1.713,77.46,France 240 | 1995,1.7624,78.64,France 241 | 2000,1.8833,79.59,France 242 | 1955,2.909,62.625,Georgia 243 | 1960,2.979,64.644,Georgia 244 | 1965,2.611,66.654,Georgia 245 | 1970,2.601,68.158,Georgia 246 | 1975,2.39,69.634,Georgia 247 | 1980,2.269,69.638,Georgia 248 | 1985,2.263,70.45,Georgia 249 | 1990,1.95,70.465,Georgia 250 | 1995,1.58,70.49,Georgia 251 | 2000,1.478,70.476,Georgia 252 | 1955,2.3,69.1,Germany 253 | 1960,2.49,70.3,Germany 254 | 1965,2.32,70.8,Germany 255 | 1970,1.64,71,Germany 256 | 1975,1.52,72.5,Germany 257 | 1980,1.46,73.8,Germany 258 | 1985,1.43,74.847,Germany 259 | 1990,1.31,76.07,Germany 260 | 1995,1.34,77.34,Germany 261 | 2000,1.346,78.67,Germany 262 | 1955,2.27,67.86,Greece 263 | 1960,2.2,69.51,Greece 264 | 1965,2.38,71,Greece 265 | 1970,2.32,72.34,Greece 266 | 1975,2.32,73.68,Greece 267 | 1980,1.96,75.24,Greece 268 | 1985,1.53,76.67,Greece 269 | 1990,1.37,77.03,Greece 270 | 1995,1.296,77.869,Greece 271 | 2000,1.277,78.256,Greece 272 | 1955,6.7,63.114,Grenada 273 | 1960,6.4,63.608,Grenada 274 | 1965,4.8,64.091,Grenada 275 | 1970,4.6,64.577,Grenada 276 | 1975,4.3,65.035,Grenada 277 | 1980,4.23,65.503,Grenada 278 | 1985,4.14,66.002,Grenada 279 | 1990,3.26,66.469,Grenada 280 | 1995,2.814,66.986,Grenada 281 | 2000,2.429,67.746,Grenada 282 | 1955,6.3,40.696,Haiti 283 | 1960,6.3,43.59,Haiti 284 | 1965,6,46.243,Haiti 285 | 1970,5.6005,48.042,Haiti 286 | 1975,5.8,49.923,Haiti 287 | 1980,6.2099,51.461,Haiti 288 | 1985,5.69985,53.636,Haiti 289 | 1990,5.14985,55.089,Haiti 290 | 1995,4.61995,56.671,Haiti 291 | 2000,4,58.137,Haiti 292 | 1955,4.72,64.75,Hong Kong 293 | 1960,5.31,67.65,Hong Kong 294 | 1965,4.02,70,Hong Kong 295 | 1970,2.89,72,Hong Kong 296 | 1975,2.32,73.6,Hong Kong 297 | 1980,1.8,75.45,Hong Kong 298 | 1985,1.31,76.2,Hong Kong 299 | 1990,1.288,77.601,Hong Kong 300 | 1995,1.08,80,Hong Kong 301 | 2000,0.94,81.495,Hong Kong 302 | 1955,4.023,73.47,Iceland 303 | 1960,3.943,73.68,Iceland 304 | 1965,3.154,73.73,Iceland 305 | 1970,2.843,74.46,Iceland 306 | 1975,2.287,76.11,Iceland 307 | 1980,2.248,76.99,Iceland 308 | 1985,2.116,77.23,Iceland 309 | 1990,2.194,78.77,Iceland 310 | 1995,2.056,78.95,Iceland 311 | 2000,1.993,80.5,Iceland 312 | 1955,5.8961,40.249,India 313 | 1960,5.8216,43.605,India 314 | 1965,5.6058,47.193,India 315 | 1970,5.264,50.651,India 316 | 1975,4.8888,54.208,India 317 | 1980,4.4975,56.596,India 318 | 1985,4.15,58.553,India 319 | 1990,3.8648,60.223,India 320 | 1995,3.4551,61.765,India 321 | 2000,3.1132,62.879,India 322 | 1955,5.672,39.918,Indonesia 323 | 1960,5.62,42.518,Indonesia 324 | 1965,5.568,45.964,Indonesia 325 | 1970,5.3,49.203,Indonesia 326 | 1975,4.73,52.702,Indonesia 327 | 1980,4.109,56.159,Indonesia 328 | 1985,3.4,60.137,Indonesia 329 | 1990,2.9,62.681,Indonesia 330 | 1995,2.55,66.041,Indonesia 331 | 2000,2.3761,68.588,Indonesia 332 | 1955,7,47.181,Iran 333 | 1960,7,49.325,Iran 334 | 1965,6.8,52.469,Iran 335 | 1970,6.4,55.234,Iran 336 | 1975,6.5,57.702,Iran 337 | 1980,6.63,59.62,Iran 338 | 1985,5.62,63.04,Iran 339 | 1990,4.328,65.742,Iran 340 | 1995,2.534,68.042,Iran 341 | 2000,2.124,69.451,Iran 342 | 1955,7.3,48.437,Iraq 343 | 1960,7.25,51.457,Iraq 344 | 1965,7.2,54.459,Iraq 345 | 1970,7.15,56.95,Iraq 346 | 1975,6.8,60.413,Iraq 347 | 1980,6.35,62.038,Iraq 348 | 1985,6.15,65.044,Iraq 349 | 1990,5.7,59.461,Iraq 350 | 1995,5.37,58.811,Iraq 351 | 2000,4.858,57.046,Iraq 352 | 1955,3.68,68.9,Ireland 353 | 1960,3.979,70.29,Ireland 354 | 1965,3.873,71.08,Ireland 355 | 1970,3.815,71.28,Ireland 356 | 1975,3.478,72.03,Ireland 357 | 1980,2.877,73.1,Ireland 358 | 1985,2.287,74.36,Ireland 359 | 1990,1.969,75.467,Ireland 360 | 1995,1.9,76.122,Ireland 361 | 2000,1.969,77.783,Ireland 362 | 1955,3.893,67.84,Israel 363 | 1960,3.852,69.39,Israel 364 | 1965,3.79,70.75,Israel 365 | 1970,3.77,71.63,Israel 366 | 1975,3.409,73.06,Israel 367 | 1980,3.125,74.45,Israel 368 | 1985,3.051,75.6,Israel 369 | 1990,2.933,76.93,Israel 370 | 1995,2.942,78.269,Israel 371 | 2000,2.906,79.696,Israel 372 | 1955,2.35,67.81,Italy 373 | 1960,2.498,69.24,Italy 374 | 1965,2.493,71.06,Italy 375 | 1970,2.325,72.19,Italy 376 | 1975,1.889,73.48,Italy 377 | 1980,1.53,74.98,Italy 378 | 1985,1.349,76.42,Italy 379 | 1990,1.275,77.44,Italy 380 | 1995,1.213,78.82,Italy 381 | 2000,1.286,80.24,Italy 382 | 1955,5.08,62.61,Jamaica 383 | 1960,5.64,65.61,Jamaica 384 | 1965,5.78,67.51,Jamaica 385 | 1970,5,69,Jamaica 386 | 1975,4,70.11,Jamaica 387 | 1980,3.55,71.21,Jamaica 388 | 1985,3.1,71.77,Jamaica 389 | 1990,2.84,71.766,Jamaica 390 | 1995,2.67,72.262,Jamaica 391 | 2000,2.628,72.047,Jamaica 392 | 1955,2.08,65.5,Japan 393 | 1960,2.02,68.73,Japan 394 | 1965,2,71.43,Japan 395 | 1970,2.07,73.42,Japan 396 | 1975,1.81,75.38,Japan 397 | 1980,1.76,77.11,Japan 398 | 1985,1.66,78.67,Japan 399 | 1990,1.49,79.36,Japan 400 | 1995,1.39,80.69,Japan 401 | 2000,1.291,82,Japan 402 | 1955,7.816,44.686,Kenya 403 | 1960,8.12,47.949,Kenya 404 | 1965,8.12,50.654,Kenya 405 | 1970,8,53.559,Kenya 406 | 1975,7.6,56.155,Kenya 407 | 1980,7.2,58.766,Kenya 408 | 1985,6.5,59.339,Kenya 409 | 1990,5.4,59.285,Kenya 410 | 1995,5,54.407,Kenya 411 | 2000,5,50.992,Kenya 412 | 1955,3.8,54.081,South Korea 413 | 1960,3.41,56.656,South Korea 414 | 1965,4.09,59.942,South Korea 415 | 1970,3.72,63.983,South Korea 416 | 1975,2.58,67.159,South Korea 417 | 1980,2.93,69.1,South Korea 418 | 1985,2.45,70.647,South Korea 419 | 1990,2.35,69.978,South Korea 420 | 1995,2.0938,67.727,South Korea 421 | 2000,1.9173,66.662,South Korea 422 | 1955,6.332,52.681,North Korea 423 | 1960,5.63,55.292,North Korea 424 | 1965,4.708,57.716,North Korea 425 | 1970,4.281,62.612,North Korea 426 | 1975,2.919,64.766,North Korea 427 | 1980,2.234,67.123,North Korea 428 | 1985,1.601,69.81,North Korea 429 | 1990,1.696,72.244,North Korea 430 | 1995,1.514,74.647,North Korea 431 | 2000,1.242,77.045,North Korea 432 | 1955,5.72,59.489,Lebanon 433 | 1960,5.689,62.094,Lebanon 434 | 1965,5.336,63.87,Lebanon 435 | 1970,4.78,65.421,Lebanon 436 | 1975,4.311,66.099,Lebanon 437 | 1980,3.895,66.983,Lebanon 438 | 1985,3.313,67.926,Lebanon 439 | 1990,3,69.292,Lebanon 440 | 1995,2.695,70.265,Lebanon 441 | 2000,2.319,71.028,Lebanon 442 | 1955,6.8,55.19,Mexico 443 | 1960,6.7495,58.299,Mexico 444 | 1965,6.7495,60.11,Mexico 445 | 1970,6.5,62.361,Mexico 446 | 1975,5.2505,65.032,Mexico 447 | 1980,4.25,67.405,Mexico 448 | 1985,3.6295,69.498,Mexico 449 | 1990,3.1905,71.455,Mexico 450 | 1995,2.6705,73.67,Mexico 451 | 2000,2.4005,74.902,Mexico 452 | 1955,3.095,72.99,Netherlands 453 | 1960,3.168,73.23,Netherlands 454 | 1965,2.797,73.82,Netherlands 455 | 1970,2.059,73.75,Netherlands 456 | 1975,1.596,75.24,Netherlands 457 | 1980,1.515,76.05,Netherlands 458 | 1985,1.555,76.83,Netherlands 459 | 1990,1.583,77.42,Netherlands 460 | 1995,1.6,78.03,Netherlands 461 | 2000,1.726,78.53,Netherlands 462 | 1955,4.07,70.26,New Zealand 463 | 1960,4.022,71.24,New Zealand 464 | 1965,3.348,71.52,New Zealand 465 | 1970,2.843,71.89,New Zealand 466 | 1975,2.178,72.22,New Zealand 467 | 1980,1.963,73.84,New Zealand 468 | 1985,2.053,74.32,New Zealand 469 | 1990,2.061,76.33,New Zealand 470 | 1995,1.952,77.55,New Zealand 471 | 2000,1.964,79.11,New Zealand 472 | 1955,6.9,37.802,Nigeria 473 | 1960,6.9,39.36,Nigeria 474 | 1965,6.9,41.04,Nigeria 475 | 1970,6.9,42.821,Nigeria 476 | 1975,6.9,44.514,Nigeria 477 | 1980,6.9,45.826,Nigeria 478 | 1985,6.834,46.886,Nigeria 479 | 1990,6.635,47.472,Nigeria 480 | 1995,6.246,47.464,Nigeria 481 | 2000,5.845,46.608,Nigeria 482 | 1955,2.837,73.44,Norway 483 | 1960,2.898,73.47,Norway 484 | 1965,2.719,74.08,Norway 485 | 1970,2.248,74.34,Norway 486 | 1975,1.81,75.37,Norway 487 | 1980,1.687,75.97,Norway 488 | 1985,1.8,75.89,Norway 489 | 1990,1.886,77.32,Norway 490 | 1995,1.853,78.32,Norway 491 | 2000,1.801,79.05,Norway 492 | 1955,6.6,45.557,Pakistan 493 | 1960,6.6,47.67,Pakistan 494 | 1965,6.6,49.8,Pakistan 495 | 1970,6.6,51.929,Pakistan 496 | 1975,6.6,54.043,Pakistan 497 | 1980,6.6,56.158,Pakistan 498 | 1985,6.66,58.245,Pakistan 499 | 1990,5.8,60.838,Pakistan 500 | 1995,4.9596,61.818,Pakistan 501 | 2000,3.9936,63.61,Pakistan 502 | 1955,6.853,46.263,Peru 503 | 1960,6.853,49.096,Peru 504 | 1965,6.56,51.445,Peru 505 | 1970,6,55.448,Peru 506 | 1975,5.378,58.447,Peru 507 | 1980,4.65,61.406,Peru 508 | 1985,4.1,64.134,Peru 509 | 1990,3.7,66.458,Peru 510 | 1995,3.0995,68.386,Peru 511 | 2000,2.7005,69.906,Peru 512 | 1955,7.13,51.334,Philippines 513 | 1960,6.85,54.757,Philippines 514 | 1965,6.5,56.393,Philippines 515 | 1970,6,58.065,Philippines 516 | 1975,5.5,60.06,Philippines 517 | 1980,4.95,62.082,Philippines 518 | 1985,4.55,64.151,Philippines 519 | 1990,4.143,66.458,Philippines 520 | 1995,3.7248,68.564,Philippines 521 | 2000,3.5436,70.303,Philippines 522 | 1955,3.29,65.77,Poland 523 | 1960,2.65,67.64,Poland 524 | 1965,2.27,69.61,Poland 525 | 1970,2.25,70.85,Poland 526 | 1975,2.26,70.67,Poland 527 | 1980,2.33,71.32,Poland 528 | 1985,2.15,70.98,Poland 529 | 1990,1.89,70.99,Poland 530 | 1995,1.478,72.75,Poland 531 | 2000,1.251,74.67,Poland 532 | 1955,3.03,61.51,Portugal 533 | 1960,3.074,64.39,Portugal 534 | 1965,2.849,66.6,Portugal 535 | 1970,2.748,69.26,Portugal 536 | 1975,2.41,70.41,Portugal 537 | 1980,1.982,72.77,Portugal 538 | 1985,1.594,74.06,Portugal 539 | 1990,1.516,74.86,Portugal 540 | 1995,1.475,75.97,Portugal 541 | 2000,1.454,77.29,Portugal 542 | 1955,8,41.5,Rwanda 543 | 1960,8.1,43,Rwanda 544 | 1965,8.2,44.1,Rwanda 545 | 1970,8.29,44.6,Rwanda 546 | 1975,8.492,45,Rwanda 547 | 1980,8.5,46.218,Rwanda 548 | 1985,8.25,44.02,Rwanda 549 | 1990,6.9,23.599,Rwanda 550 | 1995,6.0993,36.087,Rwanda 551 | 2000,6.01,43.413,Rwanda 552 | 1955,7.175,42.868,Saudi Arabia 553 | 1960,7.257,45.914,Saudi Arabia 554 | 1965,7.257,49.901,Saudi Arabia 555 | 1970,7.298,53.886,Saudi Arabia 556 | 1975,7.278,58.69,Saudi Arabia 557 | 1980,7.015,63.012,Saudi Arabia 558 | 1985,6.217,66.295,Saudi Arabia 559 | 1990,5.446,68.768,Saudi Arabia 560 | 1995,4.621,70.533,Saudi Arabia 561 | 2000,3.81,71.626,Saudi Arabia 562 | 1955,6.5,47.985,South Africa 563 | 1960,6.3,49.951,South Africa 564 | 1965,5.7,51.927,South Africa 565 | 1970,5.47,53.696,South Africa 566 | 1975,5,55.527,South Africa 567 | 1980,4.556,58.161,South Africa 568 | 1985,3.85,60.834,South Africa 569 | 1990,3.343,61.888,South Africa 570 | 1995,2.954,60.236,South Africa 571 | 2000,2.802,53.365,South Africa 572 | 1955,2.75,66.66,Spain 573 | 1960,2.89,69.69,Spain 574 | 1965,2.92,71.44,Spain 575 | 1970,2.86,73.06,Spain 576 | 1975,2.57,74.39,Spain 577 | 1980,1.89,76.3,Spain 578 | 1985,1.48,76.9,Spain 579 | 1990,1.27,77.57,Spain 580 | 1995,1.182,78.77,Spain 581 | 2000,1.287,79.78,Spain 582 | 1955,2.34,70.56,Switzerland 583 | 1960,2.51,71.32,Switzerland 584 | 1965,2.27,72.77,Switzerland 585 | 1970,1.82,73.78,Switzerland 586 | 1975,1.53,75.39,Switzerland 587 | 1980,1.53,76.21,Switzerland 588 | 1985,1.53,77.41,Switzerland 589 | 1990,1.54,78.03,Switzerland 590 | 1995,1.47,79.37,Switzerland 591 | 2000,1.415,80.62,Switzerland 592 | 1955,6.6,48.079,Turkey 593 | 1960,6.19,52.098,Turkey 594 | 1965,5.7,54.336,Turkey 595 | 1970,5.3,57.005,Turkey 596 | 1975,4.715,59.507,Turkey 597 | 1980,4.15,61.036,Turkey 598 | 1985,3.276,63.108,Turkey 599 | 1990,2.904,66.146,Turkey 600 | 1995,2.574,68.835,Turkey 601 | 2000,2.23,70.845,Turkey 602 | 1955,2.49,70.42,United Kingdom 603 | 1960,2.81,70.76,United Kingdom 604 | 1965,2.52,71.36,United Kingdom 605 | 1970,2.04,72.01,United Kingdom 606 | 1975,1.72,72.76,United Kingdom 607 | 1980,1.8,74.04,United Kingdom 608 | 1985,1.81,75.007,United Kingdom 609 | 1990,1.78,76.42,United Kingdom 610 | 1995,1.7,77.218,United Kingdom 611 | 2000,1.695,78.471,United Kingdom 612 | 1955,3.706,69.49,United States 613 | 1960,3.314,70.21,United States 614 | 1965,2.545,70.76,United States 615 | 1970,2.016,71.34,United States 616 | 1975,1.788,73.38,United States 617 | 1980,1.825,74.65,United States 618 | 1985,1.924,75.02,United States 619 | 1990,2.025,76.09,United States 620 | 1995,1.994,76.81,United States 621 | 2000,2.038,77.31,United States 622 | 1955,6.4585,57.907,Venezuela 623 | 1960,6.657,60.77,Venezuela 624 | 1965,5.9045,63.479,Venezuela 625 | 1970,4.941,65.712,Venezuela 626 | 1975,4.4685,67.456,Venezuela 627 | 1980,3.957,68.557,Venezuela 628 | 1985,3.6485,70.19,Venezuela 629 | 1990,3.25,71.15,Venezuela 630 | 1995,2.9415,72.146,Venezuela 631 | 2000,2.723,72.766,Venezuela -------------------------------------------------------------------------------- /build_a_chart/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Countries chart 6 | 7 | 8 | 9 |

Countries chart

10 |

11 | 12 |

13 |
14 | 15 |

Data courtesy of Gapminder.org

16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /build_a_chart/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | } 4 | 5 | .big-year { 6 | font-size: 100px; 7 | fill: #808080; 8 | fill-opacity: 0.25; 9 | } 10 | 11 | .country { 12 | fill: #4682B4; 13 | fill-opacity: 0.5; 14 | } 15 | 16 | .country-label { 17 | fill: #666; 18 | } 19 | 20 | .axis path, 21 | .axis line { 22 | fill: none; 23 | stroke: #666; 24 | shape-rendering: crispEdges; 25 | } 26 | 27 | .source { 28 | font-size: 6pt; 29 | } -------------------------------------------------------------------------------- /build_a_chart/main.js: -------------------------------------------------------------------------------- 1 | // set up dimensions and margins 2 | var margin = {top: 20, right: 20, bottom: 30, left: 40}, 3 | width = 960 - margin.left - margin.right, 4 | height = 500 - margin.top - margin.bottom, 5 | currentYear = 1980; 6 | 7 | // scales 8 | var x = d3.scale.linear() 9 | .range([0, width]); 10 | 11 | var y = d3.scale.linear() 12 | .range([height, 0]); 13 | 14 | // axes 15 | var xAxis = d3.svg.axis() 16 | .scale(x) 17 | .orient("bottom") 18 | .ticks(10); 19 | 20 | var yAxis = d3.svg.axis() 21 | .scale(y) 22 | .orient("left") 23 | .ticks(8); 24 | 25 | // create svg element 26 | var svg = d3.select("#chart").append("svg") 27 | .attr("width", width + margin.left + margin.right) 28 | .attr("height", height + margin.top + margin.bottom) 29 | .append("g") 30 | .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 31 | 32 | var slider = d3.select("#slider"); 33 | 34 | // create axes 35 | svg.append("g") 36 | .attr("class", "x axis") 37 | .attr("transform", "translate(0," + height + ")") 38 | .call(xAxis) 39 | .append("text") 40 | .attr("dx", width) 41 | .attr("dy", "-.3em") 42 | .style("text-anchor", "end") 43 | .text("Fertility"); 44 | 45 | svg.append("g") 46 | .attr("class", "y axis") 47 | .call(yAxis) 48 | .append("text") 49 | .attr("transform", "rotate(-90)") 50 | .attr("y", 6) 51 | .attr("dy", ".7em") 52 | .style("text-anchor", "end") 53 | .text("Life Expectancy"); 54 | 55 | var yearLabel = svg.append("text") 56 | .attr("class", "big-year") 57 | .attr("x", width/2) 58 | .attr("y", height/2) 59 | .style("text-anchor", "middle"); 60 | 61 | // country tooltip 62 | var countryLabel = svg.append("text") 63 | .attr("class", "country-label") 64 | .style({opacity: 0}); 65 | 66 | // load data 67 | d3.csv("countries.csv", function(d) { 68 | d.fertility = +d.fertility; 69 | d.life_expect = +d.life_expect; 70 | return d; 71 | }, function(error, data) { 72 | var nested = d3.nest() 73 | .key(function(d) { return d.country; }) 74 | .entries(data); 75 | 76 | nested = nested.map(function(d) { 77 | var years = {}; 78 | d.values.forEach(function(e) { 79 | years[e.year] = e; 80 | }); 81 | return { 82 | key: d.key, 83 | values: years 84 | }; 85 | }); 86 | 87 | var draw = function() { 88 | var country = svg.selectAll(".country") 89 | .data(nested, function(d) { 90 | return d.key; 91 | }); 92 | 93 | yearLabel.text(currentYear); 94 | 95 | // enter 96 | country.enter().append("circle") 97 | .attr("class", "country") 98 | .attr("r", 6); 99 | 100 | // update 101 | country 102 | .transition() 103 | .duration(500) 104 | .attr("cx", function(d) { 105 | return x(d.values[currentYear].fertility); 106 | }) 107 | .attr("cy", function(d) { 108 | return y(d.values[currentYear].life_expect); 109 | }); 110 | 111 | // interactions 112 | country.on('mouseover', function(d) { 113 | countryLabel 114 | .attr("x", x(d.values[currentYear].fertility) + 10) 115 | .attr("y", y(d.values[currentYear].life_expect) + 5) 116 | .text(d.key) 117 | .style({opacity: 1}); 118 | }); 119 | 120 | country.on('mouseout', function(d) { 121 | countryLabel.style({opacity: 0}); 122 | }); 123 | }; 124 | 125 | x.domain(d3.extent(data, function(d) { return d.fertility; })); 126 | y.domain(d3.extent(data, function(d) { return d.life_expect; })); 127 | 128 | var timeRange = d3.extent(data, function(d) { return d.year; }); 129 | 130 | slider.attr("min", timeRange[0]); 131 | slider.attr("max", timeRange[1]); 132 | slider.attr("step", 5); 133 | slider.attr("value", currentYear); 134 | slider.on("input", function() { 135 | currentYear = +this.value; 136 | draw(); 137 | }); 138 | 139 | draw(); 140 | }); 141 | -------------------------------------------------------------------------------- /d3-01.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | D3 Tutorial 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 42 | 43 | 46 | 47 | 48 | 49 | 50 |
51 | 52 |
53 |
54 |

55 | D3.js Tutorial 56 |

57 |

First Part

58 |
59 |

60 | 61 | A tutorial by Dominik Moritz (@domoritz) and Kanit "Ham" Wongsuphasawat (@kanitw) 62 | 63 |

64 |

65 | 66 | Interactive Data Lab, 67 | University of Washington 68 | 69 |

70 |

(Based on Vadim Ogievetsky and Scott Murray's work)

71 |
72 |
73 | ## Outline 74 | 75 | * Examples 76 | * Selections & Data 77 | * Transitions 78 | * Nested Selections 79 | 80 | Part 2: Interactions, scales, axes, data, layouts 81 |
82 |
83 |
84 |

Data-Driven Documents (D3)

85 |
86 | 87 |
88 |

What D3 is not

89 |
    90 |
  • Not a chart library (but it can make charts)
  • 91 |
  • Not a compatibility layer
  • 92 |
  • Not (only) about SVG or HTML or Canvas
  • 93 |
94 |
95 | 96 |
97 |

D3 is Data ↦ Elements

98 |
    99 |
  • Visualizing Data with Web Standards (HTML/SVG)
  • 100 |
  • Data ↦ Elements – constructing the DOM from Data
  • 101 |
  • In visualization, each data point has a corresponding element (graphical marks). D3 helps you maintain this mapping!
  • 102 |
103 |
104 | 105 |
106 |

Show Reels

107 | 108 |

109 | See 110 |

111 |
112 |
113 |
114 |
115 |

Selections

116 | 117 |

D3 uses CSS Selectors

118 | 119 | Single selector: 120 |

121 | #foo        //  
122 | foo         //  
123 | .foo        //  
124 | [foo=bar]   //  
125 | foo bar     //  
126 |           
127 | 128 |
129 | Multiple selectors: 130 |

131 | foo.bar     //  
132 | foo#bar     //  
133 |           
134 |
135 | 136 |
137 |

.select()

138 |
139 |

140 |

141 |
142 | 143 |
144 |

145 |

146 |
147 |
148 |
149 |

.select() + .attr(), .style()

150 |

Select and modify element properties

151 |
152 |

153 |

154 |
155 | 156 |
157 |

158 |

159 |
160 |

Note: notice chained syntax, object as argument

161 |
162 |
163 |

but .select() only selects one item!

164 | 165 |
166 |

167 |

168 |
169 | 170 |
171 |

172 |

173 |
174 |
175 |
176 |

.selectAll()

177 | 178 |
179 |

180 |

181 |
182 | 183 |
184 |

185 |

186 |
187 | 188 |

189 | See also: http://mbostock.github.io/d3/tutorial/circle.html 190 |

191 |
192 |
193 |
194 |
195 |

.data()

196 |

Data ↦ Attributes

197 |
198 |
199 |

.data()

200 |

Tell D3 that you want the selected elements to correspond to data!

201 | 202 |
203 |
204 |

205 |

206 |
207 | 208 |
209 |

210 |

211 |
212 |
213 | 214 |
215 | See in console that the selected rect selection object is an array of array that embed data in __data__ property! 216 |
217 |
218 |
219 |

Selection Object

220 |
    221 |
  • An array of arrays
  • 222 |
  • if .data() is called, __data__ of each element will contain the data mapped to that element.
  • 223 |
224 | 225 |

You should have seen this from last slide!

226 | 227 |
228 |
229 |

.data()

230 |

Data can be objects too!

231 | 232 |
233 |

234 |

235 |
236 | 237 |
238 |

239 |

240 |
241 |
242 |
243 |

.data()

244 |

What if number of data doesn't match number of items selected?

245 |
246 |

247 |

248 |
249 | 250 |
251 |

252 |

253 |
254 |
255 |
256 |

Thinking with Join

257 | 270 |

271 | DataEnterUpdateElementsExit 272 | 273 |
274 |

Calling .data() creates three arrays:

275 |
    276 |
  • enter (Data without corresponding DOM elements)
  • 277 |
  • update (DOM elements mapped to data)
  • 278 |
  • exit (DOM elements now missing data)
  • 279 |
280 |

.data() returns the update.

281 |
282 |

283 | http://bost.ocks.org/mike/join/ 284 |

285 |
286 |
287 |
288 |

.enter()

289 |
290 |

291 |

292 |
293 | 294 |
295 |

296 |

297 |
298 |
299 |
300 |

.enter()

301 |

Shorter: append, then update all together!

302 |
303 |

304 |

305 |
306 | 307 |
308 |

309 |

310 |
311 |
312 |
313 |

.enter() from scratch

314 |

This is a common way that people build visualization in D3!

315 | 316 |
317 |

318 |

319 |
320 | 321 |
322 |

323 |

324 |
325 |
326 | 327 |
328 |

.exit()

329 | 330 |
331 |

332 |

333 |
334 | 335 |
336 |

337 |

338 |
339 |
340 |
341 |
342 |
343 |

Transitions

344 |
345 |
346 |

.transition()

347 |
348 |

349 |

350 |
351 |
352 |

353 |

354 |
355 |

Note: Transitions in D3 use cubic-in-out as default easing functions. But there are others.

356 |
357 |
358 |

Nested .transition() & .delay()

359 |
360 |

361 |

362 |
363 | 364 |
365 |

366 |

367 |
368 |
369 |
370 |

Mapping Data to Elements

371 |

The default is index mapping.

372 |
373 |

374 |

375 |
376 | 377 |
378 |

379 |

380 |
381 |
382 |
383 |

Join key – .data(...,key)

384 |

A key should be a unique string.

385 |
386 |

387 |

388 |
389 | 390 |
391 |

392 |

393 |
394 |

395 | http://bost.ocks.org/mike/selection/#key 396 |

397 |
398 |
399 |

Join key – .data(...,key)

400 |

Notice how you can save lines of code with selection.call()

401 |
402 |

403 |

404 |
405 | 406 |
407 |

408 |

409 |
410 |

411 | http://bost.ocks.org/mike/selection/#key 412 |

413 |
414 |
415 |

Join key

416 |

New Data?

417 | 418 |
419 |

420 |

421 |
422 | 423 |
424 |

425 |

426 |
427 |

See even better bars transition.

428 |
429 | 430 |
431 |

See also

432 | 433 | 442 |
443 |
444 |
445 |
446 |

Nested Selections

447 |
448 |
449 |

Nested Selections

450 |
451 |

452 |

453 |
454 | 455 |
456 |

457 |

458 |
459 |
460 |
461 |

See also: How Selection Works

462 | 463 |
464 | 465 |
466 |

"Two Tables"

467 | 468 |
469 |
470 | ### More examples 471 | 472 | * [bl.ocks.org/mbostock/3887051](http://bl.ocks.org/mbostock/3887051) 473 | * [bost.ocks.org/mike/miserables/](http://bost.ocks.org/mike/miserables/) 474 |
475 |
476 | 477 |
478 |

2nd part of D3.js tutorial

479 |
480 |
481 | 482 |
483 | 484 | 485 | 486 | 487 | 542 | 543 | 544 | 545 | 546 | 547 | -------------------------------------------------------------------------------- /d3-02.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | d3 Tutorial 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 | 53 |
54 | 55 |
56 |
57 |

58 | D3.js Tutorial 59 |

60 |

Second Part

61 |
62 |

63 | 64 | A tutorial by Dominik Moritz (@domoritz) and Kanit "Ham" Wongsuphasawat (@kanitw) 65 | 66 |

67 |

68 | 69 | Interactive Data Lab, 70 | University of Washington 71 | 72 |

73 |

(Based on Vadim Ogievetsky and Scott Murray's work)

74 |
75 |
76 | ## Outline 77 | 78 | * Interactions 79 | * Scales & Axes 80 | * Tips e.g. Importing Data 81 | * Path Generators & Line Interpolators 82 | * Layouts & Maps 83 | * Let's Build a Chart & More Examples 84 |
85 |
86 |
87 |

Interactions

88 |
89 |
90 |

Event Listeners

91 |

92 | .on('mouseover',...), .on('click',...) 93 |

94 |
95 |

96 |

97 |
98 | 99 |
100 |

101 |

102 |
103 |

Note 1: :hover pseudo-selector also works with svg!

104 |

Note 2: To remove a listener, pass null as the listener. To remove all listeners for a particular event type, pass null as the listener, and .type as the type, e.g. selection.on(".foo", null).

105 |
106 |
107 |

SVG Tooltips

108 |

Last week, we did it in svg.

109 |
110 |

111 |

112 |
113 | 114 |
115 |

116 |

117 |
118 |
119 |
120 |

SVG Tooltips

121 |
122 |

123 |

124 |
125 | 126 |
127 |

128 |

129 |
130 |
131 |
132 |

HTML Tooltips

133 | 134 |

135 | See "Div Tooltip HTML" in Murray 136 |

137 |
138 |
139 |

Brushing - d3.svg.brush()

140 | 141 |

From http://bl.ocks.org/mbostock/4063663. See also Focus+Context

142 |
143 |
144 |
145 |
146 |

Scale

147 |

Domain ↦ Range

148 | 149 |
150 |
151 | So you don't have to write: 152 |

153 | function x(d) {
154 |   return d * 42 + "px";
155 | }
156 |           
157 |
158 | 159 |

160 | http://www.jeromecukier.net/blog/2011/08/11/d3-scales-and-color/ 161 |

162 |
163 | 164 |
165 |

.linear()

166 |

167 | 168 |

169 | 170 |

171 | var x = d3.scale.linear().domain([0, 10]).range([0,100]);
172 | console.log(x(-1),x(0), x(4.4), x(10), x(11)); //-10 0 44 100 110 with some rounding errors
173 | console.log(x.clamp()(-1), x.clamp()(11); // 0 100
174 |           
175 | 176 |
Source: http://www.jeromecukier.net/blog/2011/08/11/d3-scales-and-color/
177 |
178 |
179 |

Scale methods

180 |
    181 |
  • .nice() round domain to nicer numbers e.g. from [0.2014, 0.9966] to [0.2, 1] 182 |
    
    183 | d3.scale.linear().domain([0.2014,0.9966]).nice().domain() // [0.1,1]
    184 |             
    185 |
  • 186 |
  • .rangeRound() output range in integers – better for positioning marks on the screen 187 |
    
    188 | d3.scale.linear().domain([0, 10]).range([0,100])(0.1234)// 1.234
    189 | d3.scale.linear().domain([0, 10]).rangeRound([0,100])(0.1234)// 1
    190 |             
  • 191 |
  • .invert() 192 |
    
    193 |  d3.scale.linear().domain([0, 10]).range([0,100]).invert(50); //5
    194 |             
    195 |
  • 196 |
  • .ticks() return uniformly spaced ticks for your axes. (See Axes for examples)
  • 197 |
  • .clamp() limit output to range if an input outside the domain is provided
  • 198 |
199 |
200 | 201 |
202 |

Scales supports various interpolations!

203 |

Color

204 |

205 | var x = d3.scale.linear()
206 |     .domain([12, 24])
207 |     .range(["steelblue", "brown"]);
208 | x(16); // #666586
209 | x.interpolate(d3.interpolateHsl)(16); //#3cb05f
210 |           
211 |

Size

212 |

213 | var x = d3.scale.linear()
214 |     .domain([12, 24])
215 |     .range(["0px", "720px"]);
216 | x(16); // 240px
217 |           
218 |
219 | 220 |
221 |

Other Scales

222 | d3.scale.log(), d3.scale.pow(), d3.scale.quantile() 223 |
224 | 225 |
226 |

Ordinal Scales

227 |

d3.scale.ordinal()

228 | 229 |

230 | ordinal.rangePoints(interval[, padding]) – e.g. Plots 231 |

232 | 233 |

234 | ordinal.rangeBands(interval[, padding[, outerPadding]]) - e.g. Bar Chart 235 |

236 | 237 |
238 | 239 |
240 |

Categorical Color Scale

241 |

242 | .category10() 243 |

244 |

245 | #1f77b4 246 | #ff7f0e 247 | #2ca02c 248 | #d62728 249 | #9467bd 250 | #8c564b 251 | #e377c2 252 | #7f7f7f 253 | #bcbd22 254 | #17becf 255 |

256 | 257 |
258 |

259 |

260 |
261 | 262 |
263 |

264 |

265 |
266 | 267 |
268 |
269 |
270 |
271 |

SVG Axes

272 |

273 | //Create an axis for a given scale, and configure as desired.
274 | var xAxis = d3.svg.axis()
275 |     .scale(x)
276 |     .orient("bottom"); // returns a function!
277 | 
278 | svg.append("g")
279 |       .attr("class", "x axis")
280 |       .attr("transform", "translate(0," + height + ")")
281 |       .call(xAxis); //rendering axis with call
282 |

Need customization!

283 |

284 | .axis path, .axis line {
285 |   fill: none;
286 |   stroke: #000;
287 |   shape-rendering: crispEdges;
288 | }
289 | 
290 |

See Bar Chart example

291 |
292 |
293 | ## [More SVG Axes](https://github.com/mbostock/d3/wiki/SVG-Axes) 294 | 295 | [![6186172](http://bl.ocks.org/mbostock/raw/6186172/thumbnail.png)](http://bl.ocks.org/mbostock/6186172) 296 | [![5537697](http://bl.ocks.org/mbostock/raw/5537697/thumbnail.png)](http://bl.ocks.org/mbostock/5537697) 297 | [![4573883](http://bl.ocks.org/mbostock/raw/4573883/thumbnail.png)](http://bl.ocks.org/mbostock/4573883) 298 | [![4403522](http://bl.ocks.org/mbostock/raw/4403522/thumbnail.png)](http://bl.ocks.org/mbostock/4403522) 299 | [![4349486](http://bl.ocks.org/mbostock/raw/4349486/thumbnail.png)](http://bl.ocks.org/mbostock/4349486) 300 | [![3892919](http://bl.ocks.org/mbostock/raw/3892919/thumbnail.png)](http://bl.ocks.org/mbostock/3892919) 301 |
302 |
303 | ## [More SVG Axes](https://github.com/mbostock/d3/wiki/SVG-Axes) 304 | 305 | [![3371592](http://bl.ocks.org/mbostock/raw/3371592/thumbnail.png)](http://bl.ocks.org/mbostock/3371592) 306 | [![3259783](http://bl.ocks.org/mbostock/raw/3259783/thumbnail.png)](http://bl.ocks.org/mbostock/3259783) 307 | [![3212294](http://bl.ocks.org/mbostock/raw/3212294/thumbnail.png)](http://bl.ocks.org/mbostock/3212294) 308 | [![2983699](http://bl.ocks.org/mbostock/raw/2983699/thumbnail.png)](http://bl.ocks.org/mbostock/2983699) 309 | [![2996766](http://bl.ocks.org/mbostock/raw/2996766/thumbnail.png)](http://bl.ocks.org/mbostock/2996766) 310 | [![2996785](http://bl.ocks.org/mbostock/raw/2996785/thumbnail.png)](http://bl.ocks.org/mbostock/2996785) 311 | [![1849162](http://bl.ocks.org/mbostock/raw/1849162/thumbnail.png)](http://bl.ocks.org/mbostock/1849162) 312 | [![4323929](http://bl.ocks.org/mbostock/raw/4323929/thumbnail.png)](http://bl.ocks.org/mbostock/4323929) 313 |
314 |
315 | 316 |
317 |
318 |

Path Generators & Line Interpolators

319 | 320 | Charts from http://bost.ocks.org/mike/d3/workshop/#124 321 |
322 | 323 |
324 |

d3.svg.line(), d3.svg.area()

325 |

D3 provides helpers to generate SVG lines and areas.

326 |
327 |
328 |

329 |

330 |
331 | 332 |
333 |

334 |

335 |
336 |
337 |
338 | 339 |
340 |

Linear Interpolation

341 | 342 |
343 | 344 |
345 |

Step Interpolation

346 | 347 | Step-before and step-after interpolation are handy for bar charts, and for visualizing step functions (values that change instantaneously rather than gradually). 348 | 349 | 350 |
351 | 352 |
353 |

Basis Interpolation

354 | Note that with basis interpolation, the line doesn’t always go through the control point. D3 also provides cardinal and cubic monotone interpolation; the latter is generally preferred to avoid misleading. 355 | 356 |
357 | 358 |
359 | 360 |
361 |
362 |

Layouts & Maps

363 |
364 |
365 |

Pie

366 |

Many layouts are just data generators/modifier.

367 |
368 |

369 |

370 |
371 | 372 |
373 |

374 |

375 |
376 |

Source: Chapter 11 in Interactive Data Visualization for the Web by Murray

377 |
378 | 379 |
380 |

Force Directed

381 | 382 |
383 | 384 |
385 |

Pack

386 | 387 |
388 | 389 |
390 |

Tree

391 | 392 |
393 | 394 |
395 |

Treemap

396 | 397 |
398 | 399 |
400 |

Partition

401 | 402 |
403 | 404 |
405 |

Bundle

406 | 407 |
408 | 409 |
410 |

Voronoi

411 | 412 |
413 | 414 | 443 |
444 |

Maps

445 | 446 | http://bost.ocks.org/mike/map/ 447 |
448 |
449 |
450 |

Load data: d3.csv(), d3.tsv(), d3.json()

451 |

Implemented Using XMLHttpRequest

452 |

453 | var format = d3.time.format("%b %Y");
454 | 
455 | d3.csv("stocks.csv", function(d) {
456 | return {
457 |   price: +d.price,  // convert price to number
458 |   date : format.parse(d.date)
459 | };
460 | }, function(error, rows) {
461 | console.log(rows);
462 | });
463 | 
464 |

Note: A web server is required when loading external data. For example with python -m SimpleHTTPServer

465 |
Source: http://bost.ocks.org/mike/d3/workshop/#61
466 |
467 | 468 |
469 |
470 |

Useful Tips

471 |
472 |
473 | ### Useful Helpers 474 | 475 | * `max()`, `min()`, `range()`, `extent()`, `mean()`, `median()` 476 | * `keys()`, `values()` 477 | * [Arrays](https://github.com/mbostock/d3/wiki/Arrays) – Learn to use Javascript built-in + D3's [Arrays Helpers](https://github.com/mbostock/d3/wiki/Arrays)! 478 | * [SVG Helpers](https://github.com/mbostock/d3/wiki/SVG) e.g. `d3.svg.area()` 479 | * Use `window.onresize` event to resize your chart when the window is resized 480 |
481 |
482 |

Reusable d3.

483 |

Repeatable, Modifiable, Configurable, Extensible

484 | 493 |
494 |
495 |
496 |

Need in memory database?

497 | Datavore 498 | Crossfilter 499 |
500 |
501 |
502 |
503 |
504 |

Let's Build a Chart!

505 |
506 | 507 |
508 |

Use transforms to define a new origin.

509 | 510 |

It's always a good idea to sketch the transforms before you start.

511 | 512 | translate(left,top)origin 513 | 514 | From http://bost.ocks.org/mike/d3/workshop/#107 515 | 516 |
517 | 518 |
519 | Go to the example 520 |
521 | 522 |
523 | ### More Examples 524 | * https://github.com/mbostock/d3/wiki/Gallery 525 | * http://mbostock.github.io/d3/talk/20111018/ 526 | * http://bost.ocks.org/mike/map/ 527 | * http://christopheviau.com/d3list/gallery.html 528 |
529 |
530 |
531 | 532 |
533 | 534 | 535 | 536 | 537 | 592 | 593 | 594 | 595 | 596 | 597 | -------------------------------------------------------------------------------- /example/barley.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "yield": 27, 3 | "variety": "Manchuria", 4 | "year": 1931, 5 | "site": "University Farm" 6 | }, { 7 | "yield": 48.86667, 8 | "variety": "Manchuria", 9 | "year": 1931, 10 | "site": "Waseca" 11 | }, { 12 | "yield": 27.43334, 13 | "variety": "Manchuria", 14 | "year": 1931, 15 | "site": "Morris" 16 | }, { 17 | "yield": 39.93333, 18 | "variety": "Manchuria", 19 | "year": 1931, 20 | "site": "Crookston" 21 | }, { 22 | "yield": 32.96667, 23 | "variety": "Manchuria", 24 | "year": 1931, 25 | "site": "Grand Rapids" 26 | }] 27 | -------------------------------------------------------------------------------- /example/html-link.html: -------------------------------------------------------------------------------- 1 | Google.com -------------------------------------------------------------------------------- /example/html-marked.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

HTML

7 |

Basics

8 | 9 |

10 | HTML is designed for marking up text by adding tags such as <p> to create HTML elements. 11 | HTML tags begin with < and end with >. 12 | Tags often occur in pairs of opening and closing tags. 13 | Some tags such as <img> always occur alone. 14 | Those tags usually (but not required to) have trailing slash. 15 | 16 | Tags can have attributes. For example, <a> tag has href. 17 |

18 | 19 | 20 | -------------------------------------------------------------------------------- /example/html0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

HTML

7 |

Basics

8 | 9 |

10 | HTML is designed for marking up text by adding tags such as <p> to create HTML elements. 11 | HTML tags begin with < and end with >. 12 | Tags often occur in pairs of opening and closing tags. 13 | Some tags such as <img> always occur alone. 14 | Those tags usually (but not required to) have trailing slash. 15 |

16 | 17 | 18 | -------------------------------------------------------------------------------- /example/plain.html: -------------------------------------------------------------------------------- 1 | HTML 2 |

3 | Basics 4 |

5 | HTML is designed for marking up text by adding tags such as <p> to create HTML elements. HTML tags begin with < and end with >. Tags often occur in pairs of opening and closing tags. Some tags such as <img> always occur alone. Those tags usually (but not required to) have trailing slash. 6 |

7 | Tags can have attributes. For example, <a> tag has href attribute for defining link target. Similarly, <img> tag has src attribute for defining image source. 8 | 9 | -------------------------------------------------------------------------------- /frame.css: -------------------------------------------------------------------------------- 1 | body { 2 | text-align: center; } 3 | 4 | svg { 5 | font: 10px sans-serif; } 6 | 7 | text, tspan, textPath { 8 | white-space: nowrap; } 9 | 10 | user agent stylesheettext, foreignObject { 11 | display: block; } 12 | 13 | .join, .link, .node rect { 14 | fill: none; 15 | stroke: #636363; 16 | stroke-width: 1.5px; } 17 | 18 | .node .element rect { 19 | fill: #bdbdbd; 20 | stroke: none; } 21 | 22 | .link path, .node rect, .node text, .join { 23 | -webkit-transition: all 500ms linear; 24 | -moz-transition: all 500ms linear; 25 | -ms-transition: all 500ms linear; 26 | -o-transition: all 500ms linear; 27 | transition: all 500ms linear; } 28 | 29 | .node .selection rect { 30 | stroke: #e6550d; } 31 | -------------------------------------------------------------------------------- /frame.scss: -------------------------------------------------------------------------------- 1 | body{ 2 | text-align: center; 3 | } 4 | 5 | svg { 6 | font: 10px sans-serif; 7 | // text{ 8 | // fill:white; 9 | // } 10 | } 11 | 12 | 13 | text, tspan, textPath { 14 | white-space: nowrap; 15 | } 16 | user agent stylesheettext, foreignObject { 17 | display: block; 18 | } 19 | 20 | .node rect { 21 | // fill: white; 22 | } 23 | .join, .link, .node rect { 24 | fill: none; 25 | stroke: #636363; 26 | stroke-width: 1.5px; 27 | } 28 | 29 | .node .element rect { 30 | fill: #bdbdbd; 31 | stroke: none; 32 | text{ 33 | // color:white; 34 | } 35 | } 36 | 37 | .link path, .node rect, .node text, .join { 38 | -webkit-transition: all 500ms linear; 39 | -moz-transition: all 500ms linear; 40 | -ms-transition: all 500ms linear; 41 | -o-transition: all 500ms linear; 42 | transition: all 500ms linear; 43 | } 44 | 45 | .node .selection rect { 46 | stroke: #e6550d; 47 | } -------------------------------------------------------------------------------- /frame/selection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 37 | -------------------------------------------------------------------------------- /img/__data__.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/__data__.png -------------------------------------------------------------------------------- /img/box-model.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/box-model.gif -------------------------------------------------------------------------------- /img/bundle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/bundle.png -------------------------------------------------------------------------------- /img/d3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/d3.png -------------------------------------------------------------------------------- /img/d3ordinalRange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/d3ordinalRange.png -------------------------------------------------------------------------------- /img/d3scale1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/d3scale1.png -------------------------------------------------------------------------------- /img/grid-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/grid-crop.png -------------------------------------------------------------------------------- /img/pack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/pack.png -------------------------------------------------------------------------------- /img/partition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/partition.png -------------------------------------------------------------------------------- /img/range-bands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/range-bands.png -------------------------------------------------------------------------------- /img/range-point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/range-point.png -------------------------------------------------------------------------------- /img/the-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/the-grid.png -------------------------------------------------------------------------------- /img/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/tree.png -------------------------------------------------------------------------------- /img/treemap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/treemap.png -------------------------------------------------------------------------------- /img/voronoi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/img/voronoi.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | D3 Tutorial by the Interactive Data Lab, University of Washington 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 38 | 41 | 42 | 43 | 44 |
45 | 46 | 47 |
48 |
49 |

50 | Visualizing Data with D3.js 51 |

52 |

53 | 54 | Compiled by Kanit Wongsuphasawat and Dominik Moritz
55 | for the Data Visualization Course at University of Washington 56 |
57 |

58 |
59 |

60 | Technology fundamentals 61 |

62 |

63 | D3.js (1st part) 64 |

65 |

66 | D3.js (2nd part) 67 |

68 | 69 |

70 | Spring 2016 live demo, and slides. 71 |

72 | 73 |
74 | 75 |
76 | 77 |
78 | 79 | 80 | 81 | 82 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /js/chart.js: -------------------------------------------------------------------------------- 1 | function interpolateChart() { 2 | var width = 900, 3 | height = 500; 4 | 5 | var n = 36, 6 | random = d3.random.normal(height / 3 * 2, 50), 7 | data = d3.range(n).map(random); 8 | 9 | var x = d3.scale.linear() 10 | .domain([0, n - 1]) 11 | .range([0, width]); 12 | 13 | var area = d3.svg.area() 14 | .x(function(d, i) { return x(i); }) 15 | .y0(height) 16 | .y1(Number) 17 | 18 | function chart(selection) { 19 | selection.each(function(d) { 20 | 21 | var svg = d3.select(this).selectAll("svg") 22 | .data([null]); 23 | 24 | var svgEnter = svg.enter().append("svg") 25 | .datum(data) 26 | .attr("class", "interpolate chart") 27 | .attr("width", width) 28 | .attr("height", height); 29 | 30 | svgEnter.append("rect") 31 | .attr("class", "background") 32 | .attr("width", width) 33 | .attr("height", height) 34 | .style("pointer-events", "all"); 35 | 36 | svgEnter.append("path") 37 | .attr("class", "area"); 38 | 39 | svgEnter.selectAll("circle") 40 | .data(data) 41 | .enter().append("circle") 42 | .attr("r", 6); 43 | 44 | svg.selectAll("circle") 45 | .attr("cx", function(d, i) { return x(i); }) 46 | .attr("cy", Number); 47 | 48 | svg.select("path") 49 | .attr("d", area); 50 | }); 51 | } 52 | 53 | function mousemove(d) { 54 | var m = d3.mouse(this), 55 | i = Math.floor(x.invert(m[0])); 56 | d[i] = m[1] % height; // XXX webkit-transform-3d 57 | var svg = d3.select(this); 58 | svg.selectAll("circle").data(d).attr("cy", Number); 59 | svg.select("path").attr("d", area); 60 | } 61 | 62 | return d3.rebind(chart, area, "interpolate"); 63 | } -------------------------------------------------------------------------------- /js/selection.js: -------------------------------------------------------------------------------- 1 | /* global d3*/ 2 | 3 | var tutorial = tutorial || {}; 4 | tutorial.selection = (function(){ 5 | // var numbers = [4, 5, 18, 23, 42]; 6 | 7 | // var letters = [ 8 | // {name: "A", frequency: .08167}, 9 | // {name: "B", frequency: .01492}, 10 | // {name: "C", frequency: .02780}, 11 | // {name: "D", frequency: .04253}, 12 | // {name: "E", frequency: .12702} 13 | // ]; 14 | 15 | // var vowels = [ 16 | // {name: "A", frequency: .08167}, 17 | // {name: "E", frequency: .12702}, 18 | // {name: "I", frequency: .06973}, 19 | // {name: "O", frequency: .07507}, 20 | // {name: "U", frequency: .02758} 21 | // ]; 22 | 23 | // var matrix = [ 24 | // [ 0, 1, 2, 3], 25 | // [ 4, 5, 6, 7], 26 | // [ 8, 9, 10, 11], 27 | // [12, 13, 14, 15] 28 | // ]; 29 | 30 | function name(d) { 31 | return d.name; 32 | } 33 | 34 | var margin = window.svgMargin || {top: 0, right: 40, bottom: 0, left: 40}, 35 | width = window.svgWidth || 500, 36 | step = 100; 37 | 38 | var tree = function(container){ 39 | container = container || "body"; 40 | 41 | return function (leftRoot, rightRoot, outerHeight) { 42 | if (arguments.length < 3){ 43 | outerHeight = rightRoot; rightRoot = null; 44 | } 45 | 46 | var height = outerHeight - margin.top - margin.bottom; 47 | 48 | var tree = d3.layout.tree() 49 | .size([height, 1]) 50 | .separation(function() { return 1; }); 51 | 52 | var svg = d3.select(container).append("svg") 53 | .attr("width", width + margin.left + margin.right) 54 | .attr("height", height + margin.top + margin.bottom) 55 | .style("margin", "1em 0 1em " + -margin.left + "px"); 56 | 57 | var g = svg.selectAll("g") 58 | .data([].concat( 59 | leftRoot ? {type: "left", nodes: tree.nodes(leftRoot)} : [], 60 | rightRoot ? {type: "right", nodes: tree.nodes(rightRoot).map(flip), flipped: true} : [] 61 | )) 62 | .enter().append("g") 63 | .attr("class", function(d) { return d.type; }) 64 | .attr("transform", function(d) { return "translate(" + (!!d.flipped * width + margin.left) + "," + margin.top + ")"; }); 65 | 66 | var link = g.append("g") 67 | .attr("class", "link") 68 | .selectAll("path") 69 | .data(function(d) { return tree.links(d.nodes); }) 70 | .enter().append("path") 71 | .attr("class", linkType); 72 | 73 | var node = g.append("g") 74 | .attr("class", "node") 75 | .selectAll("g") 76 | .data(function(d) { return d.nodes; }) 77 | .enter().append("g") 78 | .attr("class", function(d) { return d.type; }); 79 | 80 | node.append("rect"); 81 | 82 | node.append("text") 83 | .attr("dy", ".35em") 84 | .text(function(d) { return d.name; }) 85 | .each(function(d) { d.width = Math.max(32, this.getComputedTextLength() + 12); }) 86 | .attr("x", function(d) { return d.flipped ? 6 - d.width : 6; }); 87 | 88 | node.filter(function(d) { return "join" in d; }).insert("path", "text") 89 | .attr("class", "join"); 90 | 91 | svg.call(reset); 92 | 93 | function flip(d) { 94 | d.depth *= -1; 95 | d.flipped = true; 96 | return d; 97 | } 98 | 99 | return svg; 100 | }; 101 | }; 102 | 103 | function linkType(d) { 104 | return d.target.type.split(/\s+/).map(function(t) { return "to-" + t; }) 105 | .concat(d.source.type.split(/\s+/).map(function(t) { return "from-" + t; })) 106 | .join(" "); 107 | } 108 | 109 | function reset(svg) { 110 | svg.selectAll("*") 111 | .style("stroke-opacity", null) 112 | .style("fill-opacity", null) 113 | .style("display", null); 114 | 115 | var node = svg.selectAll(".node g") 116 | .attr("class", function(d) { return d.type; }) 117 | .attr("transform", function(d, i) { return "translate(" + d.depth * step + "," + d.x + ")"; }); 118 | 119 | node.select("rect") 120 | .attr("ry", 6) 121 | .attr("rx", 6) 122 | .attr("y", -10) 123 | .attr("height", 20) 124 | .attr("width", function(d) { return d.width; }) 125 | .filter(function(d) { return d.flipped; }) 126 | .attr("x", function(d) { return -d.width; }); 127 | 128 | node.select(".join") 129 | .attr("d", d3.svg.diagonal() 130 | .source(function(d) { return {y: d.width, x: 0}; }) 131 | .target(function(d) { return {y: 88, x: d.join * 24}; }) 132 | .projection(function(d) { return [d.y, d.x]; })); 133 | 134 | svg.selectAll(".link path") 135 | .attr("class", linkType) 136 | .attr("d", d3.svg.diagonal() 137 | .source(function(d) { return {y: d.source.depth * step + (d.source.flipped ? -1 : +1) * d.source.width, x: d.source.x}; }) 138 | .target(function(d) { return {y: d.target.depth * step, x: d.target.x}; }) 139 | .projection(function(d) { return [d.y, d.x]; })); 140 | } 141 | 142 | function selectAllAnimation(startRoot, startHeight, endRoot, endHeight) { 143 | var end = tree(endRoot, endHeight).remove(), 144 | event = d3.dispatch("start", "middle", "end", "reset"), 145 | height = +end.attr("height"), 146 | start = tree(startRoot, startHeight).attr("height", height), 147 | svg = start.node(), 148 | offset = (endHeight - startHeight) / 2, 149 | transform = "translate(" + margin.left + "," + offset + ")"; 150 | 151 | var play = start.append("g") 152 | .attr("class", "play"); 153 | 154 | play.append("circle") 155 | .attr("r", 45) 156 | .attr("transform", "translate(" + (margin.left + width / 2) + "," + height / 2 + ")"); 157 | 158 | play.append("path") 159 | .attr("d", "M-22,-30l60,30l-60,30z") 160 | .attr("transform", "translate(" + (margin.left + width / 2) + "," + height / 2 + ")scale(.7)"); 161 | 162 | play.append("rect") 163 | .attr("width", width) 164 | .attr("height", height) 165 | .on("mousedown", function() { 166 | play.classed("mousedown", true); 167 | d3.select(window).on("mouseup", function() { play.classed("mousedown", false); }); 168 | }) 169 | .on("click", function() { 170 | resetAll(); 171 | animation(); 172 | }); 173 | 174 | end = d3.select(svg.appendChild(end.node().firstChild)); 175 | start = d3.select(svg.firstChild).attr("transform", transform); 176 | end.selectAll(".array").each(function() { this.parentNode.appendChild(this); }); // mask elements 177 | 178 | var startNodes = start.datum().nodes, 179 | startElements = startNodes.filter(function(d) { return d.type === "element"; }), 180 | endNodes = end.datum().nodes, 181 | endGroups = endNodes.filter(function(d) { return d.type === "array"; }); 182 | 183 | resetAll(); 184 | 185 | return event; 186 | 187 | function resetAll() { 188 | start.style("display", "none").call(reset); 189 | end.style("display", null).call(reset); 190 | play.style("display", null); 191 | event.reset(); 192 | } 193 | 194 | function animation() { 195 | start.call(fadeIn, 150); 196 | end.style("display", "none"); 197 | play.style("display", "none"); 198 | setTimeout(transition1, 1250); 199 | event.start(); 200 | } 201 | 202 | function transition1() { 203 | var t = start.transition() 204 | .duration(1000 + (startElements.length - 1) * 50) 205 | .each("end", transition2); 206 | 207 | t.selectAll(".selection,.array,.link") 208 | .duration(0) 209 | .style("stroke-opacity", 0) 210 | .style("fill-opacity", 0); 211 | 212 | t.selectAll(".element") 213 | .duration(500) 214 | .delay(function(d, i) { return 500 + i * 50; }) 215 | .attr("transform", function(d, i) { return "translate(" + (d.depth - 1) * step + "," + (endGroups[i].x - offset) + ")"; }) 216 | .attr("class", "array") 217 | .select("rect") 218 | .attr("width", function(d, i) { return endGroups[i].width; }); 219 | 220 | event.middle(); 221 | } 222 | 223 | function transition2() { 224 | end.style("display", null) 225 | .selectAll(".element,.to-element") 226 | .style("display", "none"); 227 | 228 | end.selectAll(".selection,.to-array,.array") 229 | .call(fadeIn); 230 | 231 | end.transition() 232 | .duration(500) 233 | .each("end", transition3); 234 | 235 | event.end(); 236 | } 237 | 238 | function transition3() { 239 | start.style("display", "none"); 240 | 241 | end.selectAll(".element") 242 | .style("display", null) 243 | .attr("transform", function(d) { return "translate(" + d.parent.depth * step + "," + d.parent.x + ")"; }) 244 | .transition() 245 | .duration(500) 246 | .delay(function(d, i) { return i * 50; }) 247 | .attr("transform", function(d) { return "translate(" + d.depth * step + "," + d.x + ")"; }); 248 | 249 | end.selectAll(".to-element") 250 | .style("display", null) 251 | .attr("d", d3.svg.diagonal() 252 | .source(function(d) { return {y: d.source.depth * step + d.source.width, x: d.source.x}; }) 253 | .target(function(d, i) { return {y: d.source.depth * step + d.source.width, x: d.source.x}; }) 254 | .projection(function(d) { return [d.y, d.x]; })) 255 | .transition() 256 | .duration(500) 257 | .delay(function(d, i) { return i * 50; }) 258 | .attr("d", d3.svg.diagonal() 259 | .source(function(d) { return {y: d.source.depth * step + d.source.width, x: d.source.x}; }) 260 | .target(function(d, i) { return {y: d.target.depth * step, x: d.target.x}; }) 261 | .projection(function(d) { return [d.y, d.x]; })); 262 | 263 | end.transition() 264 | .duration(2000) 265 | .each("end", resetAll); 266 | } 267 | } 268 | 269 | function updateAnimation(leftRoot, rightRoot, endRoot, outerHeight) { 270 | var start = tree(leftRoot, rightRoot, outerHeight), 271 | left = d3.select(start.node().firstChild), 272 | right = d3.select(left.node().nextSibling), 273 | end = tree(endRoot, outerHeight).remove(), 274 | height = +start.attr("height"); 275 | 276 | end = d3.select(start.node().appendChild(end.node().firstChild)); 277 | left.selectAll(".element").each(function() { this.parentNode.appendChild(this); }); // mask keys 278 | right.selectAll(".datum").each(function() { this.parentNode.appendChild(this); }); // mask keys 279 | start.node().appendChild(left.node()); 280 | start.node().appendChild(right.node()); 281 | 282 | var leftKeys = left.datum().nodes.filter(function(d) { return d.type === "key"; }), 283 | rightKeys = right.datum().nodes.filter(function(d) { return d.type === "key"; }), 284 | endElements = end.datum().nodes.filter(function(d) { return d.parent && d.parent.type === "array"; }); 285 | 286 | leftKeys.forEach(function(l, i) { 287 | if ("join" in l) { 288 | rightKeys[i + l.join].joined = true; 289 | endElements[i + l.join].start = l.parent; 290 | l.parent.end = endElements[i + l.join]; 291 | } 292 | }); 293 | 294 | leftKeys.forEach(function(l, i) { 295 | if (!("join" in l)) endElements.some(function(e) { 296 | if (!e.start) { 297 | e.start = l.parent; 298 | l.parent.end = e; 299 | return true; 300 | } 301 | }); 302 | }); 303 | 304 | var play = start.append("g") 305 | .attr("class", "play"); 306 | 307 | play.append("circle") 308 | .attr("r", 45) 309 | .attr("transform", "translate(" + (margin.left + width / 2) + "," + height / 2 + ")"); 310 | 311 | play.append("path") 312 | .attr("d", "M-22,-30l60,30l-60,30z") 313 | .attr("transform", "translate(" + (margin.left + width / 2) + "," + height / 2 + ")scale(.7)"); 314 | 315 | play.append("rect") 316 | .attr("width", width) 317 | .attr("height", height) 318 | .on("mousedown", function() { 319 | play.classed("mousedown", true); 320 | d3.select(window).on("mouseup", function() { play.classed("mousedown", false); }); 321 | }) 322 | .on("click", function() { 323 | resetAll(); 324 | animation(); 325 | }); 326 | 327 | resetAll(); 328 | 329 | function resetAll() { 330 | play.style("display", null); 331 | left.style("display", "none").call(reset); 332 | right.style("display", "none").call(reset); 333 | right.selectAll(".key").classed("joined", function(d) { return d.joined; }); 334 | right.selectAll(".datum").classed("joined", function(d) { return d.children[0].joined; }); 335 | right.selectAll(".to-key").classed("joined", function(d) { return d.target.joined; }); 336 | end.call(reset); 337 | } 338 | 339 | function animation() { 340 | play.style("display", "none"); 341 | end.style("display", "none"); 342 | left.call(fadeIn); 343 | right.call(fadeIn); 344 | setTimeout(transition1, 1250); 345 | } 346 | 347 | function transition1() { 348 | left.selectAll(".key").filter(function(d) { return !("join" in d); }) 349 | .style("stroke-opacity", 0) 350 | .style("fill-opacity", 0); 351 | 352 | left.selectAll(".to-key").filter(function(d) { return !("join" in d.target); }) 353 | .style("stroke-opacity", 0) 354 | .style("fill-opacity", 0); 355 | 356 | left.selectAll(".element").filter(function(d) { return !("join" in d.children[0]); }) 357 | .style("stroke-opacity", 0) 358 | .style("fill-opacity", 0); 359 | 360 | left.selectAll(".to-element").filter(function(d) { return !("join" in d.target.children[0]); }) 361 | .style("stroke-opacity", 0) 362 | .style("fill-opacity", 0); 363 | 364 | right.selectAll(".link > :not(.joined),.node > :not(.joined)") 365 | .style("stroke-opacity", 0) 366 | .style("fill-opacity", 0); 367 | 368 | end.style("display", null); 369 | 370 | end.selectAll(".datum,.to-datum") 371 | .style("display", "none"); 372 | 373 | end.selectAll(".element,.null") 374 | .attr("transform", function(d, i) { return "translate(" + d.depth * step + "," + d.start.x + ")"; }); 375 | 376 | end.selectAll(".to-element,.to-null") 377 | .attr("d", d3.svg.diagonal() 378 | .source(function(d) { return {y: d.source.depth * step + d.source.width, x: d.source.x}; }) 379 | .target(function(d) { return {y: d.target.depth * step, x: d.target.start.x}; }) 380 | .projection(function(d) { return [d.y, d.x]; })); 381 | 382 | setTimeout(transition2, 500); 383 | } 384 | 385 | function transition2() { 386 | left.selectAll(".element").transition() 387 | .duration(500) 388 | .attr("transform", function(d, i) { return "translate(" + d.depth * step + "," + d.end.x + ")"; }); 389 | 390 | left.selectAll(".key").transition() 391 | .duration(500) 392 | .attr("transform", function(d, i) { return "translate(" + d.depth * step + "," + d.parent.end.x + ")"; }); 393 | 394 | left.selectAll(".to-element").transition() 395 | .duration(500) 396 | .attr("d", d3.svg.diagonal() 397 | .source(function(d) { return {y: d.source.depth * step + d.source.width, x: d.source.x}; }) 398 | .target(function(d) { return {y: d.target.depth * step, x: d.target.end.x}; }) 399 | .projection(function(d) { return [d.y, d.x]; })); 400 | 401 | left.selectAll(".to-key").transition() 402 | .duration(500) 403 | .attr("d", d3.svg.diagonal() 404 | .source(function(d) { return {y: d.source.depth * step + d.source.width, x: d.source.end.x}; }) 405 | .target(function(d) { return {y: d.target.depth * step, x: d.target.parent.end.x}; }) 406 | .projection(function(d) { return [d.y, d.x]; })); 407 | 408 | left.selectAll(".join").transition() 409 | .duration(500) 410 | .attr("d", d3.svg.diagonal() 411 | .source(function(d) { return {y: d.width, x: 0}; }) 412 | .target(function(d) { return {y: 88, x: 0}; }) 413 | .projection(function(d) { return [d.y, d.x]; })); 414 | 415 | end.selectAll(".element,.null").transition() 416 | .duration(500) 417 | .attr("transform", function(d, i) { return "translate(" + d.depth * step + "," + d.x + ")"; }); 418 | 419 | end.selectAll(".to-element,.to-null").transition() 420 | .duration(500) 421 | .attr("d", d3.svg.diagonal() 422 | .source(function(d) { return {y: d.source.depth * step + d.source.width, x: d.source.x}; }) 423 | .target(function(d) { return {y: d.target.depth * step, x: d.target.x}; }) 424 | .projection(function(d) { return [d.y, d.x]; })); 425 | 426 | setTimeout(transition3, 500); 427 | } 428 | 429 | function transition3() { 430 | var offset = 12; 431 | 432 | left.selectAll(".join").transition() 433 | .duration(500) 434 | .attr("d", d3.svg.diagonal() 435 | .source(function(d) { return {y: d.width, x: 0}; }) 436 | .target(function(d) { return {y: d.width, x: 0}; }) 437 | .projection(function(d) { return [d.y, d.x]; })); 438 | 439 | left.selectAll(".to-key") 440 | .attr("class", "from-element to-datum"); 441 | 442 | right.selectAll(".to-key").transition() 443 | .duration(500) 444 | .attr("d", d3.svg.diagonal() 445 | .source(function(d) { return {y: (d.source.depth - 2) * step + offset - d.source.width, x: d.source.x}; }) 446 | .target(function(d) { return {y: (d.source.depth - 2) * step + offset - d.source.width, x: d.source.x}; }) 447 | .projection(function(d) { return [d.y, d.x]; })); 448 | 449 | right.selectAll(".key").transition() 450 | .duration(500) 451 | .attr("transform", function(d, i) { return "translate(" + ((d.depth - 1) * step + offset) + "," + d.x + ")"; }); 452 | 453 | right.selectAll(".datum").transition() 454 | .duration(500) 455 | .attr("transform", function(d, i) { return "translate(" + ((d.depth - 2) * step + offset) + "," + d.x + ")"; }); 456 | 457 | setTimeout(resetAll, 2000); 458 | } 459 | } 460 | 461 | function exitAnimation(leftRoot, rightRoot, endRoot, outerHeight) { 462 | var start = tree(leftRoot, rightRoot, outerHeight), 463 | left = d3.select(start.node().firstChild), 464 | right = d3.select(left.node().nextSibling), 465 | end = tree(endRoot, outerHeight).remove(), 466 | height = +start.attr("height"); 467 | 468 | end = d3.select(start.node().appendChild(end.node().firstChild)); 469 | start.node().appendChild(left.node()); 470 | start.node().appendChild(right.node()); 471 | 472 | var play = start.append("g") 473 | .attr("class", "play"); 474 | 475 | play.append("circle") 476 | .attr("r", 45) 477 | .attr("transform", "translate(" + (margin.left + width / 2) + "," + height / 2 + ")"); 478 | 479 | play.append("path") 480 | .attr("d", "M-22,-30l60,30l-60,30z") 481 | .attr("transform", "translate(" + (margin.left + width / 2) + "," + height / 2 + ")scale(.7)"); 482 | 483 | play.append("rect") 484 | .attr("width", width) 485 | .attr("height", height) 486 | .on("mousedown", function() { 487 | play.classed("mousedown", true); 488 | d3.select(window).on("mouseup", function() { play.classed("mousedown", false); }); 489 | }) 490 | .on("click", function() { 491 | resetAll(); 492 | animation(); 493 | }); 494 | 495 | resetAll(); 496 | 497 | function resetAll() { 498 | play.style("display", null); 499 | left.style("display", "none").call(reset); 500 | right.style("display", "none").call(reset); 501 | end.call(reset); 502 | } 503 | 504 | function animation() { 505 | play.style("display", "none"); 506 | end.style("display", "none"); 507 | left.call(fadeIn); 508 | right.call(fadeIn); 509 | setTimeout(transition1, 1250); 510 | } 511 | 512 | function transition1() { 513 | end.style("display", null); 514 | 515 | left 516 | .style("stroke-opacity", 0) 517 | .style("fill-opacity", 0); 518 | 519 | right 520 | .style("stroke-opacity", 0) 521 | .style("fill-opacity", 0); 522 | 523 | setTimeout(resetAll, 2000); 524 | } 525 | } 526 | 527 | function enterAnimation(leftRoot, rightRoot, endRoot, outerHeight) { 528 | var start = tree(leftRoot, rightRoot, outerHeight), 529 | left = d3.select(start.node().firstChild), 530 | right = d3.select(left.node().nextSibling), 531 | end = tree(endRoot, outerHeight).remove(), 532 | height = +start.attr("height"); 533 | 534 | start.node().appendChild(left.node()); 535 | start.node().appendChild(right.node()); 536 | end = d3.select(start.node().appendChild(end.node().firstChild)); 537 | 538 | var leftKeys = left.datum().nodes.filter(function(d) { return d.type === "key"; }), 539 | rightKeys = right.datum().nodes.filter(function(d) { return d.type === "key"; }); 540 | 541 | leftKeys.forEach(function(l, i) { 542 | if ("join" in l) { 543 | rightKeys[i + l.join].joined = true; 544 | } 545 | }); 546 | 547 | var play = start.append("g") 548 | .attr("class", "play"); 549 | 550 | play.append("circle") 551 | .attr("r", 45) 552 | .attr("transform", "translate(" + (margin.left + width / 2) + "," + height / 2 + ")"); 553 | 554 | play.append("path") 555 | .attr("d", "M-22,-30l60,30l-60,30z") 556 | .attr("transform", "translate(" + (margin.left + width / 2) + "," + height / 2 + ")scale(.7)"); 557 | 558 | play.append("rect") 559 | .attr("width", width) 560 | .attr("height", height) 561 | .on("mousedown", function() { 562 | play.classed("mousedown", true); 563 | d3.select(window).on("mouseup", function() { play.classed("mousedown", false); }); 564 | }) 565 | .on("click", function() { 566 | resetAll(); 567 | animation(); 568 | }); 569 | 570 | resetAll(); 571 | 572 | function resetAll() { 573 | play.style("display", null); 574 | left.style("display", "none").call(reset); 575 | right.style("display", "none").call(reset); 576 | right.selectAll(".key").classed("joined", function(d) { return d.joined; }); 577 | right.selectAll(".datum").classed("joined", function(d) { return d.children[0].joined; }); 578 | right.selectAll(".to-key").classed("joined", function(d) { return d.target.joined; }); 579 | end.call(reset); 580 | } 581 | 582 | function animation() { 583 | play.style("display", "none"); 584 | end.style("display", "none"); 585 | left.call(fadeIn); 586 | right.call(fadeIn); 587 | setTimeout(transition1, 1250); 588 | } 589 | 590 | function transition1() { 591 | end.style("display", null); 592 | 593 | end.selectAll(".element,.datum,.to-datum") 594 | .style("stroke-opacity", 0) 595 | .style("fill-opacity", 0); 596 | 597 | left.selectAll(".element,.to-element,.key,.to-key") 598 | .style("stroke-opacity", 0) 599 | .style("fill-opacity", 0); 600 | 601 | right.selectAll(".array,.to-array,.data,.to-function,.to-datum,.joined") 602 | .style("stroke-opacity", 0) 603 | .style("fill-opacity", 0); 604 | 605 | setTimeout(transition2, 750); 606 | } 607 | 608 | function transition2() { 609 | var offset = 12; 610 | 611 | right.selectAll(".key:not(.joined)").transition() 612 | .duration(500) 613 | .attr("transform", function(d, i) { return "translate(" + ((d.depth - 2) * step + offset) + "," + d.x + ")"; }); 614 | 615 | right.selectAll(".datum:not(.joined)").transition() 616 | .duration(500) 617 | .attr("transform", function(d, i) { return "translate(" + ((d.depth - 2) * step + offset) + "," + d.x + ")"; }); 618 | 619 | right.selectAll(".to-key:not(.joined)").transition() 620 | .duration(500) 621 | .attr("d", d3.svg.diagonal() 622 | .source(function(d) { return {y: (d.source.depth - 2) * step + offset - d.source.width, x: d.source.x}; }) 623 | .target(function(d) { return {y: (d.source.depth - 3) * step + offset - d.source.width, x: d.source.x}; }) 624 | .projection(function(d) { return [d.y, d.x]; })); 625 | 626 | setTimeout(transition3, 500); 627 | } 628 | 629 | function transition3() { 630 | right.selectAll(".to-key:not(.joined)") 631 | .style("stroke-opacity", 0); 632 | 633 | end.selectAll(".element,.datum,.to-datum") 634 | .style("stroke-opacity", 1) 635 | .style("fill-opacity", 1); 636 | 637 | setTimeout(resetAll, 2000); 638 | } 639 | } 640 | 641 | function fadeIn(selection, delay) { 642 | selection 643 | .style("display", null) 644 | .style("stroke-opacity", 0) 645 | .style("fill-opacity", 0) 646 | .transition() 647 | .duration(delay || 0) 648 | .style("stroke-opacity", 1) 649 | .style("fill-opacity", 1); 650 | } 651 | 652 | return { 653 | tree: tree 654 | }; 655 | })(); -------------------------------------------------------------------------------- /live.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/live.zip -------------------------------------------------------------------------------- /live/1-begin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 20 | 21 | 22 | 23 | 24 |

D3 Example

25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /live/10-transitions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 311 | 312 | 313 | -------------------------------------------------------------------------------- /live/11-csv.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 249 | 250 | 251 | -------------------------------------------------------------------------------- /live/12-exit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 286 | 287 | 288 | -------------------------------------------------------------------------------- /live/13-final.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 289 | 290 | 291 | -------------------------------------------------------------------------------- /live/2-svg.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 20 | 21 | 22 | 23 | 24 |

D3 Example

25 | 26 | 27 | 28 | 29 | Allen, Miss. Elisabeth Walton 30 | 31 | 32 | 33 | Allison, Master. Hudson Trevor 34 | 35 | 36 | 37 | 38 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /live/3-selection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 20 | 21 | 22 | 23 | 24 |

D3 Example

25 | 26 | 27 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /live/4-binding.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /live/5-scales1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 20 | 21 | 22 | 23 | 24 |

D3 Example

25 | 26 | 27 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /live/6-scales2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 20 | 21 | 22 | 23 | 24 |

D3 Example

25 | 26 | 27 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /live/7-axes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /live/8-legends.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 301 | 302 | 303 | -------------------------------------------------------------------------------- /live/9-events.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 310 | 311 | 312 | -------------------------------------------------------------------------------- /live/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D3 Example 6 | 27 | 28 | 29 | 30 | 31 |

D3 Example

32 | 33 | 34 | 289 | 290 | 291 | -------------------------------------------------------------------------------- /live/info.js: -------------------------------------------------------------------------------- 1 | var infoText = { 2 | "index": "

Titanic Passenger Visualization

This is a D3 scatterplot showing information about sampled passengers aboard the titanic.

Tutorial

We provide a step-by-step walkthrough of how to produce this visualization here. The info tab describes useful information for each step. For more information, see these slides.

", 3 | "1-begin": "

index.html

We can start by defining a simple web page, which has a header (h1) and an svg element that will hold our visualization. In the style tags, we can add CSS styling for both elements defined in the HTML.

", 4 | "2-svg": "

Manually Adding Elements

We can manually add elements to the DOM, and specify properties such as the x and y position, and the title (which appears as a tooltip on hover). Elements can be added directly to the svg element, or to svg groups. They will inherit the properties of their parent group (like location and orientation). Keep in mind that the origin for positioning elements is the upper left corner.

", 5 | "3-selection": "

Selecting an Element

d3.select() and d3.selectAll() can be used to select DOM elements by name, class, id, or many other css selectors. d3.select() selects only the first element that matches the css selectors while d3.selectAll() selects all matched elements.

Both methods return a D3 selection. We can use, access, and modify the properties of the selected elements using methods such as .attr(), .text(), .style(). Most D3 selection methods return the selection, allowing us to chain the operator calls.

Through append(), we can add new elements anywhere in the DOM. We can then use operators or CSS to set the properties of the element. We can also get rid of elements with remove(). Finally, we can store selections in variables for future use.

In this case, we select our svg element to update the width and height, and we programmatically append circles to the visualization from our data.

", 6 | "4-binding": "

Data Binding

We can use the data() function to bind data to a selection or access the data that belongs to a selection.

Enter/Update Pipeline

In this case, we now have an enter/update pipeline.

(1) We start by selectAll circles on which to bind our data. We call this selection scatter.

(2) Then, we select the enter set and append new circles as needed. For each of these new circles, we also append our title.

(3) Next, we use enter.merge(scatter) to merge* our enter elements into our update elements, and perform additional updates.

* Note: merge is new to D3v4.

", 7 | "5-scales1": "

Specifying Scales

Scales are functions that map from a domain to a range (for instance, from the data domain to the domain of the chart). For more information on D3 scales, check out this blog post.

Anonymous functions can be used to parameterize the element's attributes using the element's data. Anonymous functions can have two parameters d (our bound datum) and i (the index of our datum). An example anonymous function is used for the cx attribute of the circles.

", 8 | "6-scales2": "

More Scale Types

d3.scaleLinear create a linear mapping. You can also have d3.scaleLog, d3.scaleSqrt, and so on. You can also specify ordinal (which include nominal data types) and temporal scales. Note that the range() does not have to be a set of numbers; it can also be colors or strings (for example, the c and s scales).

Note: d3.scaleLinear is new to D3v4 and replaces d3.scale.linear. This is true for all of these camelCase method names.

", 9 | "7-axes": "

Axes

Axes can be generated based on the scales in your visualization. Axes are defined based on their position using d3.axisTop, d3.axisBottom, d3.axisRight, or d3.axisLeft. Note: each of these constructors is a function; to create our axis, we create or select the element where we want to place it, and then use call() to apply the function to it. For more information on call(), see this page.

", 10 | "8-legends": "

Legends

Legends can be constructed just like the other elements of your visualization: by creating a new set of marks and using scales to style the attributes. In addition to the rect for the legend mark, we can append text to create the legend labels.

", 11 | "9-events": "

Reacting to Events

Event listeners can be added to marks to react to events on the underlying selection using the on() method. The on() method takes the event name and a callback function that is triggered every time the specified event happens. An anonymous function can be used as the callback for the event listener. The input to the function d represents the underlying data of the mark. The scope, this, corresponds to the DOM element.

For example, here we add two event listeners for mouseover and mouseout to the circles in the enter set.

", 12 | "10-transitions": "

Using Transitions

Transitions can be used on the properties by including .transition(). Any property updates that occur after this call are applied as a transition. duration defines how long the transition should take and delay introduces a lag in when the updates occur from when they are triggered. The transitions use the previous properties of the element as the starting point and update to the desired values.

For example, here we add .transition() to the merged selection to update the circle properties.

", 13 | "11-csv": "

Loading Data

Data can be loaded from many types of external files using commands such as d3.csv, d3.json, d3.tsv. The D3 functions additionally support callback functions for dealing with the resulting data or error cases.

", 14 | "12-exit": "

Removing Data

In this step, we allow the viewer to sample a new passenger and upate the visualization to remove the oldest passenger and replace it with a new one. Is the behavior now what you would expect to see?

Highlight all the text or triple click below to see the answer.

", 15 | "13-final": "

Removing Data - CORRECTED

To remove data correctly, we use a function named key to provide each data point with a unique key value that is used to bind data to elements. Now, when data is added/removed, the DOM elements for the circle is added and removed appropriately.

See the previous step for an example of an incorrect data binding.

Tutorial Feedback

If you have feedback on this tutorial, please fill out this survey. Thank you!

" 16 | }; -------------------------------------------------------------------------------- /live/viewer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 115 | 116 | 117 | 193 | 194 | 195 | 196 | 197 |
198 |
199 | Code 200 | Info 201 |
202 |
203 | 204 |
205 |
206 | 210 |
211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /other resources/d3 Cheat Sheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uwdata/d3-tutorials/0429f6fc30d44e47125b37897e73e87592aa4b8e/other resources/d3 Cheat Sheet.pdf -------------------------------------------------------------------------------- /sass.css: -------------------------------------------------------------------------------- 1 | /* variable, operator */ 2 | body { 3 | font: 80% Helvetica, sans-serif; 4 | color: #333333; } 5 | 6 | /* nesting */ 7 | nav ul { 8 | margin: 0; 9 | padding: 0; 10 | list-style: none; } 11 | nav li { 12 | display: inline-block; } 13 | nav a { 14 | display: block; 15 | padding: 6px 12px; 16 | text-decoration: none; } 17 | 18 | /* mixin */ 19 | .box { 20 | -webkit-border-radius: 10px; 21 | -moz-border-radius: 10px; 22 | -ms-border-radius: 10px; 23 | -o-border-radius: 10px; 24 | border-radius: 10px; } 25 | -------------------------------------------------------------------------------- /sass.scss: -------------------------------------------------------------------------------- 1 | /* variable, operator */ 2 | 3 | $font-stack: Helvetica, sans-serif; 4 | $primary-color: #333; 5 | 6 | body { 7 | font: 0.8*100% $font-stack; 8 | color: $primary-color; 9 | } 10 | 11 | /* nesting */ 12 | nav { 13 | ul { 14 | margin: 0; 15 | padding: 0; 16 | list-style: none; 17 | } 18 | 19 | li { display: inline-block; } 20 | 21 | a { 22 | display: block; 23 | padding: 6px 12px; 24 | text-decoration: none; 25 | } 26 | } 27 | 28 | /* mixin */ 29 | 30 | @mixin border-radius($radius) { 31 | -webkit-border-radius: $radius; 32 | -moz-border-radius: $radius; 33 | -ms-border-radius: $radius; 34 | -o-border-radius: $radius; 35 | border-radius: $radius; 36 | } 37 | 38 | .box { @include border-radius(10px); } -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /* Theme */ 2 | 3 | .reveal { 4 | font-size: 30px; 5 | font-family: Avenir, Helvetica Neue, Helvetica, Arial; 6 | } 7 | 8 | .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 { 9 | font-family: Avenir, Helvetica Neue, Helvetica, Arial; 10 | text-transform: none; 11 | text-align: center; 12 | } 13 | 14 | .white { 15 | background-color: white; 16 | } 17 | 18 | .red { 19 | color: rgb(255, 150, 150); 20 | } 21 | 22 | .source { 23 | opacity: 0.7; 24 | } 25 | 26 | .reveal .slides { 27 | text-align: left; 28 | } 29 | 30 | .center { 31 | text-align: center; 32 | } 33 | 34 | .left-align { 35 | text-align: left; 36 | } 37 | 38 | .chart { 39 | position: absolute; 40 | top: 0; 41 | left: 0; 42 | } 43 | 44 | .chart .background { 45 | fill: none; 46 | } 47 | 48 | .axis path, .axis line { 49 | fill: none; 50 | stroke: #fff; 51 | shape-rendering: crispEdges; 52 | } 53 | 54 | .axis text { 55 | fill: #fff; 56 | font-size: 18px; 57 | } 58 | 59 | .axis.minor, 60 | .axis.minor text { 61 | display: none; 62 | } 63 | 64 | .chart .bar, 65 | .chart .dot, 66 | .chart .line { 67 | fill: none; 68 | stroke: #000; 69 | stroke-width: 1.5px; 70 | } 71 | 72 | .chart .bar, 73 | .chart .dot, 74 | .chart .area { 75 | fill: #6baed6; 76 | } 77 | 78 | .interpolate.chart circle { 79 | fill: #fd8d3c; 80 | stroke: #000; 81 | stroke-width: 1.5px; 82 | } 83 | 84 | 85 | /* Code */ 86 | .reveal pre { 87 | margin: 0; 88 | box-shadow: none; 89 | width: 100%; 90 | } 91 | 92 | .reveal pre code { 93 | color: #E0E2E4; 94 | background: #282B2E; 95 | } 96 | 97 | iframe { 98 | background-color: #222; 99 | } 100 | 101 | .left{ 102 | float:left; 103 | width:50%; 104 | text-align: center; 105 | } 106 | .right{ 107 | float:left; 108 | width:50%; 109 | text-align: center; 110 | } 111 | 112 | .reveal .left pre, .reveal .right pre{ 113 | margin: 0; 114 | } 115 | 116 | .reveal .left pre code, .reveal .right pre code{ 117 | padding:3px; 118 | } 119 | 120 | .reveal pre code { 121 | word-wrap: break-word; 122 | max-height: 500px; 123 | } 124 | 125 | pre .typeparam{ 126 | color: #fcba8f; 127 | } 128 | 129 | .right iframe{ 130 | width:100%; 131 | } 132 | 133 | .see-also{ 134 | font-size: 50%; 135 | } 136 | 137 | .overflow-y{ 138 | overflow-y: scroll; 139 | } 140 | 141 | .block, .reveal small.block{ 142 | display: block; 143 | } --------------------------------------------------------------------------------