如何使用JFreeChart制作具有平滑线条(曲线)的散点图

时间:2014-02-27 07:20:39

标签: java servlets jfreechart

我试过这个link

但我得的是直线,而不是流畅的线条

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment; filename="
            + fileName + ".pdf");
    ZipFile zipfile = new ZipFile(filePath);
    ZipEntry zipentry;
    InputStream inputstream = null;
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        ArrayList<ArrayList<String>> gpggaExcel = new ArrayList<ArrayList<String>>();
        addList.gpggaList(gpggaExcel);

        XYSeriesCollection dataset = new XYSeriesCollection();

        final XYSeries data = new XYSeries("Latitude and Longitude", false);
        dataset.addSeries(data);

        for (Enumeration<? extends ZipEntry> e = zipfile.entries(); e
                .hasMoreElements(); fileNumber++) {
            zipentry = e.nextElement();
            inputstream = zipfile.getInputStream(zipentry);
            InputStreamReader isr = new InputStreamReader(inputstream);
            BufferedReader br = new BufferedReader(isr);
            String strLine;
            while ((strLine = br.readLine()) != null) {
                String nstrLine = strLine.substring(12);
                String[] splitStr = null;
                if (nstrLine.contains("$")) {
                    splitStr = nstrLine.split("\\$|!");
                    for (int i = 0; i < splitStr.length; i++) {
                        if (splitStr[i].contains("GPGGA")) {
                            String strGPGGA = splitStr[i];
                            gpggaExcel.add(decodeGPGGA(data, strGPGGA));
                        } 
                    }
                }
            }
        }
        drawScatterPlot(dataset);
        FileInputStream fis = new FileInputStream(fileName);
        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(response.getOutputStream());
        int b;
        while ((b = bis.read()) != -1) {
            bos.write(b);
        }
        bos.flush();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (inputstream != null) {
                inputstream.close();
            }
            if (bos != null)
                bos.close();
            if (bis != null)
                bis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private ArrayList<String> decodeGPGGA(XYSeries data, String strGPGGA)
        throws IOException {
    String[] gpggastrArr = strGPGGA.split(",");
    String tokens[] = new String[gpggastrArr.length];
    for (int i = 0; i < gpggastrArr.length; i++) {
        tokens[i] = gpggastrArr[i];
    }
    latitude = tokens[2];
    longitude = tokens[4];

    // Calculating latitude and longitude in degrees
    double dlattemp = Double.valueOf(latitude) / 100.0;
    double dlat = dlattemp + (Double.valueOf(latitude) - dlattemp * 100)
            / 60.0;
    double dlontemp = Double.valueOf(longitude) / 100.0;
    double dlon = dlontemp + (Double.valueOf(longitude) - dlontemp * 100)
            / 60.0;
    gpggarowData.add(latitude);
    gpggarowData.add(longitude);
    addSeriesData(data, dlat, dlon);
    return gpggarowData;
}

private void addSeriesData(XYSeries data, double dlat, double dlon) {
    data.add(dlat, dlon);
}

private void drawScatterPlot(XYDataset dataset) {

    final JFreeChart chart = ChartFactory.createScatterPlot(
            "Latitude vs Longitude", // chart
            // title
            "Latitude", // x axis label
            "Longitude", // y axis label
            dataset, // data
            PlotOrientation.VERTICAL, true, // include legend
            true, // tooltips
            false // urls
            );
    final XYPlot plot = (XYPlot) chart.getPlot();

    plot.setDomainGridlinesVisible(false);
    plot.setRangeGridlinesVisible(false);
    plot.setBackgroundPaint(new Color(255, 255, 255, 0));
    plot.setAxisOffset(new RectangleInsets(0, 0, 0, 0));
    plot.setOutlineVisible(false);
    XYLineAndShapeRenderer renderer = new XYSplineRenderer();
    for (int i = 0; i < chart.getXYPlot().getRendererCount(); i++) {
        plot.setRenderer(i, renderer);
    }
    plot.setRenderer(renderer);

    Number maximum = DatasetUtilities.findMaximumRangeValue(dataset);
    ValueMarker max = new ValueMarker(maximum.floatValue());
    max.setPaint(Color.green);
    max.setLabel("Highest Value");
    max.setLabelTextAnchor(TextAnchor.CENTER_LEFT);
    plot.addRangeMarker(max, Layer.BACKGROUND);

    // write the chart to a PDF file...
    saveChartAsPDF(fileName, chart, 400, 300, new DefaultFontMapper());

}

