JFreeChart最佳实践:散点图

用JfreeChart画散点图,查看JfreeChart的Demo,写的都挺复杂的,关键是Demo中把简单的事情复杂化了,比如展示的例子是一个正弦曲线什么的,让初次画散点图的我们摸不着头脑。关键是他们得到数据集搞得太过复杂,后来想明白了,不就是二维数组嘛。想通了这一点,一切问题都解决了,不过,对于我们项目的特殊要求,并不是只画几个点那么简单,还要加上区域范围与文字说明,在查看文档及自己摸索下,2天时间,终于搞定。下面分享一下成果,呵,还是有点成就感的。

首先,看画图的API,参数有:

ChartFactory.createScatterPlot(),其中,有一个xydataset,那么,我们先要知道这个xydataset是什么结构的,再看所需xydataset,散点图,也就是单独画出点,也就是一个二维数据了,x ,y坐标嘛!

那么,先做好准备工作,第一步,拿数据,这就不用啰嗦了,就是得到一个List也好,Set也行。

第二步,加载到数据集:

 
 
  1. /**
  2. *
  3. *@paramxydatalist
  4. *@parambloods
  5. *@return
  6. */
  7. publicstaticXYDatasetcreatexydataset(List<PressureBean>xydatalist,
  8. Stringbloods){
  9. DefaultXYDatasetxydataset=newDefaultXYDataset();
  10. intsize=xydatalist.size();
  11. double[][]datas=newdouble[2][size];
  12. for(inti=0;i<size;i++){
  13. PressureBeanpres=xydatalist.get(i);
  14. intsys=pres.getSyspress();//收缩压
  15. intdia=pres.getDiapress();//舒张压
  16. datas[0][i]=sys;
  17. datas[1][i]=dia;
  18. }
  19. xydataset.addSeries(bloods,datas);
  20. returnxydataset;
  21. }

