Example usage for org.jfree.data.xy XYSeriesCollection getSeriesKey

List of usage examples for org.jfree.data.xy XYSeriesCollection getSeriesKey

Introduction

In this page you can find the example usage for org.jfree.data.xy XYSeriesCollection getSeriesKey.

Prototype

@Override
public Comparable getSeriesKey(int series) 

Source Link

Document

Returns the key for a series.

Usage

From source file:edu.fullerton.viewerplugin.PluginSupport.java

public static int scaleRange(XYSeriesCollection mtds, Double miny, Double maxy) {
    int exp = PluginSupport.getExp(miny, maxy);
    if (exp > 0 && exp < 100) {
        int nseries = mtds.getSeriesCount();
        XYSeries[] newSeries = new XYSeries[nseries];

        double scale = Math.pow(10, exp);
        for (int s = 0; s < nseries; s++) {
            XYSeries ds = (XYSeries) mtds.getSeries(s);
            Comparable skey = mtds.getSeriesKey(s);
            XYSeries nds = new XYSeries(skey, true);
            for (int item = 0; item < ds.getItemCount(); item++) {
                double x = ds.getX(item).doubleValue();
                double y = ds.getY(item).doubleValue();

                y *= scale;//from  w w  w.j a v a  2  s  .c  o  m
                nds.add(x, y);
            }
            newSeries[s] = nds;
        }
        mtds.removeAllSeries();
        for (int s = 0; s < nseries; s++) {
            mtds.addSeries(newSeries[s]);
        }
    } else {
        exp = 0;
    }
    return exp;
}

From source file:net.sf.jdmf.visualization.clustering.ChartGenerator.java

public JFreeChart generateXYChart(List<Cluster> clusters, Integer firstAttributeIndex,
        String firstAttributeName, Integer secondAttributeIndex, String secondAttributeName) {
    XYSeriesCollection dataset = new XYSeriesCollection();

    for (Cluster cluster : clusters) {
        XYSeries series = new XYSeries(cluster.getName());

        for (Vector<Double> point : cluster.getPoints()) {
            series.add(point.get(firstAttributeIndex), point.get(secondAttributeIndex));
        }//from  w w w .  j ava2 s .  c o m

        dataset.addSeries(series);
    }

    XYToolTipGenerator xyToolTipGenerator = new XYToolTipGenerator() {
        public String generateToolTip(XYDataset dataset, int series, int item) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(String.format("<html><p style='color:#0000ff;'>Series: '%s'</p>",
                    dataset.getSeriesKey(series)));
            Cluster cl = clusters.get(series);
            Vector<Double> point = cl.getPoints().get(item);
            for (int i = 0; i < point.size(); i++) {
                //stringBuilder.append(String.format("Attr:'%d'<br/>", d));
                try {
                    String attr = _attrName.get(i);
                    stringBuilder.append(attr + " " + point.get(i) + "<br/>");
                } catch (Exception e) {
                    // Do nothing 
                }
            }
            stringBuilder.append("</html>");
            return stringBuilder.toString();
        }
    };

    /***
    return ChartFactory.createScatterPlot( "Cluster Analysis", 
    firstAttributeName, secondAttributeName, dataset, 
    PlotOrientation.VERTICAL, true, true, false );
    ***/
    JFreeChart jfc = ChartFactory.createScatterPlot("Cluster Analysis", firstAttributeName, secondAttributeName,
            dataset, PlotOrientation.VERTICAL, true, true, false);

    XYItemRenderer render = jfc.getXYPlot().getRenderer();
    render.setBaseToolTipGenerator(xyToolTipGenerator);
    return jfc;
}

From source file:oct.analysis.application.OCTSelection.java

