1function getEventX(event) { 2 var posx = 0; 3 if (event.pageX || event.pageY) { 4 posx = event.pageX; 5 } 6 else if (event.clientX || event.clientY) { 7 posx = event.clientX + document.body.scrollLeft 8 + document.documentElement.scrollLeft; 9 } 10 return posx; 11} 12function getElementX(obj) { 13 var x = 0; 14 if (obj.offsetParent) { 15 do { 16 x += obj.offsetLeft; 17 } while (obj = obj.offsetParent); 18 } 19 return x; 20} 21function zeroPad(v, len) { 22 v = v.toString(); 23 return v.length >= len ? v : "00000000".substring(0, len - v.length) + v; 24} 25 26/** 27 * Check if the difference between the max and the min non zero capture numbers 28 * is larger than 3 orders of magnitude. If yes, we need to scale. 29**/ 30function capturegraph_scale_is_required(captures) { 31 var max = 0; 32 var min = 1000; 33 for (var i = 0; i < captures.length; i++) { 34 var year = captures[i]; 35 max = Math.max(max, Math.max.apply(null, year[1])); 36 min = Math.min(min, Math.min.apply(null, 37 year[1].filter(Boolean))); 38 } 39 return (Math.log1p(max) - Math.log1p(min) > 3); 40} 41 42/** 43 * Scale captugraph counts and max maxcount using log1p if necessary. 44 */ 45function capturegraph_scale(captures) { 46 var maxcount = 0; 47 for (var i = 0; i < captures.length; i++) { 48 maxcount = Math.max(maxcount, Math.max.apply(null, captures[i][1])); 49 } 50 if (capturegraph_scale_is_required(captures)) { 51 var scaled = []; 52 for (var i = 0; i < captures.length; i++) { 53 var year = captures[i]; 54 // XXX map may not be available on all platforms 55 scaled.push([year[0], year[1].map(Math.log1p)]); 56 } 57 captures = scaled; 58 maxcount = Math.log1p(maxcount); 59 } 60 return [captures, maxcount]; 61} 62 63/** 64 * Draw years, highlight current year, draw capture frequency per month 65 */ 66function sparkline(captures, width, height, canvas, start_year, 67 cur_year, cur_month) { 68 var ctx = canvas.getContext("2d"); 69 if (!ctx) return; 70 ctx.fillStyle = "#FFF"; 71 var end_year = new Date().getUTCFullYear(); 72 var year_width = width / (end_year - start_year + 1); 73 74 var scaled = capturegraph_scale(captures.years); 75 var years = scaled[0]; 76 var maxcount = scaled[1]; 77 78 var yscale = height / maxcount; 79 80 function year_left(year) { 81 return Math.ceil((year - start_year) * year_width) + 0.5; 82 } 83 84 if (cur_year >= start_year) { 85 var x = year_left(cur_year); 86 ctx.fillStyle = "#FFFFA5"; 87 ctx.fillRect(x, 0, year_width, height); 88 } 89 for (var year = start_year; year <= end_year; year++) { 90 var x = year_left(year); 91 ctx.beginPath(); 92 ctx.moveTo(x, 0); 93 ctx.lineTo(x, height); 94 ctx.lineWidth = 1; 95 ctx.strokeStyle = "#CCC"; 96 ctx.stroke(); 97 } 98 cur_month = parseInt(cur_month) - 1; 99 var month_width = (year_width - 1) / 12; 100 for (var i = 0; i < years.length; i++) { 101 var year = years[i][0]; 102 var months = years[i][1]; 103 var left = year_left(year) + 1.0; 104 for (var month = 0; month < 12; month++) { 105 var count = months[month]; 106 if (count > 0) { 107 var h = Math.ceil(count * yscale);
108 if (year == cur_year && month == cur_month) { 109 ctx.fillStyle = "#EC008C"; 110 } else { 111 ctx.fillStyle = "#000"; 112 } 113 // must note that when I use width=Math.round(month_width+1), 114 // the replay toolbar looks more accurate whereas the 115 // bubble calendar looks somehow different. 116 ctx.fillRect(Math.round(left), Math.ceil(height - h), 117 Math.ceil(month_width), Math.round(h)); 118 } 119 left += month_width; 120 } 121 } 122} 123 124function clear_canvas(canvas_id) { 125 var c = document.getElementById(canvas_id); 126 if (!c || !c.getContext) return; 127 var ctx = c.getContext("2d"); 128 if (!ctx) return; 129 ctx.clearRect(0, 0, c.width, c.height); 130}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.