org.jfree.data.IntegerHistogramDataset.java Source code

Java tutorial

Introduction

Here is the source code for org.jfree.data.IntegerHistogramDataset.java

Source

package org.jfree.data;

import org.jetbrains.annotations.NonNls;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class IntegerHistogramDataset extends HistogramDataset {
    /**
     * A list of maps.
     */
    private final List list = new ArrayList();

    /**
     * Adds a series.
     *
     * @param name   the series name.
     * @param values the values (<code>null</code> not permitted).
     */
    public void addSeries(String name, double[] values) {
        if (values == null) {
            throw new IllegalArgumentException(
                    "HistogramDataset.addSeries(...): 'values' argument must not be null.");
        }
        // work out bin strategy
        final double minimum = getMinimum(values);
        final double maximum = getMaximum(values);
        final int numberOfBins = 1 + (int) maximum - (int) minimum;

        final double binWidth = 1.0;
        // set up the bins
        double tmp = minimum;
        final HistogramBin[] bins = new HistogramBin[numberOfBins];
        for (int i = 0; i < bins.length; i++) {
            // make sure bins[bins.length]'s upper boundary ends at maxium
            // to avoid the rounding issue. the bins[0] lower boundary is
            // guaranteed start from min
            final HistogramBin bin;
            if (i == bins.length - 1) {
                bin = new HistogramBin(tmp, maximum);
            } else {
                bin = new HistogramBin(tmp, tmp + binWidth);
            }
            tmp += binWidth;
            bins[i] = bin;
        }
        // fill the bins
        for (double value : values) {
            for (HistogramBin bin : bins) {
                if (value >= bin.getStartBoundary() && value <= bin.getEndBoundary()) {
                    // note the greedy <=
                    bin.incrementCount();
                    break; // break out of inner loop
                }
            }
        }
        // generic map for each series
        @NonNls
        final Map map = new HashMap();
        map.put("name", name);
        map.put("bins", bins);
        map.put("values.length", values.length);
        map.put("bin width", binWidth);
        list.add(map);
    }

    /**
     * Returns the minimum value from an array.
     *
     * @param values the values.
     * @return The minimum value.
     */
    private double getMinimum(double[] values) {
        if (values == null || values.length < 1) {
            throw new IllegalArgumentException();
        }

        double min = Double.MAX_VALUE;
        for (double value : values) {
            if (value < min) {
                min = value;
            }
        }
        return min - 0.5;
    }

    /**
     * Returns the maximum value from an array.
     *
     * @param values the values.
     * @return The maximum value.
     */
    private double getMaximum(double[] values) {
        if (values == null || values.length < 1) {
            throw new IllegalArgumentException();
        }

        double max = -Double.MAX_VALUE;
        for (double value : values) {
            if (value > max) {
                max = value;
            }
        }
        return max + 0.5;
    }

    /**
     * Returns the bins for a series.
     *
     * @param series the series index.
     * @return An array of bins.
     */
    @Override
    HistogramBin[] getBins(int series) {
        @NonNls
        final Map map = (Map) list.get(series);
        return (HistogramBin[]) map.get("bins");
    }

    /**
     * Returns the total number of observations for a series.
     *
     * @param series the series index.
     * @return The total.
     */
    private int getTotal(int series) {
        @NonNls
        final Map map = (Map) list.get(series);
        return (Integer) map.get("values.length");
    }

    /**
     * Returns the bin width for a series.
     *
     * @param series the series index (zero based).
     * @return The bin width.
     */
    private double getBinWidth(int series) {
        @NonNls
        final Map map = (Map) list.get(series);
        return (Double) map.get("bin width");
    }

    /**
     * Returns the number of series in the dataset.
     *
     * @return The series count.
     */
    @Override
    public int getSeriesCount() {
        return list.size();
    }

    /**
     * Returns the name for a series.
     *
     * @param series the series index (zero based).
     * @return The series name.
     */
    @Override
    public String getSeriesName(int series) {
        @NonNls
        final Map map = (Map) list.get(series);
        return (String) map.get("name");
    }

    /**
     * Returns the number of data items for a series.
     *
     * @param series the series index (zero based).
     * @return The item count.
     */
    @Override
    public int getItemCount(int series) {
        return getBins(series).length;
    }

    /**
     * Returns the X value for a bin.
     * <p/>
     * This value won't be used for plotting histograms, since the renderer will
     * ignore it. But other renderers can use it (for example, you could use the
     * dataset to create a line chart).
     *
     * @param series the series index (zero based).
     * @param item   the item index (zero based).
     * @return The start value.
     */
    @Override
    public Number getXValue(int series, int item) {
        final HistogramBin[] bins = getBins(series);
        final HistogramBin bin = bins[item];
        return (bin.getStartBoundary() + bin.getEndBoundary()) / 2.0;
    }

    /**
     * Returns the Y value for a bin.
     *
     * @param series the series index (zero based).
     * @param item   the item index (zero based).
     * @return The Y value.
     */
    @Override
    public Number getYValue(int series, int item) {
        final HistogramBin[] bins = getBins(series);
        final double total = (double) getTotal(series);
        final double binWidth = getBinWidth(series);

        if (getType() == FREQUENCY) {
            return (double) bins[item].getCount();
        } else if (getType() == RELATIVE_FREQUENCY) {
            return (double) bins[item].getCount() / total;
        } else if (getType() == SCALE_AREA_TO_1) {
            return (double) bins[item].getCount() / (binWidth * total);
        } else { // pretty sure this shouldn't ever happen
            throw new IllegalStateException();
        }
    }

    /**
     * Returns the start value for a bin.
     *
     * @param series the series index (zero based).
     * @param item   the item index (zero based).
     * @return The start value.
     */
    @Override
    public Number getStartXValue(int series, int item) {
        final HistogramBin[] bins = getBins(series);
        return bins[item].getStartBoundary();
    }

    /**
     * Returns the end value for a bin.
     *
     * @param series the series index (zero based).
     * @param item   the item index (zero based).
     * @return The end value.
     */
    @Override
    public Number getEndXValue(int series, int item) {
        final HistogramBin[] bins = getBins(series);
        return bins[item].getEndBoundary();
    }

    /**
     * Returns the Y value for a bin.
     *
     * @param series the series index (zero based).
     * @param item   the item index (zero based).
     * @return The Y value.
     */
    @Override
    public Number getStartYValue(int series, int item) {
        //HistogramBin[] bins = getBins(series);
        return getYValue(series, item);
    }

    /**
     * Returns the Y value for a bin.
     *
     * @param series the series index (zero based).
     * @param item   the item index (zero based).
     * @return The Y value.
     */
    @Override
    public Number getEndYValue(int series, int item) {
        //HistogramBin[] bins = getBins(series);
        return getYValue(series, item);
    }
}