FlexGanttFX Developer Manual : 3.6.1 Dateline Model

Introduction

The dateline model provides the dateline control with various pieces of information so that it can layout itself correctly.
  • Resolutions - a resolution defines which temporal unit to show (e.g. hours) and how to format it. It also contains the information whether it can be shown in a top, bottom, or middle scale. Each model usually defines a long list of such resolutions. The more resolutions are defined the more flexible the dateline control becomes when it comes to zooming in and out.
  • Time Zones - The dateline control allows the user to switch between different time zones. The model defines which zones are available.
  • Scale Count - The dateline control is composed of a set of dateline scales (top, bottom, several middle scales). The model can be used to define the currently visible, the minimum and the maximum number of scales that the user can choose to see.
  • Temporal Units - The dateline control calls back onto the model to lookup the "next" temporal unit after it has either failed or succeeded to create a scale for the current unit.


The dateline model is a typed model. FlexGanttFX ships with two specializations: ChronoUnitDatelineModel and SimpleUnitDatelineModel.

Chrono Unit Dateline Model

The ChronoUnitDatelineModel class is a specialization for the ChronoUnit temporal that is part of JDK 8. It requires scale resolutions of type ChronoUnitResolution. The following listing is the implementation of this model and illustrates how to define and add resolutions and also how the resolution is used to go from one temporal unit to the next.

ChronoUnitDatelineModel
/**
 * Copyright (C) 2014 - 2016 Dirk Lemmermann Software & Consulting (dlsc.com)
 * <p>
 * This file is part of FlexGanttFX.
 */
package com.flexganttfx.model.dateline;

import java.time.temporal.ChronoUnit;

import static com.flexganttfx.model.dateline.Resolution.Position.*;
import static java.time.temporal.ChronoUnit.*;

/**
 * The chrono unit dateline model is a specialization of the dateline model that works
 * in combination with the {@link ChronoUnit}. The chrono unit basically represents standard
 * calendar units ranging from milliseconds to thousands of years.
 *
 * @since 1.0
 */
public final class ChronoUnitDatelineModel extends DatelineModel<ChronoUnit> {

