8f9d1975bbfd2ac2742c8e1d072aa0948b225447.svn-base 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /**
  2. * echarts组件:漫游控制器
  3. *
  4. * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
  5. * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
  6. *
  7. */
  8. define(function (require) {
  9. var Base = require('./base');
  10. // 图形依赖
  11. var RectangleShape = require('zrender/shape/Rectangle');
  12. var SectorShape = require('zrender/shape/Sector');
  13. var CircleShape = require('zrender/shape/Circle');
  14. var ecConfig = require('../config');
  15. ecConfig.roamController = {
  16. zlevel: 0, // 一级层叠
  17. z: 4, // 二级层叠
  18. show: true,
  19. x: 'left', // 水平安放位置,默认为全图左对齐,可选为:
  20. // 'center' ¦ 'left' ¦ 'right'
  21. // ¦ {number}(x坐标,单位px)
  22. y: 'top', // 垂直安放位置,默认为全图顶端,可选为:
  23. // 'top' ¦ 'bottom' ¦ 'center'
  24. // ¦ {number}(y坐标,单位px)
  25. width: 80,
  26. height: 120,
  27. backgroundColor: 'rgba(0,0,0,0)',
  28. borderColor: '#ccc', // 图例边框颜色
  29. borderWidth: 0, // 图例边框线宽,单位px,默认为0(无边框)
  30. padding: 5, // 图例内边距,单位px,默认各方向内边距为5,
  31. // 接受数组分别设定上右下左边距,同css
  32. handleColor: '#6495ed',
  33. fillerColor: '#fff',
  34. step: 15, // 移动幅度
  35. mapTypeControl: null
  36. };
  37. var zrUtil = require('zrender/tool/util');
  38. var zrColor = require('zrender/tool/color');
  39. var zrEvent = require('zrender/tool/event');
  40. /**
  41. * 构造函数
  42. * @param {Object} messageCenter echart消息中心
  43. * @param {ZRender} zr zrender实例
  44. * @param {Object} option 图表参数
  45. */
  46. function RoamController(ecTheme, messageCenter, zr, option, myChart) {
  47. this.rcOption = {};
  48. if (!option.roamController || !option.roamController.show) {
  49. return;
  50. }
  51. if (!option.roamController.mapTypeControl) {
  52. console.error('option.roamController.mapTypeControl has not been defined.');
  53. return;
  54. }
  55. Base.call(this, ecTheme, messageCenter, zr, option, myChart);
  56. this.rcOption = option.roamController;
  57. var self = this;
  58. this._drictionMouseDown = function(params) {
  59. return self.__drictionMouseDown(params);
  60. };
  61. this._drictionMouseUp = function(params) {
  62. return self.__drictionMouseUp(params);
  63. };
  64. this._drictionMouseMove = function(params) {
  65. return self.__drictionMouseMove(params);
  66. };
  67. this._drictionMouseOut = function(params) {
  68. return self.__drictionMouseOut(params);
  69. };
  70. this._scaleHandler = function(params) {
  71. return self.__scaleHandler(params);
  72. };
  73. this.refresh(option);
  74. }
  75. RoamController.prototype = {
  76. type: ecConfig.COMPONENT_TYPE_ROAMCONTROLLER,
  77. _buildShape: function () {
  78. if (!this.rcOption.show) {
  79. return;
  80. }
  81. // 元素组的位置参数,通过计算所得x, y, width, height
  82. this._itemGroupLocation = this._getItemGroupLocation();
  83. this._buildBackground();
  84. this._buildItem();
  85. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  86. this.zr.addShape(this.shapeList[i]);
  87. }
  88. },
  89. /**
  90. * 构建所有漫游控制器元素
  91. */
  92. _buildItem: function () {
  93. this.shapeList.push(this._getDirectionShape('up'));
  94. this.shapeList.push(this._getDirectionShape('down'));
  95. this.shapeList.push(this._getDirectionShape('left'));
  96. this.shapeList.push(this._getDirectionShape('right'));
  97. this.shapeList.push(this._getScaleShape('scaleUp'));
  98. this.shapeList.push(this._getScaleShape('scaleDown'));
  99. },
  100. _getDirectionShape: function(direction) {
  101. var r = this._itemGroupLocation.r;
  102. var x = this._itemGroupLocation.x + r;
  103. var y = this._itemGroupLocation.y + r;
  104. var sectorShape = {
  105. zlevel: this.getZlevelBase(),
  106. z: this.getZBase(),
  107. style: {
  108. x: x, // 圆心横坐标
  109. y: y, // 圆心纵坐标
  110. r: r, // 圆环外半径
  111. startAngle: -45,
  112. endAngle: 45,
  113. color: this.rcOption.handleColor,
  114. text: '>',
  115. textX: x + r / 2 + 4,
  116. textY: y - 0.5,
  117. textAlign: 'center',
  118. textBaseline: 'middle',
  119. textPosition: 'specific',
  120. textColor: this.rcOption.fillerColor,
  121. textFont: Math.floor(r / 2) + 'px arial'
  122. },
  123. highlightStyle: {
  124. color: zrColor.lift(this.rcOption.handleColor, -0.2),
  125. brushType: 'fill'
  126. },
  127. clickable: true
  128. };
  129. switch (direction) {
  130. case 'up':
  131. sectorShape.rotation = [Math.PI / 2, x, y];
  132. break;
  133. case 'left':
  134. sectorShape.rotation = [Math.PI, x, y];
  135. break;
  136. case 'down':
  137. sectorShape.rotation = [-Math.PI / 2, x, y];
  138. break;
  139. }
  140. sectorShape = new SectorShape(sectorShape);
  141. sectorShape._roamType = direction;
  142. sectorShape.onmousedown = this._drictionMouseDown;
  143. sectorShape.onmouseup = this._drictionMouseUp;
  144. sectorShape.onmousemove = this._drictionMouseMove;
  145. sectorShape.onmouseout = this._drictionMouseOut;
  146. return sectorShape;
  147. },
  148. _getScaleShape: function(text) {
  149. var width = this._itemGroupLocation.width;
  150. var height = this._itemGroupLocation.height - width;
  151. height = height < 0 ? 20 : height; // 确保height不为负
  152. var r = Math.min(width / 2 - 5, height) / 2;
  153. var x = this._itemGroupLocation.x
  154. + (text === 'scaleDown' ? (width - r) : r);
  155. var y = this._itemGroupLocation.y + this._itemGroupLocation.height - r;
  156. var scaleShape = {
  157. zlevel: this.getZlevelBase(),
  158. z: this.getZBase(),
  159. style: {
  160. x: x,
  161. y: y,
  162. r: r,
  163. color: this.rcOption.handleColor,
  164. text: text === 'scaleDown' ? '-' : '+',
  165. textX: x,
  166. textY: y - 2,
  167. textAlign: 'center',
  168. textBaseline: 'middle',
  169. textPosition: 'specific',
  170. textColor: this.rcOption.fillerColor,
  171. textFont: Math.floor(r) + 'px verdana'
  172. },
  173. highlightStyle: {
  174. color: zrColor.lift(this.rcOption.handleColor, -0.2),
  175. brushType: 'fill'
  176. },
  177. clickable: true
  178. };
  179. scaleShape = new CircleShape(scaleShape);
  180. scaleShape._roamType = text;
  181. scaleShape.onmousedown = this._scaleHandler;
  182. return scaleShape;
  183. },
  184. _buildBackground: function () {
  185. var padding = this.reformCssArray(this.rcOption.padding);
  186. this.shapeList.push(new RectangleShape({
  187. zlevel: this.getZlevelBase(),
  188. z: this.getZBase(),
  189. hoverable :false,
  190. style: {
  191. x: this._itemGroupLocation.x - padding[3],
  192. y: this._itemGroupLocation.y - padding[0],
  193. width: this._itemGroupLocation.width + padding[3] + padding[1],
  194. height: this._itemGroupLocation.height + padding[0] + padding[2],
  195. brushType: this.rcOption.borderWidth === 0 ? 'fill' : 'both',
  196. color: this.rcOption.backgroundColor,
  197. strokeColor: this.rcOption.borderColor,
  198. lineWidth: this.rcOption.borderWidth
  199. }
  200. }));
  201. },
  202. /**
  203. * 根据选项计算漫游控制器实体的位置坐标
  204. */
  205. _getItemGroupLocation: function () {
  206. var padding = this.reformCssArray(this.rcOption.padding);
  207. var width = this.rcOption.width;
  208. var height = this.rcOption.height;
  209. var zrWidth = this.zr.getWidth();
  210. var zrHeight = this.zr.getHeight();
  211. var x;
  212. switch (this.rcOption.x) {
  213. case 'center' :
  214. x = Math.floor((zrWidth - width) / 2);
  215. break;
  216. case 'left' :
  217. x = padding[3] + this.rcOption.borderWidth;
  218. break;
  219. case 'right' :
  220. x = zrWidth
  221. - width
  222. - padding[1]
  223. - padding[3]
  224. - this.rcOption.borderWidth * 2;
  225. break;
  226. default :
  227. x = this.parsePercent(this.rcOption.x, zrWidth);
  228. break;
  229. }
  230. var y;
  231. switch (this.rcOption.y) {
  232. case 'top' :
  233. y = padding[0] + this.rcOption.borderWidth;
  234. break;
  235. case 'bottom' :
  236. y = zrHeight
  237. - height
  238. - padding[0]
  239. - padding[2]
  240. - this.rcOption.borderWidth * 2;
  241. break;
  242. case 'center' :
  243. y = Math.floor((zrHeight - height) / 2);
  244. break;
  245. default :
  246. y = this.parsePercent(this.rcOption.y, zrHeight);
  247. break;
  248. }
  249. return {
  250. x: x,
  251. y: y,
  252. r: width / 2,
  253. width: width,
  254. height: height
  255. };
  256. },
  257. __drictionMouseDown: function(params) {
  258. this.mousedown = true;
  259. this._drictionHandlerOn(params);
  260. },
  261. __drictionMouseUp: function(params) {
  262. this.mousedown = false;
  263. this._drictionHandlerOff(params);
  264. },
  265. __drictionMouseMove: function(params) {
  266. if (this.mousedown) {
  267. this._drictionHandlerOn(params);
  268. }
  269. },
  270. __drictionMouseOut: function(params) {
  271. this._drictionHandlerOff(params);
  272. },
  273. _drictionHandlerOn: function(params) {
  274. this._dispatchEvent(params.event, params.target._roamType);
  275. clearInterval(this.dircetionTimer);
  276. var self = this;
  277. this.dircetionTimer = setInterval(function() {
  278. self._dispatchEvent(params.event, params.target._roamType);
  279. }, 100);
  280. zrEvent.stop(params.event);
  281. },
  282. _drictionHandlerOff: function(params) {
  283. clearInterval(this.dircetionTimer);
  284. },
  285. __scaleHandler: function(params) {
  286. this._dispatchEvent(params.event, params.target._roamType);
  287. zrEvent.stop(params.event);
  288. },
  289. _dispatchEvent: function(event, roamType){
  290. this.messageCenter.dispatch(
  291. ecConfig.EVENT.ROAMCONTROLLER,
  292. event,
  293. {
  294. roamType: roamType,
  295. mapTypeControl: this.rcOption.mapTypeControl,
  296. step: this.rcOption.step
  297. },
  298. this.myChart
  299. );
  300. },
  301. /**
  302. * 刷新
  303. */
  304. refresh: function (newOption) {
  305. if (newOption) {
  306. this.option = newOption || this.option;
  307. this.option.roamController = this.reformOption(this.option.roamController);
  308. this.rcOption = this.option.roamController;
  309. }
  310. this.clear();
  311. this._buildShape();
  312. }
  313. };
  314. zrUtil.inherits(RoamController, Base);
  315. require('../component').define('roamController', RoamController);
  316. return RoamController;
  317. });