1 package JSci.swing; 2 3 import java.awt.*; 4 import java.awt.geom.Point2D ; 5 import java.text.DecimalFormat ; 6 import java.text.NumberFormat ; 7 import java.text.ParseException ; 8 import JSci.awt.*;import JSci.maths.ExtraMath; 9 10 16 public class JBarGraph extends JCategoryGraph2D { 17 20 protected Color barColor[]={Color.blue,Color.green,Color.red,Color.yellow,Color.cyan,Color.lightGray,Color.magenta,Color.orange,Color.pink}; 21 24 protected float minY,maxY; 25 28 private final float yIncPixels = 40.0f; 29 private float yInc; 30 private boolean autoYInc = true; 31 private float xScale,yScale; 32 protected int barWidth; 33 36 protected final int barPad=0; 37 40 protected boolean numbering=true; 41 protected NumberFormat yNumberFormat = new DecimalFormat ("##0.0"); 42 45 public JBarGraph(CategoryGraph2DModel cgm) { 46 super(cgm); 47 dataChanged(new GraphDataEvent(model)); 48 } 49 53 public void dataChanged(GraphDataEvent e) { 54 minY=0.0f; 55 maxY=Float.NEGATIVE_INFINITY; 56 model.firstSeries(); 57 do { 58 for(int i=0;i<model.seriesLength();i++) { 59 float tmp=model.getValue(i); 60 minY=Math.min(tmp,minY); 61 maxY=Math.max(tmp,maxY); 62 } 63 } while(model.nextSeries()); 64 if(minY==maxY) { 65 minY-=0.5f; 66 maxY+=0.5f; 67 } 68 setNumbering(numbering); 69 } 70 75 public final void setColor(int n,Color c) { 76 barColor[n]=c; 77 redraw(); 78 } 79 83 public final Color getColor(int n) { 84 return barColor[n]; 85 } 86 89 public final void setNumbering(boolean flag) { 90 numbering=flag; 91 leftAxisPad=axisPad; 92 if(numbering && getFont() != null) { 93 final FontMetrics metrics = getFontMetrics(getFont()); 95 final int maxYNumLen = metrics.stringWidth(yNumberFormat.format(maxY)); 96 final int minYNumLen = metrics.stringWidth(yNumberFormat.format(minY)); 97 final int yNumPad = Math.max(minYNumLen, maxYNumLen); 98 leftAxisPad+=yNumPad; 99 } 100 rescale(); 101 } 102 public void addNotify() { 103 super.addNotify(); 104 setNumbering(numbering); 107 } 108 113 public final void setNumberFormat(NumberFormat format) { 114 yNumberFormat = format; 115 setNumbering(numbering); 116 } 117 120 public final void setYNumberFormat(NumberFormat format) { 121 yNumberFormat = format; 122 setNumbering(numbering); 123 } 124 128 public final void setYIncrement(float dy) { 129 if(dy < 0.0f) { 130 throw new IllegalArgumentException ("Increment should be positive."); 131 } else if(dy == 0.0f) { 132 if(!autoYInc) { 133 autoYInc = true; 134 rescale(); 135 } 136 } else { 137 autoYInc = false; 138 if(dy != yInc) { 139 yInc = dy; 140 rescale(); 141 } 142 } 143 } 144 147 public final float getYIncrement() { 148 return yInc; 149 } 150 public final float getYMinimum() { 151 return minY; 152 } 153 public final float getYMaximum() { 154 return maxY; 155 } 156 159 protected final void drawAxes(Graphics g) { 160 g.setColor(getForeground()); 161 if(minY > 0.0f) { 163 g.drawLine(leftAxisPad-scalePad,getHeight()-axisPad,getWidth()-(axisPad-scalePad),getHeight()-axisPad); 164 } else { 165 g.drawLine(leftAxisPad-scalePad,origin.y,getWidth()-(axisPad-scalePad),origin.y); 166 } 167 g.drawLine(origin.x,axisPad-scalePad,origin.x,getHeight()-(axisPad-scalePad)); 168 for(int x=0; x<model.seriesLength(); x++) { 170 drawXLabel(g, x); 171 } 172 if(numbering) { 174 for(double y=yInc; y<=maxY; y+=yInc) { 176 drawYLabel(g, (float) y); 177 } 178 for(double y=-yInc; y>=minY; y-=yInc) { 179 drawYLabel(g, (float) y); 180 } 181 } 182 } 183 protected void drawXLabel(Graphics g, int x) { 184 Point p = dataToScreen(x+1.0f, 0.0f); 185 String str = model.getCategory(x); 186 FontMetrics metrics = g.getFontMetrics(); 187 int strWidth = metrics.stringWidth(str); 188 int strHeight = metrics.getHeight(); 189 boolean numberingAbove = (maxY <= 0.0f); 190 if(numberingAbove) { 191 g.drawLine(p.x,p.y,p.x,p.y-5); 192 g.drawString(str, dataToScreen(x+0.5f-0.5f*strWidth/xScale, 0.0f).x, origin.y-5); 193 } else { 194 g.drawLine(p.x,p.y,p.x,p.y+5); 195 g.drawString(str, dataToScreen(x+0.5f-0.5f*strWidth/xScale, 0.0f).x, origin.y+strHeight); 196 } 197 } 198 protected void drawYLabel(Graphics g, float y) { 199 Point p = dataToScreen(0.0f, y); 200 String str = yNumberFormat.format(y); 201 FontMetrics metrics = g.getFontMetrics(); 202 int strWidth = metrics.stringWidth(str); 203 int strHeight = metrics.getHeight(); 204 g.drawLine(p.x, p.y, p.x-5, p.y); 205 g.drawString(str, p.x-8-strWidth, p.y+strHeight/3); 206 } 207 210 protected void drawBars(Graphics g) { 211 int numSeries=1; 213 model.firstSeries(); 214 while(model.nextSeries()) 215 numSeries++; 216 if(numSeries==1) { 217 for(int i=0;i<model.seriesLength();i++) 218 drawBar(g, i, model.getValue(i), barColor[0], barWidth, 0); 219 } else { 220 final float subBarWidth = ((float)barWidth)/((float)numSeries); 221 final int subBarPixelWidth = Math.round(subBarWidth); 222 for(int i=0;i<model.seriesLength();i++) { 223 model.firstSeries(); 225 for(int j=0;j<numSeries;j++) { 226 drawBar(g, i, model.getValue(i), barColor[j], subBarPixelWidth, Math.round(j*subBarWidth)); 227 model.nextSeries(); 228 } 229 } 230 } 231 } 232 235 private void drawBar(Graphics g, int pos, float value, Color color, int width, int xoffset) { 236 final Point p = dataToScreen(pos, value); 237 final int y = (value<0.0f ? origin.y : p.y); 238 final int dy=Math.abs(p.y-origin.y); 239 g.setColor(color); 240 g.fillRect(p.x+barPad+xoffset, y, width, dy); 241 g.setColor(Color.black); 242 g.drawRect(p.x+barPad+xoffset, y, width, dy); 243 } 244 247 protected void offscreenPaint(Graphics g) { 248 drawBars(g); 249 drawAxes(g); 250 } 251 254 public final void setBounds(int x,int y,int width,int height) { 255 super.setBounds(x,y,width,height); 256 rescale(); 257 } 258 261 protected final void rescale() { 262 final Dimension minSize=getMinimumSize(); 263 final int thisWidth=Math.max(getWidth(),minSize.width); 265 final int thisHeight=Math.max(getHeight(),minSize.height); 266 xScale = (float)(thisWidth-(leftAxisPad+axisPad)) / (float)model.seriesLength(); 267 float deltaY; 268 if(minY > 0.0f) 269 deltaY = maxY; 270 else if(maxY < 0.0) 271 deltaY = -minY; 272 else 273 deltaY = maxY-minY; 274 yScale = (float) ((double)(thisHeight-2*axisPad) / (double)(deltaY)); 275 if(autoYInc) { 276 yInc = (float) ExtraMath.round((double)yIncPixels/(double)yScale, 1); 277 if(yInc == 0.0f) 278 yInc = Float.MIN_VALUE; 279 } 280 barWidth=Math.round(xScale-2*barPad); 281 origin.x=leftAxisPad; 282 origin.y=thisHeight-axisPad+Math.round(minY*yScale); 283 redraw(); 284 } 285 288 protected final Point dataToScreen(float x,float y) { 289 return new Point(origin.x+Math.round(xScale*x),origin.y-Math.round(yScale*y)); 290 } 291 294 protected final Point2D.Float screenToData(Point p) { 295 double x = (double)(p.x-origin.x) / (double)xScale; 296 double y = (double)(origin.y-p.y) / (double)yScale; 297 return new Point2D.Float ((float)x, (float)y); 298 } 299 } 300 | Popular Tags |