Java 如何使用JFreeChart绘制平滑线(曲线)的散点图

Java 如何使用JFreeChart绘制平滑线(曲线)的散点图,java,servlets,jfreechart,Java,Servlets,Jfreechart,我试过这个 但我得到的是直线,而不是平滑的直线 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachme

我试过这个

但我得到的是直线,而不是平滑的直线

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();
    }
}
public void doGet(HttpServletRequest请求,HttpServletResponse响应)
抛出ServletException、IOException{
response.setContentType(“application/pdf”);
setHeader(“内容处置”、“附件;文件名=”
+文件名+“.pdf”);
ZipFile ZipFile=新ZipFile(文件路径);
齐彭特里;
InputStream InputStream=null;
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
试一试{
ArrayList gpggaExcel=新的ArrayList();
addList.gpggaList(gpggaExcel);
XYSeriesCollection数据集=新的XYSeriesCollection();
最终XYSeries数据=新的XYSeries(“纬度和经度”,false);
dataset.addSeries(数据);

对于(枚举不要在两条不同的线上设置渲染器。 使用
xysplinederer
代替
xylineandshaperender

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);

我已经按照您所说的进行了更新,但是得到了相同的输出。您似乎添加了一些错误的数据。您可以显示用于填充数据集的代码吗?我更新了答案以反映这一点。我没有看到
列表
的用途,因此我让该方法返回一个
XYDataItem
。我不知道这是否有帮助,但请尝试一下。
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);
}
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);
}