diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..1191ca8
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index eb7d1de..5061420 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
/bin/
/.settings/
-/.project
-/.classpath
+/target/
+
+/com/
+/.idea/
diff --git a/.project b/.project
new file mode 100644
index 0000000..d012535
--- /dev/null
+++ b/.project
@@ -0,0 +1,36 @@
+
+
+ JavaUtil
+
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.wst.common.project.facet.core.nature
+
+
diff --git a/JavaUtil.iml b/JavaUtil.iml
new file mode 100644
index 0000000..5b24bb1
--- /dev/null
+++ b/JavaUtil.iml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 46badb3..7dacfef 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,11 @@
-# JavaUtil
-Java Util Tool
+# Java Utilities
+### JDK8 or later
+
+## 1.console function: print println log logArray.
+## 2.directly compile java source code of strings.
+## 3.using function to instantiate object or create array reference.
+## 4.calc running time of codes.
+## 5.dynamic cast.
+## 6.Promise.
+
+
diff --git a/lib/gson-2.8.5-sources.jar b/lib/gson-2.8.5-sources.jar
new file mode 100644
index 0000000..a64f4e7
Binary files /dev/null and b/lib/gson-2.8.5-sources.jar differ
diff --git a/lib/gson-2.8.5.jar b/lib/gson-2.8.5.jar
new file mode 100644
index 0000000..0d5baf3
Binary files /dev/null and b/lib/gson-2.8.5.jar differ
diff --git a/lib/x.jar b/lib/x.jar
new file mode 100644
index 0000000..669ec4a
Binary files /dev/null and b/lib/x.jar differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..de62004
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,133 @@
+
+ 4.0.0
+ com.github.xiuyexye
+ xyjava
+ 0.0.20
+ java lib for me
+
+
+ org.sonatype.oss
+ oss-parent
+ 7
+
+
+
+
+ src
+ test
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.9
+
+
+ attach-javadocs
+
+ jar
+
+
+ -Xdoclint:none
+
+
+
+
+
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.6
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The Apache Software License, Version 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+
+
+
+ jdk8
+ git@github.com:XiuyeXYE/JavaUtil.git
+ scm:git:git@github.com:XiuyeXYE/JavaUtil.git
+ scm:git:git@github.com:XiuyeXYE/JavaUtil.git
+
+
+
+ xiuye
+ xiuye_engineer@outlook.com
+ ABCXIUYE
+
+
+
+
\ No newline at end of file
diff --git a/resourceURL.txt b/resourceURL.txt
new file mode 100644
index 0000000..6563258
--- /dev/null
+++ b/resourceURL.txt
@@ -0,0 +1 @@
+https://blog.csdn.net/wangjingna/article/details/50488921
\ No newline at end of file
diff --git a/resources/config.js b/resources/config.js
new file mode 100644
index 0000000..324d1bd
--- /dev/null
+++ b/resources/config.js
@@ -0,0 +1,231 @@
+/**
+ * echarts默认配置项
+ *
+ * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
+ * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
+ *
+ */
+define(function() {
+ // 请原谅我这样写,这显然可以直接返回个对象,但那样的话outline就显示不出来了~~
+ var config = {
+ // 图表类型
+ CHART_TYPE_LINE: 'line',
+ CHART_TYPE_BAR: 'bar',
+ CHART_TYPE_SCATTER: 'scatter',
+ CHART_TYPE_PIE: 'pie',
+ CHART_TYPE_RADAR: 'radar',
+ CHART_TYPE_VENN: 'venn',
+ CHART_TYPE_TREEMAP: 'treemap',
+ CHART_TYPE_TREE: 'tree',
+ CHART_TYPE_MAP: 'map',
+ CHART_TYPE_K: 'k',
+ CHART_TYPE_ISLAND: 'island',
+ CHART_TYPE_FORCE: 'force',
+ CHART_TYPE_CHORD: 'chord',
+ CHART_TYPE_GAUGE: 'gauge',
+ CHART_TYPE_FUNNEL: 'funnel',
+ CHART_TYPE_EVENTRIVER: 'eventRiver',
+ CHART_TYPE_WORDCLOUD: 'wordCloud',
+
+ // 组件类型
+ COMPONENT_TYPE_TITLE: 'title',
+ COMPONENT_TYPE_LEGEND: 'legend',
+ COMPONENT_TYPE_DATARANGE: 'dataRange',
+ COMPONENT_TYPE_DATAVIEW: 'dataView',
+ COMPONENT_TYPE_DATAZOOM: 'dataZoom',
+ COMPONENT_TYPE_TOOLBOX: 'toolbox',
+ COMPONENT_TYPE_TOOLTIP: 'tooltip',
+ COMPONENT_TYPE_GRID: 'grid',
+ COMPONENT_TYPE_AXIS: 'axis',
+ COMPONENT_TYPE_POLAR: 'polar',
+ COMPONENT_TYPE_X_AXIS: 'xAxis',
+ COMPONENT_TYPE_Y_AXIS: 'yAxis',
+ COMPONENT_TYPE_AXIS_CATEGORY: 'categoryAxis',
+ COMPONENT_TYPE_AXIS_VALUE: 'valueAxis',
+ COMPONENT_TYPE_TIMELINE: 'timeline',
+ COMPONENT_TYPE_ROAMCONTROLLER: 'roamController',
+
+ // 全图默认背景
+ backgroundColor: 'rgba(0,0,0,0)',
+
+ // 默认色板
+ color: ['#ff7f50','#87cefa','#da70d6','#32cd32','#6495ed',
+ '#ff69b4','#ba55d3','#cd5c5c','#ffa500','#40e0d0',
+ '#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700',
+ '#6699FF','#ff6666','#3cb371','#b8860b','#30e0e0'],
+
+ markPoint: {
+ clickable: true,
+ symbol: 'pin', // 标注类型
+ symbolSize: 10, // 标注大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2
+ // symbolRotate: null, // 标注旋转控制
+ large: false,
+ effect: {
+ show: false,
+ loop: true,
+ period: 15, // 运动周期,无单位,值越大越慢
+ type: 'scale', // 可用为 scale | bounce
+ scaleSize: 2, // 放大倍数,以markPoint点size为基准
+ bounceDistance: 10 // 跳动距离,单位px
+ // color: 'gold',
+ // shadowColor: 'rgba(255,215,0,0.8)',
+ // shadowBlur: 0 // 炫光模糊
+ },
+ itemStyle: {
+ normal: {
+ // color: 各异,
+ // borderColor: 各异, // 标注边线颜色,优先于color
+ borderWidth: 2, // 标注边线线宽,单位px,默认为1
+ label: {
+ show: true,
+ // 标签文本格式器,同Tooltip.formatter,不支持回调
+ // formatter: null,
+ position: 'inside' // 可选为'left'|'right'|'top'|'bottom'
+ // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
+ }
+ },
+ emphasis: {
+ // color: 各异
+ label: {
+ show: true
+ // 标签文本格式器,同Tooltip.formatter,不支持回调
+ // formatter: null,
+ // position: 'inside' // 'left'|'right'|'top'|'bottom'
+ // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
+ }
+ }
+ }
+ },
+
+ markLine: {
+ clickable: true,
+ // 标线起始和结束的symbol介绍类型,如果都一样,可以直接传string
+ symbol: ['circle', 'arrow'],
+ // 标线起始和结束的symbol大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2
+ symbolSize: [2, 4],
+ // 标线起始和结束的symbol旋转控制
+ //symbolRotate: null,
+ //smooth: false,
+ smoothness: 0.2, // 平滑度
+ precision: 2,
+ effect: {
+ show: false,
+ loop: true,
+ period: 15, // 运动周期,无单位,值越大越慢
+ scaleSize: 2 // 放大倍数,以markLine线lineWidth为基准
+ // color: 'gold',
+ // shadowColor: 'rgba(255,215,0,0.8)',
+ // shadowBlur: lineWidth * 2 // 炫光模糊,默认等于scaleSize计算所得
+ },
+ // 边捆绑
+ bundling: {
+ enable: false,
+ // [0, 90]
+ maxTurningAngle: 45
+ },
+ itemStyle: {
+ normal: {
+ // color: 各异, // 标线主色,线色,symbol主色
+ // borderColor: 随color, // 标线symbol边框颜色,优先于color
+ borderWidth: 1.5, // 标线symbol边框线宽,单位px,默认为2
+ label: {
+ show: true,
+ // 标签文本格式器,同Tooltip.formatter,不支持回调
+ // formatter: null,
+ // 可选为 'start'|'end'|'left'|'right'|'top'|'bottom'
+ position: 'end'
+ // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
+ },
+ lineStyle: {
+ // color: 随borderColor, // 主色,线色,优先级高于borderColor和color
+ // width: 随borderWidth, // 优先于borderWidth
+ type: 'dashed'
+ // shadowColor: 'rgba(0,0,0,0)', //默认透明
+ // shadowBlur: 0,
+ // shadowOffsetX: 0,
+ // shadowOffsetY: 0
+ }
+ },
+ emphasis: {
+ // color: 各异
+ label: {
+ show: false
+ // 标签文本格式器,同Tooltip.formatter,不支持回调
+ // formatter: null,
+ // position: 'inside' // 'left'|'right'|'top'|'bottom'
+ // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
+ },
+ lineStyle: {}
+ }
+ }
+ },
+
+ // 主题,主题
+ textStyle: {
+ decoration: 'none',
+ fontFamily: 'Arial, Verdana, sans-serif',
+ fontFamily2: '微软雅黑', // IE8- 字体模糊并且,不支持不同字体混排,额外指定一份
+ fontSize: 12,
+ fontStyle: 'normal',
+ fontWeight: 'normal'
+ },
+
+ EVENT: {
+ // -------全局通用
+ REFRESH: 'refresh',
+ RESTORE: 'restore',
+ RESIZE: 'resize',
+ CLICK: 'click',
+ DBLCLICK: 'dblclick',
+ HOVER: 'hover',
+ MOUSEOUT: 'mouseout',
+ //MOUSEWHEEL: 'mousewheel',
+ // -------业务交互逻辑
+ DATA_CHANGED: 'dataChanged',
+ DATA_ZOOM: 'dataZoom',
+ DATA_RANGE: 'dataRange',
+ DATA_RANGE_SELECTED: 'dataRangeSelected',
+ DATA_RANGE_HOVERLINK: 'dataRangeHoverLink',
+ LEGEND_SELECTED: 'legendSelected',
+ LEGEND_HOVERLINK: 'legendHoverLink',
+ MAP_SELECTED: 'mapSelected',
+ PIE_SELECTED: 'pieSelected',
+ MAGIC_TYPE_CHANGED: 'magicTypeChanged',
+ DATA_VIEW_CHANGED: 'dataViewChanged',
+ TIMELINE_CHANGED: 'timelineChanged',
+ MAP_ROAM: 'mapRoam',
+ FORCE_LAYOUT_END: 'forceLayoutEnd',
+ // -------内部通信
+ TOOLTIP_HOVER: 'tooltipHover',
+ TOOLTIP_IN_GRID: 'tooltipInGrid',
+ TOOLTIP_OUT_GRID: 'tooltipOutGrid',
+ ROAMCONTROLLER: 'roamController'
+ },
+ DRAG_ENABLE_TIME: 120, // 降低图表内元素拖拽敏感度,单位ms,不建议外部干预
+ EFFECT_ZLEVEL : 10, // 特效动画zlevel
+ // 主题,默认标志图形类型列表
+ symbolList: [
+ 'circle', 'rectangle', 'triangle', 'diamond',
+ 'emptyCircle', 'emptyRectangle', 'emptyTriangle', 'emptyDiamond'
+ ],
+ loadingEffect: 'spin',
+ loadingText: '数据读取中...',
+ noDataEffect: 'bubble',
+ noDataText: '暂无数据',
+ // noDataLoadingOption: null,
+ // 可计算特性配置,孤岛,提示颜色
+ calculable: false, // 默认关闭可计算特性
+ calculableColor: 'rgba(255,165,0,0.6)', // 拖拽提示边框颜色
+ calculableHolderColor: '#ccc', // 可计算占位提示颜色
+ nameConnector: ' & ',
+ valueConnector: ': ',
+ animation: true, // 过渡动画是否开启
+ addDataAnimation: true, // 动态数据接口是否开启动画效果
+ animationThreshold: 2000, // 动画元素阀值,产生的图形原素超过2000不出动画
+ animationDuration: 2000, // 过渡动画参数:进入
+ animationDurationUpdate: 500, // 过渡动画参数:更新
+ animationEasing: 'ExponentialOut' //BounceOut
+ };
+
+ return config;
+});
\ No newline at end of file
diff --git a/resources/echarts.js b/resources/echarts.js
new file mode 100644
index 0000000..6bd230b
--- /dev/null
+++ b/resources/echarts.js
@@ -0,0 +1,1759 @@
+/*!
+ * ECharts, a javascript interactive chart library.
+ *
+ * Copyright (c) 2015, Baidu Inc.
+ * All rights reserved.
+ *
+ * LICENSE
+ * https://github.com/ecomfe/echarts/blob/master/LICENSE.txt
+ */
+
+/**
+ * echarts
+ *
+ * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
+ * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
+ *
+ */
+define(function (require) {
+ var ecConfig = require('./config');
+ var zrUtil = require('zrender/tool/util');
+ var zrEvent = require('zrender/tool/event');
+
+ var self = {};
+
+ var _canvasSupported = require('zrender/tool/env').canvasSupported;
+ var _idBase = new Date() - 0;
+ var _instances = {}; // ECharts实例map索引
+ var DOM_ATTRIBUTE_KEY = '_echarts_instance_';
+
+ self.version = '2.2.4';
+ self.dependencies = {
+ zrender: '2.0.9'
+ };
+ /**
+ * 入口方法
+ */
+ self.init = function (dom, theme) {
+ var zrender = require('zrender');
+ if ((zrender.version.replace('.', '') - 0) < (self.dependencies.zrender.replace('.', '') - 0)) {
+ console.error(
+ 'ZRender ' + zrender.version
+ + ' is too old for ECharts ' + self.version
+ + '. Current version need ZRender '
+ + self.dependencies.zrender + '+'
+ );
+ }
+
+ dom = dom instanceof Array ? dom[0] : dom;
+
+ // dom与echarts实例映射索引
+ var key = dom.getAttribute(DOM_ATTRIBUTE_KEY);
+ if (!key) {
+ key = _idBase++;
+ dom.setAttribute(DOM_ATTRIBUTE_KEY, key);
+ }
+
+ if (_instances[key]) {
+ // 同一个dom上多次init,自动释放已有实例
+ _instances[key].dispose();
+ }
+ _instances[key] = new Echarts(dom);
+ _instances[key].id = key;
+ _instances[key].canvasSupported = _canvasSupported;
+ _instances[key].setTheme(theme);
+
+ return _instances[key];
+ };
+
+ /**
+ * 通过id获得ECharts实例,id可在实例化后读取
+ */
+ self.getInstanceById = function (key) {
+ return _instances[key];
+ };
+
+ /**
+ * 消息中心
+ */
+ function MessageCenter() {
+ zrEvent.Dispatcher.call(this);
+ }
+ zrUtil.merge(MessageCenter.prototype, zrEvent.Dispatcher.prototype, true);
+
+ /**
+ * 基于zrender实现Echarts接口层
+ * @param {HtmlElement} dom 必要
+ */
+ function Echarts(dom) {
+ // Fxxk IE11 for breaking initialization without a warrant;
+ // Just set something to let it be!
+ // by kener 2015-01-09
+ dom.innerHTML = '';
+ this._themeConfig = {}; // zrUtil.clone(ecConfig);
+
+ this.dom = dom;
+ // this._zr;
+ // this._option; // curOption clone
+ // this._optionRestore; // for restore;
+ // this._island;
+ // this._toolbox;
+ // this._timeline;
+ // this._refreshInside; // 内部刷新标志位
+
+ this._connected = false;
+ this._status = { // 用于图表间通信
+ dragIn: false,
+ dragOut: false,
+ needRefresh: false
+ };
+ this._curEventType = false; // 破循环信号灯
+ this._chartList = []; // 图表实例
+
+ this._messageCenter = new MessageCenter();
+
+ this._messageCenterOutSide = new MessageCenter(); // Echarts层的外部消息中心,做Echarts层的消息转发
+
+ // resize方法经常被绑定到window.resize上,闭包一个this
+ this.resize = this.resize();
+
+ // 初始化::构造函数
+ this._init();
+ }
+
+ /**
+ * ZRender EVENT
+ *
+ * @inner
+ * @const
+ * @type {Object}
+ */
+ var ZR_EVENT = require('zrender/config').EVENT;
+
+ /**
+ * 要绑定监听的zrender事件列表
+ *
+ * @const
+ * @inner
+ * @type {Array}
+ */
+ var ZR_EVENT_LISTENS = [
+ 'CLICK', 'DBLCLICK', 'MOUSEOVER', 'MOUSEOUT',
+ 'DRAGSTART', 'DRAGEND', 'DRAGENTER', 'DRAGOVER', 'DRAGLEAVE', 'DROP'
+ ];
+
+ /**
+ * 对echarts的实例中的chartList属性成员,逐个进行方法调用,遍历顺序为逆序
+ * 由于在事件触发的默认行为处理中,多次用到相同逻辑,所以抽象了该方法
+ * 由于所有的调用场景里,最多只有两个参数,基于性能和体积考虑,这里就不使用call或者apply了
+ *
+ * @inner
+ * @param {ECharts} ecInstance ECharts实例
+ * @param {string} methodName 要调用的方法名
+ * @param {*} arg0 调用参数1
+ * @param {*} arg1 调用参数2
+ * @param {*} arg2 调用参数3
+ */
+ function callChartListMethodReverse(ecInstance, methodName, arg0, arg1, arg2) {
+ var chartList = ecInstance._chartList;
+ var len = chartList.length;
+
+ while (len--) {
+ var chart = chartList[len];
+ if (typeof chart[methodName] === 'function') {
+ chart[methodName](arg0, arg1, arg2);
+ }
+ }
+ }
+
+ Echarts.prototype = {
+ /**
+ * 初始化::构造函数
+ */
+ _init: function () {
+ var self = this;
+ var _zr = require('zrender').init(this.dom);
+ this._zr = _zr;
+
+ // wrap: n,e,d,t for name event data this
+ this._messageCenter.dispatch = function(type, event, eventPackage, that) {
+ eventPackage = eventPackage || {};
+ eventPackage.type = type;
+ eventPackage.event = event;
+
+ self._messageCenter.dispatchWithContext(type, eventPackage, that);
+ self._messageCenterOutSide.dispatchWithContext(type, eventPackage, that);
+
+ // 如下注掉的代码,@see: https://github.com/ecomfe/echarts-discuss/issues/3
+ // if (type != 'HOVER' && type != 'MOUSEOUT') { // 频繁事件直接抛出
+ // setTimeout(function(){
+ // self._messageCenterOutSide.dispatchWithContext(
+ // type, eventPackage, that
+ // );
+ // },50);
+ // }
+ // else {
+ // self._messageCenterOutSide.dispatchWithContext(
+ // type, eventPackage, that
+ // );
+ // }
+ };
+
+ this._onevent = function(param){
+ return self.__onevent(param);
+ };
+ for (var e in ecConfig.EVENT) {
+ if (e != 'CLICK' && e != 'DBLCLICK'
+ && e != 'HOVER' && e != 'MOUSEOUT' && e != 'MAP_ROAM'
+ ) {
+ this._messageCenter.bind(ecConfig.EVENT[e], this._onevent, this);
+ }
+ }
+
+
+ var eventBehaviors = {};
+ this._onzrevent = function (param) {
+ return self[eventBehaviors[ param.type ]](param);
+ };
+
+ // 挂载关心的事件
+ for (var i = 0, len = ZR_EVENT_LISTENS.length; i < len; i++) {
+ var eventName = ZR_EVENT_LISTENS[i];
+ var eventValue = ZR_EVENT[eventName];
+ eventBehaviors[eventValue] = '_on' + eventName.toLowerCase();
+ _zr.on(eventValue, this._onzrevent);
+ }
+
+ this.chart = {}; // 图表索引
+ this.component = {}; // 组件索引
+
+ // 内置图表
+ // 孤岛
+ var Island = require('./chart/island');
+ this._island = new Island(this._themeConfig, this._messageCenter, _zr, {}, this);
+ this.chart.island = this._island;
+
+ // 内置通用组件
+ // 工具箱
+ var Toolbox = require('./component/toolbox');
+ this._toolbox = new Toolbox(this._themeConfig, this._messageCenter, _zr, {}, this);
+ this.component.toolbox = this._toolbox;
+
+ var componentLibrary = require('./component');
+ componentLibrary.define('title', require('./component/title'));
+ componentLibrary.define('tooltip', require('./component/tooltip'));
+ componentLibrary.define('legend', require('./component/legend'));
+
+ if (_zr.getWidth() === 0 || _zr.getHeight() === 0) {
+ console.error('Dom’s width & height should be ready before init.');
+ }
+ },
+
+ /**
+ * ECharts事件处理中心
+ */
+ __onevent: function (param){
+ param.__echartsId = param.__echartsId || this.id;
+
+ // 来自其他联动图表的事件
+ var fromMyself = (param.__echartsId === this.id);
+
+ if (!this._curEventType) {
+ this._curEventType = param.type;
+ }
+
+ switch (param.type) {
+ case ecConfig.EVENT.LEGEND_SELECTED :
+ this._onlegendSelected(param);
+ break;
+ case ecConfig.EVENT.DATA_ZOOM :
+ if (!fromMyself) {
+ var dz = this.component.dataZoom;
+ if (dz) {
+ dz.silence(true);
+ dz.absoluteZoom(param.zoom);
+ dz.silence(false);
+ }
+ }
+ this._ondataZoom(param);
+ break;
+ case ecConfig.EVENT.DATA_RANGE :
+ fromMyself && this._ondataRange(param);
+ break;
+ case ecConfig.EVENT.MAGIC_TYPE_CHANGED :
+ if (!fromMyself) {
+ var tb = this.component.toolbox;
+ if (tb) {
+ tb.silence(true);
+ tb.setMagicType(param.magicType);
+ tb.silence(false);
+ }
+ }
+ this._onmagicTypeChanged(param);
+ break;
+ case ecConfig.EVENT.DATA_VIEW_CHANGED :
+ fromMyself && this._ondataViewChanged(param);
+ break;
+ case ecConfig.EVENT.TOOLTIP_HOVER :
+ fromMyself && this._tooltipHover(param);
+ break;
+ case ecConfig.EVENT.RESTORE :
+ this._onrestore();
+ break;
+ case ecConfig.EVENT.REFRESH :
+ fromMyself && this._onrefresh(param);
+ break;
+ // 鼠标同步
+ case ecConfig.EVENT.TOOLTIP_IN_GRID :
+ case ecConfig.EVENT.TOOLTIP_OUT_GRID :
+ if (!fromMyself) {
+ // 只处理来自外部的鼠标同步
+ var grid = this.component.grid;
+ if (grid) {
+ this._zr.trigger(
+ 'mousemove',
+ {
+ connectTrigger: true,
+ zrenderX: grid.getX() + param.x * grid.getWidth(),
+ zrenderY: grid.getY() + param.y * grid.getHeight()
+ }
+ );
+ }
+ }
+ else if (this._connected) {
+ // 来自自己,并且存在多图联动,空间坐标映射修改参数分发
+ var grid = this.component.grid;
+ if (grid) {
+ param.x = (param.event.zrenderX - grid.getX()) / grid.getWidth();
+ param.y = (param.event.zrenderY - grid.getY()) / grid.getHeight();
+ }
+ }
+ break;
+ /*
+ case ecConfig.EVENT.RESIZE :
+ case ecConfig.EVENT.DATA_CHANGED :
+ case ecConfig.EVENT.PIE_SELECTED :
+ case ecConfig.EVENT.MAP_SELECTED :
+ break;
+ */
+ }
+
+ // 多图联动,只做自己的一级事件分发,避免级联事件循环
+ if (this._connected && fromMyself && this._curEventType === param.type) {
+ for (var c in this._connected) {
+ this._connected[c].connectedEventHandler(param);
+ }
+ // 分发完毕后复位
+ this._curEventType = null;
+ }
+
+ if (!fromMyself || (!this._connected && fromMyself)) { // 处理了完联动事件复位
+ this._curEventType = null;
+ }
+ },
+
+ /**
+ * 点击事件,响应zrender事件,包装后分发到Echarts层
+ */
+ _onclick: function (param) {
+ callChartListMethodReverse(this, 'onclick', param);
+
+ if (param.target) {
+ var ecData = this._eventPackage(param.target);
+ if (ecData && ecData.seriesIndex != null) {
+ this._messageCenter.dispatch(
+ ecConfig.EVENT.CLICK,
+ param.event,
+ ecData,
+ this
+ );
+ }
+ }
+ },
+
+ /**
+ * 双击事件,响应zrender事件,包装后分发到Echarts层
+ */
+ _ondblclick: function (param) {
+ callChartListMethodReverse(this, 'ondblclick', param);
+
+ if (param.target) {
+ var ecData = this._eventPackage(param.target);
+ if (ecData && ecData.seriesIndex != null) {
+ this._messageCenter.dispatch(
+ ecConfig.EVENT.DBLCLICK,
+ param.event,
+ ecData,
+ this
+ );
+ }
+ }
+ },
+
+ /**
+ * 鼠标移入事件,响应zrender事件,包装后分发到Echarts层
+ */
+ _onmouseover: function (param) {
+ if (param.target) {
+ var ecData = this._eventPackage(param.target);
+ if (ecData && ecData.seriesIndex != null) {
+ this._messageCenter.dispatch(
+ ecConfig.EVENT.HOVER,
+ param.event,
+ ecData,
+ this
+ );
+ }
+ }
+ },
+
+ /**
+ * 鼠标移出事件,响应zrender事件,包装后分发到Echarts层
+ */
+ _onmouseout: function (param) {
+ if (param.target) {
+ var ecData = this._eventPackage(param.target);
+ if (ecData && ecData.seriesIndex != null) {
+ this._messageCenter.dispatch(
+ ecConfig.EVENT.MOUSEOUT,
+ param.event,
+ ecData,
+ this
+ );
+ }
+ }
+ },
+
+ /**
+ * dragstart回调,可计算特性实现
+ */
+ _ondragstart: function (param) {
+ // 复位用于图表间通信拖拽标识
+ this._status = {
+ dragIn: false,
+ dragOut: false,
+ needRefresh: false
+ };
+
+ callChartListMethodReverse(this, 'ondragstart', param);
+ },
+
+ /**
+ * dragging回调,可计算特性实现
+ */
+ _ondragenter: function (param) {
+ callChartListMethodReverse(this, 'ondragenter', param);
+ },
+
+ /**
+ * dragstart回调,可计算特性实现
+ */
+ _ondragover: function (param) {
+ callChartListMethodReverse(this, 'ondragover', param);
+ },
+
+ /**
+ * dragstart回调,可计算特性实现
+ */
+ _ondragleave: function (param) {
+ callChartListMethodReverse(this, 'ondragleave', param);
+ },
+
+ /**
+ * dragstart回调,可计算特性实现
+ */
+ _ondrop: function (param) {
+ callChartListMethodReverse(this, 'ondrop', param, this._status);
+ this._island.ondrop(param, this._status);
+ },
+
+ /**
+ * dragdone回调 ,可计算特性实现
+ */
+ _ondragend: function (param) {
+ callChartListMethodReverse(this, 'ondragend', param, this._status);
+
+ this._timeline && this._timeline.ondragend(param, this._status);
+ this._island.ondragend(param, this._status);
+
+ // 发生过重计算
+ if (this._status.needRefresh) {
+ this._syncBackupData(this._option);
+
+ var messageCenter = this._messageCenter;
+ messageCenter.dispatch(
+ ecConfig.EVENT.DATA_CHANGED,
+ param.event,
+ this._eventPackage(param.target),
+ this
+ );
+ messageCenter.dispatch(ecConfig.EVENT.REFRESH, null, null, this);
+ }
+ },
+
+ /**
+ * 图例选择响应
+ */
+ _onlegendSelected: function (param) {
+ // 用于图表间通信
+ this._status.needRefresh = false;
+ callChartListMethodReverse(this, 'onlegendSelected', param, this._status);
+
+ if (this._status.needRefresh) {
+ this._messageCenter.dispatch(ecConfig.EVENT.REFRESH, null, null, this);
+ }
+ },
+
+ /**
+ * 数据区域缩放响应
+ */
+ _ondataZoom: function (param) {
+ // 用于图表间通信
+ this._status.needRefresh = false;
+ callChartListMethodReverse(this, 'ondataZoom', param, this._status);
+
+ if (this._status.needRefresh) {
+ this._messageCenter.dispatch(ecConfig.EVENT.REFRESH, null, null, this);
+ }
+ },
+
+ /**
+ * 值域漫游响应
+ */
+ _ondataRange: function (param) {
+ this._clearEffect();
+ // 用于图表间通信
+ this._status.needRefresh = false;
+ callChartListMethodReverse(this, 'ondataRange', param, this._status);
+
+ // 没有相互影响,直接刷新即可
+ if (this._status.needRefresh) {
+ this._zr.refreshNextFrame();
+ }
+ },
+
+ /**
+ * 动态类型切换响应
+ */
+ _onmagicTypeChanged: function () {
+ this._clearEffect();
+ this._render(this._toolbox.getMagicOption());
+ },
+
+ /**
+ * 数据视图修改响应
+ */
+ _ondataViewChanged: function (param) {
+ this._syncBackupData(param.option);
+ this._messageCenter.dispatch(
+ ecConfig.EVENT.DATA_CHANGED,
+ null,
+ param,
+ this
+ );
+ this._messageCenter.dispatch(ecConfig.EVENT.REFRESH, null, null, this);
+ },
+
+ /**
+ * tooltip与图表间通信
+ */
+ _tooltipHover: function (param) {
+ var tipShape = [];
+ callChartListMethodReverse(this, 'ontooltipHover', param, tipShape);
+ },
+
+ /**
+ * 还原
+ */
+ _onrestore: function () {
+ this.restore();
+ },
+
+ /**
+ * 刷新
+ */
+ _onrefresh: function (param) {
+ this._refreshInside = true;
+ this.refresh(param);
+ this._refreshInside = false;
+ },
+
+ /**
+ * 数据修改后的反向同步dataZoom持有的备份数据
+ */
+ _syncBackupData: function (curOption) {
+ this.component.dataZoom && this.component.dataZoom.syncBackupData(curOption);
+ },
+
+ /**
+ * 打包Echarts层的事件附件
+ */
+ _eventPackage: function (target) {
+ if (target) {
+ var ecData = require('./util/ecData');
+
+ var seriesIndex = ecData.get(target, 'seriesIndex');
+ var dataIndex = ecData.get(target, 'dataIndex');
+
+ dataIndex = seriesIndex != -1 && this.component.dataZoom
+ ? this.component.dataZoom.getRealDataIndex(
+ seriesIndex,
+ dataIndex
+ )
+ : dataIndex;
+ return {
+ seriesIndex: seriesIndex,
+ seriesName: (ecData.get(target, 'series') || {}).name,
+ dataIndex: dataIndex,
+ data: ecData.get(target, 'data'),
+ name: ecData.get(target, 'name'),
+ value: ecData.get(target, 'value'),
+ special: ecData.get(target, 'special')
+ };
+ }
+ return;
+ },
+
+ _noDataCheck: function(magicOption) {
+ var series = magicOption.series;
+
+ for (var i = 0, l = series.length; i < l; i++) {
+ if (series[i].type == ecConfig.CHART_TYPE_MAP
+ || (series[i].data && series[i].data.length > 0)
+ || (series[i].markPoint && series[i].markPoint.data && series[i].markPoint.data.length > 0)
+ || (series[i].markLine && series[i].markLine.data && series[i].markLine.data.length > 0)
+ || (series[i].nodes && series[i].nodes.length > 0)
+ || (series[i].links && series[i].links.length > 0)
+ || (series[i].matrix && series[i].matrix.length > 0)
+ || (series[i].eventList && series[i].eventList.length > 0)
+ ) {
+ return false; // 存在任意数据则为非空数据
+ }
+ }
+ var loadOption = (this._option && this._option.noDataLoadingOption)
+ || this._themeConfig.noDataLoadingOption
+ || ecConfig.noDataLoadingOption
+ || {
+ text: (this._option && this._option.noDataText)
+ || this._themeConfig.noDataText
+ || ecConfig.noDataText,
+ effect: (this._option && this._option.noDataEffect)
+ || this._themeConfig.noDataEffect
+ || ecConfig.noDataEffect
+ };
+ // 空数据
+ this.clear();
+ this.showLoading(loadOption);
+ return true;
+ },
+
+ /**
+ * 图表渲染
+ */
+ _render: function (magicOption) {
+ this._mergeGlobalConifg(magicOption);
+
+ if (this._noDataCheck(magicOption)) {
+ return;
+ }
+
+ var bgColor = magicOption.backgroundColor;
+ if (bgColor) {
+ if (!_canvasSupported
+ && bgColor.indexOf('rgba') != -1
+ ) {
+ // IE6~8对RGBA的处理,filter会带来其他颜色的影响
+ var cList = bgColor.split(',');
+ this.dom.style.filter = 'alpha(opacity=' +
+ cList[3].substring(0, cList[3].lastIndexOf(')')) * 100
+ + ')';
+ cList.length = 3;
+ cList[0] = cList[0].replace('a', '');
+ this.dom.style.backgroundColor = cList.join(',') + ')';
+ }
+ else {
+ this.dom.style.backgroundColor = bgColor;
+ }
+ }
+
+ this._zr.clearAnimation();
+ this._chartList = [];
+
+ var chartLibrary = require('./chart');
+ var componentLibrary = require('./component');
+
+ if (magicOption.xAxis || magicOption.yAxis) {
+ magicOption.grid = magicOption.grid || {};
+ magicOption.dataZoom = magicOption.dataZoom || {};
+ }
+
+ var componentList = [
+ 'title', 'legend', 'tooltip', 'dataRange', 'roamController',
+ 'grid', 'dataZoom', 'xAxis', 'yAxis', 'polar'
+ ];
+
+ var ComponentClass;
+ var componentType;
+ var component;
+ for (var i = 0, l = componentList.length; i < l; i++) {
+ componentType = componentList[i];
+ component = this.component[componentType];
+
+ if (magicOption[componentType]) {
+ if (component) {
+ component.refresh && component.refresh(magicOption);
+ }
+ else {
+ ComponentClass = componentLibrary.get(
+ /^[xy]Axis$/.test(componentType) ? 'axis' : componentType
+ );
+ component = new ComponentClass(
+ this._themeConfig, this._messageCenter, this._zr,
+ magicOption, this, componentType
+ );
+ this.component[componentType] = component;
+ }
+ this._chartList.push(component);
+ }
+ else if (component) {
+ component.dispose();
+ this.component[componentType] = null;
+ delete this.component[componentType];
+ }
+ }
+
+ var ChartClass;
+ var chartType;
+ var chart;
+ var chartMap = {}; // 记录已经初始化的图表
+ for (var i = 0, l = magicOption.series.length; i < l; i++) {
+ chartType = magicOption.series[i].type;
+ if (!chartType) {
+ console.error('series[' + i + '] chart type has not been defined.');
+ continue;
+ }
+
+ if (!chartMap[chartType]) {
+ chartMap[chartType] = true;
+ ChartClass = chartLibrary.get(chartType);
+ if (ChartClass) {
+ if (this.chart[chartType]) {
+ chart = this.chart[chartType];
+ chart.refresh(magicOption);
+ }
+ else {
+ chart = new ChartClass(
+ this._themeConfig, this._messageCenter, this._zr,
+ magicOption, this
+ );
+ }
+ this._chartList.push(chart);
+ this.chart[chartType] = chart;
+ }
+ else {
+ console.error(chartType + ' has not been required.');
+ }
+ }
+ }
+
+ // 已有实例但新option不带这类图表的实例释放
+ for (chartType in this.chart) {
+ if (chartType != ecConfig.CHART_TYPE_ISLAND && !chartMap[chartType]) {
+ this.chart[chartType].dispose();
+ this.chart[chartType] = null;
+ delete this.chart[chartType];
+ }
+ }
+
+ this.component.grid && this.component.grid.refixAxisShape(this.component);
+
+ this._island.refresh(magicOption);
+ this._toolbox.refresh(magicOption);
+
+ magicOption.animation && !magicOption.renderAsImage
+ ? this._zr.refresh()
+ : this._zr.render();
+
+ var imgId = 'IMG' + this.id;
+ var img = document.getElementById(imgId);
+ if (magicOption.renderAsImage && _canvasSupported) {
+ // IE8- 不支持图片渲染形式
+ if (img) {
+ // 已经渲染过则更新显示
+ img.src = this.getDataURL(magicOption.renderAsImage);
+ }
+ else {
+ // 没有渲染过插入img dom
+ img = this.getImage(magicOption.renderAsImage);
+ img.id = imgId;
+ img.style.position = 'absolute';
+ img.style.left = 0;
+ img.style.top = 0;
+ this.dom.firstChild.appendChild(img);
+ }
+ this.un();
+ this._zr.un();
+ this._disposeChartList();
+ this._zr.clear();
+ }
+ else if (img) {
+ // 删除可能存在的img
+ img.parentNode.removeChild(img);
+ }
+ img = null;
+
+ this._option = magicOption;
+ },
+
+ /**
+ * 还原
+ */
+ restore: function () {
+ this._clearEffect();
+ this._option = zrUtil.clone(this._optionRestore);
+ this._disposeChartList();
+ this._island.clear();
+ this._toolbox.reset(this._option, true);
+ this._render(this._option);
+ },
+
+ /**
+ * 刷新
+ * @param {Object=} param,可选参数,用于附带option,内部同步用,外部不建议带入数据修改,无法同步
+ */
+ refresh: function (param) {
+ this._clearEffect();
+ param = param || {};
+ var magicOption = param.option;
+
+ // 外部调用的refresh且有option带入
+ if (!this._refreshInside && magicOption) {
+ // 做简单的差异合并去同步内部持有的数据克隆,不建议带入数据
+ // 开启数据区域缩放、拖拽重计算、数据视图可编辑模式情况下,当用户产生了数据变化后无法同步
+ // 如有带入option存在数据变化,请重新setOption
+ magicOption = this.getOption();
+ zrUtil.merge(magicOption, param.option, true);
+ zrUtil.merge(this._optionRestore, param.option, true);
+ this._toolbox.reset(magicOption);
+ }
+
+ this._island.refresh(magicOption);
+ this._toolbox.refresh(magicOption);
+
+ // 停止动画
+ this._zr.clearAnimation();
+ // 先来后到,安顺序刷新各种图表,图表内部refresh优化检查magicOption,无需更新则不更新~
+ for (var i = 0, l = this._chartList.length; i < l; i++) {
+ this._chartList[i].refresh && this._chartList[i].refresh(magicOption);
+ }
+ this.component.grid && this.component.grid.refixAxisShape(this.component);
+ this._zr.refresh();
+ },
+
+ /**
+ * 释放图表实例
+ */
+ _disposeChartList: function () {
+ this._clearEffect();
+
+ // 停止动画
+ this._zr.clearAnimation();
+
+ var len = this._chartList.length;
+ while (len--) {
+ var chart = this._chartList[len];
+
+ if (chart) {
+ var chartType = chart.type;
+ this.chart[chartType] && delete this.chart[chartType];
+ this.component[chartType] && delete this.component[chartType];
+ chart.dispose && chart.dispose();
+ }
+ }
+
+ this._chartList = [];
+ },
+
+ /**
+ * 非图表全局属性merge~~
+ */
+ _mergeGlobalConifg: function (magicOption) {
+ var mergeList = [
+ // 背景颜色
+ 'backgroundColor',
+
+ // 拖拽重计算相关
+ 'calculable', 'calculableColor', 'calculableHolderColor',
+
+ // 孤岛显示连接符
+ 'nameConnector', 'valueConnector',
+
+ // 动画相关
+ 'animation', 'animationThreshold',
+ 'animationDuration', 'animationDurationUpdate',
+ 'animationEasing', 'addDataAnimation',
+
+ // 默认标志图形类型列表
+ 'symbolList',
+
+ // 降低图表内元素拖拽敏感度,单位ms,不建议外部干预
+ 'DRAG_ENABLE_TIME'
+ ];
+
+ var len = mergeList.length;
+ while (len--) {
+ var mergeItem = mergeList[len];
+ if (magicOption[mergeItem] == null) {
+ magicOption[mergeItem] = this._themeConfig[mergeItem] != null
+ ? this._themeConfig[mergeItem]
+ : ecConfig[mergeItem];
+ }
+ }
+
+ // 数值系列的颜色列表,不传则采用内置颜色,可配数组,借用zrender实例注入,会有冲突风险,先这样
+ var themeColor = magicOption.color;
+ if (!(themeColor && themeColor.length)) {
+ themeColor = this._themeConfig.color || ecConfig.color;
+ }
+
+ this._zr.getColor = function (idx) {
+ var zrColor = require('zrender/tool/color');
+ return zrColor.getColor(idx, themeColor);
+ };
+
+ if (!_canvasSupported) {
+ // 不支持Canvas的强制关闭动画
+ magicOption.animation = false;
+ magicOption.addDataAnimation = false;
+ }
+ },
+
+ /**
+ * 万能接口,配置图表实例任何可配置选项,多次调用时option选项做merge处理
+ * @param {Object} option
+ * @param {boolean=} notMerge 多次调用时option选项是默认是合并(merge)的,
+ * 如果不需求,可以通过notMerger参数为true阻止与上次option的合并
+ */
+ setOption: function (option, notMerge) {
+ if (!option.timeline) {
+ return this._setOption(option, notMerge);
+ }
+ else {
+ return this._setTimelineOption(option);
+ }
+ },
+
+ /**
+ * 万能接口,配置图表实例任何可配置选项,多次调用时option选项做merge处理
+ * @param {Object} option
+ * @param {boolean=} notMerge 多次调用时option选项是默认是合并(merge)的,
+ * 如果不需求,可以通过notMerger参数为true阻止与上次option的合并
+ * @param {boolean=} 默认false。keepTimeLine 表示从timeline组件调用而来,
+ * 表示当前行为是timeline的数据切换,保持timeline,
+ * 反之销毁timeline。 详见Issue #1601
+ */
+ _setOption: function (option, notMerge, keepTimeLine) {
+ if (!notMerge && this._option) {
+ this._option = zrUtil.merge(
+ this.getOption(),
+ zrUtil.clone(option),
+ true
+ );
+ }
+ else {
+ this._option = zrUtil.clone(option);
+ !keepTimeLine && this._timeline && this._timeline.dispose();
+ }
+
+ this._optionRestore = zrUtil.clone(this._option);
+
+ if (!this._option.series || this._option.series.length === 0) {
+ this._zr.clear();
+ return;
+ }
+
+ if (this.component.dataZoom // 存在dataZoom控件
+ && (this._option.dataZoom // 并且新option也存在
+ || (this._option.toolbox
+ && this._option.toolbox.feature
+ && this._option.toolbox.feature.dataZoom
+ && this._option.toolbox.feature.dataZoom.show
+ )
+ )
+ ) {
+ // dataZoom同步数据
+ this.component.dataZoom.syncOption(this._option);
+ }
+ this._toolbox.reset(this._option);
+ this._render(this._option);
+ return this;
+ },
+
+ /**
+ * 返回内部持有的当前显示option克隆
+ */
+ getOption: function () {
+ var magicOption = zrUtil.clone(this._option);
+
+ var self = this;
+ function restoreOption(prop) {
+ var restoreSource = self._optionRestore[prop];
+
+ if (restoreSource) {
+ if (restoreSource instanceof Array) {
+ var len = restoreSource.length;
+ while (len--) {
+ magicOption[prop][len].data = zrUtil.clone(
+ restoreSource[len].data
+ );
+ }
+ }
+ else {
+ magicOption[prop].data = zrUtil.clone(restoreSource.data);
+ }
+ }
+ }
+
+ // 横轴数据还原
+ restoreOption('xAxis');
+
+ // 纵轴数据还原
+ restoreOption('yAxis');
+
+ // 系列数据还原
+ restoreOption('series');
+
+ return magicOption;
+ },
+
+ /**
+ * 数据设置快捷接口
+ * @param {Array} series
+ * @param {boolean=} notMerge 多次调用时option选项是默认是合并(merge)的,
+ * 如果不需求,可以通过notMerger参数为true阻止与上次option的合并。
+ */
+ setSeries: function (series, notMerge) {
+ if (!notMerge) {
+ this.setOption({series: series});
+ }
+ else {
+ this._option.series = series;
+ this.setOption(this._option, notMerge);
+ }
+ return this;
+ },
+
+ /**
+ * 返回内部持有的当前显示series克隆
+ */
+ getSeries: function () {
+ return this.getOption().series;
+ },
+
+ /**
+ * timelineOption接口,配置图表实例任何可配置选项
+ * @param {Object} option
+ */
+ _setTimelineOption: function(option) {
+ this._timeline && this._timeline.dispose();
+ var Timeline = require('./component/timeline');
+ var timeline = new Timeline(
+ this._themeConfig, this._messageCenter, this._zr, option, this
+ );
+ this._timeline = timeline;
+ this.component.timeline = this._timeline;
+
+ return this;
+ },
+
+ /**
+ * 动态数据添加
+ * 形参为单组数据参数,多组时为数据,内容同[seriesIdx, data, isShift, additionData]
+ * @param {number} seriesIdx 系列索引
+ * @param {number | Object} data 增加数据
+ * @param {boolean=} isHead 是否队头加入,默认,不指定或false时为队尾插入
+ * @param {boolean=} dataGrow 是否增长数据队列长度,默认,不指定或false时移出目标数组对位数据
+ * @param {string=} additionData 是否增加类目轴(饼图为图例)数据,附加操作同isHead和dataGrow
+ */
+ addData: function (seriesIdx, data, isHead, dataGrow, additionData) {
+ var params = seriesIdx instanceof Array
+ ? seriesIdx
+ : [[seriesIdx, data, isHead, dataGrow, additionData]];
+
+ //this._optionRestore 和 magicOption 都要同步
+ var magicOption = this.getOption();
+ var optionRestore = this._optionRestore;
+ var self = this;
+ for (var i = 0, l = params.length; i < l; i++) {
+ seriesIdx = params[i][0];
+ data = params[i][1];
+ isHead = params[i][2];
+ dataGrow = params[i][3];
+ additionData = params[i][4];
+
+ var seriesItem = optionRestore.series[seriesIdx];
+ var inMethod = isHead ? 'unshift' : 'push';
+ var outMethod = isHead ? 'pop' : 'shift';
+ if (seriesItem) {
+ var seriesItemData = seriesItem.data;
+ var mSeriesItemData = magicOption.series[seriesIdx].data;
+
+ seriesItemData[inMethod](data);
+ mSeriesItemData[inMethod](data);
+ if (!dataGrow) {
+ seriesItemData[outMethod]();
+ data = mSeriesItemData[outMethod]();
+ }
+
+ if (additionData != null) {
+ var legend;
+ var legendData;
+
+ if (seriesItem.type === ecConfig.CHART_TYPE_PIE
+ && (legend = optionRestore.legend)
+ && (legendData = legend.data)
+ ) {
+ var mLegendData = magicOption.legend.data;
+ legendData[inMethod](additionData);
+ mLegendData[inMethod](additionData);
+
+ if (!dataGrow) {
+ var legendDataIdx = zrUtil.indexOf(legendData, data.name);
+ legendDataIdx != -1 && legendData.splice(legendDataIdx, 1);
+
+ legendDataIdx = zrUtil.indexOf(mLegendData, data.name);
+ legendDataIdx != -1 && mLegendData.splice(legendDataIdx, 1);
+ }
+ }
+ else if (optionRestore.xAxis != null && optionRestore.yAxis != null) {
+ // x轴类目
+ var axisData;
+ var mAxisData;
+ var axisIdx = seriesItem.xAxisIndex || 0;
+
+ if (optionRestore.xAxis[axisIdx].type == null
+ || optionRestore.xAxis[axisIdx].type === 'category'
+ ) {
+ axisData = optionRestore.xAxis[axisIdx].data;
+ mAxisData = magicOption.xAxis[axisIdx].data;
+
+ axisData[inMethod](additionData);
+ mAxisData[inMethod](additionData);
+ if (!dataGrow) {
+ axisData[outMethod]();
+ mAxisData[outMethod]();
+ }
+ }
+
+ // y轴类目
+ axisIdx = seriesItem.yAxisIndex || 0;
+ if (optionRestore.yAxis[axisIdx].type === 'category') {
+ axisData = optionRestore.yAxis[axisIdx].data;
+ mAxisData = magicOption.yAxis[axisIdx].data;
+
+ axisData[inMethod](additionData);
+ mAxisData[inMethod](additionData);
+ if (!dataGrow) {
+ axisData[outMethod]();
+ mAxisData[outMethod]();
+ }
+ }
+ }
+ }
+
+ // 同步图表内状态,动画需要
+ this._option.series[seriesIdx].data = magicOption.series[seriesIdx].data;
+ }
+ }
+
+ this._zr.clearAnimation();
+ var chartList = this._chartList;
+ var chartAnimationCount = 0;
+ var chartAnimationDone = function () {
+ chartAnimationCount--;
+ if (chartAnimationCount === 0) {
+ animationDone();
+ }
+ };
+ for (var i = 0, l = chartList.length; i < l; i++) {
+ if (magicOption.addDataAnimation && chartList[i].addDataAnimation) {
+ chartAnimationCount++;
+ chartList[i].addDataAnimation(params, chartAnimationDone);
+ }
+ }
+
+ // dataZoom同步数据
+ this.component.dataZoom && this.component.dataZoom.syncOption(magicOption);
+
+ this._option = magicOption;
+ function animationDone() {
+ if (!self._zr) {
+ return; // 已经被释放
+ }
+ self._zr.clearAnimation();
+ for (var i = 0, l = chartList.length; i < l; i++) {
+ // 有addData动画就去掉过渡动画
+ chartList[i].motionlessOnce =
+ magicOption.addDataAnimation && chartList[i].addDataAnimation;
+ }
+ self._messageCenter.dispatch(
+ ecConfig.EVENT.REFRESH,
+ null,
+ {option: magicOption},
+ self
+ );
+ }
+
+ if (!magicOption.addDataAnimation) {
+ setTimeout(animationDone, 0);
+ }
+ return this;
+ },
+
+ /**
+ * 动态[标注 | 标线]添加
+ * @param {number} seriesIdx 系列索引
+ * @param {Object} markData [标注 | 标线]对象,支持多个
+ */
+ addMarkPoint: function (seriesIdx, markData) {
+ return this._addMark(seriesIdx, markData, 'markPoint');
+ },
+
+ addMarkLine: function (seriesIdx, markData) {
+ return this._addMark(seriesIdx, markData, 'markLine');
+ },
+
+ _addMark: function (seriesIdx, markData, markType) {
+ var series = this._option.series;
+ var seriesItem;
+
+ if (series && (seriesItem = series[seriesIdx])) {
+ var seriesR = this._optionRestore.series;
+ var seriesRItem = seriesR[seriesIdx];
+ var markOpt = seriesItem[markType];
+ var markOptR = seriesRItem[markType];
+
+ markOpt = seriesItem[markType] = markOpt || {data: []};
+ markOptR = seriesRItem[markType] = markOptR || {data: []};
+
+ for (var key in markData) {
+ if (key === 'data') {
+ // 数据concat
+ markOpt.data = markOpt.data.concat(markData.data);
+ markOptR.data = markOptR.data.concat(markData.data);
+ }
+ else if (typeof markData[key] != 'object' || markOpt[key] == null) {
+ // 简单类型或新值直接赋值
+ markOpt[key] = markOptR[key] = markData[key];
+ }
+ else {
+ // 非数据的复杂对象merge
+ zrUtil.merge(markOpt[key], markData[key], true);
+ zrUtil.merge(markOptR[key], markData[key], true);
+ }
+ }
+
+ var chart = this.chart[seriesItem.type];
+ chart && chart.addMark(seriesIdx, markData, markType);
+ }
+
+ return this;
+ },
+
+ /**
+ * 动态[标注 | 标线]删除
+ * @param {number} seriesIdx 系列索引
+ * @param {string} markName [标注 | 标线]名称
+ */
+ delMarkPoint: function (seriesIdx, markName) {
+ return this._delMark(seriesIdx, markName, 'markPoint');
+ },
+
+ delMarkLine: function (seriesIdx, markName) {
+ return this._delMark(seriesIdx, markName, 'markLine');
+ },
+
+ _delMark: function (seriesIdx, markName, markType) {
+ var series = this._option.series;
+ var seriesItem;
+ var mark;
+ var dataArray;
+
+ if (!(
+ series
+ && (seriesItem = series[seriesIdx])
+ && (mark = seriesItem[markType])
+ && (dataArray = mark.data)
+ )
+ ) {
+ return this;
+ }
+
+ markName = markName.split(' > ');
+ var targetIndex = -1;
+
+ for (var i = 0, l = dataArray.length; i < l; i++) {
+ var dataItem = dataArray[i];
+ if (dataItem instanceof Array) {
+ if (dataItem[0].name === markName[0]
+ && dataItem[1].name === markName[1]
+ ) {
+ targetIndex = i;
+ break;
+ }
+ }
+ else if (dataItem.name === markName[0]) {
+ targetIndex = i;
+ break;
+ }
+ }
+
+ if (targetIndex > -1) {
+ dataArray.splice(targetIndex, 1);
+ this._optionRestore.series[seriesIdx][markType].data.splice(targetIndex, 1);
+
+ var chart = this.chart[seriesItem.type];
+ chart && chart.delMark(seriesIdx, markName.join(' > '), markType);
+ }
+
+ return this;
+ },
+
+ /**
+ * 获取当前dom
+ */
+ getDom: function () {
+ return this.dom;
+ },
+
+ /**
+ * 获取当前zrender实例,可用于添加额为的shape和深度控制
+ */
+ getZrender: function () {
+ return this._zr;
+ },
+
+ /**
+ * 获取Base64图片dataURL
+ * @param {string} imgType 图片类型,支持png|jpeg,默认为png
+ * @return imgDataURL
+ */
+ getDataURL: function (imgType) {
+ if (!_canvasSupported) {
+ return '';
+ }
+
+ if (this._chartList.length === 0) {
+ // 渲染为图片
+ var imgId = 'IMG' + this.id;
+ var img = document.getElementById(imgId);
+ if (img) {
+ return img.src;
+ }
+ }
+
+ // 清除可能存在的tooltip元素
+ var tooltip = this.component.tooltip;
+ tooltip && tooltip.hideTip();
+
+ switch (imgType) {
+ case 'jpeg':
+ break;
+ default:
+ imgType = 'png';
+ }
+
+ var bgColor = this._option.backgroundColor;
+ if (bgColor && bgColor.replace(' ','') === 'rgba(0,0,0,0)') {
+ bgColor = '#fff';
+ }
+
+ return this._zr.toDataURL('image/' + imgType, bgColor);
+ },
+
+ /**
+ * 获取img
+ * @param {string} imgType 图片类型,支持png|jpeg,默认为png
+ * @return img dom
+ */
+ getImage: function (imgType) {
+ var title = this._optionRestore.title;
+ var imgDom = document.createElement('img');
+ imgDom.src = this.getDataURL(imgType);
+ imgDom.title = (title && title.text) || 'ECharts';
+ return imgDom;
+ },
+
+ /**
+ * 获取多图联动的Base64图片dataURL
+ * @param {string} imgType 图片类型,支持png|jpeg,默认为png
+ * @return imgDataURL
+ */
+ getConnectedDataURL: function (imgType) {
+ if (!this.isConnected()) {
+ return this.getDataURL(imgType);
+ }
+
+ var tempDom = this.dom;
+ var imgList = {
+ 'self': {
+ img: this.getDataURL(imgType),
+ left: tempDom.offsetLeft,
+ top: tempDom.offsetTop,
+ right: tempDom.offsetLeft + tempDom.offsetWidth,
+ bottom: tempDom.offsetTop + tempDom.offsetHeight
+ }
+ };
+
+ var minLeft = imgList.self.left;
+ var minTop = imgList.self.top;
+ var maxRight = imgList.self.right;
+ var maxBottom = imgList.self.bottom;
+
+ for (var c in this._connected) {
+ tempDom = this._connected[c].getDom();
+ imgList[c] = {
+ img: this._connected[c].getDataURL(imgType),
+ left: tempDom.offsetLeft,
+ top: tempDom.offsetTop,
+ right: tempDom.offsetLeft + tempDom.offsetWidth,
+ bottom: tempDom.offsetTop + tempDom.offsetHeight
+ };
+
+ minLeft = Math.min(minLeft, imgList[c].left);
+ minTop = Math.min(minTop, imgList[c].top);
+ maxRight = Math.max(maxRight, imgList[c].right);
+ maxBottom = Math.max(maxBottom, imgList[c].bottom);
+ }
+
+ var zrDom = document.createElement('div');
+ zrDom.style.position = 'absolute';
+ zrDom.style.left = '-4000px';
+ zrDom.style.width = (maxRight - minLeft) + 'px';
+ zrDom.style.height = (maxBottom - minTop) + 'px';
+ document.body.appendChild(zrDom);
+
+ var zrImg = require('zrender').init(zrDom);
+
+ var ImageShape = require('zrender/shape/Image');
+ for (var c in imgList) {
+ zrImg.addShape(new ImageShape({
+ style: {
+ x: imgList[c].left - minLeft,
+ y: imgList[c].top - minTop,
+ image: imgList[c].img
+ }
+ }));
+ }
+
+ zrImg.render();
+ var bgColor = this._option.backgroundColor;
+ if (bgColor && bgColor.replace(/ /g, '') === 'rgba(0,0,0,0)') {
+ bgColor = '#fff';
+ }
+
+ var image = zrImg.toDataURL('image/png', bgColor);
+
+ setTimeout(function () {
+ zrImg.dispose();
+ zrDom.parentNode.removeChild(zrDom);
+ zrDom = null;
+ }, 100);
+
+ return image;
+ },
+
+ /**
+ * 获取多图联动的img
+ * @param {string} imgType 图片类型,支持png|jpeg,默认为png
+ * @return img dom
+ */
+ getConnectedImage: function (imgType) {
+ var title = this._optionRestore.title;
+ var imgDom = document.createElement('img');
+ imgDom.src = this.getConnectedDataURL(imgType);
+ imgDom.title = (title && title.text) || 'ECharts';
+ return imgDom;
+ },
+
+ /**
+ * 外部接口绑定事件
+ * @param {Object} eventName 事件名称
+ * @param {Object} eventListener 事件响应函数
+ */
+ on: function (eventName, eventListener) {
+ this._messageCenterOutSide.bind(eventName, eventListener, this);
+ return this;
+ },
+
+ /**
+ * 外部接口解除事件绑定
+ * @param {Object} eventName 事件名称
+ * @param {Object} eventListener 事件响应函数
+ */
+ un: function (eventName, eventListener) {
+ this._messageCenterOutSide.unbind(eventName, eventListener);
+ return this;
+ },
+
+ /**
+ * 多图联动
+ * @param connectTarget{ECharts | Array } connectTarget 联动目标
+ */
+ connect: function (connectTarget) {
+ if (!connectTarget) {
+ return this;
+ }
+
+ if (!this._connected) {
+ this._connected = {};
+ }
+
+ if (connectTarget instanceof Array) {
+ for (var i = 0, l = connectTarget.length; i < l; i++) {
+ this._connected[connectTarget[i].id] = connectTarget[i];
+ }
+ }
+ else {
+ this._connected[connectTarget.id] = connectTarget;
+ }
+
+ return this;
+ },
+
+ /**
+ * 解除多图联动
+ * @param connectTarget{ECharts | Array } connectTarget 解除联动目标
+ */
+ disConnect: function (connectTarget) {
+ if (!connectTarget || !this._connected) {
+ return this;
+ }
+
+ if (connectTarget instanceof Array) {
+ for (var i = 0, l = connectTarget.length; i < l; i++) {
+ delete this._connected[connectTarget[i].id];
+ }
+ }
+ else {
+ delete this._connected[connectTarget.id];
+ }
+
+ for (var k in this._connected) {
+ return k, this; // 非空
+ }
+
+ // 空,转为标志位
+ this._connected = false;
+ return this;
+ },
+
+ /**
+ * 联动事件响应
+ */
+ connectedEventHandler: function (param) {
+ if (param.__echartsId != this.id) {
+ // 来自其他联动图表的事件
+ this._onevent(param);
+ }
+ },
+
+ /**
+ * 是否存在多图联动
+ */
+ isConnected: function () {
+ return !!this._connected;
+ },
+
+ /**
+ * 显示loading过渡
+ * @param {Object} loadingOption
+ */
+ showLoading: function (loadingOption) {
+ var effectList = {
+ bar: require('zrender/loadingEffect/Bar'),
+ bubble: require('zrender/loadingEffect/Bubble'),
+ dynamicLine: require('zrender/loadingEffect/DynamicLine'),
+ ring: require('zrender/loadingEffect/Ring'),
+ spin: require('zrender/loadingEffect/Spin'),
+ whirling: require('zrender/loadingEffect/Whirling')
+ };
+ this._toolbox.hideDataView();
+
+ loadingOption = loadingOption || {};
+
+ var textStyle = loadingOption.textStyle || {};
+ loadingOption.textStyle = textStyle;
+
+ var finalTextStyle = zrUtil.merge(
+ zrUtil.merge(
+ zrUtil.clone(textStyle),
+ this._themeConfig.textStyle
+ ),
+ ecConfig.textStyle
+ );
+
+ textStyle.textFont = finalTextStyle.fontStyle + ' '
+ + finalTextStyle.fontWeight + ' '
+ + finalTextStyle.fontSize + 'px '
+ + finalTextStyle.fontFamily;
+
+ textStyle.text = loadingOption.text
+ || (this._option && this._option.loadingText)
+ || this._themeConfig.loadingText
+ || ecConfig.loadingText;
+
+ if (loadingOption.x != null) {
+ textStyle.x = loadingOption.x;
+ }
+ if (loadingOption.y != null) {
+ textStyle.y = loadingOption.y;
+ }
+
+ loadingOption.effectOption = loadingOption.effectOption || {};
+ loadingOption.effectOption.textStyle = textStyle;
+
+ var Effect = loadingOption.effect;
+ if (typeof Effect === 'string' || Effect == null) {
+ Effect = effectList[
+ loadingOption.effect
+ || (this._option && this._option.loadingEffect)
+ || this._themeConfig.loadingEffect
+ || ecConfig.loadingEffect
+ ]
+ || effectList.spin;
+ }
+ this._zr.showLoading(new Effect(loadingOption.effectOption));
+ return this;
+ },
+
+ /**
+ * 隐藏loading过渡
+ */
+ hideLoading: function () {
+ this._zr.hideLoading();
+ return this;
+ },
+
+ /**
+ * 主题设置
+ */
+ setTheme: function (theme) {
+ if (theme) {
+ if (typeof theme === 'string') {
+ // 默认主题
+ switch (theme) {
+ case 'macarons':
+ theme = require('./theme/macarons');
+ break;
+ case 'infographic':
+ theme = require('./theme/infographic');
+ break;
+ default:
+ theme = {}; // require('./theme/default');
+ }
+ }
+ else {
+ theme = theme || {};
+ }
+
+ // // 复位默认配置
+ // // this._themeConfig会被别的对象引用持有
+ // // 所以不能改成this._themeConfig = {};
+ // for (var key in this._themeConfig) {
+ // delete this._themeConfig[key];
+ // }
+ // for (var key in ecConfig) {
+ // this._themeConfig[key] = zrUtil.clone(ecConfig[key]);
+ // }
+
+ // // 颜色数组随theme,不merge
+ // theme.color && (this._themeConfig.color = []);
+
+ // // 默认标志图形类型列表,不merge
+ // theme.symbolList && (this._themeConfig.symbolList = []);
+
+ // // 应用新主题
+ // zrUtil.merge(this._themeConfig, zrUtil.clone(theme), true);
+ this._themeConfig = theme;
+ }
+
+ if (!_canvasSupported) { // IE8-
+ var textStyle = this._themeConfig.textStyle;
+ textStyle && textStyle.fontFamily && textStyle.fontFamily2
+ && (textStyle.fontFamily = textStyle.fontFamily2);
+
+ textStyle = ecConfig.textStyle;
+ textStyle.fontFamily = textStyle.fontFamily2;
+ }
+
+ this._timeline && this._timeline.setTheme(true);
+ this._optionRestore && this.restore();
+ },
+
+ /**
+ * 视图区域大小变化更新,不默认绑定,供使用方按需调用
+ */
+ resize: function () {
+ var self = this;
+ return function(){
+ self._clearEffect();
+ self._zr.resize();
+ if (self._option && self._option.renderAsImage && _canvasSupported) {
+ // 渲染为图片重走render模式
+ self._render(self._option);
+ return self;
+ }
+ // 停止动画
+ self._zr.clearAnimation();
+ self._island.resize();
+ self._toolbox.resize();
+ self._timeline && self._timeline.resize();
+ // 先来后到,不能仅刷新自己,也不能在上一个循环中刷新,如坐标系数据改变会影响其他图表的大小
+ // 所以安顺序刷新各种图表,图表内部refresh优化无需更新则不更新~
+ for (var i = 0, l = self._chartList.length; i < l; i++) {
+ self._chartList[i].resize && self._chartList[i].resize();
+ }
+ self.component.grid && self.component.grid.refixAxisShape(self.component);
+ self._zr.refresh();
+ self._messageCenter.dispatch(ecConfig.EVENT.RESIZE, null, null, self);
+ return self;
+ };
+ },
+
+ _clearEffect: function() {
+ this._zr.modLayer(ecConfig.EFFECT_ZLEVEL, { motionBlur: false });
+ this._zr.painter.clearLayer(ecConfig.EFFECT_ZLEVEL);
+ },
+
+ /**
+ * 清除已渲染内容 ,clear后echarts实例可用
+ */
+ clear: function () {
+ this._disposeChartList();
+ this._zr.clear();
+ this._option = {};
+ this._optionRestore = {};
+ this.dom.style.backgroundColor = null;
+ return this;
+ },
+
+ /**
+ * 释放,dispose后echarts实例不可用
+ */
+ dispose: function () {
+ var key = this.dom.getAttribute(DOM_ATTRIBUTE_KEY);
+ key && delete _instances[key];
+
+ this._island.dispose();
+ this._toolbox.dispose();
+ this._timeline && this._timeline.dispose();
+ this._messageCenter.unbind();
+ this.clear();
+ this._zr.dispose();
+ this._zr = null;
+ }
+ };
+
+ return self;
+});
\ No newline at end of file
diff --git a/resources/echarts.properties b/resources/echarts.properties
new file mode 100644
index 0000000..13edba1
--- /dev/null
+++ b/resources/echarts.properties
@@ -0,0 +1,29 @@
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2014-2015 abel533@gmail.com
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# \uFFFD\u01F7\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0524\uFFFD\uFFFD
+view = false
+
+# \uFFFD\uFFFD\uFFFD\uFFFDhtml\uFFFD\u013C\uFFFD\u013F\u00BC
+exportpath = /tmp/echarts
\ No newline at end of file
diff --git a/resources/template b/resources/template
new file mode 100644
index 0000000..b1965cc
--- /dev/null
+++ b/resources/template
@@ -0,0 +1,38 @@
+
+
+
+
+ ECharts - Generate By @isea533/abel533
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e69de29
diff --git a/src/com/xiuye/sharp/Castor.java b/src/com/xiuye/sharp/Castor.java
new file mode 100644
index 0000000..b9f85bc
--- /dev/null
+++ b/src/com/xiuye/sharp/Castor.java
@@ -0,0 +1,15 @@
+package com.xiuye.sharp;
+
+import com.xiuye.util.cls.XType;
+
+public interface Castor {
+
+ default T cast() {
+ return cast(this);
+ }
+
+ default R cast(I in) {
+ return XType.cast(in);
+ }
+
+}
diff --git a/src/com/xiuye/sharp/X.java b/src/com/xiuye/sharp/X.java
new file mode 100644
index 0000000..0edfc7a
--- /dev/null
+++ b/src/com/xiuye/sharp/X.java
@@ -0,0 +1,800 @@
+package com.xiuye.sharp;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+import com.google.gson.Gson;
+import com.xiuye.util.cls.XType;
+import com.xiuye.util.json.JsonUtil;
+import com.xiuye.util.log.XLog;
+
+public class X {// sharp tools
+
+ // 一般是这步的计算结果,传递给下一步
+ private RESULT result;
+ // 这步产生的错误
+ private Throwable error;
+
+ // 异常必须处理后才能进行下一步
+ private static boolean ignoreException = true;
+
+ public X() {
+
+ }
+
+ public X(RESULT result) {
+ this.result = result;
+ }
+
+ public X(RESULT result, Throwable error) {
+ this.result = result;
+ this.error = error;
+ }
+
+ public X(Throwable error) {
+ this.error = error;
+ }
+
+ public Throwable getError() {
+ return error;
+ }
+
+ public RESULT get() {
+ return result;
+ }
+
+ private static void ifError(VoidCallbackWithParam callback, X x) {
+ if (!ignoreException && x.error != null) {
+ callback.vci(x.error);
+ }
+ }
+
+ private static void ifError(X x) {
+ ifError((e) -> {
+ throw new RuntimeException("Some errors occur!" + "Please use \"except\" to handle error next step!", e);
+ }, x);
+ }
+
+ //有异常都捕获
+ private static R catchExec(ReturnCallbackNoParam callback, X x) {
+ ifError(x);
+ try {
+ return callback.rcv();
+ } catch (Throwable e) {
+ x.error = e;
+ }
+ return null;
+ }
+
+ private static T catchExec(VoidCallbackNoParam callback, X x) {
+ ifError(x);
+ try {
+ callback.vcv();
+ } catch (Throwable e) {
+ x.error = e;
+ }
+ // error 的时候 ,result是不存在的!所有返回null是正确的!
+ return x.result;
+ }
+
+ private static R errorHandler(VoidCallbackNoParam callback, X x) {
+ try {
+ callback.vcv();
+ // 捕获异常后将上一步的异常 清理掉
+ // 能到这一步,表示编译完美无误的处理异常!
+ // error 是 类中局部变量,好处是不会被 final 约束了
+ x.error = null;
+ } catch (Throwable e) {
+ x.error = e;
+ }
+ // error 的时候 ,result是不存在的!所有返回null是正确的!
+ return null;
+ }
+
+ // 必须自己实现与其他类库无关的接口,哪怕是SDK 标准库
+ // 否则 将面临 传参 的 一些莫名其妙的错误!
+
+ /**
+ * R call (I)
+ *
+ * @param
+ * @param
+ */
+ public /* static default */ interface ReturnCallbackWithParam {
+ R rci(I in);
+ }
+
+ /**
+ * void callback(I)
+ *
+ * @param
+ */
+ public /* static default */ interface VoidCallbackWithParam {
+ void vci(I in);
+ }
+
+ public /* static default */ interface VoidCallbackNoParam {
+ void vcv();
+ }
+
+ /**
+ * R call()
+ *
+ * @param
+ */
+ public /* static default */ interface ReturnCallbackNoParam {
+ R rcv();
+ }
+
+ public static void ignoreException(boolean ignore) {
+ ignoreException = ignore;
+ }
+
+ // static and non-static all can use it
+ private static boolean parseBoolean(I t) {
+ if (t == null) {
+ return false;
+ } else {// existence is true
+ boolean b = true;
+ if (t instanceof Boolean) {
+ b = XType.cast(t);
+ }
+ return b;
+ }
+ }
+
+ public static X resolve() {
+ return new X<>();
+ }
+
+ public static X resolve(R r) {
+ return new X<>(r);
+ }
+
+ private static X resolve(R r, E error) {
+ return new X<>(r, error);
+ }
+
+ public static X reject(E e) {
+ return new X<>(e);
+ }
+
+ public static X of() {
+ return resolve();
+ }
+
+ public static X of(R t) {
+ return resolve(t);
+ }
+
+ public static X of(R r, E error) {
+ return resolve(r, error);
+ }
+
+ public X THEN(ReturnCallbackNoParam callback) {
+ return of(catchExec(() -> callback.rcv(), this), this.error);
+ }
+
+ public X THEN(ReturnCallbackWithParam callback) {
+ return of(catchExec(() -> callback.rci(result), this), error);
+ }
+
+ public X THEN(VoidCallbackWithParam callback) {
+ return of(catchExec(() -> callback.vci(result), this), error);
+ }
+
+ public X THEN(VoidCallbackNoParam callback) {
+ return of(catchExec(() -> callback.vcv(), this), error);
+ }
+
+ public X FINALLY(ReturnCallbackNoParam callback) {
+ return THEN(callback);
+ }
+
+ public X FINALLY(ReturnCallbackWithParam callback) {
+ return THEN(callback);
+ }
+
+ public X FINALLY(VoidCallbackWithParam callback) {
+ return THEN(callback);
+ }
+
+ public X FINALLY(VoidCallbackNoParam callback) {
+ return THEN(callback);
+ }
+
+ // 传入都是空!所以随便返回什么类型
+
+ private boolean errorExist() {
+ return error != null;
+ }
+
+ public X EX(ReturnCallbackNoParam callback) {
+ return resolve(errorExist() ? errorHandler(() -> callback.rcv(), this) : result, error);
+ }
+
+ public X EX(ReturnCallbackWithParam callback) {
+ return resolve(errorExist() ? errorHandler(() -> callback.rci(error), this) : result, error);
+ }
+
+ public X EX(VoidCallbackWithParam callback) {
+ return resolve(errorExist() ? errorHandler(() -> callback.vci(error), this) : result, error);
+ }
+
+ public X EX(VoidCallbackNoParam callback) {
+ return resolve(errorExist() ? errorHandler(() -> callback.vcv(), this) : result, error);
+ }
+
+ private boolean exist() {
+ return result != null;
+ }
+
+ // exist
+ public X E() {
+ return of(exist(), error);
+ }
+
+ public X E(ReturnCallbackNoParam callback) {
+ return exist() ? THEN(callback) : reject(error);
+ }
+
+ public X E(ReturnCallbackWithParam callback) {
+ return exist() ? THEN(callback) : reject(error);
+ }
+
+ public X E(VoidCallbackWithParam callback) {
+ return exist() ? THEN(callback) : reject(error);
+ }
+
+ public X E(VoidCallbackNoParam callback) {
+ return exist() ? THEN(callback) : reject(error);
+ }
+
+ public X1 begin() {
+ return new X1<>(result, error);
+ }
+
+ public static X1 beginS() {
+ return new X1<>();
+ }
+
+ private boolean truely() {
+ return catchExec(() -> parseBoolean(result), this);
+ }
+
+ // true
+ public X T() {
+ return of(truely(), error);
+ }
+
+ public X T(ReturnCallbackNoParam callback) {
+ return truely() ? THEN(callback) : reject(error);
+ }
+
+ public X T(ReturnCallbackWithParam callback) {
+ return truely() ? THEN(callback) : reject(error);
+ }
+
+ public X T(VoidCallbackWithParam callback) {
+ return truely() ? THEN(callback) : reject(error);
+ }
+
+ public X T(VoidCallbackNoParam callback) {
+ return truely() ? THEN(callback) : reject(error);
+ }
+
+ public X F() {
+ return of(!truely(), error);
+ }
+
+ public X F(ReturnCallbackNoParam callback) {
+ return !truely() ? THEN(callback) : reject(error);
+ }
+
+ public X F(ReturnCallbackWithParam callback) {
+ return !truely() ? THEN(callback) : reject(error);
+ }
+
+ public X F(VoidCallbackWithParam callback) {
+ return !truely() ? THEN(callback) : reject(error);
+ }
+
+ public X F(VoidCallbackNoParam callback) {
+ return !truely() ? THEN(callback) : reject(error);
+ }
+
+ public static abstract class AbstractPromiseTask extends Thread {
+
+ protected FUNC func;
+ protected R result;
+ protected I input;
+ protected Throwable error;
+
+ public AbstractPromiseTask(FUNC func) {
+ this.func = func;
+ }
+
+ public AbstractPromiseTask(FUNC func, I input) {
+ this(func);
+ this.input = input;
+ }
+
+ protected T catchExec(ReturnCallbackNoParam callback) {
+ try {
+ return callback.rcv();
+ } catch (Throwable e) {
+ error = e;
+ }
+ return null;
+ }
+
+ protected T catchExec(VoidCallbackNoParam callback) {
+ try {
+ callback.vcv();
+ } catch (Throwable e) {
+ error = e;
+ }
+ return null;
+ }
+
+ public R get() {
+ try {
+ this.join();
+ } catch (InterruptedException e) {
+ error = e;
+ }
+ return result;
+ }
+
+ public R get(long millis) throws InterruptedException {
+ try {
+ this.join(millis);
+ } catch (InterruptedException e) {
+ error = e;
+ }
+ return result;
+ }
+
+// public void set(R result) {
+// this.result = result;
+// }
+
+ public Throwable getError() {
+ return error;
+ }
+
+ public I getInput() {
+ return input;
+ }
+
+ public void setInput(I input) {
+ this.input = input;
+ }
+
+ }
+
+ public static class PromiseTaskRCI extends AbstractPromiseTask, R, I> {
+
+ public PromiseTaskRCI(ReturnCallbackWithParam func) {
+ super(func);
+ }
+
+ public PromiseTaskRCI(ReturnCallbackWithParam func, I input) {
+ super(func, input);
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ result = catchExec(() -> func.rci(input));
+ }
+
+ }
+
+ public static class PromiseTaskRCV extends AbstractPromiseTask, R, I> {
+
+ public PromiseTaskRCV(ReturnCallbackNoParam func) {
+ super(func);
+ }
+
+ public PromiseTaskRCV(ReturnCallbackNoParam func, I input) {
+ super(func, input);
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ result = catchExec(() -> func.rcv());
+ }
+
+ }
+
+ public static class PromiseTaskVCI extends AbstractPromiseTask, R, I> {
+
+ public PromiseTaskVCI(VoidCallbackWithParam func) {
+ super(func);
+ }
+
+ public PromiseTaskVCI(VoidCallbackWithParam func, I input) {
+ super(func, input);
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ result = catchExec(() -> func.vci(input));
+ }
+
+ }
+
+ public static class PromiseTaskVCV extends AbstractPromiseTask {
+
+ public PromiseTaskVCV(VoidCallbackNoParam func) {
+ super(func);
+ }
+
+ public PromiseTaskVCV(VoidCallbackNoParam func, I input) {
+ super(func, input);
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ result = catchExec(() -> func.vcv());
+ }
+
+ }
+
+ public static X> taskS(VoidCallbackNoParam callback) {
+ AbstractPromiseTask taskObj = new PromiseTaskVCV<>(callback);
+ taskObj.start();
+ return of(taskObj);
+ }
+
+ public static X, R, I>> taskS(
+ VoidCallbackWithParam callback) {
+ AbstractPromiseTask, R, I> taskObj = new PromiseTaskVCI<>(callback);
+ taskObj.start();
+ return of(taskObj);
+ }
+
+ public static X, R, I>> taskS(VoidCallbackWithParam callback,
+ I input) {
+ AbstractPromiseTask, R, I> taskObj = new PromiseTaskVCI<>(callback, input);
+ taskObj.start();
+ return of(taskObj);
+ }
+
+ public static X, R, I>> taskS(
+ ReturnCallbackNoParam callback) {
+ AbstractPromiseTask, R, I> taskObj = new PromiseTaskRCV<>(callback);
+ taskObj.start();
+ return of(taskObj);
+ }
+
+ public static X, R, I>> taskS(
+ ReturnCallbackWithParam callback) {
+ AbstractPromiseTask, R, I> taskObj = new PromiseTaskRCI<>(callback);
+ taskObj.start();
+ return of(taskObj);
+ }
+
+ public static X, R, I>> taskS(
+ ReturnCallbackWithParam callback, I input) {
+ AbstractPromiseTask, R, I> taskObj = new PromiseTaskRCI<>(callback, input);
+ taskObj.start();
+ return of(taskObj);
+ }
+
+ public X> task(VoidCallbackNoParam callback) {
+ AbstractPromiseTask taskObj = new PromiseTaskVCV<>(callback, result);
+ taskObj.start();
+ return of(taskObj, error);
+ }
+
+ public X, R, RESULT>> task(
+ VoidCallbackWithParam callback) {
+ AbstractPromiseTask, R, RESULT> taskObj = new PromiseTaskVCI<>(callback, result);
+ taskObj.start();
+ return of(taskObj, error);
+ }
+
+ public X, R, I>> task(VoidCallbackWithParam callback,
+ I input) {
+ AbstractPromiseTask, R, I> taskObj = new PromiseTaskVCI<>(callback, input);
+ taskObj.start();
+ return of(taskObj, error);
+ }
+
+ public X, R, RESULT>> task(ReturnCallbackNoParam callback) {
+ AbstractPromiseTask, R, RESULT> taskObj = new PromiseTaskRCV<>(callback, result);
+ taskObj.start();
+ return of(taskObj, error);
+ }
+
+ public X, R, RESULT>> task(
+ ReturnCallbackWithParam callback) {
+ AbstractPromiseTask, R, RESULT> taskObj = new PromiseTaskRCI<>(callback,
+ result);
+ taskObj.start();
+ return of(taskObj, error);
+ }
+
+ public X, R, I>> task(
+ ReturnCallbackWithParam callback, I input) {
+ AbstractPromiseTask, R, I> taskObj = new PromiseTaskRCI<>(callback, input);
+ taskObj.start();
+ return of(taskObj, error);
+ }
+
+ @SafeVarargs
+ public static X logS(R... in) {
+ XLog.lg(in);
+ return of(in);
+ }
+
+ @SafeVarargs
+ public static X lgS(R... in) {
+ return logS(in);
+ }
+
+ @SafeVarargs
+ public static X lineS(R... in) {
+ X pro = of(in);
+ catchExec(() -> {
+ XLog.attach(3);
+ XLog.line(in);
+ XLog.dettach(3);
+ }, pro);
+
+ return pro;
+ }
+
+ @SafeVarargs
+ public static X lnS(R... in) {
+ X pro = of(in);
+ catchExec(() -> {
+ XLog.attach(3);
+ XLog.line(in);
+ XLog.dettach(3);
+ }, pro);
+
+ return pro;
+ }
+
+ public X log() {
+ XLog.lg(result);
+ return of(result, error);
+ }
+
+ public X lg() {
+ return log();
+ }
+
+ public X line() {
+ catchExec(() -> {
+ XLog.attach(3);
+ XLog.line(result);
+ XLog.dettach(3);
+ }, this);
+ return of(result, error);
+ }
+
+ public X ln() {
+ catchExec(() -> {
+ XLog.attach(3);
+ XLog.ln(result);
+ XLog.dettach(3);
+ }, this);
+ return of(result, error);
+ }
+
+ public static X2 beanS(String name) {
+ return new X2<>(name);
+ }
+
+ public static X2 beanS(String name, R object) {
+ return beanS(name, object, false);
+ }
+
+ public static X2 beanS(String name, R object, boolean replace) {
+ return new X2<>(name, object, replace);
+ }
+
+ public static X2 beanS(String name, Class clazz) {
+ return new X2<>(name, clazz);
+ }
+
+ public static X2 beanS(String name, Class clazz, R r) {
+ return beanS(name, clazz, r, false);
+ }
+
+ public static X2 beanS(String name, Class clazz, R r, boolean replace) {
+ return new X2<>(name, clazz, r, replace);
+ }
+
+ public static X2 beanS( Class clazz,String name,R r) {
+ return beanS(clazz,name,r,false);
+ }
+
+ public static X2 beanS( Class clazz,String name,R r, boolean replace) {
+ return new X2<>(name, clazz, r, replace);
+ }
+
+ public static X2 beanS(Class clazz) {
+ return new X2<>(clazz);
+ }
+
+ public static X2 beanS(Class clazz, R r) {
+ return beanS(clazz, r, false);
+ }
+
+ public static X2 beanS(Class clazz, R r, boolean replace) {
+ return new X2<>(clazz, r, replace);
+ }
+
+ public X2 bean(String name) {
+ return beanS(name);
+ }
+
+ public X2 bean(String name, R object) {
+ return beanS(name, object);
+ }
+
+ public X2 bean(String name, R object, boolean replace) {
+ return beanS(name, object, replace);
+ }
+
+ public X2 bean(String name, Class clazz) {
+ return beanS(name, clazz);
+ }
+
+ public X2 bean(String name, Class clazz, R r) {
+ return beanS(name, clazz, r);
+ }
+
+ public X2 bean(String name, Class clazz, R r, boolean replace) {
+ return beanS(name, clazz, r, replace);
+ }
+
+ public X2 bean(Class clazz) {
+ return beanS(clazz);
+ }
+
+ public X2 bean(Class clazz, R r) {
+ return beanS(clazz, r);
+ }
+
+ public X2 bean(Class clazz, R r, boolean replace) {
+ return beanS(clazz, r, replace);
+ }
+
+ public X2 bean(){
+ return beanS("X",result,true);
+ }
+
+ public void set(RESULT r) {
+ this.result = r;
+ }
+
+ public static X tcpS(int port) {
+
+ X x = of();
+ try {
+ x.set(new ServerSocket(port));
+ } catch (IOException e) {
+ x.error = e;
+ }
+ return x;
+ }
+
+ public X tcp(int port) {
+ return tcpS(port);
+ }
+
+ public static X tcpS(String ip, int port) {
+ X x = of();
+ try {
+// return of(new Socket(ip, port));
+ x.set(new Socket(ip, port));
+ } catch (IOException e) {
+// e.printStackTrace();
+ x.error = e;
+ }
+ return x;
+ }
+
+ public X tcp(String ip, int port) {
+ return tcp(ip, port);
+ }
+
+ public static X udpS(int port) {
+ X x = of();
+ try {
+// return of(new DatagramSocket(port));
+ x.set(new DatagramSocket(port));
+ } catch (SocketException e) {
+ x.error = e;
+ }
+ return x;
+ }
+
+ public X udp(int port) {
+ return udpS(port);
+ }
+
+ public static X udpS() {
+ X x = of();
+ try {
+ x.set(new DatagramSocket());
+ } catch (SocketException e) {
+// e.printStackTrace();
+ x.error = e;
+ }
+ return x;
+ }
+
+ public X udp() {
+ return udpS();
+ }
+
+
+ public X toFormatJson() {
+ return of(catchExec(() -> JsonUtil.instance(JsonUtil.FORMAT_GSON).toJson(result),this), error);
+ }
+
+ public X toJson() {
+ return of(catchExec(() -> JsonUtil.instance().toJson(result),this));
+ }
+
+ public X toObject(Class clazz) {
+ return of(catchExec(() -> JsonUtil.instance().fromJson(result != null ? result.toString() : null, clazz),this),
+ error);
+ }
+
+ public static X formatterJsonKitS() {
+
+ X gsonX = of();
+ gsonX.set(
+ catchExec(()->JsonUtil.instance(JsonUtil.FORMAT_GSON),
+ gsonX));
+
+ return gsonX;
+ }
+
+ public static X jsonKitS() {
+ X gsonX = of();
+ gsonX.set(
+ catchExec(()->JsonUtil.instance(),
+ gsonX));
+ return gsonX;
+ }
+
+ public X formatterJsonKit() {
+ return of(catchExec(() -> JsonUtil.instance(JsonUtil.FORMAT_GSON),this), error);
+ }
+
+ public X jsonKit() {
+ return of(catchExec(() -> JsonUtil.instance(),this), error);
+ }
+
+
+ public static X