class deweyModel extends deweyItem implements MapModel{ MapLayout algorithm; Mappable[] items; ArrayList deweyItemArray; float textPadding = 12; boolean layoutValid; boolean contentsVisible; public deweyModel(){ deweyItemArray = new ArrayList(); } public deweyModel(String name){ this(); this.name = name; } public deweyModel(MapLayout algorithm){ this(); this.algorithm = algorithm; } void addDeweyItem(int dewey, int amount,int rank,float curP,float prevP){ deweyItem item = new deweyItem(this,dewey,amount,rank,curP,prevP); item.setSize(amount); deweyItemArray.add(item); size += amount; } void addDeweyCate(deweyModel parent,deweyModel deweyCate){ deweyCate.parent = parent; deweyCate.algorithm = parent.algorithm; deweyItemArray.add(deweyCate); size += deweyCate.getSize(); } void finishAddItem(float prevP){ items = new deweyItem[deweyItemArray.size()]; deweyItemArray.toArray(items); this.curP = (float)(size / currentSum); this.prevP = prevP; if(curP - prevP <= 0){ negCateChangePercent.add((prevP - curP) / prevP); }else{ if(prevP == 0){} //posCateChangePercent.add(10); else posCateChangePercent.add((curP - prevP) / prevP); } } void finishAddCate(){ items = new deweyModel[deweyItemArray.size()]; deweyItemArray.toArray(items); } void checkLayout( ) { if (!layoutValid) { if (getItemCount()!= 0) { algorithm.layout(this, bounds); } layoutValid = true; } } boolean textFits() { float wide = textWidth(name) + textPadding*2; float high = textAscent() + textDescent() + textPadding*2; return (boxRight - boxLeft > wide) && (boxBottom - boxTop > high); } void draw( ) { checkLayout(); calcBox(); if(contentsVisible){ for (int i = 0; i < items.length; i++) items[i].draw( ); }else{ fill(c); rect(boxLeft, boxTop, boxRight, boxBottom); if (mouseInside()) { rolloverItem = this; } } noFill(); stroke(204); strokeWeight(2); rect(boxLeft, boxTop, boxRight, boxBottom); if(name != null && textFits() && zoomItem!=this){ drawTitle(); } } void drawTitle() { fill(255,200); textFont(pfont); float middleX = (boxLeft + boxRight) / 2; float middleY = (boxTop + boxBottom) / 2; if (middleX > 0 && middleX < width && middleY > 0 && middleY < height) { if (boxLeft + textWidth(name) + textPadding*2 > width) { textAlign(RIGHT); text(name, width - textPadding, boxBottom - textPadding); } else { textAlign(LEFT); text(name, boxLeft + textPadding, boxBottom - textPadding); } } } Mappable[] getItems( ) { return items; } int getItemCount( ) { return items.length; } boolean mousePressed() { if (mouseInside()){ if (contentsVisible) { // Pass the mouse press to the child items for (int i = 0; i < items.length; i++) { deweyItem item = (deweyItem) items[i]; if (item.mousePressed()) { return true; } } }else { // not opened if (mouseButton == LEFT) { if (parent == zoomItem) { showContents(); }else { parent.zoomIn(); } }else if (mouseButton == RIGHT) { if (parent == zoomItem) { parent.zoomOut(); }else{ parent.hideContents(); } } return true; } } return false; } // Zoom to the parent's boundary, zooming out from this item void zoomOut() { if (parent != null) { // Close contents of any opened children for (int i = 0; i < items.length; i++) { if (items[i] instanceof deweyModel) { ((deweyModel)items[i]).hideContents(); } } parent.zoomIn(); } } void updateColors() { if(parent != null){ if(curP - prevP <= 0){ c = lerpColor(downColor,0,negCateChangePercent.percentile((prevP - curP) / prevP)); }else{ if(prevP == 0) c = upColor; else c = lerpColor(0,upColor,posCateChangePercent.percentile((curP - prevP) / prevP)); } } for (int i = 0; i < items.length; i++) { ((deweyItem)items[i]).updateColors(); } } void zoomIn() { zoomItem = this; zoomBounds.target(x, y, w, h); ///width, h/height); } void showContents(){ contentsVisible = true; } void showChildrenContents(){ for (int i = 0; i < items.length; i++) { ((deweyModel)items[i]).showContents(); } } void hideContents(){ // Prevent the user from closing the root level. if (parent != null){ contentsVisible = false; } } void hideChildrenContents(){ for (int i = 0; i < items.length; i++) { ((deweyModel)items[i]).hideContents(); } } void highlightSameColor(color cs){ if(this == RootTreeMap){ for(int i = 0; i < items.length; i++){ ((deweyModel)items[i]).highlightSameColor(cs); } }else{ for(int i = 0; i < items.length; i++){ ((deweyItem)items[i]).highlightSameColor(cs); } } } }