下一步,另外一个准备工作,画图方法:

 
 
  1. publicstaticJFreeChartcreateChart(XYDatasetxydataset,
  2. Stringbloodcattile,Stringshou,Stringshu,StringnobloodData,
  3. Stringbloods,Stringnomal,Stringfore,Stringone,Stringtwo,
  4. List<PressureBean>list,Loglog){
  5. //有可能用户在后面的版本中故意输入不正常数值,但是为了保证图片画图的完整,这里先计算
  6. //用户血压值的最大值。
  7. intmaxpress=160;
  8. intaddmax=20;
  9. if(list!=null&&list.size()>0){
  10. Iterator<PressureBean>it=list.iterator();
  11. while(it.hasNext()){
  12. PressureBeanpres=it.next();
  13. if(maxpress<pres.getDiapress()){
  14. maxpress=pres.getDiapress();
  15. }
  16. if(maxpress<pres.getSyspress()){
  17. maxpress=pres.getSyspress();
  18. }
  19. }
  20. maxpress+=addmax;
  21. log.info("highpressvalueis="+maxpress);
  22. }
  23. JFreeChartjfreechart=ChartFactory.createScatterPlot(bloodcattile,
  24. shou,shu,xydataset,PlotOrientation.VERTICAL,true,false,
  25. false);
  26. jfreechart.setBackgroundPaint(Color.white);
  27. jfreechart.setBorderPaint(Color.GREEN);
  28. jfreechart.setBorderStroke(newBasicStroke(1.5f));
  29. XYPlotxyplot=(XYPlot)jfreechart.getPlot();
  30. xyplot.setNoDataMessage(nobloodData);
  31. xyplot.setNoDataMessageFont(newFont("",Font.BOLD,14));
  32. xyplot.setNoDataMessagePaint(newColor(87,149,117));
  33. xyplot.setBackgroundPaint(newColor(255,253,246));
  34. ValueAxisvaaxis=xyplot.getDomainAxis();
  35. vaaxis.setAxisLineStroke(newBasicStroke(1.5f));
  36. ValueAxisva=xyplot.getDomainAxis(0);
  37. va.setAxisLineStroke(newBasicStroke(1.5f));
  38. va.setAxisLineStroke(newBasicStroke(1.5f));//坐标轴粗细
  39. va.setAxisLinePaint(newColor(215,215,215));//坐标轴颜色
  40. xyplot.setOutlineStroke(newBasicStroke(1.5f));//边框粗细
  41. va.setLabelPaint(newColor(10,10,10));//坐标轴标题颜色
  42. va.setTickLabelPaint(newColor(102,102,102));//坐标轴标尺值颜色
  43. ValueAxisaxis=xyplot.getRangeAxis();
  44. axis.setAxisLineStroke(newBasicStroke(1.5f));
  45. XYLineAndShapeRendererxylineandshaperenderer=(XYLineAndShapeRenderer)xyplot
  46. .getRenderer();
  47. xylineandshaperenderer.setSeriesOutlinePaint(0,Color.WHITE);
  48. xylineandshaperenderer.setUseOutlinePaint(true);
  49. NumberAxisnumberaxis=(NumberAxis)xyplot.getDomainAxis();
  50. numberaxis.setAutoRangeIncludesZero(false);
  51. numberaxis.setTickMarkInsideLength(2.0F);
  52. numberaxis.setTickMarkOutsideLength(0.0F);
  53. numberaxis.setAxisLineStroke(newBasicStroke(1.5f));
  54. numberaxis.setUpperBound(maxpress);
  55. numberaxis.setLowerBound(60);//最小值设置为60
  56. NumberAxisnumberaxis1=(NumberAxis)xyplot.getRangeAxis();
  57. numberaxis1.setTickMarkInsideLength(2.0F);
  58. numberaxis1.setTickMarkOutsideLength(0.0F);
  59. numberaxis1.setUpperBound(105d);
  60. numberaxis1.setLowerBound(35);
  61. numberaxis1.setAxisLineStroke(newBasicStroke(1.5f));
  62. //if(xydataset!=null){
  63. XYBoxAnnotationbox=newXYBoxAnnotation(0,0,89,59);//正常血压所在区域内边界
  64. XYBoxAnnotationbox1=newXYBoxAnnotation(0,0,119,79);//高血压前期所在区域内边界
  65. XYBoxAnnotationbox2=newXYBoxAnnotation(0,0,139,89);//高血压一期所在区域内边界
  66. XYBoxAnnotationbox3=newXYBoxAnnotation(0,0,159,99);//高血压二期所在区域内边界
  67. XYTextAnnotationtext1=newXYTextAnnotation(nomal,70,62.5);//标识“正常”
  68. XYTextAnnotationtext=newXYTextAnnotation(fore,70,82.5);//“高血压前期”
  69. XYTextAnnotationtext2=newXYTextAnnotation(one,70,91.5);//“高血压一期”
  70. XYTextAnnotationtext3=newXYTextAnnotation(two,70,101.5);//“高血压二期”
  71. //将上面的边界线条,说明文字加入到xyplot中。
  72. xyplot.addAnnotation(box);
  73. xyplot.addAnnotation(box1);
  74. xyplot.addAnnotation(box2);
  75. xyplot.addAnnotation(box3);
  76. xyplot.addAnnotation(text);
  77. xyplot.addAnnotation(text1);
  78. xyplot.addAnnotation(text2);
  79. xyplot.addAnnotation(text3);
  80. //}
  81. returnjfreechart;
  82. }

最后一步,返回图片URL

 
 
  1. publicstaticvoiddrawScatterChart(IrisIoInterfaceio,Loglog,
  2. XYDatasetxydataSet,Stringtitle,Stringshou,Stringshu,
  3. Stringnodata,Stringboolds,Stringnomal,Stringfore,
  4. Stringone,Stringtwo,List<PressureBean>list){
  5. JFreeChartchart=createChart(xydataSet,title,shou,shu,nodata,
  6. boolds,nomal,fore,one,two,list,log);
  7. HttpServletRequestrequest=io.getRequest();
  8. Stringfilename="";
  9. StringgraphURL="";
  10. try{
  11. filename=ServletUtilities.saveChartAsPNG(chart,400,300,null,
  12. io.getSession());
  13. graphURL=request.getContextPath()+"/displayChart?filename="
  14. +filename;
  15. }catch(IOExceptione){
  16. //TODOAuto-generatedcatchblock
  17. e.printStackTrace();
  18. log.error(e);
  19. }
  20. io.setData("filename",filename,BeanShare.BEAN_SHARE_REQUEST);
  21. io.setData("scatterurl",graphURL,BeanShare.BEAN_SHARE_REQUEST);
  22. }

效果图:

原文链接:http://juliana-only.iteye.com/blog/544104