    /**
     * Constructs a new dateline model with a long list of predefined
     * resolutions of type {@link ChronoUnitResolution}.
     *
     * @since 1.0
     */
    public ChronoUnitDatelineModel() {
        addResolution(new ChronoUnitResolution(MILLIS, "EEEE, dd. MMMM yyyy, HH:mm:ss:SSS", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MILLIS, "EEEE, dd.MM.yy, HH:mm:ss:SSS", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MILLIS, "E, dd.MM.yy, HH:mm:ss:SSS", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MILLIS, "dd.MM.yy, HH:mm:ss:SSS", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MILLIS, "dd.MM, HH:mm:ss:SSS", 1, TOP));
        addResolution(new ChronoUnitResolution(MILLIS, "SSS", 1, BOTTOM));
        addResolution(new ChronoUnitResolution(MILLIS, "SSS", 5, BOTTOM));
        addResolution(new ChronoUnitResolution(MILLIS, "SSS", 10, BOTTOM));
        addResolution(new ChronoUnitResolution(MILLIS, "SSS", 15, BOTTOM));

        addResolution(new ChronoUnitResolution(SECONDS, "EEEE, dd. MMMM yyyy, HH:mm:ss", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(SECONDS, "EEEE, dd.MM.yy, HH:mm:ss", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(SECONDS, "E, dd.MM.yy, HH:mm:ss", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(SECONDS, "dd.MM.yy, HH:mm:ss", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(SECONDS, "dd.MM, HH:mm:ss", 1, MIDDLE));
        addResolution(new ChronoUnitResolution(SECONDS, "HH:mm:ss", 1, MIDDLE));
        addResolution(new ChronoUnitResolution(SECONDS, "ss", 1, BOTTOM));
        addResolution(new ChronoUnitResolution(SECONDS, "ss", 5, BOTTOM));
        addResolution(new ChronoUnitResolution(SECONDS, "ss", 10, BOTTOM));
        addResolution(new ChronoUnitResolution(SECONDS, "ss", 15, BOTTOM));

        addResolution(new ChronoUnitResolution(MINUTES, "EEEE, dd. MMMM yyyy, HH:mm", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MINUTES, "EEEE, dd.MM.yy, HH:mm", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MINUTES, "E, dd.MM.yy, HH:mm", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MINUTES, "dd.MM.yy, HH:mm", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MINUTES, "dd.MM, HH:mm", 1, TOP));
        addResolution(new ChronoUnitResolution(MINUTES, "HH:mm", 1, MIDDLE));
        addResolution(new ChronoUnitResolution(MINUTES, "mm", 1, BOTTOM));
        addResolution(new ChronoUnitResolution(MINUTES, "mm", 5, BOTTOM));
        addResolution(new ChronoUnitResolution(MINUTES, "mm", 10, BOTTOM));
        addResolution(new ChronoUnitResolution(MINUTES, "mm", 15, BOTTOM));

        addResolution(new ChronoUnitResolution(HOURS, "EEEE, dd. MMMM yyyy, HH:mm", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(HOURS, "EEEE, dd.MM.yy, HH:mm", 1, TOP, BOTTOM, ONLY));
        addResolution(new ChronoUnitResolution(HOURS, "E, dd.MM.yy, HH:mm", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(HOURS, "dd.MM.yy, HH:mm", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(HOURS, "dd.MM, HH:mm", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(HOURS, "H:mm", 1, MIDDLE, BOTTOM));
        addResolution(new ChronoUnitResolution(HOURS, "H:mm", 3, MIDDLE, BOTTOM));
        addResolution(new ChronoUnitResolution(HOURS, "H:mm", 6, MIDDLE, BOTTOM));

        addResolution(new ChronoUnitResolution(DAYS, "EEEE d. MMMM yyyy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(DAYS, "EEEE d. MMMM yy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(DAYS, "E, d. MMMM yy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(DAYS, "E, d. MMMM", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(DAYS, "E, dd.MM.yy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(DAYS, "EEEE dd", 1, MIDDLE, BOTTOM));
        addResolution(new ChronoUnitResolution(DAYS, "E dd", 1, MIDDLE, BOTTOM));
        addResolution(new ChronoUnitResolution(DAYS, "dd.MM", 1, MIDDLE, BOTTOM));
        addResolution(new ChronoUnitResolution(DAYS, "dd", 1, BOTTOM));

        addResolution(new ChronoUnitResolution(WEEKS, "'W' w, EEEE d. MMMM yy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(WEEKS, "'W' w, d. MMMM yy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(WEEKS, "'W' w, d. MMMM", 1));
        addResolution(new ChronoUnitResolution(WEEKS, "'W' w, E, dd.MM.yy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(WEEKS, "'W' w, dd.MM.yy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(WEEKS, "'W' w, dd.MM", 1, BOTTOM));
        addResolution(new ChronoUnitResolution(WEEKS, "'W' w", 1, MIDDLE, BOTTOM));

        addResolution(new ChronoUnitResolution(MONTHS, "MMMM yyyy", 1, TOP, ONLY));
        addResolution(new ChronoUnitResolution(MONTHS, "MMMM", 1, MIDDLE, BOTTOM));
        addResolution(new ChronoUnitResolution(MONTHS, "MMM", 1, MIDDLE, BOTTOM));
        addResolution(new ChronoUnitResolution(MONTHS, "M", 1, MIDDLE, BOTTOM));

        addResolution(new ChronoUnitResolution(YEARS, "yyyy", 1));
        addResolution(new ChronoUnitResolution(DECADES, "yyyy", 1));
        addResolution(new ChronoUnitResolution(CENTURIES, "yyyy", 1));
        addResolution(new ChronoUnitResolution(MILLENNIA, "yyyy", 1));
    }

    @Override
    public final ChronoUnit nextTemporalUnit(ChronoUnit unit) {
        switch (unit) {
            case NANOS:
                return MICROS;
            case MICROS:
                return MILLIS;
            case MILLIS:
                return SECONDS;
            case SECONDS:
                return MINUTES;
            case MINUTES:
                return HOURS;
            case HOURS:
                return DAYS;
            case DAYS:
                return WEEKS;
            case WEEKS:
                return MONTHS;
            case MONTHS:
                return YEARS;
            case YEARS:
                return DECADES;
            case DECADES:
                return CENTURIES;
            case CENTURIES:
                return MILLENNIA;
            default:
            /*
			 * We are ignoring HALF DAYS.
			 */
                return null;
        }
    }
}

Simple Unit Dateline Model

The SimpleUnitDatelineModel class is a specialization for the SimpleUnit temporal which ships with FlexGanttFX. It requires scale resolutions of type SimpleUnitResolution. The implementation of this model class below shows why the unit is called "simple".

SimpleUnitDatelineModel
 /**
 * Copyright (C) 2014 Dirk Lemmermann Software & Consulting (dlsc.com) 
 * 
 * This file is part of FlexGanttFX.
 */
package com.flexganttfx.model.dateline;


import com.flexganttfx.model.util.SimpleUnit;

public final class SimpleUnitDatelineModel extends DatelineModel<SimpleUnit> {

	public SimpleUnitDatelineModel() {
		for (SimpleUnit unit : SimpleUnit.values()) {
			addResolution(new SimpleUnitResolution(unit, "", 1));
		}
	}

	@Override
	public SimpleUnit nextTemporalUnit(SimpleUnit unit) {
		int ordinal = unit.ordinal();
		if (ordinal < SimpleUnit.values().length - 1) {
			return SimpleUnit.values()[ordinal + 1];
		}
		return null;
	}
}

Timezones

The dateline model manages a list of zone IDs, which is used by the UI to create menu items for each ID. This way the user can easily toggle between them. The default list is set up in the DatelineModel class like this:

DatelineModel
/**
 * Constructs a new model and populates the list of available zone IDs.
 */
protected DatelineModel() {
	addZoneId("Europe/Berlin");
	addZoneId("America/New_York");
	addZoneId("Australia/Darwin");
	addZoneId("Australia/Sydney");
	addZoneId("America/Argentina/Buenos_Aires");
	addZoneId("Africa/Cairo");
	addZoneId("America/Anchorage");
	addZoneId("America/Sao_Paulo");
	addZoneId("Asia/Dhaka");
	addZoneId("Africa/Harare");
	addZoneId("America/St_Johns");
	addZoneId("America/Chicago");
	addZoneId("Asia/Shanghai");
	addZoneId("Africa/Addis_Ababa")
	addZoneId("Europe/Paris");
	addZoneId("America/Indiana/Indianapolis");
	addZoneId("Asia/Kolkata");
	addZoneId("Asia/Tokyo");
	addZoneId("Pacific/Apia");
	addZoneId("Asia/Yerevan");
	addZoneId("Pacific/Auckland");
	addZoneId("Asia/Karachi");
	addZoneId("America/Phoenix");
	addZoneId("America/Puerto_Rico");
	addZoneId("America/Los_Angeles");
	addZoneId("Pacific/Guadalcanal");
	addZoneId("Asia/Ho_Chi_Minh");
}

Please note that the currently used timezone is managed by the Dateline control, not the model.