/****************************************************************************************
* Copyright (c) 2014 Michael Goldbach <michael@wildplot.com> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
* Foundation; either version 3 of the License, or (at your option) any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
package com.wildplot.android.rendering;
import com.wildplot.android.rendering.graphics.wrapper.ColorWrap;
import com.wildplot.android.rendering.graphics.wrapper.GraphicsWrap;
import com.wildplot.android.rendering.graphics.wrapper.RectangleWrap;
import com.wildplot.android.rendering.interfaces.Drawable;
/**
* BarGraph Drawable, draw bars on specified positions filled with color or not
*
*
*/
public class XAxisBarGraph implements Drawable {
private double extraScaleFactor = 1;
private boolean autoscale = false;
private double scaleFactor = 10;
private boolean isOnFrame = false;
private double yOffset = 0;
private PlotSheet plotSheet;
private double[][] points;
private double size = 1;
private ColorWrap color;
private ColorWrap fillColor;
private boolean filling = false;
/**
* @param plotSheet
* @param points the points used for calculating histogram data
* @param size size of bars from left to right
* @param color border color of bars, for filling color use setFilling() and setFillingColor()
*/
public XAxisBarGraph(PlotSheet plotSheet, double[][] points, double size, ColorWrap color) {
super();
this.plotSheet = plotSheet;
this.points = points;
this.size = size;
this.color = color;
}
/**
* determine if bars are filled with color or not
* @param filling true if bars should be filled
*/
public void setFilling(boolean filling) {
this.filling = filling;
if(this.fillColor == null && filling) {
this.fillColor = this.color.brighter();
}
}
/**
* set filling color for bars
* @param fillColor
*/
public void setFillColor(ColorWrap fillColor) {
this.fillColor = fillColor;
}
/* (non-Javadoc)
* @see rendering.Drawable#paint(java.awt.Graphics)
*/
@Override
public void paint(GraphicsWrap g) {
ColorWrap oldColor = g.getColor();
RectangleWrap field = g.getClipBounds();
g.setColor(color);
if(autoscale){
double[] start = this.plotSheet.toCoordinatePoint(0, 0, field);
double[] end = this.plotSheet.toCoordinatePoint(0,
0+this.plotSheet.getFrameThickness()[PlotSheet.UPPER_FRAME_THICKNESS_INDEX], field);
this.scaleFactor = Math.abs(end[1] - start[1]);
} else {
this.scaleFactor = 1.0;
}
if(this.isOnFrame)
yOffset = plotSheet.getyRange()[0];
for(int i = 0; i<this.points[0].length; i++) {
if(points.length == 3) {
drawBar(points[0][i], points[1][i]*scaleFactor*extraScaleFactor, g, field, points[2][i]);
} else {
drawBar(points[0][i], points[1][i]*scaleFactor*extraScaleFactor, g, field);
}
}
g.setColor(oldColor);
}
/**
* draw a single bar at given coordinate and with the given height
* @param x coordinate on plot
* @param y height
* @param g graphic object used to draw this bar
* @param field bounds of plot
*/
private void drawBar(double x, double y, GraphicsWrap g, RectangleWrap field) {
drawBar(x,y,g,field,this.size);
}
/**
* draw a single bar at given coordinate and with the given height with given specific size
* @param x coordinate on plot
* @param heigth height
* @param g graphic object used to draw this bar
* @param field bounds of plot
* @param size specific size (width) of this bar
*/
private void drawBar(double x, double heigth, GraphicsWrap g, RectangleWrap field, double size) {
float[] pointUpLeft = plotSheet.toGraphicPoint(x, heigth, field);
float[] pointUpRight = plotSheet.toGraphicPoint(x+size, heigth, field);
float[] pointBottomLeft = plotSheet.toGraphicPoint(x, 0, field);
if(heigth < 0) {
pointUpLeft = plotSheet.toGraphicPoint(x, 0, field);
pointUpRight = plotSheet.toGraphicPoint(x+size, 0, field);
pointBottomLeft = plotSheet.toGraphicPoint(x, heigth, field);
}
if(this.isOnFrame) {
pointUpLeft = plotSheet.toGraphicPoint(x, this.yOffset, field);
pointUpRight = plotSheet.toGraphicPoint(x+size, this.yOffset, field);
pointBottomLeft = plotSheet.toGraphicPoint(x,this.yOffset-heigth , field);
}
if(filling){
ColorWrap oldColor = g.getColor();
if(this.fillColor != null)
g.setColor(fillColor);
g.fillRect(pointUpLeft[0], pointUpLeft[1], pointUpRight[0]-pointUpLeft[0], pointBottomLeft[1]-pointUpLeft[1]);
//g.fillRect(pointUpLeft[0], pointUpLeft[1], pointUpRight[0]-pointUpLeft[0], pointBottomLeft[1]-pointUpLeft[1]);
g.setColor(oldColor);
}
g.drawRect(pointUpLeft[0], pointUpLeft[1], pointUpRight[0]-pointUpLeft[0], pointBottomLeft[1]-pointUpLeft[1]);
// g.drawLine(pointUpLeft[0], pointUpLeft[1], pointUpRight[0], pointUpRight[1]);
// g.drawLine(pointUpLeft[0], pointUpLeft[1], pointBottomLeft[0], pointBottomLeft[1]);
// g.drawLine(pointBottomRight[0], pointBottomRight[1], pointBottomLeft[0], pointBottomLeft[1]);
}
/**
* unset the axis to draw on the border between outer frame and plot
*/
public void unsetOnFrame() {
this.isOnFrame = false;
yOffset = 0;
}
public void setOnFrame(double extraSpace) {
this.isOnFrame = true;
yOffset = plotSheet.getyRange()[0]-extraSpace;
}
public void setOnFrame() {
setOnFrame(0);
}
/**
* returns if this histogram is can draw on the outer frame of plot
*/
public boolean isOnFrame() {
return this.isOnFrame;
}
public void setAutoscale() {
this.autoscale = true;
}
public void unsetAutoscale() {
this.autoscale = false;
}
public double getExtraScaleFactor() {
return extraScaleFactor;
}
public void setExtraScaleFactor(double extraScaleFactor) {
this.extraScaleFactor = extraScaleFactor;
}
@Override
public void abortAndReset() {
// TODO Auto-generated method stub
}
@Override
public boolean isClusterable() {
return true;
}
@Override
public boolean isCritical() {
return false;
}
}