public JPanel createLRPPanel() {
    //create the series collection from the LRP data
    XYSeriesCollection lrp = new XYSeriesCollection();
    lrp.addSeries(getLrpSeriesFromOCT(OCTAnalysisManager.getInstance().getOctImage()));
    //        System.out.println("Processing graph " + lrp.getSeriesKey(0).toString());
    lrp.addSeries(findMaximums(lrp.getSeries(0), selectionName + " LRP Maximums"));
    List<XYSeries> fwhm = getFWHMForLRPPeaks(lrp.getSeries(1), lrp.getSeries(0));
    fwhm.forEach((fwhmSeries) -> {/*from   ww  w  . j  ava  2  s. com*/
        lrp.addSeries(fwhmSeries);
    });
    //create chart panel for LRP
    JFreeChart chart = ChartFactory.createXYLineChart(lrp.getSeriesKey(0).toString(), "Pixel Height",
            "Reflectivity", lrp, PlotOrientation.HORIZONTAL, false, true, false);
    XYPlot plot = chart.getXYPlot();
    //        plot.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
    //        plot.getDomainAxis().setInverted(true);
    //set up rendering principles
    XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
    renderer.setSeriesLinesVisible(0, true);
    renderer.setSeriesShapesVisible(0, false);
    renderer.setSeriesPaint(0, Color.RED);
    renderer.setSeriesLinesVisible(1, false);
    renderer.setSeriesShapesVisible(1, true);
    renderer.setSeriesShapesFilled(1, true);
    renderer.setSeriesPaint(1, Color.BLUE);
    for (int i = 2; i < fwhm.size() + 2; i++) {
        renderer.setSeriesLinesVisible(i, true);
        renderer.setSeriesShapesVisible(i, false);
        renderer.setSeriesPaint(i, Color.BLACK);
    }
    plot.setRenderer(renderer);
    //make panel
    ChartPanel panel = new ChartPanel(chart);
    panel.setPreferredSize(new Dimension(200, 200));
    panel.setFillZoomRectangle(true);
    panel.setMouseWheelEnabled(true);
    return panel;
}

From source file:org.moeaframework.analysis.plot.Plot.java

/**
 * Creates a new scatter plot series.  The series is added to the given
 * dataset, or if {@code null} a new dataset is created.
 * //from w  ww  .  j  ava  2  s  . co  m
 * @param label the label for the series
 * @param x the x values
 * @param y the y values
 * @param dataset the dataset, or {@code null} if a new dataset should be
 *        created
 * @return a reference to this {@code Plot} instance
 */
private Plot scatter(String label, List<? extends Number> x, List<? extends Number> y,
        XYSeriesCollection dataset) {
    if (dataset == null) {
        createXYPlot();
        currentDataset++;
        dataset = new XYSeriesCollection();
    }

    // generate the dataset
    XYSeries series = new XYSeries(label, false, true);

    for (int i = 0; i < x.size(); i++) {
        series.add(x.get(i), y.get(i));
    }

    dataset.addSeries(series);

    // add the dataset to the plot
    XYPlot plot = chart.getXYPlot();
    plot.setDataset(currentDataset, dataset);

    // setup the renderer
    Paint paint = paintHelper.get(dataset.getSeriesKey(0));
    XYDotRenderer renderer = new XYDotRenderer();

    renderer.setDotHeight(6);
    renderer.setDotWidth(6);
    renderer.setBasePaint(paint);
    renderer.setBaseFillPaint(paint);

    plot.setRenderer(currentDataset, renderer);

    return this;
}

From source file:org.moeaframework.analysis.plot.Plot.java

/**
 * Creates a new line plot series.  The series is added to the given
 * dataset, or if {@code null} a new dataset is created.
 * //from  ww w . j a  v a  2  s  .  c  o m
 * @param label the label for the series
 * @param x the x values
 * @param y the y values
 * @param dataset the dataset, or {@code null} if a new dataset should be
 *        created
 * @return a reference to this {@code Plot} instance
 */
private Plot line(String label, List<? extends Number> x, List<? extends Number> y,
        XYSeriesCollection dataset) {
    if (dataset == null) {
        createXYPlot();
        currentDataset++;
        dataset = new XYSeriesCollection();
    }

    // generate the dataset
    XYSeries series = new XYSeries(label, false, true);

    for (int i = 0; i < x.size(); i++) {
        series.add(x.get(i), y.get(i));
    }

    dataset.addSeries(series);

    // add the dataset to the plot
    XYPlot plot = chart.getXYPlot();
    plot.setDataset(currentDataset, dataset);

    // setup the renderer
    Paint paint = paintHelper.get(dataset.getSeriesKey(0));
    XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false);
    renderer.setAutoPopulateSeriesStroke(false);

    renderer.setBaseStroke(new BasicStroke(3f, 1, 1));
    renderer.setBasePaint(paint);
    renderer.setBaseFillPaint(paint);

    plot.setRenderer(currentDataset, renderer);

    return this;
}

From source file:org.moeaframework.analysis.plot.Plot.java

