Example usage for org.jfree.data.time TimeSeriesCollection TimeSeriesCollection

List of usage examples for org.jfree.data.time TimeSeriesCollection TimeSeriesCollection

Introduction

In this page you can find the example usage for org.jfree.data.time TimeSeriesCollection TimeSeriesCollection.

Prototype

public TimeSeriesCollection() 

Source Link

Document

Constructs an empty dataset, tied to the default timezone.

Usage

From source file:mekhq.gui.FinancesTab.java

private XYDataset setupFinanceDataset() {
    TimeSeries s1 = new TimeSeries("C-Bills"); // NOI18N
    ArrayList<Transaction> transactions = getCampaign().getFinances().getAllTransactions();
    Calendar cal = Calendar.getInstance();

    long balance = 0;
    for (int i = 0; i < transactions.size(); i++) {
        balance += transactions.get(i).getAmount();
        cal.setTime(transactions.get(i).getDate());
        // since there may be more than one entry per day and the dataset for the graph can only have one entry per day
        // we use addOrUpdate() which assumes transactions are in sequential order by date so we always have the most
        // up-to-date entry for each day
        s1.addOrUpdate(new Day(cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH) + 1, // Gregorian and Julian calendars start at 0: https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#MONTH
                cal.get(Calendar.YEAR)), balance);
    }//from   w ww .j  av  a  2s.com

    TimeSeriesCollection dataset = new TimeSeriesCollection();
    dataset.addSeries(s1);

    return dataset;
}

From source file:ec.ui.view.RevisionSaSeriesView.java

private void showResults() {
    if (history_ == null) {
        return;//from  w w w.  ja v a  2s .c  o m
    }

    lastIndexSelected = -1;

    final TimeSeriesCollection chartSeries = new TimeSeriesCollection();
    sRef = history_.referenceSeries(info_);
    TsPeriodSelector selector = new TsPeriodSelector();
    int n = sRef.getDomain().getLength();
    int freq = sRef.getDomain().getFrequency().intValue();
    int l = years_ * freq + 1;
    int n0 = n - l;
    if (n0 < minyears_ * freq) {
        n0 = minyears_ * freq;
    }
    if (n0 < n) {
        firstPeriod = sRef.getDomain().get(n0);
        selector.from(sRef.getDomain().get(n0).firstday());
    } else {
        firstPeriod = sRef.getStart();
    }
    addSeries(chartSeries, sRef.select(selector));

    final TimeSeriesCollection startSeries = new TimeSeriesCollection();
    TsDomain dom = sRef.getDomain();
    for (int i = n0; i < n - 1; ++i) {
        addStart(startSeries, info_, dom.get(i));
    }

    if (startSeries.getSeriesCount() == 0 || chartSeries.getSeriesCount() == 0) {
        chartpanel_.setChart(mainChart);
        return;
    }

    setRange(chartSeries, startSeries);

    XYPlot plot = mainChart.getXYPlot();
    plot.setDataset(S_INDEX, chartSeries);

    plot.setDataset(REV_INDEX, startSeries);

    for (int i = 0; i < startSeries.getSeriesCount(); i++) {
        revRenderer.setSeriesShape(i, new Ellipse2D.Double(-3, -3, 6, 6));
        revRenderer.setSeriesShapesFilled(i, false);
        revRenderer.setSeriesPaint(i, themeSupport.getLineColor(ColorScheme.KnownColor.BLUE));
    }
    plot.setRenderer(REV_INDEX, revRenderer);

    setRange(chartSeries, startSeries);
    configureAxis(plot);

    plot.mapDatasetToDomainAxis(S_INDEX, REV_INDEX);
    plot.mapDatasetToRangeAxis(S_INDEX, REV_INDEX);
    plot.mapDatasetToDomainAxis(REV_INDEX, REV_INDEX);
    plot.mapDatasetToRangeAxis(REV_INDEX, REV_INDEX);

    chartpanel_.setChart(mainChart);

    showRevisionsDocument(revisions());
}

From source file:net.brewspberry.front.JFreeGraphServlet.java

