Table of contents
1. Module development - data preprocessing
(1) Create a Maven project and add related dependencies
(2) Create a JavaBean object and encapsulate logging
(3) Create a MapReduce program and perform data preprocessing
2. Module development - data warehouse development
3. Module development - data analysis
4. Module development - data export
5. Module development - log analysis system report display
1. Build a log analysis system
(1) Create a project and add related dependencies
2. Realize the report function display
(4) Realize the Controller layer
3. Display of system function modules
material:
1. Module development - data preprocessing
1. Analyze preprocessed data
In the collected log files, under normal circumstances, the log files cannot be directly analyzed for data, because there are many illegal data in the log files (for example, the log data is lost during network transmission).
In the data preprocessing stage, the main purpose is to clean and filter the collected raw data, so it can be easily realized by using MapReduce technology. In actual development, the data preprocessing process usually does not directly delete illegal data, but adds an identification field to each piece of data, so as to avoid data loss when used by other businesses.
In addition, this data preprocessing is only to clean and filter illegal data information. It will read each line of log file data and finally output a piece of data, and will not perform other operations. Therefore, in the process of processing using MapReduce technology, it will only involve The Map phase does not involve the Reduce phase. By default, the ReduceTask value is 1, so in the main running function, Job.setNumReduceTasks(0) needs to be set.
2. Realize data preprocessing
(1) Create a Maven project and add related dependencies
The pom.xml file is configured as follows:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itcast</groupId>
<artifactId>HadoopDataReport</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
</project>
(2) Create a JavaBean object and encapsulate logging
In the collected log data, each line represents a log record and contains multiple field information separated by spaces. To facilitate subsequent data processing, a JavaBean object is created to encapsulate each piece of data.
WebLogBean.java
package cn.itcast.weblog.bean;
import org.apache.hadoop.io.Writable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* 对接外部数据的层,表结构定义最好跟外部数据源保持一致
* 同时实现序列号,方便网络数据传播
*/
public class WebLogBean implements Writable {
private boolean valid = true; //标记数据是否合法
private String remote_addr; //访客IP地址
private String remote_user; //记录访客用户信息,忽略属性“-”
private String time_local; //记录访问时间与时区
private String request; //记录请求的URL
private String status; //请求状态
private String body_bytes_sent; //记录发送给客户端文件主体内容大小
private String http_referer; //记录从哪个页面链接访问过来的
private String http_user_agent; //记录客户浏览器的相关信息
//设置 WebLogBean 进行字段数据封装
public void setBean(boolean valid, String remote_addr, String remote_user,
String time_local, String request, String status,
String body_bytes_sent,
String http_referer, String http_user_agent) {
this.valid = valid;
this.remote_addr = remote_addr;
this.remote_user = remote_user;
this.time_local = time_local;
this.request = request;
this.status = status;
this.body_bytes_sent = body_bytes_sent;
this.http_referer = http_referer;
this.http_user_agent = http_user_agent;
}
public boolean isValid() {
return valid;
}
public void setValid(boolean valid) {
this.valid = valid;
}
public String getRemote_addr() {
return remote_addr;
}
public void setRemote_addr(String remote_addr) {
this.remote_addr = remote_addr;
}
public String getRemote_user() {
return remote_user;
}
public void setRemote_user(String remote_user) {
this.remote_user = remote_user;
}
public String getTime_local() {
return time_local;
}
public void setTime_local(String time_local) {
this.time_local = time_local;
}
public String getRequest() {
return request;
}
public void setRequest(String request) {
this.request = request;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getBody_bytes_sent() {
return body_bytes_sent;
}
public void setBody_bytes_sent(String body_bytes_sent) {
this.body_bytes_sent = body_bytes_sent;
}
public String getHttp_referer() {
return http_referer;
}
public void setHttp_referer(String http_referer) {
this.http_referer = http_referer;
}
public String getHttp_user_agent() {
return http_user_agent;
}
public void setHttp_user_agent(String http_user_agent) {
this.http_user_agent = http_user_agent;
}
//重写 toString() 方法,使用 Hive 默认分隔符进行分隔,为后续导入 Hive 表提供便利
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(valid);
sb.append("\001").append(this.getRemote_addr());
sb.append("\001").append(this.getRemote_user());
sb.append("\001").append(this.getTime_local());
sb.append("\001").append(this.getRequest());
sb.append("\001").append(this.getStatus());
sb.append("\001").append(this.getBody_bytes_sent());
sb.append("\001").append(this.getHttp_referer());
sb.append("\001").append(this.getHttp_user_agent());
return sb.toString();
}
//序列化方法
@Override
public void readFields(DataInput dataInput) throws IOException {
this.valid = dataInput.readBoolean();
this.remote_addr = dataInput.readUTF();
this.remote_user = dataInput.readUTF();
this.time_local = dataInput.readUTF();
this.request = dataInput.readUTF();
this.status = dataInput.readUTF();
this.body_bytes_sent = dataInput.readUTF();
this.http_referer = dataInput.readUTF();
this.http_user_agent = dataInput.readUTF();
}
// 反序列化方法(注意与序列化方法顺序保持一致)
@Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeBoolean(this.valid);
dataOutput.writeUTF(this.remote_addr);
dataOutput.writeUTF(this.remote_user);
dataOutput.writeUTF(this.time_local);
dataOutput.writeUTF(this.request);
dataOutput.writeUTF(this.status);
dataOutput.writeUTF(this.body_bytes_sent);
dataOutput.writeUTF(this.http_referer);
dataOutput.writeUTF(this.http_user_agent);
}
}
(3) Create a MapReduce program and perform data preprocessing
After creating the JavaBean entity class, the next step is to write the MapReduce program for data preprocessing.
WebLogPreProcess.java
package cn.itcast.weblog.preproces;
import cn.itcast.weblog.bean.WebLogBean;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
/**
* 日志数据处理:数据清洗、日期格式转换、缺失字段填充默认值、字段添加合法标记
*/
public class WebLogPreProcess {
public static void main(String[] args) throws Exception{
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(WebLogPreProcess.class);
job.setMapperClass(WebLogPreProcessMapper.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
//此次案例测试数据不是非常大,所以使用本地路径
//(实际情况会对 HDFS 上存储的文件进行处理)
FileInputFormat.setInputPaths(job, new Path("/home/huanganchi/Hadoop/实训项目/HadoopDemo/textHadoop/weblog/input"));
FileOutputFormat.setOutputPath(job, new Path("/home/huanganchi/Hadoop/实训项目/HadoopDemo/textHadoop/weblog/output"));
//将 ReduceTask 属设置为 0,不需要 Reduce 阶段
job.setNumReduceTasks(0);
boolean res = job.waitForCompletion(true);
System.exit(res ? 0 : 1);
}
//mapreduce 程序 map 阶段
public static class WebLogPreProcessMapper extends Mapper<LongWritable, Text, Text, NullWritable> {
//用来存储网站 URL 分类数据
Set<String> pages = new HashSet<String>();
Text k = new Text();
NullWritable v = NullWritable.get();
/**
* 设置初始化方法, 用来表示用户请求的是合法数据
*/
@Override
protected void setup(Context context) throws IOException, InterruptedException {
pages.add("/about");
pages.add("/black-ip-list");
pages.add("/cassendra-cluster/");
pages.add("/finance-rhive-repurchase");
pages.add("/hadoop-family-roadmad");
pages.add("/hadoop-hive-intro/");
pages.add("/hadoop-zookeeper-intro");
pages.add("/hadoop-mahout-roadmap");
}
/**
* 重写 map()方法,对每行记录重新解析转换并输出
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//获取一行数据
String line = value.toString();
//调用解析类 WebLogParser 解析日志数据,最后封装为 WebLogBean 对象
WebLogBean webLogBean = WebLogParser.parser(line);
if (webLogBean != null) {
//过滤 js/图片/css 等静态资源
WebLogParser.filtStaticResource(webLogBean, pages);
k.set(webLogBean.toString());
context.write(k, v);
}
}
}
}
WebLogParser.java
package cn.itcast.weblog.preproces;
import cn.itcast.weblog.bean.WebLogBean;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Set;
public class WebLogParser {
//定义时间格式
public static SimpleDateFormat df1 = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.US);
public static SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
/**
* 根据采集的数据字段信息进行解析封装
*/
public static WebLogBean parser(String line) {
WebLogBean webLogBean = new WebLogBean();
//把一行数据以空格字符切割并存入数组arr中
String[] arr = line.split(" ");
//如果数组长度小于等于11,说明这条数据不完整,因此可以忽略这条数据
if (arr.length > 11) {
//满足条件的数据逐个赋值给webLogBean对象
webLogBean.setRemote_addr(arr[0]);
webLogBean.setRemote_user(arr[1]);
String time_local = formatDate(arr[3].substring(1));
if (null == time_local || "".equals(time_local)) time_local = "-invalid_time-";
webLogBean.setTime_local(time_local);
webLogBean.setRequest(arr[6]);
webLogBean.setStatus(arr[8]);
webLogBean.setBody_bytes_sent(arr[9]);
webLogBean.setHttp_referer(arr[10]);
//如果useragent元素较多,拼接useragent
if (arr.length > 12) {
StringBuilder sb = new StringBuilder();
for (int i = 11; i < arr.length; i++) {
sb.append(arr[i]);
}
webLogBean.setHttp_user_agent(sb.toString());
} else {
webLogBean.setHttp_user_agent(arr[11]);
}
//大于 400,HTTP 错误
if (Integer.parseInt(webLogBean.getStatus()) >= 400) {
webLogBean.setValid(false);
}
if ("-invalid_time-".equals(webLogBean.getTime_local())) {
webLogBean.setValid(false);
}
} else {
webLogBean = null;
}
return webLogBean;
}
//对请求路径资源是否合法进行标记
public static void filtStaticResource(WebLogBean bean, Set<String> pages) {
if (!pages.contains(bean.getRequest())) {
bean.setValid(false);
}
}
//格式化时间方法
public static String formatDate(String time_local) {
try {
return df2.format(df1.parse(time_local));
} catch (ParseException e) {
return null;
}
}
}
operation result:
2. Module development - data warehouse development
1. Upload files
Create a directory weblog under the root directory of the Linux system where Hadoop is started, and upload the result files generated by the preprocessing to the weblog directory.
cd
mkdir weblog
cd weblog
执行 rz 文件上传命令
Create a directory on HDFS to store preprocessed data and upload the data to HDFS.
hadoop fs -mkdir -p /weblog/preprocessed
hadoop fs -put part-m-00000 /weblog/preprocessed
2. Realize the data warehouse
启动Hive数据仓库,执行以下操作:
--创建数据仓库
DROP DATABASE IF EXISTS weblog;
CREATE DATABASE weblog;
USE weblog;
--创建表
CREATE TABLE ods_weblog_origin (
valid string, --有效标志
remote_addr string, --来源IP
remote_user string, --用户标志
time_local string, --访问完整时间
request string, --请求的URL
status string, --响应码
body_bytes_sent string, --传输字节数
http_referer string, --来源URL
http_user_agent string --客户终端标志
)
partitioned by (datestr string)
row format delimited fields terminated by '\001';
--导入数据
load data inpath '/weblog/preprocessed' overwrite into table ods_weblog_origin partition(datestr='20130918');
--生成明细表
--1. 创建明细表 ods_weblog_detwail
CREATE TABLE ods_weblog_detwail (
valid string, --有效标志
remote_addr string, --来源IP
remote_user string, --用户标志
time_local string, --访问完整时间
daystr string, --访问日期
timestr string, --访问时间
month string, --访问月
day string, --访问日
hour string, --访问时
request string, --请求的URL
status string, --响应码
body_bytes_sent string, --传输字节数
http_referer string, --来源URL
ref_host string, --来源的host
ref_path string, --来源路径
ref_query string, --来源参数query
ref_query_id string, --来源参数query的值
http_user_agent string --客户终端标志
)
partitioned by (datestr string);
--2. 创建临时中间表 t_ods_tmp_referurl
CREATE TABLE t_ods_tmp_referurl as SELECT a.*, b.*
FROM ods_weblog_origin a LATERAL VIEW
parse_url_tuple(regexp_replace(http_referer, "\"", ""),'HOST', 'PATH', 'QUERY', 'QUERY:id') b
as host, path, query, query_id;
--3. 创建临时中间表 t_ods_tmp_detail
CREATE TABLE t_ods_tmp_detail as
SELECT b.*, substring(time_local, 0, 10) as daystr,
substring(time_local, 12) as tmstr,
substring(time_local, 6, 2) as month,
substring(time_local, 9, 2) as day,
substring(time_local, 11, 3) as hour
FROM t_ods_tmp_referurl b;
--4. 修改默认动态分区参数
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
--5. 向 ods_weblog_detwail 表中加载数据
insert overwrite table ods_weblog_detwail partition(datestr)
SELECT DISTINCT otd.valid, otd.remote_addr, otd.remote_user,
otd.time_local, otd.daystr, otd.tmstr, otd.month, otd.day, otd.hour,
otr.request, otr.status, otr.body_bytes_sent,
otr.http_referer, otr.host, otr.path,
otr.query, otr.query_id, otr.http_user_agent, otd.daystr
FROM t_ods_tmp_detail as otd, t_ods_tmp_referurl as otr
WHERE otd.remote_addr = otr.remote_addr
AND otd.time_local = otr.time_local
AND otd.body_bytes_sent = otr.body_bytes_sent
AND otd.request = otr.request;
3. Module development - data analysis
--数据分析
--流量分析
--创建每日访问量表dw_pvs_everyday
CREATE TABLE IF NOT EXISTS dw_pvs_everyday(pvs bigint, month string, day string);
--从宽表 ods_weblog_detwail 获取每日访问量数据并插入维度表 dw_pvs_everyday
INSERT INTO TABLE dw_pvs_everyday
SELECT COUNT(*) AS pvs, owd.month AS month, owd.day AS day
FROM ods_weblog_detwail owd GROUP BY owd.month, owd.day;
--人均浏览量分析
--创建维度表dw_avgpv_user_everyday
CREATE TABLE IF NOT EXISTS dw_avgpv_user_everyday (day string, avgpv string);
--从宽表 ods_weblog_detwail 获取相关数据并插入维度表 dw_avgpv_user_everyday
INSERT INTO TABLE dw_avgpv_user_everyday
SELECT '2013-09-18', SUM(b.pvs)/COUNT(b.remote_addr) FROM
(SELECT remote_addr, COUNT(1) AS pvs FROM ods_weblog_detwail WHERE
datestr = '2013-09-18' GROUP by remote_addr) b;
INSERT INTO TABLE dw_avgpv_user_everyday
SELECT '2013-09-19', SUM(b.pvs)/COUNT(b.remote_addr) FROM
(SELECT remote_addr, COUNT(1) AS pvs FROM ods_weblog_detwail WHERE
datestr = '2013-09-19' GROUP by remote_addr) b;
INSERT INTO TABLE dw_avgpv_user_everyday
SELECT '2013-09-20', SUM(b.pvs)/COUNT(b.remote_addr) FROM
(SELECT remote_addr, COUNT(1) AS pvs FROM ods_weblog_detwail WHERE
datestr = '2013-09-20' GROUP by remote_addr) b;
INSERT INTO TABLE dw_avgpv_user_everyday
SELECT '2013-09-21', SUM(b.pvs)/COUNT(b.remote_addr) FROM
(SELECT remote_addr, COUNT(1) AS pvs FROM ods_weblog_detwail WHERE
datestr = '2013-09-21' GROUP by remote_addr) b;
INSERT INTO TABLE dw_avgpv_user_everyday
SELECT '2013-09-22', SUM(b.pvs)/COUNT(b.remote_addr) FROM
(SELECT remote_addr, COUNT(1) AS pvs FROM ods_weblog_detwail WHERE
datestr = '2013-09-22' GROUP by remote_addr) b;
INSERT INTO TABLE dw_avgpv_user_everyday
SELECT '2013-09-23', SUM(b.pvs)/COUNT(b.remote_addr) FROM
(SELECT remote_addr, COUNT(1) AS pvs FROM ods_weblog_detwail WHERE
datestr = '2013-09-23' GROUP by remote_addr) b;
INSERT INTO TABLE dw_avgpv_user_everyday
SELECT '2013-09-24', SUM(b.pvs)/COUNT(b.remote_addr) FROM
(SELECT remote_addr, COUNT(1) AS pvs FROM ods_weblog_detwail WHERE
datestr = '2013-09-24' GROUP by remote_addr) b;
4. Module development - data export
1. 创建 MySql 数据库和表
--数据导出
--创建数据仓库
DROP DATABASE IF EXISTS sqoopdb;
CREATE DATABASE sqoopdb;
USE sqoopdb;
--创建表
CREATE TABLE t_avgpv_num (
dateStr VARCHAR(255) DEFAULT NULL,
avgPvNum DECIMAL(6,2) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
2. 执行数据导出命令
sqoop export \
--connect jdbc:mysql://hadoop01.bgd01:3306/sqoopdb \
--username root \
--password 123456 \
--table t_avgpv_num \
--columns "dateStr,avgPvNum" \
--fields-terminated-by '\001' \
--export-dir /user/hive/warehouse/weblog.db/dw_avgpv_user_everyday
5. Module development - log analysis system report display
1. Build a log analysis system
(1) Create a project and add related dependencies
Create a Maven project for the Java Web Framework
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itcast</groupId>
<artifactId>Weblog</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>1.2.15</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.2</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<port>8080</port>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
(2) Write configuration files
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<!-- 数据库连接池 -->
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:properties/db.properties" />
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>
<!-- 让spring管理sqlsessionfactory使用mybatis和spring整合包中的 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 加载mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
</bean>
<!-- 使用扫描包的形式来创建mapper代理对象 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.itcast.mapper" />
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 传播行为 -->
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 切面 -->
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* cn.itcast.service..*.*(..))" />
</aop:config>
<!-- 配置包扫描器,扫描所有带@Service注解的类 -->
<context:component-scan base-package="cn.itcast.service" />
</beans>
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.8.201:3306/sqoopdb?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 扫描指定包路径 使路径当中的@controller注解生效 -->
<context:component-scan base-package="cn.itcast.controller" />
<!-- mvc的注解驱动 -->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置资源映射 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/echarts/" mapping="/echarts/**"/>
<mvc:resources location="/assets/" mapping="/assets/**"/>
<mvc:resources location="/img/" mapping="/img/**"/>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Weblog</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置springmvc的前端控制器 -->
<servlet>
<servlet-name>data-report</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 拦截所有请求 jsp除外 -->
<servlet-mapping>
<servlet-name>data-report</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 全局错误页面 -->
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/404.jsp</location>
</error-page>
</web-app>
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
2. Realize the report function display
(1) Create a persistent class
TAvgpvNum.java
package cn.itcast.pojo;
import java.math.BigDecimal;
public class TAvgpvNum {
private String datestr;// 日期
private BigDecimal avgpvnum;// 平均PV数量
public String getDatestr() {
return datestr;
}
public void setDatestr(String datestr) {
this.datestr = datestr == null ? null : datestr.trim();
}
public BigDecimal getAvgpvnum() {
return avgpvnum;
}
public void setAvgpvnum(BigDecimal avgpvnum) {
this.avgpvnum = avgpvnum;
}
}
AvgToPageBean.java
package cn.itcast.pojo;
public class AvgToPageBean {
private String[] dates;
private double[] data;
public String[] getDates() {
return dates;
}
public void setDates(String[] dates) {
this.dates = dates;
}
public double[] getData() {
return data;
}
public void setData(double[] data) {
this.data = data;
}
}
(2) Realize the DAO layer
TAvgpvNumMapper.java
package cn.itcast.mapper;
import java.util.List;
import cn.itcast.pojo.TAvgpvNum;
public interface TAvgpvNumMapper {
public List<TAvgpvNum> selectByDate(String startDate, String endDate);
}
TAvgpvNumMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.itcast.mapper.TAvgpvNumMapper">
<select id="selectByDate" resultType="cn.itcast.pojo.TAvgpvNum"
parameterType="String">
select *
from t_avgpv_num
where dateStr between #{0} and #{1} order by dateStr asc;
</select>
</mapper>
(3) Realize the Service layer
AvgPvService.java
package cn.itcast.service;
public interface AvgPvService {
//根据日期查询数据
public String getAvgPvNumByDates(String startDate, String endDate);
}
AvgPvServiceImpl.java
package cn.itcast.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.itcast.mapper.TAvgpvNumMapper;
import cn.itcast.pojo.AvgToPageBean;
import cn.itcast.pojo.TAvgpvNum;
import cn.itcast.service.AvgPvService;
@Service
public class AvgPvServiceImpl implements AvgPvService {
@Autowired
private TAvgpvNumMapper mapper;
@Override
public String getAvgPvNumByDates(String startDate, String endDate) {
//调用查询方法
List<TAvgpvNum> lists = mapper.selectByDate(startDate, endDate);
// 数组大小
int size = 7;
//保存日期数据
String[] dates = new String[size];
//保存人均浏览页面数据
double[] datas = new double[size];
int i = 0;
for (TAvgpvNum tAvgpvNum : lists) {
dates[i] = tAvgpvNum.getDatestr();
datas[i] = tAvgpvNum.getAvgpvnum().doubleValue();
i++;
}
//定义AvgToPageBean对象,用于前台页面展示
AvgToPageBean bean = new AvgToPageBean();
bean.setDates(dates);
bean.setData(datas);
//Jackson提供的类,用于把对象转换成Json字符串
ObjectMapper om = new ObjectMapper();
String beanJson = null;
try {
beanJson = om.writeValueAsString(bean);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//返回Json格式的对象
return beanJson;
}
}
(4) Realize the Controller layer
IndexController.java
package cn.itcast.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.itcast.service.AvgPvService;
@Controller
public class IndexController {
@Autowired
private AvgPvService pvService;
@RequestMapping("/index")
public String showIndex() {
return "index";
}
@RequestMapping(value = "/avgPvNum", produces = "application/json;charset=UTF-8")
@ResponseBody
public String getChart() {
System.out.println("获取平均pv数据..");
String data = pvService.getAvgPvNumByDates("2013-09-18", "2013-09-24");
return data;
}
}
(5) Implement page functions
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- BEGIN META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="Olive Enterprise">
<!-- END META -->
<script src="/js/jquery-1.11.3.min.js"></script>
<script src="/js/echarts.min.js"></script>
<script src="/js/china.js"></script>
<!-- BEGIN SHORTCUT ICON -->
<link rel="shortcut icon" href="/img/favicon.ico">
<!-- END SHORTCUT ICON -->
<title>流量运营分析 - pinyougou®itcast全站数据平台</title>
<!-- BEGIN STYLESHEET-->
<link href="/css/bootstrap.min.css" rel="stylesheet">
<!-- BOOTSTRAP CSS -->
<link href="/css/bootstrap-reset.css" rel="stylesheet">
<!-- BOOTSTRAP CSS -->
<link href="/assets/font-awesome/css/font-awesome.css" rel="stylesheet">
<!-- FONT AWESOME ICON CSS -->
<link href="/css/style.css" rel="stylesheet">
<!-- THEME BASIC CSS -->
<link href="/css/style-responsive.css" rel="stylesheet">
<!-- THEME RESPONSIVE CSS -->
<link href="/assets/morris.js-0.4.3/morris.css" rel="stylesheet">
<!-- MORRIS CHART CSS -->
<!--dashboard calendar-->
<link href="/css/clndr.css" rel="stylesheet">
<!-- CALENDER CSS -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js">
</script>
<script src="js/respond.min.js">
</script>
<![endif]-->
<!-- END STYLESHEET-->
</head>
<body>
<!-- BEGIN SECTION -->
<section id="container">
<!-- BEGIN HEADER -->
<header class="header white-bg">
<!-- SIDEBAR TOGGLE BUTTON -->
<div class="sidebar-toggle-box">
<div data-placement="right" class="fa fa-bars tooltips"></div>
</div>
<!-- SIDEBAR TOGGLE BUTTON END-->
<a href="index.html" class="logo"> ITCAST <span> PINYOUGOU
</span><span> 全站流量运营分析 </span>
</a>
<!-- START HEADER NAV -->
<nav class="nav notify-row" id="top_menu">
<ul class="nav top-menu">
<!-- START NOTIFY TASK BAR -->
<li class="dropdown"><a data-toggle="dropdown"
class="dropdown-toggle" href="#"> <i class="fa fa-tasks">
</i> <span class="badge bg-success"> 6 </span>
</a>
<ul class="dropdown-menu extended tasks-bar">
<li class="notify-arrow notify-arrow-blue"></li>
<li>
<p class="blue">You have 6 pending tasks</p>
</li>
<li><a href="#">
<div class="task-info">
<div class="desc">Dashboard v1.3</div>
<div class="percent">40%</div>
</div>
<div class="progress progress-striped">
<div class="progress-bar progress-bar-success set-40"
role="progressbar" aria-valuenow="40" aria-valuemin="0"
aria-valuemax="100">
<span class="sr-only"> 40% Complete (success) </span>
</div>
</div>
</a></li>
<li><a href="#">
<div class="task-info">
<div class="desc">Database Update</div>
<div class="percent">60%</div>
</div>
<div class="progress progress-striped">
<div class="progress-bar progress-bar-warning set-60"
role="progressbar" aria-valuenow="60" aria-valuemin="0"
aria-valuemax="100">
<span class="sr-only"> 60% Complete (warning) </span>
</div>
</div>
</a></li>
<li><a href="#">
<div class="task-info">
<div class="desc">Iphone Development</div>
<div class="percent">87%</div>
</div>
<div class="progress progress-striped">
<div class="progress-bar progress-bar-info set-87"
role="progressbar" aria-valuenow="20" aria-valuemin="0"
aria-valuemax="100">
<span class="sr-only"> 87% Complete </span>
</div>
</div>
</a></li>
<li><a href="#">
<div class="task-info">
<div class="desc">Mobile App</div>
<div class="percent">33%</div>
</div>
<div class="progress progress-striped">
<div class="progress-bar progress-bar-danger set-33"
role="progressbar" aria-valuenow="80" aria-valuemin="0"
aria-valuemax="100">
<span class="sr-only"> 33% Complete (danger) </span>
</div>
</div>
</a></li>
<li><a href="#">
<div class="task-info">
<div class="desc">Dashboard v1.3</div>
<div class="percent">45%</div>
</div>
<div class="progress progress-striped active">
<div class="progress-bar set-45" role="progressbar"
aria-valuenow="45" aria-valuemin="0" aria-valuemax="100">
<span class="sr-only"> 45% Complete </span>
</div>
</div>
</a></li>
<li class="external"><a href="#"> See All Tasks </a></li>
</ul></li>
<!-- END NOTIFY TASK BAR -->
<!-- START NOTIFY INBOX BAR -->
<li id="header_inbox_bar" class="dropdown"><a
data-toggle="dropdown" class="dropdown-toggle" href="#"> <i
class="fa fa-envelope-o"> </i> <span class="badge bg-important">
5 </span>
</a>
<ul class="dropdown-menu extended inbox">
<li class="notify-arrow notify-arrow-blue"></li>
<li>
<p class="blue">You have 5 new messages</p>
</li>
<li><a href="#"> <span class="photo"> <img
alt="avatar" src="./img/avatar-mini.jpg">
</span> <span class="subject"> <span class="from">
Chintan Pandya </span> <span class="time"> Just now </span>
</span> <span class="message"> Hello, this is an example msg. </span>
</a></li>
<li><a href="#"> <span class="photo"> <img
alt="avatar" src="./img/avatar-mini2.jpg">
</span> <span class="subject"> <span class="from"> Parth
Jani </span> <span class="time"> 10 mins </span>
</span> <span class="message"> Hi, Bro how are you ? </span>
</a></li>
<li><a href="#"> <span class="photo"> <img
alt="avatar" src="./img/avatar-mini3.jpg">
</span> <span class="subject"> <span class="from"> Jay
Bardolia </span> <span class="time"> 3 hrs </span>
</span> <span class="message"> This is awesome dashboard. </span>
</a></li>
<li><a href="#"> <span class="photo"> <img
alt="avatar" src="./img/avatar-mini4.jpg">
</span> <span class="subject"> <span class="from"> ADMIN
BLACK </span> <span class="time"> Just now </span>
</span> <span class="message"> Hello, this is metrolab </span>
</a></li>
<li><a href="#"> See all messages </a></li>
</ul></li>
<!-- END NOTIFY INBOX BAR -->
<!-- START NOTIFY NOTIFICATION BAR -->
<li id="header_notification_bar" class="dropdown"><a
data-toggle="dropdown" class="dropdown-toggle" href="#"> <i
class="fa fa-bell-o"> </i> <span class="badge bg-warning">
7 </span>
</a>
<ul class="dropdown-menu extended notification">
<li class="notify-arrow notify-arrow-blue"></li>
<li>
<p class="blue">You have 7 new notifications</p>
</li>
<li><a href="#"> <span class="label label-danger">
<i class="fa fa-bolt"> </i>
</span> Server #3 overloaded. <span class="small italic"> 34
mins </span>
</a></li>
<li><a href="#"> <span class="label label-warning">
<i class="fa fa-bell"> </i>
</span> Server #10 not respoding. <span class="small italic"> 1
Hours </span>
</a></li>
<li><a href="#"> <span class="label label-danger">
<i class="fa fa-bolt"> </i>
</span> Database overloaded 24%. <span class="small italic"> 4
hrs </span>
</a></li>
<li><a href="#"> <span class="label label-success">
<i class="fa fa-plus"> </i>
</span> New user registered. <span class="small italic"> Just
now </span>
</a></li>
<li><a href="#"> <span class="label label-primary">
<i class="fa fa-bullhorn"> </i>
</span> Application error. <span class="small italic"> 10 mins </span>
</a></li>
<li><a href="#"> See all notifications </a></li>
</ul></li>
<!-- END NOTIFY NOTIFICATION BAR -->
</ul>
</nav>
<!-- END HEADER NAV -->
<!-- START USER LOGIN DROPDOWN -->
<div class="top-nav ">
<ul class="nav pull-right top-menu">
<li><input type="text" class="form-control search"
placeholder="Search"></li>
<li class="dropdown"><a data-toggle="dropdown"
class="dropdown-toggle" href="#"> <img alt=""
src="img/avatar1_small.jpg"> <span class="username">
ADMIN BLACK </span> <b class="caret"> </b>
</a>
<ul class="dropdown-menu extended logout">
<li class="log-arrow-up"></li>
<li><a href="#"> <i class=" fa fa-suitcase"> </i>
Profile
</a></li>
<li><a href="#"> <i class="fa fa-cog"> </i> Settings
</a></li>
<li><a href="#"> <i class="fa fa-bell-o"> </i>
Notification
</a></li>
<li><a href="login.html"> <i class="fa fa-key"> </i> Log
Out
</a></li>
</ul></li>
</ul>
</div>
<!-- END USER LOGIN DROPDOWN -->
</header>
<!-- END HEADER -->
<!-- BEGIN SIDEBAR -->
<aside>
<div id="sidebar" class="nav-collapse">
<ul class="sidebar-menu" id="nav-accordion">
<li><a href="index.html" class="active"> <i
class="fa fa-dashboard"> </i> <span> 流量概况 </span>
</a></li>
<li class="sub-menu"><a href="javascript:;"> <i
class="fa fa-book"> </i> <span> 流量分析 </span>
</a>
<ul class="sub">
<li><a href="flow-trend.html"> 趋势分析 </a></li>
<li><a href="flow-contract.html"> 对比分析 </a></li>
<li><a href="flow-online.html"> 当前在线 </a></li>
<li><a href="flow-detail.html"> 访问明细 </a></li>
</ul></li>
<li class="sub-menu"><a href="javascript:;"> <i
class="fa fa-th"> </i> <span> 来源分析 </span>
</a>
<ul class="sub">
<li><a href="#"> 来源分类 </a></li>
<li><a href="#"> 搜索引擎 </a></li>
<li><a href="#"> 搜索词 </a></li>
<li><a href="#"> 来路域名 </a></li>
<li><a href="#"> 来路页面 </a></li>
</ul></li>
<li class="sub-menu"><a href="javascript:;"> <i
class="fa fa-book"> </i> <span> 受访分析 </span>
</a>
<ul class="sub">
<li><a href="#"> 受访分析 </a></li>
<li><a href="#"> 受访域名 </a></li>
<li><a href="#"> 受访页面 </a></li>
<li><a href="#"> 受访升降榜 </a></li>
<li><a href="#"> 热点图 </a></li>
</ul></li>
<li class="sub-menu"><a href="javascript:;"> <i
class="fa fa-th"> </i> <span> 访客分析 </span>
</a>
<ul class="sub">
<li><a href="basic_table.html"> 地区/运营商 </a></li>
<li><a href="responsive_table.html">终端详情 </a></li>
<li><a href="dynamic_table.html"> 新老访客</a></li>
<li><a href="advanced_table.html"> 忠诚度 </a></li>
<li><a href="editable_table.html"> 活跃度 </a></li>
</ul></li>
</ul>
</div>
</aside>
<!-- END SIDEBAR -->
<!-- BEGIN MAIN CONTENT -->
<section id="main-content">
<!-- BEGIN WRAPPER -->
<section class="wrapper">
<!-- 流量概况表 开始 -->
<div class="row">
<div class="col-lg-12 col-sm-12">
<section class="panel">
<div class="panel-body">
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div>
<span><h3>流量信息概况</h3></span>
</div>
<div id="trendtable" style="width: 90%;">
<table id='pv_table' class="table table-bordered" margin=auto>
<thead style='font-weight: bold'>
<tr>
<td>日期</td>
<td>浏览次数(PV)</td>
<td>独立访客(UV)</td>
<td>IP</td>
<td>新独立访客</td>
<td>访问次数</td>
</tr>
</thead>
<tbody>
<tr>
<td>1001</td>
<td>4702</td>
<td>3096</td>
<td>2880</td>
<td>2506</td>
<td>3773</td>
</tr>
<tr>
<td>1002</td>
<td>7528</td>
<td>4860</td>
<td>4435</td>
<td>4209</td>
<td>5975</td>
</tr>
<tr>
<td>1003</td>
<td>7286</td>
<td>4741</td>
<td>4409</td>
<td>4026</td>
<td>5817</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
</div>
</div>
<!-- 流量概况表 结束-->
<!-- BEGIN ROW 最近7天日平均PV量-->
<div class="row">
<div class="col-lg-6 col-sm-6">
<section class="panel">
<div class="panel-body">
<div id="main1" style="width: 100%; height: 400px;"></div>
<script type="text/javascript">
$(document)
.ready(
function() {
var myChart = echarts
.init(document
.getElementById('main1'));
// 显示标题,图例和空的坐标轴
myChart
.setOption({
title : {
text : '最近7天日平均PV量',
subtext : '动态数据'
},
tooltip : {},
legend : {
data : [ '日平均PV量' ]
},
xAxis : {
data : []
},
yAxis : {},
series : [ {
name : '日平均PV量',
type : 'bar',
data : []
} ]
});
//loading 动画
myChart.showLoading();
// 异步加载数据
$.get('http://localhost:8080/avgPvNum').done(function(data) {
//填入数据
myChart.setOption({
xAxis : {
data : data.dates
},
series : [ {
// 根据名字对应到相应的系列
name : 'PV量',
data : data.data
} ]
});
//数据加载完成后再调用 hideLoading 方法隐藏加载动画
myChart.hideLoading();
});
});
</script>
</div>
</section>
</div>
<div class="col-lg-6 col-sm-6">
<section class="panel">
<div class="panel-body">
<div id="main2" style="width: 600px; height: 400px;"
align="center"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document
.getElementById('main2'));
myChart
.setOption({
series : [ {
name : '访问来源',
type : 'pie',
radius : '55%',
data : [ {
value : 235,
name : '视频广告'
}, {
value : 274,
name : '联盟广告'
}, {
value : 310,
name : '邮件营销'
}, {
value : 335,
name : '直接访问'
}, {
value : 400,
name : '搜索引擎'
} ]
} ],
itemStyle : {
normal : {
// 阴影的大小
shadowBlur : 200,
// 阴影水平方向上的偏移
shadowOffsetX : 0,
// 阴影垂直方向上的偏移
shadowOffsetY : 0,
// 阴影颜色
shadowColor : 'rgba(0, 0, 0, 0.5)'
}
}
})
</script>
</div>
</section>
</div>
</div>
<!-- END ROW -->
<!-- 折线图 row 开始 -->
<div class="row">
<div class="col-lg-12 col-sm-12">
<section class="panel">
<div class="panel-body">
<div id="main3" style="width: 100%; height: 500px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart3 = echarts.init(document
.getElementById('main3'));
option = {
title : {
text : '访客来源地区分布图',
subtext : '模拟数据',
x : 'center'
},
tooltip : {
trigger : 'item'
},
legend : {
orient : 'vertical',
x : 'left',
data : [ '访客UV' ]
},
dataRange : {
min : 0,
max : 2500,
x : 'left',
y : 'bottom',
text : [ '高', '低' ], // 文本,默认为数值文本
calculable : true
},
toolbox : {
show : true,
orient : 'vertical',
x : 'right',
y : 'center',
feature : {
mark : {
show : true
},
dataView : {
show : true,
readOnly : false
},
restore : {
show : true
},
saveAsImage : {
show : true
}
}
},
roamController : {
show : true,
x : 'right',
mapTypeControl : {
'china' : true
}
},
series : [
{
name : '访客UV',
type : 'map',
mapType : 'china',
roam : false,
itemStyle : {
normal : {
label : {
show : true
}
},
emphasis : {
label : {
show : true
}
}
},
data : [
{
name : '北京',
value : Math
.round(Math
.random() * 1000)
},
{
name : '天津',
value : Math
.round(Math
.random() * 1000)
},
{
name : '上海',
value : Math
.round(Math
.random() * 1000)
},
{
name : '重庆',
value : Math
.round(Math
.random() * 1000)
},
{
name : '河北',
value : Math
.round(Math
.random() * 1000)
},
{
name : '河南',
value : Math
.round(Math
.random() * 1000)
},
{
name : '云南',
value : Math
.round(Math
.random() * 1000)
},
{
name : '辽宁',
value : Math
.round(Math
.random() * 1000)
},
{
name : '黑龙江',
value : Math
.round(Math
.random() * 1000)
},
{
name : '湖南',
value : Math
.round(Math
.random() * 1000)
},
{
name : '安徽',
value : Math
.round(Math
.random() * 1000)
},
{
name : '山东',
value : Math
.round(Math
.random() * 1000)
},
{
name : '新疆',
value : Math
.round(Math
.random() * 1000)
},
{
name : '江苏',
value : Math
.round(Math
.random() * 1000)
},
{
name : '浙江',
value : Math
.round(Math
.random() * 1000)
},
{
name : '江西',
value : Math
.round(Math
.random() * 1000)
},
{
name : '湖北',
value : Math
.round(Math
.random() * 1000)
},
{
name : '广西',
value : Math
.round(Math
.random() * 1000)
},
{
name : '甘肃',
value : Math
.round(Math
.random() * 1000)
},
{
name : '山西',
value : Math
.round(Math
.random() * 1000)
},
{
name : '内蒙古',
value : Math
.round(Math
.random() * 1000)
},
{
name : '陕西',
value : Math
.round(Math
.random() * 1000)
},
{
name : '吉林',
value : Math
.round(Math
.random() * 1000)
},
{
name : '福建',
value : Math
.round(Math
.random() * 1000)
},
{
name : '贵州',
value : Math
.round(Math
.random() * 1000)
},
{
name : '广东',
value : Math
.round(Math
.random() * 1000)
},
{
name : '青海',
value : Math
.round(Math
.random() * 1000)
},
{
name : '西藏',
value : Math
.round(Math
.random() * 1000)
},
{
name : '四川',
value : Math
.round(Math
.random() * 1000)
},
{
name : '宁夏',
value : Math
.round(Math
.random() * 1000)
},
{
name : '海南',
value : Math
.round(Math
.random() * 1000)
},
{
name : '台湾',
value : Math
.round(Math
.random() * 1000)
},
{
name : '香港',
value : Math
.round(Math
.random() * 1000)
},
{
name : '澳门',
value : Math
.round(Math
.random() * 1000)
} ]
},
]
};
myChart3.setOption(option);
</script>
</div>
</section>
</div>
</div>
<!-- 折线图 row 结束 -->
<!-- 动态加载数据示例 开始-->
<div class="row">
<div class="col-lg-12 col-sm-12">
<section class="panel">
<div class="panel-body">
<div id="main4" style="width: 100%; height: 400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart4 = echarts.init(document
.getElementById('main4'));
// 指定图表的配置项和数据
option = {
title : {
text : '近一周访客数量变化趋势',
subtext : '动态数据'
},
tooltip : {
trigger : 'axis'
},
legend : {
data : [ '独立访客', '新独立访客' ]
},
toolbox : {
show : true,
feature : {
mark : {
show : true
},
dataView : {
show : true,
readOnly : false
},
magicType : {
show : true,
type : [ 'line', 'bar' ]
},
restore : {
show : true
},
saveAsImage : {
show : true
}
}
},
calculable : true,
xAxis : [ {
type : 'category',
boundaryGap : false,
data : []
} ],
yAxis : [ {
type : 'value',
axisLabel : {
formatter : '{value} 人'
}
} ],
series : [ {
name : '独立访客',
type : 'line',
data : [],
markPoint : {
data : [ {
type : 'max',
name : '最大值'
}, {
type : 'min',
name : '最小值'
} ]
},
markLine : {
data : [ {
type : 'average',
name : '平均值'
} ]
}
}, {
name : '新独立访客',
type : 'line',
data : [],
markPoint : {
data : [ {
type : 'max',
name : '最大值'
}, {
type : 'min',
name : '最小值'
} ]
},
markLine : {
data : [ {
type : 'average',
name : '平均值'
} ]
}
} ]
};
// 使用刚指定的配置项和数据显示图表。
myChart4.setOption(option);
myChart4.showLoading();
// 异步加载数据
$.get('http://localhost:8080/flowNum')
.done(function(data) {
// 填入数据
myChart4.setOption({
xAxis : {
data : data.dates
},
series : [ {
name : '独立访客',
data : data.uvs
}, {
name : '新独立访客',
data : data.new_uvs
} ]
});
myChart4.hideLoading();
});
</script>
</div>
</section>
</div>
</div>
<!-- 动态加载数据示例 结束-->
<!-- BEGIN ROW -->
<div class="row">
<div class="col-lg-6">
<div class="panel">
<div class="panel-body">
<footer class="project-category">
<ul>
<li class="active">
<h5>Project 1</h5>
<div id="work-progress6"></div>
</li>
<li>
<h5>Project 2</h5>
<div id="work-progress7"></div>
</li>
<li>
<h5>Project 3</h5>
<div id="work-progress8"></div>
</li>
</ul>
<h1>Projects accomplished</h1>
</footer>
<!-- END FOOTER -->
</div>
</div>
</div>
<div class="col-lg-6">
<div class="panel">
<div class="panel-body">
<div class="bio-chart">
<input class="knob" data-width="100" data-height="100"
data-displayPrevious=true data-thickness=".2" value="78"
data-fgColor="#f9a3a3" data-bgColor="#e8e8e8">
<h4 class="red">Profit</h4>
</div>
<div class="bio-chart">
<input class="knob" data-width="100" data-height="100"
data-displayPrevious=true data-thickness=".2" value="63"
data-fgColor="#fcce54" data-bgColor="#e8e8e8">
<h4 class="yellow">Expansion</h4>
</div>
</div>
</div>
</div>
</div>
<!-- END ROW -->
</section>
<!-- END WRAPPER -->
</section>
<!-- END MAIN CONTENT -->
<!-- BEGIN FOOTER -->
<footer class="site-footer">
<div class="text-center">
2017 © PINYOUGOU by <a href="" target="_blank">
www.itcast.cn </a> <a href="http://www.itcast.cn" class="go-top"> <i
class="fa fa-angle-up"> </i>
</a>
</div>
</footer>
<!-- END FOOTER -->
</section>
<!-- END SECTION -->
<!-- BEGIN JS -->
<!-- BASIC JQUERY 1.8.3 LIB. JS -->
<script src="js/bootstrap.min.js"></script>
<!-- BOOTSTRAP JS -->
<script src="js/jquery.dcjqaccordion.2.7.js"></script>
<!-- ACCORDIN JS -->
<script src="js/jquery.scrollTo.min.js"></script>
<!-- SCROLLTO JS -->
<script src="js/jquery.nicescroll.js"></script>
<!-- NICESCROLL JS -->
<script src="js/respond.min.js"></script>
<!-- RESPOND JS -->
<script src="js/jquery.sparkline.js"></script>
<!-- SPARKLINE JS -->
<script src="js/sparkline-chart.js"></script>
<!-- SPARKLINE CHART JS -->
<script src="js/common-scripts.js"></script>
<!-- BASIC COMMON JS -->
<script src="js/count.js"></script>
<!-- COUNT JS -->
<!--Morris-->
<script src="assets/morris.js-0.4.3/morris.min.js"></script>
<!-- MORRIS JS -->
<script src="assets/morris.js-0.4.3/raphael-min.js"></script>
<!-- MORRIS JS -->
<script src="js/chart.js"></script>
<!-- CHART JS -->
<!--Calendar-->
<script src="js/calendar/clndr.js"></script>
<!-- CALENDER JS -->
<script src="js/calendar/evnt.calendar.init.js"></script>
<!-- CALENDER EVENT JS -->
<script src="js/calendar/moment-2.2.1.js"></script>
<!-- CALENDER MOMENT JS -->
<!-- <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script> -->
<!-- UNDERSCORE JS -->
<script src="assets/jquery-knob/js/jquery.knob.js"></script>
<!-- JQUERY KNOB JS -->
<script>
//knob
$(".knob").knob();
</script>
<!-- END JS -->
</body>
</html>
3. Display of system function modules
Reference books:
"Hadoop big data technology principle and application"