/******************************************************************************* * Copyright (c) 2013 Luigi Sgro. All rights reserved. This * program and the accompanying materials are made available under the terms of * the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Luigi Sgro - initial API and implementation ******************************************************************************/ package com.quantcomponents.chart.series; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import com.quantcomponents.chart.IMarkScale; import com.quantcomponents.chart.IMark; /** * A mark scale for chart axis with {@link java.util.Date} values * This class is not thread-safe. In a multi-threading environment a new instance must should be created for each use. */ public abstract class TimeScale implements IMarkScale<Date> { private final int calendarUnit; private final int calendarAmount; private final long stepDuration; private TimeScale parent; protected final Calendar cal; public TimeScale(int calendarUnit, int calendarAmount, TimeZone timeZone, long stepDuration) { this.calendarUnit = calendarUnit; this.calendarAmount = calendarAmount; this.stepDuration = stepDuration; cal = Calendar.getInstance(timeZone); parent = buildParent(timeZone); } protected abstract TimeScale buildParent(TimeZone timeZone); public int getCalendarUnit() { return calendarUnit; } public int getCalendarAmount() { return calendarAmount; } @Override public double getStepSize() { return stepDuration; } @Override public int compareTo(IMarkScale<Date> o) { if (o instanceof TimeScale) { TimeScale tg = (TimeScale) o; if (calendarUnit == tg.calendarUnit) { return Integer.valueOf(calendarAmount).compareTo(tg.calendarAmount); } else { return - Integer.valueOf(calendarUnit).compareTo(tg.calendarUnit); // Calendar units are ordered inversely of magnitude } } else { throw new IllegalArgumentException("Can only compare to a " + TimeScale.class.getName() + " instance"); } } @Override public IMark<Date> followingMark(Date date) { cal.setTime(previousMark(date).getValue()); cal.add(getCalendarUnit(), getCalendarAmount()); return new TimeMark(this, cal.getTime()); } @Override public IMark<Date> nearestMark(Date date) { IMark<Date> p = previousMark(date); IMark<Date> f = followingMark(date); if (date.getTime() - p.getValue().getTime() <= f.getValue().getTime() - date.getTime()) { return p; } else { return f; } } @Override public boolean equals(Object o) { if (o instanceof TimeScale) { TimeScale tg = (TimeScale) o; return calendarUnit == tg.calendarUnit && calendarAmount == tg.calendarAmount; } else { return false; } } @Override public int hashCode() { return Integer.valueOf(calendarUnit + calendarAmount).hashCode(); } @Override public IMarkScale<Date> parent() { return parent; } }