⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphengine.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/**
 * $RCSfile  $
 * $Revision  $
 * $Date  $
 *
 * Copyright (C) 2008 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution, or a commercial license
 * agreement with Jive.
 */
package org.jivesoftware.openfire.reporting.graph;

import org.jivesoftware.openfire.reporting.stats.StatsViewer;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.axis.*;
import org.jfree.chart.encoders.KeypointPNGEncoderAdapter;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.renderer.xy.XYAreaRenderer;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.*;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.util.Rotation;
import org.jivesoftware.openfire.stats.Statistic;
import org.jivesoftware.util.JiveGlobals;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.NumberFormat;

/**
 * Builds graphs off of statistics tracked in the <i>StatsEngine</i>.
 *
 * @author Alexander Wenckus
 * @see StatsViewer
 */
public class GraphEngine {
    private StatsViewer statsViewer;

    private static final long YEAR = 31104000000L;

    private static final long MONTH = 2592000000L;

    private static final long WEEK = 604800000L;

    private static final long DAY = 86400000L;

    private TickUnits tickUnits;
    private Locale oldLocale;

    /**
     * Default constructor used by the plugin container to construct the graph engine.
     *
     * @param statsViewer The viewer provides an mechanism to view the data being tracked by the <i>StatsEngine</i>.
     */
    public GraphEngine(StatsViewer statsViewer) {
        this.statsViewer = statsViewer;
    }

    /**
     * Creates a graph in PNG format.  The PNG graph is encoded by the KeypointPNGEncoderAdapter
     * so that the resulting PNG is encoded with alpha transparency.
     *
     * @param key
     * @param width
     * @param height
     * @param startTime
     * @param endTime
     * @param dataPoints
     * @return
     * @throws IOException
     */
    public byte[] generateGraph(String key, int width, int height, String color, long startTime, long endTime,
                                int dataPoints) throws IOException
    {

        JFreeChart chart = generateChart(key, width, height, color, startTime, endTime,dataPoints);
        KeypointPNGEncoderAdapter encoder = new KeypointPNGEncoderAdapter();
        encoder.setEncodingAlpha(true);
        return encoder.encode(chart.createBufferedImage(width, height, BufferedImage.BITMASK, null));
    }

    /**
     * Creates a chart.
     *
     * @param key
     * @param width
     * @param height
     * @param startTime
     * @param endTime
     * @param dataPoints
     * @return
     * @throws IOException
     */
    public JFreeChart generateChart(String key, int width, int height, String color, long startTime, long endTime,
                                    int dataPoints) throws IOException
    {
        Statistic[] def = statsViewer.getStatistic(key);
        if (def == null) {
            return null;
        }

        XYDataset data = populateData(key, def, startTime, endTime, dataPoints);
        if (data == null) {
            return null;
        }
        JFreeChart chart;
        switch(def[0].getStatType()) {
            case count:
                chart = createTimeBarChart(null, color, def[0].getUnits(), data);
                break;
            default:
                chart = createTimeAreaChart(null, color, def[0].getUnits(), data);
        }

        return chart;
    }



    /**
     * Generates a Sparkline type graph. Sparkline graphs
     * are "intense, simple, wordlike graphics" so named by Edward Tufte. The big
     * difference between the graph produced by this method compared to the
     * graph produced by the <code>generateGraph</code> method is that this one
     * produces graphs with no x-axis and no y-axis and is usually smaller in size.
     * @param key
     * @param width
     * @param height
     * @param startTime
     * @param endTime
     * @param dataPoints
     * @return
     * @throws IOException
     */
    public byte[] generateSparklinesGraph(String key, int width, int height, String color, long startTime,
                                          long endTime, int dataPoints) throws IOException
    {
        Statistic[] def = statsViewer.getStatistic(key);
        if (def == null) {
            return null;
        }

        JFreeChart chart;
        switch (def[0].getStatType()) {
            case count:
                chart = generateSparklineBarGraph(key, color, def, startTime, endTime, dataPoints);
                break;
            default:
                chart = generateSparklineAreaChart(key, color, def, startTime, endTime, dataPoints);
        }

        KeypointPNGEncoderAdapter encoder = new KeypointPNGEncoderAdapter();
        encoder.setEncodingAlpha(true);
        return encoder.encode(chart.createBufferedImage(width, height, BufferedImage.BITMASK, null));
    }