/**
 * This method creates a TimeSeriesCollection from raw String values
 * /*from  www.j  a  v a  2  s.  c  o m*/
 * @param data
 * @return
 * @throws NumberFormatException
 * @throws ParseException
 */
public TimeSeriesCollection createDataset(List<String[]> data, boolean timeLimited, boolean fromDB)
        throws NumberFormatException, ParseException {

    TimeSeriesCollection dataSet = new TimeSeriesCollection();

    int compteur = data.size();
    List<TimeSeries> serie = new ArrayList<TimeSeries>();

    logger.fine("Compteur " + compteur + " length :" + data.get(0).length);

    // On cree autant de series qu'il y a de sondes
    for (int k = 0; k <= (data.get(0).length - 5) / 2; k++) {
        serie.add(new TimeSeries("PROBE" + k));
        logger.fine("Added timeSeries PROBE" + k);
    }

    /*
     * For each line like [2015-07-21 12:34:56, 12345, 54321]
     */
    for (int i = 0; i < compteur; i++) {

        /*
         * for each temperature value
         */
        int increment;
        if (fromDB) {
            increment = 1;
        } else {
            increment = 2;
        }
        for (int j = 5; j < data.get(i).length; j += increment) {

            Date dataDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(data.get(i)[0]);

            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(dataDate);
            Calendar cal2 = Calendar.getInstance();
            cal2.add(Calendar.MINUTE, graphHorizontalTimeLengthInMinutes);
            logger.fine("Array size : " + data.get(i).length + " & compteur=" + j);

            if (timeLimited) {
                if (cal1.after(cal2)) {
                    if (data.get(i)[j] != null) {
                        // Adds [time, temperature] to the corresponding (i)
                        // serie

                        logger.fine("Adding temperature" + data.get(i)[j] + " to serie nbr" + (j - 5) / 2);
                        serie.get((j - 5) / 2).addOrUpdate(new Second(dataDate),
                                Double.parseDouble(data.get(i)[j]));
                    }
                }
            } else {
                if (data.get(i)[j] != null) {

                    serie.get((j - 5)).addOrUpdate(new Second(dataDate), Double.parseDouble(data.get(i)[j]));
                }
            }
        }
    }

    // Adds each serie to the dataset
    for (int l = 0; l < serie.size(); l++) {
        logger.fine("serie size : " + serie.get(l).getItemCount());

        dataSet.addSeries(serie.get(l));
    }

    logger.fine("dataSet size : " + dataSet.getSeriesCount());

    return dataSet;

}

From source file:com.jbombardier.reports.OldReportGenerator.java

private TimeSeriesCollection extractTimeSeriesCollection(List<Chunk> timeOrderedResults, String transactionName,
        Statistic statistic) {/*  ww  w .  j  av  a  2  s  .  c  o  m*/
    TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
    TimeSeries timeSeries = extractTimeSeries(timeOrderedResults, transactionName, statistic);

    timeSeriesCollection.addSeries(timeSeries);
    return timeSeriesCollection;
}

From source file:Data.java

/**
 * Creates a dataset, consisting of two series of monthly data.
 *
 * @return The dataset./*from w  ww  .  j  a  v  a  2  s . c o  m*/
 * @throws ClassNotFoundException 
 */
