From 4c411e1ea7221ff92b438c4039e1431d2add611c Mon Sep 17 00:00:00 2001
From: lz <18519020056@139.com>
Date: Wed, 17 Jan 2018 23:13:11 +0800
Subject: [PATCH] message
---
TrustStudy.iml | 88 +
pom.xml | 410 +
.../java/trust/controller/TestController.java | 45 +
src/main/java/trust/entity/CountHelper.java | 35 +
src/main/java/trust/entity/Record.java | 55 +
src/main/java/trust/entity/Result.java | 26 +
src/main/java/trust/entity/Ser.java | 89 +
.../java/trust/entity/TrustMeasureCustom.java | 25 +
src/main/java/trust/entity/Usage.java | 34 +
src/main/java/trust/entity/User.java | 71 +
.../java/trust/mapper/CountHelperMapper.java | 14 +
.../java/trust/mapper/CountHelperMapper.xml | 25 +
src/main/java/trust/mapper/RecordMapper.java | 16 +
src/main/java/trust/mapper/RecordMapper.xml | 48 +
src/main/java/trust/mapper/ServiceMapper.java | 14 +
src/main/java/trust/mapper/ServiceMapper.xml | 35 +
src/main/java/trust/mapper/UsageMapper.java | 13 +
src/main/java/trust/mapper/UsageMapper.xml | 26 +
src/main/java/trust/mapper/UserMapper.java | 14 +
src/main/java/trust/mapper/UserMapper.xml | 33 +
src/main/java/trust/role/ConsumerService.java | 13 +
src/main/java/trust/role/PlatformService.java | 13 +
src/main/java/trust/role/ProviderService.java | 10 +
src/main/java/trust/role/Serve.java | 78 +
.../trust/role/impl/ConsumerServiceImpl.java | 80 +
.../trust/role/impl/PlatformServiceImpl.java | 123 +
.../trust/role/impl/ProviderServiceImpl.java | 32 +
src/main/java/trust/service/TestService.java | 16 +
.../trust/service/impl/TestServiceImpl.java | 135 +
src/main/resources/config.properties | 6 +
src/main/resources/log4j.properties | 34 +
src/main/resources/mybatis-config.xml | 53 +
src/main/resources/spring-dataSource.xml | 120 +
src/main/resources/spring-mvc.xml | 110 +
src/main/resources/spring.xml | 53 +
src/main/test/BasicGenerator.java | 20 +
src/main/test/BasicGeneratorDemo.java | 17 +
src/main/test/BasicOperation.java | 22 +
src/main/test/CountedObject.java | 8 +
src/main/test/DelegatingVehicleTracker.java | 53 +
src/main/test/Ensemble.java | 16 +
src/main/test/ExtendedOperation.java | 50 +
src/main/test/Father.java | 37 +
src/main/test/Generator.java | 4 +
src/main/test/Herb.java | 40 +
.../test/Item41/CollectionClassifier.java | 29 +
src/main/test/Item41/Overriding.java | 23 +
src/main/test/Item41/SetList.java | 23 +
src/main/test/MonitorVehicleTracker.java | 61 +
src/main/test/MutablePoint.java | 20 +
src/main/test/Operation.java | 4 +
src/main/test/Phase.java | 48 +
src/main/test/PojoBug.java | 14 +
src/main/test/Stack.java | 44 +
src/main/test/Sub.java | 19 +
src/main/test/Super.java | 8 +
src/main/test/TestSum.java | 16 +
src/main/test/Testsyn.java | 17 +
src/main/test/ThreadA.java | 14 +
src/main/test/aaa.java | 23 +
src/main/test/concurrent/Beer.java | 48 +
.../test/concurrent/LaunderThrowable.java | 24 +
src/main/test/concurrent/PrimeProducer.java | 33 +
src/main/test/concurrent/TestHarness.java | 41 +
src/main/test/concurrent/TestIntterupt.java | 51 +
src/main/test/sdadsad.java | 55 +
src/main/test/test.java | 16 +
src/main/test/testThread.java | 17 +
src/main/webapp/WEB-INF/views/echarts.js | 63738 ++++++++++++++++
src/main/webapp/WEB-INF/views/macarons.js | 198 +
.../webapp/WEB-INF/views/performanceList.jsp | 377 +
src/main/webapp/WEB-INF/views/result.jsp | 130 +
src/main/webapp/WEB-INF/web.xml | 66 +
src/main/webapp/index.jsp | 5 +
src/main/webapp/static/echarts.js | 63738 ++++++++++++++++
src/main/webapp/static/macarons.js | 198 +
76 files changed, 131357 insertions(+)
create mode 100644 TrustStudy.iml
create mode 100644 pom.xml
create mode 100644 src/main/java/trust/controller/TestController.java
create mode 100644 src/main/java/trust/entity/CountHelper.java
create mode 100644 src/main/java/trust/entity/Record.java
create mode 100644 src/main/java/trust/entity/Result.java
create mode 100644 src/main/java/trust/entity/Ser.java
create mode 100644 src/main/java/trust/entity/TrustMeasureCustom.java
create mode 100644 src/main/java/trust/entity/Usage.java
create mode 100644 src/main/java/trust/entity/User.java
create mode 100644 src/main/java/trust/mapper/CountHelperMapper.java
create mode 100644 src/main/java/trust/mapper/CountHelperMapper.xml
create mode 100644 src/main/java/trust/mapper/RecordMapper.java
create mode 100644 src/main/java/trust/mapper/RecordMapper.xml
create mode 100644 src/main/java/trust/mapper/ServiceMapper.java
create mode 100644 src/main/java/trust/mapper/ServiceMapper.xml
create mode 100644 src/main/java/trust/mapper/UsageMapper.java
create mode 100644 src/main/java/trust/mapper/UsageMapper.xml
create mode 100644 src/main/java/trust/mapper/UserMapper.java
create mode 100644 src/main/java/trust/mapper/UserMapper.xml
create mode 100644 src/main/java/trust/role/ConsumerService.java
create mode 100644 src/main/java/trust/role/PlatformService.java
create mode 100644 src/main/java/trust/role/ProviderService.java
create mode 100644 src/main/java/trust/role/Serve.java
create mode 100644 src/main/java/trust/role/impl/ConsumerServiceImpl.java
create mode 100644 src/main/java/trust/role/impl/PlatformServiceImpl.java
create mode 100644 src/main/java/trust/role/impl/ProviderServiceImpl.java
create mode 100644 src/main/java/trust/service/TestService.java
create mode 100644 src/main/java/trust/service/impl/TestServiceImpl.java
create mode 100644 src/main/resources/config.properties
create mode 100644 src/main/resources/log4j.properties
create mode 100644 src/main/resources/mybatis-config.xml
create mode 100644 src/main/resources/spring-dataSource.xml
create mode 100644 src/main/resources/spring-mvc.xml
create mode 100644 src/main/resources/spring.xml
create mode 100644 src/main/test/BasicGenerator.java
create mode 100644 src/main/test/BasicGeneratorDemo.java
create mode 100644 src/main/test/BasicOperation.java
create mode 100644 src/main/test/CountedObject.java
create mode 100644 src/main/test/DelegatingVehicleTracker.java
create mode 100644 src/main/test/Ensemble.java
create mode 100644 src/main/test/ExtendedOperation.java
create mode 100644 src/main/test/Father.java
create mode 100644 src/main/test/Generator.java
create mode 100644 src/main/test/Herb.java
create mode 100644 src/main/test/Item41/CollectionClassifier.java
create mode 100644 src/main/test/Item41/Overriding.java
create mode 100644 src/main/test/Item41/SetList.java
create mode 100644 src/main/test/MonitorVehicleTracker.java
create mode 100644 src/main/test/MutablePoint.java
create mode 100644 src/main/test/Operation.java
create mode 100644 src/main/test/Phase.java
create mode 100644 src/main/test/PojoBug.java
create mode 100644 src/main/test/Stack.java
create mode 100644 src/main/test/Sub.java
create mode 100644 src/main/test/Super.java
create mode 100644 src/main/test/TestSum.java
create mode 100644 src/main/test/Testsyn.java
create mode 100644 src/main/test/ThreadA.java
create mode 100644 src/main/test/aaa.java
create mode 100644 src/main/test/concurrent/Beer.java
create mode 100644 src/main/test/concurrent/LaunderThrowable.java
create mode 100644 src/main/test/concurrent/PrimeProducer.java
create mode 100644 src/main/test/concurrent/TestHarness.java
create mode 100644 src/main/test/concurrent/TestIntterupt.java
create mode 100644 src/main/test/sdadsad.java
create mode 100644 src/main/test/test.java
create mode 100644 src/main/test/testThread.java
create mode 100644 src/main/webapp/WEB-INF/views/echarts.js
create mode 100644 src/main/webapp/WEB-INF/views/macarons.js
create mode 100644 src/main/webapp/WEB-INF/views/performanceList.jsp
create mode 100644 src/main/webapp/WEB-INF/views/result.jsp
create mode 100644 src/main/webapp/WEB-INF/web.xml
create mode 100644 src/main/webapp/index.jsp
create mode 100644 src/main/webapp/static/echarts.js
create mode 100644 src/main/webapp/static/macarons.js
diff --git a/TrustStudy.iml b/TrustStudy.iml
new file mode 100644
index 0000000..fd382b8
--- /dev/null
+++ b/TrustStudy.iml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..3a7d77d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,410 @@
+
+ 4.0.0
+ com.eliteams
+ TrustStudy
+ war
+ 1.0.0
+ quick4j App
+ https://github.com/starzou/quick4j
+
+
+ TrustStudy
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${plugin.maven-compiler}
+
+
+ ${project.build.jdk}
+ ${project.build.sourceEncoding}
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${plugin.maven-surefire}
+
+ ${skipTests}
+
+
+
+
+
+
+
+ src/main/resources
+
+ **/*.properties
+ **/*.xml
+
+ true
+
+
+ src/main/java
+
+ **/*.properties
+ **/*.xml
+
+ true
+
+
+
+
+
+
+ UTF-8
+ zh_CN
+ 1.7
+
+
+ ${basedir}/src/test/resources/generatorConfig.xml
+ file:///${basedir}/src/test/resources/generatorConfig.properties
+
+
+ 1.3.1
+ 3.1
+ 2.18.1
+ true
+
+
+ 4.11
+ 4.2.4.RELEASE
+ 3.2.8
+ 1.2.3
+ 5.1.30
+ 1.7.6
+ 1.2.12
+ 1.9.13
+ 1.0.11
+ 7.0.53
+ 1.2
+ 1.3.1
+ 1.9
+ 3.3
+ 1.6.12
+ 5.1.1.Final
+
+
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ 1.9.13
+
+
+
+ junit
+ junit
+ ${junit.version}
+
+
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.7.0
+
+
+
+
+ com.github.pagehelper
+ pagehelper
+ 5.0.0
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.3.2
+
+
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+
+
+
+ commons-dbcp
+ commons-dbcp
+ 1.2.2
+
+
+
+ javax.servlet
+ jstl
+ 1.2
+
+
+
+ taglibs
+ standard
+ 1.1.2
+
+
+
+ org.springframework
+ spring-web
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-jdbc
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-beans
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-webmvc
+ ${spring.version}
+
+
+
+
+
+
+ redis.clients
+ jedis
+ 2.9.0
+
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.0
+
+
+
+
+ org.aspectj
+ aspectjweaver
+ 1.7.4
+
+
+
+
+
+
+ org.springframework
+ spring-aop
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-context-support
+ ${spring.version}
+
+
+
+
+
+
+ org.mybatis
+ mybatis
+ ${mybatis.version}
+
+
+
+
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.connector.version}
+
+
+
+
+ com.alibaba
+ druid
+ ${druid.version}
+
+
+
+
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ ${jackson.version}
+
+
+
+
+ log4j
+ log4j
+ ${log4j.version}
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${slf4j.version}
+
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.0.1
+ provided
+
+
+
+
+
+ commons-fileupload
+ commons-fileupload
+ ${commons.fileupload.version}
+
+
+
+ commons-codec
+ commons-codec
+ ${commons.codec.version}
+
+
+
+ commons-net
+ commons-net
+ ${commons.net.version}
+
+
+
+ commons-logging
+ commons-logging
+ 1.1.3
+
+
+ commons-collections
+ commons-collections
+ 3.2.1
+
+
+
+
+
+
+
+
+
+
+
+ org.hibernate
+ hibernate-validator
+ ${hibernate.validator.version}
+
+
+
+
+
+
+ org.mybatis
+ mybatis-spring
+ 1.2.3
+
+
+
+ redis.clients
+ jedis
+ 2.6.2
+ jar
+ compile
+
+
+ org.springframework.data
+ spring-data-redis
+ 1.8.0.RELEASE
+
+
+ redis.clients
+ jedis
+ 2.9.0
+
+
+ org.apache.commons
+ commons-pool2
+ 2.0
+
+
+ com.google.guava
+ guava
+ 14.0-rc2
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.7.0
+
+
+ com.github.pagehelper
+ pagehelper
+ 5.0.0
+
+
+
+ com.alibaba
+ fastjson
+ 1.2.16
+
+
+
+ com.ning
+ async-http-client
+ 1.9.40
+
+
+
+ net.sf.kxml
+ kxml2
+ 2.3.0
+
+
+ xmlpull
+ xmlpull
+ 1.1.3.1
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.2
+
+
+ org.apache.maven
+ maven-parent
+ 23
+ pom
+
+
+
\ No newline at end of file
diff --git a/src/main/java/trust/controller/TestController.java b/src/main/java/trust/controller/TestController.java
new file mode 100644
index 0000000..a51de74
--- /dev/null
+++ b/src/main/java/trust/controller/TestController.java
@@ -0,0 +1,45 @@
+package trust.controller;
+
+
+import com.google.gson.Gson;
+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.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
+import trust.entity.Result;
+import trust.service.TestService;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.concurrent.BrokenBarrierException;
+
+
+@Controller
+@RequestMapping("/trust")
+public class TestController {
+
+ @Autowired
+ TestService testService;
+
+ //开始进行模拟
+ @RequestMapping(value="/test",method= RequestMethod.POST)
+ public void Test() throws BrokenBarrierException, InterruptedException {
+ testService.Run();
+ }
+
+ //获取实验的结果
+ @RequestMapping(value="/result")
+ public ModelAndView Result(HttpServletRequest request) throws BrokenBarrierException, InterruptedException {
+ List results=testService.GetResult();
+ Gson gson=new Gson();
+ request.setAttribute("result", gson.toJson(results));
+ return new ModelAndView("/result");
+ }
+
+ //清除当前测试的数据重新开始
+ @RequestMapping(value="/clear",method= RequestMethod.POST)
+ public void Clear() {
+ testService.Clear();
+ }
+}
diff --git a/src/main/java/trust/entity/CountHelper.java b/src/main/java/trust/entity/CountHelper.java
new file mode 100644
index 0000000..46e0474
--- /dev/null
+++ b/src/main/java/trust/entity/CountHelper.java
@@ -0,0 +1,35 @@
+package trust.entity;
+
+/**
+ * Created by inst1 on 2017/7/30.
+ * 用来显示结果的辅助类
+ */
+public class CountHelper {
+ private int gen;
+ private int successCount;
+ private int totalCount;
+
+ public int getTotalCount() {
+ return totalCount;
+ }
+
+ public void setTotalCount(int totalCount) {
+ this.totalCount = totalCount;
+ }
+
+ public int getSuccessCount() {
+ return successCount;
+ }
+
+ public void setSuccessCount(int successCount) {
+ this.successCount = successCount;
+ }
+
+ public int getGen() {
+ return gen;
+ }
+
+ public void setGen(int gen) {
+ this.gen = gen;
+ }
+}
diff --git a/src/main/java/trust/entity/Record.java b/src/main/java/trust/entity/Record.java
new file mode 100644
index 0000000..bac19db
--- /dev/null
+++ b/src/main/java/trust/entity/Record.java
@@ -0,0 +1,55 @@
+package trust.entity;
+
+import java.util.Date;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ * 可信反馈记录
+ */
+public class Record {
+ private Integer id;
+ private Integer usr;
+ private Integer se;
+ private Date time;
+ private double trust;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public Integer getUsr() {
+ return usr;
+ }
+
+ public void setUsr(Integer usr) {
+ this.usr = usr;
+ }
+
+ public Integer getSe() {
+ return se;
+ }
+
+ public void setSe(Integer se) {
+ this.se = se;
+ }
+
+ public double getTrust() {
+ return trust;
+ }
+
+ public void setTrust(double trust) {
+ this.trust = trust;
+ }
+
+ public Date getTime() {
+ return time;
+ }
+
+ public void setTime(Date time) {
+ this.time = time;
+ }
+}
diff --git a/src/main/java/trust/entity/Result.java b/src/main/java/trust/entity/Result.java
new file mode 100644
index 0000000..c80c0ee
--- /dev/null
+++ b/src/main/java/trust/entity/Result.java
@@ -0,0 +1,26 @@
+package trust.entity;
+
+/**
+ * Created by inst1 on 2017/8/6.
+ * 用来存储统计后的结果
+ */
+public class Result {
+ private int round;
+ private float trust;
+
+ public int getRound() {
+ return round;
+ }
+
+ public void setRound(int round) {
+ this.round = round;
+ }
+
+ public float getTrust() {
+ return trust;
+ }
+
+ public void setTrust(float trust) {
+ this.trust = trust;
+ }
+}
diff --git a/src/main/java/trust/entity/Ser.java b/src/main/java/trust/entity/Ser.java
new file mode 100644
index 0000000..628da88
--- /dev/null
+++ b/src/main/java/trust/entity/Ser.java
@@ -0,0 +1,89 @@
+package trust.entity;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ * 服务提供商
+ */
+public class Ser {
+ private int id;
+ private String name;
+ private int quality;
+ private int count;
+ private String role;
+ private float usability;
+ private float reliability;
+ private float responseTime;
+ private float throughPut;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getQuality() {
+ return quality;
+ }
+
+ public void setQuality(int quality) {
+ this.quality = quality;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public float getUsability() {
+ return usability;
+ }
+
+ public void setUsability(float usability) {
+ this.usability = usability;
+ }
+
+ public float getReliability() {
+ return reliability;
+ }
+
+ public void setReliability(float reliability) {
+ this.reliability = reliability;
+ }
+
+ public float getResponseTime() {
+ return responseTime;
+ }
+
+ public void setResponseTime(float responseTime) {
+ this.responseTime = responseTime;
+ }
+
+ public float getThroughPut() {
+ return throughPut;
+ }
+
+ public void setThroughPut(float throughPut) {
+ this.throughPut = throughPut;
+ }
+}
diff --git a/src/main/java/trust/entity/TrustMeasureCustom.java b/src/main/java/trust/entity/TrustMeasureCustom.java
new file mode 100644
index 0000000..ebcc63c
--- /dev/null
+++ b/src/main/java/trust/entity/TrustMeasureCustom.java
@@ -0,0 +1,25 @@
+package trust.entity;
+
+/**
+ * Created by inst1 on 2017/11/9.
+ */
+public class TrustMeasureCustom {
+ private double trust;
+ private double weight;
+
+ public double getTrust() {
+ return trust;
+ }
+
+ public void setTrust(double trust) {
+ this.trust = trust;
+ }
+
+ public double getWeight() {
+ return weight;
+ }
+
+ public void setWeight(double weight) {
+ this.weight = weight;
+ }
+}
diff --git a/src/main/java/trust/entity/Usage.java b/src/main/java/trust/entity/Usage.java
new file mode 100644
index 0000000..93c6a27
--- /dev/null
+++ b/src/main/java/trust/entity/Usage.java
@@ -0,0 +1,34 @@
+package trust.entity;
+
+/**
+ * Created by inst1 on 2017/11/6.
+ */
+public class Usage {
+ private int id;
+ private int usr;
+ private int se;
+
+ public int getUsr() {
+ return usr;
+ }
+
+ public void setUsr(int usr) {
+ this.usr = usr;
+ }
+
+ public int getSe() {
+ return se;
+ }
+
+ public void setSe(int se) {
+ this.se = se;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+}
diff --git a/src/main/java/trust/entity/User.java b/src/main/java/trust/entity/User.java
new file mode 100644
index 0000000..0cf5030
--- /dev/null
+++ b/src/main/java/trust/entity/User.java
@@ -0,0 +1,71 @@
+package trust.entity;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ * 用户
+ */
+public class User {
+ private int id;
+ private String name;
+ private int count;
+ private float usability;
+ private float reliability;
+ private float responseTime;
+ private float throughPut;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+ public float getUsability() {
+ return usability;
+ }
+
+ public void setUsability(float usability) {
+ this.usability = usability;
+ }
+
+ public float getReliability() {
+ return reliability;
+ }
+
+ public void setReliability(float reliability) {
+ this.reliability = reliability;
+ }
+
+ public float getResponseTime() {
+ return responseTime;
+ }
+
+ public void setResponseTime(float responseTime) {
+ this.responseTime = responseTime;
+ }
+
+ public float getThroughPut() {
+ return throughPut;
+ }
+
+ public void setThroughPut(float throughPut) {
+ this.throughPut = throughPut;
+ }
+}
diff --git a/src/main/java/trust/mapper/CountHelperMapper.java b/src/main/java/trust/mapper/CountHelperMapper.java
new file mode 100644
index 0000000..e378ba4
--- /dev/null
+++ b/src/main/java/trust/mapper/CountHelperMapper.java
@@ -0,0 +1,14 @@
+package trust.mapper;
+
+import trust.entity.CountHelper;
+
+import java.util.List;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ */
+public interface CountHelperMapper {
+ int insert(CountHelper countHelper);
+ List selectAll();
+
+}
diff --git a/src/main/java/trust/mapper/CountHelperMapper.xml b/src/main/java/trust/mapper/CountHelperMapper.xml
new file mode 100644
index 0000000..9f06b3d
--- /dev/null
+++ b/src/main/java/trust/mapper/CountHelperMapper.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+ gen,success_count,total_count
+
+
+ insert into count_helper (gen,success_count,total_count)
+ values ( #{gen,jdbcType=INTEGER}, #{successCount,jdbcType=INTEGER}, #{totalCount,jdbcType=INTEGER})
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/trust/mapper/RecordMapper.java b/src/main/java/trust/mapper/RecordMapper.java
new file mode 100644
index 0000000..687625b
--- /dev/null
+++ b/src/main/java/trust/mapper/RecordMapper.java
@@ -0,0 +1,16 @@
+package trust.mapper;
+
+import trust.entity.Record;
+
+import java.util.List;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ */
+public interface RecordMapper {
+ int insert(Record r);
+ int clearAll();
+ List selectByService(Integer se);
+ int clearPart();
+ List selectByUserAndService(Integer usr,Integer se);
+}
diff --git a/src/main/java/trust/mapper/RecordMapper.xml b/src/main/java/trust/mapper/RecordMapper.xml
new file mode 100644
index 0000000..0f4743c
--- /dev/null
+++ b/src/main/java/trust/mapper/RecordMapper.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+ id, usr, se,time, trust
+
+
+ insert into record (usr, se,time,trust)
+ values ( #{usr,jdbcType=INTEGER}, #{se,jdbcType=INTEGER}, #{time,jdbcType=TIMESTAMP}, #{trust,jdbcType=DOUBLE})
+
+
+
+
+
+
+
+ delete from record;
+ update Service set count=0 and counta=0;
+ update user set count=0;
+ delete from count_helper;
+ delete from useage;
+
+
+ delete from record;
+ update Service set count=0 and counta=0;
+ update user set count=0;
+ delete from useage;
+
+
+
\ No newline at end of file
diff --git a/src/main/java/trust/mapper/ServiceMapper.java b/src/main/java/trust/mapper/ServiceMapper.java
new file mode 100644
index 0000000..084b1e9
--- /dev/null
+++ b/src/main/java/trust/mapper/ServiceMapper.java
@@ -0,0 +1,14 @@
+package trust.mapper;
+
+import trust.entity.Ser;
+
+import java.util.List;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ */
+public interface ServiceMapper {
+ List selectByQuality(Integer low, Integer high);
+ int count(Integer id);
+ int countA(Integer id);
+}
diff --git a/src/main/java/trust/mapper/ServiceMapper.xml b/src/main/java/trust/mapper/ServiceMapper.xml
new file mode 100644
index 0000000..f824f5a
--- /dev/null
+++ b/src/main/java/trust/mapper/ServiceMapper.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, name, quality,count,role,usability,reliability,response_time,through_put
+
+
+
+
+ update service set count=count+1 where id=#{id}
+
+
+
+ update service set counta=counta+1 where id=#{id}
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/trust/mapper/UsageMapper.java b/src/main/java/trust/mapper/UsageMapper.java
new file mode 100644
index 0000000..9fde606
--- /dev/null
+++ b/src/main/java/trust/mapper/UsageMapper.java
@@ -0,0 +1,13 @@
+package trust.mapper;
+
+import trust.entity.Usage;
+
+import java.util.List;
+
+/**
+ * Created by inst1 on 2017/11/6.
+ */
+public interface UsageMapper {
+ int insertUsage(Usage usage);
+ List selectUserUsage(int se);
+}
diff --git a/src/main/java/trust/mapper/UsageMapper.xml b/src/main/java/trust/mapper/UsageMapper.xml
new file mode 100644
index 0000000..1cdc47d
--- /dev/null
+++ b/src/main/java/trust/mapper/UsageMapper.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+ id, usr, se;
+
+
+
+
+
+
+ insert useage (usr,se)
+ values(#{usr},#{se})
+
+
+
\ No newline at end of file
diff --git a/src/main/java/trust/mapper/UserMapper.java b/src/main/java/trust/mapper/UserMapper.java
new file mode 100644
index 0000000..3807e3c
--- /dev/null
+++ b/src/main/java/trust/mapper/UserMapper.java
@@ -0,0 +1,14 @@
+package trust.mapper;
+
+import trust.entity.User;
+
+import java.util.List;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ */
+public interface UserMapper {
+ List selectAll();
+ int count(Integer id);
+ int countSuccess();
+}
diff --git a/src/main/java/trust/mapper/UserMapper.xml b/src/main/java/trust/mapper/UserMapper.xml
new file mode 100644
index 0000000..b2154fc
--- /dev/null
+++ b/src/main/java/trust/mapper/UserMapper.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, name, count,usability,reliability,response_time,through_put
+
+
+
+
+
+
+ update user set count=count+1 where id=#{id}
+
+
+
\ No newline at end of file
diff --git a/src/main/java/trust/role/ConsumerService.java b/src/main/java/trust/role/ConsumerService.java
new file mode 100644
index 0000000..748dd26
--- /dev/null
+++ b/src/main/java/trust/role/ConsumerService.java
@@ -0,0 +1,13 @@
+package trust.role;
+
+import trust.entity.Ser;
+import trust.entity.User;
+
+import java.util.List;
+
+/**
+ * Created by inst1 on 2017/7/16.
+ */
+public interface ConsumerService {
+ void UseService(List services , User user, int gen);
+}
diff --git a/src/main/java/trust/role/PlatformService.java b/src/main/java/trust/role/PlatformService.java
new file mode 100644
index 0000000..7b5178d
--- /dev/null
+++ b/src/main/java/trust/role/PlatformService.java
@@ -0,0 +1,13 @@
+package trust.role;
+
+import trust.entity.Ser;
+import trust.entity.User;
+
+import java.util.List;
+
+/**
+ * Created by inst1 on 2017/10/31.
+ */
+public interface PlatformService {
+ List getTrustedService(int ranLow, int ranHigh, User user,int choice);
+}
diff --git a/src/main/java/trust/role/ProviderService.java b/src/main/java/trust/role/ProviderService.java
new file mode 100644
index 0000000..8142094
--- /dev/null
+++ b/src/main/java/trust/role/ProviderService.java
@@ -0,0 +1,10 @@
+package trust.role;
+
+import trust.entity.Ser;
+
+/**
+ * Created by inst1 on 2017/7/16.
+ */
+public interface ProviderService {
+ Ser ProduceServiceActualQuality(Ser se,int order);
+}
diff --git a/src/main/java/trust/role/Serve.java b/src/main/java/trust/role/Serve.java
new file mode 100644
index 0000000..f743eda
--- /dev/null
+++ b/src/main/java/trust/role/Serve.java
@@ -0,0 +1,78 @@
+package trust.role;
+
+import trust.entity.Ser;
+import trust.entity.User;
+
+import java.util.List;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ */
+
+
+public class Serve extends Thread {
+ int gen;
+ AtomicInteger count;
+ User user;
+ PlatformService platformService;
+ ConsumerService consumerService;
+ ProviderService providerService;
+ CountDownLatch countDownLatch;
+ CyclicBarrier beforeBarrier;
+ CyclicBarrier afterBarrier;
+ int choice;
+
+ //初始化多线程,将需要用到的mapper和service加入到类中
+ public Serve(User user, PlatformService platformService, ConsumerService consumerService, ProviderService providerService, CountDownLatch countDownLatch, AtomicInteger count, CyclicBarrier beforeBarrier, CyclicBarrier afterBarrie, int choice,int gen){
+ //将客户端需要的东西注入到线程中,由于mapper等需要连接的东西是通过threadlocal存储的所以不存在线程安全问题
+ this.user=user;
+ this.platformService=platformService;
+ this.consumerService=consumerService;
+ this.providerService=providerService;
+ this.countDownLatch=countDownLatch;
+ this.count=count;
+ this.beforeBarrier=beforeBarrier;
+ this.afterBarrier=afterBarrie;
+ this.choice=choice;
+ this.gen=gen;
+ }
+
+ @Override
+ public void run() {
+ //客户端初始化完,等待其他用户的客户端
+ countDownLatch.countDown();
+ try {
+ countDownLatch.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ //定义代,根据代别来统计准确率
+ for(int i=0;i services=platformService.getTrustedService(ranLow,ranHigh,user,choice);
+ consumerService.UseService(services,user,i);
+
+
+
+ }
+ try {
+ //根据每个迭代的统计操作控制
+ beforeBarrier.await();
+ afterBarrier.await();
+ } catch (InterruptedException | BrokenBarrierException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/src/main/java/trust/role/impl/ConsumerServiceImpl.java b/src/main/java/trust/role/impl/ConsumerServiceImpl.java
new file mode 100644
index 0000000..02e2147
--- /dev/null
+++ b/src/main/java/trust/role/impl/ConsumerServiceImpl.java
@@ -0,0 +1,80 @@
+package trust.role.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import trust.entity.Record;
+import trust.entity.Ser;
+import trust.entity.Usage;
+import trust.entity.User;
+import trust.mapper.RecordMapper;
+import trust.mapper.ServiceMapper;
+import trust.mapper.UsageMapper;
+import trust.mapper.UserMapper;
+import trust.role.ConsumerService;
+import trust.role.ProviderService;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Created by inst1 on 2017/7/16.
+ */
+@Service("ConsumerService")
+public class ConsumerServiceImpl implements ConsumerService {
+ @Autowired
+ private ProviderService providerService;
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @Autowired
+ private ServiceMapper serviceMapper;
+
+ @Autowired
+ private RecordMapper recordMapper;
+
+ @Autowired
+ private UsageMapper usageMapper;
+
+ private int SelectService(List services){
+ //根据被评估为可信的服务列表随机选择服务
+ Random random=new Random();
+ return random.nextInt(services.size());
+ }
+ @Override
+ public void UseService(List services ,User user,int gen){
+ int len=services.size();
+ //如果有可选的服务则选择服务
+ if(len>0){
+ int ran =SelectService(services);
+ Record r = new Record();
+ //调用服务器service模拟服务提供过程获取实际qos值
+ Ser actual=providerService.ProduceServiceActualQuality(services.get(ran),gen);
+ //计算可信值
+ float trust=actual.getReliability()*user.getReliability()+actual.getThroughPut()*user.getThroughPut()+actual.getResponseTime()*user.getResponseTime()+actual.getUsability()*user.getUsability();
+ //录入反馈记录
+ r.setSe(services.get(ran).getId());
+ r.setTime(new Date());
+ r.setUsr(user.getId());
+ r.setTrust(trust );
+ //如果服务最终评估为实际可信,则证明推荐和评估过程成功了。
+ if(trust>=0.9){
+ userMapper.count(user.getId());
+ }
+
+ //插入反馈记录
+ recordMapper.insert(r);
+ //记录服务被调用次数
+ serviceMapper.count(services.get(ran).getId());
+ //记录用户调用的服务
+ Usage usage=new Usage();
+ usage.setSe(services.get(ran).getId());
+ usage.setUsr(user.getId());
+ usageMapper.insertUsage(usage);
+ }
+ }
+
+
+
+}
diff --git a/src/main/java/trust/role/impl/PlatformServiceImpl.java b/src/main/java/trust/role/impl/PlatformServiceImpl.java
new file mode 100644
index 0000000..52eb8e2
--- /dev/null
+++ b/src/main/java/trust/role/impl/PlatformServiceImpl.java
@@ -0,0 +1,123 @@
+package trust.role.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import trust.entity.Record;
+import trust.entity.Ser;
+import trust.entity.TrustMeasureCustom;
+import trust.entity.User;
+import trust.mapper.RecordMapper;
+import trust.mapper.ServiceMapper;
+import trust.mapper.UsageMapper;
+import trust.role.PlatformService;
+
+import java.util.List;
+
+/**
+ * Created by inst1 on 2017/10/31.
+ */
+
+
+@Service("PlatformService")
+public class PlatformServiceImpl implements PlatformService {
+ @Autowired
+ private ServiceMapper serviceMapper;
+
+ @Autowired
+ private RecordMapper recordMapper;
+
+ @Autowired
+ private UsageMapper usageMapper;
+
+ @Override
+ public List getTrustedService(int ranLow, int ranHigh, User user,int choice) {
+
+ //根据qos需求初步筛选服务
+ List services = serviceMapper.selectByQuality(ranLow, ranHigh);
+ Integer len = services.size();
+ //评估每个服务的可信性
+ for (int i = 0; i < len; i++) {
+ //记录服务曾被选中次数,便于可能的统计工作
+ serviceMapper.countA(services.get(i).getId());
+ //获取所有使用过该服务的历史评估信息
+ double avg=measureServiceTrust(services.get(i),choice);
+
+ //根据平均值选择是否不考虑该服务
+ if (avg < 0.9 && services.get(i).getCount() > 4) {
+ //不选择则去除该服务,方便最后用户随机抽取可信服务
+ services.remove(i);
+ i--;
+ len--;
+
+ }
+ }
+ return services;
+ }
+
+ private TrustMeasureCustom getAverageByTime(List records){
+ Integer reLen = records.size();
+ //获取当前时间
+ long now =System.currentTimeMillis();
+ double avg = 0;
+ double timeWeightAll = 0;
+ double timeWeight = 0;
+ for (int y = 0; y < reLen; y++) {
+ //获取每个历史纪录到当前时间的时间差,用来计算比重
+ long between=(now-records.get(y).getTime().getTime())/1000;
+ //计算比重值,乘上信任值加到总计中,同时加到总比重中,最后一除就是可信值
+ timeWeight=Math.pow(2.5,-between);
+ timeWeightAll+=timeWeight;
+ avg+=records.get(y).getTrust()*timeWeight;
+ }
+ //计算平均评分
+
+
+ TrustMeasureCustom trustMeasureCustom=new TrustMeasureCustom();
+ trustMeasureCustom.setTrust(avg);
+ trustMeasureCustom.setWeight(timeWeightAll);
+ return trustMeasureCustom;
+ }
+
+ private TrustMeasureCustom getAverage(List records){
+ Integer reLen = records.size();
+ //获取当前时间
+ double avg = 0;
+ for (int y = 0; y < reLen; y++) {
+ //在无时间衰减记录下,直接取平均就行
+ avg += records.get(y).getTrust();
+ }
+
+
+ //计算平均评分
+
+ TrustMeasureCustom trustMeasureCustom=new TrustMeasureCustom();
+ trustMeasureCustom.setTrust(avg);
+ trustMeasureCustom.setWeight(reLen);
+ return trustMeasureCustom;
+ }
+
+ double measureServiceTrust(Ser ser,int choice){
+ List users=usageMapper.selectUserUsage(ser.getId());
+ double sum=0,weight=0;
+ for(int i=0;i records=recordMapper.selectByUserAndService(user,ser);
+ if(choice==0){
+ return getAverageByTime(records);
+ }
+ else{
+ return getAverage(records);
+ }
+
+ }
+
+
+
+}
diff --git a/src/main/java/trust/role/impl/ProviderServiceImpl.java b/src/main/java/trust/role/impl/ProviderServiceImpl.java
new file mode 100644
index 0000000..60432f4
--- /dev/null
+++ b/src/main/java/trust/role/impl/ProviderServiceImpl.java
@@ -0,0 +1,32 @@
+package trust.role.impl;
+
+import org.springframework.stereotype.Service;
+import trust.entity.Ser;
+import trust.role.ProviderService;
+
+import java.util.Random;
+
+/**
+ * Created by inst1 on 2017/7/16.
+ */
+@Service("ProviderService")
+public class ProviderServiceImpl implements ProviderService {
+ public Ser ProduceServiceActualQuality(Ser ser,int round){
+ Random random=new Random();
+ //模拟不良商家为了获取用户信任而使用的开始正常服务后来低水平服务的不可信行为,此模拟可凸显出不使用时间衰减因子时造成的可信错误评价情况
+ if(round<3||ser.getRole().equals("good")){
+ ser.setUsability((float) (random.nextFloat()/10+0.9));
+ ser.setReliability((float) (random.nextFloat()/10+0.9));
+ ser.setResponseTime((float) (random.nextFloat()/10+0.9));
+ ser.setThroughPut((float) (random.nextFloat()/10+0.9));
+ }
+ else{
+ ser.setUsability((float) (random.nextFloat()/4+0.7));
+ ser.setReliability((float) (random.nextFloat()/4+0.7));
+ ser.setResponseTime((float) (random.nextFloat()/4+0.7));
+ ser.setThroughPut((float) (random.nextFloat()/4+0.7));
+ }
+
+ return ser;
+ }
+}
diff --git a/src/main/java/trust/service/TestService.java b/src/main/java/trust/service/TestService.java
new file mode 100644
index 0000000..6013baf
--- /dev/null
+++ b/src/main/java/trust/service/TestService.java
@@ -0,0 +1,16 @@
+package trust.service;
+
+import trust.entity.Result;
+
+import java.util.List;
+import java.util.concurrent.BrokenBarrierException;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ */
+public interface TestService {
+ void Clear();
+ List GetResult();
+ void Run() throws BrokenBarrierException, InterruptedException;
+
+}
diff --git a/src/main/java/trust/service/impl/TestServiceImpl.java b/src/main/java/trust/service/impl/TestServiceImpl.java
new file mode 100644
index 0000000..f3785d4
--- /dev/null
+++ b/src/main/java/trust/service/impl/TestServiceImpl.java
@@ -0,0 +1,135 @@
+package trust.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import trust.entity.CountHelper;
+import trust.entity.Result;
+import trust.entity.User;
+import trust.mapper.CountHelperMapper;
+import trust.mapper.RecordMapper;
+import trust.mapper.ServiceMapper;
+import trust.mapper.UserMapper;
+import trust.role.ConsumerService;
+import trust.role.PlatformService;
+import trust.role.ProviderService;
+import trust.role.Serve;
+import trust.service.TestService;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Created by inst1 on 2017/6/21.
+ */
+@Service("TestService")
+public class TestServiceImpl implements TestService {
+ public volatile AtomicInteger k=new AtomicInteger();
+ @Autowired
+ UserMapper userMapper;
+
+ @Autowired
+ ServiceMapper serviceMapper;
+
+ @Autowired
+ RecordMapper recordMapper;
+
+ @Autowired
+ ConsumerService consumerService;
+
+ @Autowired
+ ProviderService providerService;
+
+ @Autowired
+ CountHelperMapper countHelperMapper;
+ @Autowired
+ PlatformService platformService;
+ private Integer id;
+ private void Test(int gen,int choice) throws BrokenBarrierException, InterruptedException {
+ //从数据库中取出用户
+ final List users=userMapper.selectAll();
+ long start=System.currentTimeMillis();
+ //记录总共调用服务次数的数值,为之后统计图服务。
+ AtomicInteger test=new AtomicInteger(0);
+ //第一个栅栏用来拦住全部正在调用服务的用户,让服务统计。确保全部用户完成了调用量再统计
+ CyclicBarrier beforeBarrier=new CyclicBarrier(users.size()+1);
+ //第二个栅栏用来确保在统计时用户不会在继续调用,等到统计完成了再放用户进行下一轮使用,确保一致性。
+ CyclicBarrier afterBarrier=new CyclicBarrier(users.size()+1);
+ //确保全部用户线程同时开启(可有可无)
+ final CountDownLatch countDownLatch=new CountDownLatch(users.size());
+ //创建客户端,开始调用服务并模拟平台自动评估服务可信值,模拟用户在可选列表的服务列表中随机选择服务,服务提供商模拟提供特定范围内的服务质量,根据对比值自动产生反馈值并录入数据库中,将上面步骤中加入的栅栏加入到每个客户端中协助控制
+ for(User user:users){
+ Serve s=new Serve(user,platformService,consumerService,providerService,countDownLatch,test,beforeBarrier,afterBarrier,choice,gen);
+ s.start();
+ }
+ //对应多个代用来在最终统计图中显示出平台在渐渐加强服务评估的精度,每次使用第一个栅栏等待所有的用户调用完当前迭代的量,第二个栅栏卡住用户等自己统计完插入进数据库再放行
+ for(int i=0;i GetResult() {
+ //获取全部迭代中的数据
+ List countHelpers=countHelperMapper.selectAll();
+ List results=new ArrayList<>();
+ int j=countHelpers.size();
+ for(int i=0;i
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/spring-dataSource.xml b/src/main/resources/spring-dataSource.xml
new file mode 100644
index 0000000..f07528d
--- /dev/null
+++ b/src/main/resources/spring-dataSource.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/spring-mvc.xml b/src/main/resources/spring-mvc.xml
new file mode 100644
index 0000000..9e8b761
--- /dev/null
+++ b/src/main/resources/spring-mvc.xml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/spring.xml b/src/main/resources/spring.xml
new file mode 100644
index 0000000..f751119
--- /dev/null
+++ b/src/main/resources/spring.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/test/BasicGenerator.java b/src/main/test/BasicGenerator.java
new file mode 100644
index 0000000..25e9ea3
--- /dev/null
+++ b/src/main/test/BasicGenerator.java
@@ -0,0 +1,20 @@
+//: net/mindview/util/BasicGenerator.java
+// Automatically create a Generator, given a class
+// with a default (no-arg) constructor.
+
+public class BasicGenerator implements Generator {
+ private Class type;
+ public BasicGenerator(Class type){ this.type = type; }
+ public T next() {
+ try {
+ // Assumes type is a public class:
+ return type.newInstance();
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // Produce a Default generator given a type token:
+ public static Generator create(Class type) {
+ return new BasicGenerator(type);
+ }
+} ///:~
diff --git a/src/main/test/BasicGeneratorDemo.java b/src/main/test/BasicGeneratorDemo.java
new file mode 100644
index 0000000..9384818
--- /dev/null
+++ b/src/main/test/BasicGeneratorDemo.java
@@ -0,0 +1,17 @@
+//: generics/BasicGeneratorDemo.java
+
+
+public class BasicGeneratorDemo {
+ public static void main(String[] args) {
+ Generator gen =
+ BasicGenerator.create(CountedObject.class);
+ for(int i = 0; i < 5; i++)
+ System.out.println(gen.next());
+ }
+} /* Output:
+CountedObject 0
+CountedObject 1
+CountedObject 2
+CountedObject 3
+CountedObject 4
+*///:~
diff --git a/src/main/test/BasicOperation.java b/src/main/test/BasicOperation.java
new file mode 100644
index 0000000..db5db66
--- /dev/null
+++ b/src/main/test/BasicOperation.java
@@ -0,0 +1,22 @@
+// Emulated extensible enum using an interface - Basic implementation - Page 165
+public enum BasicOperation implements Operation {
+ PLUS("+") {
+ public double apply(double x, double y) { return x + y; }
+ },
+ MINUS("-") {
+ public double apply(double x, double y) { return x - y; }
+ },
+ TIMES("*") {
+ public double apply(double x, double y) { return x * y; }
+ },
+ DIVIDE("/") {
+ public double apply(double x, double y) { return x / y; }
+ };
+ private final String symbol;
+ BasicOperation(String symbol) {
+ this.symbol = symbol;
+ }
+ @Override public String toString() {
+ return symbol;
+ }
+}
diff --git a/src/main/test/CountedObject.java b/src/main/test/CountedObject.java
new file mode 100644
index 0000000..757f2ae
--- /dev/null
+++ b/src/main/test/CountedObject.java
@@ -0,0 +1,8 @@
+//: generics/CountedObject.java
+
+public class CountedObject {
+ private static long counter = 0;
+ private final long id = counter++;
+ public long id() { return id; }
+ public String toString() { return "CountedObject " + counter;}
+} ///:~
diff --git a/src/main/test/DelegatingVehicleTracker.java b/src/main/test/DelegatingVehicleTracker.java
new file mode 100644
index 0000000..e9ecaed
--- /dev/null
+++ b/src/main/test/DelegatingVehicleTracker.java
@@ -0,0 +1,53 @@
+import java.awt.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * DelegatingVehicleTracker
+ *
+ * Delegating thread safety to a ConcurrentHashMap
+ *
+ * @author Brian Goetz and Tim Peierls
+ */
+public class DelegatingVehicleTracker {
+ private final ConcurrentMap locations;
+ private final Map unmodifiableMap;
+
+ public DelegatingVehicleTracker(Map points) {
+ locations = new ConcurrentHashMap(points);
+ unmodifiableMap = Collections.unmodifiableMap(locations);
+ }
+
+ public Map getLocations() {
+ return unmodifiableMap;
+ }
+
+ public Point getLocation(String id) {
+ return locations.get(id);
+ }
+
+ public void setLocation(String id, int x, int y) {
+ locations.put(id, new Point(x, y));
+ }
+ Vector sada=new Vector<>();
+
+ // Alternate version of getLocations (Listing 4.8)
+ public Map getLocationsAsStatic() {
+
+ return Collections.unmodifiableMap(
+ new HashMap(locations));
+ }
+
+ public static void main(String args[]){
+ Map points=new HashMap<>();
+ DelegatingVehicleTracker delegatingVehicleTracker=new DelegatingVehicleTracker(points);
+ Map point1=delegatingVehicleTracker.getLocations();
+ delegatingVehicleTracker.setLocation("asdasda",123,123);
+ System.out.println(delegatingVehicleTracker.getLocations().get("asdasda"));
+ }
+}
+
diff --git a/src/main/test/Ensemble.java b/src/main/test/Ensemble.java
new file mode 100644
index 0000000..9a3be77
--- /dev/null
+++ b/src/main/test/Ensemble.java
@@ -0,0 +1,16 @@
+// Enum with integer data stored in an instance field
+public enum Ensemble {
+ SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
+ SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8),
+ NONET(9), DECTET(10), TRIPLE_QUARTET(12);
+
+ private final int numberOfMusicians;
+ Ensemble(int size) { this.numberOfMusicians = size; }
+ public int numberOfMusicians() { return ordinal(); }
+ public static void main(String args[]){
+ Ensemble ensemble=Ensemble.OCTET;
+
+ System.out.println(ensemble.ordinal());
+
+ }
+}
diff --git a/src/main/test/ExtendedOperation.java b/src/main/test/ExtendedOperation.java
new file mode 100644
index 0000000..45e192d
--- /dev/null
+++ b/src/main/test/ExtendedOperation.java
@@ -0,0 +1,50 @@
+// Emulated extension enum - Page 166-167
+
+import java.util.*;
+
+public enum ExtendedOperation implements Operation {
+ EXP("^") {
+ public double apply(double x, double y) {
+ return Math.pow(x, y);
+ }
+ },
+ REMAINDER("%") {
+ public double apply(double x, double y) {
+ return x % y;
+ }
+ };
+
+ private final String symbol;
+ ExtendedOperation(String symbol) {
+ this.symbol = symbol;
+ }
+ @Override public String toString() {
+ return symbol;
+ }
+
+ // Test class to exercise all operations in "extension enum" - Page 167
+ public static void main(String[] args) {
+ double x = Double.parseDouble(String.valueOf(23));
+ double y = Double.parseDouble(String.valueOf(32));
+ test(ExtendedOperation.class, x, y);
+
+ System.out.println(); // Print a blank line between tests
+ test2(Arrays.asList(ExtendedOperation.values()), x, y);
+ }
+
+ // test parameter is a bounded type token (Item 29)
+ private static & Operation> void test(
+ Class opSet, double x, double y) {
+ for (Operation op : opSet.getEnumConstants())
+ System.out.printf("%f %s %f = %f%n",
+ x, op, y, op.apply(x, y));
+ }
+
+ // test parameter is a bounded wildcard type (Item 28)
+ private static void test2(Collection extends Operation> opSet,
+ double x, double y) {
+ for (Operation op : opSet)
+ System.out.printf("%f %s %f = %f%n",
+ x, op, y, op.apply(x, y));
+ }
+}
diff --git a/src/main/test/Father.java b/src/main/test/Father.java
new file mode 100644
index 0000000..37f7aed
--- /dev/null
+++ b/src/main/test/Father.java
@@ -0,0 +1,37 @@
+/**
+ * Created by inst1 on 2017/7/7.
+ */
+public class Father {
+
+
+ static int length;
+ static int height;
+ static int[][] arr1 = {{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
+ public static boolean Find(int target, int[][] array) {
+ height=array[0].length;
+ length=array.length;
+
+ return cut(target,length-1,0,array);
+ }
+ public static boolean cut(int target, int left, int down, int[][] array){
+
+ if(left<0||down==height){
+ return false;
+ }
+
+ if(array[left][down]==target){
+ return true;
+ }
+ else if(array[left][down]>target){
+ return cut(target,--left,down,array);
+ }
+ else {
+ return cut(target,left,++down,array);
+ }
+
+
+ }
+ public static void main(String args[]){
+ System.out.print(Find(7,arr1));
+
+ }}
\ No newline at end of file
diff --git a/src/main/test/Generator.java b/src/main/test/Generator.java
new file mode 100644
index 0000000..d106de6
--- /dev/null
+++ b/src/main/test/Generator.java
@@ -0,0 +1,4 @@
+//: net/mindview/util/Generator.java
+// A generic interface.
+
+public interface Generator { T next(); } ///:~
diff --git a/src/main/test/Herb.java b/src/main/test/Herb.java
new file mode 100644
index 0000000..c8d1ce3
--- /dev/null
+++ b/src/main/test/Herb.java
@@ -0,0 +1,40 @@
+// Using an EnumMap to associate data with an enum - Pages 161-162
+
+import java.util.*;
+
+// Simplistic class representing a culinary herb - Page 161
+public class Herb {
+ public enum Type { ANNUAL, PERENNIAL, BIENNIAL }
+
+ private final String name;
+ private final Type type;
+
+ Herb(String name, Type type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ @Override public String toString() {
+ return name;
+ }
+
+ public static void main(String[] args) {
+ Herb[] garden = {
+ new Herb("Basil", Type.ANNUAL),
+ new Herb("Carroway", Type.BIENNIAL),
+ new Herb("Dill", Type.ANNUAL),
+ new Herb("Lavendar", Type.PERENNIAL),
+ new Herb("Parsley", Type.BIENNIAL),
+ new Herb("Rosemary", Type.PERENNIAL)
+ };
+
+ // Using an EnumMap to associate data with an enum - Page 162
+ Map> herbsByType =
+ new EnumMap>(Type.class);
+ for (Type t : Type.values())
+ herbsByType.put(t, new HashSet());
+ for (Herb h : garden)
+ herbsByType.get(h.type).add(h);
+ System.out.println(herbsByType);
+ }
+}
diff --git a/src/main/test/Item41/CollectionClassifier.java b/src/main/test/Item41/CollectionClassifier.java
new file mode 100644
index 0000000..12bd152
--- /dev/null
+++ b/src/main/test/Item41/CollectionClassifier.java
@@ -0,0 +1,29 @@
+package Item41;// Broken! - What does this program print?
+
+import java.util.*;
+import java.math.*;
+
+public class CollectionClassifier {
+ public static String classify(Set> s) {
+ return "Set";
+ }
+
+ public static String classify(List> lst) {
+ return "List";
+ }
+
+ public static String classify(Collection> c) {
+ return "Unknown Collection";
+ }
+
+ public static void main(String[] args) {
+ Collection>[] collections = {
+ new HashSet(),
+ new ArrayList(),
+ new HashMap().values()
+ };
+
+ for (Collection> c : collections)
+ System.out.println(classify(c));
+ }
+}
diff --git a/src/main/test/Item41/Overriding.java b/src/main/test/Item41/Overriding.java
new file mode 100644
index 0000000..bddd43d
--- /dev/null
+++ b/src/main/test/Item41/Overriding.java
@@ -0,0 +1,23 @@
+package Item41;// Overriding demonstration - Page 192
+
+class Wine {
+ String name() { return "wine"; }
+}
+
+class SparklingWine extends Wine {
+ @Override String name() { return "sparkling wine"; }
+}
+
+class Champagne extends SparklingWine {
+ @Override String name() { return "champagne"; }
+}
+
+public class Overriding {
+ public static void main(String[] args) {
+ Wine[] wines = {
+ new Wine(), new SparklingWine(), new Champagne()
+ };
+ for (Wine wine : wines)
+ System.out.println(wine.name());
+ }
+}
diff --git a/src/main/test/Item41/SetList.java b/src/main/test/Item41/SetList.java
new file mode 100644
index 0000000..5d1f52a
--- /dev/null
+++ b/src/main/test/Item41/SetList.java
@@ -0,0 +1,23 @@
+package Item41;// What does this program print? - Page 194
+
+import java.util.*;
+
+public class SetList {
+ public static void main(String[] args) {
+ Set set = new TreeSet();
+ List list = new ArrayList();
+
+ for (int i = -3; i < 3; i++) {
+ set.add(i);
+ list.add(i);
+ }
+
+ for (int i = 0; i < 3; i++) {
+ list.remove(i);
+ set.remove(i);
+
+ }
+
+ System.out.println(set + " " + list);
+ }
+}
diff --git a/src/main/test/MonitorVehicleTracker.java b/src/main/test/MonitorVehicleTracker.java
new file mode 100644
index 0000000..020c4de
--- /dev/null
+++ b/src/main/test/MonitorVehicleTracker.java
@@ -0,0 +1,61 @@
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * MonitorVehicleTracker
+ *
+ * Monitor-based vehicle tracker implementation
+ *
+ * @author Brian Goetz and Tim Peierls
+ */
+ public class MonitorVehicleTracker {
+ private final Map locations;
+
+ public MonitorVehicleTracker(Map locations) {
+ this.locations =deepCopy(locations);
+ }
+
+ public synchronized Map getLocations() {
+ return locations;
+ }
+
+ public synchronized MutablePoint getLocation(String id) {
+ MutablePoint loc = locations.get(id);
+ return loc == null ? null : new MutablePoint(loc);
+ }
+
+ public synchronized void setLocation(String id, int x, int y) {
+ MutablePoint loc = locations.get(id);
+ if (loc == null)
+ throw new IllegalArgumentException("No such ID: " + id);
+ loc.x = x;
+ loc.y = y;
+ }
+
+ private static Map deepCopy(Map m) {
+ Map result = new HashMap();
+
+ for (String id : m.keySet())
+ result.put(id, new MutablePoint(m.get(id)));
+
+ return Collections.unmodifiableMap(result);
+ }
+
+ public static void main(String qrgs[]){
+ Map locations=new HashMap();
+
+ MonitorVehicleTracker monitorVehicleTracker=new MonitorVehicleTracker(locations);
+ Map locations1=monitorVehicleTracker.getLocations();
+ System.out.println(locations==locations1);
+
+ locations1=monitorVehicleTracker.getLocations();
+ locations1.put("test",new MutablePoint());
+ locations1=monitorVehicleTracker.getLocations();
+ System.out.println(locations1);
+ AtomicLong as=new AtomicLong(213213);
+
+ }
+}
+
diff --git a/src/main/test/MutablePoint.java b/src/main/test/MutablePoint.java
new file mode 100644
index 0000000..751c22b
--- /dev/null
+++ b/src/main/test/MutablePoint.java
@@ -0,0 +1,20 @@
+/**
+ * MutablePoint
+ *
+ * Mutable Point class similar to java.awt.Point
+ *
+ * @author Brian Goetz and Tim Peierls
+ */
+public class MutablePoint {
+ public int x, y;
+
+ public MutablePoint() {
+ x = 0;
+ y = 0;
+ }
+
+ public MutablePoint(MutablePoint p) {
+ this.x = p.x;
+ this.y = p.y;
+ }
+}
diff --git a/src/main/test/Operation.java b/src/main/test/Operation.java
new file mode 100644
index 0000000..a8ffdbf
--- /dev/null
+++ b/src/main/test/Operation.java
@@ -0,0 +1,4 @@
+// Emulated extensible enum using an interface - Page 165
+public interface Operation {
+ double apply(double x, double y);
+}
diff --git a/src/main/test/Phase.java b/src/main/test/Phase.java
new file mode 100644
index 0000000..f86c2b2
--- /dev/null
+++ b/src/main/test/Phase.java
@@ -0,0 +1,48 @@
+// Using a nested EnumMap to associate data with enum pairs - Pags 163-164
+
+import java.util.*;
+
+public enum Phase {
+ SOLID, LIQUID, GAS;
+
+ public enum Transition {
+ MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID),
+ BOIL(LIQUID, GAS), CONDENSE(GAS, LIQUID),
+ SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID);
+
+ private final Phase src;
+ private final Phase dst;
+
+ Transition(Phase src, Phase dst) {
+ this.src = src;
+ this.dst = dst;
+ }
+ // Initialize the phase transition map
+ private static final Map> m =
+ new EnumMap>(Phase.class);
+ static {
+ for (Phase p : Phase.values())
+ m.put(p,new EnumMap(Phase.class));
+ for (Transition trans : Transition.values()) {
+ m.get(trans.src).put(trans.dst, trans);
+ }
+ int asd=123;
+
+ }
+
+ public static Transition from(Phase src, Phase dst) {
+ return m.get(src).get(dst);
+ }
+ }
+
+ // Simple demo program - prints a sloppy table
+ public static void main(String[] args) {
+ for (Phase src : Phase.values())
+ for (Phase dst : Phase.values())
+ if (src != dst)
+ System.out.printf("%s to %s : %s %n", src, dst,
+ Transition.from(src, dst));
+
+ int asd=21;
+ }
+}
diff --git a/src/main/test/PojoBug.java b/src/main/test/PojoBug.java
new file mode 100644
index 0000000..e53478b
--- /dev/null
+++ b/src/main/test/PojoBug.java
@@ -0,0 +1,14 @@
+/**
+ * Created by inst1 on 2017/7/17.
+ */
+public class PojoBug {
+ private aaa aa;
+
+ public aaa getAa() {
+ return aa;
+ }
+
+ public void setAa(aaa aa) {
+ this.aa = aa;
+ }
+}
diff --git a/src/main/test/Stack.java b/src/main/test/Stack.java
new file mode 100644
index 0000000..4a176d8
--- /dev/null
+++ b/src/main/test/Stack.java
@@ -0,0 +1,44 @@
+// Can you spot the "memory leak"?
+
+import java.util.*;
+
+public class Stack {
+ private Object[] elements;
+ private int size = 0;
+ private static final int DEFAULT_INITIAL_CAPACITY = 16;
+
+ public Stack() {
+ elements = new Object[DEFAULT_INITIAL_CAPACITY];
+ }
+
+ public void push(Object e) {
+ ensureCapacity();
+ elements[size++] = e;
+ }
+
+ public Object pop() {
+ if (size == 0)
+ throw new EmptyStackException();
+ return elements[--size];
+ }
+
+ /**
+ * Ensure space for at least one more element, roughly
+ * doubling the capacity each time the array needs to grow.
+ */
+ private void ensureCapacity() {
+ if (elements.length == size)
+ elements = Arrays.copyOf(elements, 2 * size + 1);
+ }
+ public static void main(String[] args){
+ Stack stack=new Stack();
+ while(true){
+ for(int i=0;i<16;i++){
+ stack.push(new String("addasdasdas"));
+ }
+ for(int j=0;j<16;j++){
+ stack.pop();
+ }
+ }
+ }
+}
diff --git a/src/main/test/Sub.java b/src/main/test/Sub.java
new file mode 100644
index 0000000..1babd26
--- /dev/null
+++ b/src/main/test/Sub.java
@@ -0,0 +1,19 @@
+import java.util.*;
+
+public class Sub extends Super {
+ private final Date date; // Blank final, set by constructor
+
+ Sub() {
+ date = new Date();
+ }
+
+ // Overriding method invoked by superclass constructor
+ @Override public void overrideMe() {
+ System.out.println(date);
+ }
+
+ public static void main(String[] args) {
+ Sub sub = new Sub();
+ sub.overrideMe();
+ }
+}
diff --git a/src/main/test/Super.java b/src/main/test/Super.java
new file mode 100644
index 0000000..cd5ad1a
--- /dev/null
+++ b/src/main/test/Super.java
@@ -0,0 +1,8 @@
+public class Super {
+ // Broken - constructor invokes an overridable method
+ public Super() {
+ overrideMe();
+ }
+ public void overrideMe() {
+ }
+}
diff --git a/src/main/test/TestSum.java b/src/main/test/TestSum.java
new file mode 100644
index 0000000..e77305b
--- /dev/null
+++ b/src/main/test/TestSum.java
@@ -0,0 +1,16 @@
+import java.util.Date;
+
+/**
+ * Created by inst1 on 2017/7/12.
+ */
+public class TestSum {
+ public static void main(String[] args){
+ long start=new Date().getTime();
+ long sum=0L;
+ for(long i=0;i
+ * If the Throwable is an Error, throw it; if it is a
+ * RuntimeException return it, otherwise throw IllegalStateException
+ */
+ public static RuntimeException launderThrowable(Throwable t) {
+ if (t instanceof RuntimeException)
+ return (RuntimeException) t;
+ else if (t instanceof Error)
+ throw (Error) t;
+ else
+ throw new IllegalStateException("Not unchecked", t);
+ }
+}
diff --git a/src/main/test/concurrent/PrimeProducer.java b/src/main/test/concurrent/PrimeProducer.java
new file mode 100644
index 0000000..dd53725
--- /dev/null
+++ b/src/main/test/concurrent/PrimeProducer.java
@@ -0,0 +1,33 @@
+package concurrent;
+
+import java.math.BigInteger;
+import java.util.concurrent.*;
+
+/**
+ * PrimeProducer
+ *
+ * Using interruption for cancellation
+ *
+ * @author Brian Goetz and Tim Peierls
+ */
+public class PrimeProducer extends Thread {
+ private final BlockingQueue queue;
+
+ PrimeProducer(BlockingQueue queue) {
+ this.queue = queue;
+ }
+
+ public void run() {
+ try {
+ BigInteger p = BigInteger.ONE;
+ while (!Thread.currentThread().isInterrupted())
+ queue.put(p = p.nextProbablePrime());
+ } catch (InterruptedException consumed) {
+ /* Allow thread to exit */
+ }
+ }
+
+ public void cancel() {
+ interrupt();
+ }
+}
diff --git a/src/main/test/concurrent/TestHarness.java b/src/main/test/concurrent/TestHarness.java
new file mode 100644
index 0000000..82f26eb
--- /dev/null
+++ b/src/main/test/concurrent/TestHarness.java
@@ -0,0 +1,41 @@
+package concurrent;
+
+import java.util.concurrent.*;
+
+/**
+ * TestHarness
+ *
+ * Using CountDownLatch for starting and stopping threads in timing tests
+ *
+ * @author Brian Goetz and Tim Peierls
+ */
+public class TestHarness {
+ public long timeTasks(int nThreads, final Runnable task)
+ throws InterruptedException {
+ final CountDownLatch startGate = new CountDownLatch(1);
+ final CountDownLatch endGate = new CountDownLatch(nThreads);
+
+ for (int i = 0; i < nThreads; i++) {
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ startGate.await();
+ try {
+ task.run();
+ } finally {
+ endGate.countDown();
+ }
+ } catch (InterruptedException ignored) {
+ }
+ }
+ };
+ t.start();
+ }
+
+ long start = System.nanoTime();
+ startGate.countDown();
+ endGate.await();
+ long end = System.nanoTime();
+ return end - start;
+ }
+}
diff --git a/src/main/test/concurrent/TestIntterupt.java b/src/main/test/concurrent/TestIntterupt.java
new file mode 100644
index 0000000..0ccbe4f
--- /dev/null
+++ b/src/main/test/concurrent/TestIntterupt.java
@@ -0,0 +1,51 @@
+package concurrent;
+
+/**
+ * Created by inst1 on 2017/7/25.
+ */
+public class TestIntterupt implements Runnable {
+ @Override
+ public void run() {
+ try {
+ another();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ public static void main(String args[]){
+ Thread t=new Thread(new TestIntterupt());
+ t.start();
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ System.out.println("开始尝试终止");
+ t.interrupt();
+
+ }
+ void synchronize() throws InterruptedException {
+ while(!Thread.currentThread().isInterrupted()){
+
+ }
+ throw new InterruptedException();
+
+ }
+ void another() throws InterruptedException{
+ int i=0;
+ try {
+ synchronize();
+ while (true) {
+ i++;
+
+ }
+ }
+ catch(InterruptedException e){
+
+ Thread.currentThread().interrupt();
+ }
+ while(true){
+
+ }
+ }
+}
diff --git a/src/main/test/sdadsad.java b/src/main/test/sdadsad.java
new file mode 100644
index 0000000..6261005
--- /dev/null
+++ b/src/main/test/sdadsad.java
@@ -0,0 +1,55 @@
+/**
+ * Created by inst1 on 2017/9/17.
+ */
+public class sdadsad {
+ public static int Ip2Int(String strIp){
+ String[] ss = strIp.split("\\.");
+ if(ss.length != 4){
+ return 0;
+ }
+ byte[] bytes = new byte[ss.length];
+ for(int i = 0; i < bytes.length; i++){
+ bytes[i] = (byte) Integer.parseInt(ss[i]);
+ }
+ return byte2Int(bytes);
+ }
+ /**
+ * 将int型ip转成String型ip
+ * @param intIp
+ * @return
+ */
+ public static String int2Ip(int intIp){
+ byte[] bytes = int2byte(intIp);
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i < 4; i++){
+ sb.append(bytes[i] & 0xFF);
+ if(i < 3){
+ sb.append(".");
+ }
+ }
+ return sb.toString();
+ }
+
+ private static byte[] int2byte(int i) {
+ byte[] bytes = new byte[4];
+ bytes[0] = (byte) (0xff & i);
+ bytes[1] = (byte) ((0xff00 & i) >> 8);
+ bytes[2] = (byte) ((0xff0000 & i) >> 16);
+ bytes[3] = (byte) ((0xff000000 & i) >> 24);
+ return bytes;
+ }
+ private static int byte2Int(byte[] bytes) {
+ int n = bytes[0] & 0xFF;
+ n |= ((bytes[1] << 8) & 0xFF00);
+ n |= ((bytes[2] << 16) & 0xFF0000);
+ n |= ((bytes[3] << 24) & 0xFF000000);
+ return n;
+ }
+
+ public static void main(String[] args) {
+ String ip1 = "192.168.0.1";
+ int intIp = Ip2Int(ip1);
+ String ip2 = int2Ip(intIp);
+ System.out.println(ip2);
+ }
+}
diff --git a/src/main/test/test.java b/src/main/test/test.java
new file mode 100644
index 0000000..1235538
--- /dev/null
+++ b/src/main/test/test.java
@@ -0,0 +1,16 @@
+/**
+ * Created by inst1 on 2017/7/16.
+ */
+public class test
+{
+ static int i=0;
+
+ public static void main(String args[]){
+ eee(++i);
+
+ }
+
+ static void eee(int i){
+ System.out.print(i);
+ }
+}
diff --git a/src/main/test/testThread.java b/src/main/test/testThread.java
new file mode 100644
index 0000000..844dcb1
--- /dev/null
+++ b/src/main/test/testThread.java
@@ -0,0 +1,17 @@
+/**
+ * Created by inst1 on 2017/7/16.
+ */
+public class testThread implements Runnable {
+ int count=0;
+
+ @Override
+ public void run() {
+ for(int i=0;i<10000;i++) {
+ add();
+ }
+ }
+ public void add(){
+ count++;
+ System.out.println(this.hashCode() + ":" + count);
+ }
+}
diff --git a/src/main/webapp/WEB-INF/views/echarts.js b/src/main/webapp/WEB-INF/views/echarts.js
new file mode 100644
index 0000000..60c5d61
--- /dev/null
+++ b/src/main/webapp/WEB-INF/views/echarts.js
@@ -0,0 +1,63738 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory();
+ else if(typeof define === 'function' && define.amd)
+ define([], factory);
+ else if(typeof exports === 'object')
+ exports["echarts"] = factory();
+ else
+ root["echarts"] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId])
+/******/ return installedModules[moduleId].exports;
+
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ exports: {},
+/******/ id: moduleId,
+/******/ loaded: false
+/******/ };
+
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+
+/******/ // Flag the module as loaded
+/******/ module.loaded = true;
+
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+
+
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "";
+
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ function(module, exports, __webpack_require__) {
+
+ /**
+ * Export echarts as CommonJS module
+ */
+ module.exports = __webpack_require__(1);
+
+ // Import all charts and components
+ __webpack_require__(99);
+ __webpack_require__(133);
+ __webpack_require__(138);
+ __webpack_require__(147);
+ __webpack_require__(151);
+
+ __webpack_require__(161);
+ __webpack_require__(182);
+ __webpack_require__(194);
+ __webpack_require__(215);
+ __webpack_require__(219);
+ __webpack_require__(223);
+ __webpack_require__(238);
+ __webpack_require__(244);
+ __webpack_require__(251);
+ __webpack_require__(257);
+ __webpack_require__(261);
+ __webpack_require__(269);
+
+ __webpack_require__(112);
+ __webpack_require__(273);
+ __webpack_require__(279);
+ __webpack_require__(283);
+ __webpack_require__(294);
+ __webpack_require__(224);
+ __webpack_require__(297);
+ __webpack_require__(303);
+
+ __webpack_require__(315);
+
+ __webpack_require__(316);
+ __webpack_require__(330);
+
+ __webpack_require__(345);
+ __webpack_require__(351);
+ __webpack_require__(354);
+
+ __webpack_require__(357);
+ __webpack_require__(366);
+
+ __webpack_require__(379);
+
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+ // Enable DEV mode when using source code without build. which has no __DEV__ variable
+ // In build process 'typeof __DEV__' will be replace with 'boolean'
+ // So this code will be removed or disabled anyway after built.
+ if (false) {
+ // In browser
+ if (typeof window !== 'undefined') {
+ window.__DEV__ = true;
+ }
+ // In node
+ else if (typeof global !== 'undefined') {
+ global.__DEV__ = true;
+ }
+ }
+
+ /*!
+ * ECharts, a javascript interactive chart library.
+ *
+ * Copyright (c) 2015, Baidu Inc.
+ * All rights reserved.
+ *
+ * LICENSE
+ * https://github.com/ecomfe/echarts/blob/master/LICENSE.txt
+ */
+
+ /**
+ * @module echarts
+ */
+
+
+ var env = __webpack_require__(2);
+
+ var GlobalModel = __webpack_require__(3);
+ var ExtensionAPI = __webpack_require__(25);
+ var CoordinateSystemManager = __webpack_require__(26);
+ var OptionManager = __webpack_require__(27);
+
+ var ComponentModel = __webpack_require__(19);
+ var SeriesModel = __webpack_require__(28);
+
+ var ComponentView = __webpack_require__(29);
+ var ChartView = __webpack_require__(42);
+ var graphic = __webpack_require__(43);
+
+ var zrender = __webpack_require__(81);
+ var zrUtil = __webpack_require__(4);
+ var colorTool = __webpack_require__(39);
+ var Eventful = __webpack_require__(33);
+ var timsort = __webpack_require__(85);
+
+ var each = zrUtil.each;
+
+ var PRIORITY_PROCESSOR_FILTER = 1000;
+ var PRIORITY_PROCESSOR_STATISTIC = 5000;
+
+
+ var PRIORITY_VISUAL_LAYOUT = 1000;
+ var PRIORITY_VISUAL_GLOBAL = 2000;
+ var PRIORITY_VISUAL_CHART = 3000;
+ var PRIORITY_VISUAL_COMPONENT = 4000;
+ var PRIORITY_VISUAL_BRUSH = 5000;
+
+ // Main process have three entries: `setOption`, `dispatchAction` and `resize`,
+ // where they must not be invoked nestedly, except the only case: invoke
+ // dispatchAction with updateMethod "none" in main process.
+ // This flag is used to carry out this rule.
+ // All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]).
+ var IN_MAIN_PROCESS = '__flag_in_main_process';
+ var HAS_GRADIENT_OR_PATTERN_BG = '_hasGradientOrPatternBg';
+
+
+ var OPTION_UPDATED = '_optionUpdated';
+
+ function createRegisterEventWithLowercaseName(method) {
+ return function (eventName, handler, context) {
+ // Event name is all lowercase
+ eventName = eventName && eventName.toLowerCase();
+ Eventful.prototype[method].call(this, eventName, handler, context);
+ };
+ }
+ /**
+ * @module echarts~MessageCenter
+ */
+ function MessageCenter() {
+ Eventful.call(this);
+ }
+ MessageCenter.prototype.on = createRegisterEventWithLowercaseName('on');
+ MessageCenter.prototype.off = createRegisterEventWithLowercaseName('off');
+ MessageCenter.prototype.one = createRegisterEventWithLowercaseName('one');
+ zrUtil.mixin(MessageCenter, Eventful);
+ /**
+ * @module echarts~ECharts
+ */
+ function ECharts (dom, theme, opts) {
+ opts = opts || {};
+
+ // Get theme by name
+ if (typeof theme === 'string') {
+ theme = themeStorage[theme];
+ }
+
+ /**
+ * @type {string}
+ */
+ this.id;
+ /**
+ * Group id
+ * @type {string}
+ */
+ this.group;
+ /**
+ * @type {HTMLDomElement}
+ * @private
+ */
+ this._dom = dom;
+ /**
+ * @type {module:zrender/ZRender}
+ * @private
+ */
+ this._zr = zrender.init(dom, {
+ renderer: opts.renderer || 'canvas',
+ devicePixelRatio: opts.devicePixelRatio
+ });
+
+ /**
+ * @type {Object}
+ * @private
+ */
+ this._theme = zrUtil.clone(theme);
+
+ /**
+ * @type {Array.}
+ * @private
+ */
+ this._chartsViews = [];
+
+ /**
+ * @type {Object.}
+ * @private
+ */
+ this._chartsMap = {};
+
+ /**
+ * @type {Array.}
+ * @private
+ */
+ this._componentsViews = [];
+
+ /**
+ * @type {Object.}
+ * @private
+ */
+ this._componentsMap = {};
+
+ /**
+ * @type {module:echarts/ExtensionAPI}
+ * @private
+ */
+ this._api = new ExtensionAPI(this);
+
+ /**
+ * @type {module:echarts/CoordinateSystem}
+ * @private
+ */
+ this._coordSysMgr = new CoordinateSystemManager();
+
+ Eventful.call(this);
+
+ /**
+ * @type {module:echarts~MessageCenter}
+ * @private
+ */
+ this._messageCenter = new MessageCenter();
+
+ // Init mouse events
+ this._initEvents();
+
+ // In case some people write `window.onresize = chart.resize`
+ this.resize = zrUtil.bind(this.resize, this);
+
+ // Can't dispatch action during rendering procedure
+ this._pendingActions = [];
+ // Sort on demand
+ function prioritySortFunc(a, b) {
+ return a.prio - b.prio;
+ }
+ timsort(visualFuncs, prioritySortFunc);
+ timsort(dataProcessorFuncs, prioritySortFunc);
+
+ this._zr.animation.on('frame', this._onframe, this);
+ }
+
+ var echartsProto = ECharts.prototype;
+
+ echartsProto._onframe = function () {
+ // Lazy update
+ if (this[OPTION_UPDATED]) {
+
+ this[IN_MAIN_PROCESS] = true;
+
+ updateMethods.prepareAndUpdate.call(this);
+
+ this[IN_MAIN_PROCESS] = false;
+
+ this[OPTION_UPDATED] = false;
+ }
+ };
+ /**
+ * @return {HTMLDomElement}
+ */
+ echartsProto.getDom = function () {
+ return this._dom;
+ };
+
+ /**
+ * @return {module:zrender~ZRender}
+ */
+ echartsProto.getZr = function () {
+ return this._zr;
+ };
+
+ /**
+ * @param {Object} option
+ * @param {boolean} notMerge
+ * @param {boolean} [lazyUpdate=false] Useful when setOption frequently.
+ */
+ echartsProto.setOption = function (option, notMerge, lazyUpdate) {
+ if (true) {
+ zrUtil.assert(!this[IN_MAIN_PROCESS], '`setOption` should not be called during main process.');
+ }
+
+ this[IN_MAIN_PROCESS] = true;
+
+ if (!this._model || notMerge) {
+ var optionManager = new OptionManager(this._api);
+ var theme = this._theme;
+ var ecModel = this._model = new GlobalModel(null, null, theme, optionManager);
+ ecModel.init(null, null, theme, optionManager);
+ }
+
+ this._model.setOption(option, optionPreprocessorFuncs);
+
+ if (lazyUpdate) {
+ this[OPTION_UPDATED] = true;
+ }
+ else {
+ updateMethods.prepareAndUpdate.call(this);
+ this._zr.refreshImmediately();
+ this[OPTION_UPDATED] = false;
+ }
+
+ this[IN_MAIN_PROCESS] = false;
+
+ this._flushPendingActions();
+ };
+
+ /**
+ * @DEPRECATED
+ */
+ echartsProto.setTheme = function () {
+ console.log('ECharts#setTheme() is DEPRECATED in ECharts 3.0');
+ };
+
+ /**
+ * @return {module:echarts/model/Global}
+ */
+ echartsProto.getModel = function () {
+ return this._model;
+ };
+
+ /**
+ * @return {Object}
+ */
+ echartsProto.getOption = function () {
+ return this._model && this._model.getOption();
+ };
+
+ /**
+ * @return {number}
+ */
+ echartsProto.getWidth = function () {
+ return this._zr.getWidth();
+ };
+
+ /**
+ * @return {number}
+ */
+ echartsProto.getHeight = function () {
+ return this._zr.getHeight();
+ };
+
+ /**
+ * Get canvas which has all thing rendered
+ * @param {Object} opts
+ * @param {string} [opts.backgroundColor]
+ */
+ echartsProto.getRenderedCanvas = function (opts) {
+ if (!env.canvasSupported) {
+ return;
+ }
+ opts = opts || {};
+ opts.pixelRatio = opts.pixelRatio || 1;
+ opts.backgroundColor = opts.backgroundColor
+ || this._model.get('backgroundColor');
+ var zr = this._zr;
+ var list = zr.storage.getDisplayList();
+ // Stop animations
+ zrUtil.each(list, function (el) {
+ el.stopAnimation(true);
+ });
+ return zr.painter.getRenderedCanvas(opts);
+ };
+ /**
+ * @return {string}
+ * @param {Object} opts
+ * @param {string} [opts.type='png']
+ * @param {string} [opts.pixelRatio=1]
+ * @param {string} [opts.backgroundColor]
+ */
+ echartsProto.getDataURL = function (opts) {
+ opts = opts || {};
+ var excludeComponents = opts.excludeComponents;
+ var ecModel = this._model;
+ var excludesComponentViews = [];
+ var self = this;
+
+ each(excludeComponents, function (componentType) {
+ ecModel.eachComponent({
+ mainType: componentType
+ }, function (component) {
+ var view = self._componentsMap[component.__viewId];
+ if (!view.group.ignore) {
+ excludesComponentViews.push(view);
+ view.group.ignore = true;
+ }
+ });
+ });
+
+ var url = this.getRenderedCanvas(opts).toDataURL(
+ 'image/' + (opts && opts.type || 'png')
+ );
+
+ each(excludesComponentViews, function (view) {
+ view.group.ignore = false;
+ });
+ return url;
+ };
+
+
+ /**
+ * @return {string}
+ * @param {Object} opts
+ * @param {string} [opts.type='png']
+ * @param {string} [opts.pixelRatio=1]
+ * @param {string} [opts.backgroundColor]
+ */
+ echartsProto.getConnectedDataURL = function (opts) {
+ if (!env.canvasSupported) {
+ return;
+ }
+ var groupId = this.group;
+ var mathMin = Math.min;
+ var mathMax = Math.max;
+ var MAX_NUMBER = Infinity;
+ if (connectedGroups[groupId]) {
+ var left = MAX_NUMBER;
+ var top = MAX_NUMBER;
+ var right = -MAX_NUMBER;
+ var bottom = -MAX_NUMBER;
+ var canvasList = [];
+ var dpr = (opts && opts.pixelRatio) || 1;
+ for (var id in instances) {
+ var chart = instances[id];
+ if (chart.group === groupId) {
+ var canvas = chart.getRenderedCanvas(
+ zrUtil.clone(opts)
+ );
+ var boundingRect = chart.getDom().getBoundingClientRect();
+ left = mathMin(boundingRect.left, left);
+ top = mathMin(boundingRect.top, top);
+ right = mathMax(boundingRect.right, right);
+ bottom = mathMax(boundingRect.bottom, bottom);
+ canvasList.push({
+ dom: canvas,
+ left: boundingRect.left,
+ top: boundingRect.top
+ });
+ }
+ }
+
+ left *= dpr;
+ top *= dpr;
+ right *= dpr;
+ bottom *= dpr;
+ var width = right - left;
+ var height = bottom - top;
+ var targetCanvas = zrUtil.createCanvas();
+ targetCanvas.width = width;
+ targetCanvas.height = height;
+ var zr = zrender.init(targetCanvas);
+
+ each(canvasList, function (item) {
+ var img = new graphic.Image({
+ style: {
+ x: item.left * dpr - left,
+ y: item.top * dpr - top,
+ image: item.dom
+ }
+ });
+ zr.add(img);
+ });
+ zr.refreshImmediately();
+
+ return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png'));
+ }
+ else {
+ return this.getDataURL(opts);
+ }
+ };
+
+ var updateMethods = {
+
+
+ /**
+ * @param {Object} payload
+ * @private
+ */
+ update: function (payload) {
+ // console.time && console.time('update');
+
+ var ecModel = this._model;
+ var api = this._api;
+ var coordSysMgr = this._coordSysMgr;
+ var zr = this._zr;
+ // update before setOption
+ if (!ecModel) {
+ return;
+ }
+
+ // Fixme First time update ?
+ ecModel.restoreData();
+
+ // TODO
+ // Save total ecModel here for undo/redo (after restoring data and before processing data).
+ // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call.
+
+ // Create new coordinate system each update
+ // In LineView may save the old coordinate system and use it to get the orignal point
+ coordSysMgr.create(this._model, this._api);
+
+ processData.call(this, ecModel, api);
+
+ stackSeriesData.call(this, ecModel);
+
+ coordSysMgr.update(ecModel, api);
+
+ doVisualEncoding.call(this, ecModel, payload);
+
+ doRender.call(this, ecModel, payload);
+
+ // Set background
+ var backgroundColor = ecModel.get('backgroundColor') || 'transparent';
+
+ var painter = zr.painter;
+ // TODO all use clearColor ?
+ if (painter.isSingleCanvas && painter.isSingleCanvas()) {
+ zr.configLayer(0, {
+ clearColor: backgroundColor
+ });
+ }
+ else {
+ // In IE8
+ if (!env.canvasSupported) {
+ var colorArr = colorTool.parse(backgroundColor);
+ backgroundColor = colorTool.stringify(colorArr, 'rgb');
+ if (colorArr[3] === 0) {
+ backgroundColor = 'transparent';
+ }
+ }
+ if (backgroundColor.colorStops || backgroundColor.image) {
+ // Gradient background
+ // FIXME Fixed layer?
+ zr.configLayer(0, {
+ clearColor: backgroundColor
+ });
+ this[HAS_GRADIENT_OR_PATTERN_BG] = true;
+
+ this._dom.style.background = 'transparent';
+ }
+ else {
+ if (this[HAS_GRADIENT_OR_PATTERN_BG]) {
+ zr.configLayer(0, {
+ clearColor: null
+ });
+ }
+ this[HAS_GRADIENT_OR_PATTERN_BG] = false;
+
+ this._dom.style.background = backgroundColor;
+ }
+ }
+
+ // console.time && console.timeEnd('update');
+ },
+
+ // PENDING
+ /**
+ * @param {Object} payload
+ * @private
+ */
+ updateView: function (payload) {
+ var ecModel = this._model;
+
+ // update before setOption
+ if (!ecModel) {
+ return;
+ }
+
+ ecModel.eachSeries(function (seriesModel) {
+ seriesModel.getData().clearAllVisual();
+ });
+
+ doVisualEncoding.call(this, ecModel, payload);
+
+ invokeUpdateMethod.call(this, 'updateView', ecModel, payload);
+ },
+
+ /**
+ * @param {Object} payload
+ * @private
+ */
+ updateVisual: function (payload) {
+ var ecModel = this._model;
+
+ // update before setOption
+ if (!ecModel) {
+ return;
+ }
+
+ ecModel.eachSeries(function (seriesModel) {
+ seriesModel.getData().clearAllVisual();
+ });
+
+ doVisualEncoding.call(this, ecModel, payload);
+
+ invokeUpdateMethod.call(this, 'updateVisual', ecModel, payload);
+ },
+
+ /**
+ * @param {Object} payload
+ * @private
+ */
+ updateLayout: function (payload) {
+ var ecModel = this._model;
+
+ // update before setOption
+ if (!ecModel) {
+ return;
+ }
+
+ doLayout.call(this, ecModel, payload);
+
+ invokeUpdateMethod.call(this, 'updateLayout', ecModel, payload);
+ },
+
+ /**
+ * @param {Object} payload
+ * @private
+ */
+ highlight: function (payload) {
+ toggleHighlight.call(this, 'highlight', payload);
+ },
+
+ /**
+ * @param {Object} payload
+ * @private
+ */
+ downplay: function (payload) {
+ toggleHighlight.call(this, 'downplay', payload);
+ },
+
+ /**
+ * @param {Object} payload
+ * @private
+ */
+ prepareAndUpdate: function (payload) {
+ var ecModel = this._model;
+
+ prepareView.call(this, 'component', ecModel);
+
+ prepareView.call(this, 'chart', ecModel);
+
+ updateMethods.update.call(this, payload);
+ }
+ };
+
+ /**
+ * @param {Object} payload
+ * @private
+ */
+ function toggleHighlight(method, payload) {
+ var ecModel = this._model;
+
+ // dispatchAction before setOption
+ if (!ecModel) {
+ return;
+ }
+
+ ecModel.eachComponent(
+ {mainType: 'series', query: payload},
+ function (seriesModel, index) {
+ var chartView = this._chartsMap[seriesModel.__viewId];
+ if (chartView && chartView.__alive) {
+ chartView[method](
+ seriesModel, ecModel, this._api, payload
+ );
+ }
+ },
+ this
+ );
+ }
+
+ /**
+ * Resize the chart
+ */
+ echartsProto.resize = function () {
+ if (true) {
+ zrUtil.assert(!this[IN_MAIN_PROCESS], '`resize` should not be called during main process.');
+ }
+
+ this[IN_MAIN_PROCESS] = true;
+
+ this._zr.resize();
+
+ var optionChanged = this._model && this._model.resetOption('media');
+ updateMethods[optionChanged ? 'prepareAndUpdate' : 'update'].call(this);
+
+ // Resize loading effect
+ this._loadingFX && this._loadingFX.resize();
+
+ this[IN_MAIN_PROCESS] = false;
+
+ this._flushPendingActions();
+ };
+
+ /**
+ * Show loading effect
+ * @param {string} [name='default']
+ * @param {Object} [cfg]
+ */
+ echartsProto.showLoading = function (name, cfg) {
+ if (zrUtil.isObject(name)) {
+ cfg = name;
+ name = '';
+ }
+ name = name || 'default';
+
+ this.hideLoading();
+ if (!loadingEffects[name]) {
+ if (true) {
+ console.warn('Loading effects ' + name + ' not exists.');
+ }
+ return;
+ }
+ var el = loadingEffects[name](this._api, cfg);
+ var zr = this._zr;
+ this._loadingFX = el;
+
+ zr.add(el);
+ };
+
+ /**
+ * Hide loading effect
+ */
+ echartsProto.hideLoading = function () {
+ this._loadingFX && this._zr.remove(this._loadingFX);
+ this._loadingFX = null;
+ };
+
+ /**
+ * @param {Object} eventObj
+ * @return {Object}
+ */
+ echartsProto.makeActionFromEvent = function (eventObj) {
+ var payload = zrUtil.extend({}, eventObj);
+ payload.type = eventActionMap[eventObj.type];
+ return payload;
+ };
+
+ /**
+ * @pubilc
+ * @param {Object} payload
+ * @param {string} [payload.type] Action type
+ * @param {boolean} [silent=false] Whether trigger event.
+ */
+ echartsProto.dispatchAction = function (payload, silent) {
+ var actionWrap = actions[payload.type];
+ if (!actionWrap) {
+ return;
+ }
+
+ var actionInfo = actionWrap.actionInfo;
+ var updateMethod = actionInfo.update || 'update';
+
+ // if (__DEV__) {
+ // zrUtil.assert(
+ // !this[IN_MAIN_PROCESS],
+ // '`dispatchAction` should not be called during main process.'
+ // + 'unless updateMathod is "none".'
+ // );
+ // }
+
+ // May dispatchAction in rendering procedure
+ if (this[IN_MAIN_PROCESS]) {
+ this._pendingActions.push(payload);
+ return;
+ }
+
+ this[IN_MAIN_PROCESS] = true;
+
+ var payloads = [payload];
+ var batched = false;
+ // Batch action
+ if (payload.batch) {
+ batched = true;
+ payloads = zrUtil.map(payload.batch, function (item) {
+ item = zrUtil.defaults(zrUtil.extend({}, item), payload);
+ item.batch = null;
+ return item;
+ });
+ }
+
+ var eventObjBatch = [];
+ var eventObj;
+ var isHighlightOrDownplay = payload.type === 'highlight' || payload.type === 'downplay';
+ for (var i = 0; i < payloads.length; i++) {
+ var batchItem = payloads[i];
+ // Action can specify the event by return it.
+ eventObj = actionWrap.action(batchItem, this._model);
+ // Emit event outside
+ eventObj = eventObj || zrUtil.extend({}, batchItem);
+ // Convert type to eventType
+ eventObj.type = actionInfo.event || eventObj.type;
+ eventObjBatch.push(eventObj);
+
+ // Highlight and downplay are special.
+ isHighlightOrDownplay && updateMethods[updateMethod].call(this, batchItem);
+ }
+
+ if (updateMethod !== 'none' && !isHighlightOrDownplay) {
+ // Still dirty
+ if (this[OPTION_UPDATED]) {
+ // FIXME Pass payload ?
+ updateMethods.prepareAndUpdate.call(this, payload);
+ this[OPTION_UPDATED] = false;
+ }
+ else {
+ updateMethods[updateMethod].call(this, payload);
+ }
+ }
+
+ // Follow the rule of action batch
+ if (batched) {
+ eventObj = {
+ type: actionInfo.event || payload.type,
+ batch: eventObjBatch
+ };
+ }
+ else {
+ eventObj = eventObjBatch[0];
+ }
+
+ this[IN_MAIN_PROCESS] = false;
+
+ !silent && this._messageCenter.trigger(eventObj.type, eventObj);
+
+ this._flushPendingActions();
+
+ };
+
+ echartsProto._flushPendingActions = function () {
+ var pendingActions = this._pendingActions;
+ while (pendingActions.length) {
+ var payload = pendingActions.shift();
+ this.dispatchAction(payload);
+ }
+ };
+
+ /**
+ * Register event
+ * @method
+ */
+ echartsProto.on = createRegisterEventWithLowercaseName('on');
+ echartsProto.off = createRegisterEventWithLowercaseName('off');
+ echartsProto.one = createRegisterEventWithLowercaseName('one');
+
+ /**
+ * @param {string} methodName
+ * @private
+ */
+ function invokeUpdateMethod(methodName, ecModel, payload) {
+ var api = this._api;
+
+ // Update all components
+ each(this._componentsViews, function (component) {
+ var componentModel = component.__model;
+ component[methodName](componentModel, ecModel, api, payload);
+
+ updateZ(componentModel, component);
+ }, this);
+
+ // Upate all charts
+ ecModel.eachSeries(function (seriesModel, idx) {
+ var chart = this._chartsMap[seriesModel.__viewId];
+ chart[methodName](seriesModel, ecModel, api, payload);
+
+ updateZ(seriesModel, chart);
+
+ updateProgressiveAndBlend(seriesModel, chart);
+ }, this);
+
+ // If use hover layer
+ updateHoverLayerStatus(this._zr, ecModel);
+ }
+
+ /**
+ * Prepare view instances of charts and components
+ * @param {module:echarts/model/Global} ecModel
+ * @private
+ */
+ function prepareView(type, ecModel) {
+ var isComponent = type === 'component';
+ var viewList = isComponent ? this._componentsViews : this._chartsViews;
+ var viewMap = isComponent ? this._componentsMap : this._chartsMap;
+ var zr = this._zr;
+
+ for (var i = 0; i < viewList.length; i++) {
+ viewList[i].__alive = false;
+ }
+
+ ecModel[isComponent ? 'eachComponent' : 'eachSeries'](function (componentType, model) {
+ if (isComponent) {
+ if (componentType === 'series') {
+ return;
+ }
+ }
+ else {
+ model = componentType;
+ }
+
+ // Consider: id same and type changed.
+ var viewId = model.id + '_' + model.type;
+ var view = viewMap[viewId];
+ if (!view) {
+ var classType = ComponentModel.parseClassType(model.type);
+ var Clazz = isComponent
+ ? ComponentView.getClass(classType.main, classType.sub)
+ : ChartView.getClass(classType.sub);
+ if (Clazz) {
+ view = new Clazz();
+ view.init(ecModel, this._api);
+ viewMap[viewId] = view;
+ viewList.push(view);
+ zr.add(view.group);
+ }
+ else {
+ // Error
+ return;
+ }
+ }
+
+ model.__viewId = viewId;
+ view.__alive = true;
+ view.__id = viewId;
+ view.__model = model;
+ }, this);
+
+ for (var i = 0; i < viewList.length;) {
+ var view = viewList[i];
+ if (!view.__alive) {
+ zr.remove(view.group);
+ view.dispose(ecModel, this._api);
+ viewList.splice(i, 1);
+ delete viewMap[view.__id];
+ }
+ else {
+ i++;
+ }
+ }
+ }
+
+ /**
+ * Processor data in each series
+ *
+ * @param {module:echarts/model/Global} ecModel
+ * @private
+ */
+ function processData(ecModel, api) {
+ each(dataProcessorFuncs, function (process) {
+ process.func(ecModel, api);
+ });
+ }
+
+ /**
+ * @private
+ */
+ function stackSeriesData(ecModel) {
+ var stackedDataMap = {};
+ ecModel.eachSeries(function (series) {
+ var stack = series.get('stack');
+ var data = series.getData();
+ if (stack && data.type === 'list') {
+ var previousStack = stackedDataMap[stack];
+ if (previousStack) {
+ data.stackedOn = previousStack;
+ }
+ stackedDataMap[stack] = data;
+ }
+ });
+ }
+
+ /**
+ * Layout before each chart render there series, special visual encoding stage
+ *
+ * @param {module:echarts/model/Global} ecModel
+ * @private
+ */
+ function doLayout(ecModel, payload) {
+ var api = this._api;
+ each(visualFuncs, function (visual) {
+ if (visual.isLayout) {
+ visual.func(ecModel, api, payload);
+ }
+ });
+ }
+
+ /**
+ * Encode visual infomation from data after data processing
+ *
+ * @param {module:echarts/model/Global} ecModel
+ * @private
+ */
+ function doVisualEncoding(ecModel, payload) {
+ var api = this._api;
+ ecModel.clearColorPalette();
+ ecModel.eachSeries(function (seriesModel) {
+ seriesModel.clearColorPalette();
+ });
+ each(visualFuncs, function (visual) {
+ visual.func(ecModel, api, payload);
+ });
+ }
+
+ /**
+ * Render each chart and component
+ * @private
+ */
+ function doRender(ecModel, payload) {
+ var api = this._api;
+ // Render all components
+ each(this._componentsViews, function (componentView) {
+ var componentModel = componentView.__model;
+ componentView.render(componentModel, ecModel, api, payload);
+
+ updateZ(componentModel, componentView);
+ }, this);
+
+ each(this._chartsViews, function (chart) {
+ chart.__alive = false;
+ }, this);
+
+ // Render all charts
+ ecModel.eachSeries(function (seriesModel, idx) {
+ var chartView = this._chartsMap[seriesModel.__viewId];
+ chartView.__alive = true;
+ chartView.render(seriesModel, ecModel, api, payload);
+
+ chartView.group.silent = !!seriesModel.get('silent');
+
+ updateZ(seriesModel, chartView);
+
+ updateProgressiveAndBlend(seriesModel, chartView);
+
+ }, this);
+
+ // If use hover layer
+ updateHoverLayerStatus(this._zr, ecModel);
+
+ // Remove groups of unrendered charts
+ each(this._chartsViews, function (chart) {
+ if (!chart.__alive) {
+ chart.remove(ecModel, api);
+ }
+ }, this);
+ }
+
+ var MOUSE_EVENT_NAMES = [
+ 'click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'mouseup', 'globalout'
+ ];
+ /**
+ * @private
+ */
+ echartsProto._initEvents = function () {
+ each(MOUSE_EVENT_NAMES, function (eveName) {
+ this._zr.on(eveName, function (e) {
+ var ecModel = this.getModel();
+ var el = e.target;
+ if (el && el.dataIndex != null) {
+ var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex);
+ var params = dataModel && dataModel.getDataParams(el.dataIndex, el.dataType) || {};
+ params.event = e;
+ params.type = eveName;
+ this.trigger(eveName, params);
+ }
+ // If element has custom eventData of components
+ else if (el && el.eventData) {
+ this.trigger(eveName, el.eventData);
+ }
+ }, this);
+ }, this);
+
+ each(eventActionMap, function (actionType, eventType) {
+ this._messageCenter.on(eventType, function (event) {
+ this.trigger(eventType, event);
+ }, this);
+ }, this);
+ };
+
+ /**
+ * @return {boolean}
+ */
+ echartsProto.isDisposed = function () {
+ return this._disposed;
+ };
+
+ /**
+ * Clear
+ */
+ echartsProto.clear = function () {
+ this.setOption({ series: [] }, true);
+ };
+ /**
+ * Dispose instance
+ */
+ echartsProto.dispose = function () {
+ if (this._disposed) {
+ if (true) {
+ console.warn('Instance ' + this.id + ' has been disposed');
+ }
+ return;
+ }
+ this._disposed = true;
+
+ var api = this._api;
+ var ecModel = this._model;
+
+ each(this._componentsViews, function (component) {
+ component.dispose(ecModel, api);
+ });
+ each(this._chartsViews, function (chart) {
+ chart.dispose(ecModel, api);
+ });
+
+ // Dispose after all views disposed
+ this._zr.dispose();
+
+ delete instances[this.id];
+ };
+
+ zrUtil.mixin(ECharts, Eventful);
+
+ function updateHoverLayerStatus(zr, ecModel) {
+ var storage = zr.storage;
+ var elCount = 0;
+ storage.traverse(function (el) {
+ if (!el.isGroup) {
+ elCount++;
+ }
+ });
+ if (elCount > ecModel.get('hoverLayerThreshold') && !env.node) {
+ storage.traverse(function (el) {
+ if (!el.isGroup) {
+ el.useHoverLayer = true;
+ }
+ });
+ }
+ }
+ /**
+ * Update chart progressive and blend.
+ * @param {module:echarts/model/Series|module:echarts/model/Component} model
+ * @param {module:echarts/view/Component|module:echarts/view/Chart} view
+ */
+ function updateProgressiveAndBlend(seriesModel, chartView) {
+ // Progressive configuration
+ var elCount = 0;
+ chartView.group.traverse(function (el) {
+ if (el.type !== 'group' && !el.ignore) {
+ elCount++;
+ }
+ });
+ var frameDrawNum = +seriesModel.get('progressive');
+ var needProgressive = elCount > seriesModel.get('progressiveThreshold') && frameDrawNum && !env.node;
+ if (needProgressive) {
+ chartView.group.traverse(function (el) {
+ // FIXME marker and other components
+ if (!el.isGroup) {
+ el.progressive = needProgressive ?
+ Math.floor(elCount++ / frameDrawNum) : -1;
+ if (needProgressive) {
+ el.stopAnimation(true);
+ }
+ }
+ });
+ }
+
+ // Blend configration
+ var blendMode = seriesModel.get('blendMode') || null;
+ if (true) {
+ if (!env.canvasSupported && blendMode && blendMode !== 'source-over') {
+ console.warn('Only canvas support blendMode');
+ }
+ }
+ chartView.group.traverse(function (el) {
+ // FIXME marker and other components
+ if (!el.isGroup) {
+ el.setStyle('blend', blendMode);
+ }
+ });
+ }
+ /**
+ * @param {module:echarts/model/Series|module:echarts/model/Component} model
+ * @param {module:echarts/view/Component|module:echarts/view/Chart} view
+ */
+ function updateZ(model, view) {
+ var z = model.get('z');
+ var zlevel = model.get('zlevel');
+ // Set z and zlevel
+ view.group.traverse(function (el) {
+ if (el.type !== 'group') {
+ z != null && (el.z = z);
+ zlevel != null && (el.zlevel = zlevel);
+ }
+ });
+ }
+ /**
+ * @type {Array.}
+ * @inner
+ */
+ var actions = [];
+
+ /**
+ * Map eventType to actionType
+ * @type {Object}
+ */
+ var eventActionMap = {};
+
+ /**
+ * Data processor functions of each stage
+ * @type {Array.>}
+ * @inner
+ */
+ var dataProcessorFuncs = [];
+
+ /**
+ * @type {Array.}
+ * @inner
+ */
+ var optionPreprocessorFuncs = [];
+
+ /**
+ * Visual encoding functions of each stage
+ * @type {Array.>}
+ * @inner
+ */
+ var visualFuncs = [];
+ /**
+ * Theme storage
+ * @type {Object.}
+ */
+ var themeStorage = {};
+ /**
+ * Loading effects
+ */
+ var loadingEffects = {};
+
+
+ var instances = {};
+ var connectedGroups = {};
+
+ var idBase = new Date() - 0;
+ var groupIdBase = new Date() - 0;
+ var DOM_ATTRIBUTE_KEY = '_echarts_instance_';
+ /**
+ * @alias module:echarts
+ */
+ var echarts = {
+ /**
+ * @type {number}
+ */
+ version: '3.2.3',
+ dependencies: {
+ zrender: '3.1.3'
+ }
+ };
+
+ function enableConnect(chart) {
+
+ var STATUS_PENDING = 0;
+ var STATUS_UPDATING = 1;
+ var STATUS_UPDATED = 2;
+ var STATUS_KEY = '__connectUpdateStatus';
+ function updateConnectedChartsStatus(charts, status) {
+ for (var i = 0; i < charts.length; i++) {
+ var otherChart = charts[i];
+ otherChart[STATUS_KEY] = status;
+ }
+ }
+ zrUtil.each(eventActionMap, function (actionType, eventType) {
+ chart._messageCenter.on(eventType, function (event) {
+ if (connectedGroups[chart.group] && chart[STATUS_KEY] !== STATUS_PENDING) {
+ var action = chart.makeActionFromEvent(event);
+ var otherCharts = [];
+ for (var id in instances) {
+ var otherChart = instances[id];
+ if (otherChart !== chart && otherChart.group === chart.group) {
+ otherCharts.push(otherChart);
+ }
+ }
+ updateConnectedChartsStatus(otherCharts, STATUS_PENDING);
+ each(otherCharts, function (otherChart) {
+ if (otherChart[STATUS_KEY] !== STATUS_UPDATING) {
+ otherChart.dispatchAction(action);
+ }
+ });
+ updateConnectedChartsStatus(otherCharts, STATUS_UPDATED);
+ }
+ });
+ });
+
+ }
+ /**
+ * @param {HTMLDomElement} dom
+ * @param {Object} [theme]
+ * @param {Object} opts
+ */
+ echarts.init = function (dom, theme, opts) {
+ if (true) {
+ // Check version
+ if ((zrender.version.replace('.', '') - 0) < (echarts.dependencies.zrender.replace('.', '') - 0)) {
+ throw new Error(
+ 'ZRender ' + zrender.version
+ + ' is too old for ECharts ' + echarts.version
+ + '. Current version need ZRender '
+ + echarts.dependencies.zrender + '+'
+ );
+ }
+ if (!dom) {
+ throw new Error('Initialize failed: invalid dom.');
+ }
+ if (zrUtil.isDom(dom) && dom.nodeName.toUpperCase() !== 'CANVAS' && (!dom.clientWidth || !dom.clientHeight)) {
+ console.warn('Can\'t get dom width or height');
+ }
+ }
+
+ var chart = new ECharts(dom, theme, opts);
+ chart.id = 'ec_' + idBase++;
+ instances[chart.id] = chart;
+
+ dom.setAttribute &&
+ dom.setAttribute(DOM_ATTRIBUTE_KEY, chart.id);
+
+ enableConnect(chart);
+
+ return chart;
+ };
+
+ /**
+ * @return {string|Array.} groupId
+ */
+ echarts.connect = function (groupId) {
+ // Is array of charts
+ if (zrUtil.isArray(groupId)) {
+ var charts = groupId;
+ groupId = null;
+ // If any chart has group
+ zrUtil.each(charts, function (chart) {
+ if (chart.group != null) {
+ groupId = chart.group;
+ }
+ });
+ groupId = groupId || ('g_' + groupIdBase++);
+ zrUtil.each(charts, function (chart) {
+ chart.group = groupId;
+ });
+ }
+ connectedGroups[groupId] = true;
+ return groupId;
+ };
+
+ /**
+ * @return {string} groupId
+ */
+ echarts.disConnect = function (groupId) {
+ connectedGroups[groupId] = false;
+ };
+
+ /**
+ * Dispose a chart instance
+ * @param {module:echarts~ECharts|HTMLDomElement|string} chart
+ */
+ echarts.dispose = function (chart) {
+ if (zrUtil.isDom(chart)) {
+ chart = echarts.getInstanceByDom(chart);
+ }
+ else if (typeof chart === 'string') {
+ chart = instances[chart];
+ }
+ if ((chart instanceof ECharts) && !chart.isDisposed()) {
+ chart.dispose();
+ }
+ };
+
+ /**
+ * @param {HTMLDomElement} dom
+ * @return {echarts~ECharts}
+ */
+ echarts.getInstanceByDom = function (dom) {
+ var key = dom.getAttribute(DOM_ATTRIBUTE_KEY);
+ return instances[key];
+ };
+ /**
+ * @param {string} key
+ * @return {echarts~ECharts}
+ */
+ echarts.getInstanceById = function (key) {
+ return instances[key];
+ };
+
+ /**
+ * Register theme
+ */
+ echarts.registerTheme = function (name, theme) {
+ themeStorage[name] = theme;
+ };
+
+ /**
+ * Register option preprocessor
+ * @param {Function} preprocessorFunc
+ */
+ echarts.registerPreprocessor = function (preprocessorFunc) {
+ optionPreprocessorFuncs.push(preprocessorFunc);
+ };
+
+ /**
+ * @param {number} [priority=1000]
+ * @param {Function} processorFunc
+ */
+ echarts.registerProcessor = function (priority, processorFunc) {
+ if (typeof priority === 'function') {
+ processorFunc = priority;
+ priority = PRIORITY_PROCESSOR_FILTER;
+ }
+ if (true) {
+ if (isNaN(priority)) {
+ throw new Error('Unkown processor priority');
+ }
+ }
+ dataProcessorFuncs.push({
+ prio: priority,
+ func: processorFunc
+ });
+ };
+
+ /**
+ * Usage:
+ * registerAction('someAction', 'someEvent', function () { ... });
+ * registerAction('someAction', function () { ... });
+ * registerAction(
+ * {type: 'someAction', event: 'someEvent', update: 'updateView'},
+ * function () { ... }
+ * );
+ *
+ * @param {(string|Object)} actionInfo
+ * @param {string} actionInfo.type
+ * @param {string} [actionInfo.event]
+ * @param {string} [actionInfo.update]
+ * @param {string} [eventName]
+ * @param {Function} action
+ */
+ echarts.registerAction = function (actionInfo, eventName, action) {
+ if (typeof eventName === 'function') {
+ action = eventName;
+ eventName = '';
+ }
+ var actionType = zrUtil.isObject(actionInfo)
+ ? actionInfo.type
+ : ([actionInfo, actionInfo = {
+ event: eventName
+ }][0]);
+
+ // Event name is all lowercase
+ actionInfo.event = (actionInfo.event || actionType).toLowerCase();
+ eventName = actionInfo.event;
+
+ if (!actions[actionType]) {
+ actions[actionType] = {action: action, actionInfo: actionInfo};
+ }
+ eventActionMap[eventName] = actionType;
+ };
+
+ /**
+ * @param {string} type
+ * @param {*} CoordinateSystem
+ */
+ echarts.registerCoordinateSystem = function (type, CoordinateSystem) {
+ CoordinateSystemManager.register(type, CoordinateSystem);
+ };
+
+ /**
+ * Layout is a special stage of visual encoding
+ * Most visual encoding like color are common for different chart
+ * But each chart has it's own layout algorithm
+ *
+ * @param {number} [priority=1000]
+ * @param {Function} layoutFunc
+ */
+ echarts.registerLayout = function (priority, layoutFunc) {
+ if (typeof priority === 'function') {
+ layoutFunc = priority;
+ priority = PRIORITY_VISUAL_LAYOUT;
+ }
+ if (true) {
+ if (isNaN(priority)) {
+ throw new Error('Unkown layout priority');
+ }
+ }
+ visualFuncs.push({
+ prio: priority,
+ func: layoutFunc,
+ isLayout: true
+ });
+ };
+
+ /**
+ * @param {number} [priority=3000]
+ * @param {Function} visualFunc
+ */
+ echarts.registerVisual = function (priority, visualFunc) {
+ if (typeof priority === 'function') {
+ visualFunc = priority;
+ priority = PRIORITY_VISUAL_CHART;
+ }
+ if (true) {
+ if (isNaN(priority)) {
+ throw new Error('Unkown visual priority');
+ }
+ }
+ visualFuncs.push({
+ prio: priority,
+ func: visualFunc
+ });
+ };
+
+ /**
+ * @param {string} name
+ */
+ echarts.registerLoading = function (name, loadingFx) {
+ loadingEffects[name] = loadingFx;
+ };
+
+
+ var parseClassType = ComponentModel.parseClassType;
+ /**
+ * @param {Object} opts
+ * @param {string} [superClass]
+ */
+ echarts.extendComponentModel = function (opts, superClass) {
+ var Clazz = ComponentModel;
+ if (superClass) {
+ var classType = parseClassType(superClass);
+ Clazz = ComponentModel.getClass(classType.main, classType.sub, true);
+ }
+ return Clazz.extend(opts);
+ };
+
+ /**
+ * @param {Object} opts
+ * @param {string} [superClass]
+ */
+ echarts.extendComponentView = function (opts, superClass) {
+ var Clazz = ComponentView;
+ if (superClass) {
+ var classType = parseClassType(superClass);
+ Clazz = ComponentView.getClass(classType.main, classType.sub, true);
+ }
+ return Clazz.extend(opts);
+ };
+
+ /**
+ * @param {Object} opts
+ * @param {string} [superClass]
+ */
+ echarts.extendSeriesModel = function (opts, superClass) {
+ var Clazz = SeriesModel;
+ if (superClass) {
+ superClass = 'series.' + superClass.replace('series.', '');
+ var classType = parseClassType(superClass);
+ Clazz = SeriesModel.getClass(classType.main, classType.sub, true);
+ }
+ return Clazz.extend(opts);
+ };
+
+ /**
+ * @param {Object} opts
+ * @param {string} [superClass]
+ */
+ echarts.extendChartView = function (opts, superClass) {
+ var Clazz = ChartView;
+ if (superClass) {
+ superClass.replace('series.', '');
+ var classType = parseClassType(superClass);
+ Clazz = ChartView.getClass(classType.main, true);
+ }
+ return Clazz.extend(opts);
+ };
+
+ /**
+ * ZRender need a canvas context to do measureText.
+ * But in node environment canvas may be created by node-canvas.
+ * So we need to specify how to create a canvas instead of using document.createElement('canvas')
+ *
+ * Be careful of using it in the browser.
+ *
+ * @param {Function} creator
+ * @example
+ * var Canvas = require('canvas');
+ * var echarts = require('echarts');
+ * echarts.setCanvasCreator(function () {
+ * // Small size is enough.
+ * return new Canvas(32, 32);
+ * });
+ */
+ echarts.setCanvasCreator = function (creator) {
+ zrUtil.createCanvas = creator;
+ };
+
+ echarts.registerVisual(PRIORITY_VISUAL_GLOBAL, __webpack_require__(93));
+ echarts.registerPreprocessor(__webpack_require__(94));
+ echarts.registerLoading('default', __webpack_require__(96));
+
+ // Default action
+ echarts.registerAction({
+ type: 'highlight',
+ event: 'highlight',
+ update: 'highlight'
+ }, zrUtil.noop);
+ echarts.registerAction({
+ type: 'downplay',
+ event: 'downplay',
+ update: 'downplay'
+ }, zrUtil.noop);
+
+
+ // --------
+ // Exports
+ // --------
+ //
+ echarts.List = __webpack_require__(97);
+ echarts.Model = __webpack_require__(12);
+
+ echarts.graphic = __webpack_require__(43);
+ echarts.number = __webpack_require__(7);
+ echarts.format = __webpack_require__(6);
+ echarts.matrix = __webpack_require__(11);
+ echarts.vector = __webpack_require__(10);
+ echarts.color = __webpack_require__(39);
+
+ echarts.util = {};
+ each([
+ 'map', 'each', 'filter', 'indexOf', 'inherits',
+ 'reduce', 'filter', 'bind', 'curry', 'isArray',
+ 'isString', 'isObject', 'isFunction', 'extend', 'defaults'
+ ],
+ function (name) {
+ echarts.util[name] = zrUtil[name];
+ }
+ );
+
+ // PRIORITY
+ echarts.PRIORITY = {
+ PROCESSOR: {
+ FILTER: PRIORITY_PROCESSOR_FILTER,
+ STATISTIC: PRIORITY_PROCESSOR_STATISTIC
+ },
+ VISUAL: {
+ LAYOUT: PRIORITY_VISUAL_LAYOUT,
+ GLOBAL: PRIORITY_VISUAL_GLOBAL,
+ CHART: PRIORITY_VISUAL_CHART,
+ COMPONENT: PRIORITY_VISUAL_COMPONENT,
+ BRUSH: PRIORITY_VISUAL_BRUSH
+ }
+ };
+
+ module.exports = echarts;
+
+
+/***/ },
+/* 2 */
+/***/ function(module, exports) {
+
+ /**
+ * echarts设备环境识别
+ *
+ * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
+ * @author firede[firede@firede.us]
+ * @desc thanks zepto.
+ */
+
+ var env = {};
+ if (typeof navigator === 'undefined') {
+ // In node
+ env = {
+ browser: {},
+ os: {},
+ node: true,
+ // Assume canvas is supported
+ canvasSupported: true
+ };
+ }
+ else {
+ env = detect(navigator.userAgent);
+ }
+
+ module.exports = env;
+
+ // Zepto.js
+ // (c) 2010-2013 Thomas Fuchs
+ // Zepto.js may be freely distributed under the MIT license.
+
+ function detect(ua) {
+ var os = {};
+ var browser = {};
+ // var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);
+ // var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
+ // var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
+ // var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
+ // var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
+ // var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);
+ // var touchpad = webos && ua.match(/TouchPad/);
+ // var kindle = ua.match(/Kindle\/([\d.]+)/);
+ // var silk = ua.match(/Silk\/([\d._]+)/);
+ // var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);
+ // var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);
+ // var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);
+ // var playbook = ua.match(/PlayBook/);
+ // var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
+ var firefox = ua.match(/Firefox\/([\d.]+)/);
+ // var safari = webkit && ua.match(/Mobile\//) && !chrome;
+ // var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;
+ var ie = ua.match(/MSIE\s([\d.]+)/)
+ // IE 11 Trident/7.0; rv:11.0
+ || ua.match(/Trident\/.+?rv:(([\d.]+))/);
+ var edge = ua.match(/Edge\/([\d.]+)/); // IE 12 and 12+
+
+ // Todo: clean this up with a better OS/browser seperation:
+ // - discern (more) between multiple browsers on android
+ // - decide if kindle fire in silk mode is android or not
+ // - Firefox on Android doesn't specify the Android version
+ // - possibly devide in os, device and browser hashes
+
+ // if (browser.webkit = !!webkit) browser.version = webkit[1];
+
+ // if (android) os.android = true, os.version = android[2];
+ // if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.');
+ // if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.');
+ // if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
+ // if (webos) os.webos = true, os.version = webos[2];
+ // if (touchpad) os.touchpad = true;
+ // if (blackberry) os.blackberry = true, os.version = blackberry[2];
+ // if (bb10) os.bb10 = true, os.version = bb10[2];
+ // if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];
+ // if (playbook) browser.playbook = true;
+ // if (kindle) os.kindle = true, os.version = kindle[1];
+ // if (silk) browser.silk = true, browser.version = silk[1];
+ // if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
+ // if (chrome) browser.chrome = true, browser.version = chrome[1];
+ if (firefox) browser.firefox = true, browser.version = firefox[1];
+ // if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;
+ // if (webview) browser.webview = true;
+ if (ie) {
+ browser.ie = true; browser.version = ie[1];
+ }
+ if (ie) {
+ browser.ie = true;
+ browser.version = ie[1];
+ }
+ if (edge) {
+ browser.edge = true;
+ browser.version = edge[1];
+ }
+
+ // os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
+ // (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));
+ // os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos ||
+ // (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
+ // (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));
+
+ return {
+ browser: browser,
+ os: os,
+ node: false,
+ // 原生canvas支持,改极端点了
+ // canvasSupported : !(browser.ie && parseFloat(browser.version) < 9)
+ canvasSupported : document.createElement('canvas').getContext ? true : false,
+ // @see
+ // works on most browsers
+ // IE10/11 does not support touch event, and MS Edge supports them but not by
+ // default, so we dont check navigator.maxTouchPoints for them here.
+ touchEventsSupported: 'ontouchstart' in window && !browser.ie && !browser.edge,
+ // .
+ pointerEventsSupported: 'onpointerdown' in window
+ // Firefox supports pointer but not by default,
+ // only MS browsers are reliable on pointer events currently.
+ && (browser.edge || (browser.ie && browser.version >= 10))
+ };
+ }
+
+
+/***/ },
+/* 3 */
+/***/ function(module, exports, __webpack_require__) {
+
+ /**
+ * ECharts global model
+ *
+ * @module {echarts/model/Global}
+ *
+ */
+
+
+
+ var zrUtil = __webpack_require__(4);
+ var modelUtil = __webpack_require__(5);
+ var Model = __webpack_require__(12);
+ var each = zrUtil.each;
+ var filter = zrUtil.filter;
+ var map = zrUtil.map;
+ var isArray = zrUtil.isArray;
+ var indexOf = zrUtil.indexOf;
+ var isObject = zrUtil.isObject;
+
+ var ComponentModel = __webpack_require__(19);
+
+ var globalDefault = __webpack_require__(23);
+
+ var OPTION_INNER_KEY = '\0_ec_inner';
+
+ /**
+ * @alias module:echarts/model/Global
+ *
+ * @param {Object} option
+ * @param {module:echarts/model/Model} parentModel
+ * @param {Object} theme
+ */
+ var GlobalModel = Model.extend({
+
+ constructor: GlobalModel,
+
+ init: function (option, parentModel, theme, optionManager) {
+ theme = theme || {};
+
+ this.option = null; // Mark as not initialized.
+
+ /**
+ * @type {module:echarts/model/Model}
+ * @private
+ */
+ this._theme = new Model(theme);
+
+ /**
+ * @type {module:echarts/model/OptionManager}
+ */
+ this._optionManager = optionManager;
+ },
+
+ setOption: function (option, optionPreprocessorFuncs) {
+ zrUtil.assert(
+ !(OPTION_INNER_KEY in option),
+ 'please use chart.getOption()'
+ );
+
+ this._optionManager.setOption(option, optionPreprocessorFuncs);
+
+ this.resetOption();
+ },
+
+ /**
+ * @param {string} type null/undefined: reset all.
+ * 'recreate': force recreate all.
+ * 'timeline': only reset timeline option
+ * 'media': only reset media query option
+ * @return {boolean} Whether option changed.
+ */
+ resetOption: function (type) {
+ var optionChanged = false;
+ var optionManager = this._optionManager;
+
+ if (!type || type === 'recreate') {
+ var baseOption = optionManager.mountOption(type === 'recreate');
+
+ if (!this.option || type === 'recreate') {
+ initBase.call(this, baseOption);
+ }
+ else {
+ this.restoreData();
+ this.mergeOption(baseOption);
+ }
+ optionChanged = true;
+ }
+
+ if (type === 'timeline' || type === 'media') {
+ this.restoreData();
+ }
+
+ if (!type || type === 'recreate' || type === 'timeline') {
+ var timelineOption = optionManager.getTimelineOption(this);
+ timelineOption && (this.mergeOption(timelineOption), optionChanged = true);
+ }
+
+ if (!type || type === 'recreate' || type === 'media') {
+ var mediaOptions = optionManager.getMediaOption(this, this._api);
+ if (mediaOptions.length) {
+ each(mediaOptions, function (mediaOption) {
+ this.mergeOption(mediaOption, optionChanged = true);
+ }, this);
+ }
+ }
+
+ return optionChanged;
+ },
+
+ /**
+ * @protected
+ */
+ mergeOption: function (newOption) {
+ var option = this.option;
+ var componentsMap = this._componentsMap;
+ var newCptTypes = [];
+
+ // 如果不存在对应的 component model 则直接 merge
+ each(newOption, function (componentOption, mainType) {
+ if (componentOption == null) {
+ return;
+ }
+
+ if (!ComponentModel.hasClass(mainType)) {
+ option[mainType] = option[mainType] == null
+ ? zrUtil.clone(componentOption)
+ : zrUtil.merge(option[mainType], componentOption, true);
+ }
+ else {
+ newCptTypes.push(mainType);
+ }
+ });
+
+ // FIXME OPTION 同步是否要改回原来的
+ ComponentModel.topologicalTravel(
+ newCptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this
+ );
+
+ this._seriesIndices = this._seriesIndices || [];
+
+ function visitComponent(mainType, dependencies) {
+ var newCptOptionList = modelUtil.normalizeToArray(newOption[mainType]);
+
+ var mapResult = modelUtil.mappingToExists(
+ componentsMap[mainType], newCptOptionList
+ );
+
+ makeKeyInfo(mainType, mapResult);
+
+ var dependentModels = getComponentsByTypes(
+ componentsMap, dependencies
+ );
+
+ option[mainType] = [];
+ componentsMap[mainType] = [];
+
+ each(mapResult, function (resultItem, index) {
+ var componentModel = resultItem.exist;
+ var newCptOption = resultItem.option;
+
+ zrUtil.assert(
+ isObject(newCptOption) || componentModel,
+ 'Empty component definition'
+ );
+
+ // Consider where is no new option and should be merged using {},
+ // see removeEdgeAndAdd in topologicalTravel and
+ // ComponentModel.getAllClassMainTypes.
+ if (!newCptOption) {
+ componentModel.mergeOption({}, this);
+ componentModel.optionUpdated({}, false);
+ }
+ else {
+ var ComponentModelClass = ComponentModel.getClass(
+ mainType, resultItem.keyInfo.subType, true
+ );
+
+ if (componentModel && componentModel instanceof ComponentModelClass) {
+ componentModel.mergeOption(newCptOption, this);
+ componentModel.optionUpdated(newCptOption, false);
+ }
+ else {
+ // PENDING Global as parent ?
+ var extraOpt = zrUtil.extend(
+ {
+ dependentModels: dependentModels,
+ componentIndex: index
+ },
+ resultItem.keyInfo
+ );
+ componentModel = new ComponentModelClass(
+ newCptOption, this, this, extraOpt
+ );
+ componentModel.init(newCptOption, this, this, extraOpt);
+ // Call optionUpdated after init.
+ // newCptOption has been used as componentModel.option
+ // and may be merged with theme and default, so pass null
+ // to avoid confusion.
+ componentModel.optionUpdated(null, true);
+ }
+ }
+
+ componentsMap[mainType][index] = componentModel;
+ option[mainType][index] = componentModel.option;
+ }, this);
+
+ // Backup series for filtering.
+ if (mainType === 'series') {
+ this._seriesIndices = createSeriesIndices(componentsMap.series);
+ }
+ }
+ },
+
+ /**
+ * Get option for output (cloned option and inner info removed)
+ * @public
+ * @return {Object}
+ */
+ getOption: function () {
+ var option = zrUtil.clone(this.option);
+
+ each(option, function (opts, mainType) {
+ if (ComponentModel.hasClass(mainType)) {
+ var opts = modelUtil.normalizeToArray(opts);
+ for (var i = opts.length - 1; i >= 0; i--) {
+ // Remove options with inner id.
+ if (modelUtil.isIdInner(opts[i])) {
+ opts.splice(i, 1);
+ }
+ }
+ option[mainType] = opts;
+ }
+ });
+
+ delete option[OPTION_INNER_KEY];
+
+ return option;
+ },
+
+ /**
+ * @return {module:echarts/model/Model}
+ */
+ getTheme: function () {
+ return this._theme;
+ },
+
+ /**
+ * @param {string} mainType
+ * @param {number} [idx=0]
+ * @return {module:echarts/model/Component}
+ */
+ getComponent: function (mainType, idx) {
+ var list = this._componentsMap[mainType];
+ if (list) {
+ return list[idx || 0];
+ }
+ },
+
+ /**
+ * @param {Object} condition
+ * @param {string} condition.mainType
+ * @param {string} [condition.subType] If ignore, only query by mainType
+ * @param {number} [condition.index] Either input index or id or name.
+ * @param {string} [condition.id] Either input index or id or name.
+ * @param {string} [condition.name] Either input index or id or name.
+ * @return {Array.}
+ */
+ queryComponents: function (condition) {
+ var mainType = condition.mainType;
+ if (!mainType) {
+ return [];
+ }
+
+ var index = condition.index;
+ var id = condition.id;
+ var name = condition.name;
+
+ var cpts = this._componentsMap[mainType];
+
+ if (!cpts || !cpts.length) {
+ return [];
+ }
+
+ var result;
+
+ if (index != null) {
+ if (!isArray(index)) {
+ index = [index];
+ }
+ result = filter(map(index, function (idx) {
+ return cpts[idx];
+ }), function (val) {
+ return !!val;
+ });
+ }
+ else if (id != null) {
+ var isIdArray = isArray(id);
+ result = filter(cpts, function (cpt) {
+ return (isIdArray && indexOf(id, cpt.id) >= 0)
+ || (!isIdArray && cpt.id === id);
+ });
+ }
+ else if (name != null) {
+ var isNameArray = isArray(name);
+ result = filter(cpts, function (cpt) {
+ return (isNameArray && indexOf(name, cpt.name) >= 0)
+ || (!isNameArray && cpt.name === name);
+ });
+ }
+ else {
+ // Return all components with mainType
+ result = cpts;
+ }
+
+ return filterBySubType(result, condition);
+ },
+
+ /**
+ * The interface is different from queryComponents,
+ * which is convenient for inner usage.
+ *
+ * @usage
+ * var result = findComponents(
+ * {mainType: 'dataZoom', query: {dataZoomId: 'abc'}}
+ * );
+ * var result = findComponents(
+ * {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}}
+ * );
+ * var result = findComponents(
+ * {mainType: 'series'},
+ * function (model, index) {...}
+ * );
+ * // result like [component0, componnet1, ...]
+ *
+ * @param {Object} condition
+ * @param {string} condition.mainType Mandatory.
+ * @param {string} [condition.subType] Optional.
+ * @param {Object} [condition.query] like {xxxIndex, xxxId, xxxName},
+ * where xxx is mainType.
+ * If query attribute is null/undefined or has no index/id/name,
+ * do not filtering by query conditions, which is convenient for
+ * no-payload situations or when target of action is global.
+ * @param {Function} [condition.filter] parameter: component, return boolean.
+ * @return {Array.}
+ */
+ findComponents: function (condition) {
+ var query = condition.query;
+ var mainType = condition.mainType;
+
+ var queryCond = getQueryCond(query);
+ var result = queryCond
+ ? this.queryComponents(queryCond)
+ : this._componentsMap[mainType];
+
+ return doFilter(filterBySubType(result, condition));
+
+ function getQueryCond(q) {
+ var indexAttr = mainType + 'Index';
+ var idAttr = mainType + 'Id';
+ var nameAttr = mainType + 'Name';
+ return q && (
+ q.hasOwnProperty(indexAttr)
+ || q.hasOwnProperty(idAttr)
+ || q.hasOwnProperty(nameAttr)
+ )
+ ? {
+ mainType: mainType,
+ // subType will be filtered finally.
+ index: q[indexAttr],
+ id: q[idAttr],
+ name: q[nameAttr]
+ }
+ : null;
+ }
+
+ function doFilter(res) {
+ return condition.filter
+ ? filter(res, condition.filter)
+ : res;
+ }
+ },
+
+ /**
+ * @usage
+ * eachComponent('legend', function (legendModel, index) {
+ * ...
+ * });
+ * eachComponent(function (componentType, model, index) {
+ * // componentType does not include subType
+ * // (componentType is 'xxx' but not 'xxx.aa')
+ * });
+ * eachComponent(
+ * {mainType: 'dataZoom', query: {dataZoomId: 'abc'}},
+ * function (model, index) {...}
+ * );
+ * eachComponent(
+ * {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}},
+ * function (model, index) {...}
+ * );
+ *
+ * @param {string|Object=} mainType When mainType is object, the definition
+ * is the same as the method 'findComponents'.
+ * @param {Function} cb
+ * @param {*} context
+ */
+ eachComponent: function (mainType, cb, context) {
+ var componentsMap = this._componentsMap;
+
+ if (typeof mainType === 'function') {
+ context = cb;
+ cb = mainType;
+ each(componentsMap, function (components, componentType) {
+ each(components, function (component, index) {
+ cb.call(context, componentType, component, index);
+ });
+ });
+ }
+ else if (zrUtil.isString(mainType)) {
+ each(componentsMap[mainType], cb, context);
+ }
+ else if (isObject(mainType)) {
+ var queryResult = this.findComponents(mainType);
+ each(queryResult, cb, context);
+ }
+ },
+
+ /**
+ * @param {string} name
+ * @return {Array.}
+ */
+ getSeriesByName: function (name) {
+ var series = this._componentsMap.series;
+ return filter(series, function (oneSeries) {
+ return oneSeries.name === name;
+ });
+ },
+
+ /**
+ * @param {number} seriesIndex
+ * @return {module:echarts/model/Series}
+ */
+ getSeriesByIndex: function (seriesIndex) {
+ return this._componentsMap.series[seriesIndex];
+ },
+
+ /**
+ * @param {string} subType
+ * @return {Array.}
+ */
+ getSeriesByType: function (subType) {
+ var series = this._componentsMap.series;
+ return filter(series, function (oneSeries) {
+ return oneSeries.subType === subType;
+ });
+ },
+
+ /**
+ * @return {Array.}
+ */
+ getSeries: function () {
+ return this._componentsMap.series.slice();
+ },
+
+ /**
+ * After filtering, series may be different
+ * frome raw series.
+ *
+ * @param {Function} cb
+ * @param {*} context
+ */
+ eachSeries: function (cb, context) {
+ assertSeriesInitialized(this);
+ each(this._seriesIndices, function (rawSeriesIndex) {
+ var series = this._componentsMap.series[rawSeriesIndex];
+ cb.call(context, series, rawSeriesIndex);
+ }, this);
+ },
+
+ /**
+ * Iterate raw series before filtered.
+ *
+ * @param {Function} cb
+ * @param {*} context
+ */
+ eachRawSeries: function (cb, context) {
+ each(this._componentsMap.series, cb, context);
+ },
+
+ /**
+ * After filtering, series may be different.
+ * frome raw series.
+ *
+ * @parma {string} subType
+ * @param {Function} cb
+ * @param {*} context
+ */
+ eachSeriesByType: function (subType, cb, context) {
+ assertSeriesInitialized(this);
+ each(this._seriesIndices, function (rawSeriesIndex) {
+ var series = this._componentsMap.series[rawSeriesIndex];
+ if (series.subType === subType) {
+ cb.call(context, series, rawSeriesIndex);
+ }
+ }, this);
+ },
+
+ /**
+ * Iterate raw series before filtered of given type.
+ *
+ * @parma {string} subType
+ * @param {Function} cb
+ * @param {*} context
+ */
+ eachRawSeriesByType: function (subType, cb, context) {
+ return each(this.getSeriesByType(subType), cb, context);
+ },
+
+ /**
+ * @param {module:echarts/model/Series} seriesModel
+ */
+ isSeriesFiltered: function (seriesModel) {
+ assertSeriesInitialized(this);
+ return zrUtil.indexOf(this._seriesIndices, seriesModel.componentIndex) < 0;
+ },
+
+ /**
+ * @param {Function} cb
+ * @param {*} context
+ */
+ filterSeries: function (cb, context) {
+ assertSeriesInitialized(this);
+ var filteredSeries = filter(
+ this._componentsMap.series, cb, context
+ );
+ this._seriesIndices = createSeriesIndices(filteredSeries);
+ },
+
+ restoreData: function () {
+ var componentsMap = this._componentsMap;
+
+ this._seriesIndices = createSeriesIndices(componentsMap.series);
+
+ var componentTypes = [];
+ each(componentsMap, function (components, componentType) {
+ componentTypes.push(componentType);
+ });
+
+ ComponentModel.topologicalTravel(
+ componentTypes,
+ ComponentModel.getAllClassMainTypes(),
+ function (componentType, dependencies) {
+ each(componentsMap[componentType], function (component) {
+ component.restoreData();
+ });
+ }
+ );
+ }
+
+ });
+
+ /**
+ * @inner
+ */
+ function mergeTheme(option, theme) {
+ for (var name in theme) {
+ // 如果有 component model 则把具体的 merge 逻辑交给该 model 处理
+ if (!ComponentModel.hasClass(name)) {
+ if (typeof theme[name] === 'object') {
+ option[name] = !option[name]
+ ? zrUtil.clone(theme[name])
+ : zrUtil.merge(option[name], theme[name], false);
+ }
+ else {
+ if (option[name] == null) {
+ option[name] = theme[name];
+ }
+ }
+ }
+ }
+ }
+
+ function initBase(baseOption) {
+ baseOption = baseOption;
+
+ // Using OPTION_INNER_KEY to mark that this option can not be used outside,
+ // i.e. `chart.setOption(chart.getModel().option);` is forbiden.
+ this.option = {};
+ this.option[OPTION_INNER_KEY] = 1;
+
+ /**
+ * @type {Object.>}
+ * @private
+ */
+ this._componentsMap = {};
+
+ /**
+ * Mapping between filtered series list and raw series list.
+ * key: filtered series indices, value: raw series indices.
+ * @type {Array.}
+ * @private
+ */
+ this._seriesIndices = null;
+
+ mergeTheme(baseOption, this._theme.option);
+
+ // TODO Needs clone when merging to the unexisted property
+ zrUtil.merge(baseOption, globalDefault, false);
+
+ this.mergeOption(baseOption);
+ }
+
+ /**
+ * @inner
+ * @param {Array.|string} types model types
+ * @return {Object} key: {string} type, value: {Array.