1(function Timeline() { 2 /* global d3 */ 3 var svg = d3.select("#timeline"), 4 margin = { top: 20, right: 0, bottom: 40, left: 0 }, 5 // width = (svg.node().width.baseVal.value||900) - margin.left - margin.right, 6 width = 900 - margin.left - margin.right, 7 height = +svg.attr("height") - margin.top - margin.bottom, 8 g = svg 9 .append("g") 10 .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 11 var gData = g.append("g").attr("class", "data"); 12 var y = d3 13 .scaleBand() 14 .rangeRound([0, height]) 15 .paddingInner(0.05) 16 .align(0.1); 17 18 var x = d3.scaleTime(); 19 20 var color = d3.scaleOrdinal().range(["#507B94", "#86C6D7"]); 21 var parseDate = d3.timeParse("%m/%Y"); 22 23 var xAxis = g 24 .append("g") 25 .attr("class", "axis") 26 .attr("transform", "translate(0," + (height) + ")"); 27 xAxis.append("path").attr("class", "base"); 28 29 function fnWidth(d) { 30 return x(d.End) - x(d.Start) - 2; 31 } 32 33 function fnHeight(d) { 34 return (y.bandwidth() - 1) * d.Height; 35 } 36 function fnX() { 37 return 1; 38 } 39 function fnY(d) { 40 return d.yOffset * fnHeight(d) + 1; 41 } 42 function fnColor(d) { 43 return color(d.Type); 44 } 45 46 function update(data) { 47 try { 48 width = 49 (d3 50 .select("#timeline") 51 .node() 52 .getBoundingClientRect().width || 900) - 53 margin.left - 54 margin.right; 55 } catch (e) { 56 width = 900 - margin.left - margin.right; 57 } 58 59 x.domain([ 60 d3.min(data, function(d) { 61 return d.Start; 62 }), 63 d3.max(data, function(d) { 64 return d.End; 65 }), 66 ]).rangeRound([0, width]); 67 y.domain( 68 data.map(function(d) { 69 return d.Type; 70 }) 71 ); 72 // z.domain(keys); 73 74 var entries = gData.selectAll(".entry").data(data); 75 76 var entriesEnter = entries 77 .enter() 78 .append("g") 79 .attr("class", "entry"); 80 81 entriesEnter.merge(entries).attr("transform", function(d) { 82 return "translate(" + x(d.Start) + "," + y(d.Type) + ")"; 83 }); 84 85 entriesEnter 86 .append("rect") 87 .attr("rx", 2) 88 .attr("ry", 2) 89 .attr("width", 0) 90 .merge(entries.select("rect")) 91 .attr("x", fnX) 92 .attr("y", fnY) 93 94 .style("fill", fnColor) 95 .attr("height", fnHeight) 96 97 .transition() 98 .duration(1000) 99 .attr("width", fnWidth); 100 101 entriesEnter 102 .append("text") 103 .text(function(d) { 104 return d.Description; 105 }) 106 .merge(entries.select("text")) 107 .attr("x", function(d) { 108 return fnX(d) + fnWidth(d) / 2; 109 }) 110 .attr("y", function(d) { 111 return fnY(d) + fnHeight(d) / 2 + 5; 112 }); 113 114 xAxis 115 .transition() 116 .duration(2000) 117 .call(function(sel) { 118 sel.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%Y"))); 119 sel 120 .selectAll("line") 121 .attr("stroke", null) 122 .attr("y1", -6); 123 }) 124 .select(".base") 125 .attr( 126 "d", 127 d3.line()([ 128 [0, 0], 129 [width, 0], 130 ]) 131 ); 132 } 133 134 d3.csv( 135 "experience.csv", 136 function(d) { 137 d.Start = parseDate(d.Start); 138 d.End = d.End !== "-" ? parseDate(d.End) : new Date(); 139 return d; 140 } 141 ).then(function(data) { 142 update(data); 143 144 window.addEventListener("resize", function() { 145 update(data); 146 }); 147 }); 148})();
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.