Search in sources :

Example 1 with SeriesException

use of org.jfree.data.general.SeriesException in project zm-mailbox by Zimbra.

the class ChartUtil method readCsvFiles.

private void readCsvFiles() throws Exception {
    Date minDate = null;
    Date maxDate = null;
    // per-file--shouldn't happen much since this is only for groupplot
    for (DataColumn c : mUniqueStringColumns) {
        String inFilename = c.getInfile();
        Reader reader = null;
        StringSeries data = mStringSeries.get(c);
        try {
            reader = new MultipleDirsFileReader(inFilename, mSrcDirs);
        } catch (FileNotFoundException e) {
            System.out.printf("CSV file %s not found; Skipping...\n", inFilename);
            continue;
        }
        CsvReader csv = null;
        try {
            csv = new CsvReader(reader);
            int line = 1;
            while (csv.hasNext()) {
                line++;
                String ctx = inFilename + ", line " + line;
                Date ts = null;
                try {
                    ts = readTS(csv, ctx);
                } catch (ParseException e) {
                    if (e.getMessage().compareTo("Unparseable date: \"timestamp\"") != 0) {
                        // bug 54626, ignored the repeat timestamp header
                        System.out.println(ctx + ": " + e);
                    }
                    continue;
                }
                if (ts.before(mStartAt) || ts.after(mEndAt))
                    continue;
                if (minDate == null) {
                    minDate = ts;
                    maxDate = ts;
                } else {
                    if (ts.compareTo(minDate) < 0)
                        minDate = ts;
                    if (ts.compareTo(maxDate) > 0)
                        maxDate = ts;
                }
                String value = csv.getValue(c.getColumn());
                data.AddEntry(ts, value);
            }
        } finally {
            if (csv != null)
                csv.close();
        }
    }
    // Read CSVs and populate data series.
    for (Iterator<Map.Entry<String, Set<Pair<String, DataSeries>>>> mapIter = mColumnsByInfile.entrySet().iterator(); mapIter.hasNext(); ) {
        Map.Entry<String, Set<Pair<String, DataSeries>>> entry = mapIter.next();
        String inFilename = entry.getKey();
        Set<Pair<String, DataSeries>> columns = entry.getValue();
        System.out.println("Reading CSV " + inFilename);
        Reader reader = null;
        try {
            reader = new MultipleDirsFileReader(inFilename, mSrcDirs);
        } catch (FileNotFoundException e) {
            System.out.printf("CSV file %s not found; Skipping...\n", inFilename);
            continue;
        }
        CsvReader csv = null;
        try {
            csv = new CsvReader(reader);
            int line = 1;
            while (csv.hasNext()) {
                line++;
                String context = inFilename + ", line " + line;
                Date ts = null;
                try {
                    ts = readTS(csv, context);
                } catch (ParseException e) {
                    if (e.getMessage().compareTo("Unparseable date: \"timestamp\"") != 0) {
                        // bug 54626, ignored the repeat timestamp header
                        System.out.println(context + ": " + e);
                    }
                    continue;
                }
                if (ts.before(mStartAt) || ts.after(mEndAt))
                    continue;
                // Set min/max date
                if (minDate == null) {
                    minDate = ts;
                    maxDate = ts;
                } else {
                    if (ts.compareTo(minDate) < 0) {
                        minDate = ts;
                    }
                    if (ts.compareTo(maxDate) > 0) {
                        maxDate = ts;
                    }
                }
                // Parse values
                for (Iterator<Pair<String, DataSeries>> colIter = columns.iterator(); colIter.hasNext(); ) {
                    Pair<String, DataSeries> colSeries = colIter.next();
                    String column = colSeries.getFirst();
                    DataSeries series = colSeries.getSecond();
                    String val = csv.getValue(column);
                    if (!StringUtil.isNullOrEmpty(val)) {
                        try {
                            double d = Double.parseDouble(val);
                            try {
                                series.AddEntry(ts, d);
                            } catch (SeriesException e) {
                                System.out.printf("Can't add sample to series: timestamp=%s, value=%s\n", ts, val);
                                e.printStackTrace(System.out);
                            }
                        } catch (NumberFormatException e) {
                            System.out.println(String.format("%s: unable to parse value '%s' for %s: %s", context, val, column, e));
                        }
                    } else {
                        // default an entry to 0 if string is empty
                        series.AddEntry(ts, 0.0);
                    }
                }
            }
            for (Iterator<Pair<String, DataSeries>> colIter = columns.iterator(); colIter.hasNext(); ) {
                Pair<String, DataSeries> colSeries = colIter.next();
                String column = colSeries.getFirst();
                DataSeries series = colSeries.getSecond();
                System.out.format("Adding %d %s points between %s and %s.\n\n", series.size(), column, minDate, maxDate);
            }
        } finally {
            if (csv != null)
                csv.close();
        }
    }
    adustSampleRange(minDate, maxDate);
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) FileNotFoundException(java.io.FileNotFoundException) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) CsvReader(com.zimbra.common.util.CsvReader) FileReader(java.io.FileReader) SeriesException(org.jfree.data.general.SeriesException) Date(java.util.Date) CsvReader(com.zimbra.common.util.CsvReader) ParseException(java.text.ParseException) HashMap(java.util.HashMap) Map(java.util.Map) Pair(com.zimbra.common.util.Pair)