public void saveChartAsPDF(String fileName, JFreeChart chart, int width,
        int height, FontMapper mapper) {
    OutputStream out = null;
    try {
        out = new BufferedOutputStream(new FileOutputStream(fileName));
        writeChartAsPDF(out, chart, width, height, mapper);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private void writeChartAsPDF(OutputStream out, JFreeChart chart, int width,
        int height, FontMapper mapper) {
    Rectangle pagesize = new Rectangle(width, height);
    Document document = new Document(pagesize, 50, 50, 50, 50);
    try {
        PdfWriter writer = PdfWriter.getInstance(document, out);
        document.addAuthor("Praveensai");
        document.addSubject("VDR Plot");
        document.open();
        PdfContentByte cb = writer.getDirectContent();
        PdfTemplate tp = cb.createTemplate(width, height);
        @SuppressWarnings("deprecation")
        Graphics2D g2 = tp.createGraphics(width, height, mapper);
        Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height);
        chart.draw(g2, r2D);
        g2.dispose();
        cb.addTemplate(tp, 0, 0);
    } catch (DocumentException de) {
        de.printStackTrace();
    } finally {
        document.close();
    }
}

Output of the scattered plot 在Adance中感谢

1 个答案:

答案 0 :(得分:0)

不要将渲染器设置在两个不同的行上。 使用XYSplineRenderer代替XYLineAndShapeRenderer

XYLineAndShapeRenderer renderer = new XYSplineRenderer();
plot.setRenderer(renderer);

请注意plot.setRenderer(renderer)方法调用setRenderer(0, renderer),如果您打算使用多个渲染器,则必须为所有索引设置样条线渲染器:

XYLineAndShapeRenderer renderer = new XYSplineRenderer();
for (int i = 0; i < chart.getXYPlot().getRendererCount(); i++) {
    plot.setRenderer(i, renderer);
}
plot.setRenderer(renderer);

更新:

我对您的代码进行了一些更改。

我的想法是在添加项目之前对项目进行排序,试试这个:

List<XYDataItem> items = new LinkedList<XYDataItem>();
for (Enumeration<? extends ZipEntry> e = zipfile.entries(); e .hasMoreElements(); fileNumber++) {
   zipentry = e.nextElement();
   inputstream = zipfile.getInputStream(zipentry);
   InputStreamReader isr = new InputStreamReader(inputstream);
   BufferedReader br = new BufferedReader(isr);
   String strLine;
   while ((strLine = br.readLine()) != null) {
      String nstrLine = strLine.substring(12);
      String[] splitStr = null;
      if (nstrLine.contains("$")) {
         splitStr = nstrLine.split("\\$|!");
         for (String aSplitStr : splitStr) {
            if (aSplitStr.contains("GPGGA")) {
               XYDataItem item = decodeGPGGA(aSplitStr);
               items.add(item);
            }
         }
      }
   }
}
Collections.sort(items);
for (XYDataItem item : items) {
   data.add(item);
}

一个新的decodeGPPGA:

private XYDataItem decodeGPGGA(String strGPGGA)
      throws IOException {
   String[] tokens = strGPGGA.split(",");
   String latitude = tokens[2].trim();
   String longitude = tokens[4].trim();

   // Calculating latitude and longitude in degrees
   double dlattemp = Double.parseDouble(latitude) / 100.0;
   double dlat = dlattemp + (Double.parseDouble(latitude) - dlattemp * 100) / 60.0;

   double dlontemp = Double.parseDouble(longitude) / 100.0;
   double dlon = dlontemp + (Double.parseDouble(longitude) - dlontemp * 100) / 60.0;

   return new XYDataItem(dlat, dlon);
}