27 package org.sleuthkit.autopsy.timeline.ui.detailview;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.List;
32 import javafx.beans.property.ObjectProperty;
33 import javafx.beans.property.ObjectPropertyBase;
34 import javafx.beans.property.ReadOnlyDoubleProperty;
35 import javafx.beans.property.ReadOnlyDoubleWrapper;
36 import javafx.scene.chart.Axis;
37 import org.joda.time.DateTime;
38 import org.joda.time.Interval;
52 final class DateAxis
extends Axis<DateTime> {
54 private ObjectProperty<DateTime> lowerBound =
new ObjectPropertyBase<DateTime>() {
56 protected void invalidated() {
57 if (!isAutoRanging()) {
64 public Object getBean() {
69 public String getName() {
79 private DateTime maxDate;
86 private DateTime minDate;
90 private final ReadOnlyDoubleWrapper tickSpacing =
new ReadOnlyDoubleWrapper();
92 private final ObjectProperty<DateTime> upperBound =
new ObjectPropertyBase<DateTime>() {
94 protected void invalidated() {
95 if (!isAutoRanging()) {
102 public Object getBean() {
103 return DateAxis.this;
107 public String getName() {
117 setAutoRanging(
false);
121 public double getDisplayPosition(DateTime date) {
122 final double length = -200 + (getSide().isHorizontal() ? getWidth() : getHeight());
125 double diff = getUpperBound().getMillis() - getLowerBound().getMillis();
129 double range = length - getZeroPosition();
133 double d = (date.getMillis() - getLowerBound().getMillis()) / diff;
136 if (getSide().isVertical()) {
137 return getHeight() - d * range + getZeroPosition();
139 return d * range + getZeroPosition();
150 public final DateTime getLowerBound() {
151 return lowerBound.get();
161 public final void setLowerBound(DateTime date) {
162 lowerBound.set(date);
172 public final DateTime getUpperBound() {
173 return upperBound.get();
183 public final void setUpperBound(DateTime date) {
184 upperBound.set(date);
188 public DateTime getValueForDisplay(
double displayPosition) {
189 final double length = - 200 + (getSide().isHorizontal() ? getWidth() : getHeight());
192 double diff = getUpperBound().getMillis() - getLowerBound().getMillis();
196 double range = length - getZeroPosition();
198 if (getSide().isVertical()) {
201 return new DateTime((
long) ((displayPosition - getZeroPosition() - getHeight()) / -range * diff + getLowerBound().getMillis()),
TimeLineController.
getJodaTimeZone());
210 public double getZeroPosition() {
215 public void invalidateRange(List<DateTime> list) {
216 super.invalidateRange(list);
218 Collections.sort(list);
219 if (list.isEmpty()) {
220 minDate = maxDate =
new DateTime();
221 }
else if (list.size() == 1) {
222 minDate = maxDate = list.get(0);
223 }
else if (list.size() > 1) {
224 minDate = list.get(0);
225 maxDate = list.get(list.size() - 1);
230 public boolean isValueOnAxis(DateTime date) {
231 return date.getMillis() > getLowerBound().getMillis() && date.getMillis() < getUpperBound().getMillis();
235 public double toNumericValue(DateTime date) {
236 return date.getMillis();
240 public DateTime toRealValue(
double v) {
241 return new DateTime((
long) v);
245 protected Interval autoRange(
double length) {
246 if (isAutoRanging()) {
247 return new Interval(minDate, maxDate);
249 if (getLowerBound() == null || getUpperBound() == null) {
257 protected List<DateTime> calculateTickValues(
double length, Object range) {
258 List<DateTime> tickDates =
new ArrayList<>();
263 final DateTime lowerBound1 = getLowerBound();
264 final DateTime upperBound1 = getUpperBound();
266 if (lowerBound1 == null || upperBound1 == null) {
272 DateTime current = lower;
274 while (current.isBefore(upper)) {
275 tickDates.add(current);
280 tickDates.add(upper);
286 if (tickDates.size() > 2) {
287 DateTime secondDate = tickDates.get(1);
288 DateTime thirdDate = tickDates.get(2);
289 DateTime lastDate = tickDates.get(tickDates.size() - 2);
290 DateTime previousLastDate = tickDates.get(tickDates.size() - 3);
293 if (secondDate.getMillis() - lower.getMillis() < (thirdDate.getMillis() - secondDate.getMillis()) / 2) {
294 tickDates.remove(lower);
299 if (upper.getMillis() - lastDate.getMillis() < (lastDate.getMillis() - previousLastDate.getMillis()) / 2) {
300 tickDates.remove(lastDate);
304 if (tickDates.size() >= 2) {
305 tickSpacing.set(getDisplayPosition(tickDates.get(1)) - getDisplayPosition(tickDates.get(0)));
306 }
else if (tickDates.size() >= 4) {
307 tickSpacing.set(getDisplayPosition(tickDates.get(2)) - getDisplayPosition(tickDates.get(1)));
313 protected Interval getRange() {
314 return new Interval(getLowerBound(), getUpperBound());
318 protected String getTickMarkLabel(DateTime date) {
323 protected void layoutChildren() {
324 super.layoutChildren();
333 protected void setRange(Object range,
boolean animating) {
339 ReadOnlyDoubleProperty getTickSpacing() {
340 return tickSpacing.getReadOnlyProperty();
DateTimeFormatter getTickFormatter()
static RangeDivisionInfo getRangeDivisionInfo(Interval timeRange)
static DateTimeZone getJodaTimeZone()
TimeUnits getPeriodSize()