A
Timeline
that implements a "segmented" timeline with included,
excluded and exception segments.
A Timeline will present a series of values to be used for an axis. Each
Timeline must provide transformation methods between domain values and
timeline values.
A timeline can be used as parameter to a
DateAxis
to define the values that this axis
supports. This class implements a timeline formed by segments of equal
length (ex. days, hours, minutes) where some segments can be included in the
timeline and others excluded. Therefore timelines like "working days" or
"working hours" can be created where non-working days or non-working hours
respectively can be removed from the timeline, and therefore from the axis.
This creates a smooth plot with equal separation between all included
segments.
Because Timelines were created mainly for Date related axis, values are
represented as longs instead of doubles. In this case, the domain value is
just the number of milliseconds since January 1, 1970, 00:00:00 GMT as
defined by the getTime() method of
java.util.Date
.
In this class, a segment is defined as a unit of time of fixed length.
Examples of segments are: days, hours, minutes, etc. The size of a segment
is defined as the number of milliseconds in the segment. Some useful segment
sizes are defined as constants in this class: DAY_SEGMENT_SIZE,
HOUR_SEGMENT_SIZE, FIFTEEN_MINUTE_SEGMENT_SIZE and MINUTE_SEGMENT_SIZE.
Segments are group together to form a Segment Group. Each Segment Group will
contain a number of Segments included and a number of Segments excluded. This
Segment Group structure will repeat for the whole timeline.
For example, a working days SegmentedTimeline would be formed by a group of
7 daily segments, where there are 5 included (Monday through Friday) and 2
excluded (Saturday and Sunday) segments.
Following is a diagram that explains the major attributes that define a
segment. Each box is one segment and must be of fixed length (ms, second,
hour, day, etc).
start time
|
v
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
| | | | | |EE|EE| | | | | |EE|EE| | | | | |EE|EE|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
\____________/ \___/ \_/
\/ | |
included excluded segment
segments segments size
\_________ _______/
\/
segment group
Legend:
<space> = Included segment
EE = Excluded segments in the base timeline
In the example, the following segment attributes are presented:
- segment size: the size of each segment in ms.
- start time: the start of the first segment of the first segment group to
consider.
- included segments: the number of segments to include in the group.
- excluded segments: the number of segments to exclude in the group.
Exception Segments are allowed. These exception segments are defined as
segments that would have been in the included segments of the Segment Group,
but should be excluded for special reasons. In the previous working days
SegmentedTimeline example, holidays would be considered exceptions.
Additionally the
startTime
, or start of the first Segment of
the smallest segment group needs to be defined. This startTime could be
relative to January 1, 1970, 00:00:00 GMT or any other date. This creates a
point of reference to start counting Segment Groups. For example, for the
working days SegmentedTimeline, the
startTime
could be
00:00:00 GMT of the first Monday after January 1, 1970. In this class, the
constant FIRST_MONDAY_AFTER_1900 refers to a reference point of the first
Monday of the last century.
A SegmentedTimeline can include a baseTimeline. This combination of
timelines allows the creation of more complex timelines. For example, in
order to implement a SegmentedTimeline for an intraday stock trading
application, where the trading period is defined as 9:00 AM through 4:00 PM
Monday through Friday, two SegmentedTimelines are used. The first one (the
baseTimeline) would be a working day SegmentedTimeline (daily timeline
Monday through Friday). On top of this baseTimeline, a second one is defined
that maps the 9:00 AM to 4:00 PM period. Because the baseTimeline defines a
timeline of Monday through Friday, the resulting (combined) timeline will
expose the period 9:00 AM through 4:00 PM only on Monday through Friday,
and will remove all other intermediate intervals.
Two factory methods newMondayThroughFridayTimeline() and
newFifteenMinuteTimeline() are provided as examples to create special
SegmentedTimelines.
addBaseTimelineException
public void addBaseTimelineException(Date date)
Adds a segment relative to the baseTimeline as an exception. An
exception segment is defined as a segment to exclude from what would
otherwise be considered a valid segment of the timeline. An exception
segment can not be contained inside an already excluded segment. If so,
no action will occure (the proposed exception segment will be discarded).
The segment is identified by a domainValue into any part of the segment.
Therefore the segmentStart <= domainValue <= segmentEnd.
date
- date domain value to treat as a baseTimeline exception
addBaseTimelineException
public void addBaseTimelineException(long domainValue)
Adds a segment relative to the baseTimeline as an exception. Because a
base segment is normally larger than our segments, this may add one or
more segment ranges to the exception list.
An exception segment is defined as a segment
to exclude from what would otherwise be considered a valid segment of
the timeline. An exception segment can not be contained inside an
already excluded segment. If so, no action will occur (the proposed
exception segment will be discarded).
The segment is identified by a domainValue into any part of the
baseTimeline segment.
domainValue
- domain value to teat as a baseTimeline exception.
addBaseTimelineExclusions
public void addBaseTimelineExclusions(long fromBaseDomainValue,
long toBaseDomainValue)
Adds all excluded segments from the BaseTimeline as exceptions to our
timeline. This allows us to combine two timelines for more complex
calculations.
fromBaseDomainValue
- Start of the range where exclusions will be
extracted.toBaseDomainValue
- End of the range to process.
addException
public void addException(Date exceptionDate)
Adds a segment as an exception. An exception segment is defined as a
segment to exclude from what would otherwise be considered a valid
segment of the timeline. An exception segment can not be contained
inside an already excluded segment. If so, no action will occur (the
proposed exception segment will be discarded).
The segment is identified by a Date into any part of the segment.
exceptionDate
- Date into the segment to exclude.
addException
public void addException(long millisecond)
Adds a segment as an exception. An exception segment is defined as a
segment to exclude from what would otherwise be considered a valid
segment of the timeline. An exception segment can not be contained
inside an already excluded segment. If so, no action will occur (the
proposed exception segment will be discarded).
The segment is identified by a domainValue into any part of the segment.
Therefore the segmentStart <= domainValue <= segmentEnd.
millisecond
- domain value to treat as an exception
addException
public void addException(long fromDomainValue,
long toDomainValue)
Adds a segment range as an exception. An exception segment is defined as
a segment to exclude from what would otherwise be considered a valid
segment of the timeline. An exception segment can not be contained
inside an already excluded segment. If so, no action will occur (the
proposed exception segment will be discarded).
The segment range is identified by a domainValue that begins a valid
segment and ends with a domainValue that ends a valid segment.
Therefore the range will contain all segments whose segmentStart
<= domainValue and segmentEnd <= toDomainValue.
fromDomainValue
- start of domain range to treat as an exceptiontoDomainValue
- end of domain range to treat as an exception
addExceptions
public void addExceptions(List exceptionList)
Adds a list of dates as segment exceptions. Each exception segment is
defined as a segment to exclude from what would otherwise be considered
a valid segment of the timeline. An exception segment can not be
contained inside an already excluded segment. If so, no action will
occur (the proposed exception segment will be discarded).
The segment is identified by a Date into any part of the segment.
exceptionList
- List of Date objects that identify the segments to
exclude.
clone
public Object clone()
throws CloneNotSupportedException
Returns a clone of the timeline.
containsDomainRange
public boolean containsDomainRange(Date dateDomainValueStart,
Date dateDomainValueEnd)
Returns true
if a range of values are contained in the
timeline. This is implemented verifying that all segments are in the
range.
- containsDomainRange in interface Timeline
dateDomainValueStart
- start of the range to verifydateDomainValueEnd
- end of the range to verify
true
if the range is contained in the timeline
containsDomainRange
public boolean containsDomainRange(long domainValueStart,
long domainValueEnd)
Returns true
if a range of values are contained in the
timeline. This is implemented verifying that all segments are in the
range.
- containsDomainRange in interface Timeline
domainValueStart
- start of the range to verifydomainValueEnd
- end of the range to verify
true
if the range is contained in the timeline
containsDomainValue
public boolean containsDomainValue(long millisecond)
Returns true
if a value is contained in the timeline.
- containsDomainValue in interface Timeline
millisecond
- the value to verify.
true
if value is contained in the timeline.
equals
public boolean equals(Object o)
Returns true if we are equal to the parameter
o
- Object to verify with us
getAdjustForDaylightSaving
public boolean getAdjustForDaylightSaving()
Returns the flag that controls whether or not the daylight saving
adjustment is applied.
getDate
public Date getDate(long value)
Converts a millisecond value into a Date
object.
value
- the millisecond value.
getExceptionSegmentCount
public long getExceptionSegmentCount(long fromMillisecond,
long toMillisecond)
Returns the number of exception segments wholly contained in the
(fromDomainValue, toDomainValue) interval.
fromMillisecond
- the beginning of the interval.toMillisecond
- the end of the interval.
- Number of exception segments contained in the interval.
getExceptionSegments
public List getExceptionSegments()
Returns a list of all the exception segments. This list is not
modifiable.
getGroupSegmentCount
public int getGroupSegmentCount()
Returns the number of segments in a segment group. This will be equal to
segments included plus segments excluded.
getSegment
public SegmentedTimeline.Segment getSegment(Date date)
Returns a segment that contains a date. For accurate calculations,
the calendar should use TIME_ZONE for its calculation (or any other
similar time zone).
If the date is not contained in the timeline (because it is not
contained in the baseTimeline), a Segment that contains
date + segmentSize*m
will be returned for the smallest
m
possible.
date
- date into the segment
- A Segment that contains date, or the next possible Segment.
getSegment
public SegmentedTimeline.Segment getSegment(long millisecond)
Returns a segment that contains a domainValue. If the domainValue is
not contained in the timeline (because it is not contained in the
baseTimeline), a Segment that contains
index + segmentSize*m
will be returned for the smallest
m
possible.
millisecond
- index into the segment
- A Segment that contains index, or the next possible Segment.
getSegmentSize
public long getSegmentSize()
Returns the size of one segment in ms.
- The segment size in milliseconds.
getSegmentsExcluded
public int getSegmentsExcluded()
Returns the number of segments excluded per segment group.
- The number of segments excluded.
getSegmentsExcludedSize
public long getSegmentsExcludedSize()
Returns the size in milliseconds of the segments excluded per segment
group.
- The size in milliseconds.
getSegmentsGroupSize
public long getSegmentsGroupSize()
Returns the size in milliseconds of a segment group. This will be equal
to size of the segments included plus the size of the segments excluded.
- The segment group size in milliseconds.
getSegmentsIncluded
public int getSegmentsIncluded()
Returns the number of segments included per segment group.
getSegmentsIncludedSize
public long getSegmentsIncludedSize()
Returns the size in ms of the segments included per segment group.
- The segment size in milliseconds.
getStartTime
public long getStartTime()
Returns the start time for the timeline. This is the beginning of
segment zero.
getTime
public long getTime(Date date)
Special method that handles conversion between the Default Time Zone and
a UTC time zone with no DST. This is needed so all days have the same
size. This method is the prefered way of converting a Data into
milliseconds for usage in this class.
date
- Date to convert to long.
getTimeFromLong
public long getTimeFromLong(long date)
Converts a date/time value to take account of daylight savings time.
hashCode
public int hashCode()
Returns a hash code for this object.
newFifteenMinuteTimeline
public static SegmentedTimeline newFifteenMinuteTimeline()
Factory method to create a 15-min, 9:00 AM thought 4:00 PM, Monday
through Friday SegmentedTimeline.
This timeline uses a segmentSize of FIFTEEN_MIN_SEGMENT_SIZE. The
segment group is defined as 28 included segments (9:00 AM through
4:00 PM) and 68 excluded segments (4:00 PM through 9:00 AM the next day).
In order to exclude Saturdays and Sundays it uses a baseTimeline that
only includes Monday through Friday days.
The
startTime
of the resulting timeline will be 9:00 AM
after the startTime of the baseTimeline. This will correspond to 9:00 AM
of the first Monday after 1/1/1900.
- A fully initialized SegmentedTimeline.
newMondayThroughFridayTimeline
public static SegmentedTimeline newMondayThroughFridayTimeline()
Factory method to create a Monday through Friday SegmentedTimeline.
The
startTime
of the resulting timeline will be midnight
of the first Monday after 1/1/1900.
- A fully initialized SegmentedTimeline.
setAdjustForDaylightSaving
public void setAdjustForDaylightSaving(boolean adjust)
Sets the flag that controls whether or not the daylight saving adjustment
is applied.
setExceptionSegments
public void setExceptionSegments(List exceptionSegments)
Sets the exception segments list.
exceptionSegments
- the exception segments.
setStartTime
public void setStartTime(long millisecond)
Sets the start time for the timeline. This is the beginning of segment
zero.
millisecond
- the start time (encoded as in java.util.Date).
toMillisecond
public long toMillisecond(long timelineValue)
Translates a value relative to the timeline into a millisecond.
- toMillisecond in interface Timeline
timelineValue
- the timeline value (in milliseconds).
- The domain value (in milliseconds).
toTimelineValue
public long toTimelineValue(Date date)
Translates a date into a value relative to the segmented timeline. The
values relative to the segmented timeline are all consecutives starting
at zero at the startTime.
- toTimelineValue in interface Timeline
date
- date relative to the domain.
- The timeline value (in milliseconds).
toTimelineValue
public long toTimelineValue(long millisecond)
Translates a value relative to the domain value (all Dates) into a value
relative to the segmented timeline. The values relative to the segmented
timeline are all consecutives starting at zero at the startTime.
- toTimelineValue in interface Timeline
millisecond
- the millisecond (as encoded by java.util.Date).