// --------------------------------------------------- // University of California Santa Barbara // Media Arts and Technology // MAT 259 | Visualizing Information | Winter 2011 // // Patrick Rudolph // Project 3 | Animation // // Main Program // --------------------------------------------------- /* ### ALTERNATIVE 1 ### (- more description of whats going on) - diffrent colors --> no ### ALTERNATIVE 2 ### - change to 3D with a graph on the z-axis - maybe reorder layout to a table (topics x, dewey y) --> bad quality in 3d environment */ import controlP5.*; // --------------------------------------------------- // GLOBAL VARIABLES // --------------------------------------------------- // fonts PFont fTitle,fTitleSmall,fTitleTiny,fTitleBig,fTitleHuge; // colors final color cBg = #333333; final color cCircle1 = #ffffff; // outer circle, alpha is applied, see Circle class final color cCircle2 = #000000; // shadow of inner circle, alpha is applied, see Circle class final color cCircle3 = #ffffa0; // creamy yellow circle color final color cTitle = #ffffff; final color cTitleBorder = #222222; final color cText = #eeeeee; color cBar = cCircle3; // layout float centerX,centerY; // strings String[] years = { "2006","2007","2008","2009","2010" }; String[] months = { "January","February","March","April","May","June", "July","August","September","October","November","December" }; String yearCount = years[0]; String monthCount = months[0]; final String title = "Hot Topic Evolution "+years[0]+"-"+years[years.length-1]+""; // infobox Circle info = null; float infoSum,infoShare; String infoName; String[] deweyNames; // data Level1 root; Level1[] topics = new Level1[5]; final String[][] names = { { "Global Warming", "globalwarming" } , { "Bush", "bush" } , { "National Parks", "nationalparks" } , { "Soccer", "soccer" } , { "Obama", "obama" } }; float[] fixRotation = { TWO_PI*6.5/11, TWO_PI*8.66/11, TWO_PI*10.8/11, TWO_PI*2.1/11, TWO_PI*4.3/11 }; PImage particle; ArrayList checkouts = new ArrayList(); final int dayMax = 1827; int maxSum; // animation float prevMillis = 0; // controls ControlP5 controlP5; Slider s0,s1,s2; CheckBox cb; PImage setOn,setOff; int setX,setY; public int period = 30; public int speed = 20; public int curDay = 0; boolean[] effects = { true,false }; // --------------------------------------------------- // INITIALIZING (runs only once) // --------------------------------------------------- public void setup() { // general if(frame != null) frame.setTitle(title+" | 2011W MAT259 Visualizing Information | Patrick Rudolph"); size(700,700); centerX = width/2-20; centerY = height/2; frameRate(30); smooth(); noStroke(); particle = loadImage("particle.png"); deweyNames = loadStrings("deweyNames.txt"); // fonts fTitleTiny = loadFont("Ebrima-11.vlw"); fTitleSmall = loadFont("Ebrima-12.vlw"); fTitle = loadFont("Ebrima-14.vlw"); fTitleBig = loadFont("Ebrima-Bold-16.vlw"); fTitleHuge = loadFont("Ebrima-Bold-22.vlw"); // controls controlP5 = new ControlP5(this); setOn = loadImage("settings_on.png"); setOff = loadImage("settings_off.png"); setX = width-40; setY = 10; // change the original colors controlP5.setColorForeground(cCircle3); controlP5.setColorBackground(cTitleBorder); controlP5.setColorLabel(cText); controlP5.setColorValue(cText); controlP5.setColorActive(cTitle); controlP5.addSlider("curDay",0,dayMax,width-270,10,190,10); s0 = (Slider)controlP5.controller("curDay"); s0.setSliderMode(Slider.FLEXIBLE); s0.setVisible(false); controlP5.addSlider("speed",1,30,width-180,30,100,10); s1 = (Slider)controlP5.controller("speed"); s1.setNumberOfTickMarks(10); s1.setSliderMode(Slider.FLEXIBLE); s1.setLabel("Days / Second"); s1.setVisible(false); controlP5.addSlider("period",10,90,width-180,52,100,10); s2 = (Slider)controlP5.controller("period"); s2.setNumberOfTickMarks(9); s2.setSliderMode(Slider.FLEXIBLE); s2.setLabel("Period (in days)"); s2.setVisible(false); cb = controlP5.addCheckBox("Checkout Effects",width-180,80); cb.setSpacingRow(5); //cb.setLabel("Checkout Effects"); cb.setItemsPerRow(1); cb.addItem("Checkout Effect Topic",0); cb.addItem("Checkout Effect Dewey",0); cb.activate(0); cb.setVisible(false); // data translate(centerX,centerY); root = new Level1(null,"SPL","spl",0,0,50,0); for(int i = 0; i < topics.length; i++) { topics[i] = new Level1(root,names[i][0],names[i][1], sin(TWO_PI*i/topics.length), -cos(TWO_PI*i/topics.length), 0,fixRotation[i]); } } // --------------------------------------------------- // DRAWING (runs at framerate, default 60 frames/s) // --------------------------------------------------- public void draw() { background(cBg); imageMode(CENTER); float m = millis(); if( m-prevMillis >= (1000/speed) ) { if(curDay < dayMax) { curDay++; prevMillis=m; for(int i = 0; i < topics.length; i++) { topics[i].add(curDay); } } updateLabels(); } pushMatrix(); translate(centerX,centerY); for(int i = 0; i < topics.length; i++) { topics[i].draw(); drawDataBars(i); } root.draw(); if(!checkouts.isEmpty()) { // check particle queue for(int i=0;i 1) percent = 1; fill(cBar,percent*255); pushMatrix(); rotate(TWO_PI*topic/topics.length-TWO_PI/4); rect(x-barW/2,-8,x+barW/2,8); popMatrix(); valueSum = 0; } } } // --------------------------------------------------- // UPDATES LABELS AT ANIMATION SPEED (NOT FPS!) // --------------------------------------------------- public void updateLabels() { // date yearCount = years[(int)curDay/366]; monthCount = months[(int) (round(curDay/30.8) % 12) ]; s0.setLabel(monthCount+" "+yearCount); // days s0.setValue(curDay); // particles if(effects[0]) { for(int i = 0; i < topics.length; i++) { float value = topics[i].data[curDay].size(); float x = map(curDay, 0, dayMax, 30, 200); for(int c = 0; c < value; c+=2) { checkouts.add(new Checkout( ( x+random(-2,6) ) , ( random(-10,10) ) , TWO_PI*i/topics.length-TWO_PI/4 )); } } } // max sum maxSum = period/3*50; } // --------------------------------------------------- // DRAWS THE TITLE OF THE SKETCH // --------------------------------------------------- public void drawTitle() { textFont(fTitleHuge); textAlign(LEFT,CENTER); noStroke(); fill(0); textShadow(title,20,20); fill(cText); text(title,20,20); } // --------------------------------------------------- // DRAWS THE INFO FOR EACH TOPIC / DEWEY CLASS // --------------------------------------------------- public void drawInfo() { if(info != null) { if(!info.mouseInside()) { info = null; return; } String name,checkouts,share; float alpha; alpha = 230; pushMatrix(); translate(20,60); if(info.parent == null) { // root name = info.name; checkouts = round(info.sum)+" checkouts the last "+period+" days"; share = ""; } else if(info.parent == root) { // Level 1 name = info.name; checkouts = round(info.sum)+" checkouts the last "+period+" days"; share = round(info.share*100)+"% of total"; } else { // Level 2 name = deweyNames[Integer.parseInt(info.name.substring(0,1))]+" - "+info.parent.name; checkouts = round(info.sum)+" checkouts the last "+period+" days"; share = round(info.share*100)+"% of "+info.parent.name; } textAlign(LEFT,CENTER); noStroke(); textFont(fTitleBig); fill(20,alpha); textShadow(name,0,0); fill(cText,alpha); text(name,0,0); textFont(fTitleTiny); fill(20,alpha); textShadow(checkouts,0,20); fill(cText,alpha); text(checkouts,0,20); textFont(fTitleTiny); fill(20,alpha); textShadow(share,0,35); fill(cText,alpha); text(share,0,35); popMatrix(); } }