/**
 * Creates a new area plot series.  The series is added to the given
 * dataset, or if {@code null} a new dataset is created.
 * /*from  w w  w.  j  a v a 2 s .  c o m*/
 * @param label the label for the series
 * @param x the x values
 * @param y the y values
 * @param dataset the dataset, or {@code null} if a new dataset should be
 *        created
 * @return a reference to this {@code Plot} instance
 */
private Plot area(String label, List<? extends Number> x, List<? extends Number> y,
        XYSeriesCollection dataset) {
    if (dataset == null) {
        createXYPlot();
        currentDataset++;
        dataset = new XYSeriesCollection();
    }

    // generate the dataset
    XYSeries series = new XYSeries(label, false, true);

    for (int i = 0; i < x.size(); i++) {
        series.add(x.get(i), y.get(i));
    }

    dataset.addSeries(series);

    // add the dataset to the plot
    XYPlot plot = chart.getXYPlot();
    plot.setDataset(currentDataset, dataset);

    // setup the renderer
    Paint paint = paintHelper.get(dataset.getSeriesKey(0));
    XYAreaRenderer renderer = new XYAreaRenderer();
    renderer.setAutoPopulateSeriesStroke(false);

    renderer.setBaseStroke(new BasicStroke(3f, 1, 1));
    renderer.setBasePaint(paint);
    renderer.setBaseFillPaint(paint);

    plot.setRenderer(currentDataset, renderer);

    return this;
}

From source file:org.pentaho.platform.uifoundation.chart.XYSeriesCollectionChartComponent.java

@Override
public Document getXmlContent() {

    // Create a document that describes the result
    Document result = DocumentHelper.createDocument();
    IPentahoRequestContext requestContext = PentahoRequestContextHolder.getRequestContext();
    String contextPath = requestContext.getContextPath();

    setXslProperty("baseUrl", contextPath + "/"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    String mapName = "chart" + AbstractChartComponent.chartCount++; //$NON-NLS-1$
    Document chartDefinition = jcrHelper.getSolutionDocument(definitionPath, RepositoryFilePermission.READ);

    if (chartDefinition == null) {
        Element errorElement = result.addElement("error"); //$NON-NLS-1$
        errorElement.addElement("title").setText( //$NON-NLS-1$
                Messages.getInstance().getString("ABSTRACTCHARTEXPRESSION.ERROR_0001_ERROR_GENERATING_CHART")); //$NON-NLS-1$
        String message = Messages.getInstance().getString("CHARTS.ERROR_0001_CHART_DEFINIION_MISSING", //$NON-NLS-1$
                definitionPath);/*from   ww  w.  j  a  v  a  2s .c  o m*/
        errorElement.addElement("message").setText(message); //$NON-NLS-1$
        error(message);
        return result;
    }
    // create a pie definition from the XML definition
    dataDefinition = createChart(chartDefinition);

    if (dataDefinition == null) {
        Element errorElement = result.addElement("error"); //$NON-NLS-1$
        errorElement.addElement("title").setText( //$NON-NLS-1$
                Messages.getInstance().getString("ABSTRACTCHARTEXPRESSION.ERROR_0001_ERROR_GENERATING_CHART")); //$NON-NLS-1$
        String message = Messages.getInstance().getString("CHARTS.ERROR_0002_CHART_DATA_MISSING", actionPath); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        errorElement.addElement("message").setText(message); //$NON-NLS-1$
        // System .out.println( result.asXML() );
        return result;
    }

    // create an image for the dial using the JFreeChart engine
    PrintWriter printWriter = new PrintWriter(new StringWriter());
    // we'll dispay the title in HTML so that the dial image does not have
    // to
    // accommodate it
    String chartTitle = ""; //$NON-NLS-1$
    try {
        if (width == -1) {
            width = Integer.parseInt(chartDefinition.selectSingleNode("/chart/width").getText()); //$NON-NLS-1$
        }
        if (height == -1) {
            height = Integer.parseInt(chartDefinition.selectSingleNode("/chart/height").getText()); //$NON-NLS-1$
        }
    } catch (Exception e) {
        // go with the default
    }
    if (chartDefinition.selectSingleNode("/chart/" + AbstractChartComponent.URLTEMPLATE_NODE_NAME) != null) { //$NON-NLS-1$
        urlTemplate = chartDefinition.selectSingleNode("/chart/" + AbstractChartComponent.URLTEMPLATE_NODE_NAME) //$NON-NLS-1$
                .getText();
    }

    if (chartDefinition.selectSingleNode("/chart/paramName") != null) { //$NON-NLS-1$
        paramName = chartDefinition.selectSingleNode("/chart/paramName").getText(); //$NON-NLS-1$
    }

    Element root = result.addElement("charts"); //$NON-NLS-1$
    XYSeriesCollection chartDataDefinition = (XYSeriesCollection) dataDefinition;
    if (chartDataDefinition.getSeriesCount() > 0) {
        // create temporary file names
        String[] tempFileInfo = createTempFile();
        String fileName = tempFileInfo[AbstractChartComponent.FILENAME_INDEX];
        String filePathWithoutExtension = tempFileInfo[AbstractChartComponent.FILENAME_WITHOUT_EXTENSION_INDEX];

        ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());
        JFreeChartEngine.saveChart(chartDataDefinition, chartTitle, "", filePathWithoutExtension, width, height, //$NON-NLS-1$
                JFreeChartEngine.OUTPUT_PNG, printWriter, info, this);
        applyOuterURLTemplateParam();
        populateInfo(info);
        Element chartElement = root.addElement("chart"); //$NON-NLS-1$
        chartElement.addElement("mapName").setText(mapName); //$NON-NLS-1$
        chartElement.addElement("width").setText(Integer.toString(width)); //$NON-NLS-1$
        chartElement.addElement("height").setText(Integer.toString(height)); //$NON-NLS-1$
        for (int row = 0; row < chartDataDefinition.getSeriesCount(); row++) {
            for (int column = 0; column < chartDataDefinition.getItemCount(row); column++) {
                Number value = chartDataDefinition.getY(row, column);
                Comparable rowKey = chartDataDefinition.getSeriesKey(row);
                Number columnKey = chartDataDefinition.getX(row, column);
                Element valueElement = chartElement.addElement("value2D"); //$NON-NLS-1$
                valueElement.addElement("value").setText(value.toString()); //$NON-NLS-1$
                valueElement.addElement("row-key").setText(rowKey.toString()); //$NON-NLS-1$
                valueElement.addElement("column-key").setText(columnKey.toString()); //$NON-NLS-1$
            }
        }
        String mapString = ImageMapUtilities.getImageMap(mapName, info);
        chartElement.addElement("imageMap").setText(mapString); //$NON-NLS-1$
        chartElement.addElement("image").setText(fileName); //$NON-NLS-1$
    }
    return result;
}

