JFreeChart与AJAX+JSON+ECharts两种处理方式生成热词统计可视化图表

来源:互联网 发布:yy网络直播间 编辑:程序博客网 时间:2024/05/18 02:09

本篇的思想:对HDFS获取的数据进行两种不同的可视化图表处理方式。第一种JFreeChar可视化处理生成图片文件查看。第二种AJAX+JSON+ECharts实现可视化图表,并呈现于浏览器上。

        对此,给出代码示例,通过网络爬虫技术,将上传到HDFS的新浪网新闻信息实现热词统计功能,通过图表的柱状图来显示出来。

------>

目录:

1、JFreeChart可视化处理(生成本地图片)

  【1】HDFS文件读取

  【2】JDFreeChart库应用

2、AJAX+JSON+EChart生成可视化图表(网页呈现图表)

  【1】EChart基本方法

  【2】JSON数据格式

  【3】AJAX技术

  【4】热词统计示例

3、总结

------>

1、JFreeChart可视化处理

【1】HDFS文件读取

保存时,我们数据使用了两种方式保存:

1) 纯文本方式:适合整体读取数据,并按行将内容读取出来处理。

2) MapFileFormat的方式:适合按key来查找value

 

这里可以使用FSDataInputStream来直接读入文本方式的数据。

代码呈现:

 1 public class TestReadData { 2  3     public static void main(String[] args) throws Exception { 4         Configuration conf = new Configuration(); 5         FileSystem fs = null; 6         Path path = new Path("hdfs://localhost:9000/output/part-00000"); 7         fs = path.getFileSystem(conf); 8         FSDataInputStream is = fs.open(path); 9         // 使用一个缓冲流或者内存流来整体读入数据10         BufferedReader br = new BufferedReader(new InputStreamReader(is));11         String line = null;12         while ((line = br.readLine()) != null) {13             String[] strs = line.split("\t");14             System.out.println(strs[0] + " --> " + strs[1]);15         }16     }17 }

 

下面我们想从这些词里提取出出现频率最高的10个词。

这里就需要使用插入排序的方法来完成。

因此我们这里编写一个工具类,来帮助我们完成排序功能。

同时,为了方便进行对象的保存和传递,建议编写一个vo类来保存关键字和出现次数。

 

代码呈现:

 1 public class MyKeyValue { 2  3     private String key; 4     private Integer value; 5  6     public MyKeyValue() { 7     } 8  9     public MyKeyValue(String key, Integer value) {10         this.key = key;11         this.value = value;12     }13 14     public String getKey() {15         return key;16     }17 18     public void setKey(String key) {19         this.key = key;20     }21 22     public Integer getValue() {23         return value;24     }25 26     public void setValue(Integer value) {27         this.value = value;28     }29 30     public int compare(MyKeyValue other) {31         if (this.value >= other.value) {32             return 1;33         } else {34             return -1;35         }36     }37 }

 

此时需要修改TestReadData类,添加vo对象,以及排除一些热词:

 

 1 public class TestReadData { 2  3     private static Set<String> allNoKeyword = new HashSet<>(); 4  5     static { 6         allNoKeyword.add("新闻"); 7         allNoKeyword.add("新浪网"); 8         allNoKeyword.add("新浪"); 9         allNoKeyword.add("聚合");10         allNoKeyword.add("中国");11         allNoKeyword.add("视频");12         allNoKeyword.add("图片");13         allNoKeyword.add("图集");14         allNoKeyword.add("最新");15         allNoKeyword.add("阅读");16     }17 18     public static void main(String[] args) throws Exception {19         Configuration conf = new Configuration();20         FileSystem fs = null;21         Path path = new Path("hdfs://localhost:9000/output/part-00000");22         fs = path.getFileSystem(conf);23         FSDataInputStream is = fs.open(path);24         // 使用一个缓冲流或者内存流来整体读入数据25         BufferedReader br = new BufferedReader(new InputStreamReader(is));26         String line = null;27         // 建立工具类28         ValueSortList list = new ValueSortList();29         while ((line = br.readLine()) != null) {30             String[] strs = line.split("\t");31             // 建立vo对象32             if (!allNoKeyword.contains(strs[0]) && strs[0].length() > 1) {33                 MyKeyValue keyValue = new MyKeyValue(strs[0],34                         Integer.parseInt(strs[1]));35                 list.add(keyValue);36             }37         }38 39         System.out.println(list);40     }41 }

 

【2】JFreeChart库应用

 

JFreeChart是由Java提供的免费不开源的数据可视化的库。

 

首先将支持包加入到项目中。

之后可以通过以下固定的步骤,来根据数据,生成图表。

1) 创建数据集合

2) 向集合中添加数据

3) 建立图表对象(根据需要选择不同的图表)

4) 设置图表的参数

