/*
* Author: tdanford
* Date: Jul 18, 2008
*/
package org.seqcode.viz.paintable;
import java.util.*;
import java.awt.*;
public class PaintableScale {
private double min, max;
private LinkedList<PaintableScaleListener> listeners;
public PaintableScale(double m1, double m2) {
min = m1;
max = m2;
listeners = new LinkedList<PaintableScaleListener>();
}
public String toString() {
return String.format("Scale: %.3f-%.3f", min, max);
}
public void addPaintableScaleListener(PaintableScaleListener psl) {
listeners.addLast(psl);
}
public void removePaintableScaleListener(PaintableScaleListener psl) {
listeners.remove(psl);
}
public double getMin() { return min; }
public double getMax() { return max; }
public double getRange() { return max - min; }
public double fractionalOffset(double value) { return (value-min)/getRange(); }
public void setScale(double m1, double m2) {
if(m1 > m2) { throw new IllegalArgumentException(); }
min = m1;
max = m2;
dispatchPaintableChangedEvent();
}
public void updateScale(double newPoint) {
if(newPoint < min){
min = newPoint;
dispatchPaintableChangedEvent();
}else if(newPoint>max){
max = Math.max(newPoint, max);
dispatchPaintableChangedEvent();
}
}
private void dispatchPaintableChangedEvent() {
PaintableScaleChangedEvent evt = new PaintableScaleChangedEvent(this);
for(PaintableScaleListener list : listeners) {
list.paintableScaleChanged(evt);
}
}
private static double pow(double base, int exp) {
double x = 1.0;
for(int i = 0; i < exp; i++) { x *= base; }
for(int i = 0; i > exp; i--) { x /= base; }
return x;
}
public double[] findHashMarks(int maxTicks) {
double range = max-min;
double exp = Math.log(range) / Math.log(10.0);
double hash = pow(10.0, (int)Math.floor(exp));
int ticks = (int)Math.floor(range/hash);
double[] mults = new double[] { 5.0, 2.0 };
for(int i = 0; ticks > maxTicks; i += 1) {
hash *= mults[i % mults.length];
ticks = (int)Math.floor(range / hash);
}
double lower = Math.floor(min/hash) * hash;
if(lower < min) { lower += hash; }
double upper = Math.ceil(max/hash) * hash;
if(upper > max) { upper -= hash; }
int count = (int)Math.round((upper-lower)/hash);
double[] array = new double[count];
double h = lower;
for(int i = 0; i < array.length; i++, h += hash) {
array[i] = h;
}
return array;
}
}