From source file:iDynoOptimizer.MOEAFramework26.src.org.moeaframework.analysis.diagnostics.ApproximationSetPlot.java

@Override
protected void update() {
    XYSeriesCollection dataset = new XYSeriesCollection();

    for (ResultKey key : frame.getSelectedResults()) {
        NondominatedPopulation population = new EpsilonBoxDominanceArchive(EPSILON);

        for (Accumulator accumulator : controller.get(key)) {
            if (!accumulator.keySet().contains(metric)) {
                continue;
            }//from  www . ja v  a 2s. c om

            List<?> list = (List<?>) accumulator.get(metric, accumulator.size(metric) - 1);

            for (Object object : list) {
                population.add((Solution) object);
            }
        }

        if (!population.isEmpty()) {
            XYSeries series = new XYSeries(key, false, true);

            for (Solution solution : population) {
                if (solution.getNumberOfObjectives() == 1) {
                    series.add(solution.getObjective(0), solution.getObjective(0));
                } else if (solution.getNumberOfObjectives() > 1) {
                    series.add(solution.getObjective(0), solution.getObjective(1));
                }
            }

            dataset.addSeries(series);
        }
    }

    JFreeChart chart = ChartFactory.createScatterPlot(metric, localization.getString("text.objective", 1),
            localization.getString("text.objective", 2), dataset, PlotOrientation.VERTICAL, true, true, false);

    XYPlot plot = chart.getXYPlot();
    XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(false, true);

    for (int i = 0; i < dataset.getSeriesCount(); i++) {
        Paint paint = frame.getPaintHelper().get(dataset.getSeriesKey(i));

        renderer.setSeriesStroke(i, new BasicStroke(3f, 1, 1));
        renderer.setSeriesPaint(i, paint);
        renderer.setSeriesFillPaint(i, paint);
    }

    plot.setRenderer(renderer);

    //add overlay
    if (controller.getShowLastTrace() && (controller.getLastAccumulator() != null)
            && controller.getLastAccumulator().keySet().contains(metric)) {
        XYSeriesCollection dataset2 = new XYSeriesCollection();
        NondominatedPopulation population = new EpsilonBoxDominanceArchive(EPSILON);

        if (controller.getLastAccumulator().keySet().contains(metric)) {
            List<?> list = (List<?>) controller.getLastAccumulator().get(metric,
                    controller.getLastAccumulator().size(metric) - 1);

            for (Object object : list) {
                population.add((Solution) object);
            }
        }

        if (!population.isEmpty()) {
            XYSeries series = new XYSeries(localization.getString("text.last"), false, true);

            for (Solution solution : population) {
                series.add(solution.getObjective(0), solution.getObjective(1));
            }

            dataset2.addSeries(series);
        }

        XYLineAndShapeRenderer renderer2 = new XYLineAndShapeRenderer(false, true);
        renderer2.setSeriesPaint(0, Color.BLACK);

        plot.setDataset(1, dataset2);
        plot.setRenderer(1, renderer2);
        plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
    }

    removeAll();
    add(new ChartPanel(chart), BorderLayout.CENTER);
    revalidate();
    repaint();
}