5) 将图表输出

 

饼状图(这里还支持环状和3D效果):

 1 public class PieDemo { 2         3     public static void main(String[] args) throws Exception { 4         // 数据集 5         DefaultPieDataset dataset = new DefaultPieDataset(); 6  7         // 添加数据 8         ValueSortList list = TestReadData.getValues(); 9 10         for (MyKeyValue keyValue : list.getList()) {11             dataset.setValue(keyValue.getKey(), keyValue.getValue());12         }13 14         // 创建对象15         JFreeChart chart = ChartFactory.createPieChart("新浪新闻热词分析", dataset,16                 true, true, false);17 18         // 设置属性19 20         // 输出21         ChartUtilities.saveChartAsPNG(new File("E:/pie.png"), chart, 500, 500);22 23     }24 25 }

柱状图和线型图:(还支持线、3D柱、3D线、区域)

 1 public class BarDemo { 2  3     public static void main(String[] args) throws Exception { 4         DefaultCategoryDataset dataset = new DefaultCategoryDataset(); 5  6         ValueSortList list = TestReadData.getValues(); 7  8         for (MyKeyValue keyValue : list.getList()) { 9             dataset.addValue(keyValue.getValue(), keyValue.getKey(), "");10         }11 12         JFreeChart chart = ChartFactory.createBarChart("热词分析", "词", "次数",13                 dataset, PlotOrientation.VERTICAL, true, true, false);14 15         ChartUtilities.saveChartAsPNG(new File("E:/bar.png"), chart, 1000, 500);16 17     }18 }

 

 

 

2、AJAX+JSON+ECharts生成可视化图表

【1】ECharts基本使用

 

ECharts最早是有一些开源的工程师来开发的免费使用的图表工具,在 12版本时都是放在github上。之后ECharts被百度投资收购,加入了百度的开源产品中。

如果想使用ECharts这种的开源工具,必须先去其官网下载开发包。

 

下载时,建议将完整版和开发版都下载下来,开发版用于开发时进行调试,完整版用于上线提升性能。

 

下面就需要了解怎样完成一个简单的ECharts图表(此也为官网给出的代码示例)。

 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>Document</title> 6     <script type="text/javascript" src="echarts.js"></script> 7     <script type="text/javascript"> 8         function initChart() { 9             // 初始化要显示的图标div10             var myChart = echarts.init(document.getElementById('my_chart'));11             var option = {12                 title: {13                     text: 'ECharts 入门示例'14                 },15                 tooltip: {16                     trigger:"axis",17                     label:"销量"18                 },19                 legend: {20                     data:['销量','价格']21                 },22                 xAxis: {23                     data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]24                 },25                 yAxis: {},26                 series: [{27                     name: '销量',28                     type: 'bar',29                     data: [5, 20, 36, 10, 10, 20]30                 },{31                     name: '价格',32                     type: 'line',33                     data: [30, 40, 32, 15, 80, 30]34                 }]35             };36 37             myChart.setOption(option);38         }39 40     </script>41 </head>42 <body onload="initChart();">43     44     <div  style="width:600px;height:400px;"></div>45 46 </body>47 </html>

 

【2】JSON数据格式

JSONJavaScript Object Notation,是ECMAScript的标准语法

这个语法是现在所有AJAX或者说数据传输的最常用的语法格式。

使用该语法的原因是语法格式简单,没有关键字来干扰或者占用内存。

解析时各种语言都有很容易的解析方法。

特别是JavaScript,可以直接通过自带的eval()方法来完成字符串转换对象或数组的操作。

 

JSON语法很简单:

1) 对象:{}

  a) 属性:属性名:属性值,多个属性之间逗号分隔

  b) 方法:方法名:function(){}

2) 数组:[]

  a) 每个元素使用逗号分隔。

 

【3】AJAX技术

AJAXAsynchronous JavaScript And Xml,异步的JavaScriptXML,不是新技术,是基于JSXML技术的应用,但是现在XML一般都被JSON替代了,所以实际上AJAX已经变成了纯JS的技术了。

通过AJAX技术,可以在页面不刷新的情况下,让前端沟通后台来获取数据,数据通过JSON格式来返回进行处理。

