├── README.md ├── js ├── comfortmodels.js ├── psychrometrics.js └── psychchart.js ├── psych.html ├── css └── psychchart.css ├── data └── rh-curves.json └── d3.js /README.md: -------------------------------------------------------------------------------- 1 | psych-chart-d3 2 | ============== 3 | 4 | Psychrometric chart visualization with d3 -------------------------------------------------------------------------------- /js/comfortmodels.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoyt/psych-chart-d3/HEAD/js/comfortmodels.js -------------------------------------------------------------------------------- /psych.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /css/psychchart.css: -------------------------------------------------------------------------------- 1 | path { 2 | fill:none; 3 | stroke-width:1px; 4 | } 5 | 6 | .axis path{ 7 | fill:none; 8 | stroke: black; 9 | } 10 | .axis { 11 | font-size:10pt; 12 | font-family:sans-serif; 13 | } 14 | .tick { 15 | fill:none; 16 | stroke:black; 17 | } 18 | circle.outer{ 19 | stroke:red; 20 | stroke-width:2px; 21 | fill: none; 22 | } 23 | circle.inner{ 24 | stroke:red; 25 | stroke-width:2px; 26 | fill: red; 27 | } 28 | path.rh100{ 29 | stroke:Black; 30 | } 31 | path.rhline{ 32 | stroke:Gray; 33 | } 34 | path.w{ 35 | fill: White; 36 | } 37 | rect.chartbg{ 38 | fill: rgb(100,100,100); 39 | fill-opacity: 0.1; 40 | } 41 | rect.w{ 42 | fill: White; 43 | } 44 | path.comfortzone{ 45 | fill: rgb(0,0,250); 46 | fill-opacity: 0.5; 47 | } -------------------------------------------------------------------------------- /js/psychrometrics.js: -------------------------------------------------------------------------------- 1 | var psy = psy || {}; 2 | 3 | psy.PROP = { Patm: 101325.0, 4 | CpAir: 1004.0, 5 | CpWat: 4186.0, 6 | CpVap: 1805.0, 7 | Hfg: 2501000.0, 8 | RAir: 287.055, 9 | TKelConv: 273.15 }; 10 | 11 | psy.PREC = { rh: 0, 12 | wetbulb: 1, 13 | w: 3, 14 | dewpoint: 1, 15 | vappress: 1 }; 16 | 17 | // tdb = $('#ta').val() 18 | // hum = $('#rh').val() 19 | // psy.convert(hum, tdb, window.humUnit, 'rh') 20 | 21 | 22 | psy.convert = function(x, tdb, origin, target){ 23 | switch (origin){ 24 | case 'rh': 25 | a = this.tdb_rh(tdb, x); 26 | break; 27 | case 'wetbulb': 28 | a = this.tdb_twb(tdb, x); 29 | break; 30 | case 'w': 31 | a = this.tdb_w(tdb, x); 32 | break; 33 | case 'dewpoint': 34 | a = this.tdb_dewpoint(tdb, x); 35 | break; 36 | case 'vappress': 37 | a = this.tdb_vappress(tdb, x); 38 | break; 39 | } 40 | switch (target){ 41 | case 'rh': 42 | return a.rh; 43 | case 'wetbulb': 44 | return a.wetbulb; 45 | case 'w': 46 | return a.w; 47 | case 'dewpoint': 48 | return a.dewpoint; 49 | case 'vappress': 50 | return a.vappress; 51 | } 52 | } 53 | 54 | psy.tdb_rh = function(tdb, rh){ 55 | var a = {}; 56 | var psat = this.satpress(tdb); 57 | 58 | a.rh = parseFloat(rh); 59 | a.vappress = rh/100 * psat; 60 | a.w = this.humratio(this.PROP.Patm, a.vappress); 61 | a.wetbulb = this.wetbulb(tdb, a.w); 62 | a.dewpoint = this.dewpoint(a.w); 63 | return a; 64 | } 65 | 66 | psy.tdb_twb = function(tdb, twb){ 67 | var a = {}; 68 | var psat = this.satpress(twb); 69 | var PROP = this.PROP; 70 | var wstar = this.humratio(PROP.Patm, psat); 71 | 72 | a.wetbulb = twb; 73 | a.w = ((PROP.Hfg + (PROP.CpVap - PROP.CpWat) * twb) * wstar - 74 | PROP.CpAir * (tdb - twb)) / 75 | (PROP.Hfg + PROP.CpVap * tdb - PROP.CpWat * twb); 76 | psat = this.satpress(tdb); 77 | a.rh = 100 * this.relhum(PROP.Patm, psat, a.w); 78 | a.dewpoint = this.dewpoint(a.w); 79 | a.vappress = a.rh / 100 * psat; 80 | 81 | return a; 82 | } 83 | 84 | psy.tdb_w = function(tdb, w){ 85 | var a = {}; 86 | var psat = this.satpress(tdb); 87 | 88 | a.w = w; 89 | a.rh = 100 * psy.relhum(this.PROP.Patm, psat, w); 90 | a.wetbulb = this.wetbulb(tdb, w); 91 | a.dewpoint = this.dewpoint(w); 92 | a.vappress = a.rh / 100 * psat; 93 | 94 | return a; 95 | } 96 | 97 | psy.tdb_dewpoint = function(tdb, dewpoint){ 98 | var w_l=0.00001, w_r=0.2, eps=0.0001; 99 | var fn = function(w){ 100 | var dpstar = psy.dewpoint(w); 101 | return dewpoint - dpstar; 102 | } 103 | var w = this.bisect(w_l, w_r, fn, eps, 0); 104 | return psy.tdb_w(tdb, w); 105 | } 106 | 107 | psy.tdb_vappress = function(tdb, vappress){ 108 | var psat = this.satpress(tdb); 109 | var rh = 100 * vappress / psat; 110 | 111 | return psy.tdb_rh(tdb, rh); 112 | } 113 | 114 | psy.drybulb = function(h, w){ 115 | var PROP = this.PROP; 116 | return (H - PROP.Hfg * w) / (PROP.CpAir + PROP.CpVap * w); 117 | } 118 | 119 | psy.wetbulb = function(tdb, w){ 120 | var psatStar, wStar, fn, eps=0.01, wetbulb_l=-100, wetbulb_r=150; 121 | var PROP = this.PROP; 122 | 123 | fn = function(t){ 124 | psatStar = psy.satpress(t); 125 | wStar = psy.humratio(PROP.Patm ,psatStar); 126 | newW = ((PROP.Hfg - PROP.CpWat - PROP.CpVap * t) * wStar - 127 | PROP.CpAir * (tdb - t)) / (PROP.Hfg + PROP.CpVap * tdb - 128 | PROP.CpWat * t); 129 | return (w - newW); 130 | } 131 | return this.bisect(wetbulb_l, wetbulb_r, fn, eps, 0); 132 | } 133 | 134 | psy.satpress = function(tdb){ 135 | var tKel = tdb + this.PROP.TKelConv, 136 | C1 = -5674.5359, 137 | C2 = 6.3925247, 138 | C3 = -0.9677843 * Math.pow(10,-2), 139 | C4 = 0.62215701 * Math.pow(10,-6), 140 | C5 = 0.20747825 * Math.pow(10,-8), 141 | C6 = -0.9484024 * Math.pow(10,-12), 142 | C7 = 4.1635019, 143 | C8 = -5800.2206, 144 | C9 = 1.3914993, 145 | C10 = -0.048640239, 146 | C11 = 0.41764768 * Math.pow(10,-4), 147 | C12 = -0.14452093 * Math.pow(10,-7), 148 | C13 = 6.5459673, 149 | pascals; 150 | 151 | if (tKel < 273.15){ 152 | pascals = Math.exp(C1/tKel+C2+tKel*(C3+tKel*(C4+tKel*(C5+C6*tKel)))+C7*Math.log(tKel)); 153 | }else if (tKel >= 273.15){ 154 | pascals = Math.exp(C8/tKel+C9+tKel*(C10+tKel*(C11+tKel*C12))+C13*Math.log(tKel)); 155 | } 156 | return pascals; 157 | } 158 | 159 | psy.relhum = function(patm, psat, humRatio){ 160 | var pw, rh; 161 | pw = patm * humRatio / (0.62198 + humRatio); 162 | rh = pw / psat; 163 | return rh; 164 | } 165 | 166 | psy.humratio = function(patm, pw){ 167 | // ASHRAE Fundamentals 2009: 0.621945 168 | return 0.62198 * pw / (patm - pw); 169 | } 170 | 171 | psy.enthalpy = function(tdb, w){ 172 | var hDryAir, hSatVap, h; 173 | var PROP = this.PROP; 174 | hDryAir = PROP.CpAir * tdb; 175 | hSatVap = PROP.Hfg + PROP.CpVap * tdb; 176 | h = hDryAir + w * hSatVap; 177 | return h; 178 | } 179 | 180 | psy.rhodry = function(tdb, w){ 181 | var PROP = this.PROP; 182 | var pAir = 0.62198 * PROP.Patm / (0.62198 + w) 183 | return pAir / PROP.RAir / (tdb + PROP.TKelConv); 184 | } 185 | 186 | psy.rhomoist = function(rhodry, w){ 187 | return rhodry * (1 + w); 188 | } 189 | 190 | psy.enthsat = function(tdb){ 191 | var psat = this.satpress(tdb); 192 | var w = this.humratio(this.PROP.Patm, psat); 193 | 194 | return this.enthalpy(tdb, w); 195 | } 196 | 197 | psy.dewpoint = function(w){ 198 | var pw = this.PROP.Patm * w / (0.62198 + w); 199 | 200 | return this.sattemp(pw); 201 | } 202 | 203 | psy.sattemp = function(p){ 204 | var tsat_l = 0, tsat_r = 500, eps = 0.0001, psat; 205 | var fn = function(t){ 206 | return (p - psy.satpress(t)); 207 | } 208 | 209 | return this.bisect(tsat_l, tsat_r, fn, eps, 0); 210 | } 211 | 212 | psy.tairsat = function(hsat){ 213 | var tsat_l = 0, tsat_r = 1000, eps = 0.01; 214 | var fn = function(t){ 215 | return (hsat - psy.enthsat(t)); 216 | } 217 | return this.bisect(tsat_l, tsat_r, fn, eps, 0); 218 | } 219 | 220 | psy.bisect = function(a, b, fn, epsilon, target){ 221 | var a_T, b_T, midpoint, midpoint_T; 222 | while (Math.abs(b - a) > 2*epsilon) { 223 | midpoint = (b + a) / 2; 224 | a_T = fn(a); 225 | b_T = fn(b); 226 | midpoint_T = fn(midpoint); 227 | if ((a_T - target) * (midpoint_T - target) < 0) 228 | b = midpoint; 229 | else if ((b_T - target) * (midpoint_T - target) < 0) 230 | a = midpoint; 231 | else 232 | return -999; 233 | } 234 | return midpoint; 235 | } 236 | 237 | psy.globetemp = function(ta, vel, tglobe, diameter, emissivity){ 238 | pow = Math.pow; 239 | return pow(pow(tglobe + 273, 4) + (1.1 * pow(10,8) * pow(vel, 0.6)) / (emissivity * pow(diameter,0.4)) * (tglobe - ta), 0.25) - 273; 240 | } 241 | 242 | // for use with node 243 | // exports.psy = psy; 244 | 245 | 246 | -------------------------------------------------------------------------------- /js/psychchart.js: -------------------------------------------------------------------------------- 1 | 2 | var pc = new function() { 3 | 4 | var CtoF = function(x){ return x * 9 / 5 + 32 } 5 | 6 | this.margin = 40 7 | this.rbmargin = 60 8 | this.width = 700 9 | this.height = 500 10 | this.db_min = 10 11 | this.db_max = 36 12 | 13 | this.db_extent = [this.db_min, this.db_max] 14 | this.db_scale = d3.scale.linear() 15 | .range([this.margin,this.width - this.rbmargin]) 16 | .domain(this.db_extent) 17 | 18 | 19 | this.db_extent_F = [CtoF(this.db_min), CtoF(this.db_max)] 20 | this.db_scale_F = d3.scale.linear() 21 | .range([this.margin,this.width - this.rbmargin]) 22 | .domain(this.db_extent_F) 23 | 24 | this.hr_extent = [0, 30] 25 | this.hr_scale = d3.scale.linear() 26 | .range([this.height - this.rbmargin, this.rbmargin]) 27 | .domain(this.hr_extent) 28 | 29 | this.pline = d3.svg.line() 30 | .x(function(d){return this.db_scale(d.db)}) 31 | .y(function(d){return this.hr_scale(1000 * d.hr)}) 32 | 33 | this.drawChart = function(data) { 34 | 35 | console.log(data) 36 | var db_axis = d3.svg.axis().scale(pc.db_scale) 37 | var db_axis_F = d3.svg.axis().scale(pc.db_scale_F) 38 | var hr_axis = d3.svg.axis().scale(pc.hr_scale).orient("right") 39 | 40 | var line = d3.svg.line() 41 | .x(function(d){return pc.db_scale(d.db)}) 42 | .y(function(d){return pc.hr_scale(1000 * d.hr)}) 43 | .interpolate('cardinal') 44 | 45 | var dpoly = data.rh100.concat({"db":9, "hr": 0.03}) 46 | 47 | d3.select("body") 48 | .append("svg") 49 | .attr("class", "chart") 50 | .attr("width", pc.width) 51 | .attr("height", pc.height) 52 | 53 | d3.select("svg") 54 | .append("rect") 55 | .attr("width", pc.width - pc.margin - pc.rbmargin) 56 | .attr("height", pc.height - pc.margin - pc.rbmargin-20) 57 | .attr("class", "chartbg") 58 | .attr("transform", "translate(" + pc.margin + "," + pc.rbmargin + ")") 59 | 60 | d3.select("svg") 61 | .append("defs") 62 | .append("clipPath") 63 | .attr("id", "clip") 64 | .append("rect") 65 | .attr("x", "0") 66 | .attr("y", "0") 67 | .attr("width", pc.width - pc.margin - pc.rbmargin) 68 | .attr("height", pc.height - pc.margin - pc.rbmargin-20) 69 | .attr("transform", "translate(" + pc.margin + "," + pc.rbmargin + ")") 70 | 71 | d3.select("svg") 72 | .append("path") 73 | .attr("d", line(dpoly)) 74 | .attr("class", "w") 75 | 76 | d3.select("svg") 77 | .append("path") 78 | .attr("d", line(data.rh100)) 79 | .attr("class", "rh100") 80 | .attr("clip-path", "url(#clip)") 81 | 82 | for (var key in data){ 83 | if (key=="rh100") continue 84 | d3.select("svg") 85 | .append("path") 86 | .attr("d", line(data[key])) 87 | .attr("class", "rhline") 88 | .attr("clip-path", "url(#clip)") 89 | } 90 | 91 | d3.select("svg") 92 | .append("g") 93 | .attr("class", "db axis") 94 | .attr("id", "db-axis-C") 95 | .attr("transform", "translate(0," + (pc.height - pc.rbmargin) + ")") 96 | .call(db_axis) 97 | 98 | d3.select("svg") 99 | .append("g") 100 | .attr("class", "db axis") 101 | .attr("id", "db-axis-F") 102 | .attr("opacity", "0") 103 | .attr("transform", "translate(0," + (pc.height - pc.rbmargin) + ")") 104 | .call(db_axis_F) 105 | 106 | d3.select("svg") 107 | .append("g") 108 | .attr("class", "hr axis") 109 | .attr("transform", "translate(" + (pc.width - pc.rbmargin) + ",0)") 110 | .call(hr_axis) 111 | 112 | d3.select("#db-axis-C") 113 | .append("text") 114 | .text("Drybulb Temperature [°C]") 115 | .attr("id", "db-unit") 116 | .attr("x", (pc.width / 2) - 1.9 * pc.margin) 117 | .attr("y", pc.rbmargin / 1.3) 118 | 119 | d3.select("#db-axis-F") 120 | .append("text") 121 | .text("Drybulb Temperature [°F]") 122 | .attr("id", "db-unit") 123 | .attr("x", (pc.width / 2) - 1.9 * pc.margin) 124 | .attr("y", pc.rbmargin / 1.3) 125 | 126 | d3.select(".hr.axis") 127 | .append("text") 128 | .attr("id", "hr-text") 129 | .attr("transform", "rotate (-90, -43, 0) translate(-360,90)") 130 | .append("tspan") 131 | .text("Humidity Ratio [g") 132 | .attr("id", "hr-unit0") 133 | 134 | d3.select("#hr-text") 135 | .append("tspan") 136 | .text("w") 137 | .style("baseline-shift", "sub") 138 | 139 | d3.select("#hr-text") 140 | .append("tspan") 141 | .text(" / kg") 142 | .attr("id", "hr-unit1") 143 | 144 | d3.select("#hr-text") 145 | .append("tspan") 146 | .text("da") 147 | .style("baseline-shift", "sub") 148 | 149 | d3.select("#hr-text") 150 | .append("tspan") 151 | .text("]") 152 | } 153 | 154 | this.drawComfortRegion = function(data){ 155 | 156 | d3.select("svg") 157 | .append("path") 158 | .attr("clip-path", "url(#clip)") 159 | .attr("d", pc.pline(data) + "Z") 160 | .attr("class", "comfortzone") 161 | 162 | } 163 | 164 | this.redrawComfortRegion = function(data){ 165 | 166 | d3.select("path.comfortzone") 167 | .attr("d", pc.pline(data) + "Z") 168 | 169 | } 170 | 171 | this.drawPoint = function(data){ 172 | 173 | d3.select("svg") 174 | .append("circle") 175 | .attr("class", "outer") 176 | .attr("r", 12) 177 | 178 | d3.select("svg") 179 | .append("circle") 180 | .attr("class", "inner") 181 | .attr("r", 2) 182 | 183 | d3.selectAll("circle") 184 | .attr("cx", pc.db_scale(data[0].db)) 185 | .attr("cy", pc.hr_scale(1000 * data[0].hr)) 186 | 187 | } 188 | 189 | this.redrawPoint = function(data) { 190 | 191 | d3.selectAll("circle") 192 | .attr("cx", pc.db_scale(data[0].db)) 193 | .attr("cy", pc.hr_scale(1000 * data[0].hr)) 194 | 195 | } 196 | 197 | this.getHumRatio = function(db, rh) { 198 | return psy.humratio(psy.PROP.Patm, rh * psy.satpress(db) / 100) 199 | } 200 | 201 | this.findComfortBoundary = function(d, pmvlimit) { 202 | var boundary = [] 203 | 204 | function solve(rh, target){ 205 | var epsilon = 0.001 206 | var a = 0 207 | var b = 100 208 | var fn = function(db){ 209 | return pmvElevatedAirspeed(db, d.tr, d.vel, rh, d.met, d.clo, d.wme)[0][0] 210 | } 211 | t = psy.bisect(a, b, fn, epsilon, target) 212 | return {"db": t, "hr": pc.getHumRatio(t,rh)} 213 | } 214 | 215 | for (rh = 0; rh <= 100; rh += 10){ 216 | boundary.push(solve(rh, -pmvlimit)) 217 | } 218 | while (true){ 219 | t += 0.5 220 | boundary.push({"db": t, "hr": pc.getHumRatio(t,100)}) 221 | if (pmvElevatedAirspeed(t, d.tr, d.vel, rh, d.met, d.clo, d.wme)[0][0] > pmvlimit) break 222 | } 223 | for (rh = 100; rh >= 0; rh -= 10){ 224 | boundary.push(solve(rh, pmvlimit)) 225 | } 226 | return boundary 227 | } 228 | 229 | this.setupChart = function(d){ 230 | d3.json('data/rh-curves.json', pc.drawChart) 231 | var json = [{"db": d.ta, "hr": pc.getHumRatio(d.ta, d.rh)}] 232 | var b = pc.findComfortBoundary(d,0.5) 233 | setTimeout(function(){pc.drawComfortRegion(b)}, 10) 234 | setTimeout(function(){pc.drawPoint(json)}, 10) 235 | } 236 | 237 | this.toggleUnits = function(isCelsius) { 238 | 239 | if (isCelsius){ 240 | d3.select("#db-axis-C").attr("opacity", "100") 241 | d3.select("#db-axis-F").attr("opacity", "0") 242 | document.getElementById('hr-unit0').textContent = "Humidity Ratio [g" 243 | document.getElementById('hr-unit1').textContent = "/ kg" 244 | }else{ 245 | d3.select("#db-axis-C").attr("opacity", "0") 246 | d3.select("#db-axis-F").attr("opacity", "100") 247 | document.getElementById('hr-unit0').textContent = "Humidity Ratio [lb" 248 | document.getElementById('hr-unit1').textContent = "/ klb" 249 | } 250 | 251 | } 252 | 253 | } 254 | -------------------------------------------------------------------------------- /data/rh-curves.json: -------------------------------------------------------------------------------- 1 | { 2 | "rh10": [ 3 | { 4 | "db": 10, 5 | "hr": 0.000754715 6 | }, 7 | { 8 | "db": 12, 9 | "hr": 0.000862169 10 | }, 11 | { 12 | "db": 14, 13 | "hr": 0.000982888 14 | }, 15 | { 16 | "db": 16, 17 | "hr": 0.00111825 18 | }, 19 | { 20 | "db": 18, 21 | "hr": 0.001269745 22 | }, 23 | { 24 | "db": 20, 25 | "hr": 0.001438988 26 | }, 27 | { 28 | "db": 22, 29 | "hr": 0.001627721 30 | }, 31 | { 32 | "db": 24, 33 | "hr": 0.001837824 34 | }, 35 | { 36 | "db": 26, 37 | "hr": 0.002071322 38 | }, 39 | { 40 | "db": 28, 41 | "hr": 0.002330393 42 | }, 43 | { 44 | "db": 30, 45 | "hr": 0.002617379 46 | }, 47 | { 48 | "db": 32, 49 | "hr": 0.002934792 50 | }, 51 | { 52 | "db": 34, 53 | "hr": 0.003285329 54 | }, 55 | { 56 | "db": 36, 57 | "hr": 0.003671875 58 | } 59 | ], 60 | "rh20": [ 61 | { 62 | "db": 10, 63 | "hr": 0.001511264 64 | }, 65 | { 66 | "db": 12, 67 | "hr": 0.001726732 68 | }, 69 | { 70 | "db": 14, 71 | "hr": 0.001968888 72 | }, 73 | { 74 | "db": 16, 75 | "hr": 0.002240528 76 | }, 77 | { 78 | "db": 18, 79 | "hr": 0.002544685 80 | }, 81 | { 82 | "db": 20, 83 | "hr": 0.00288465 84 | }, 85 | { 86 | "db": 22, 87 | "hr": 0.003263984 88 | }, 89 | { 90 | "db": 24, 91 | "hr": 0.003686542 92 | }, 93 | { 94 | "db": 26, 95 | "hr": 0.004156486 96 | }, 97 | { 98 | "db": 28, 99 | "hr": 0.004678315 100 | }, 101 | { 102 | "db": 30, 103 | "hr": 0.00525688 104 | }, 105 | { 106 | "db": 32, 107 | "hr": 0.005897412 108 | }, 109 | { 110 | "db": 34, 111 | "hr": 0.006605548 112 | }, 113 | { 114 | "db": 36, 115 | "hr": 0.007387362 116 | } 117 | ], 118 | "rh30": [ 119 | { 120 | "db": 10, 121 | "hr": 0.002269654 122 | }, 123 | { 124 | "db": 12, 125 | "hr": 0.002593698 126 | }, 127 | { 128 | "db": 14, 129 | "hr": 0.002958014 130 | }, 131 | { 132 | "db": 16, 133 | "hr": 0.003366856 134 | }, 135 | { 136 | "db": 18, 137 | "hr": 0.003824852 138 | }, 139 | { 140 | "db": 20, 141 | "hr": 0.004337032 142 | }, 143 | { 144 | "db": 22, 145 | "hr": 0.004908857 146 | }, 147 | { 148 | "db": 24, 149 | "hr": 0.005546249 150 | }, 151 | { 152 | "db": 26, 153 | "hr": 0.006255632 154 | }, 155 | { 156 | "db": 28, 157 | "hr": 0.007043964 158 | }, 159 | { 160 | "db": 30, 161 | "hr": 0.007918784 162 | }, 163 | { 164 | "db": 32, 165 | "hr": 0.008888255 166 | }, 167 | { 168 | "db": 34, 169 | "hr": 0.009961217 170 | }, 171 | { 172 | "db": 36, 173 | "hr": 0.011147242 174 | } 175 | ], 176 | "rh40": [ 177 | { 178 | "db": 10, 179 | "hr": 0.003029891 180 | }, 181 | { 182 | "db": 12, 183 | "hr": 0.003463078 184 | }, 185 | { 186 | "db": 14, 187 | "hr": 0.003950281 188 | }, 189 | { 190 | "db": 16, 191 | "hr": 0.004497255 192 | }, 193 | { 194 | "db": 18, 195 | "hr": 0.005110278 196 | }, 197 | { 198 | "db": 20, 199 | "hr": 0.005796182 200 | }, 201 | { 202 | "db": 22, 203 | "hr": 0.006562406 204 | }, 205 | { 206 | "db": 24, 207 | "hr": 0.007417045 208 | }, 209 | { 210 | "db": 26, 211 | "hr": 0.008368899 212 | }, 213 | { 214 | "db": 28, 215 | "hr": 0.009427541 216 | }, 217 | { 218 | "db": 30, 219 | "hr": 0.010603378 220 | }, 221 | { 222 | "db": 32, 223 | "hr": 0.011907728 224 | }, 225 | { 226 | "db": 34, 227 | "hr": 0.013352907 228 | }, 229 | { 230 | "db": 36, 231 | "hr": 0.014952315 232 | } 233 | ], 234 | "rh50": [ 235 | { 236 | "db": 10, 237 | "hr": 0.003791981 238 | }, 239 | { 240 | "db": 12, 241 | "hr": 0.004334881 242 | }, 243 | { 244 | "db": 14, 245 | "hr": 0.004945703 246 | }, 247 | { 248 | "db": 16, 249 | "hr": 0.005631749 250 | }, 251 | { 252 | "db": 18, 253 | "hr": 0.006400995 254 | }, 255 | { 256 | "db": 20, 257 | "hr": 0.007262146 258 | }, 259 | { 260 | "db": 22, 261 | "hr": 0.008224702 262 | }, 263 | { 264 | "db": 24, 265 | "hr": 0.009299028 266 | }, 267 | { 268 | "db": 26, 269 | "hr": 0.010496432 270 | }, 271 | { 272 | "db": 28, 273 | "hr": 0.011829251 274 | }, 275 | { 276 | "db": 30, 277 | "hr": 0.013310953 278 | }, 279 | { 280 | "db": 32, 281 | "hr": 0.014956244 282 | }, 283 | { 284 | "db": 34, 285 | "hr": 0.0167812 286 | }, 287 | { 288 | "db": 36, 289 | "hr": 0.018803402 290 | } 291 | ], 292 | "rh60": [ 293 | { 294 | "db": 10, 295 | "hr": 0.004555933 296 | }, 297 | { 298 | "db": 12, 299 | "hr": 0.005209119 300 | }, 301 | { 302 | "db": 14, 303 | "hr": 0.005944297 304 | }, 305 | { 306 | "db": 16, 307 | "hr": 0.00677036 308 | }, 309 | { 310 | "db": 18, 311 | "hr": 0.007697037 312 | }, 313 | { 314 | "db": 20, 315 | "hr": 0.008734973 316 | }, 317 | { 318 | "db": 22, 319 | "hr": 0.009895814 320 | }, 321 | { 322 | "db": 24, 323 | "hr": 0.011192301 324 | }, 325 | { 326 | "db": 26, 327 | "hr": 0.012638375 328 | }, 329 | { 330 | "db": 28, 331 | "hr": 0.014249302 332 | }, 333 | { 334 | "db": 30, 335 | "hr": 0.016041805 336 | }, 337 | { 338 | "db": 32, 339 | "hr": 0.018034224 340 | }, 341 | { 342 | "db": 34, 343 | "hr": 0.020246692 344 | }, 345 | { 346 | "db": 36, 347 | "hr": 0.022701342 348 | } 349 | ], 350 | "rh70": [ 351 | { 352 | "db": 10, 353 | "hr": 0.005321752 354 | }, 355 | { 356 | "db": 12, 357 | "hr": 0.0060858 358 | }, 359 | { 360 | "db": 14, 361 | "hr": 0.006946078 362 | }, 363 | { 364 | "db": 16, 365 | "hr": 0.007913109 366 | }, 367 | { 368 | "db": 18, 369 | "hr": 0.008998435 370 | }, 371 | { 372 | "db": 20, 373 | "hr": 0.01021471 374 | }, 375 | { 376 | "db": 22, 377 | "hr": 0.011575812 378 | }, 379 | { 380 | "db": 24, 381 | "hr": 0.013096963 382 | }, 383 | { 384 | "db": 26, 385 | "hr": 0.014794875 386 | }, 387 | { 388 | "db": 28, 389 | "hr": 0.016687905 390 | }, 391 | { 392 | "db": 30, 393 | "hr": 0.018796237 394 | }, 395 | { 396 | "db": 32, 397 | "hr": 0.021142097 398 | }, 399 | { 400 | "db": 34, 401 | "hr": 0.023749992 402 | }, 403 | { 404 | "db": 36, 405 | "hr": 0.026646994 406 | } 407 | ], 408 | "rh80": [ 409 | { 410 | "db": 10, 411 | "hr": 0.006089445 412 | }, 413 | { 414 | "db": 12, 415 | "hr": 0.006964936 416 | }, 417 | { 418 | "db": 14, 419 | "hr": 0.007951059 420 | }, 421 | { 422 | "db": 16, 423 | "hr": 0.00906002 424 | }, 425 | { 426 | "db": 18, 427 | "hr": 0.010305225 428 | }, 429 | { 430 | "db": 20, 431 | "hr": 0.011701408 432 | }, 433 | { 434 | "db": 22, 435 | "hr": 0.013264767 436 | }, 437 | { 438 | "db": 24, 439 | "hr": 0.015013119 440 | }, 441 | { 442 | "db": 26, 443 | "hr": 0.016966082 444 | }, 445 | { 446 | "db": 28, 447 | "hr": 0.019145273 448 | }, 449 | { 450 | "db": 30, 451 | "hr": 0.021574554 452 | }, 453 | { 454 | "db": 32, 455 | "hr": 0.0242803 456 | }, 457 | { 458 | "db": 34, 459 | "hr": 0.027291722 460 | }, 461 | { 462 | "db": 36, 463 | "hr": 0.030641242 464 | } 465 | ], 466 | "rh90": [ 467 | { 468 | "db": 10, 469 | "hr": 0.00685902 470 | }, 471 | { 472 | "db": 12, 473 | "hr": 0.007846536 474 | }, 475 | { 476 | "db": 14, 477 | "hr": 0.008959258 478 | }, 479 | { 480 | "db": 16, 481 | "hr": 0.010211115 482 | }, 483 | { 484 | "db": 18, 485 | "hr": 0.011617438 486 | }, 487 | { 488 | "db": 20, 489 | "hr": 0.013195114 490 | }, 491 | { 492 | "db": 22, 493 | "hr": 0.014962751 494 | }, 495 | { 496 | "db": 24, 497 | "hr": 0.016940873 498 | }, 499 | { 500 | "db": 26, 501 | "hr": 0.019152145 502 | }, 503 | { 504 | "db": 28, 505 | "hr": 0.021621624 506 | }, 507 | { 508 | "db": 30, 509 | "hr": 0.024377069 510 | }, 511 | { 512 | "db": 32, 513 | "hr": 0.02744928 514 | }, 515 | { 516 | "db": 34, 517 | "hr": 0.030872519 518 | }, 519 | { 520 | "db": 36, 521 | "hr": 0.034684987 522 | } 523 | ], 524 | "rh100": [ 525 | { 526 | "db": 10, 527 | "hr": 0.007630483 528 | }, 529 | { 530 | "db": 12, 531 | "hr": 0.008730611 532 | }, 533 | { 534 | "db": 14, 535 | "hr": 0.009970689 536 | }, 537 | { 538 | "db": 16, 539 | "hr": 0.011366417 540 | }, 541 | { 542 | "db": 18, 543 | "hr": 0.012935109 544 | }, 545 | { 546 | "db": 20, 547 | "hr": 0.014695879 548 | }, 549 | { 550 | "db": 22, 551 | "hr": 0.016669837 552 | }, 553 | { 554 | "db": 24, 555 | "hr": 0.018880331 556 | }, 557 | { 558 | "db": 26, 559 | "hr": 0.021353218 560 | }, 561 | { 562 | "db": 28, 563 | "hr": 0.02411718 564 | }, 565 | { 566 | "db": 30, 567 | "hr": 0.027204099 568 | }, 569 | { 570 | "db": 32, 571 | "hr": 0.030649492 572 | }, 573 | { 574 | "db": 34, 575 | "hr": 0.034493031 576 | }, 577 | { 578 | "db": 36, 579 | "hr": 0.038779157 580 | } 581 | ] 582 | } -------------------------------------------------------------------------------- /d3.js: -------------------------------------------------------------------------------- 1 | (function(){function e(a,b){try{for(var c in b)Object.defineProperty(a.prototype,c,{value:b[c],enumerable:!1})}catch(d){a.prototype=b}}function g(a){var b=-1,c=a.length,d=[];while(++b0?e=c:e=0:c>0&&(b.start({type:"start",alpha:e=c}),d3.timer(a.tick)),a):e},a.start=function(){function s(a,c){var d=t(b),e=-1,f=d.length,g;while(++ee&&(e=h),d.push(h)}for(g=0;g =i[0]&&o<=i[1]&&(k=g[d3.bisect(j,o,1,m)-1],k.y+=n,k.push(e[f]));return g}var a=!0,b=Number,c=d_,d=dZ;return e.value=function(a){return arguments.length?(b=a,e):b},e.range=function(a){return arguments.length?(c=d3.functor(a),e):c},e.bins=function(a){return arguments.length?(d=typeof a=="number"?function(b){return d$(b,a)}:d3.functor(a),e):d},e.frequency=function(b){return arguments.length?(a=!!b,e):a},e},d3.layout.hierarchy=function(){function e(f,h,i){var j=b.call(g,f,h),k=ef?f:{data:f};k.depth=h,i.push(k);if(j&&(m=j.length)){var l=-1,m,n=k.children=[],o=0,p=h+1;while(++l 0&&(eD(eE(g,a,d),a,m),i+=m,j+=m),k+=g._tree.mod,i+=e._tree.mod,l+=h._tree.mod,j+=f._tree.mod;g&&!ew(f)&&(f._tree.thread=g,f._tree.mod+=k-j),e&&!ev(h)&&(h._tree.thread=e,h._tree.mod+=i-l,d=a)}return d}var f=a.call(this,d,e),g=f[0];eB(g,function(a,b){a._tree={ancestor:a,prelim:0,mod:0,change:0,shift:0,number:b?b._tree.number+1:0}}),h(g),i(g,-g._tree.prelim);var k=ex(g,ez),l=ex(g,ey),m=ex(g,eA),n=k.x-b(k,l)/2,o=l.x+b(l,k)/2,p=m.depth||1;return eB(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=a.depth/p*c[1],delete a._tree}),f}var a=d3.layout.hierarchy().sort(null).value(null),b=eu,c=[1,1];return d.separation=function(a){return arguments.length?(b=a,d):b},d.size=function(a){return arguments.length?(c=a,d):c},ea(d,a)},d3.layout.treemap=function(){function i(a,b){var c=-1,d=a.length,e,f;while(++c 0)d.push(g=f[o-1]),d.area+=g.area,(k=l(d,n))<=h?(f.pop(),h=k):(d.area-=d.pop().area,m(d,n,c,!1),n=Math.min(c.dx,c.dy),d.length=d.area=0,h=Infinity);d.length&&(m(d,n,c,!0),d.length=d.area=0),b.forEach(j)}}function k(a){var b=a.children;if(b&&b.length){var c=e(a),d=b.slice(),f,g=[];i(d,c.dx*c.dy/a.value),g.area=0;while(f=d.pop())g.push(f),g.area+=f.area,f.z!=null&&(m(g,f.z?c.dx:c.dy,c,!d.length),g.length=g.area=0);b.forEach(k)}}function l(a,b){var c=a.area,d,e=0,f=Infinity,g=-1,i=a.length;while(++ge&&(e=d)}return c*=c,b*=b,c?Math.max(b*e*h/c,c/(b*f*h)):Infinity}function m(a,c,d,e){var f=-1,g=a.length,h=d.x,i=d.y,j=c?b(a.area/c):0,k;if(c==d.dx){if(e||j>d.dy)j=d.dy;while(++f d.dx)j=d.dx;while(++f =a.length)return d;if(i)return i=!1,c;var b=f.lastIndex;if(a.charCodeAt(b)===34){var e=b;while(e++ 50?b:f<-140?c:g<21?d:a)(e)}var a=d3.geo.albers(),b=d3.geo.albers().origin([-160,60]).parallels([55,65]),c=d3.geo.albers().origin([-160,20]).parallels([8,18]),d=d3.geo.albers().origin([-60,10]).parallels([8,18]);return e.scale=function(f){return arguments.length?(a.scale(f),b.scale(f*.6),c.scale(f),d.scale(f*1.5),e.translate(a.translate())):a.scale()},e.translate=function(f){if(!arguments.length)return a.translate();var g=a.scale()/1e3,h=f[0],i=f[1];return a.translate(f),b.translate([h-400*g,i+170*g]),c.translate([h-190*g,i+200*g]),d.translate([h+580*g,i+430*g]),e},e.scale(a.scale())},d3.geo.bonne=function(){function g(g){var h=g[0]*eJ-c,i=g[1]*eJ-d;if(e){var j=f+e-i,k=h*Math.cos(i)/j;h=j*Math.sin(k),i=j*Math.cos(k)-f}else h*=Math.cos(i),i*=-1;return[a*h+b[0],a*i+b[1]]}var a=200,b=[480,250],c,d,e,f;return g.invert=function(d){var g=(d[0]-b[0])/a,h=(d[1]-b[1])/a;if(e){var i=f+h,j=Math.sqrt(g*g+i*i);h=f+e-j,g=c+j*Math.atan2(g,i)/Math.cos(h)}else h*=-1,g/=Math.cos(h);return[g/eJ,h/eJ]},g.parallel=function(a){return arguments.length?(f=1/Math.tan(e=a*eJ),g):e/eJ},g.origin=function(a){return arguments.length?(c=a[0]*eJ,d=a[1]*eJ,g):[c/eJ,d/eJ]},g.scale=function(b){return arguments.length?(a=+b,g):a},g.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],g):b},g.origin([0,0]).parallel(45)},d3.geo.equirectangular=function(){function c(c){var d=c[0]/360,e=-c[1]/360;return[a*d+b[0],a*e+b[1]]}var a=500,b=[480,250];return c.invert=function(c){var d=(c[0]-b[0])/a,e=(c[1]-b[1])/a;return[360*d,-360*e]},c.scale=function(b){return arguments.length?(a=+b,c):a},c.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],c):b},c},d3.geo.mercator=function(){function c(c){var d=c[0]/360,e=-(Math.log(Math.tan(Math.PI/4+c[1]*eJ/2))/eJ)/360;return[a*d+b[0],a*Math.max(-0.5,Math.min(.5,e))+b[1]]}var a=500,b=[480,250];return c.invert=function(c){var d=(c[0]-b[0])/a,e=(c[1]-b[1])/a;return[360*d,2*Math.atan(Math.exp(-360*e*eJ))/eJ-90]},c.scale=function(b){return arguments.length?(a=+b,c):a},c.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],c):b},c},d3.geo.path=function(){function d(c,d){return typeof a=="function"&&(b=eL(a.apply(this,arguments))),f(c)||null}function e(a){return c(a).join(",")}function h(a){var b=k(a[0]),c=0,d=a.length;while(++c 0){b.push("M");while(++h0){b.push("M");while(++k d&&(d=a),f e&&(e=f)}),[[b,c],[d,e]]};var eN={Feature:eO,FeatureCollection:eP,GeometryCollection:eQ,LineString:eR,MultiLineString:eS,MultiPoint:eR,MultiPolygon:eT,Point:eU,Polygon:eV};d3.geo.circle=function(){function e(){}function f(a){return d.distance(a) =k*k+l*l?d[f].index=-1:(d[m].index=-1,o=d[f].angle,m=f,n=g)):(o=d[f].angle,m=f,n=g);e.push(h);for(f=0,g=0;f<2;++g)d[g].index!==-1&&(e.push(d[g].index),f++);p=e.length;for(;g =0?(c=a.ep.r,d=a.ep.l):(c=a.ep.l,d=a.ep.r),a.a===1?(g=c?c.y:-1e6,e=a.c-a.b*g,h=d?d.y:1e6,f=a.c-a.b*h):(e=c?c.x:-1e6,g=a.c-a.a*e,f=d?d.x:1e6,h=a.c-a.a*f);var i=[e,g],j=[f,h];b[a.region.l.index].push(i,j),b[a.region.r.index].push(i,j)}),b.map(function(b,c){var d=a[c][0],e=a[c][1];return b.forEach(function(a){a.angle=Math.atan2(a[0]-d,a[1]-e)}),b.sort(function(a,b){return a.angle-b.angle}).filter(function(a,c){return!c||a.angle-b[c-1].angle>1e-10})})};var fd={l:"r",r:"l"};d3.geom.delaunay=function(a){var b=a.map(function(){return[]}),c=[];return fe(a,function(c){b[c.region.l.index].push(a[c.region.r.index])}),b.forEach(function(b,d){var e=a[d],f=e[0],g=e[1];b.forEach(function(a){a.angle=Math.atan2(a[0]-f,a[1]-g)}),b.sort(function(a,b){return a.angle-b.angle});for(var h=0,i=b.length-1;h=g,j=b.y>=h,l=(j<<1)+i;a.leaf=!1,a=a.nodes[l]||(a.nodes[l]=ff()),i?c=g:e=g,j?d=h:f=h,k(a,b,c,d,e,f)}var f,g=-1,h=a.length;h&&isNaN(a[0].x)&&(a=a.map(fh));if(arguments.length<5)if(arguments.length===3)e=d=c,c=b;else{b=c=Infinity,d=e=-Infinity;while(++g d&&(d=f.x),f.y>e&&(e=f.y);var i=d-b,j=e-c;i>j?e=c+i:d=b+j}var m=ff();return m.add=function(a){k(m,a,b,c,d,e)},m.visit=function(a){fg(a,m,b,c,d,e)},a.forEach(m.add),m},d3.time={};var fi=Date;fj.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(a){this._.setUTCDate(a)},setDay:function(a){this._.setUTCDay(a)},setFullYear:function(a){this._.setUTCFullYear(a)},setHours:function(a){this._.setUTCHours(a)},setMilliseconds:function(a){this._.setUTCMilliseconds(a)},setMinutes:function(a){this._.setUTCMinutes(a)},setMonth:function(a){this._.setUTCMonth(a)},setSeconds:function(a){this._.setUTCSeconds(a)},setTime:function(a){this._.setTime(a)}},d3.time.format=function(a){function c(c){var d=[],e=-1,f=0,g,h;while(++e=12?"PM":"AM"},S:function(a){return fl(a.getSeconds())},U:function(a){return fl(d3.time.sundayOfYear(a))},w:function(a){return a.getDay()},W:function(a){return fl(d3.time.mondayOfYear(a))},x:d3.time.format("%m/%d/%y"),X:d3.time.format("%H:%M:%S"),y:function(a){return fl(a.getFullYear()%100)},Y:function(a){return fn(a.getFullYear()%1e4)},Z:fR,"%":function(a){return"%"}},fq={a:fr,A:fs,b:fv,B:fx,c:fB,d:fI,e:fI,H:fJ,I:fK,L:fN,m:fH,M:fL,p:fP,S:fM,x:fC,X:fD,y:fF,Y:fE},ft=/^(?:sun|mon|tue|wed|thu|fri|sat)/i,fu=/^(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)/i;d3_time_weekdays=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var fw=d3.map({jan:0,feb:1,mar:2,apr:3,may:4,jun:5,jul:6,aug:7,sep:8,oct:9,nov:10,dec:11}),fy=/^(?:January|February|March|April|May|June|July|August|September|October|November|December)/ig,fz=d3.map({january:0,february:1,march:2,april:3,may:4,june:5,july:6,august:7,september:8,october:9,november:10,december:11}),fA=["January","February","March","April","May","June","July","August","September","October","November","December"],fO=/\s*\d+/,fQ=d3.map({am:0,pm:1});d3.time.format.utc=function(a){function c(a){try{fi=fj;var c=new fi;return c._=a,b(c)}finally{fi=Date}}var b=d3.time.format(a);return c.parse=function(a){try{fi=fj;var c=b.parse(a);return c&&c._}finally{fi=Date}},c.toString=b.toString,c};var fS=d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");d3.time.format.iso=Date.prototype.toISOString?fT:fS,fT.parse=function(a){return new Date(a)},fT.toString=fS.toString,d3.time.second=fU(function(a){return new fi(Math.floor(a/1e3)*1e3)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*1e3)},function(a){return a.getSeconds()}),d3.time.seconds=d3.time.second.range,d3.time.seconds.utc=d3.time.second.utc.range,d3.time.minute=fU(function(a){return new fi(Math.floor(a/6e4)*6e4)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*6e4)},function(a){return a.getMinutes()}),d3.time.minutes=d3.time.minute.range,d3.time.minutes.utc=d3.time.minute.utc.range,d3.time.hour=fU(function(a){var b=a.getTimezoneOffset()/60;return new fi((Math.floor(a/36e5-b)+b)*36e5)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*36e5)},function(a){return a.getHours()}),d3.time.hours=d3.time.hour.range,d3.time.hours.utc=d3.time.hour.utc.range,d3.time.day=fU(function(a){return new fi(a.getFullYear(),a.getMonth(),a.getDate())},function(a,b){a.setDate(a.getDate()+b)},function(a){return a.getDate()-1}),d3.time.days=d3.time.day.range,d3.time.days.utc=d3.time.day.utc.range,d3.time.dayOfYear=function(a){var b=d3.time.year(a);return Math.floor((a-b)/864e5-(a.getTimezoneOffset()-b.getTimezoneOffset())/1440)},d3_time_weekdays.forEach(function(a,b){a=a.toLowerCase(),b=7-b;var c=d3.time[a]=fU(function(a){return(a=d3.time.day(a)).setDate(a.getDate()-(a.getDay()+b)%7),a},function(a,b){a.setDate(a.getDate()+Math.floor(b)*7)},function(a){var c=d3.time.year(a).getDay();return Math.floor((d3.time.dayOfYear(a)+(c+b)%7)/7)-(c!==b)});d3.time[a+"s"]=c.range,d3.time[a+"s"].utc=c.utc.range,d3.time[a+"OfYear"]=function(a){var c=d3.time.year(a).getDay();return Math.floor((d3.time.dayOfYear(a)+(c+b)%7)/7)}}),d3.time.week=d3.time.sunday,d3.time.weeks=d3.time.sunday.range,d3.time.weeks.utc=d3.time.sunday.utc.range,d3.time.weekOfYear=d3.time.sundayOfYear,d3.time.month=fU(function(a){return new fi(a.getFullYear(),a.getMonth(),1)},function(a,b){a.setMonth(a.getMonth()+b)},function(a){return a.getMonth()}),d3.time.months=d3.time.month.range,d3.time.months.utc=d3.time.month.utc.range,d3.time.year=fU(function(a){return new fi(a.getFullYear(),0,1)},function(a,b){a.setFullYear(a.getFullYear()+b)},function(a){return a.getFullYear()}),d3.time.years=d3.time.year.range,d3.time.years.utc=d3.time.year.utc.range;var ga=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],gb=[[d3.time.second,1],[d3.time.second,5],[d3.time.second,15],[d3.time.second,30],[d3.time.minute,1],[d3.time.minute,5],[d3.time.minute,15],[d3.time.minute,30],[d3.time.hour,1],[d3.time.hour,3],[d3.time.hour,6],[d3.time.hour,12],[d3.time.day,1],[d3.time.day,2],[d3.time.week,1],[d3.time.month,1],[d3.time.month,3],[d3.time.year,1]],gc=[[d3.time.format("%Y"),function(a){return!0}],[d3.time.format("%B"),function(a){return a.getMonth()}],[d3.time.format("%b %d"),function(a){return a.getDate()!=1}],[d3.time.format("%a %d"),function(a){return a.getDay()&&a.getDate()!=1}],[d3.time.format("%I %p"),function(a){return a.getHours()}],[d3.time.format("%I:%M"),function(a){return a.getMinutes()}],[d3.time.format(":%S"),function(a){return a.getSeconds()}],[d3.time.format(".%L"),function(a){return a.getMilliseconds()}]],gd=d3.scale.linear(),ge=fZ(gc);gb.year=function(a,b){return gd.domain(a.map(f_)).ticks(b).map(f$)},d3.time.scale=function(){return fW(d3.scale.linear(),gb,ge)};var gf=gb.map(function(a){return[a[0].utc,a[1]]}),gg=[[d3.time.format.utc("%Y"),function(a){return!0}],[d3.time.format.utc("%B"),function(a){return a.getUTCMonth()}],[d3.time.format.utc("%b %d"),function(a){return a.getUTCDate()!=1}],[d3.time.format.utc("%a %d"),function(a){return a.getUTCDay()&&a.getUTCDate()!=1}],[d3.time.format.utc("%I %p"),function(a){return a.getUTCHours()}],[d3.time.format.utc("%I:%M"),function(a){return a.getUTCMinutes()}],[d3.time.format.utc(":%S"),function(a){return a.getUTCSeconds()}],[d3.time.format.utc(".%L"),function(a){return a.getUTCMilliseconds()}]],gh=fZ(gg);gf.year=function(a,b){return gd.domain(a.map(gj)).ticks(b).map(gi)},d3.time.scale.utc=function(){return fW(d3.scale.linear(),gf,gh)}})(); --------------------------------------------------------------------------------