From source file:iDynoOptimizer.MOEAFramework26.src.org.moeaframework.analysis.diagnostics.ApproximationSetViewer.java

/**
 * Updates the display.  This method must only be invoked on the event
 * dispatch thread./*from  w  w  w  .  j  av a  2s  . c om*/
 */
protected void update() {
    XYSeriesCollection dataset = new XYSeriesCollection();

    //generate approximation set
    for (int seedIndex : seedList.getSelectedIndices()) {
        Accumulator accumulator = accumulators.get(seedIndex);
        int index = 0;

        if (!accumulator.keySet().contains("Approximation Set")) {
            continue;
        }

        while ((index < accumulator.size("NFE") - 1)
                && ((Integer) accumulator.get("NFE", index) < slider.getValue())) {
            index++;
        }

        List<?> list = (List<?>) accumulator.get("Approximation Set", index);
        XYSeries series = new XYSeries(localization.getString("text.seed", seedIndex + 1), false, true);

        for (Object object : list) {
            Solution solution = (Solution) object;
            series.add(getValue(solution, 0), getValue(solution, 1));
        }

        dataset.addSeries(series);
    }

    //generate reference set
    if (referenceSet != null) {
        XYSeries series = new XYSeries(localization.getString("text.referenceSet"), false, true);

        for (Solution solution : referenceSet) {
            series.add(getValue(solution, 0), getValue(solution, 1));
        }

        dataset.addSeries(series);
    }

    JFreeChart chart = ChartFactory.createScatterPlot(getTitle() + " @ " + slider.getValue() + " NFE",
            (String) xAxisSelection.getSelectedItem(), (String) yAxisSelection.getSelectedItem(), dataset,
            PlotOrientation.VERTICAL, true, true, false);

    //set the renderer to only display shapes
    XYPlot plot = chart.getXYPlot();
    XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(false, true);

    for (int i = 0; i < dataset.getSeriesCount(); i++) {
        Paint paint = paintHelper.get(dataset.getSeriesKey(i));
        renderer.setSeriesPaint(i, paint);
    }

    plot.setRenderer(renderer);

    //set the zoom based on the user's preferences
    if ((initialRangeBounds == null) || (initialDomainBounds == null)) {
        initialRangeBounds = plot.getRangeAxis().getRange();
        initialDomainBounds = plot.getDomainAxis().getRange();
    }

    if (useInitialBounds.isSelected()) {
        plot.getRangeAxis().setRange(initialRangeBounds);
        plot.getDomainAxis().setRange(initialDomainBounds);
    } else if (useZoomBounds.isSelected()) {
        if ((zoomRangeBounds == null) || (zoomDomainBounds == null)) {
            zoomRangeBounds = initialRangeBounds;
            zoomDomainBounds = initialDomainBounds;
        }

        plot.getRangeAxis().setRange(zoomRangeBounds);
        plot.getDomainAxis().setRange(zoomDomainBounds);
    } else if (useReferenceSetBounds.isSelected()) {
        if (referenceRangeBounds.getLength() > 0.0) {
            plot.getRangeAxis().setRange(referenceRangeBounds);
        }

        if (referenceDomainBounds.getLength() > 0.0) {
            plot.getDomainAxis().setRange(referenceDomainBounds);
        }
    }

    //register with the chart to receive zoom events
    chart.addChangeListener(this);

    chartContainer.removeAll();
    chartContainer.add(new ChartPanel(chart), BorderLayout.CENTER);
    chartContainer.revalidate();
    chartContainer.repaint();
}

From source file:dbseer.gui.chart.DBSeerChartFactory.java