Example 2 with SeriesException

use of org.jfree.data.general.SeriesException in project SIMVA-SoS by SESoS.

the class TimeSeries method add.

/**
 * Adds a data item to the series and sends a {@link SeriesChangeEvent} to
 * all registered listeners.
 *
 * @param item  the (timeperiod, value) pair (<code>null</code> not
 *              permitted).
 * @param notify  notify listeners?
 */
public void add(TimeSeriesDataItem item, boolean notify) {
    ParamChecks.nullNotPermitted(item, "item");
    item = (TimeSeriesDataItem) item.clone();
    Class c = item.getPeriod().getClass();
    if (this.timePeriodClass == null) {
        this.timePeriodClass = c;
    } else if (!this.timePeriodClass.equals(c)) {
        StringBuilder b = new StringBuilder();
        b.append("You are trying to add data where the time period class ");
        b.append("is ");
        b.append(item.getPeriod().getClass().getName());
        b.append(", but the TimeSeries is expecting an instance of ");
        b.append(this.timePeriodClass.getName());
        b.append(".");
        throw new SeriesException(b.toString());
    }
    // make the change (if it's not a duplicate time period)...
    boolean added = false;
    int count = getItemCount();
    if (count == 0) {
        this.data.add(item);
        added = true;
    } else {
        RegularTimePeriod last = getTimePeriod(getItemCount() - 1);
        if (item.getPeriod().compareTo(last) > 0) {
            this.data.add(item);
            added = true;
        } else {
            int index = Collections.binarySearch(this.data, item);
            if (index < 0) {
                this.data.add(-index - 1, item);
                added = true;
            } else {
                StringBuilder b = new StringBuilder();
                b.append("You are attempting to add an observation for ");
                b.append("the time period ");
                b.append(item.getPeriod().toString());
                b.append(" but the series already contains an observation");
                b.append(" for that time period. Duplicates are not ");
                b.append("permitted.  Try using the addOrUpdate() method.");
                throw new SeriesException(b.toString());
            }
        }
    }
    if (added) {
        updateBoundsForAddedItem(item);
        // check if this addition will exceed the maximum item count...
        if (getItemCount() > this.maximumItemCount) {
            TimeSeriesDataItem d = (TimeSeriesDataItem) this.data.remove(0);
            updateBoundsForRemovedItem(d);
        }
        // remove old items if necessary, but
        removeAgedItems(false);
        // happens next anyway...
        if (notify) {
            fireSeriesChanged();
        }
    }
}
Also used : SeriesException(org.jfree.data.general.SeriesException)

Example 3 with SeriesException

use of org.jfree.data.general.SeriesException in project zm-mailbox by Zimbra.

the class ChartUtil method createJFReeChart.

