1 3 package org.faceless.graph2; 4 5 import java.text.DateFormat ; 6 import java.text.SimpleDateFormat ; 7 import java.util.*; 8 9 26 public class DateAxis extends Axis 27 { 28 private static final long MIDPOINT = 788940000; private static final int SECDAYS=60*60*24; private static final double mul=1000; 33 final DateFormat f; 34 final boolean hasseconds, hashours, hasminutes, hasdays, hasmonths; 35 private final float mdensity; 36 private boolean barsatnoon; 37 38 41 public DateAxis() 42 { 43 this(new SimpleDateFormat ("dd-MMM-yyyy")); 44 } 45 46 49 public DateAxis(DateFormat format) 50 { 51 this(format, DENSITY_NORMAL); 52 } 53 54 60 public DateAxis(DateFormat format, int density) 61 { 62 f = format; 63 long l = 1012820522000l; String s = f.format(new Date(l)); 65 hasseconds = !s.equals(f.format(new Date(l+1000l))); 66 hasminutes = !s.equals(f.format(new Date(l+60000l))); 67 hashours = !s.equals(f.format(new Date(l+3700000l))); 68 hasdays = !s.equals(f.format(new Date(l+90100000l))); 69 hasmonths = !s.equals(f.format(new Date(l+2678400000l))); 70 this.mdensity = density/10f; 71 } 72 73 public String format(double in) 74 { 75 return f.format(toDate(in)); 76 } 77 78 89 public static final double toDouble(Date in) 90 { 91 return (double)(in.getTime()/mul)-MIDPOINT; 92 } 93 94 99 public static final Date toDate(double in) 100 { 101 return new Date((long)((in+MIDPOINT)*mul)); 102 } 103 104 public double[] steps(double min, double max) 105 { 106 Date start = toDate(min); 107 Date end = toDate(max); 108 long diff = (long)(max-min); int step; 110 111 if (hasseconds && diff<1800) { 112 step = 1; 113 } else if (hasminutes && diff<43200) { 114 step = 60; 115 } else if (hashours && diff<SECDAYS*7) { 116 step = 3600; 117 } else { 118 step = SECDAYS; 119 } 120 121 List a = new ArrayList(); 122 123 String oldt=null, t=null; 124 for (long i=((int)(min+step)/step)*step;i<=(int)(max+(step/2));i+=step) 125 { 126 Calendar c = new GregorianCalendar(); 127 c.setTime(toDate((double)i)); 128 if (step==SECDAYS && c.get(c.HOUR_OF_DAY)!=0) { 129 int h = c.get(c.HOUR_OF_DAY); 130 if (h>=22) h=24-h; 131 i-=(h*60*60); 132 c.setTime(toDate((double)i)); 133 } 134 135 boolean add=false; 136 if (hasseconds && diff<=15*mdensity) { add=true; 138 } else if (hasseconds && diff<=60*mdensity) { if (c.get(c.SECOND)%5==0) add=true; 140 } else if (hasseconds && diff<=180*mdensity) { if (c.get(c.SECOND)%15==0) add=true; 142 } else if (hasseconds && diff<=300*mdensity) { if (c.get(c.SECOND)%30==0) add=true; 144 } else if (hasminutes && diff<=900*mdensity) { if (c.get(c.SECOND)==0) add=true; 146 } else if (hasminutes && diff<=3600*mdensity) { if (c.get(c.MINUTE)%5==0 && c.get(c.SECOND)==0) add=true; 148 } else if (hasminutes && diff<=7200*mdensity) { if (c.get(c.MINUTE)%10==0 && c.get(c.SECOND)==0) add=true; 150 } else if (hasminutes && diff<=10800*mdensity) { if (c.get(c.MINUTE)%15==0 && c.get(c.SECOND)==0) add=true; 152 } else if (hasminutes && diff<=21600*mdensity) { if (c.get(c.MINUTE)%30==0 && c.get(c.SECOND)==0) add=true; 154 } else if (hashours && diff<=SECDAYS*mdensity) { if (c.get(c.HOUR_OF_DAY)%2==0 && c.get(c.MINUTE)==0) add=true; 156 } else if (hashours && diff<4*SECDAYS*mdensity) { if (c.get(c.HOUR_OF_DAY)%6==0 && c.get(c.MINUTE)==0) add=true; 158 } else if (hashours && diff<=6*SECDAYS*mdensity) { if (c.get(c.HOUR_OF_DAY)%12==0 && c.get(c.MINUTE)==0) add=true; 160 } else if (diff<15*SECDAYS*mdensity) { if (step>3600 || c.get(c.HOUR_OF_DAY)==0) add=true; 162 } else if (diff<32*SECDAYS*mdensity) { if (c.get(c.DAY_OF_MONTH)%2==1 && c.get(c.HOUR_OF_DAY)==0) add=true; 164 } else if (diff<100*SECDAYS*mdensity) { if (c.get(c.DAY_OF_WEEK)==1 && c.get(c.HOUR_OF_DAY)==0) add=true; 166 } else if (diff<200*SECDAYS*mdensity) { if ((c.get(c.DAY_OF_MONTH)==1 || c.get(c.DAY_OF_MONTH)==15) && c.get(c.HOUR_OF_DAY)==0) add=true; 168 } else if (diff<367*SECDAYS*mdensity) { if (c.get(c.DAY_OF_MONTH)==1 && c.get(c.HOUR_OF_DAY)==0) add=true; 170 } else if (diff<730*SECDAYS*mdensity) { if (c.get(c.DAY_OF_MONTH)==1 && c.get(c.MONTH)%2==0 && c.get(c.HOUR_OF_DAY)==0) add=true; 172 } else if (diff<2190*SECDAYS*mdensity) { if (c.get(c.DAY_OF_MONTH)==1 && c.get(c.MONTH)%3==0 && c.get(c.HOUR_OF_DAY)==0) add=true; 174 } else if (diff<4400*SECDAYS*mdensity) { if (c.get(c.DAY_OF_MONTH)==1 && c.get(c.MONTH)%6==0 && c.get(c.HOUR_OF_DAY)==0) add=true; 176 } else if (diff<5478*SECDAYS*mdensity) { if (c.get(c.DAY_OF_MONTH)==1 && c.get(c.MONTH)==0 && c.get(c.HOUR_OF_DAY)==0) add=true; 178 } else { int y = (int)(diff/(5478*SECDAYS*mdensity))+1; 180 if (c.get(c.DAY_OF_MONTH)==1 && c.get(c.MONTH)==0 && (c.get(c.YEAR)%y)==0 && c.get(c.HOUR_OF_DAY)==0) add=true; 181 } 182 if (add) { 183 oldt=t; 184 t = format((double)i); 185 if (!t.equals(oldt)) { 186 a.add(new Double (i)); 187 } 188 } 189 } 190 191 if (a.size()<2) { 196 a.clear(); 197 a.add(new Double (min)); 198 a.add(new Double (max)); 199 } else { 200 double first = ((Double )a.get(0)).doubleValue(); 201 double last = ((Double )a.get(a.size()-1)).doubleValue(); 202 if (first!=min) { 203 t = format(min); 204 String t2 = format(first); 205 if (!t.equals(t2)) { 206 if ((first-min)/(max-min)>0.05/mdensity) { 207 a.add(0, new Double (min)); 208 } else { 210 a.set(0, new Double (min)); 211 } 212 } else { 213 a.set(0, new Double (first<min?first:min)); 214 } 215 } 216 if (last!=max) { 217 t = format(max); 218 String t2 = format(last); 219 if (!t.equals(t2)) { 220 if (((max-last)/(max-min))>0.05/mdensity) { 221 a.add(new Double (max)); 222 } else { 223 a.set(a.size()-1, new Double (max)); 224 } 225 } else { 226 a.set(a.size()-1, new Double (last>max?last:max)); 227 } 228 } 229 } 230 231 double[] out = new double[a.size()]; 234 for (int i=0;i<out.length;i++) { 235 out[i] = ((Double )a.get(i)).doubleValue(); 236 } 237 return out; 238 } 239 240 249 public void setBarsAtNoon(boolean noon) 250 { 251 this.barsatnoon = noon; 252 } 253 254 boolean getBarsAtNoon() 255 { 256 return barsatnoon; 257 } 258 } 259 | Popular Tags |