这样前后台分离就更彻底了,后台只需要专注于后台接口的开发即可,通过接口返回JSON数据。

前台则是接收了返回的数据后,根据数据完成各种页面效果的展示。

 

AJAX技术已经很成熟了,通过固定的4个步骤就可以沟通后台接收结果。

1、 建立核心配置对象XMLHttpRequest

2、 建立与后台的连接

3、 设置返回时的回调函数

当后台执行完结果返回数据时,前台必须有个方法可以接收这个数据,并进行处理,这个方法就是回调函数(Callback

 

【4】热词统计生成可视化图表

基于ECharts,我们来把热词统计功能,通过这个ECharts图表的柱状图来显示出来。

 1         var xmlHttp ; 2          3         function createXMLHttp() { 4             if (window.XMLHttpRequest != null) { 5                 xmlHttp = new XMLHttpRequest(); 6             } else { 7                 xmlHttp = new ActiveXObject("Microsoft.xmlhttp"); 8             } 9         }10     11         function initChart() {12             // 初始化要显示的图标div13             var myChart = echarts.init(document.getElementById('my_chart'));14             15             // 这里就需要通过AJAX技术,来调用后台数据操作,接收返回的JSON格式数据16             // 117             createXMLHttp();18             // 219             xmlHttp.open("get","<%=basePath%>ajax.do");20             // 321             xmlHttp.onreadystatechange = chartCallback;22             // 423             xmlHttp.send();24         }25         26         function chartCallback() {27             28         }

 

 之后,需要在后台的ajax.do中进行HDFS的操作,将需要的数据取得,并通过JSON的格式来返回页面。

    @RequestMapping(value = "/ajax.do")    public void ajax(HttpServletRequest request, HttpServletResponse response)            throws Exception {        // 读取HDFS中的文本数据        ValueSortList list = HDFSUtils.getValues();        StringBuilder builder = new StringBuilder(                "{ title: {text: '新浪新闻热词分析'},tooltip: {trigger:'axis'},");        builder.append("legend: {data:['词频']},xAxis: {data: [");        StringBuilder tempSeries = new StringBuilder();        tempSeries.append("series: [{name:'词频',type:'bar',data:[");        for (MyKeyValue kv : list.getList()) {            builder.append("'");            builder.append(kv.getKey());            builder.append("',");            tempSeries.append(kv.getValue());            tempSeries.append(",");        }        // 需要把最后一段截取掉        String resultStr = builder.substring(0, builder.length() - 1)                + "]}, yAxis: {},";        resultStr += tempSeries.substring(0, tempSeries.length() - 1) + "]}]}";        // 结果返回需要通过PrintWriter来输出        // 需要先处理返回乱码        response.setCharacterEncoding("UTF-8");        response.setContentType("text/html");        PrintWriter writer = response.getWriter();        writer.print(resultStr);        writer.close();    }

 

之后编写页面回调函数就可以显示图表了。

1         function chartCallback() {2             // 判断结果是否真正返回3             if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {4                 var resultStr = xmlHttp.responseText;5                 // 转换为对象6                 var option = eval("("+resultStr+")");7                 myChart.setOption(option);8             }9         }

 

但是我们会发现,拼写JSON字符串太麻烦了,因此实际开发中会有很多java用的json数据处理的库,可以帮助我们简单的拼写出json字符串

例如:org.json

 1     @RequestMapping(value = "/ajax.do") 2     public void ajax(HttpServletRequest request, HttpServletResponse response) 3             throws Exception { 4         // 读取HDFS中的文本数据 5         ValueSortList list = HDFSUtils.getValues(); 6  7         JSONObject obj = new JSONObject(); 8          9 10         JSONObject titleObj = new JSONObject();11         titleObj.put("text", "新浪新闻热词分析");12         obj.put("title", titleObj);13 14         JSONObject tooltipsObj = new JSONObject();15         tooltipsObj.put("trigger", "axis");16         obj.put("tooltip", tooltipsObj);17 18         JSONObject legendObj = new JSONObject();19         legendObj.put("data", "词频");20         obj.put("legend", legendObj);21 22         obj.put("yAxis", new JSONObject());23 24         JSONObject xObj = new JSONObject();25         JSONArray seArr = new JSONArray();26         JSONObject seObj = new JSONObject();27         seObj.put("name", "词频");28         seObj.put("type", "bar");29         JSONArray xDataArr = new JSONArray();30         JSONArray seDataArr = new JSONArray();31 32         for (MyKeyValue kv : list.getList()) {33             xDataArr.put(kv.getKey());34             seDataArr.put(kv.getValue());35         }36 37         xObj.put("data", xDataArr);38         seObj.put("data", seDataArr);39         seArr.put(seObj);40 41         obj.put("xAxis", xObj);42         obj.put("series", seArr);43 44         // 结果返回需要通过PrintWriter来输出45         // 需要先处理返回乱码46         response.setCharacterEncoding("UTF-8");47         response.setContentType("text/html");48         PrintWriter writer = response.getWriter();49         writer.print(obj.toString());50         writer.close();51     }

 

对于这种热词分析,前台最好的展示方式应该是文字云,因此我们这里直接使用文字云的插件来完成。

首先也要导入js文件。

 1 <script type="text/javascript" src="echarts/echarts.js"></script> 2 <script type="text/javascript" src="echarts/echarts-wordcloud.js"></script> 3 <script type="text/javascript"> 4         var xmlHttp ; 5          6         var myChart ; 7          8         var option ; 9         10         function createXMLHttp() {11             if (window.XMLHttpRequest != null) {12                 xmlHttp = new XMLHttpRequest();13             } else {14                 xmlHttp = new ActiveXObject("Microsoft.xmlhttp");15             }16         }17     18         function initChart() {19             // 初始化要显示的图标div20             myChart = echarts.init(document.getElementById('my_chart'));21             22             option = {23                     tooltip: {},24                     series: [{25                         type: 'wordCloud',26                         gridSize: 2,27                         sizeRange: [12, 50],28                         rotationRange: [-90, 90],29                         shape: 'pentagon',30                         width: 600,31                         height: 400,32                         drawOutOfBound: true,33                         textStyle: {34                             normal: {35                                 color: function () {36                                     return 'rgb(' + [37                                         Math.round(Math.random() * 160),38                                         Math.round(Math.random() * 160),39                                         Math.round(Math.random() * 160)40                                     ].join(',') + ')';41                                 }42                             },43                             emphasis: {44                                 shadowBlur: 10,45                                 shadowColor: '#333'46                             }47                         }48                     }]49             };50             51             // 这里就需要通过AJAX技术,来调用后台数据操作,接收返回的JSON格式数据52             // 153             createXMLHttp();54             // 255             xmlHttp.open("get","<%=basePath%>ajax_cloud.do");56             // 357             xmlHttp.onreadystatechange = chartCallback;58             // 459             xmlHttp.send();60         }61 这里为了简化后台拼写JSON,将固定的内容提前设置到option对象中。

 

之后在后台完成数据的拼写。

 1     @RequestMapping(value="/ajax_cloud.do") 2     public void ajaxCloud(HttpServletRequest request, 3             HttpServletResponse response) throws Exception { 4         ValueSortList list = HDFSUtils.getValues(); 5  6         JSONArray array = new JSONArray(); 7         for (MyKeyValue kv : list.getList()) { 8             JSONObject obj = new JSONObject(); 9             obj.put("name", kv.getKey());10             obj.put("value", kv.getValue());11             array.put(obj);12         }13         14         response.setCharacterEncoding("UTF-8");15         response.setContentType("text/html");16         PrintWriter writer = response.getWriter();17         writer.print(array.toString());18         writer.close();19     }

 

最后在回调函数中进行设置处理。

1         function chartCallback() {2             // 判断结果是否真正返回3             if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {4                 var resultStr = xmlHttp.responseText;5                 // 转换为对象6                 option.series[0].data = eval("("+resultStr+")");7                 myChart.setOption(option);8             }9         }

 

 

结果呈现(柱状图):

 总结:

  从前面阐述的网络爬虫、HDFS数据读取、MR数据分析、Lucene垂直搜索引擎,到现在的可视化图表呈现,一个简单的大数据处理框架也渐浮水面。

     1、数据获取数据记录

     2、提取清洁数据标注

     3、整合聚集数据表达

     4、建立模型数据分析

     5、合理解释可视化

   虽然并不如真正的大数据处理的数据量之大、之复杂,可视化的程度也仅限于热词统计,不过既然授之以渔,而且也算是对此有了一个基本的了解了。

  关于本篇给出的两种可视化处理方法,其实还有很多方式。我只阐述了EFreeChart和ECharts两种方式,一种生成本地图片文件类型,一种结合AJAX+JSON可以在网页上呈现可视化图表。不过见解很浅薄,仅借本文能够让未知的读者实现一个简单的图表展现方式,给内功深厚的高手淡然一笑,我也就心满意足了。

   

 

原创粉丝点击