1// mar15 > TOP 100 COMPANIES + THEIR TOP 200 INVESTORS 2 3//var exo2; 4var exo6; 5var exo3; 6var exo5; 7var particleSystem = []; 8var investorSystem = []; 9var attractors = []; 10var repulsors = []; 11var table; 12var categories = {}; 13var catnums = {}; 14var aggregated = {}; 15var investors = []; 16var selectInvestors = []; 17var particles = []; 18var connections = []; 19var iOpacity = 100; 20var mouseState = false; 21 22function preload(){ 23 table = loadTable("data/supertotal2.csv", "csv", "header"); 24 exo3 = loadFont("fonts/Exo2-Light.ttf"); 25 exo5 = loadFont("fonts/Exo2-Medium.ttf"); 26 exo6 = loadFont("fonts/Exo2-SemiBold.ttf"); 27} 28 29function windowResized() { 30 resizeCanvas(windowWidth, windowHeight); 31} 32 33//+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 34//SETUP 35function setup() { 36 var canvas = createCanvas(windowWidth, windowHeight); 37 frameRate(30); 38 colorMode(HSB, 360, 100, 100, 100); 39 background(0); 40 rectMode(CENTER); 41 textAlign(CENTER, CENTER); 42 43 //+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 44 45 //MAKE AGGREGATED COMPANIES & INVESTORS ARRAYS 46 for (var r = 0; r < table.getRowCount(); r++){ 47 var cname = table.getString(r, "company_name"); 48 var iname = table.getString(r, "investor_name"); 49 var category = table.getString(r, "category_code"); 50 var catnumb = table.getString(r, "category_num"); 51 var invested = table.getString(r, "amount_usd"); 52 invested = parseInt(invested); 53 54 //total investment (to companies) 55 if(!isNaN(invested)){ 56 if(aggregated.hasOwnProperty(cname)){ 57 aggregated[cname] += invested; 58 }else{ 59 aggregated[cname] = invested; 60 } 61 } 62 63 //total investment (from investors) 64 if(!isNaN(invested)){ 65 if(investors.hasOwnProperty(iname)){ 66 investors[iname] += invested; 67 }else{ 68 investors[iname] = invested; 69 } 70 } 71 72 categories[cname] = category; 73 catnums[cname] = catnumb; 74 75 } 76 77 //create aAggregated array 78 var aAggregated = []; 79 Object.keys(aggregated).forEach(function(name_){ 80 var company = {}; 81 company.name = name_; 82 company.category = categories[name_]; 83 company.cnum = catnums[name_]; 84 company.sum = aggregated[name_] 85 aAggregated.push(company); 86 }); 87 88 //create aaInvestors array 89 var aInvestors = []; 90 Object.keys(investors).forEach(function(name_){ 91 var investor = {}; 92 investor.iname = name_; 93 investor.totalInv = investors[name_]; 94 aInvestors.push(investor); 95 }); 96 97 //sort by sum 98 aAggregated.sort(function(companyA, companyB){ 99 return companyB.sum - companyA.sum; 100 }); 101 102 aAggregated = aAggregated.slice(0, 100); 103 104 //+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 105 //MAKING CONNECTIONS ARRAY 106 for (var r = 0; r < table.getRowCount(); r++){ 107 var compname = table.getString(r, "company_name"); 108 var invname = table.getString(r, "investor_name"); 109 var date = table.getString(r, "funded_at"); 110 var category = table.getString(r, "category_code"); 111 var amt = table.getString(r, "amount_usd"); 112 amt = parseInt(amt); 113 114 var foundCompany = aAggregated.find(function(element, index, array){ 115 if(element.name == compname){ 116 return true; 117 }else{ 118 return false; 119 } 120 }); 121 122 if(foundCompany){ 123 var foundInvestor = false; 124 foundInvestor = aInvestors.find(function(element, index, array){ 125 if(element.iname == invname){ 126 return true; 127 }else{ 128 return false; 129 } 130 }); 131 132 if(foundInvestor){ 133 var connection = {}; 134 connection.company = foundCompany; 135 connection.investor = foundInvestor; 136 connection.amount = amt; 137 //connection.date = date; 138 //connection.category = category; 139 connections.push(connection); 140 } 141 142 } 143 144 } 145 146 print(connections); 147 148 //+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 149 150 //Make selectInvestors array from connections 151 connections.forEach(function(connection){ 152 var found = selectInvestors.find(function(selectInvestor){ 153 return selectInvestor == connection.investor; 154 }); 155 if(!found) selectInvestors.push(connection.investor) 156 }); 157 158 //sort by totalInv 159 selectInvestors.sort(function(inameA, inameB){ 160 return inameB.totalInv - inameA.totalInv; 161 }); 162 163 selectInvestors = selectInvestors.slice(0, 200); 164 165 166 //+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 167 168 //# of objects in array AS PARTICLES 169 for (var i=0; i<aAggregated.length; i++) { 170 var p = new Particle(aAggregated[i].name, 171 aAggregated[i].sum, 172 aAggregated[i].category, 173 aAggregated[i].cnum); 174 particleSystem.push(p); 175 } 176 177 for (var h=0; h<selectInvestors.length; h++) { 178 var j = new investorParticle(selectInvestors[h].iname, 179 selectInvestors[h].totalInv); 180 investorSystem.push(j); 181 } 182 183 // attractor position & strength 184 var at = new Attractor(createVector(width*.5, height*.5), 84); 185 attractors.push(at); 186 187 // repulsor position & strength 188 var rp = new Repulsor(createVector(width*.5, height*.5), 84); 189 repulsors.push(rp); 190 191} 192 193//+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 194//DRAW 195function draw() { 196 background(0, 0, 100, 100); 197 198 for (var STEPS = 0; STEPS<3; STEPS++) { 199 for (var i=0; i<particleSystem.length-1; i++){ 200 for (var j=i+1; j<particleSystem.length; j++){ 201 var pa = particleSystem[i]; 202 var pb = particleSystem[j]; 203 var ab = p5.Vector.sub(pb.pos, pa.pos); 204 var distSq = ab.magSq(); 205 if(distSq <= sq(pa.radius + pb.radius)){ 206 var dist = sqrt(distSq); 207 var overlap = (pa.radius + pb.radius) - dist; 208 ab.div(dist); 209 ab.mult(overlap*0.5); 210 pb.pos.add(ab); 211 ab.mult(-1); 212 pa.pos.add(ab); 213 //friction 214 pa.vel.mult(0.98); 215 pb.vel.mult(0.98); 216 217 } 218 } 219 } 220 } 221 222 for (var STEPS = 0; STEPS<3; STEPS++) { 223 for (var i=0; i<investorSystem.length-1; i++){ 224 for (var j=i+1; j<investorSystem.length; j++){ 225 var pa = investorSystem[i]; 226 var pb = investorSystem[j]; 227 var ab = p5.Vector.sub(pb.pos, pa.pos); 228 var distSq = ab.magSq(); 229 if(distSq <= sq(pa.radius + pb.radius)){ 230 var dist = sqrt(distSq); 231 var overlap = (pa.radius + pb.radius) - dist; 232 ab.div(dist); 233 ab.mult(overlap*0.5); 234 pb.pos.add(ab); 235 ab.mult(-1); 236 pa.pos.add(ab); 237 //friction 238 pa.vel.mult(0.98); 239 pb.vel.mult(0.98); 240 241 } 242 } 243 } 244 } 245 246 investorSystem.forEach(function(j) { 247 j.update(); 248 j.draw(); 249 }); 250 251 particleSystem.forEach(function(p) { 252 p.update(); 253 p.draw(); 254 }); 255
256 attractors.forEach(function(at){ 257 at.draw(); 258 }); 259 260 repulsors.forEach(function(rp){ 261 rp.draw(); 262 }); 263 264} 265 266//+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 267//INVESTOR PARTICLE 268var investorParticle = function(iname, totalInv) { 269 this.iname = iname; 270 this.totalInv = totalInv; 271 var iColor = random(16, 32); 272 this.opacity = iOpacity; 273 this.radius = sqrt(this.totalInv)/2000; 274 var initialRadius = this.radius; 275 var maxRadius = 88; 276 var angleInc = TWO_PI / random(0.1, PI); 277 var ang = -0.75; 278 ang = ang + angleInc; 279 this.pos = createVector(sin(ang), cos(ang)); 280 this.pos.mult(460); 281 this.pos.add(width/2, height/2); 282 this.vel = createVector(0, 0); 283 var acc = createVector(0, 0); 284 var isMouseOver = false; 285 286 this.update = function() { 287 288 checkMouse(this); 289 this.opacity = iOpacity; 290 291 attractors.forEach(function(A){ 292 var att = p5.Vector.sub(A.getPos(), this.pos); 293 var distanceSq = att.magSq(); 294 if(distanceSq > 1){ 295 att.normalize(); 296 att.mult(5); 297 att.mult(initialRadius*.001); 298 acc.add(att); 299 } 300 301 }, this); 302 303 //REPULSOR 304 repulsors.forEach(function(R){ 305 var rpp = p5.Vector.sub(R.getPos(), this.pos); 306 var distanceSq = rpp.magSq(); 307 if(distanceSq > 1){ 308 rpp.normalize(); 309 rpp.mult(5*-1); 310 rpp.mult(initialRadius*.001); 311 acc.add(rpp); 312 } 313 314 }, this); 315 316 this.pos.add(this.vel); 317 this.vel.add(acc); 318 acc.mult(0); 319 320 } 321 322 this.draw = function() { 323 324 if(isMouseOver == true){ 325 //fill when hover 326 fill(iColor, 50, 80, 100) 327 }else{ 328 //fill default 329 fill(iColor, 55, 80, this.opacity) 330 }; 331 332 noStroke(); 333 ellipse(this.pos.x, 334 this.pos.y, 335 this.radius*2-4, 336 this.radius*2-4); 337 338 //DRAW INVESTOR NAME IN BUBBLE AT MAXRADIUS 339 if(this.radius == maxRadius){ 340 341 //this.opacity = 50; 342 //text color 343 fill(0, 0, 100, 100); 344 345 //show text for company name 346 textFont(exo5); 347 textSize(22); 348 349 //with wrap: 350 text(this.iname, 351 this.pos.x, 352 this.pos.y-12, 353 maxRadius, maxRadius); 354 355 //show text for sum 356 textFont(exo6); 357 textSize(14); 358 text("invested:", this.pos.x, this.pos.y+50); 359 dispSum = nfc(this.totalInv/1000000000, 2); 360 text("$" + dispSum + "B", this.pos.x, this.pos.y+64); 361 362 } 363 364 } 365 366 function checkMouse(instance){ 367 var mousePos = createVector(mouseX, mouseY); 368 if(mousePos.dist(instance.pos) <= instance.radius){ 369 incRadius(instance); 370 isMouseOver = true; 371 }else{ 372 decRadius(instance); 373 isMouseOver = false; 374 } 375 } 376 377 function incRadius(instance){ 378 instance.radius+=6; 379 if(instance.radius > maxRadius){ 380 instance.radius = maxRadius; 381 } 382 383 } 384 385 function decRadius(instance){ 386 instance.radius-=8; 387 if(instance.radius < initialRadius){ 388 instance.radius = initialRadius; 389 } 390 391 } 392 393} 394 395//+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 396//COMPANY PARTICLE 397var Particle = function(name, sum, category, cnum) { 398 this.name = name; 399 this.sum = sum; 400 this.category = category; 401 this.cnum = cnum; 402 var color = map(this.cnum, 0, 44, 120, 330); 403 this.opacity = 100; 404 this.radius = sqrt(sum)/2000; 405 var initialRadius = this.radius; 406 var maxRadius = 108; 407 var tempAng = random(0, TWO_PI); 408 this.pos = createVector(cos(tempAng), sin(tempAng)); 409 this.pos.div(this.radius); 410 this.pos.mult(15000); 411 this.pos.set(this.pos.x + width/2, this.pos.y + height/2); 412 this.vel = createVector(0, 0); 413 var acc = createVector(0, 0); 414 var isMouseOver = false;
415 416 this.update = function() { 417 418 checkMouse(this); 419 420 attractors.forEach(function(A){ 421 var att = p5.Vector.sub(A.getPos(), this.pos); 422 var distanceSq = att.magSq(); 423 if(distanceSq > 1){ 424 att.normalize(); 425 att.mult(4); 426 att.mult(initialRadius*.001); 427 acc.add(att); 428 } 429 430 }, this); 431 432 this.pos.add(this.vel); 433 this.vel.add(acc); 434 acc.mult(0); 435 436 } 437 438 this.draw = function() { 439 440 if(isMouseOver == true){ 441 fill(color, 50, 80, 100) 442 }else{ 443 fill(color, 55, 80, this.opacity) 444 }; 445 446 noStroke(); 447 ellipse(this.pos.x, 448 this.pos.y, 449 this.radius*2-4, 450 this.radius*2-4); 451 452 //DRAW COMPANY NAME IN BUBBLE AT MAXRADIUS 453 if(this.radius == maxRadius){ 454 //text color 455 fill(0, 0, 100, 100); 456 457 //show text for company name 458 textFont(exo3); 459 textSize(32); 460 461 //with wrap: 462 text(this.name, 463 this.pos.x, 464 this.pos.y-10, 465 maxRadius, maxRadius); 466 467 //show text for sum 468 textFont(exo5); 469 textSize(16); 470 dispSum = nfc(this.sum/1000000000, 2); 471 text("$" + dispSum + "B", this.pos.x, this.pos.y+78); 472 473 //show text for category 474 textFont(exo5); 475 textSize(16); 476 text(this.category, this.pos.x, this.pos.y+60); 477 478 } 479 480 } 481 482 483 function checkMouse(instance){ 484 var mousePos = createVector(mouseX, mouseY); 485 if(mousePos.dist(instance.pos) <= instance.radius){ 486 incRadius(instance); 487 isMouseOver = true; 488 }else{ 489 decRadius(instance); 490 isMouseOver = false; 491 } 492 } 493 494 function incRadius(instance){ 495 instance.radius+=6; 496 if(instance.radius > maxRadius){ 497 instance.radius = maxRadius; 498 } 499 500 } 501 502 function decRadius(instance){ 503 instance.radius-=8; 504 if(instance.radius < initialRadius){ 505 instance.radius = initialRadius; 506 } 507 508 } 509 510} 511 512//+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ 513//ATTRACTOR + REPULSOR 514var Attractor = function(pos, s){ 515 this.pos = pos.copy(); 516 var strength = s*10; 517 this.draw = function(){ 518 noStroke(); 519 fill(230, 0, 0, 0); 520 ellipse(this.pos.x, this.pos.y, strength, strength); 521 } 522 523 this.getPos = function(){ 524 return this.pos.copy(); 525 } 526
527 this.getStrength = function(){ 528 return strength*10; 529 } 530 531} 532 533var Repulsor = function(pos, s){ 534 this.pos = pos.copy(); 535 var strength = s*10; 536 this.draw = function(){ 537 noStroke(); 538 fill(230, 0, 0, 0); 539 ellipse(this.pos.x, this.pos.y, strength, strength); 540 } 541 542 this.getPos = function(){ 543 return this.pos.copy(); 544 } 545 546 this.getStrength = function(){ 547 return strength*10; 548 } 549 550} 551
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.