用JfreeChart画散点图,查看JfreeChart的Demo,写的都挺复杂的,关键是Demo中把简单的事情复杂化了,比如展示的例子是一个正弦曲线什么的,让初次画散点图的我们摸不着头脑。关键是他们得到数据集搞得太过复杂,后来想明白了,不就是二维数组嘛。想通了这一点,一切问题都解决了,不过,对于我们项目的特殊要求,并不是只画几个点那么简单,还要加上区域范围与文字说明,在查看文档及自己摸索下,2天时间,终于搞定。下面分享一下成果,呵,还是有点成就感的。
首先,看画图的API,参数有:
ChartFactory.createScatterPlot(),其中,有一个xydataset,那么,我们先要知道这个xydataset是什么结构的,再看所需xydataset,散点图,也就是单独画出点,也就是一个二维数据了,x ,y坐标嘛!
那么,先做好准备工作,第一步,拿数据,这就不用啰嗦了,就是得到一个List也好,Set也行。
第二步,加载到数据集:
/** * * @param xydatalist * @param bloods * @return */ public static XYDataset createxydataset(List<PressureBean> xydatalist, String bloods) { DefaultXYDataset xydataset = new DefaultXYDataset(); int size = xydatalist.size(); double[][] datas = new double[2][size]; for (int i = 0; i < size; i++) { PressureBean pres = xydatalist.get(i); int sys = pres.getSyspress();//收缩压 int dia = pres.getDiapress();//舒张压 datas[0][i] = sys; datas[1][i] = dia; } xydataset.addSeries(bloods, datas); return xydataset; }
下一步,另外一个准备工作,画图方法:
public static JFreeChart createChart(XYDataset xydataset, String bloodcattile, String shou, String shu, String nobloodData, String bloods, String nomal, String fore, String one, String two, List<PressureBean> list, Log log) { // 有可能用户在后面的版本中故意输入不正常数值,但是为了保证图片画图的完整,这里先计算 // 用户血压值的最大值。 int maxpress = 160; int addmax = 20; if (list != null && list.size() > 0) { Iterator<PressureBean> it = list.iterator(); while (it.hasNext()) { PressureBean pres = it.next(); if (maxpress < pres.getDiapress()) { maxpress = pres.getDiapress(); } if (maxpress < pres.getSyspress()) { maxpress = pres.getSyspress(); } } maxpress += addmax; log.info("high press value is =" + maxpress); } JFreeChart jfreechart = ChartFactory.createScatterPlot(bloodcattile, shou, shu, xydataset, PlotOrientation.VERTICAL, true, false, false); jfreechart.setBackgroundPaint(Color.white); jfreechart.setBorderPaint(Color.GREEN); jfreechart.setBorderStroke(new BasicStroke(1.5f)); XYPlot xyplot = (XYPlot) jfreechart.getPlot(); xyplot.setNoDataMessage(nobloodData); xyplot.setNoDataMessageFont(new Font("", Font.BOLD, 14)); xyplot.setNoDataMessagePaint(new Color(87, 149, 117)); xyplot.setBackgroundPaint(new Color(255, 253, 246)); ValueAxis vaaxis = xyplot.getDomainAxis(); vaaxis.setAxisLineStroke(new BasicStroke(1.5f)); ValueAxis va = xyplot.getDomainAxis(0); va.setAxisLineStroke(new BasicStroke(1.5f)); va.setAxisLineStroke(new BasicStroke(1.5f)); // 坐标轴粗细 va.setAxisLinePaint(new Color(215, 215, 215)); // 坐标轴颜色 xyplot.setOutlineStroke(new BasicStroke(1.5f)); // 边框粗细 va.setLabelPaint(new Color(10, 10, 10)); // 坐标轴标题颜色 va.setTickLabelPaint(new Color(102, 102, 102)); // 坐标轴标尺值颜色 ValueAxis axis = xyplot.getRangeAxis(); axis.setAxisLineStroke(new BasicStroke(1.5f)); XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyplot .getRenderer(); xylineandshaperenderer.setSeriesOutlinePaint(0, Color.WHITE); xylineandshaperenderer.setUseOutlinePaint(true); NumberAxis numberaxis = (NumberAxis) xyplot.getDomainAxis(); numberaxis.setAutoRangeIncludesZero(false); numberaxis.setTickMarkInsideLength(2.0F); numberaxis.setTickMarkOutsideLength(0.0F); numberaxis.setAxisLineStroke(new BasicStroke(1.5f)); numberaxis.setUpperBound(maxpress); numberaxis.setLowerBound(60);//最小值设置为60 NumberAxis numberaxis1 = (NumberAxis) xyplot.getRangeAxis(); numberaxis1.setTickMarkInsideLength(2.0F); numberaxis1.setTickMarkOutsideLength(0.0F); numberaxis1.setUpperBound(105d); numberaxis1.setLowerBound(35); numberaxis1.setAxisLineStroke(new BasicStroke(1.5f)); // if (xydataset != null) { XYBoxAnnotation box = new XYBoxAnnotation(0, 0, 89, 59); //正常血压所在区域内边界 XYBoxAnnotation box1 = new XYBoxAnnotation(0, 0, 119, 79);//高血压前期所在区域内边界 XYBoxAnnotation box2 = new XYBoxAnnotation(0, 0, 139, 89);//高血压一期所在区域内边界 XYBoxAnnotation box3 = new XYBoxAnnotation(0, 0, 159, 99);//高血压二期所在区域内边界 XYTextAnnotation text1 = new XYTextAnnotation(nomal, 70, 62.5);//标识“正常” XYTextAnnotation text = new XYTextAnnotation(fore, 70, 82.5);//“高血压前期” XYTextAnnotation text2 = new XYTextAnnotation(one, 70, 91.5);//“高血压一期” XYTextAnnotation text3 = new XYTextAnnotation(two, 70, 101.5);//“高血压二期” //将上面的边界线条,说明文字加入到xyplot中。 xyplot.addAnnotation(box); xyplot.addAnnotation(box1); xyplot.addAnnotation(box2); xyplot.addAnnotation(box3); xyplot.addAnnotation(text); xyplot.addAnnotation(text1); xyplot.addAnnotation(text2); xyplot.addAnnotation(text3); // } return jfreechart; }
最后一步,返回图片URL
public static void drawScatterChart(IrisIoInterface io, Log log, XYDataset xydataSet, String title, String shou, String shu, String nodata, String boolds, String nomal, String fore, String one, String two, List<PressureBean> list) { JFreeChart chart = createChart(xydataSet, title, shou, shu, nodata, boolds, nomal, fore, one, two, list, log); HttpServletRequest request = io.getRequest(); String filename = ""; String graphURL = ""; try { filename = ServletUtilities.saveChartAsPNG(chart, 400, 300, null, io.getSession()); graphURL = request.getContextPath() + "/displayChart?filename=" + filename; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); log.error(e); } io.setData("filename", filename, BeanShare.BEAN_SHARE_REQUEST); io.setData("scatterurl", graphURL, BeanShare.BEAN_SHARE_REQUEST); }
效果图: