org.jtotus.gui.graph.GraphPrinter.java Source code

Java tutorial

Introduction

Here is the source code for org.jtotus.gui.graph.GraphPrinter.java

Source

/*
This file is part of jTotus.
    
jTotus is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
jTotus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with jTotus.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * http://tutorials.jenkov.com/java-collections/navigableset.html
 */
package org.jtotus.gui.graph;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYTextAnnotation;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBubbleRenderer;
import org.jfree.chart.renderer.xy.XYDotRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.renderer.xy.XYStepRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.joda.time.LocalDate;
import org.jtotus.common.StockUnit;

/**
 *
 * @author Evgeni Kappinen
 */
public class GraphPrinter {
    // Create a chart

    private String mainPlotName = "MainPlot";
    private JFreeChart mainChart = null;
    private ChartPanel mainPanel = null;
    private CombinedDomainXYPlot mainPlot = null;
    private HashMap<String, TimeSeries> seriesMap = null;
    private HashMap<String, XYPlot> plotMap = null;

    public GraphPrinter(String reviewTarget) {

        seriesMap = new HashMap<String, TimeSeries>();
        plotMap = new HashMap<String, XYPlot>();

        mainChart = this.createChart(reviewTarget);
        if (mainChart == null) {
            return;
        }

        mainPanel = new ChartPanel(mainChart, false);
        mainPanel.setMouseZoomable(true, false);
        mainPanel.setFillZoomRectangle(true);
        mainPanel.setMouseWheelEnabled(true);

    }

    private JFreeChart createChart(String title) {

        // valueAxis.setAutoRangeMinimumSize(1);
        DateAxis domain = new DateAxis("Date");
        domain.setDateFormatOverride(new SimpleDateFormat("dd-MM-yyyy"));

        mainPlot = new CombinedDomainXYPlot(domain);
        mainPlot.setGap(4.0);
        //mainPlot.setOrientation(PlotOrientation.HORIZONTAL);
        mainPlot.setBackgroundPaint(Color.lightGray);
        mainPlot.setRangePannable(true);
        mainPlot.setDomainGridlinesVisible(true);
        mainPlot.setOutlineVisible(true);
        mainPlot.setDomainCrosshairVisible(true);
        mainPlot.setRangeMinorGridlinesVisible(true);

        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, mainPlot, true);

        chart.setBackgroundPaint(Color.white);

        return chart;

    }

    private XYItemRenderer getDefaultLine() {
        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();

        renderer.setSeriesLinesVisible(1, true);
        renderer.setSeriesShapesVisible(1, true);
        return renderer;
    }

    private XYItemRenderer getdDefualtBuble() {
        XYBubbleRenderer renderer = new XYBubbleRenderer();
        renderer.setAutoPopulateSeriesOutlineStroke(false);
        return renderer;
    }

    private XYItemRenderer getdDefualtDot() {
        XYDotRenderer renderer = new XYDotRenderer();
        return renderer;
    }

    private XYItemRenderer getDefualtCandleStick() {
        XYStepRenderer renderer = new XYStepRenderer();

        return renderer;
    }

    public XYItemRenderer getRenderer(GraphSeriesType type) {
        if (type == null) {
            return this.getDefaultLine();
        }

        switch (type) {
        case SIMPLELINE:
            return this.getDefaultLine();
        case SIMPLEBUBLE:
            return this.getdDefualtBuble();
        case SIMPLECANDLESTICK:
            return this.getDefualtCandleStick();
        case SIMPLEDOT:
            return this.getdDefualtDot();
        default:
            return this.getDefaultLine();
        }
    }

    public Container getContainer() {
        return mainPanel;
    }

    public synchronized void cleanChart() {

        Iterator<TimeSeries> serIter = seriesMap.values().iterator();
        while (serIter.hasNext()) {
            serIter.next().clear();
        }

        return;
    }

    private XYPlot createSubPlot(String plotName, GraphSeriesType type) {

        final TimeSeriesCollection collection = new TimeSeriesCollection();
        final NumberAxis range = new NumberAxis("Value");
        final XYPlot newSubPlot = new XYPlot(collection, null, range, this.getRenderer(type));

        newSubPlot.setDomainCrosshairVisible(true);
        newSubPlot.setRangeCrosshairVisible(true);
        newSubPlot.setDomainGridlinesVisible(true);

        if (!plotMap.containsKey(plotName)) {
            plotMap.put(plotName, newSubPlot);
            mainPlot.add(newSubPlot);
            return newSubPlot;
        }

        return null;
    }

    private XYPlot fetchPlot(String name) {
        if (name == null) {
            name = this.mainPlotName;
        }
        return plotMap.get(name);
    }

    private TimeSeries createTimeSeries(GraphPacket packet) {
        XYPlot addSeriesToPlot = null;
        //TimeSeries with packet.seriesTitle is not found.

        //Create MainPlot for the rest of the packets.
        //This plot will be used if in packet.plotName is null
        if (plotMap.isEmpty()) {
            addSeriesToPlot = this.createSubPlot(this.mainPlotName, GraphSeriesType.SIMPLELINE);
        }

        //If packet.plotName is null, lets use MainPlot
        if (packet.plotName != null) {
            addSeriesToPlot = plotMap.get(packet.plotName);
            if (addSeriesToPlot == null) {
                addSeriesToPlot = this.createSubPlot(packet.plotName, packet.type);
            }
        }

        //If we are in this function, this means that
        //unique name of timeseries is not found in seriesMap.
        TimeSeries newSeries = new TimeSeries(packet.seriesTitle);
        seriesMap.put(packet.seriesTitle, newSeries);

        return newSeries;
    }

    private Day localDateToDay(LocalDate date) {
        Day tmpDay = new Day(date.getDayOfMonth(), date.getMonthOfYear(), date.getYear());

        return tmpDay;
    }

    /*
     * Creates new plot if neeed and adds values to time series
     *
     * @param packet Packet Object from blocking queus
     */
    public void drawSeries(GraphPacket packet) {
        TimeSeries series = null;

        if (seriesMap.containsKey(packet.seriesTitle)) { //Series Exists
            series = seriesMap.get(packet.seriesTitle);
        } else {
            series = this.createTimeSeries(packet);
            //FIXME: is it prefereable to add series after points are added ?
            TimeSeriesCollection collection = (TimeSeriesCollection) this.fetchPlot(packet.plotName).getDataset();
            collection.addSeries(series);
        }

        Iterator<StockUnit> iter = packet.results.iterator();
        while (iter.hasNext()) {
            //update if already existing series
            StockUnit unit = iter.next();
            if (unit.annotation != null) {
                final XYTextAnnotation annotation = new XYTextAnnotation(unit.annotation,
                        this.localDateToDay(unit.date).getMiddleMillisecond(), unit.value);
                annotation.setFont(new Font("SansSerif", Font.PLAIN, 9));
                this.fetchPlot(packet.plotName).addAnnotation(annotation);
            }

            series.addOrUpdate(this.localDateToDay(unit.date), unit.value);
        }
    }
}