├── LICENSE ├── README.md ├── ch1 ├── bar-charts │ ├── index.html │ └── js │ │ ├── excanvas.min.js │ │ └── flotr2.min.js ├── bubble-charts │ ├── img │ │ └── gulf.png │ ├── index.html │ └── js │ │ ├── excanvas.min.js │ │ └── flotr2.min.js ├── custom-charts │ ├── index.html │ └── js │ │ ├── excanvas.min.js │ │ └── flotr2.min.js ├── line-charts │ ├── index.html │ └── js │ │ ├── excanvas.min.js │ │ └── flotr2.min.js ├── pie-charts │ ├── index.html │ └── js │ │ ├── excanvas.min.js │ │ └── flotr2.min.js ├── radar-charts │ ├── index.html │ └── js │ │ ├── excanvas.min.js │ │ └── flotr2.min.js └── scatter-charts │ ├── index.html │ └── js │ ├── excanvas.min.js │ └── flotr2.min.js ├── ch2 ├── data-via-ajax │ ├── index.html │ └── js │ │ └── excanvas.min.js ├── selecting-content │ ├── index.html │ └── js │ │ └── excanvas.min.js ├── tracking-values │ ├── index.html │ └── js │ │ └── excanvas.min.js └── zooming │ ├── index.html │ └── js │ ├── excanvas.min.js │ └── jquery.flot.selection.js ├── ch3 ├── annotations │ ├── index.html │ └── js │ │ └── excanvas.min.js ├── classic-sparkline │ ├── index.html │ └── js │ │ └── excanvas.min.js ├── click-events │ ├── index.html │ └── js │ │ └── excanvas.min.js ├── composite-charts │ ├── index.html │ └── js │ │ └── excanvas.min.js └── small-multiples │ ├── index.html │ └── js │ └── excanvas.min.js ├── ch4 ├── gantt-charts │ ├── css │ │ └── jquery.gantt.css │ ├── img │ │ ├── grid.png │ │ ├── icon_sprite.png │ │ ├── loader_bg.png │ │ └── slider_handle.png │ ├── index.html │ └── js │ │ ├── excanvas.min.js │ │ └── jquery.fn.gantt.min.js ├── graphs │ ├── index.html │ └── js │ │ ├── sigma.layout.forceAtlas2.min.js │ │ └── sigma.min.js ├── heat-maps │ ├── font │ │ ├── digital7-webfont.eot │ │ ├── digital7-webfont.ttf │ │ ├── digital7-webfont.woff │ │ └── digital7.css │ ├── img │ │ └── basketball.png │ ├── index.html │ └── js │ │ ├── excanvas.min.js │ │ └── heatmap-mod.js ├── tree-maps │ ├── index.html │ └── js │ │ ├── raphael-min.js │ │ └── treemap-squared-0.5.min.js └── word-clouds │ ├── index.html │ └── wordcloud2.js ├── ch5 ├── chronoline │ ├── css │ │ ├── chronoline.css │ │ ├── jquery.qtip.css │ │ └── sprites.png │ ├── index.html │ └── js │ │ ├── chronoline.js │ │ ├── jquery.min.js │ │ ├── jquery.qtip.js │ │ └── raphael-min.js ├── javascript │ └── index.html └── timelinejs │ ├── css │ ├── fancybox_sprite.png │ ├── fancybox_sprite@2x.png │ ├── loading.gif │ ├── timeline.css │ ├── timeline.png │ └── timeline@2x.png │ ├── index.html │ └── js │ ├── jquery.min.js │ └── timeline.js ├── ch6 └── leaflet │ ├── css │ ├── leaflet.css │ └── normalize.css │ ├── images │ ├── layers-2x.png │ ├── layers.png │ ├── marker-icon-2x.png │ ├── marker-icon.png │ └── marker-shadow.png │ ├── index.html │ └── js │ └── leaflet.js ├── ch7 ├── chart │ └── index.html ├── force │ ├── data.json │ └── index.html ├── map │ ├── index.html │ ├── tornadoes.csv │ └── us-states.json └── sunburst │ ├── index.html │ └── tornadoes.csv └── running ├── .bowerrc ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .yo-rc.json ├── Gruntfile.js ├── app ├── 404.html ├── data │ └── runs.json ├── favicon.ico ├── index.html ├── robots.txt ├── scripts │ ├── collections │ │ └── runs.js │ ├── main.js │ ├── models │ │ └── run.js │ ├── routes │ │ └── app.js │ ├── templates │ │ ├── charts.ejs │ │ ├── details.ejs │ │ ├── map.ejs │ │ ├── properties.ejs │ │ ├── summary.ejs │ │ └── summaryRow.ejs │ └── views │ │ ├── charts.js │ │ ├── details.js │ │ ├── map.js │ │ ├── properties.js │ │ ├── summary.js │ │ └── summaryRow.js └── styles │ └── main.css ├── bower.json └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Stephen A Thomas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jsDataV.is-source 2 | ================= 3 | 4 | This repository contains source code for data visualizations on the [jsDataV.is](http://jsDataV.is) site, including those used as examples in the book [_Data Visualization with JavaScript_](http://www.nostarch.com/datavisualization). All code is available under MIT license and can be freely used without attribution (though attribution is always welcome). 5 | 6 | > Note: Chapters 8, 9, and 10 in the print and ebook versions (appendices A and B in the online version) are combined in a single `running` folder. 7 | -------------------------------------------------------------------------------- /ch1/bar-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 54 | 55 | -------------------------------------------------------------------------------- /ch1/bubble-charts/img/gulf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch1/bubble-charts/img/gulf.png -------------------------------------------------------------------------------- /ch1/bubble-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 14 |

Hurricane Katrina 2005: Course and Wind Strength

15 |
16 |

Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA.

17 | 18 | 19 | 20 | 133 | 134 | -------------------------------------------------------------------------------- /ch1/custom-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 152 | 153 | -------------------------------------------------------------------------------- /ch1/line-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 150 | 151 | -------------------------------------------------------------------------------- /ch1/pie-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 41 | 42 | -------------------------------------------------------------------------------- /ch1/radar-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 78 | 79 | -------------------------------------------------------------------------------- /ch1/scatter-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 106 | 107 | -------------------------------------------------------------------------------- /ch2/data-via-ajax/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 122 | 123 | -------------------------------------------------------------------------------- /ch2/selecting-content/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 15 | 16 | 17 | 18 | 19 |
20 |
Gross Domestic Product (Current US$ in Trillions)
21 |
22 |
23 |

Select Regions to Include:

24 |
25 |
26 | 27 | 28 | 29 | 30 | 91 | 92 | -------------------------------------------------------------------------------- /ch2/zooming/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 61 | 62 | -------------------------------------------------------------------------------- /ch3/annotations/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |
 
14 |
15 |
16 |
17 |
18 |
19 | 20 | 21 | 22 | 23 | 116 | 117 | -------------------------------------------------------------------------------- /ch3/classic-sparkline/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |

11 | 12 | 170,134,115,128,168,166,122,81,56,39,97,114,114,130,151, 13 | 184,148,145,134,145,145,145,143,148,224,181,112,111,129, 14 | 151,131,131,131,114,112,112,112,124,187,202,200,203,237, 15 | 263,221,197,184,185,203,290,330,330,226,113,148,169,148, 16 | 78,96,96,96,77,59,22,22,70,110,128 17 | 18 | 128 19 | Glucose 20 |

21 | 22 | 23 | 24 | 25 | 39 | 40 | -------------------------------------------------------------------------------- /ch3/click-events/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 14 | 17 | 18 | 19 | 20 | 21 | 108 | 109 | -------------------------------------------------------------------------------- /ch3/composite-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |
 
14 |
15 |
16 |
17 |
18 |
19 | 20 | 21 | 22 | 23 | 137 | 138 | -------------------------------------------------------------------------------- /ch3/small-multiples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 |
SymbolCompany2012 PerformanceAnnual Gain (Loss)
AAPLApple Inc.418.68,416.11,416.6,443.34,455.63,489.08,497.7,517.81,540.38,540.37,580.42,590.8,594.27,628.1,599.9,567.94,597.69,560.27,561.72,525.71,557.34,556.05,575.21,569.08,576.98,578.86,600.55,599.64,598.98,580.01,610.28,618.87,645.16,660.2,662.22,677.35,688.14,696.91,664.07,649.62,626.85,607.07,601.25,574.18,547.06,527.68,571.5,585.28,533.25,509.79,519.33,509.59,532.1727%
ALTRAltera Corporation37.1,36.92,39.93,39.81,40.43,39.76,39.73,38.55,36.89,37.68,39.18,38.47,39.49,37.85,37.17,34.95,35.26,33.4,33.53,33.03,34.21,32.09,33.29,32.86,33.24,33.64,32.54,31.16,31.04,35.82,35.58,37,36.23,36.23,37.21,37.85,38.03,36.62,33.89,33.32,32.22,32.4,30.3,30.41,30.64,30.45,31.86,32.39,31.58,32.86,34.5,34.01,34.39(7%)
BMYBristol Meyers Squibb Co.32.86,32.46,31.36,31.01,30.98,30.64,31.81,31.31,31.3,31.61,31.87,31.65,32.41,32.67,31.57,33.21,32.32,32.37,32.12,31.74,32.1,32.33,33.34,33.21,34.3,34.88,33.9,34.64,34.69,35.31,31.97,31.07,30.92,31.9,32.33,32.61,32.55,32.92,33.05,33.28,32.73,33.45,33.26,32.82,31.88,31.37,32.27,32.28,32.21,32.38,32.21,31.56,32.24(2%)
BRKABerkshire Hathaway Inc.114500,116520,119775,119211,119800,117980,119190,120000,117434,119065,122190,122170,121900,121295,118385,118580,120925,121950,122795,119850,119500,119845,122000,123375,122670,124945,123898,126625,125730,127735,128479,127175,128880,128225,126560,129942,133000,134584,132700,135555,132502,133841,129725,130550,127585,129345,132606,131916,131090,133795,134800,133000,13406017%
COPConocoPhillips52.95,51.26,51.89,50.58,51.35,52.65,53.95,55.85,57.1,56.74,56.76,56.26,55.9,55.42,54.15,53.59,52.93,51.29,51.61,49.65,50.91,50.01,52.73,54.18,52.18,54.59,53.49,53.71,55.34,54.34,55.07,56.62,56.73,55.71,56.14,55.99,57.54,56.7,56.52,56.92,56.17,57.45,57.31,57.65,55.67,55.03,56.67,56.94,57.94,57.69,58.61,57.07,57.9910%
CTXSCitrix Systems, Inc.62.02,64.85,68.12,65.14,68.78,71.46,74.77,75.16,75.43,76.27,78.2,77.68,78.91,78.28,75.12,77.78,85.78,82.85,79.46,74.82,75.43,70.79,77.12,80.12,80.14,83.94,77.45,76.63,80.75,77.81,72.44,76.26,78.08,77,77.69,80.59,81.74,81.19,76.53,71.57,67.7,64.16,62.82,62.77,60.17,59.21,61.77,61.16,62.03,65.02,66.15,64.3,65.626%
CVXChevron Corporation104.78,102.63,103.4,100.57,102.06,101.85,103.97,106.33,106.85,106.81,107.5,103.68,104.51,102.11,98.24,99.94,103.52,101.11,100.1,96.84,97.24,94.83,99.18,102.62,98.79,103.77,103.34,104.27,107.4,107.47,109.3,111.69,111.7,111.05,111.2,113.03,116.25,116.79,115.56,116.5,111.11,112.41,110.23,107.44,104.94,102.4,105.47,105.69,106.99,107.82,109.71,106.45,108.143%
FFord Motor Company11.5,11.82,12.36,12.03,12.6,12.26,12.57,12.05,12.54,12.4,12.33,12.14,12.3,12.29,11.75,11.24,11.43,10.56,10.47,9.91,10.49,10.02,10.55,10.24,10.09,9.49,9.4,9.18,9.12,8.91,9.05,9.3,9.58,9.44,9.29,10.09,10.48,10.35,9.81,10.11,10.07,10.13,10.31,11.17,10.93,10.5,11.1,11.45,11.48,11.1,11.86,12.87,12.9513%
FNMAFederal National Mortgage Association0.2,0.23,0.24,0.23,0.24,0.3,0.38,0.32,0.32,0.32,0.31,0.31,0.29,0.28,0.27,0.29,0.28,0.27,0.3,0.27,0.27,0.26,0.26,0.26,0.26,0.26,0.25,0.24,0.24,0.24,0.24,0.28,0.24,0.25,0.25,0.24,0.28,0.28,0.28,0.28,0.27,0.27,0.27,0.27,0.28,0.27,0.28,0.27,0.27,0.27,0.26,0.26,0.2630%
GEGeneral Electric Company18.03,18.21,18.51,18.39,18.38,18.25,18.64,18.76,18.5,18.57,19.7,19.29,19.57,19.01,18.41,18.88,19.29,18.86,18.54,18.48,18.72,18.08,18.72,19.5,19.48,20.5,19.67,19.44,19.54,20.57,20.61,20.75,20.65,20.46,20.37,21.23,21.74,22.33,22.5,22.91,22.28,21.83,20.92,21.12,20.81,19.97,20.85,20.94,21.27,21.42,20.88,20.44,20.9916%
GLWCorning Incorporated13.18,13.64,14.05,12.3,13.23,13.25,13.49,13.4,12.73,13.02,14.04,13.74,13.8,13.27,13.31,12.91,14.16,13.39,13.04,12.49,12.65,12.43,12.94,12.82,12.67,12.74,12.61,12.14,12.09,11.36,11.18,11.4,11.82,11.35,11.89,12.45,13.01,13.11,13.04,13.19,12.88,13.41,11.72,11.61,11.25,10.9,11.29,12.23,12.54,12.62,12.6,12.47,12.62(4%)
GMGeneral Motors Company22.92,24.29,25,24.37,26.18,25.5,27.34,26.07,26.45,25.62,25.57,25.17,25.65,24.81,23.8,23.6,23.53,22.36,22,21.18,22.44,22.01,22.05,21.74,20.6,19.72,20.31,19.62,19.36,19.67,20.04,20.54,22.01,21.18,21.35,23.37,24.14,24.8,22.75,24.8,24.44,24.59,23.28,25.79,25.04,23.85,25.21,25.88,25.19,24.61,27.32,27.85,28.8326%
HPQHewlett-Packard Company25.67,25.76,27.35,27.11,28.27,27.91,28.77,25.9,24.62,23.51,23.93,23.09,23.29,22.58,24.01,23.95,24.19,23.72,22.62,20.97,21.82,20.77,21.8,21.27,20.02,19.77,19.24,18.66,18.29,18.25,17.95,19.37,19.19,17.28,16.59,17.12,18,17.42,16.9,14.59,14.27,14.34,13.96,13.63,13.48,12.73,12.32,12.87,13.81,14.75,14.34,13.68,14.25(44%)
QCOMQUALCOMM, Inc.55.28,55.65,56.83,56.88,60.1,60.76,61.54,62.45,61.66,63.14,64.61,65.86,67.22,66.36,65.85,61.49,63.39,61.15,61.1,55.29,56.62,54.68,58.29,56.05,55.19,55.23,54.87,54.54,57.22,58.86,59.76,61.48,62.78,61.93,60.97,61.69,64.62,64.02,62.22,62.39,58.66,58.52,58.81,59.07,61.38,61.69,62.88,63.37,63.86,59.83,61.61,60.64,61.8612%
TERTeradyne, Inc.14.63,14.84,16.14,16.95,17.03,16.5,17.01,16.38,16.11,16.21,17.05,16.82,16.89,16.42,16.29,16.3,17.39,16.13,15.71,14.32,14.79,13.61,14.38,14.46,14.31,14.06,13.67,13.21,13.64,14.97,14.8,15.59,15.94,15.74,15.62,16.28,16.43,14.6,14.22,14.07,13.62,14.12,14.5,15.31,15.51,15.03,15.93,15.64,15.84,16.49,16.75,16.42,16.8915%
TSLATesla Motors Inc26.91,22.79,26.6,29.33,31.15,31.1,34.97,33.75,34.04,34.74,35.32,34.08,37.24,34.48,33.59,33.16,33.34,31.83,32.25,27.56,29.81,28.15,30.08,29.91,33.79,31.29,30.99,34.25,31.79,29.51,27.27,29.94,30.01,29.5,28.52,29.35,30.39,30.02,29.28,28.89,27.64,27.74,27.38,28.92,30.32,31.84,32.13,33.82,34.17,33.81,34,33.22,33.8726%
WMTWal-Mart Stores, Inc.57.58,58.11,59.54,59.25,60.54,60.41,60.98,57.38,57.59,59.03,59.77,59.68,60.13,59.61,58.72,61.35,57.99,57.67,58.77,61.75,64.6,64.84,67.48,67.01,66.57,68.96,70.58,72.38,71.46,73.71,73.74,73.27,71.59,71.71,72.2,73.41,74.09,74.04,73.39,74.72,75.39,75.2,74.7,72.37,71.91,67.65,69.81,71.62,72.29,68.75,68.65,67.61,68.2318%
XOMExxon Mobil Corporation83.01,82.78,85.33,83.71,82.82,82.17,83.96,85.65,84.66,82.67,84.76,83.89,85.05,83.17,81.34,83.65,84.41,82.93,82.05,80.44,81.04,76.94,79.82,82.17,81.07,84.49,83.73,84.39,84.86,86.34,86.44,87.89,87.85,87.5,86.76,89.36,91.73,91.35,90.88,91.97,90.46,91.58,90.06,89.71,87.21,86.45,89.09,88.14,88.6,88.08,87.23,85.1,86.554%
130 | 131 | 132 | 133 | 134 | 153 | 154 | -------------------------------------------------------------------------------- /ch4/gantt-charts/css/jquery.gantt.css: -------------------------------------------------------------------------------- 1 | .gantt, .gantt2 { 2 | width: 100%; 3 | margin: 20px auto; 4 | border: 14px solid #ddd; 5 | -webkit-border-radius: 6px; 6 | -moz-border-radius: 6px; 7 | border-radius: 6px; 8 | -webkit-box-sizing: border-box; 9 | -moz-box-sizing: border-box; 10 | box-sizing: border-box; 11 | } 12 | 13 | .gantt:after { 14 | content: "."; 15 | visibility: hidden; 16 | display: block; 17 | height: 0; 18 | clear: both; 19 | } 20 | 21 | .fn-gantt { 22 | width: 100%; 23 | } 24 | 25 | .fn-gantt .fn-content { 26 | overflow: hidden; 27 | position: relative; 28 | width: 100%; 29 | } 30 | 31 | 32 | 33 | 34 | /* === LEFT PANEL === */ 35 | 36 | .fn-gantt .leftPanel { 37 | float: left; 38 | width: 225px; 39 | overflow: hidden; 40 | border-right: 1px solid #DDD; 41 | position: relative; 42 | z-index: 20; 43 | } 44 | 45 | .fn-gantt .row { 46 | float: left; 47 | height: 24px; 48 | line-height: 24px; 49 | margin-left: -24px; 50 | } 51 | 52 | .fn-gantt .leftPanel .fn-label { 53 | display: inline-block; 54 | margin: 0 0 0 5px; 55 | color: #484A4D; 56 | width: 110px; 57 | white-space: nowrap; 58 | text-overflow: ellipsis; 59 | overflow: hidden; 60 | } 61 | 62 | .fn-gantt .leftPanel .row0 { 63 | border-top: 1px solid #DDD; 64 | } 65 | .fn-gantt .leftPanel .name, .fn-gantt .leftPanel .desc { 66 | float: left; 67 | height: 23px; 68 | margin: 0; 69 | border-bottom: 1px solid #DDD; 70 | background-color: #f6f6f6; 71 | } 72 | 73 | .fn-gantt .leftPanel .name { 74 | width: 110px; 75 | font-weight: bold; 76 | } 77 | 78 | .fn-gantt .leftPanel .desc { 79 | width: 115px; 80 | } 81 | 82 | .fn-gantt .leftPanel .fn-wide, .fn-gantt .leftPanel .fn-wide .fn-label { 83 | width: 225px; 84 | } 85 | 86 | .fn-gantt .spacer { 87 | margin: -2px 0 1px 0; 88 | border-bottom: none; 89 | background-color: #f6f6f6; 90 | } 91 | 92 | 93 | 94 | 95 | /* === RIGHT PANEL === */ 96 | 97 | .fn-gantt .rightPanel { 98 | overflow: hidden; 99 | } 100 | 101 | .fn-gantt .dataPanel { 102 | margin-left: 0px; 103 | border-right: 1px solid #DDD; 104 | background-image: url(../img/grid.png); 105 | background-repeat: repeat; 106 | background-position: 24px 24px; 107 | } 108 | .fn-gantt .day, .fn-gantt .date { 109 | overflow: visible; 110 | width: 24px; 111 | line-height: 24px; 112 | text-align: center; 113 | border-left: 1px solid #DDD; 114 | border-bottom: 1px solid #DDD; 115 | margin: -1px 0 0 -1px; 116 | font-size: 11px; 117 | color: #484a4d; 118 | text-shadow: 0 1px 0 rgba(255,255,255,0.75); 119 | text-align: center; 120 | } 121 | 122 | .fn-gantt .holiday { 123 | background-color: #ffd263; 124 | height: 23px; 125 | margin: 0 0 -1px -1px; 126 | } 127 | 128 | .fn-gantt .today { 129 | background-color: #fff8da; 130 | height: 23px; 131 | margin: 0 0 -1px -1px; 132 | font-weight: bold; 133 | text-align: center; 134 | } 135 | 136 | .fn-gantt .sa, .fn-gantt .sn, .fn-gantt .wd { 137 | height: 23px; 138 | margin: 0 0 0 -1px; 139 | text-align: center; 140 | } 141 | 142 | .fn-gantt .sa, .fn-gantt .sn { 143 | color: #939496; 144 | background-color: #f5f5f5; 145 | text-align: center; 146 | } 147 | 148 | .fn-gantt .wd { 149 | background-color: #f6f6f6; 150 | text-align: center; 151 | } 152 | 153 | .fn-gantt .rightPanel .month, .fn-gantt .rightPanel .year { 154 | float: left; 155 | overflow: hidden; 156 | border-left: 1px solid #DDD; 157 | border-bottom: 1px solid #DDD; 158 | height: 23px; 159 | margin: 0 0 0 -1px; 160 | background-color: #f6f6f6; 161 | font-weight: bold; 162 | font-size: 11px; 163 | color: #484a4d; 164 | text-shadow: 0 1px 0 rgba(255,255,255,0.75); 165 | text-align: center; 166 | } 167 | 168 | .fn-gantt-hint { 169 | border: 5px solid #edc332; 170 | background-color: #fff5d4; 171 | padding: 10px; 172 | position: absolute; 173 | display: none; 174 | z-index: 11; 175 | -webkit-border-radius: 4px; 176 | -moz-border-radius: 4px; 177 | border-radius: 4px; 178 | } 179 | 180 | .fn-gantt .bar { 181 | background-color: #D0E4FD; 182 | height: 18px; 183 | margin: 4px 3px 3px 3px; 184 | position: absolute; 185 | z-index: 10; 186 | text-align: center; 187 | -webkit-box-shadow: 0 0 1px rgba(0,0,0,0.25) inset; 188 | -moz-box-shadow: 0 0 1px rgba(0,0,0,0.25) inset; 189 | box-shadow: 0 0 1px rgba(0,0,0,0.25) inset; 190 | -webkit-border-radius: 3px; 191 | -moz-border-radius: 3px; 192 | border-radius: 3px; 193 | } 194 | 195 | .fn-gantt .bar .fn-label { 196 | line-height: 18px; 197 | font-weight: bold; 198 | white-space: nowrap; 199 | width: 100%; 200 | text-overflow: ellipsis; 201 | overflow: hidden; 202 | text-shadow: 0 1px 0 rgba(255,255,255,0.4); 203 | color: #414B57 !important; 204 | text-align: center; 205 | font-size: 11px; 206 | } 207 | 208 | .fn-gantt .ganttRed { 209 | background-color: #F9C4E1; 210 | } 211 | .fn-gantt .ganttRed .fn-label { 212 | color: #78436D !important; 213 | } 214 | 215 | .fn-gantt .ganttGreen { 216 | background-color: #D8EDA3; 217 | } 218 | .fn-gantt .ganttGreen .fn-label { 219 | color: #778461 !important; 220 | } 221 | 222 | .fn-gantt .ganttOrange { 223 | background-color: #FCD29A; 224 | } 225 | .fn-gantt .ganttOrange .fn-label { 226 | color: #714715 !important; 227 | } 228 | 229 | 230 | /* === BOTTOM NAVIGATION === */ 231 | 232 | .fn-gantt .bottom { 233 | clear: both; 234 | background-color: #f6f6f6; 235 | width: 100%; 236 | } 237 | .fn-gantt .navigate { 238 | border-top: 1px solid #DDD; 239 | padding: 10px 0 10px 225px; 240 | } 241 | 242 | .fn-gantt .navigate .nav-slider { 243 | height: 20px; 244 | display: inline-block; 245 | } 246 | 247 | .fn-gantt .navigate .nav-slider-left, .fn-gantt .navigate .nav-slider-right { 248 | text-align: center; 249 | height: 20px; 250 | display: inline-block; 251 | } 252 | 253 | .fn-gantt .navigate .nav-slider-left { 254 | float: left; 255 | } 256 | 257 | .fn-gantt .navigate .nav-slider-right { 258 | float: right; 259 | } 260 | 261 | .fn-gantt .navigate .nav-slider-content { 262 | text-align: left; 263 | width: 160px; 264 | height: 20px; 265 | display: inline-block; 266 | margin: 0 10px; 267 | } 268 | 269 | .fn-gantt .navigate .nav-slider-bar, .fn-gantt .navigate .nav-slider-button { 270 | position: absolute; 271 | display: block; 272 | } 273 | 274 | .fn-gantt .navigate .nav-slider-bar { 275 | width: 155px; 276 | height: 6px; 277 | background-color: #838688; 278 | margin: 8px 0 0 0; 279 | -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.6) inset; 280 | -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.6) inset; 281 | box-shadow: 0 1px 3px rgba(0,0,0,0.6) inset; 282 | -webkit-border-radius: 3px; 283 | -moz-border-radius: 3px; 284 | border-radius: 3px; 285 | } 286 | 287 | .fn-gantt .navigate .nav-slider-button { 288 | width: 17px; 289 | height: 60px; 290 | background: url(../img/slider_handle.png) center center no-repeat; 291 | left: 0px; 292 | top: 0px; 293 | margin: -26px 0 0 0; 294 | cursor: pointer; 295 | } 296 | 297 | .fn-gantt .navigate .page-number { 298 | display: inline-block; 299 | font-size: 10px; 300 | height: 20px; 301 | } 302 | 303 | .fn-gantt .navigate .page-number span { 304 | color: #666666; 305 | margin: 0 6px; 306 | height: 20px; 307 | line-height: 20px; 308 | display: inline-block; 309 | } 310 | 311 | .fn-gantt .navigate a:link, .fn-gantt .navigate a:visited, .fn-gantt .navigate a:active { 312 | text-decoration: none; 313 | } 314 | 315 | .fn-gantt .nav-link { 316 | margin: 0 3px 0 0; 317 | display: inline-block; 318 | width: 20px; 319 | height: 20px; 320 | font-size: 0px; 321 | background: #595959 url(../img/icon_sprite.png) !important; 322 | border: 1px solid #454546; 323 | cursor: pointer; 324 | vertical-align: top; 325 | -webkit-border-radius: 2px; 326 | -moz-border-radius: 2px; 327 | border-radius: 2px; 328 | -webkit-box-shadow: 0 1px 0 rgba(255,255,255,0.1) inset, 0 1px 1px rgba(0,0,0,0.2); 329 | -moz-box-shadow: 0 1px 0 rgba(255,255,255,0.1) inset, 0 1px 1px rgba(0,0,0,0.2); 330 | box-shadow: 0 1px 0 rgba(255,255,255,0.1) inset, 0 1px 1px rgba(0,0,0,0.2); 331 | -webkit-box-sizing: border-box; 332 | -moz-box-sizing: border-box; 333 | box-sizing: border-box; 334 | } 335 | .fn-gantt .nav-link:active { 336 | -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.25) inset, 0 1px 0 #FFF; 337 | -moz-box-shadow: 0 1px 1px rgba(0,0,0,0.25) inset, 0 1px 0 #FFF; 338 | box-shadow: 0 1px 1px rgba(0,0,0,0.25) inset, 0 1px 0 #FFF; 339 | } 340 | 341 | .fn-gantt .navigate .nav-page-back { 342 | background-position: 1px 0 !important; 343 | margin: 0; 344 | } 345 | 346 | .fn-gantt .navigate .nav-page-next { 347 | background-position: 1px -16px !important; 348 | margin-right: 15px; 349 | } 350 | 351 | .fn-gantt .navigate .nav-slider .nav-page-next { 352 | margin-right: 5px; 353 | } 354 | 355 | .fn-gantt .navigate .nav-begin { 356 | background-position: 1px -112px !important; 357 | } 358 | 359 | .fn-gantt .navigate .nav-prev-week { 360 | background-position: 1px -128px !important; 361 | } 362 | 363 | .fn-gantt .navigate .nav-prev-day { 364 | background-position: 1px -48px !important; 365 | } 366 | 367 | .fn-gantt .navigate .nav-next-day { 368 | background-position: 1px -64px !important; 369 | } 370 | 371 | .fn-gantt .navigate .nav-next-week { 372 | background-position: 1px -160px !important; 373 | } 374 | 375 | .fn-gantt .navigate .nav-end { 376 | background-position: 1px -144px !important; 377 | } 378 | 379 | .fn-gantt .navigate .nav-zoomOut { 380 | background-position: 1px -96px !important; 381 | } 382 | 383 | .fn-gantt .navigate .nav-zoomIn { 384 | background-position: 1px -80px !important; 385 | margin-left: 15px; 386 | } 387 | 388 | .fn-gantt .navigate .nav-now { 389 | background-position: 1px -32px !important; 390 | } 391 | 392 | .fn-gantt .navigate .nav-slider .nav-now { 393 | margin-right: 5px; 394 | } 395 | 396 | .fn-gantt-loader { 397 | background-image: url(../img/loader_bg.png); 398 | z-index: 30; 399 | } 400 | 401 | .fn-gantt-loader-spinner { 402 | width: 100px; 403 | height: 20px; 404 | position: absolute; 405 | margin-left: 50%; 406 | margin-top: 50%; 407 | text-align: center; 408 | } 409 | .fn-gantt-loader-spinner span { 410 | color: #fff; 411 | font-size: 12px; 412 | font-weight: bold; 413 | } 414 | 415 | .row:after { 416 | clear: both; 417 | } 418 | 419 | -------------------------------------------------------------------------------- /ch4/gantt-charts/img/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch4/gantt-charts/img/grid.png -------------------------------------------------------------------------------- /ch4/gantt-charts/img/icon_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch4/gantt-charts/img/icon_sprite.png -------------------------------------------------------------------------------- /ch4/gantt-charts/img/loader_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch4/gantt-charts/img/loader_bg.png -------------------------------------------------------------------------------- /ch4/gantt-charts/img/slider_handle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch4/gantt-charts/img/slider_handle.png -------------------------------------------------------------------------------- /ch4/gantt-charts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 129 | 130 | -------------------------------------------------------------------------------- /ch4/graphs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 355 | 356 | -------------------------------------------------------------------------------- /ch4/graphs/js/sigma.layout.forceAtlas2.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";var a=sigma.utils.pkg("sigma.layout.forceatlas2");a.ForceAtlas2=function(b,c){var d=this;this.graph=b,this.p=sigma.utils.extend(c||{},a.defaultSettings),this.state={step:0,index:0},this.init=function(){return d.state={step:0,index:0},d.graph.nodes().forEach(function(a){a.fa2={mass:1+d.graph.degree(a.id),old_dx:0,old_dy:0,dx:0,dy:0}}),d},this.go=function(){for(;d.atomicGo(););},this.atomicGo=function(){var b,c,e,f,g,h,i,j=d.graph,k=j.nodes,l=j.edges,m=k(),n=l(),o=d.p.complexIntervals,p=d.p.simpleIntervals;switch(d.state.step){case 0:for(b=0,f=m.length;f>b;b++)c=m[b],c.fa2=c.fa2?{mass:1+d.graph.degree(c.id),old_dx:c.fa2.dx||0,old_dy:c.fa2.dy||0,dx:0,dy:0}:{mass:1+d.graph.degree(c.id),old_dx:0,old_dy:0,dx:0,dy:0};if(d.p.barnesHutOptimize&&(d.rootRegion=new a.Region(m,0),d.rootRegion.buildSubRegions()),d.p.outboundAttractionDistribution){for(d.p.outboundAttCompensation=0,b=0,f=m.length;f>b;b++)c=m[b],d.p.outboundAttCompensation+=c.fa2.mass;d.p.outboundAttCompensation/=m.length}return d.state.step=1,d.state.index=0,!0;case 1:var q,r,s,t,u,v,w=d.ForceFactory.buildRepulsion(d.p.adjustSizes,d.p.scalingRatio);if(d.p.barnesHutOptimize){for(u=d.rootRegion,v=d.p.barnesHutTheta,b=d.state.index;bt;t++)(r=m[t]).fa2&&w.apply_nn(q,r);s===m.length?d.state={step:2,index:0}:d.state.index=s}return!0;case 2:var x=d.p.strongGravityMode?d.ForceFactory.getStrongGravity(d.p.scalingRatio):d.ForceFactory.buildRepulsion(d.p.adjustSizes,d.p.scalingRatio),y=d.p.gravity,z=d.p.scalingRatio;for(b=d.state.index;bb;b++)c=m[b],g=c.fixed||!1,!g&&c.fa2&&(h=Math.sqrt(Math.pow(c.fa2.old_dx-c.fa2.dx,2)+Math.pow(c.fa2.old_dy-c.fa2.dy,2)),D+=c.fa2.mass*h,E+=.5*c.fa2.mass*Math.sqrt(Math.pow(c.fa2.old_dx+c.fa2.dx,2)+Math.pow(c.fa2.old_dy+c.fa2.dy,2)));for(d.p.totalSwinging=D,d.p.totalEffectiveTraction=E,C=Math.pow(d.p.jitterTolerance,2)*d.p.totalEffectiveTraction/d.p.totalSwinging,B=.5,d.p.speed=d.p.speed+Math.min(C-d.p.speed,B*d.p.speed),b=0,f=m.length;f>b;b++)c=m[b],c.old_x=+c.x,c.old_y=+c.y;return d.state.step=5,!0;case 5:var F,G;if(b=d.state.index,d.p.adjustSizes)for(G=d.p.speed;ba;a++)delete b[a].fa2},this.setAutoSettings=function(){var a=this.graph;return this.p.scalingRatio=a.nodes().length>=100?2:10,this.p.strongGravityMode=!1,this.p.gravity=1,this.p.outboundAttractionDistribution=!1,this.p.linLogMode=!1,this.p.adjustSizes=!1,this.p.edgeWeightInfluence=1,this.p.jitterTolerance=a.nodes().length>=5e4?10:a.nodes().length>=5e3?1:.1,this.p.barnesHutOptimize=a.nodes().length>=1e3?!0:!1,this.p.barnesHutTheta=1.2,this},this.kill=function(){},this.ForceFactory={buildRepulsion:function(a,b){return a?new this.linRepulsion_antiCollision(b):new this.linRepulsion(b)},getStrongGravity:function(a){return new this.strongGravity(a)},buildAttraction:function(a,b,c,d){return c?a?b?new this.logAttraction_degreeDistributed_antiCollision(d):new this.logAttraction_antiCollision(d):b?new this.linAttraction_degreeDistributed_antiCollision(d):new this.linAttraction_antiCollision(d):a?b?new this.logAttraction_degreeDistributed(d):new this.logAttraction(d):b?new this.linAttraction_massDistributed(d):new this.linAttraction(d)},linRepulsion:function(a){this.coefficient=a,this.apply_nn=function(a,b){if(a.fa2&&b.fa2){var c=a.x-b.x,d=a.y-b.y,e=Math.sqrt(c*c+d*d);if(e>0){var f=this.coefficient*a.fa2.mass*b.fa2.mass/Math.pow(e,2);a.fa2.dx+=c*f,a.fa2.dy+=d*f,b.fa2.dx-=c*f,b.fa2.dy-=d*f}}},this.apply_nr=function(a,b){var c=a.x-b.p.massCenterX,d=a.y-b.p.massCenterY,e=Math.sqrt(c*c+d*d);if(e>0){var f=this.coefficient*a.fa2.mass*b.p.mass/Math.pow(e,2);a.fa2.dx+=c*f,a.fa2.dy+=d*f}},this.apply_g=function(a,b){var c=a.x,d=a.y,e=Math.sqrt(c*c+d*d);if(e>0){var f=this.coefficient*a.fa2.mass*b/e;a.fa2.dx-=c*f,a.fa2.dy-=d*f}}},linRepulsion_antiCollision:function(a){this.coefficient=a,this.apply_nn=function(a,b){var c;if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=Math.sqrt(d*d+e*e)-a.size-b.size;f>0?(c=this.coefficient*a.fa2.mass*b.fa2.mass/Math.pow(f,2),a.fa2.dx+=d*c,a.fa2.dy+=e*c,b.fa2.dx-=d*c,b.fa2.dy-=e*c):0>f&&(c=100*this.coefficient*a.fa2.mass*b.fa2.mass,a.fa2.dx+=d*c,a.fa2.dy+=e*c,b.fa2.dx-=d*c,b.fa2.dy-=e*c)}},this.apply_nr=function(a,b){var c,d=a.fa2.x()-b.getMassCenterX(),e=a.fa2.y()-b.getMassCenterY(),f=Math.sqrt(d*d+e*e);f>0?(c=this.coefficient*a.fa2.mass*b.getMass()/Math.pow(f,2),a.fa2.dx+=d*c,a.fa2.dy+=e*c):0>f&&(c=-this.coefficient*a.fa2.mass*b.getMass()/f,a.fa2.dx+=d*c,a.fa2.dy+=e*c)},this.apply_g=function(a,b){var c=a.x,d=a.y,e=Math.sqrt(c*c+d*d);if(e>0){var f=this.coefficient*a.fa2.mass*b/e;a.fa2.dx-=c*f,a.fa2.dy-=d*f}}},strongGravity:function(a){this.coefficient=a,this.apply_nn=function(){},this.apply_nr=function(){},this.apply_g=function(a,b){var c=a.x,d=a.y,e=Math.sqrt(c*c+d*d);if(e>0){var f=this.coefficient*a.fa2.mass*b;a.fa2.dx-=c*f,a.fa2.dy-=d*f}}},linAttraction:function(a){this.coefficient=a,this.apply_nn=function(a,b,c){if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=-this.coefficient*c;a.fa2.dx+=d*f,a.fa2.dy+=e*f,b.fa2.dx-=d*f,b.fa2.dy-=e*f}}},linAttraction_massDistributed:function(a){this.coefficient=a,this.apply_nn=function(a,b,c){if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=-this.coefficient*c/a.fa2.mass;a.fa2.dx+=d*f,a.fa2.dy+=e*f,b.fa2.dx-=d*f,b.fa2.dy-=e*f}}},logAttraction:function(a){this.coefficient=a,this.apply_nn=function(a,b,c){if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=Math.sqrt(d*d+e*e);if(f>0){var g=-this.coefficient*c*Math.log(1+f)/f;a.fa2.dx+=d*g,a.fa2.dy+=e*g,b.fa2.dx-=d*g,b.fa2.dy-=e*g}}}},logAttraction_degreeDistributed:function(a){this.coefficient=a,this.apply_nn=function(a,b,c){if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=Math.sqrt(d*d+e*e);if(f>0){var g=-this.coefficient*c*Math.log(1+f)/f/a.fa2.mass;a.fa2.dx+=d*g,a.fa2.dy+=e*g,b.fa2.dx-=d*g,b.fa2.dy-=e*g}}}},linAttraction_antiCollision:function(a){this.coefficient=a,this.apply_nn=function(a,b,c){if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=Math.sqrt(d*d+e*e);if(f>0){var g=-this.coefficient*c;a.fa2.dx+=d*g,a.fa2.dy+=e*g,b.fa2.dx-=d*g,b.fa2.dy-=e*g}}}},linAttraction_degreeDistributed_antiCollision:function(a){this.coefficient=a,this.apply_nn=function(a,b,c){if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=Math.sqrt(d*d+e*e);if(f>0){var g=-this.coefficient*c/a.fa2.mass;a.fa2.dx+=d*g,a.fa2.dy+=e*g,b.fa2.dx-=d*g,b.fa2.dy-=e*g}}}},logAttraction_antiCollision:function(a){this.coefficient=a,this.apply_nn=function(a,b,c){if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=Math.sqrt(d*d+e*e);if(f>0){var g=-this.coefficient*c*Math.log(1+f)/f;a.fa2.dx+=d*g,a.fa2.dy+=e*g,b.fa2.dx-=d*g,b.fa2.dy-=e*g}}}},logAttraction_degreeDistributed_antiCollision:function(a){this.coefficient=a,this.apply_nn=function(a,b,c){if(a.fa2&&b.fa2){var d=a.x-b.x,e=a.y-b.y,f=Math.sqrt(d*d+e*e);if(f>0){var g=-this.coefficient*c*Math.log(1+f)/f/a.fa2.mass;a.fa2.dx+=d*g,a.fa2.dy+=e*g,b.fa2.dx-=d*g,b.fa2.dy-=e*g}}}}}},a.Region=function(a,b){this.depthLimit=20,this.size=0,this.nodes=a,this.subregions=[],this.depth=b,this.p={mass:0,massCenterX:0,massCenterY:0},this.updateMassAndGeometry()},a.Region.prototype.updateMassAndGeometry=function(){if(this.nodes.length>1){var a=0,b=0,c=0;this.nodes.forEach(function(d){a+=d.fa2.mass,b+=d.x*d.fa2.mass,c+=d.y*d.fa2.mass});var d,e=b/a,f=c/a;this.nodes.forEach(function(a){var b=Math.sqrt((a.x-e)*(a.x-e)+(a.y-f)*(a.y-f));d=Math.max(d||2*b,2*b)}),this.p.mass=a,this.p.massCenterX=e,this.p.massCenterY=f,this.size=d}},a.Region.prototype.buildSubRegions=function(){if(this.nodes.length>1){var b,c,d,e,f=[],g=[],h=[],i=this.p.massCenterX,j=this.p.massCenterY,k=this.depth+1,l=this,m=[],n=[],o=[],p=[];this.nodes.forEach(function(a){b=a.xthis.size?b.apply_nr(a,this):this.subregions.forEach(function(d){d.applyForce(a,b,c)})}},sigma.prototype.startForceAtlas2=function(){function b(){conrad.hasJob("forceatlas2_"+c.id)||conrad.addJob({id:"forceatlas2_"+c.id,job:c.forceatlas2.atomicGo,end:function(){c.refresh(),c.forceatlas2.isRunning&&b()}})}if((this.forceatlas2||{}).isRunning)return this;this.forceatlas2||(this.forceatlas2=new a.ForceAtlas2(this.graph),this.forceatlas2.setAutoSettings(),this.forceatlas2.init()),this.forceatlas2.isRunning=!0;var c=this;return b(),this},sigma.prototype.stopForceAtlas2=function(){return(this.forceatlas2||{}).isRunning&&(this.forceatlas2.state={step:0,index:0},this.forceatlas2.isRunning=!1,this.forceatlas2.clean()),conrad.hasJob("forceatlas2_"+this.id)&&conrad.killJob("forceatlas2_"+this.id),this},a.defaultSettings={autoSettings:!0,linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:0,scalingRatio:1,strongGravityMode:!1,gravity:1,jitterTolerance:1,barnesHutOptimize:!1,barnesHutTheta:1.2,speed:1,outboundAttCompensation:1,totalSwinging:0,totalEffectiveTraction:0,complexIntervals:500,simpleIntervals:1e3}}(); -------------------------------------------------------------------------------- /ch4/heat-maps/font/digital7-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch4/heat-maps/font/digital7-webfont.eot -------------------------------------------------------------------------------- /ch4/heat-maps/font/digital7-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch4/heat-maps/font/digital7-webfont.ttf -------------------------------------------------------------------------------- /ch4/heat-maps/font/digital7-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch4/heat-maps/font/digital7-webfont.woff -------------------------------------------------------------------------------- /ch4/heat-maps/font/digital7.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'digital7'; 3 | src: url('digital7-webfont.eot'); 4 | src: url('digital7-webfont.eot?#iefix') format('embedded-opentype'), 5 | url('digital7-webfont.woff') format('woff'), 6 | url('digital7-webfont.ttf') format('truetype'); 7 | font-weight: normal; 8 | font-style: normal; 9 | 10 | } -------------------------------------------------------------------------------- /ch4/heat-maps/img/basketball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch4/heat-maps/img/basketball.png -------------------------------------------------------------------------------- /ch4/tree-maps/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 132 | 133 | -------------------------------------------------------------------------------- /ch4/tree-maps/js/treemap-squared-0.5.min.js: -------------------------------------------------------------------------------- 1 | var Treemap={}; 2 | (function(){Treemap.generate=function(){function q(a,b,c,e){this.xoffset=a;this.yoffset=b;this.height=e;this.width=c;this.shortestEdge=function(){return Math.min(this.height,this.width)};this.getCoordinates=function(a){var b=[],c=this.xoffset,f=this.yoffset,m=l(a)/this.height,e=l(a)/this.width,d;if(this.width>=this.height)for(d=0;d=this.height? 3 | (a/=this.height,a=new q(this.xoffset+a,this.yoffset,this.width-a,this.height)):(a/=this.width,a=new q(this.xoffset,this.yoffset+a,this.width,this.height-a));return a}}function r(a,b,c,e,h){var e="undefined"===typeof e?0:e,h="undefined"===typeof h?0:h,d=[],i=[],f;if(a[0]&&a[0].constructor===Array){for(f=0;f=h);i?(b.push(p),d(a.slice(1),b,c,e)):(p=c.cutArea(l(b),e),e.push(c.getCoordinates(b)),d(a,[],p,e));return e}}function j(a, 5 | b){var c=Math.min.apply(Math,a),d=Math.max.apply(Math,a),h=l(a);return Math.max(Math.pow(b,2)*d/Math.pow(h,2),Math.pow(h,2)/(Math.pow(b,2)*c))}function l(a){var b=0,c;for(c=0;cj-f&&e.getBBox().width<=l-g&&e.rotate(-90)}}();a.background="undefined"===typeof a.background?{}:a.background;a.label="undefined"=== 9 | typeof a.label?{}:a.label;a.box="undefined"===typeof a.box?{}:a.box;a.draw="undefined"===typeof a.draw?e:a.draw;b=new Raphael(g,d,j);b.rect(0,0,d,j).attr(a.background);g=Treemap.generate(l,d,j);r(b,g,k,a,[])}}()})(); -------------------------------------------------------------------------------- /ch4/word-clouds/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 |
12 |
13 | 14 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /ch5/chronoline/css/chronoline.css: -------------------------------------------------------------------------------- 1 | .chronoline-wrapper { 2 | position: relative; 3 | } 4 | .chronoline-wrapper * { 5 | -moz-user-select: -moz-none; 6 | -khtml-user-select: none; 7 | -webkit-user-select: none; 8 | user-select: none; 9 | } 10 | .chronoline-canvas { 11 | overflow: hidden; 12 | position: relative; 13 | width: 100%; 14 | } 15 | .chronoline-canvas > svg { 16 | position: relative; 17 | } 18 | .chronoline-wrapper:hover > .chronoline-left, 19 | .chronoline-wrapper:hover > .chronoline-right { 20 | display: block; 21 | } 22 | .chronoline-left, 23 | .chronoline-right { 24 | display: none; 25 | *display: block; 26 | top: 0; 27 | position: absolute; 28 | width: 20px; 29 | opacity: 0.6; 30 | filter: alpha(opacity=60); 31 | background-color: #000000; 32 | cursor: pointer; 33 | } 34 | .chronoline-left:hover, 35 | .chronoline-right:hover { 36 | opacity: 1; 37 | filter: alpha(opacity=100); 38 | background-color: #97aceb; 39 | } 40 | .chronoline-left { 41 | left: 0; 42 | } 43 | .chronoline-right { 44 | right: 0; 45 | } 46 | .chronoline-left-icon, 47 | .chronoline-right-icon { 48 | background: url("sprites.png") no-repeat scroll 0px 0 transparent; 49 | height: 15px; 50 | width: 10px; 51 | cursor: pointer; 52 | margin: 0 auto; 53 | } 54 | .chronoline-right-icon { 55 | background-position: -10px 0; 56 | } 57 | .tooltip-style { 58 | font-size: 12px; 59 | background-color: #222222; 60 | color: #ffffff; 61 | border-radius: 2px; 62 | max-width: 300px; 63 | } 64 | 65 | .chronoline-draggable { 66 | cursor:hand; 67 | cursor:grab; 68 | cursor:-moz-grab; 69 | cursor:-webkit-grab; 70 | } 71 | 72 | .chronoline-draggable.dragging { 73 | cursor:grabbing; 74 | cursor:-moz-grabbing; 75 | cursor:-webkit-grabbing; 76 | } 77 | 78 | .chronoline-draggable .chronoline-canvas .chronoline-event { 79 | cursor: default; 80 | } 81 | -------------------------------------------------------------------------------- /ch5/chronoline/css/jquery.qtip.css: -------------------------------------------------------------------------------- 1 | /* 2 | * qTip2 - Pretty powerful tooltips - v2.2.0 3 | * http://qtip2.com 4 | * 5 | * Copyright (c) 2013 Craig Michael Thompson 6 | * Released under the MIT, GPL licenses 7 | * http://jquery.org/license 8 | * 9 | * Date: Sun Dec 15 2013 10:12 EST-0500 10 | * Plugins: None 11 | * Styles: None 12 | */ 13 | .qtip{ 14 | position: absolute; 15 | left: -28000px; 16 | top: -28000px; 17 | display: none; 18 | 19 | max-width: 280px; 20 | min-width: 50px; 21 | 22 | font-size: 10.5px; 23 | line-height: 12px; 24 | 25 | direction: ltr; 26 | 27 | box-shadow: none; 28 | padding: 0; 29 | } 30 | 31 | .qtip-content{ 32 | position: relative; 33 | padding: 5px 9px; 34 | overflow: hidden; 35 | 36 | text-align: left; 37 | word-wrap: break-word; 38 | } 39 | 40 | .qtip-titlebar{ 41 | position: relative; 42 | padding: 5px 35px 5px 10px; 43 | overflow: hidden; 44 | 45 | border-width: 0 0 1px; 46 | font-weight: bold; 47 | } 48 | 49 | .qtip-titlebar + .qtip-content{ border-top-width: 0 !important; } 50 | 51 | /* Default close button class */ 52 | .qtip-close{ 53 | position: absolute; 54 | right: -9px; top: -9px; 55 | 56 | cursor: pointer; 57 | outline: medium none; 58 | 59 | border-width: 1px; 60 | border-style: solid; 61 | border-color: transparent; 62 | } 63 | 64 | .qtip-titlebar .qtip-close{ 65 | right: 4px; top: 50%; 66 | margin-top: -9px; 67 | } 68 | 69 | * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */ 70 | 71 | .qtip-titlebar .ui-icon, 72 | .qtip-icon .ui-icon{ 73 | display: block; 74 | text-indent: -1000em; 75 | direction: ltr; 76 | } 77 | 78 | .qtip-icon, .qtip-icon .ui-icon{ 79 | -moz-border-radius: 3px; 80 | -webkit-border-radius: 3px; 81 | border-radius: 3px; 82 | text-decoration: none; 83 | } 84 | 85 | .qtip-icon .ui-icon{ 86 | width: 18px; 87 | height: 14px; 88 | 89 | line-height: 14px; 90 | text-align: center; 91 | text-indent: 0; 92 | font: normal bold 10px/13px Tahoma,sans-serif; 93 | 94 | color: inherit; 95 | background: transparent none no-repeat -100em -100em; 96 | } 97 | 98 | /* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */ 99 | .qtip-focus{} 100 | 101 | /* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */ 102 | .qtip-hover{} 103 | 104 | /* Default tooltip style */ 105 | .qtip-default{ 106 | border-width: 1px; 107 | border-style: solid; 108 | border-color: #F1D031; 109 | 110 | background-color: #FFFFA3; 111 | color: #555; 112 | } 113 | 114 | .qtip-default .qtip-titlebar{ 115 | background-color: #FFEF93; 116 | } 117 | 118 | .qtip-default .qtip-icon{ 119 | border-color: #CCC; 120 | background: #F1F1F1; 121 | color: #777; 122 | } 123 | 124 | .qtip-default .qtip-titlebar .qtip-close{ 125 | border-color: #AAA; 126 | color: #111; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /ch5/chronoline/css/sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch5/chronoline/css/sprites.png -------------------------------------------------------------------------------- /ch5/timelinejs/css/fancybox_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch5/timelinejs/css/fancybox_sprite.png -------------------------------------------------------------------------------- /ch5/timelinejs/css/fancybox_sprite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch5/timelinejs/css/fancybox_sprite@2x.png -------------------------------------------------------------------------------- /ch5/timelinejs/css/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch5/timelinejs/css/loading.gif -------------------------------------------------------------------------------- /ch5/timelinejs/css/timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch5/timelinejs/css/timeline.png -------------------------------------------------------------------------------- /ch5/timelinejs/css/timeline@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch5/timelinejs/css/timeline@2x.png -------------------------------------------------------------------------------- /ch6/leaflet/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.1 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox. 29 | * Correct `block` display not defined for `main` in IE 11. 30 | */ 31 | 32 | article, 33 | aside, 34 | details, 35 | figcaption, 36 | figure, 37 | footer, 38 | header, 39 | hgroup, 40 | main, 41 | nav, 42 | section, 43 | summary { 44 | display: block; 45 | } 46 | 47 | /** 48 | * 1. Correct `inline-block` display not defined in IE 8/9. 49 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 50 | */ 51 | 52 | audio, 53 | canvas, 54 | progress, 55 | video { 56 | display: inline-block; /* 1 */ 57 | vertical-align: baseline; /* 2 */ 58 | } 59 | 60 | /** 61 | * Prevent modern browsers from displaying `audio` without controls. 62 | * Remove excess height in iOS 5 devices. 63 | */ 64 | 65 | audio:not([controls]) { 66 | display: none; 67 | height: 0; 68 | } 69 | 70 | /** 71 | * Address `[hidden]` styling not present in IE 8/9/10. 72 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 73 | */ 74 | 75 | [hidden], 76 | template { 77 | display: none; 78 | } 79 | 80 | /* Links 81 | ========================================================================== */ 82 | 83 | /** 84 | * Remove the gray background color from active links in IE 10. 85 | */ 86 | 87 | a { 88 | background: transparent; 89 | } 90 | 91 | /** 92 | * Improve readability when focused and also mouse hovered in all browsers. 93 | */ 94 | 95 | a:active, 96 | a:hover { 97 | outline: 0; 98 | } 99 | 100 | /* Text-level semantics 101 | ========================================================================== */ 102 | 103 | /** 104 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 105 | */ 106 | 107 | abbr[title] { 108 | border-bottom: 1px dotted; 109 | } 110 | 111 | /** 112 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 113 | */ 114 | 115 | b, 116 | strong { 117 | font-weight: bold; 118 | } 119 | 120 | /** 121 | * Address styling not present in Safari and Chrome. 122 | */ 123 | 124 | dfn { 125 | font-style: italic; 126 | } 127 | 128 | /** 129 | * Address variable `h1` font-size and margin within `section` and `article` 130 | * contexts in Firefox 4+, Safari, and Chrome. 131 | */ 132 | 133 | h1 { 134 | font-size: 2em; 135 | margin: 0.67em 0; 136 | } 137 | 138 | /** 139 | * Address styling not present in IE 8/9. 140 | */ 141 | 142 | mark { 143 | background: #ff0; 144 | color: #000; 145 | } 146 | 147 | /** 148 | * Address inconsistent and variable font size in all browsers. 149 | */ 150 | 151 | small { 152 | font-size: 80%; 153 | } 154 | 155 | /** 156 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 157 | */ 158 | 159 | sub, 160 | sup { 161 | font-size: 75%; 162 | line-height: 0; 163 | position: relative; 164 | vertical-align: baseline; 165 | } 166 | 167 | sup { 168 | top: -0.5em; 169 | } 170 | 171 | sub { 172 | bottom: -0.25em; 173 | } 174 | 175 | /* Embedded content 176 | ========================================================================== */ 177 | 178 | /** 179 | * Remove border when inside `a` element in IE 8/9/10. 180 | */ 181 | 182 | img { 183 | border: 0; 184 | } 185 | 186 | /** 187 | * Correct overflow not hidden in IE 9/10/11. 188 | */ 189 | 190 | svg:not(:root) { 191 | overflow: hidden; 192 | } 193 | 194 | /* Grouping content 195 | ========================================================================== */ 196 | 197 | /** 198 | * Address margin not present in IE 8/9 and Safari. 199 | */ 200 | 201 | figure { 202 | margin: 1em 40px; 203 | } 204 | 205 | /** 206 | * Address differences between Firefox and other browsers. 207 | */ 208 | 209 | hr { 210 | -moz-box-sizing: content-box; 211 | box-sizing: content-box; 212 | height: 0; 213 | } 214 | 215 | /** 216 | * Contain overflow in all browsers. 217 | */ 218 | 219 | pre { 220 | overflow: auto; 221 | } 222 | 223 | /** 224 | * Address odd `em`-unit font size rendering in all browsers. 225 | */ 226 | 227 | code, 228 | kbd, 229 | pre, 230 | samp { 231 | font-family: monospace, monospace; 232 | font-size: 1em; 233 | } 234 | 235 | /* Forms 236 | ========================================================================== */ 237 | 238 | /** 239 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 240 | * styling of `select`, unless a `border` property is set. 241 | */ 242 | 243 | /** 244 | * 1. Correct color not being inherited. 245 | * Known issue: affects color of disabled elements. 246 | * 2. Correct font properties not being inherited. 247 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 248 | */ 249 | 250 | button, 251 | input, 252 | optgroup, 253 | select, 254 | textarea { 255 | color: inherit; /* 1 */ 256 | font: inherit; /* 2 */ 257 | margin: 0; /* 3 */ 258 | } 259 | 260 | /** 261 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 262 | */ 263 | 264 | button { 265 | overflow: visible; 266 | } 267 | 268 | /** 269 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 270 | * All other form control elements do not inherit `text-transform` values. 271 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 272 | * Correct `select` style inheritance in Firefox. 273 | */ 274 | 275 | button, 276 | select { 277 | text-transform: none; 278 | } 279 | 280 | /** 281 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 282 | * and `video` controls. 283 | * 2. Correct inability to style clickable `input` types in iOS. 284 | * 3. Improve usability and consistency of cursor style between image-type 285 | * `input` and others. 286 | */ 287 | 288 | button, 289 | html input[type="button"], /* 1 */ 290 | input[type="reset"], 291 | input[type="submit"] { 292 | -webkit-appearance: button; /* 2 */ 293 | cursor: pointer; /* 3 */ 294 | } 295 | 296 | /** 297 | * Re-set default cursor for disabled elements. 298 | */ 299 | 300 | button[disabled], 301 | html input[disabled] { 302 | cursor: default; 303 | } 304 | 305 | /** 306 | * Remove inner padding and border in Firefox 4+. 307 | */ 308 | 309 | button::-moz-focus-inner, 310 | input::-moz-focus-inner { 311 | border: 0; 312 | padding: 0; 313 | } 314 | 315 | /** 316 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 317 | * the UA stylesheet. 318 | */ 319 | 320 | input { 321 | line-height: normal; 322 | } 323 | 324 | /** 325 | * It's recommended that you don't attempt to style these elements. 326 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 327 | * 328 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 329 | * 2. Remove excess padding in IE 8/9/10. 330 | */ 331 | 332 | input[type="checkbox"], 333 | input[type="radio"] { 334 | box-sizing: border-box; /* 1 */ 335 | padding: 0; /* 2 */ 336 | } 337 | 338 | /** 339 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 340 | * `font-size` values of the `input`, it causes the cursor style of the 341 | * decrement button to change from `default` to `text`. 342 | */ 343 | 344 | input[type="number"]::-webkit-inner-spin-button, 345 | input[type="number"]::-webkit-outer-spin-button { 346 | height: auto; 347 | } 348 | 349 | /** 350 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 351 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 352 | * (include `-moz` to future-proof). 353 | */ 354 | 355 | input[type="search"] { 356 | -webkit-appearance: textfield; /* 1 */ 357 | -moz-box-sizing: content-box; 358 | -webkit-box-sizing: content-box; /* 2 */ 359 | box-sizing: content-box; 360 | } 361 | 362 | /** 363 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 364 | * Safari (but not Chrome) clips the cancel button when the search input has 365 | * padding (and `textfield` appearance). 366 | */ 367 | 368 | input[type="search"]::-webkit-search-cancel-button, 369 | input[type="search"]::-webkit-search-decoration { 370 | -webkit-appearance: none; 371 | } 372 | 373 | /** 374 | * Define consistent border, margin, and padding. 375 | */ 376 | 377 | fieldset { 378 | border: 1px solid #c0c0c0; 379 | margin: 0 2px; 380 | padding: 0.35em 0.625em 0.75em; 381 | } 382 | 383 | /** 384 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 385 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 386 | */ 387 | 388 | legend { 389 | border: 0; /* 1 */ 390 | padding: 0; /* 2 */ 391 | } 392 | 393 | /** 394 | * Remove default vertical scrollbar in IE 8/9/10/11. 395 | */ 396 | 397 | textarea { 398 | overflow: auto; 399 | } 400 | 401 | /** 402 | * Don't inherit the `font-weight` (applied by a rule above). 403 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 404 | */ 405 | 406 | optgroup { 407 | font-weight: bold; 408 | } 409 | 410 | /* Tables 411 | ========================================================================== */ 412 | 413 | /** 414 | * Remove most spacing between table cells. 415 | */ 416 | 417 | table { 418 | border-collapse: collapse; 419 | border-spacing: 0; 420 | } 421 | 422 | td, 423 | th { 424 | padding: 0; 425 | } 426 | -------------------------------------------------------------------------------- /ch6/leaflet/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch6/leaflet/images/layers-2x.png -------------------------------------------------------------------------------- /ch6/leaflet/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch6/leaflet/images/layers.png -------------------------------------------------------------------------------- /ch6/leaflet/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch6/leaflet/images/marker-icon-2x.png -------------------------------------------------------------------------------- /ch6/leaflet/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch6/leaflet/images/marker-icon.png -------------------------------------------------------------------------------- /ch6/leaflet/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/ch6/leaflet/images/marker-shadow.png -------------------------------------------------------------------------------- /ch7/chart/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 16 |
17 |
18 | 19 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /ch7/map/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GeoJSON with Voronoi 6 | 7 | 10 | 11 | 12 |
13 | 14 |
15 | 16 | 17 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /ch7/sunburst/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Zoomable radial chart with color scales 6 | 7 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /running/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /running/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 4 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /running/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /running/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | test/temp 4 | .sass-cache 5 | app/bower_components 6 | .tmp 7 | test/bower_components/ 8 | -------------------------------------------------------------------------------- /running/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 4, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "jquery": true, 22 | "globals": { 23 | "Running": true, 24 | "running": true, 25 | "_": false, 26 | "Backbone": false, 27 | "JST": false, 28 | "beforeEach": false, 29 | "describe": false, 30 | "it": false, 31 | "assert": true, 32 | "expect": true, 33 | "should": true 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /running/.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-backbone": { 3 | "appPath": "app", 4 | "appName": "Running", 5 | "coffee": false, 6 | "testFramework": "mocha", 7 | "templateFramework": "lodash", 8 | "compassBootstrap": false, 9 | "includeRequireJS": false 10 | }, 11 | "generator-mocha": {} 12 | } -------------------------------------------------------------------------------- /running/Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var LIVERELOAD_PORT = 35729; 3 | var SERVER_PORT = 9000; 4 | var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT}); 5 | var mountFolder = function (connect, dir) { 6 | return connect.static(require('path').resolve(dir)); 7 | }; 8 | 9 | // # Globbing 10 | // for performance reasons we're only matching one level down: 11 | // 'test/spec/{,*/}*.js' 12 | // use this if you want to match all subfolders: 13 | // 'test/spec/**/*.js' 14 | // templateFramework: 'lodash' 15 | 16 | module.exports = function (grunt) { 17 | // show elapsed time at the end 18 | require('time-grunt')(grunt); 19 | // load all grunt tasks 20 | require('load-grunt-tasks')(grunt); 21 | 22 | // configurable paths 23 | var yeomanConfig = { 24 | app: 'app', 25 | dist: 'dist' 26 | }; 27 | 28 | grunt.initConfig({ 29 | yeoman: yeomanConfig, 30 | watch: { 31 | options: { 32 | nospawn: true, 33 | livereload: true 34 | }, 35 | livereload: { 36 | options: { 37 | livereload: grunt.option('livereloadport') || LIVERELOAD_PORT 38 | }, 39 | files: [ 40 | '<%= yeoman.app %>/*.html', 41 | '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css', 42 | '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js', 43 | '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}', 44 | '<%= yeoman.app %>/scripts/templates/*.{ejs,mustache,hbs}', 45 | 'test/spec/**/*.js' 46 | ] 47 | }, 48 | jst: { 49 | files: [ 50 | '<%= yeoman.app %>/scripts/templates/*.ejs' 51 | ], 52 | tasks: ['jst'] 53 | }, 54 | test: { 55 | files: ['<%= yeoman.app %>/scripts/{,*/}*.js', 'test/spec/**/*.js'], 56 | tasks: ['test:true'] 57 | } 58 | }, 59 | connect: { 60 | options: { 61 | port: grunt.option('port') || SERVER_PORT, 62 | // change this to '0.0.0.0' to access the server from outside 63 | hostname: 'localhost' 64 | }, 65 | livereload: { 66 | options: { 67 | middleware: function (connect) { 68 | return [ 69 | lrSnippet, 70 | mountFolder(connect, '.tmp'), 71 | mountFolder(connect, yeomanConfig.app) 72 | ]; 73 | } 74 | } 75 | }, 76 | test: { 77 | options: { 78 | port: 9001, 79 | middleware: function (connect) { 80 | return [ 81 | lrSnippet, 82 | mountFolder(connect, '.tmp'), 83 | mountFolder(connect, 'test'), 84 | mountFolder(connect, yeomanConfig.app) 85 | ]; 86 | } 87 | } 88 | }, 89 | dist: { 90 | options: { 91 | middleware: function (connect) { 92 | return [ 93 | mountFolder(connect, yeomanConfig.dist) 94 | ]; 95 | } 96 | } 97 | } 98 | }, 99 | open: { 100 | server: { 101 | path: 'http://localhost:<%= connect.options.port %>' 102 | }, 103 | test: { 104 | path: 'http://localhost:<%= connect.test.options.port %>' 105 | } 106 | }, 107 | clean: { 108 | dist: ['.tmp', '<%= yeoman.dist %>/*'], 109 | server: '.tmp' 110 | }, 111 | jshint: { 112 | options: { 113 | jshintrc: '.jshintrc', 114 | reporter: require('jshint-stylish') 115 | }, 116 | all: [ 117 | 'Gruntfile.js', 118 | '<%= yeoman.app %>/scripts/{,*/}*.js', 119 | '!<%= yeoman.app %>/scripts/vendor/*', 120 | 'test/spec/{,*/}*.js' 121 | ] 122 | }, 123 | mocha: { 124 | all: { 125 | options: { 126 | run: true, 127 | urls: ['http://localhost:<%= connect.test.options.port %>/index.html'] 128 | } 129 | } 130 | }, 131 | // not enabled since usemin task does concat and uglify 132 | // check index.html to edit your build targets 133 | // enable this task if you prefer defining your build targets here 134 | /*uglify: { 135 | dist: {} 136 | },*/ 137 | useminPrepare: { 138 | html: '<%= yeoman.app %>/index.html', 139 | options: { 140 | dest: '<%= yeoman.dist %>' 141 | } 142 | }, 143 | usemin: { 144 | html: ['<%= yeoman.dist %>/{,*/}*.html'], 145 | css: ['<%= yeoman.dist %>/styles/{,*/}*.css'], 146 | options: { 147 | dirs: ['<%= yeoman.dist %>'] 148 | } 149 | }, 150 | imagemin: { 151 | dist: { 152 | files: [{ 153 | expand: true, 154 | cwd: '<%= yeoman.app %>/images', 155 | src: '{,*/}*.{png,jpg,jpeg}', 156 | dest: '<%= yeoman.dist %>/images' 157 | }] 158 | } 159 | }, 160 | cssmin: { 161 | dist: { 162 | files: { 163 | '<%= yeoman.dist %>/styles/main.css': [ 164 | '.tmp/styles/{,*/}*.css', 165 | '<%= yeoman.app %>/styles/{,*/}*.css' 166 | ] 167 | } 168 | } 169 | }, 170 | htmlmin: { 171 | dist: { 172 | options: { 173 | /*removeCommentsFromCDATA: true, 174 | // https://github.com/yeoman/grunt-usemin/issues/44 175 | //collapseWhitespace: true, 176 | collapseBooleanAttributes: true, 177 | removeAttributeQuotes: true, 178 | removeRedundantAttributes: true, 179 | useShortDoctype: true, 180 | removeEmptyAttributes: true, 181 | removeOptionalTags: true*/ 182 | }, 183 | files: [{ 184 | expand: true, 185 | cwd: '<%= yeoman.app %>', 186 | src: '*.html', 187 | dest: '<%= yeoman.dist %>' 188 | }] 189 | } 190 | }, 191 | copy: { 192 | dist: { 193 | files: [{ 194 | expand: true, 195 | dot: true, 196 | cwd: '<%= yeoman.app %>', 197 | dest: '<%= yeoman.dist %>', 198 | src: [ 199 | '*.{ico,txt}', 200 | 'images/{,*/}*.{webp,gif}', 201 | 'styles/fonts/{,*/}*.*', 202 | ] 203 | }, { 204 | src: 'node_modules/apache-server-configs/dist/.htaccess', 205 | dest: '<%= yeoman.dist %>/.htaccess' 206 | }] 207 | } 208 | }, 209 | jst: { 210 | compile: { 211 | files: { 212 | '.tmp/scripts/templates.js': ['<%= yeoman.app %>/scripts/templates/*.ejs'] 213 | } 214 | } 215 | }, 216 | rev: { 217 | dist: { 218 | files: { 219 | src: [ 220 | '<%= yeoman.dist %>/scripts/{,*/}*.js', 221 | '<%= yeoman.dist %>/styles/{,*/}*.css', 222 | '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}', 223 | '/styles/fonts/{,*/}*.*', 224 | ] 225 | } 226 | } 227 | } 228 | }); 229 | 230 | grunt.registerTask('createDefaultTemplate', function () { 231 | grunt.file.write('.tmp/scripts/templates.js', 'this.JST = this.JST || {};'); 232 | }); 233 | 234 | grunt.registerTask('server', function (target) { 235 | grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); 236 | grunt.task.run(['serve' + (target ? ':' + target : '')]); 237 | }); 238 | 239 | grunt.registerTask('serve', function (target) { 240 | if (target === 'dist') { 241 | return grunt.task.run(['build', 'open:server', 'connect:dist:keepalive']); 242 | } 243 | 244 | if (target === 'test') { 245 | return grunt.task.run([ 246 | 'clean:server', 247 | 'createDefaultTemplate', 248 | 'jst', 249 | 'connect:test', 250 | 'open:test', 251 | 'watch' 252 | ]); 253 | } 254 | 255 | grunt.task.run([ 256 | 'clean:server', 257 | 'createDefaultTemplate', 258 | 'jst', 259 | 'connect:livereload', 260 | 'open:server', 261 | 'watch' 262 | ]); 263 | }); 264 | 265 | grunt.registerTask('test', function (isConnected) { 266 | isConnected = Boolean(isConnected); 267 | var testTasks = [ 268 | 'clean:server', 269 | 'createDefaultTemplate', 270 | 'jst', 271 | 'connect:test', 272 | 'mocha', 273 | ]; 274 | 275 | if(!isConnected) { 276 | return grunt.task.run(testTasks); 277 | } else { 278 | // already connected so not going to connect again, remove the connect:test task 279 | testTasks.splice(testTasks.indexOf('connect:test'), 1); 280 | return grunt.task.run(testTasks); 281 | } 282 | }); 283 | 284 | grunt.registerTask('build', [ 285 | 'clean:dist', 286 | 'createDefaultTemplate', 287 | 'jst', 288 | 'useminPrepare', 289 | 'imagemin', 290 | 'htmlmin', 291 | 'concat', 292 | 'cssmin', 293 | 'uglify', 294 | 'copy', 295 | 'rev', 296 | 'usemin' 297 | ]); 298 | 299 | grunt.registerTask('default', [ 300 | 'jshint', 301 | 'test', 302 | 'build' 303 | ]); 304 | }; 305 | -------------------------------------------------------------------------------- /running/app/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found :( 6 | 141 | 142 | 143 |
144 |

Not found :(

145 |

Sorry, but the page you were trying to view does not exist.

146 |

It looks like this was the result of either:

147 |
    148 |
  • a mistyped address
  • 149 |
  • an out-of-date link
  • 150 |
151 | 154 | 155 |
156 | 157 | 158 | -------------------------------------------------------------------------------- /running/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sathomas/jsDataV.is-source/9b1146c075c3074ce1cd9ea5a08e4fb5c385b06d/running/app/favicon.ico -------------------------------------------------------------------------------- /running/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Running 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /running/app/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /running/app/scripts/collections/runs.js: -------------------------------------------------------------------------------- 1 | /*global Running, Backbone*/ 2 | 3 | Running.Collections = Running.Collections || {}; 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | Running.Collections.Runs = Backbone.Collection.extend({ 9 | 10 | /* 11 | * Instead of using the real Nike+ API, fetch the 12 | * data from a local file. This avoids the complications 13 | * of dealing with authentication, etc. 14 | */ 15 | url: 'data/runs.json', 16 | model: Running.Models.Run 17 | 18 | }); 19 | 20 | })(); 21 | -------------------------------------------------------------------------------- /running/app/scripts/main.js: -------------------------------------------------------------------------------- 1 | /*global Running, $*/ 2 | 3 | window.Running = { 4 | Models: {}, 5 | Collections: {}, 6 | Views: {}, 7 | Routers: {}, 8 | init: function () { 9 | this.app = new this.Routers.App(); 10 | } 11 | }; 12 | 13 | $(document).ready(function () { 14 | 'use strict'; 15 | Running.init(); 16 | }); 17 | -------------------------------------------------------------------------------- /running/app/scripts/models/run.js: -------------------------------------------------------------------------------- 1 | /*global Running, Backbone*/ 2 | 3 | Running.Models = Running.Models || {}; 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | Running.Models.Run = Backbone.Model.extend({ 9 | 10 | idAttribute: 'activityId', 11 | 12 | url: 'https://api.nike.com/v1/me/sport/activities/', 13 | 14 | initialize: function() { 15 | }, 16 | 17 | defaults: { 18 | }, 19 | 20 | validate: function(attrs, options) { 21 | }, 22 | 23 | parse: function(response, options) { 24 | return response; 25 | } 26 | }); 27 | 28 | })(); 29 | -------------------------------------------------------------------------------- /running/app/scripts/routes/app.js: -------------------------------------------------------------------------------- 1 | /*global Running, Backbone*/ 2 | 3 | Running.Routers = Running.Routers || {}; 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | Running.Routers.App = Backbone.Router.extend({ 9 | routes: { 10 | '': 'summary', 11 | 'runs/:id': 'details' 12 | }, 13 | 14 | initialize: function() { 15 | // Since we're not connecting to the real Nike+ API, 16 | // Load the collection from the sample data on 17 | // initialization. We'll need this collection no 18 | // matter which route is active. Force a reset event 19 | // so any views can catch the update. 20 | this.runs = new Running.Collections.Runs(); 21 | this.runs.fetch({reset:true}); 22 | 23 | // Start push state history 24 | Backbone.history.start({pushState: true}); 25 | }, 26 | 27 | summary: function() { 28 | // Clean up any existing details view. 29 | if (this.detailsView) { 30 | this.detailsView.off('summarize'); 31 | this.detailsView.remove(); 32 | this.detailsView = null; 33 | } 34 | // We only need to create the summary view once. 35 | if (!this.summaryView) { 36 | this.summaryView = new Running.Views.Summary({collection: this.runs}); 37 | this.summaryView.render(); 38 | this.summaryView.on('select', this.selected, this); 39 | } 40 | $('body').html(this.summaryView.el); 41 | }, 42 | 43 | selected: function(id) { 44 | this.navigate('runs/' + id, { trigger: true }); 45 | }, 46 | 47 | details: function(id) { 48 | if (this.summaryView) { 49 | this.summaryView.$el.detach(); 50 | } 51 | this.detailsView = new Running.Views.Details({model: this.runs.get(id)}); 52 | $('body').html(this.detailsView.render().el); 53 | this.detailsView.on('summarize', this.summarize, this); 54 | }, 55 | 56 | summarize: function() { 57 | this.navigate('', { trigger: true }); 58 | } 59 | 60 | }); 61 | 62 | })(); 63 | -------------------------------------------------------------------------------- /running/app/scripts/templates/charts.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
-------------------------------------------------------------------------------- /running/app/scripts/templates/details.ejs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /running/app/scripts/templates/map.ejs: -------------------------------------------------------------------------------- 1 |

Your content here.

2 | 3 | -------------------------------------------------------------------------------- /running/app/scripts/templates/properties.ejs: -------------------------------------------------------------------------------- 1 |
<%= key %>
2 |
<%= value %>
-------------------------------------------------------------------------------- /running/app/scripts/templates/summary.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | Date 4 | Duration 5 | Distance 6 | Calories 7 | Pace 8 | 9 | 10 | -------------------------------------------------------------------------------- /running/app/scripts/templates/summaryRow.ejs: -------------------------------------------------------------------------------- 1 | <%= date %> 2 | <%= duration %> 3 | <%= distance %> 4 | <%= calories %> 5 | <%= pace %> 6 | -------------------------------------------------------------------------------- /running/app/scripts/views/details.js: -------------------------------------------------------------------------------- 1 | /*global Running, Backbone, JST*/ 2 | 3 | Running.Views = Running.Views || {}; 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | Running.Views.Details = Backbone.View.extend({ 9 | 10 | events: { 11 | 'click button': 'clicked' 12 | }, 13 | 14 | clicked: function () { 15 | this.trigger('summarize'); 16 | }, 17 | 18 | render: function () { 19 | this.$el.empty(); 20 | this.$el.append( 21 | new Running.Views.Properties({model: this.model}).render().el 22 | ); 23 | this.$el.append( 24 | new Running.Views.Charts({model: this.model}).render().el 25 | ); 26 | this.$el.append( 27 | new Running.Views.Map({model: this.model}).render().el 28 | ); 29 | this.$el.append( 30 | $("