1class SentimentPieChart{ 2 constructor(height, width, margin, element_selector){ 3 $(element_selector).empty(); 4 5 this.height = height; 6 this.width = width; 7 this.margin = margin; 8 this.radius = Math.min(this.width, this.height) / 2 - this.margin; 9 10 this.svg = d3.select(element_selector) 11 .attr("viewBox", [0, 0, this.width, this.height]) 12 .attr("perserveAspectRatio", "xMinYMid") 13 .attr("width", this.width) 14 .attr("height", this.height) 15 .append("g") 16 .attr("transform", "translate(" + this.width / 2 + "," + this.height / 2 + ")"); 17 18 this.svg.append("g") 19 .attr("class", "slices"); 20 this.svg.append("g") 21 .attr("class", "labels"); 22 this.svg.append("g") 23 .attr("class", "lines"); 24 25 this.color = d3.scaleOrdinal() 26 .domain(['strongly negative', 'negative', 'slightly negative', 'neutral','slightly positive', 'positive', 'strongly positive'], ) 27 .range([ '#DC143C', '#FF6347', '#FFA07A', '#EFE199', '#ADFF2F', '#32CD32', '#228B22'] ); 28 29 this.pie = d3.pie() 30 .sort(null) 31 .value(function(d) { 32 return d.accfreq; 33 }); 34 35 this.arc = d3.arc() 36 .outerRadius(this.radius * 0.7) 37 .innerRadius(this.radius * 0.3); 38 39 this.arcOver = d3.arc() 40 .innerRadius(this.radius * 0.3) 41 .outerRadius(this.radius * 0.8); 42 43 var radius = this.radius; 44 this.outerArc = d3.arc() 45 .innerRadius(this.radius * 0.9) 46 .outerRadius(function(d){ 47 var modifier = 0; 48 if(d.data.word.includes('strongly')) modifier = 2; 49 if(d.data.word.includes('slightly')) modifier = -1; 50 if(d.data.word == 'positive' || d.data.word == 'negative' ) modifier = 0.3; 51 return radius * 0.9 + modifier*30; 52 }); 53 54 this.key = function(d){ return d.data.word; }; 55 56 }; 57 58 binMe(data, size="all", sort_property = 'freq', filterneutrals=false, 59 bins= [-1,-0.6,-0.3, -0.005, 0.005,0.3,0.6,1], 60 names = ['strongly negative', 'negative', 'slightly negative', 'neutral','slightly positive', 'positive', 'strongly positive'], 61 ){ 62 var data2 = data.sort(fancysort(sort_property)); 63 if(size!='all')data2 = data2.slice(0, Math.min(data2.length, size) ); 64 65 var aggrdata = []; 66 for(var i = 0; i < bins.length-1; i++){ 67 68 if(names[i] == 'neutral' && filterneutrals) continue; 69 70 var bin1 = bins[i]; 71 var bin2 = bins[i+1]; 72 var accf = []; 73 var accs = []; 74 for(var j = 0; j < data2.length; j++){ 75 var w = data2[j]; 76 if(w['sent'] >= bin1 && w['sent'] < bin2 ){ 77 accf.push(w['freq']); 78 accs.push( w['sent'] ); 79 } 80 } 81 var accfreq = accf.reduce((a, b) => a + b, 0); 82 83 var avgsent = undefined; 84 if(accs.length > 0) avgsent = accs.reduce((a, b) => a + b, 0) / accs.length; 85 if(accfreq>0)aggrdata.push({ word: names[i], accfreq: accfreq, avgsent: avgsent , relfreq: 0} ); 86 } 87 88 var totf = 0; 89 for(var i = 0; i< aggrdata.length; i++){ 90 totf += aggrdata[i]['accfreq']; 91 } 92 for(var i = 0; i< aggrdata.length; i++){ 93 var relfreq = (aggrdata[i]['accfreq'] / totf * 100).toFixed(2); 94 aggrdata[i]['relfreq'] = relfreq; 95 } 96 97 return aggrdata; 98 } 99 100 change(data, size="all", sort_property="freq", filterneutrals=false, binme = true) { 101 var radius = this.radius; 102 var svg = this.svg; 103 var height = this.height; 104 var width = this.width; 105 var margin = this.margin; 106 var color = this.color; 107 var pie = this.pie; 108 var key = this.key; 109 var outerArc = this.outerArc; 110 var arc = this.arc; 111 var arcOver = this.arcOver; 112 113 //preprocess the data, cut by the size 114 if(binme){ 115 var data = this.binMe(data, size, sort_property, filterneutrals); 116 } 117 118 /* ------- PIE SLICES -------*/ 119 var slice = svg.select(".slices").selectAll("path.slice") 120 .data(pie(data), key); 121 122 slice.enter() 123 .insert("path") 124 .style("fill", function(d) { return color(d.data.word); }) 125 .attr("class", "slice") 126 .on("mouseover", function(d) { 127 d3.select(this).transition() 128 .duration(500) 129 .attr("d", arcOver); 130 }) 131 .on("mouseout", function(d) { 132 d3.select(this).transition() 133 .duration(500) 134 .attr("d", arc); 135 });; 136 137 slice 138 .transition().duration(1000) 139 .attrTween("d", function(d) { 140 this._current = this._current || d; 141 var interpolate = d3.interpolate(this._current, d); 142 this._current = interpolate(0); 143 return function(t) { 144 return arc(interpolate(t)); 145 }; 146 }) 147 148 slice.exit() 149 .remove(); 150 151 /* ------- TEXT LABELS -------*/ 152 153 var text = svg.select(".labels").selectAll("text") 154 .data(pie(data), key); 155 156 text.enter() 157 .append("text") 158 .attr("dy", ".35em") 159 .attr("font-size", "10px") 160 .text(function(d) { 161 return d.data.word + " ("+d.data.relfreq+"%)"; 162 }); 163 164 function midAngle(d){ 165 return d.startAngle + (d.endAngle - d.startAngle)/2; 166 } 167 168 169 text.transition().duration(1000) 170 .attr('transform', function(d) { 171 var pos = outerArc.centroid(d); 172 var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2;
173 pos[0] = radius * 0.6 * (midangle < Math.PI ? 1 : -1); 174 return 'translate(' + pos + ')'; 175 }) 176 .style('text-anchor', function(d) { 177 var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2 178 return (midangle < Math.PI ? 'start' : 'end') 179 }) 180 181 text.exit() 182 .remove(); 183 184 /* ------- SLICE TO TEXT POLYLINES -------*/ 185 var polyline = svg.select(".lines").selectAll("polyline") 186 .data(pie(data), key); 187 188 polyline.enter() 189 .append("polyline"); 190 191 polyline.transition().duration(1000) 192 .attrTween("points", function(d){ 193 this._current = this._current || d; 194 var interpolate = d3.interpolate(this._current, d); 195 this._current = interpolate(0); 196 return function(t) { 197 var d2 = interpolate(t); 198 var pos = outerArc.centroid(d2); 199 pos[0] = radius * 0.6 * (midAngle(d2) < Math.PI ? 1 : -1); 200 return [arc.centroid(d2), outerArc.centroid(d2), pos]; 201 }; 202 }); 203 204 polyline.exit() 205 .remove(); 206 207 208 }; 209 210} 211
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.