private static XYDataset createDataset(Statement stmt) throws ClassNotFoundException {

    TimeSeries s1 = new TimeSeries("Humidit");
    TimeSeries s2 = new TimeSeries("Temprature");
    ResultSet rs = null;

    try {
        String sqlRequest = "SELECT * FROM `t_temphum`";
        rs = stmt.executeQuery(sqlRequest);
        Double hum;
        Double temp;
        Timestamp date;

        while (rs.next()) {
            hum = rs.getDouble("tmp_humidity");
            temp = rs.getDouble("tmp_temperature");
            date = rs.getTimestamp("tmp_date");

            if (tempUnit == "F") {
                temp = celsiusToFahrenheit(temp.toString());
            }

            if (date != null) {
                s1.add(new Second(date), hum);
                s2.add(new Second(date), temp);
            } else {
                JOptionPane.showMessageDialog(panelPrincipal, "Il manque une date dans la dase de donne",
                        "Date null", JOptionPane.WARNING_MESSAGE);
            }
        }

        rs.close();
    } catch (SQLException e) {
        String exception = e.toString();

        if (e.getErrorCode() == 0) {
            JOptionPane.showMessageDialog(panelPrincipal,
                    "Le serveur met trop de temps  rpondre ! Veuillez rssayer plus tard ou contacter un administrateur",
                    "Connection timed out", JOptionPane.ERROR_MESSAGE);
        } else {
            JOptionPane.showMessageDialog(panelPrincipal, "Voici l'exception : " + exception,
                    "Titre : exception", JOptionPane.ERROR_MESSAGE);
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } catch (Exception e) {
        String exception = e.toString();
        JOptionPane.showMessageDialog(panelPrincipal, "Voici l'exception : " + exception, "Titre : exception",
                JOptionPane.ERROR_MESSAGE);
        e.printStackTrace();
    }

    // ******************************************************************
    //  More than 150 demo applications are included with the JFreeChart
    //  Developer Guide...for more information, see:
    //
    //  >   http://www.object-refinery.com/jfreechart/guide.html
    //
    // ******************************************************************

    TimeSeriesCollection dataset = new TimeSeriesCollection();
    dataset.addSeries(s1);
    dataset.addSeries(s2);

    return dataset;

}

From source file:org.mwc.debrief.track_shift.views.StackedDotHelper.java

/**
 * ok, our track has been dragged, calculate the new series of offsets
 * // w  w w  .  j a va 2  s . c  o m
 * @param linePlot
 * @param dotPlot
 * @param onlyVis
 * @param showCourse
 * @param b
 * @param holder
 * @param logger
 * 
 * @param currentOffset
 *          how far the current track has been dragged
 */
public void updateBearingData(final XYPlot dotPlot, final XYPlot linePlot, final TrackDataProvider tracks,
        final boolean onlyVis, final boolean showCourse, final boolean flipAxes, final Composite holder,
        final ErrorLogger logger, final boolean updateDoublets) {
    // do we even have a primary track
    if (_primaryTrack == null)
        return;

    // ok, find the track wrappers
    if (_secondaryTrack == null)
        initialise(tracks, false, onlyVis, holder, logger, "Bearing", true, false);

    // did it work?
    // if (_secondaryTrack == null)
    // return;

    // ok - the tracks have moved. better update the doublets
    if (updateDoublets)
        updateDoublets(onlyVis, true, false);

    // aah - but what if we've ditched our doublets?
    if ((_primaryDoublets == null) || (_primaryDoublets.size() == 0)) {
        // better clear the plot
        dotPlot.setDataset(null);
        linePlot.setDataset(null);
        return;
    }

    // create the collection of series
    final TimeSeriesCollection errorSeries = new TimeSeriesCollection();
    final TimeSeriesCollection actualSeries = new TimeSeriesCollection();

    // produce a dataset for each track
    final TimeSeries errorValues = new TimeSeries(_primaryTrack.getName());

    final TimeSeries measuredValues = new TimeSeries("Measured");
    final TimeSeries ambigValues = new TimeSeries("Ambiguous Bearing");
    final TimeSeries calculatedValues = new TimeSeries("Calculated");

    final TimeSeries osCourseValues = new TimeSeries("Course");

    // ok, run through the points on the primary track
    final Iterator<Doublet> iter = _primaryDoublets.iterator();
    while (iter.hasNext()) {
        final Doublet thisD = iter.next();

        try {
            // obvious stuff first (stuff that doesn't need the tgt data)
            final Color thisColor = thisD.getColor();
            double measuredBearing = thisD.getMeasuredBearing();
            double ambigBearing = thisD.getAmbiguousMeasuredBearing();
            final HiResDate currentTime = thisD.getDTG();
            final FixedMillisecond thisMilli = new FixedMillisecond(currentTime.getDate().getTime());

            // put the measured bearing back in the positive domain
            if (measuredBearing < 0)
                measuredBearing += 360d;

            // stop, stop, stop - do we wish to plot bearings in the +/- 180 domain?
            if (flipAxes)
                if (measuredBearing > 180)
                    measuredBearing -= 360;

            final ColouredDataItem mBearing = new ColouredDataItem(thisMilli, measuredBearing, thisColor, false,
                    null);

            // and add them to the series
            measuredValues.add(mBearing);

            if (ambigBearing != Doublet.INVALID_BASE_FREQUENCY) {
                if (flipAxes)
                    if (ambigBearing > 180)
                        ambigBearing -= 360;

                final ColouredDataItem amBearing = new ColouredDataItem(thisMilli, ambigBearing, thisColor,
                        false, null);
                ambigValues.add(amBearing);
            }

            // do we have target data?
            if (thisD.getTarget() != null) {
                double calculatedBearing = thisD.getCalculatedBearing(null, null);
                final Color calcColor = thisD.getTarget().getColor();
                final double thisError = thisD.calculateBearingError(measuredBearing, calculatedBearing);
                final ColouredDataItem newError = new ColouredDataItem(thisMilli, thisError, thisColor, false,
                        null);

                if (flipAxes)
                    if (calculatedBearing > 180)
                        calculatedBearing -= 360;

                final ColouredDataItem cBearing = new ColouredDataItem(thisMilli, calculatedBearing, calcColor,
                        true, null);

                errorValues.add(newError);
                calculatedValues.add(cBearing);
            }

        } catch (final SeriesException e) {
            CorePlugin.logError(Status.INFO, "some kind of trip whilst updating bearing plot", e);
        }

    }

    // right, we do course in a special way, since it isn't dependent on the
    // target track. Do course here.
    HiResDate startDTG, endDTG;

    // just double-check we've still got our primary doublets
    if (_primaryDoublets == null) {
        CorePlugin.logError(Status.WARNING, "FOR SOME REASON PRIMARY DOUBLETS IS NULL - INVESTIGATE", null);
        return;
    }

    if (_primaryDoublets.size() == 0) {
        CorePlugin.logError(Status.WARNING, "FOR SOME REASON PRIMARY DOUBLETS IS ZERO LENGTH - INVESTIGATE",
                null);
        return;
    }

    startDTG = _primaryDoublets.first().getDTG();
    endDTG = _primaryDoublets.last().getDTG();

    if (startDTG.greaterThan(endDTG)) {
        System.err.println("in the wrong order, start:" + startDTG + " end:" + endDTG);
        return;
    }

    final Collection<Editable> hostFixes = _primaryTrack.getItemsBetween(startDTG, endDTG);

    // loop through th items
    for (final Iterator<Editable> iterator = hostFixes.iterator(); iterator.hasNext();) {
        final Editable editable = (Editable) iterator.next();
        final FixWrapper fw = (FixWrapper) editable;
        final FixedMillisecond thisMilli = new FixedMillisecond(fw.getDateTimeGroup().getDate().getTime());
        double ownshipCourse = MWC.Algorithms.Conversions.Rads2Degs(fw.getCourse());

        // stop, stop, stop - do we wish to plot bearings in the +/- 180 domain?
        if (flipAxes)
            if (ownshipCourse > 180)
                ownshipCourse -= 360;

        final ColouredDataItem crseBearing = new ColouredDataItem(thisMilli, ownshipCourse, fw.getColor(), true,
                null);
        osCourseValues.add(crseBearing);
    }

    // ok, add these new series

    if (showCourse) {
        actualSeries.addSeries(osCourseValues);
    }

    if (errorValues.getItemCount() > 0)
        errorSeries.addSeries(errorValues);

    actualSeries.addSeries(measuredValues);

    if (ambigValues.getItemCount() > 0)
        actualSeries.addSeries(ambigValues);

    if (calculatedValues.getItemCount() > 0)
        actualSeries.addSeries(calculatedValues);

    dotPlot.setDataset(errorSeries);
    linePlot.setDataset(actualSeries);
}

From source file:compecon.dashboard.panel.IndustriesPanel.java

protected ChartPanel createProductionFunctionMechanicsPanel(Currency currency, GoodType outputGoodType) {
    TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();

    timeSeriesCollection.addSeries(ApplicationContext.getInstance().getModelRegistry()
            .getNationalEconomyModel(currency).getIndustryModel(outputGoodType).budgetModel.getTimeSeries());
    for (ConvexProductionFunctionTerminationCause terminationCause : ConvexProductionFunctionTerminationCause
            .values()) {//from  w  w w.  j a va  2s  .com
        timeSeriesCollection
                .addSeries(ApplicationContext.getInstance().getModelRegistry().getNationalEconomyModel(currency)
                        .getIndustryModel(outputGoodType).convexProductionFunctionTerminationCauseModels
                                .get(terminationCause).getTimeSeries());
    }

    // budget is correct here, as the chart illustrates budget
    // emergence from these causes
    JFreeChart chart = ChartFactory.createTimeSeriesChart(
            outputGoodType.toString() + " Production Function Mechanics", "Date", "Budget Spent",
            (XYDataset) timeSeriesCollection, true, true, false);
    configureChart(chart);
    return new ChartPanel(chart);
}

From source file:com.android.ddmuilib.log.event.DisplayGraph.java

/**
* Returns a {@link TimeSeriesCollection} for a specific {@link com.android.ddmlib.log.EventValueDescription.ValueType}.
* If the data set is not yet created, it is first allocated and set up into the
* {@link org.jfree.chart.JFreeChart} object.
* @param type the {@link com.android.ddmlib.log.EventValueDescription.ValueType} of the data set.
* @param accumulateValues/*from   w ww  .j  a  va 2s. co m*/
*/
private TimeSeriesCollection getValueDataset(EventValueDescription.ValueType type, boolean accumulateValues) {
    TimeSeriesCollection dataset = mValueTypeDataSetMap.get(type);
    if (dataset == null) {
        // create the data set and store it in the map
        dataset = new TimeSeriesCollection();
        mValueTypeDataSetMap.put(type, dataset);

        // create the renderer and configure it depending on the ValueType
        AbstractXYItemRenderer renderer;
        if (type == EventValueDescription.ValueType.PERCENT && accumulateValues) {
            renderer = new XYAreaRenderer();
        } else {
            XYLineAndShapeRenderer r = new XYLineAndShapeRenderer();
            r.setBaseShapesVisible(type != EventValueDescription.ValueType.PERCENT);

            renderer = r;
        }

        // set both the dataset and the renderer in the plot object.
        XYPlot xyPlot = mChart.getXYPlot();
        xyPlot.setDataset(mDataSetCount, dataset);
        xyPlot.setRenderer(mDataSetCount, renderer);

        // put a new axis label, and configure it.
        NumberAxis axis = new NumberAxis(type.toString());

        if (type == EventValueDescription.ValueType.PERCENT) {
            // force percent range to be (0,100) fixed.
            axis.setAutoRange(false);
            axis.setRange(0., 100.);
        }

        // for the index, we ignore the occurrence dataset
        int count = mDataSetCount;
        if (mOccurrenceDataSet != null) {
            count--;
        }

        xyPlot.setRangeAxis(count, axis);
        if ((count % 2) == 0) {
            xyPlot.setRangeAxisLocation(count, AxisLocation.BOTTOM_OR_LEFT);
        } else {
            xyPlot.setRangeAxisLocation(count, AxisLocation.TOP_OR_RIGHT);
        }

        // now we link the dataset and the axis
        xyPlot.mapDatasetToRangeAxis(mDataSetCount, count);

        mDataSetCount++;
    }

    return dataset;
}

From source file:org.streamspinner.harmonica.application.CQGraphTerminal.java

public void dataDistributed(CQRowSetEvent e) {
    try {/*from   w  w w  .  j a v a2s  . c om*/
        base = 0;
        CQRowSet rs = (CQRowSet) e.getSource();

        CQRowSetMetaData meta = rs.getMetaData();

        if (chart == null) {
            c = new TimeSeriesCollection();
            boolean first_loop = true;
            rs.beforeFirst();
            String[] t_obj = new String[meta.getColumnCount()];
            String[] t_val = new String[meta.getColumnCount()];

            while (rs.next()) {
                for (int i = 1; i <= meta.getColumnCount(); i++) {
                    double val = 0;

                    t_obj[i - 1] = meta.getColumnName(i);

                    if (meta.getColumnTypeName(i).equals(DataTypes.STRING)) {
                        t_val[i - 1] = rs.getString(i);
                        continue;
                    }
                    if (meta.getColumnTypeName(i).equals(DataTypes.OBJECT)) {
                        t_val[i - 1] = rs.getObject(i).toString();
                        continue;
                    }
                    if (meta.getColumnTypeName(i).equals(DataTypes.LONG)) {
                        long lval = rs.getLong(i);
                        val = (double) lval;
                        t_val[i - 1] = String.valueOf(lval);
                    } else if (meta.getColumnTypeName(i).equals(DataTypes.DOUBLE)) {
                        val = rs.getDouble(i);
                        t_val[i - 1] = String.valueOf(val);
                    } else {
                        t_val[i - 1] = rs.getString(i);
                        continue;
                    }

                    if (val < 1000000 || Double.isNaN(val)) {
                        TimeSeries ts = updateTimeSeries(meta.getColumnName(i), i, val);
                    }

                }
                if (model == null) {
                    model = new DefaultTableModel(t_obj, 0);
                    getJTable().setModel(model);
                }

                model.addRow(t_val);
                while (model.getRowCount() > 100) {
                    model.removeRow(0);
                }

                first_loop = false;
            }

            chart = ChartFactory.createTimeSeriesChart("", "", "", c, true, true, true);

            XYPlot plot = chart.getXYPlot();
            plot.setBackgroundPaint(Color.BLACK);
            plot.setRangeGridlinePaint(Color.WHITE);
            plot.getDomainAxis().setAutoRange(true);
            plot.getRangeAxis().setAutoRange(true);

            ValueAxis axis = plot.getDomainAxis();
            axis.setLowerMargin(0.03);
            axis.setUpperMargin(0.03);

            ChartPanel panel = (ChartPanel) getJPanel();
            panel.setChart(chart);
        } else {
            String[] t_val = new String[meta.getColumnCount()];
            rs.beforeFirst();
            while (rs.next()) {
                for (int i = 1; i <= meta.getColumnCount(); i++) {
                    double val = 0;

                    if (meta.getColumnTypeName(i).equals(DataTypes.STRING)) {
                        t_val[i - 1] = rs.getString(i);
                        continue;
                    }
                    if (meta.getColumnTypeName(i).equals(DataTypes.OBJECT)) {
                        t_val[i - 1] = rs.getObject(i).toString();
                        continue;
                    }
                    if (meta.getColumnTypeName(i).equals(DataTypes.LONG)) {
                        long lval = rs.getLong(i);
                        val = (double) lval;
                        t_val[i - 1] = String.valueOf(lval);
                    } else if (meta.getColumnTypeName(i).equals(DataTypes.DOUBLE)) {
                        val = rs.getDouble(i);
                        t_val[i - 1] = String.valueOf(val);
                    } else {
                        t_val[i - 1] = rs.getString(i);
                        continue;
                    }

                    if (val < 1000000 || Double.isNaN(val)) {
                        TimeSeries ts = updateTimeSeries(meta.getColumnName(i), i, val);
                    }
                }

                model.addRow(t_val);
                while (model.getRowCount() > 100) {
                    model.removeRow(0);
                }
            }
            repaint();
        }
    } catch (CQException ce) {
        ce.printStackTrace();
    }
}

From source file:ucar.unidata.idv.control.chart.TimeSeriesChart.java

/**
 * Make the plot//from   w  ww .  j a  v  a 2s  .com
 *
 * @return The plot_
 */
public Plot doMakePlot() {

    IdvPreferenceManager pref = control.getControlContext().getIdv().getPreferenceManager();
    TimeZone timeZone = pref.getDefaultTimeZone();
    NumberAxis valueAxis = new FixedWidthNumberAxis("");
    final SimpleDateFormat sdf = new SimpleDateFormat(
            ((dateFormat != null) ? dateFormat : pref.getDefaultDateFormat()));
    sdf.setTimeZone(timeZone);
    DateAxis timeAxis = new DateAxis("Time (" + timeZone.getID() + ")", timeZone) {

        protected List xxxxxrefreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {

            List ticks = super.refreshTicksHorizontal(g2, dataArea, edge);

            List<Tick> result = new java.util.ArrayList<Tick>();

            Font tickLabelFont = getTickLabelFont();
            g2.setFont(tickLabelFont);

            if (isAutoTickUnitSelection()) {
                selectAutoTickUnit(g2, dataArea, edge);
            }

            DateTickUnit unit = getTickUnit();
            Date tickDate = calculateLowestVisibleTickValue(unit);
            Date upperDate = getMaximumDate();

            Date firstDate = null;
            while (tickDate.before(upperDate)) {

                if (!isHiddenValue(tickDate.getTime())) {
                    // work out the value, label and position
                    String tickLabel;
                    DateFormat formatter = getDateFormatOverride();
                    if (firstDate == null) {
                        if (formatter != null) {
                            tickLabel = formatter.format(tickDate);
                        } else {
                            tickLabel = getTickUnit().dateToString(tickDate);
                        }
                        firstDate = tickDate;
                    } else {
                        double msdiff = tickDate.getTime() - firstDate.getTime();
                        int hours = (int) (msdiff / 1000 / 60 / 60);
                        tickLabel = hours + "H";
                    }
                    //                tickLabel = tickLabel;
                    TextAnchor anchor = null;
                    TextAnchor rotationAnchor = null;
                    double angle = 0.0;
                    if (isVerticalTickLabels()) {
                        anchor = TextAnchor.CENTER_RIGHT;
                        rotationAnchor = TextAnchor.CENTER_RIGHT;
                        if (edge == RectangleEdge.TOP) {
                            angle = Math.PI / 2.0;
                        } else {
                            angle = -Math.PI / 2.0;
                        }
                    } else {
                        if (edge == RectangleEdge.TOP) {
                            anchor = TextAnchor.BOTTOM_CENTER;
                            rotationAnchor = TextAnchor.BOTTOM_CENTER;
                        } else {
                            anchor = TextAnchor.TOP_CENTER;
                            rotationAnchor = TextAnchor.TOP_CENTER;
                        }
                    }

                    Tick tick = new DateTick(tickDate, tickLabel, anchor, rotationAnchor, angle);
                    result.add(tick);
                    tickDate = unit.addToDate(tickDate, getTimeZone());
                } else {
                    tickDate = unit.rollDate(tickDate, getTimeZone());

                    continue;
                }

                // could add a flag to make the following correction optional...
                switch (unit.getUnit()) {

                case (DateTickUnit.MILLISECOND):
                case (DateTickUnit.SECOND):
                case (DateTickUnit.MINUTE):
                case (DateTickUnit.HOUR):
                case (DateTickUnit.DAY):
                    break;

                case (DateTickUnit.MONTH):
                    tickDate = calculateDateForPositionX(new Month(tickDate, getTimeZone()),
                            getTickMarkPosition());

                    break;

                case (DateTickUnit.YEAR):
                    tickDate = calculateDateForPositionX(new Year(tickDate, getTimeZone()),
                            getTickMarkPosition());

                    break;

                default:
                    break;

                }

            }

            return result;

        }

        private Date calculateDateForPositionX(RegularTimePeriod period, DateTickMarkPosition position) {

            if (position == null) {
                throw new IllegalArgumentException("Null 'position' argument.");
            }
            Date result = null;
            if (position == DateTickMarkPosition.START) {
                result = new Date(period.getFirstMillisecond());
            } else if (position == DateTickMarkPosition.MIDDLE) {
                result = new Date(period.getMiddleMillisecond());
            } else if (position == DateTickMarkPosition.END) {
                result = new Date(period.getLastMillisecond());
            }

            return result;

        }

    };
    timeAxis.setDateFormatOverride(sdf);

    final XYPlot[] xyPlotHolder = { null };

    xyPlotHolder[0] = new MyXYPlot(new TimeSeriesCollection(), timeAxis, valueAxis, null) {
        public void drawBackground(Graphics2D g2, Rectangle2D area) {
            super.drawBackground(g2, area);
            drawSunriseSunset(g2, xyPlotHolder[0], area);
        }
    };

    if (animationTimeAnnotation != null) {
        xyPlotHolder[0].addAnnotation(animationTimeAnnotation);
    }

    return xyPlotHolder[0];

}