public static JFreeChart createXYLinePredictionChart(PredictionCenter center) throws Exception {
    StatisticalPackageRunner runner = DBSeerGUI.runner;

    String title = runner.getVariableString("title");
    Object[] legends = (Object[]) runner.getVariableCell("legends");
    Object[] xCellArray = (Object[]) runner.getVariableCell("Xdata");
    Object[] yCellArray = (Object[]) runner.getVariableCell("Ydata");
    String xLabel = runner.getVariableString("Xlabel");
    String yLabel = runner.getVariableString("Ylabel");

    XYSeriesCollection dataSet = new XYSeriesCollection();

    int numLegends = legends.length;
    int numXCellArray = xCellArray.length;
    int numYCellArray = yCellArray.length;
    int dataCount = 0;

    if (numXCellArray != numYCellArray) {
        JOptionPane.showMessageDialog(null, "The number of X dataset and Y dataset does not match.",
                "The number of X dataset and Y dataset does not match.", JOptionPane.ERROR_MESSAGE);
        System.out.println(numXCellArray + " : " + numYCellArray);
        return null;
    }// ww w  . j a va  2s  .co m

    final java.util.List<String> transactionNames = center.getTrainConfig().getDataset(0)
            .getTransactionTypeNames();
    for (int i = 0; i < numLegends; ++i) {
        String legend = (String) legends[i];
        for (int j = 0; j < transactionNames.size(); ++j) {
            if (legend.contains("Type " + (j + 1))) {
                legends[i] = legend.replace("Type " + (j + 1), transactionNames.get(j));
                break;
            }
        }
    }
    for (int j = 0; j < transactionNames.size(); ++j) {
        if (xLabel.contains("Type " + (j + 1))) {
            xLabel = xLabel.replace("Type " + (j + 1), transactionNames.get(j));
            break;
        }
    }
    for (int j = 0; j < transactionNames.size(); ++j) {
        if (yLabel.contains("Type " + (j + 1))) {
            yLabel = yLabel.replace("Type " + (j + 1), transactionNames.get(j));
            break;
        }
    }

    for (int i = 0; i < numYCellArray; ++i) {
        double[] xArray = (double[]) xCellArray[i];
        runner.eval("yArraySize = size(Ydata{" + (i + 1) + "});");
        runner.eval("yArray = Ydata{" + (i + 1) + "};");
        double[] yArraySize = runner.getVariableDouble("yArraySize");
        double[] yArray = runner.getVariableDouble("yArray");

        int xLength = xArray.length;
        int row = (int) yArraySize[0];
        int col = (int) yArraySize[1];

        for (int c = 0; c < col; ++c) {
            XYSeries series;
            int legendIdx = (dataCount >= numLegends) ? numLegends - 1 : dataCount;
            String legend = (String) legends[legendIdx];
            if (numLegends == 0) {
                series = new XYSeries("Data " + dataCount + 1);
            } else if (dataCount >= numLegends) {
                series = new XYSeries(legend + (dataCount + 1));
            } else {
                series = new XYSeries(legend);
            }

            for (int r = 0; r < row; ++r) {
                int xRow = (r >= xLength) ? xLength - 1 : r;
                double yValue = yArray[r + c * row];
                // remove negatives & NaN & infs.
                if (yValue < 0 || yValue == Double.NaN || yValue == Double.POSITIVE_INFINITY
                        || yValue == Double.NEGATIVE_INFINITY) {
                    yValue = 0.0;
                }
                series.add(xArray[xRow], yValue);
            }
            dataSet.addSeries(series);
            ++dataCount;
        }
    }

    JFreeChart chart = ChartFactory.createXYLineChart(title, xLabel, yLabel, dataSet);

    // change 'predicted' data to have dotted lines.
    BasicStroke dashStroke = toStroke(STYLE_DASH);
    BasicStroke dotStroke = toStroke(STYLE_DOT);
    BasicStroke lineStroke = toStroke(STYLE_LINE);
    for (int i = 0; i < dataSet.getSeriesCount(); ++i) {
        String legend = (String) dataSet.getSeriesKey(i);
        XYPlot plot = chart.getXYPlot();
        XYItemRenderer renderer = plot.getRenderer();
        if (legend.contains("predicted") || legend.contains("Predicted")) {
            renderer.setSeriesStroke(i, dotStroke);
        } else {
            renderer.setSeriesStroke(i, lineStroke);
        }
    }

    return chart;
}