private List<JFreeChart> createJFReeChart(ChartSettings cs) {
    double minValue = Double.MAX_VALUE;
    double maxValue = Double.MIN_VALUE;
    double d = 0;
    double count = 0;
    double total = 0;
    TimeSeriesCollection data = new TimeSeriesCollection();
    ArrayList<ChartSettings> syntheticSettings = new ArrayList<ChartSettings>();
    for (GroupPlotSettings gps : cs.getGroupPlots()) {
        String groupBy = gps.getGroupBy();
        DataColumn dc = new DataColumn(gps.getInfile(), groupBy);
        StringSeries groupBySeries = mStringSeries.get(dc);
        dc = new DataColumn(gps.getInfile(), gps.getDataColumn());
        DataSeries ds = mDataSeries.get(dc);
        int idx = 0;
        Map<String, List<Integer>> groups = new HashMap<String, List<Integer>>();
        for (StringEntry e : groupBySeries.dataCollection) {
            String g = e.getVal();
            List<Integer> indices = groups.get(g);
            if (indices == null) {
                indices = new ArrayList<Integer>();
                groups.put(g, indices);
            }
            indices.add(idx);
            idx++;
        }
        for (Map.Entry<String, List<Integer>> g : groups.entrySet()) {
            String groupByValue = g.getKey();
            if (gps.getIgnoreSet().contains(groupByValue))
                continue;
            List<Integer> indices = g.getValue();
            DataSeries syntheticDS = new DataSeries();
            DataColumn c = new DataColumn(gps.getInfile(), GROUP_PLOT_SYNTHETIC + groupByValue + ":" + gps.getDataColumn());
            for (int i : indices) {
                Entry e = ds.get(i);
                syntheticDS.AddEntry(e.getTimestamp(), e.getVal());
            }
            mDataSeries.put(c, syntheticDS);
            PlotSettings syntheticPlot = new PlotSettings(groupByValue, c.getInfile(), c.getColumn(), gps.getShowRaw(), gps.getShowMovingAvg(), gps.getMovingAvgPoints(), gps.getMultiplier(), gps.getDivisor(), gps.getNonNegative(), gps.getPercentTime(), gps.getDataFunction(), gps.getAggregateFunction(), gps.getOptional(), null, null);
            cs.addPlot(syntheticPlot);
            if (cs.getOutDocument() != null) {
                ChartSettings s = new ChartSettings(String.format(cs.getTitle(), groupByValue), cs.getCategory(), String.format(cs.getOutfile(), groupByValue), cs.getXAxis(), cs.getYAxis(), cs.getAllowLogScale(), cs.getPlotZero(), cs.getWidth(), cs.getHeight(), null, cs.getTopPlots(), cs.getTopPlotsType());
                s.addPlot(syntheticPlot);
                syntheticSettings.add(s);
            }
        }
    }
    if (cs.getOutDocument() != null && cs.getGroupPlots().size() != 0) {
        ArrayList<JFreeChart> charts = new ArrayList<JFreeChart>();
        for (ChartSettings c : syntheticSettings) {
            charts.addAll(createJFReeChart(c));
            c.setOutDocument(cs.getOutDocument());
        }
        mSyntheticChartSettings.addAll(syntheticSettings);
        return charts;
    }
    List<PlotSettings> plots = cs.getPlots();
    if (cs.getTopPlots() > 0 && plots.size() > cs.getTopPlots()) {
        String aggregateFunction = cs.getTopPlotsType().name().toLowerCase();
        System.out.println(String.format("Reducing %d to %d plots for chart '%s'", plots.size(), cs.getTopPlots(), cs.getTitle()));
        ArrayList<PlotAggregatePair> aggregates = new ArrayList<PlotAggregatePair>();
        for (PlotSettings ps : plots) {
            DataColumn dc = new DataColumn(ps.getInfile(), ps.getDataColumn());
            String key = ps.getInfile() + ":" + ps.getDataColumn() + ":" + ps.getAggregateFunction();
            PlotDataIterator pdIter = new PlotDataIterator(ps, mDataSeries.get(dc));
            double aggregate = mAggregator.compute(pdIter, aggregateFunction, mAggregateStartAt, mAggregateEndAt, key);
            aggregates.add(new PlotAggregatePair(ps, aggregate));
        }
        Collections.sort(aggregates);
        while (aggregates.size() > cs.getTopPlots()) {
            PlotAggregatePair pair = aggregates.remove(0);
            plots.remove(pair.ps);
        }
    }
    for (PlotSettings ps : plots) {
        String columnName = ps.getDataColumn();
        if (columnName == null) {
            columnName = RATIO_PLOT_SYNTHETIC + ps.getRatioTop() + "/" + ps.getRatioBottom();
            String infile = ps.getInfile();
            String[] top = ps.getRatioTop().split("\\+");
            String[] bottom = ps.getRatioBottom().split("\\+");
            DataColumn[] ratioTop = new DataColumn[top.length];
            DataColumn[] ratioBottom = new DataColumn[bottom.length];
            for (int i = 0, j = top.length; i < j; i++) ratioTop[i] = new DataColumn(infile, top[i]);
            for (int i = 0, j = bottom.length; i < j; i++) ratioBottom[i] = new DataColumn(infile, bottom[i]);
            DataSeries[] topData = new DataSeries[ratioTop.length];
            DataSeries[] bottomData = new DataSeries[ratioBottom.length];
            for (int i = 0, j = ratioTop.length; i < j; i++) topData[i] = mDataSeries.get(ratioTop[i]);
            for (int i = 0, j = ratioBottom.length; i < j; i++) bottomData[i] = mDataSeries.get(ratioBottom[i]);
            DataSeries ds = new DataSeries();
            for (int i = 0, j = topData[0].size(); i < j; i++) {
                double topValue = 0.0;
                double bottomValue = 0.0;
                double ratio = 0.0;
                Entry lastEntry = null;
                for (int m = 0, n = topData.length; m < n; m++) {
                    Entry e = topData[m].get(i);
                    topValue += e.getVal();
                }
                for (int m = 0, n = bottomData.length; m < n; m++) {
                    Entry e = bottomData[m].get(i);
                    bottomValue += e.getVal();
                    lastEntry = e;
                }
                if (bottomValue != 0.0) {
                    ratio = topValue / bottomValue;
                }
                // should never be null
                assert lastEntry != null;
                ds.AddEntry(lastEntry.getTimestamp(), ratio);
            }
            mDataSeries.put(new DataColumn(infile, columnName), ds);
            ps.setDataColumn(columnName);
        }
        DataColumn dc = new DataColumn(ps.getInfile(), ps.getDataColumn());
        DataSeries ds = mDataSeries.get(dc);
        TimeSeries ts = new TimeSeries(ps.getLegend(), FixedMillisecond.class);
        int numSamples = 0;
        for (PlotDataIterator pdIter = new PlotDataIterator(ps, ds); pdIter.hasNext(); numSamples++) {
            Pair<Date, Double> entry = pdIter.next();
            Date tstamp = entry.getFirst();
            double val = entry.getSecond().doubleValue();
            if (val != 0 || cs.getPlotZero()) {
                if (d < minValue)
                    minValue = val;
                if (d > maxValue)
                    maxValue = val;
                count++;
                total += val;
                try {
                    ts.addOrUpdate(new FixedMillisecond(tstamp), val);
                } catch (SeriesException e) {
                    e.printStackTrace(System.out);
                }
            }
        }
        if (numSamples == 0 && ps.getOptional()) {
            System.out.format("Skipping optional plot %s (no data sample found)\n\n", ps.getLegend());
            continue;
        }
        System.out.format("Adding %d %s points to %s.\n\n", ds.size(), ps.getLegend(), cs.getOutfile());
        if (ps.getShowRaw()) {
            data.addSeries(ts);
        }
        if (ps.getShowMovingAvg()) {
            int numPoints = ps.getMovingAvgPoints();
            if (numPoints == PlotSettings.DEFAULT_PLOT_MOVING_AVG_POINTS) {
                // Display 200 points for moving average.
                // Divide the total number of points by 200 to
                // determine the number of samples to average
                // for each point.
                numPoints = ts.getItemCount() / 200;
            }
            if (numPoints >= 2) {
                TimeSeries ma = MovingAverage.createPointMovingAverage(ts, ps.getLegend() + " (moving avg)", numPoints);
                data.addSeries(ma);
            } else {
                System.out.println("Not enough data to display moving average for " + ps.getLegend());
                data.addSeries(ts);
            }
        }
    }
    // Create chart
    boolean legend = (data.getSeriesCount() > 1);
    JFreeChart chart = ChartFactory.createTimeSeriesChart(null, cs.getXAxis(), cs.getYAxis(), data, legend, false, false);
    // Make Y-axis logarithmic if a spike was detected
    if (cs.getAllowLogScale() && (minValue > 0) && (maxValue > 0) && (maxValue > 20 * (total / count))) {
        if (maxValue / minValue > 100) {
            XYPlot plot = (XYPlot) chart.getPlot();
            ValueAxis oldAxis = plot.getRangeAxis();
            LogarithmicAxis newAxis = new LogarithmicAxis(oldAxis.getLabel());
            plot.setRangeAxis(newAxis);
        }
    }
    mChartMap.put(cs, chart);
    return Arrays.asList(chart);
}
Also used : TimeSeries(org.jfree.data.time.TimeSeries) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) FixedMillisecond(org.jfree.data.time.FixedMillisecond) TimeSeriesCollection(org.jfree.data.time.TimeSeriesCollection) ValueAxis(org.jfree.chart.axis.ValueAxis) ArrayList(java.util.ArrayList) List(java.util.List) SeriesException(org.jfree.data.general.SeriesException) JFreeChart(org.jfree.chart.JFreeChart) Date(java.util.Date) LogarithmicAxis(org.jfree.chart.axis.LogarithmicAxis) XYPlot(org.jfree.chart.plot.XYPlot) HashMap(java.util.HashMap) Map(java.util.Map)

Example 4 with SeriesException

use of org.jfree.data.general.SeriesException in project SIMVA-SoS by SESoS.

the class TimePeriodValues method createCopy.

/**
 * Creates a new instance by copying a subset of the data in this
 * collection.
 *
 * @param start  the index of the first item to copy.
 * @param end  the index of the last item to copy.
 *
 * @return A copy of a subset of the items.
 *
 * @throws CloneNotSupportedException if there is a cloning problem.
 */
public TimePeriodValues createCopy(int start, int end) throws CloneNotSupportedException {
    TimePeriodValues copy = (TimePeriodValues) super.clone();
    copy.data = new ArrayList();
    if (this.data.size() > 0) {
        for (int index = start; index <= end; index++) {
            TimePeriodValue item = (TimePeriodValue) this.data.get(index);
            TimePeriodValue clone = (TimePeriodValue) item.clone();
            try {
                copy.add(clone);
            } catch (SeriesException e) {
                System.err.println("Failed to add cloned item.");
            }
        }
    }
    return copy;
}
Also used : ArrayList(java.util.ArrayList) SeriesException(org.jfree.data.general.SeriesException)

Example 5 with SeriesException

use of org.jfree.data.general.SeriesException in project SIMVA-SoS by SESoS.

the class TimeSeries method addOrUpdate.

/**
 * Adds or updates an item in the times series and sends a
 * {@link SeriesChangeEvent} to all registered listeners.
 *
 * @param item  the data item (<code>null</code> not permitted).
 *
 * @return A copy of the overwritten data item, or <code>null</code> if no
 *         item was overwritten.
 *
 * @since 1.0.14
 */
public TimeSeriesDataItem addOrUpdate(TimeSeriesDataItem item) {
    ParamChecks.nullNotPermitted(item, "item");
    Class periodClass = item.getPeriod().getClass();
    if (this.timePeriodClass == null) {
        this.timePeriodClass = periodClass;
    } else if (!this.timePeriodClass.equals(periodClass)) {
        String msg = "You are trying to add data where the time " + "period class is " + periodClass.getName() + ", but the TimeSeries is expecting an instance of " + this.timePeriodClass.getName() + ".";
        throw new SeriesException(msg);
    }
    TimeSeriesDataItem overwritten = null;
    int index = Collections.binarySearch(this.data, item);
    if (index >= 0) {
        TimeSeriesDataItem existing = (TimeSeriesDataItem) this.data.get(index);
        overwritten = (TimeSeriesDataItem) existing.clone();
        // figure out if we need to iterate through all the y-values
        // to find the revised minY / maxY
        boolean iterate = false;
        Number oldYN = existing.getValue();
        double oldY = oldYN != null ? oldYN.doubleValue() : Double.NaN;
        if (!Double.isNaN(oldY)) {
            iterate = oldY <= this.minY || oldY >= this.maxY;
        }
        existing.setValue(item.getValue());
        if (iterate) {
            updateMinMaxYByIteration();
        } else if (item.getValue() != null) {
            double yy = item.getValue().doubleValue();
            this.minY = minIgnoreNaN(this.minY, yy);
            this.maxY = maxIgnoreNaN(this.maxY, yy);
        }
    } else {
        item = (TimeSeriesDataItem) item.clone();
        this.data.add(-index - 1, item);
        updateBoundsForAddedItem(item);
        // check if this addition will exceed the maximum item count...
        if (getItemCount() > this.maximumItemCount) {
            TimeSeriesDataItem d = (TimeSeriesDataItem) this.data.remove(0);
            updateBoundsForRemovedItem(d);
        }
    }
    // remove old items if necessary, but
    removeAgedItems(false);
    // don't notify anyone, because that
    // happens next anyway...
    fireSeriesChanged();
    return overwritten;
}
Also used : SeriesException(org.jfree.data.general.SeriesException)

Aggregations

SeriesException (org.jfree.data.general.SeriesException)6 ArrayList (java.util.ArrayList)2 Date (java.util.Date)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 CsvReader (com.zimbra.common.util.CsvReader)1 Pair (com.zimbra.common.util.Pair)1 FileNotFoundException (java.io.FileNotFoundException)1 FileReader (java.io.FileReader)1 InputStreamReader (java.io.InputStreamReader)1 Reader (java.io.Reader)1 ParseException (java.text.ParseException)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Set (java.util.Set)1 JFreeChart (org.jfree.chart.JFreeChart)1 LogarithmicAxis (org.jfree.chart.axis.LogarithmicAxis)1 ValueAxis (org.jfree.chart.axis.ValueAxis)1 XYPlot (org.jfree.chart.plot.XYPlot)1 FixedMillisecond (org.jfree.data.time.FixedMillisecond)1