/* ** ======================================================== ** MAT259 Visualizaing Data | Winter 2011 | George Legrady ** ======================================================= ** Project 1 : Checkout Durations by Dewey Category ** ================================================ ** Nichole Stockman ** ================ ** ** ** ===================================================================== ** For information on how the data was parsed, how the application works ** and some key notes and observations, please see the README file.` ** Thank you! ** ===================================================================== */ //============================= //Global Variables //============================= final int yearGraph = 1, monthGraph = 2, dayGraph = 3, category = 1, subcategory = 2; int graphType = yearGraph, mode = category, yearDurMax = 0, monthDurMax = 0, dayDurMax = 0, cutoff = 180, selectedYearIdx = 0, selectedMonthIdx = 0; YearObject[] YearObjs; //Plot dimensions //----------------------------- final int graphWidth = 1024, graphHeight = 768; final float plotLeft = (0.15)*graphWidth, plotRight = graphWidth - 20, plotTop = 100, plotBottom = graphHeight - 110, plotWidth = plotRight - plotLeft, plotHeight = plotBottom - plotTop; //Fonts //----------------------------- PFont titleFont, lLabelFont, lLabelSubFont, bLabelMainNumFont, bLabelMainTxtFont, bLabelSubSelectedNumFont, bLabelSubSelectedTxtFont, bLabelSubNumFont, bLabelSubTxtFont, topButtonFont; //Label colors //----------------------------- final color titleColor = #48394D, bLabelColor = #48394D, //bottom labels lLabelColor = #48394D; //left side //Label positions //----------------------------- final int titleX = 25, titleY = 55; final float bLabelPosY = graphHeight - 80, lLabelPosX = 10; //Sub-label transparencies //----------------------------- final int lSubLabelTransparency = 200, bSubLabelTransparency = 100; //Background, grid and line colors //----------------------------- final int sLabelColor = 90, //switch to (sub)category mode label (also acts as a button) bkgdColor = 200, gridColor = bkgdColor - 25, gridLineColor = 85, labelLineColor = 50, barOutlineColor = 90, barHighlightColor = 225, highlightBoxColor = 240; //Line weights //----------------------------- final float labelLineWeight = 1.5, gridLineWeight = 1, highlightBoxWeight = 5, barHighlightWeight = 2; //Label strings //----------------------------- final String title = "Checkout Durations by Dewey Category", lLabelTitle = "First two digits of Dewey Category"; final String[] Years = {"2005", "2006", "2007", "2008", "2009", "2010"}, Months = {"Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"}, Dewey = {"Comp Sci", "Phil/Psych", "Religion", "Social Sci", "Language", "Science/Math", "Tech/Applied Sci", "Arts/Recreation", "Literature", "History/Geo/Bio"}, DeweySub = {"Knowledge & Systems", "Bibliographies", "Library/Info Sci", "Encyclopedias", "fmrly: Essays by Lang", "Mag's/Jrnls/Serials", "Assoc's/Org's/Museums", "News Media", "Gen. Collections", "Manuscripts/Rare", "Philosophy", "Metaphysics", "Epistemology", "Paranormal", "Phil. Schools", "Psychology", "Logic", "Ethics", "Ancient/Medieval/Oriental Phil", "Modern West. Phil.", "Religion", "Natural Theology", "Bible", "Christian Theol.", "Christ. Devotional Theol.", "Christ. orders & church", "Christ. Social Thol.", "Christ. Church Hist.", "Christ. Denom's/Sects", "Comparative Religions", "Social Sci", "General Stat's", "Political Sci", "Economics", "Law", "Public Admin.", "Social Svcs", "Education", "Commerce/Communication/Transport", "Customs/Folklore", "Language", "Linguistics", "English & Old Eng.", "Germanic Languages", "Romance Lang's & French", "Italian & Romanian", "Spanish & Portugese", "Italic Languages", "Hellenic Languages", "Other Languages", "Science", "Mathematics", "Astronomy", "Physics", "Chemistry", "Earth Sciences", "Paleontology/Paleozoology", "Life Sciences", "Plants", "Zoological Sciences", "Technology", "Medical Sciences", "Engineering", "Agriculture", "Home Economics", "Mgmt & Aux. Services", "Chemical Engineering", "Manufacturing", "Manufacture - spec. uses", "Buildings", "Arts", "Civic/Landscape Art", "Architecture", "Plastic Arts/Sculpture", "Drawing", "Painting", "Graphic Arts", "Photography", "Music", "Performing Arts", "Literature Rhetoric", "American Lit in English", "Old English Literatures", "Lit. of Germanic Lang's", "Lit. of Romance Lang's", "Italian/Romanian", "Spanish & Portugese Lit's", "Italic Literatures", "Hellenic Literatures", "Lit's of Other Lang's", "History", "Geography & Travel", "Biography/Genealogy", "History of Ancient World", "History of Europe", "History of Asia", "History of Africa", "History of N. America", "History of S. America", "History of other Areas"}; color[] DeweyColor = new color[100]; //============================= //Setup() Method //============================= void setup() { size(graphWidth, graphHeight); smooth(); //Initialize Fonts //----------------------------- titleFont = loadFont("Aharoni-Bold-40.vlw"); lLabelFont = loadFont("Aharoni-Bold-16.vlw"); lLabelSubFont = loadFont("Aharoni-Bold-12.vlw"); bLabelMainNumFont = loadFont("Aharoni-Bold-20.vlw"); bLabelMainTxtFont = loadFont("Aharoni-Bold-16.vlw"); bLabelSubSelectedNumFont = loadFont("Aharoni-Bold-18.vlw"); bLabelSubSelectedTxtFont = loadFont("Aharoni-Bold-14.vlw"); bLabelSubNumFont = loadFont("Aharoni-Bold-16.vlw"); bLabelSubTxtFont = loadFont("Aharoni-Bold-12.vlw"); topButtonFont = loadFont("Aharoni-Bold-16.vlw"); //Initialize Dewey Colors //----------------------------- for(int i = 0; i < DeweyColor.length; i++){ if(i >= 0 && i < 10){ DeweyColor[i] = #57C973; } else if (i >= 10 && i < 20){ DeweyColor[i] = #DE37B7; } else if (i >= 20 && i < 30){ DeweyColor[i] = #B1BF17; } else if (i >= 30 && i < 40){ DeweyColor[i] = #1AC9C1; } else if (i >= 40 && i < 50){ DeweyColor[i] = #DE4747; } else if (i >= 50 && i < 60){ DeweyColor[i] = #44BD1C; } else if (i >= 60 && i < 70){ DeweyColor[i] = #3C49D6; } else if (i >= 70 && i < 80){ DeweyColor[i] = #C451BB; } else if (i >= 80 && i < 90){ DeweyColor[i] = #0AADAB; } else if (i >= 90 && i < 100){ DeweyColor[i] = #E8C24F; } } //Load the data //----------------------------- loadData(); } //============================= //loadData() Method //============================= void loadData() { //Load text files to use (they contain results of mySQL queries) //-------------------------------------------------------------------- String [] YearRows = loadStrings("yearDurations.txt"); String [] MonthRows = loadStrings("monthDurations.txt"); String [] DayRows = loadStrings("dayDurations.txt"); YearObjs = new YearObject[6]; //YearDurations.txt has info from 2005 to 2010 int index = 0; //Initialize first YearObject //---------------------------------- String[] YearParseList = split(YearRows[0], ", "); YearObject yOb = new YearObject(Integer.valueOf(YearParseList[0])); yOb.YearCatAvgs[Integer.valueOf(YearParseList[1])] = min(Integer.valueOf(YearParseList[2]), cutoff); YearObjs[index] = yOb; //Parse YearDurations.txt and populate YearObject Array //-------------------------------------------------------------------- yearDurMax = 0; for (int i = 0; i < YearRows.length; i++) { YearParseList = split(YearRows[i], ", "); int yr = Integer.valueOf(YearParseList[0]); if (Integer.valueOf(YearParseList[2]) > yearDurMax && Integer.valueOf(YearParseList[2]) < cutoff) { yearDurMax = Integer.valueOf(YearParseList[2]); } if(yr == YearObjs[index].yr) { YearObjs[index].YearCatAvgs[Integer.valueOf(YearParseList[1])] = min(Integer.valueOf(YearParseList[2]), cutoff); } else { yOb = new YearObject(Integer.valueOf(YearParseList[0])); yOb.YearCatAvgs[Integer.valueOf(YearParseList[1])] = min(Integer.valueOf(YearParseList[2]), cutoff); index++; YearObjs[index] = yOb; } } //Calculate year averages for each broad category //----------------------------------------------------------------- for(int i = 0; i < YearObjs.length; i++){ for (int j = 0; j < YearObjs[i].YearSingleAvgs.length; j++){ int total = 0; for(int k = j*10; k < (j+1)*10; k++){ total += YearObjs[i].YearCatAvgs[k]; } int avg = total / 10; YearObjs[i].YearSingleAvgs[j] = avg; } } //Initialize first MonthObject //---------------------------------- String[] MonthParseList = split(MonthRows[0], ", "); MonthObject mOb = new MonthObject(Integer.valueOf(MonthParseList[1])); index = 0; mOb.MonthCatAvgs[Integer.valueOf(MonthParseList[2])] = min(Integer.valueOf(MonthParseList[3]), cutoff); YearObjs[index].MonthObjs[mOb.mo-1] = mOb; //Parse MonthDurations.txt and populate MonthObject Arrays //-------------------------------------------------------------------- monthDurMax = 0; int yr = Integer.valueOf(MonthParseList[0]); for (int i = 0; i < MonthRows.length; i++) { MonthParseList = split(MonthRows[i], ", "); yr = Integer.valueOf(MonthParseList[0]); int mo = Integer.valueOf(MonthParseList[1]); if (Integer.valueOf(MonthParseList[3]) > monthDurMax && Integer.valueOf(MonthParseList[3]) < cutoff) { monthDurMax = Integer.valueOf(MonthParseList[3]); } if(yr == YearObjs[index].yr) { if( mo == YearObjs[index].MonthObjs[mOb.mo-1].mo) { YearObjs[index].MonthObjs[mo-1].MonthCatAvgs[Integer.valueOf(MonthParseList[2])] = min(Integer.valueOf(MonthParseList[3]), cutoff); } else { mOb = new MonthObject(Integer.valueOf(MonthParseList[1])); mOb.MonthCatAvgs[Integer.valueOf(MonthParseList[2])] = min(Integer.valueOf(MonthParseList[3]), cutoff); YearObjs[index].MonthObjs[mOb.mo-1] = mOb; } } else { index++; mOb = new MonthObject(Integer.valueOf(MonthParseList[1])); mOb.MonthCatAvgs[Integer.valueOf(MonthParseList[2])] = min(Integer.valueOf(MonthParseList[3]), cutoff); YearObjs[index].MonthObjs[mOb.mo-1] = mOb; } } //Calculate month averages for each broad category //----------------------------------------------------------------- for(int i = 0; i < YearObjs.length; i++){ for(int j = 0; j < YearObjs[i].MonthObjs.length; j++){ for(int k = 0; k < YearObjs[i].MonthObjs[j].MonthSingleAvgs.length; k++){ int total = 0; for(int m = k*10; m < (k+1)*10; m++){ total += YearObjs[i].MonthObjs[j].MonthCatAvgs[m]; } int avg = total/10; YearObjs[i].MonthObjs[j].MonthSingleAvgs[k] = avg; } } } //Initialize first DayObject //---------------------------------- String[] DayParseList = split(DayRows[0], ", "); int mo = Integer.valueOf(DayParseList[0].substring(5,7)); int moIndex = mo-1; int yrIndex = 0; DayObject dOb = new DayObject(Integer.valueOf(DayParseList[0].substring(8,10))); yr = Integer.valueOf(DayParseList[0].substring(0,4)); dOb.DayCatAvgs[Integer.valueOf(DayParseList[1])] = min(Integer.valueOf(DayParseList[2]), cutoff); YearObjs[yrIndex].MonthObjs[moIndex].DayObjs[dOb.dy - 1] = dOb; //Parse dayDurations.txt and populate DayObject Arrays //-------------------------------------------------------------------- dayDurMax = 0; for (int i = 0; i < DayRows.length; i++) { DayParseList = split(DayRows[i], ", "); yr = Integer.valueOf(DayParseList[0].substring(0,4)); mo = Integer.valueOf(DayParseList[0].substring(5,7)); int dy = Integer.valueOf(DayParseList[0].substring(8,10)); if (Integer.valueOf(DayParseList[2]) > dayDurMax && Integer.valueOf(DayParseList[2]) < cutoff) { dayDurMax = Integer.valueOf(DayParseList[2]); } if(yr == YearObjs[yrIndex].yr) { if(mo == YearObjs[yrIndex].MonthObjs[moIndex].mo) { if( dy == YearObjs[yrIndex].MonthObjs[moIndex].DayObjs[dOb.dy - 1].dy) { YearObjs[yrIndex].MonthObjs[moIndex].DayObjs[dy-1].DayCatAvgs[Integer.valueOf(DayParseList[1])] = min(Integer.valueOf(DayParseList[2]), cutoff); } else { dOb = new DayObject(Integer.valueOf(DayParseList[0].substring(8,10))); dOb.DayCatAvgs[Integer.valueOf(DayParseList[1])] = min(Integer.valueOf(DayParseList[2]), cutoff); YearObjs[yrIndex].MonthObjs[moIndex].DayObjs[dOb.dy-1] = dOb; } } else { moIndex = Integer.valueOf(DayParseList[0].substring(5,7)) - 1; dOb = new DayObject(Integer.valueOf(DayParseList[0].substring(8,10))); dOb.DayCatAvgs[Integer.valueOf(DayParseList[1])] = min(Integer.valueOf(DayParseList[2]), cutoff); YearObjs[yrIndex].MonthObjs[moIndex].DayObjs[dOb.dy-1] = dOb; } } else { yrIndex++; moIndex = Integer.valueOf(DayParseList[0].substring(5,7)) - 1; dOb = new DayObject(Integer.valueOf(DayParseList[0].substring(8,10))); dOb.DayCatAvgs[Integer.valueOf(DayParseList[1])] = min(Integer.valueOf(DayParseList[2]), cutoff); YearObjs[yrIndex].MonthObjs[moIndex].DayObjs[dOb.dy-1] = dOb; } } //Calculate day averages for each broad category //----------------------------------------------------------------- for(int i = 0; i < YearObjs.length; i++){ for(int j = 0; j < YearObjs[i].MonthObjs.length; j++){ for(int k = 0; k < YearObjs[i].MonthObjs[j].DayObjs.length; k++){ for(int m = 0; m < YearObjs[i].MonthObjs[j].DayObjs[k].DaySingleAvgs.length; m++){ int total = 0; for(int n = m*10; n < (m+1)*10; n++){ total += YearObjs[i].MonthObjs[j].DayObjs[k].DayCatAvgs[n]; } int avg = total/10; YearObjs[i].MonthObjs[j].DayObjs[k].DaySingleAvgs[m] = avg; } } } } } //============================= //draw() Method //============================= void draw() { noStroke(); background(bkgdColor); fill(gridColor); rect(plotLeft, plotTop, plotWidth, plotHeight); drawTitle(); drawLabels(); drawGraph(); drawButtonHighlights(); } //============================= //drawTitle() Method //============================= void drawTitle() { textFont(titleFont); fill(titleColor); if(graphType == yearGraph) { text(title, titleX, titleY); } else if (graphType == monthGraph) { text(title + " [" + (selectedYearIdx+2005) + "]", titleX, titleY); } else if (graphType == dayGraph) { text(title + " [" + (selectedMonthIdx+1) + " - " + (selectedYearIdx+2005) + "]", titleX, titleY); } } //============================= //drawLabels() Method //============================= void drawLabels() { //All Left Side Labels //---------------------------------- float rowHeight = (0.96*plotHeight)/100; float y = plotTop + (0.02*plotHeight); fill(lLabelColor); //Left Side Category labels //---------------------------------- textFont(lLabelFont); for(int i = 0; i < 100; i++) { if(i < 10) { text(Dewey[i], lLabelPosX, y + (i+1)*10*rowHeight - 5*rowHeight); if(i < 9) { //lines between labels //--------------------- stroke(labelLineColor); strokeWeight(labelLineWeight); line(lLabelPosX-5, y + (i+1)*10*rowHeight, plotLeft-30, y + (i+1)*10*rowHeight); //grid lines //------------------- stroke(gridLineColor); strokeWeight(gridLineWeight); line(plotLeft+3, y + (i+1)*10*rowHeight, plotRight-3, y + (i+1)*10*rowHeight); } } } //Bottom Labels //---------------------------------- float colWidth; float x = plotLeft; if (graphType == yearGraph) { colWidth = plotWidth / YearObjs.length; for(int i = 0; i < YearObjs.length; i++) { if(i > 0) { drawLines(x, i, colWidth); } drawBottomLabels(i, colWidth); } } else if (graphType == monthGraph) { colWidth = plotWidth / YearObjs[selectedYearIdx].MonthObjs.length; for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs.length; i++) { if(i > 0) { drawLines(x, i, colWidth); } drawBottomLabels(i, colWidth); } } else if (graphType == dayGraph) { colWidth = plotWidth/31; for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs[selectedMonthIdx].DayObjs.length; i++) { if(i == 5 || i == 10 || i == 15 || i == 20 || i == 25 ) { drawLines(x, i, colWidth); } drawBottomLabels(i, colWidth); } } } //============================= //drawLines() Method //============================= void drawLines(float xValue, int idx, float colW){ //Draw lines between bottom labels //-------------------------------------- stroke(labelLineColor); strokeWeight(labelLineWeight); line(xValue+(idx*colW), bLabelPosY+5, xValue+(idx*colW), bLabelPosY-15); //Draw grid lines //-------------------------- stroke(gridLineColor); strokeWeight(gridLineWeight); line(xValue+(idx*colW), plotTop+3, xValue+(idx*colW), plotTop + plotHeight-3); } //============================= //drawBottomLabels() Method //============================= void drawBottomLabels(int idx, float colW){ //Draw Labels //-------------------------- fill(bLabelColor); if(graphType == yearGraph){ textFont(bLabelMainNumFont); text(Years[idx], (idx+1)*colW+50, bLabelPosY); } else if (graphType == monthGraph){ textFont(bLabelMainTxtFont); text(Months[idx], (idx+1.5)*colW+colW, bLabelPosY); } else{ textFont(bLabelMainNumFont); text((idx+1), (idx+3.75)*colW+2*colW, bLabelPosY); } } //============================= //drawGraph() Method //============================= void drawGraph() { float y = plotTop + (0.02*plotHeight); float constant = plotLeft + 5; float rowHeight; if (mode == category){ rowHeight = (0.96*plotHeight)/10; } else{ //mode == subcategory rowHeight = (0.96*plotHeight)/110; } stroke(barOutlineColor); if (graphType == yearGraph) { float colWidth = plotWidth / YearObjs.length; for(int i = 0; i < YearObjs.length; i++) { float x = constant + i*colWidth; if(mode == category){ for(int j = 0; j < 10; j++) { fill(DeweyColor[j*10]); float barLength = map(YearObjs[i].YearSingleAvgs[j], 0, yearDurMax, 0, colWidth-10); rect(x, y+(j*rowHeight+4), barLength, rowHeight-8); } } else{ float sumRems = 0; for(int j = 0; j < 100; j++) { fill(DeweyColor[j]); float barLength = map(YearObjs[i].YearCatAvgs[j], 0, yearDurMax, 0, colWidth-10); if(j > 0 && j%10 == 0){ sumRems ++; } rect(x, y+(j*rowHeight) + sumRems*rowHeight, barLength, rowHeight); } } } } else if (graphType == monthGraph) { float colWidth = plotWidth / YearObjs[selectedYearIdx].MonthObjs.length; for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs.length; i++) { float x = constant + i*colWidth; if(mode == category){ for(int j = 0; j < 10; j++) { fill(DeweyColor[j*10]); float barLength = map(YearObjs[selectedYearIdx].MonthObjs[i].MonthSingleAvgs[j], 0, monthDurMax, 0, colWidth-10); rect(x, y+(j*rowHeight+4), barLength, rowHeight-8); } } else{ float sumRems = 0; for(int j = 0; j < 100; j++) { fill(DeweyColor[j]); float barLength = map(YearObjs[selectedYearIdx].MonthObjs[i].MonthCatAvgs[j], 0, monthDurMax, 0, colWidth-10); if(j > 0 && j%10 == 0){ sumRems ++; } rect(x, y+(j*rowHeight) + sumRems*rowHeight, barLength, rowHeight); } } } } else if (graphType == dayGraph) { float colWidth = plotWidth / 31; for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs[selectedMonthIdx].DayObjs.length; i++) { float x = constant + i*colWidth; if(mode == category){ for(int j = 0; j < 10; j++) { fill(DeweyColor[j*10]); float barLength = map(YearObjs[selectedYearIdx].MonthObjs[selectedMonthIdx].DayObjs[i].DaySingleAvgs[j], 0, dayDurMax, 0, colWidth-10); rect(x, y+(j*rowHeight+4), barLength, rowHeight-8); } } else{ float sumRems = 0; for(int j = 0; j < 100; j++) { fill(DeweyColor[j]); float barLength = map(YearObjs[selectedYearIdx].MonthObjs[selectedMonthIdx].DayObjs[i].DayCatAvgs[j], 0, dayDurMax, 0, colWidth-10); if(j > 0 && j%10 == 0){ sumRems ++; } rect(x, y+(j*rowHeight) + sumRems*rowHeight, barLength, rowHeight); } } } } } //============================= //drawButtonHighlights() Method //============================= void drawButtonHighlights(){ //Switch between main view and subcategory view //---------------------------------------------- if(mode == category){ textFont(topButtonFont); fill(sLabelColor); text("Switch to Subcategory View", 0.915*plotWidth, 0.91*titleY+30); } else{ textFont(topButtonFont); fill(sLabelColor); text("Switch to Category View", 0.925*plotWidth, 0.91*titleY+30); } if(mouseInRect(0.91*plotWidth, 0.5*titleY+30, 210, 40)){ noFill(); stroke(highlightBoxColor); strokeWeight(highlightBoxWeight); rect(0.91*plotWidth, 0.5*titleY+30, 230, 40); } int boxHeight = 35; //In Years View //-------------------------------------------- if (graphType == yearGraph) { float colWidth = plotWidth/YearObjs.length; //Highlighting around year labels //------------------------------- for(int i = 0; i < YearObjs.length; i++) { if( mouseX >= (plotLeft + i*colWidth) && mouseX <= (plotLeft + (i+1)*colWidth) && mouseY >= (plotBottom + 5) && mouseY <= (plotBottom + 5 + boxHeight)){ noFill(); stroke(highlightBoxColor); strokeWeight(highlightBoxWeight); rect(plotLeft + i*colWidth + 1, plotBottom + 5, colWidth - 2, boxHeight); } } //MouseoverHandling for subcategory labels //------------------------------------------ if (mode == subcategory){ float y = plotTop + (0.02*plotHeight); float constant = plotLeft + 5; float rowHeight = (0.96*plotHeight)/110; for(int i = 0; i < YearObjs.length; i++) { float x = constant + i*colWidth; float sumRems = 0; for(int j = 0; j < 100; j++) { float barLength = map(YearObjs[i].YearCatAvgs[j], 0, yearDurMax, 0, colWidth-10); if(j > 0 && j%10 == 0){ sumRems ++; } if(mouseInRect(x, y+(j*rowHeight) + sumRems*rowHeight, colWidth, rowHeight)){ stroke(barHighlightColor); strokeWeight(barHighlightWeight); noFill(); for(int k = 0; k < YearObjs.length; k++){ barLength = map(YearObjs[k].YearCatAvgs[j], 0, yearDurMax, 0, colWidth-10); rect(plotLeft + 5 + k*colWidth, y+(j*rowHeight) + sumRems*rowHeight, barLength, rowHeight); } int area = j/10; area *= 10; float shift = 50; textFont(lLabelSubFont); fill(lLabelColor, lSubLabelTransparency); text("(" + DeweySub[j] + ")", lLabelPosX, y+(area*rowHeight)+sumRems*rowHeight + shift); } } } } } //In Months View //----------------------------------------------- else if (graphType == monthGraph){ float colWidth = plotWidth/YearObjs[selectedYearIdx].MonthObjs.length; float yrOffset = boxHeight + 5; //Highlighting around month labels //------------------------------------------ for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs.length; i++) { if(mouseX >= (plotLeft + i*colWidth) && mouseX <= (plotLeft + (i+1)*colWidth) && mouseY >= (plotBottom + 5) && mouseY <= (plotBottom + 5 + boxHeight)){ noFill(); stroke(highlightBoxColor); strokeWeight(highlightBoxWeight); rect(plotLeft + i*colWidth + 1, plotBottom + 5, colWidth - 2, boxHeight); } } //Shifted year labels //------------------------------------------ float yrColWidth = plotWidth/YearObjs.length; for(int i = 0; i < YearObjs.length; i++) { if(i == selectedYearIdx){ textFont(bLabelSubSelectedNumFont); fill(bLabelColor); } else{ textFont(bLabelSubNumFont); fill(bLabelColor, bSubLabelTransparency); } text(Years[i], (i+1)*yrColWidth+60, bLabelPosY + yrOffset); //Highlighting on shifted year labels //---------------------------------------- if( mouseX >= (plotLeft + i*yrColWidth) && mouseX <= (plotLeft + (i+1)*yrColWidth) && mouseY >= (plotBottom + 5 + yrOffset) && mouseY <= (plotBottom + 5 + yrOffset + boxHeight)){ noFill(); stroke(highlightBoxColor); strokeWeight(highlightBoxWeight); rect(plotLeft + i*yrColWidth + 1, plotBottom + 5 + yrOffset, yrColWidth - 2, boxHeight); } if( mouseX >= 0 && mouseX <= (plotLeft -1) && mouseY >= (plotBottom + 5 + yrOffset) && mouseY <= (plotBottom + 5 + yrOffset + boxHeight)){ noFill(); stroke(highlightBoxColor); strokeWeight(highlightBoxWeight); rect(1, plotBottom + 5 + yrOffset, plotLeft - 1 - 2, boxHeight); } } fill(bLabelColor, bSubLabelTransparency); text("All Years", 25, bLabelPosY + yrOffset); //MouseoverHandling for subcategory labels //------------------------------------------ if (mode == subcategory){ float y = plotTop + (0.02*plotHeight); float constant = plotLeft + 5; float rowHeight = (0.96*plotHeight)/110; for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs.length; i++) { float x = constant + i*colWidth; float sumRems = 0; for(int j = 0; j < 100; j++) { float barLength = map(YearObjs[selectedYearIdx].MonthObjs[i].MonthCatAvgs[j], 0, monthDurMax, 0, colWidth-10); if(j > 0 && j%10 == 0){ sumRems ++; } if(mouseInRect(x, y+(j*rowHeight) + sumRems*rowHeight, colWidth, rowHeight)){ stroke(barHighlightColor); strokeWeight(barHighlightWeight); noFill(); for(int k = 0; k < YearObjs[selectedYearIdx].MonthObjs.length; k++){ barLength = map(YearObjs[selectedYearIdx].MonthObjs[k].MonthCatAvgs[j], 0, monthDurMax, 0, colWidth-10); rect(plotLeft + 5 + k*colWidth, y+(j*rowHeight) + sumRems*rowHeight, barLength, rowHeight); } int area = j/10; area *= 10; float shift = 50; textFont(lLabelSubFont); fill(lLabelColor, lSubLabelTransparency); text("(" + DeweySub[j] + ")", lLabelPosX, y+(area*rowHeight)+sumRems*rowHeight + shift); } } } } } //In Days View //------------------------------------------------ else if (graphType == dayGraph){ float colWidth = plotWidth/31; float moOffset = 35; float yrOffset = 70; //Shifted month labels //------------------------------------------ float moColWidth = plotWidth/YearObjs[selectedYearIdx].MonthObjs.length; for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs.length; i++) { if(i == selectedMonthIdx){ textFont(bLabelSubSelectedTxtFont); fill(bLabelColor); } else{ textFont(bLabelSubTxtFont); fill(bLabelColor, bSubLabelTransparency); } text(Months[i], (i+1.5)*moColWidth+60, bLabelPosY + moOffset); //Highlighting on shifted month labels //---------------------------------------- if( mouseX >= (plotLeft + i*moColWidth) && mouseX <= (plotLeft + (i+1)*moColWidth) && mouseY >= (plotBottom + 5 + moOffset) && mouseY <= (plotBottom + 5 + moOffset + boxHeight)){ noFill(); stroke(highlightBoxColor); strokeWeight(highlightBoxWeight); rect(plotLeft + i*moColWidth + 1, plotBottom + 5 + moOffset, moColWidth - 2, boxHeight); } } //Shifted year labels //------------------------------------------ float yrColWidth = plotWidth/YearObjs.length; for(int i = 0; i < YearObjs.length; i++) { if(i == selectedYearIdx){ textFont(bLabelSubSelectedNumFont); fill(bLabelColor); } else{ textFont(bLabelSubNumFont); fill(bLabelColor, bSubLabelTransparency); } // text(Years[i], (i+1)*yrColWidth, bLabelPosY + yrOffset); text(Years[i], (i+1)*yrColWidth+60, bLabelPosY + yrOffset); //Highlighting on shifted year labels //---------------------------------------- if( mouseX >= (plotLeft + i*yrColWidth) && mouseX <= (plotLeft + (i+1)*yrColWidth) && mouseY >= (plotBottom + 5 + yrOffset) && mouseY <= (plotBottom + 5 + yrOffset + boxHeight)){ noFill(); stroke(highlightBoxColor); strokeWeight(highlightBoxWeight); rect(plotLeft + i*yrColWidth + 1, plotBottom + 5 + yrOffset, yrColWidth - 2, boxHeight); } if( mouseX >= 0 && mouseX <= (plotLeft -1) && mouseY >= (plotBottom + 5 + yrOffset) && mouseY <= (plotBottom + 5 + yrOffset + boxHeight)){ noFill(); stroke(highlightBoxColor); strokeWeight(highlightBoxWeight); rect(1, plotBottom + 5 + yrOffset, plotLeft - 1 - 2, boxHeight); } } fill(bLabelColor, bSubLabelTransparency); text("All Years", 25, bLabelPosY + yrOffset); //MouseoverHandling for subcategory labels //------------------------------------------ if (mode == subcategory){ float y = plotTop + (0.02*plotHeight); float constant = plotLeft + 5; float rowHeight = (0.96*plotHeight)/110; for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs[selectedMonthIdx].DayObjs.length; i++) { float x = constant + i*colWidth; float sumRems = 0; for(int j = 0; j < 100; j++) { float barLength = map(YearObjs[selectedYearIdx].MonthObjs[selectedMonthIdx].DayObjs[i].DayCatAvgs[j], 0, dayDurMax, 0, colWidth-10); if(j > 0 && j%10 == 0){ sumRems ++; } if(mouseInRect(x, y+(j*rowHeight) + sumRems*rowHeight, colWidth, rowHeight)){ stroke(barHighlightColor); strokeWeight(barHighlightWeight); noFill(); for(int k = 0; k < YearObjs[selectedYearIdx].MonthObjs[selectedMonthIdx].DayObjs.length; k++){ barLength = map(YearObjs[selectedYearIdx].MonthObjs[selectedMonthIdx].DayObjs[k].DayCatAvgs[j], 0, dayDurMax, 0, colWidth-10); rect(plotLeft + 5 + k*colWidth, y+(j*rowHeight) + sumRems*rowHeight, barLength, rowHeight); } int area = j/10; area *= 10; float shift = 50; textFont(lLabelSubFont); fill(lLabelColor, lSubLabelTransparency); text("(" + DeweySub[j] + ")", lLabelPosX, y+(area*rowHeight)+sumRems*rowHeight + shift); } } } } } } //============================= //mouseInRect() Method //============================= boolean mouseInRect(float xUpLeft, float yUpLeft, float rectWidth, float rectHeight) { if((mouseX > xUpLeft) && (mouseX < (xUpLeft+rectWidth)) && (mouseY > yUpLeft) && (mouseY < yUpLeft+rectHeight)) { return true; } else { return false; } } //============================= //mousePressed() Method //============================= void mousePressed() { //If "switch to (sub)category mode" button is pressed, then switch accordingly //------------------------------------------------------------ if (mouseInRect(0.9*plotWidth, 0.5*titleY+30, 230, 40)){ if(mode == category){ mode = subcategory; } else{ mode = category; } } //Year View //----------------------------------------- if (graphType == yearGraph) { float colWidth = plotWidth/YearObjs.length; //Set Selected Year //------------------ for(int i = 0; i < YearObjs.length; i++) { if( mouseInRect(plotLeft + i*colWidth, plotBottom, colWidth, 35)) { rect(plotLeft + i*colWidth, plotBottom, colWidth, 35); selectedYearIdx = i; graphType = monthGraph; } } } //MonthView //----------------------------------------- else if (graphType == monthGraph) { float colWidth = plotWidth/YearObjs[selectedYearIdx].MonthObjs.length; float yrColWidth = plotWidth/YearObjs.length; //Set Selected Month //------------------ for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs.length; i++) { if( mouseInRect(plotLeft + i*colWidth, plotBottom, colWidth, 40)) { selectedMonthIdx = i; graphType = dayGraph; } } //Set Selected Year //------------------ for(int i = 0; i < YearObjs.length; i++) { if( mouseInRect(plotLeft + i*yrColWidth, plotBottom + 5 + 35, yrColWidth, 35)) { selectedYearIdx = i; graphType = monthGraph; } } //If "All Years" button is pressed, revert to Year View //------------------ if(mouseInRect(0, plotBottom + 5 + 35, plotLeft, 35)){ selectedYearIdx = 0; graphType = yearGraph; } } //DayView //----------------------------------------- else if (graphType == dayGraph) { float moColWidth = plotWidth/YearObjs[selectedYearIdx].MonthObjs.length; float yrColWidth = plotWidth/YearObjs.length; //Set Selected Month //------------------ for(int i = 0; i < YearObjs[selectedYearIdx].MonthObjs.length; i++) { if( mouseInRect(plotLeft + i*moColWidth, plotBottom+5+35, moColWidth, 35)) { selectedMonthIdx = i; graphType = dayGraph; } } //Set Selected Year //------------------ for(int i = 0; i < YearObjs.length; i++) { if( mouseInRect(plotLeft + i*yrColWidth, plotBottom + 5 + 65, yrColWidth, 35)) { selectedYearIdx = i; graphType = dayGraph; } } //If "All Years" button is pressed, revert to Year View //------------------ if(mouseInRect(0, plotBottom + 5 + 65, plotLeft, 35)){ selectedYearIdx = 0; graphType = yearGraph; } } }