    private XYDataset populateData(String key, Statistic[] def, long startTime, long endTime,
                                   int dataPoints)
    {
        double[][] values = statsViewer.getData(key, startTime, endTime, dataPoints);
        long timePeriod = endTime - startTime;
        TimeSeries[] series = new TimeSeries[values.length];
        TimeSeriesCollection dataSet = new TimeSeriesCollection();

        for (int d = 0; d < values.length; d++) {
            series[d] = new TimeSeries(def[d].getName(), getTimePeriodClass(timePeriod));
            Statistic.Type type = def[d].getStatType();

            long interval = timePeriod / values[d].length;
            for (int i = 0; i < values[d].length; i++) {
                series[d].addOrUpdate(
                        getTimePeriod(timePeriod, new Date(startTime + (i * interval)),
                                JiveGlobals.getTimeZone()), cleanData(type, values[d][i]));
            }
            dataSet.addSeries(series[d]);
        }
        return dataSet;
    }

    private Class<? extends RegularTimePeriod> getTimePeriodClass(long timePeriod) {
        if (timePeriod > 86400000) {
            return Day.class;
        } else if (timePeriod > 3600000) {
            return Hour.class;
        } else {
            return Minute.class;
        }
    }

    private RegularTimePeriod getTimePeriod(long timePeriod, Date date, TimeZone zone) {
        if (timePeriod > 86400000) {
            return new Day(date, zone);
        } else if (timePeriod > 3600000) {
            return new Hour(date, zone);
        } else {
            return new Minute(date, zone);
        }
    }


    /**
     * Round up a defined value.
     *
     * @param type  the type of Statistic.
     * @param value the value.
     * @return the rounded up value.
     */
    private double cleanData(Statistic.Type type, double value) {
        if(type == Statistic.Type.count) {
            return Math.round(value);
        }
        return value;
    }

    /**
     * Generates a generic Time Area Chart.
     *
     * @param title      the title of the Chart.
     * @param valueLabel the Y Axis label.
     * @param data       the data to populate with.
     * @return the generated Chart.
     */
    private JFreeChart createTimeAreaChart(String title, String color, String valueLabel, XYDataset data) {
        PlotOrientation orientation = PlotOrientation.VERTICAL;

        DateAxis xAxis = generateTimeAxis();

        NumberAxis yAxis = new NumberAxis(valueLabel);

        NumberFormat formatter = NumberFormat.getNumberInstance(JiveGlobals.getLocale());
        formatter.setMaximumFractionDigits(2);
        formatter.setMinimumFractionDigits(0);
        yAxis.setNumberFormatOverride(formatter);

        XYAreaRenderer renderer = new XYAreaRenderer(XYAreaRenderer.AREA);
        renderer.setOutline(true);

        return createChart(title, data, xAxis, yAxis, orientation, renderer,
                GraphDefinition.getDefinition(color));
    }

    /**
     * Generates a generic Time Bar Chart.
     *
     * @param title      the title of the Chart.
     * @param valueLabel the X Axis Label.
     * @param data       the data to populate with.
     * @return the generated Chart.
     */
    private JFreeChart createTimeBarChart(String title, String color, String valueLabel, XYDataset data) {
        PlotOrientation orientation = PlotOrientation.VERTICAL;
        DateAxis xAxis = generateTimeAxis();

        NumberAxis yAxis = new NumberAxis(valueLabel);
        NumberFormat formatter = NumberFormat.getNumberInstance(JiveGlobals.getLocale());
        formatter.setMaximumFractionDigits(2);
        formatter.setMinimumFractionDigits(0);
        yAxis.setNumberFormatOverride(formatter);
        yAxis.setAutoRangeIncludesZero(true);

        return createChart(title, data, xAxis, yAxis, orientation, new XYBarRenderer(),
                GraphDefinition.getDefinition(color));
    }

    /**
     * Generates a Chart.
     *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -