CLIENT GUI Framework
[vnfsdk/refrepo.git] / portal-common / src / main / webapp / common / thirdparty / echarts / echarts.js
1 (function webpackUniversalModuleDefinition(root, factory) {\r
2         if(typeof exports === 'object' && typeof module === 'object')\r
3                 module.exports = factory();\r
4         else if(typeof define === 'function' && define.amd)\r
5                 define([], factory);\r
6         else if(typeof exports === 'object')\r
7                 exports["echarts"] = factory();\r
8         else\r
9                 root["echarts"] = factory();\r
10 })(this, function() {\r
11 return /******/ (function(modules) { // webpackBootstrap\r
12 /******/        // The module cache\r
13 /******/        var installedModules = {};\r
14 \r
15 /******/        // The require function\r
16 /******/        function __webpack_require__(moduleId) {\r
17 \r
18 /******/                // Check if module is in cache\r
19 /******/                if(installedModules[moduleId])\r
20 /******/                        return installedModules[moduleId].exports;\r
21 \r
22 /******/                // Create a new module (and put it into the cache)\r
23 /******/                var module = installedModules[moduleId] = {\r
24 /******/                        exports: {},\r
25 /******/                        id: moduleId,\r
26 /******/                        loaded: false\r
27 /******/                };\r
28 \r
29 /******/                // Execute the module function\r
30 /******/                modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\r
31 \r
32 /******/                // Flag the module as loaded\r
33 /******/                module.loaded = true;\r
34 \r
35 /******/                // Return the exports of the module\r
36 /******/                return module.exports;\r
37 /******/        }\r
38 \r
39 \r
40 /******/        // expose the modules object (__webpack_modules__)\r
41 /******/        __webpack_require__.m = modules;\r
42 \r
43 /******/        // expose the module cache\r
44 /******/        __webpack_require__.c = installedModules;\r
45 \r
46 /******/        // __webpack_public_path__\r
47 /******/        __webpack_require__.p = "";\r
48 \r
49 /******/        // Load entry module and return exports\r
50 /******/        return __webpack_require__(0);\r
51 /******/ })\r
52 /************************************************************************/\r
53 /******/ ([\r
54 /* 0 */\r
55 /***/ function(module, exports, __webpack_require__) {\r
56 \r
57         /**\r
58          * Export echarts as CommonJS module\r
59          */\r
60         module.exports = __webpack_require__(1);\r
61 \r
62         // Import all charts and components\r
63         __webpack_require__(91);\r
64         __webpack_require__(127);\r
65         __webpack_require__(132);\r
66         __webpack_require__(141);\r
67         __webpack_require__(145);\r
68 \r
69         __webpack_require__(155);\r
70         __webpack_require__(177);\r
71         __webpack_require__(189);\r
72         __webpack_require__(207);\r
73         __webpack_require__(211);\r
74         __webpack_require__(215);\r
75         __webpack_require__(230);\r
76         __webpack_require__(236);\r
77         __webpack_require__(243);\r
78         __webpack_require__(249);\r
79         __webpack_require__(253);\r
80         __webpack_require__(258);\r
81 \r
82         __webpack_require__(106);\r
83         __webpack_require__(262);\r
84         __webpack_require__(268);\r
85         __webpack_require__(272);\r
86         __webpack_require__(283);\r
87         __webpack_require__(216);\r
88 \r
89         __webpack_require__(285);\r
90 \r
91         __webpack_require__(286);\r
92         __webpack_require__(300);\r
93 \r
94         __webpack_require__(315);\r
95         __webpack_require__(319);\r
96 \r
97         __webpack_require__(322);\r
98         __webpack_require__(331);\r
99 \r
100         __webpack_require__(345);\r
101 \r
102 \r
103 /***/ },\r
104 /* 1 */\r
105 /***/ function(module, exports, __webpack_require__) {\r
106 \r
107         /*!\r
108          * ECharts, a javascript interactive chart library.\r
109          *\r
110          * Copyright (c) 2015, Baidu Inc.\r
111          * All rights reserved.\r
112          *\r
113          * LICENSE\r
114          * https://github.com/ecomfe/echarts/blob/master/LICENSE.txt\r
115          */\r
116 \r
117         /**\r
118          * @module echarts\r
119          */\r
120 \r
121 \r
122             var GlobalModel = __webpack_require__(2);\r
123             var ExtensionAPI = __webpack_require__(24);\r
124             var CoordinateSystemManager = __webpack_require__(25);\r
125             var OptionManager = __webpack_require__(26);\r
126 \r
127             var ComponentModel = __webpack_require__(19);\r
128             var SeriesModel = __webpack_require__(27);\r
129 \r
130             var ComponentView = __webpack_require__(28);\r
131             var ChartView = __webpack_require__(41);\r
132             var graphic = __webpack_require__(42);\r
133 \r
134             var zrender = __webpack_require__(77);\r
135             var zrUtil = __webpack_require__(3);\r
136             var colorTool = __webpack_require__(38);\r
137             var env = __webpack_require__(78);\r
138             var Eventful = __webpack_require__(32);\r
139 \r
140             var each = zrUtil.each;\r
141 \r
142             var VISUAL_CODING_STAGES = ['echarts', 'chart', 'component'];\r
143 \r
144             // TODO Transform first or filter first\r
145             var PROCESSOR_STAGES = ['transform', 'filter', 'statistic'];\r
146 \r
147             function createRegisterEventWithLowercaseName(method) {\r
148                 return function (eventName, handler, context) {\r
149                     // Event name is all lowercase\r
150                     eventName = eventName && eventName.toLowerCase();\r
151                     Eventful.prototype[method].call(this, eventName, handler, context);\r
152                 };\r
153             }\r
154             /**\r
155              * @module echarts~MessageCenter\r
156              */\r
157             function MessageCenter() {\r
158                 Eventful.call(this);\r
159             }\r
160             MessageCenter.prototype.on = createRegisterEventWithLowercaseName('on');\r
161             MessageCenter.prototype.off = createRegisterEventWithLowercaseName('off');\r
162             MessageCenter.prototype.one = createRegisterEventWithLowercaseName('one');\r
163             zrUtil.mixin(MessageCenter, Eventful);\r
164             /**\r
165              * @module echarts~ECharts\r
166              */\r
167             function ECharts (dom, theme, opts) {\r
168                 opts = opts || {};\r
169 \r
170                 // Get theme by name\r
171                 if (typeof theme === 'string') {\r
172                     theme = themeStorage[theme];\r
173                 }\r
174 \r
175                 if (theme) {\r
176                     each(optionPreprocessorFuncs, function (preProcess) {\r
177                         preProcess(theme);\r
178                     });\r
179                 }\r
180                 /**\r
181                  * @type {string}\r
182                  */\r
183                 this.id;\r
184                 /**\r
185                  * Group id\r
186                  * @type {string}\r
187                  */\r
188                 this.group;\r
189                 /**\r
190                  * @type {HTMLDomElement}\r
191                  * @private\r
192                  */\r
193                 this._dom = dom;\r
194                 /**\r
195                  * @type {module:zrender/ZRender}\r
196                  * @private\r
197                  */\r
198                 this._zr = zrender.init(dom, {\r
199                     renderer: opts.renderer || 'canvas',\r
200                     devicePixelRatio: opts.devicePixelRatio\r
201                 });\r
202 \r
203                 /**\r
204                  * @type {Object}\r
205                  * @private\r
206                  */\r
207                 this._theme = zrUtil.clone(theme);\r
208 \r
209                 /**\r
210                  * @type {Array.<module:echarts/view/Chart>}\r
211                  * @private\r
212                  */\r
213                 this._chartsViews = [];\r
214 \r
215                 /**\r
216                  * @type {Object.<string, module:echarts/view/Chart>}\r
217                  * @private\r
218                  */\r
219                 this._chartsMap = {};\r
220 \r
221                 /**\r
222                  * @type {Array.<module:echarts/view/Component>}\r
223                  * @private\r
224                  */\r
225                 this._componentsViews = [];\r
226 \r
227                 /**\r
228                  * @type {Object.<string, module:echarts/view/Component>}\r
229                  * @private\r
230                  */\r
231                 this._componentsMap = {};\r
232 \r
233                 /**\r
234                  * @type {module:echarts/ExtensionAPI}\r
235                  * @private\r
236                  */\r
237                 this._api = new ExtensionAPI(this);\r
238 \r
239                 /**\r
240                  * @type {module:echarts/CoordinateSystem}\r
241                  * @private\r
242                  */\r
243                 this._coordSysMgr = new CoordinateSystemManager();\r
244 \r
245                 Eventful.call(this);\r
246 \r
247                 /**\r
248                  * @type {module:echarts~MessageCenter}\r
249                  * @private\r
250                  */\r
251                 this._messageCenter = new MessageCenter();\r
252 \r
253                 // Init mouse events\r
254                 this._initEvents();\r
255 \r
256                 // In case some people write `window.onresize = chart.resize`\r
257                 this.resize = zrUtil.bind(this.resize, this);\r
258             }\r
259 \r
260             var echartsProto = ECharts.prototype;\r
261 \r
262             /**\r
263              * @return {HTMLDomElement}\r
264              */\r
265             echartsProto.getDom = function () {\r
266                 return this._dom;\r
267             };\r
268 \r
269             /**\r
270              * @return {module:zrender~ZRender}\r
271              */\r
272             echartsProto.getZr = function () {\r
273                 return this._zr;\r
274             };\r
275 \r
276             /**\r
277              * @param {Object} option\r
278              * @param {boolean} notMerge\r
279              * @param {boolean} [notRefreshImmediately=false] Useful when setOption frequently.\r
280              */\r
281             echartsProto.setOption = function (option, notMerge, notRefreshImmediately) {\r
282                 if (!this._model || notMerge) {\r
283                     this._model = new GlobalModel(\r
284                         null, null, this._theme, new OptionManager(this._api)\r
285                     );\r
286                 }\r
287 \r
288                 this._model.setOption(option, optionPreprocessorFuncs);\r
289 \r
290                 updateMethods.prepareAndUpdate.call(this);\r
291 \r
292                 !notRefreshImmediately && this._zr.refreshImmediately();\r
293             };\r
294 \r
295             /**\r
296              * @DEPRECATED\r
297              */\r
298             echartsProto.setTheme = function () {\r
299                 console.log('ECharts#setTheme() is DEPRECATED in ECharts 3.0');\r
300             };\r
301 \r
302             /**\r
303              * @return {module:echarts/model/Global}\r
304              */\r
305             echartsProto.getModel = function () {\r
306                 return this._model;\r
307             };\r
308 \r
309             /**\r
310              * @return {Object}\r
311              */\r
312             echartsProto.getOption = function () {\r
313                 return this._model.getOption();\r
314             };\r
315 \r
316             /**\r
317              * @return {number}\r
318              */\r
319             echartsProto.getWidth = function () {\r
320                 return this._zr.getWidth();\r
321             };\r
322 \r
323             /**\r
324              * @return {number}\r
325              */\r
326             echartsProto.getHeight = function () {\r
327                 return this._zr.getHeight();\r
328             };\r
329 \r
330             /**\r
331              * Get canvas which has all thing rendered\r
332              * @param {Object} opts\r
333              * @param {string} [opts.backgroundColor]\r
334              */\r
335             echartsProto.getRenderedCanvas = function (opts) {\r
336                 if (!env.canvasSupported) {\r
337                     return;\r
338                 }\r
339                 opts = opts || {};\r
340                 opts.pixelRatio = opts.pixelRatio || 1;\r
341                 opts.backgroundColor = opts.backgroundColor\r
342                     || this._model.get('backgroundColor');\r
343                 var zr = this._zr;\r
344                 var list = zr.storage.getDisplayList();\r
345                 // Stop animations\r
346                 zrUtil.each(list, function (el) {\r
347                     el.stopAnimation(true);\r
348                 });\r
349                 return zr.painter.getRenderedCanvas(opts);\r
350             };\r
351             /**\r
352              * @return {string}\r
353              * @param {Object} opts\r
354              * @param {string} [opts.type='png']\r
355              * @param {string} [opts.pixelRatio=1]\r
356              * @param {string} [opts.backgroundColor]\r
357              */\r
358             echartsProto.getDataURL = function (opts) {\r
359                 opts = opts || {};\r
360                 var excludeComponents = opts.excludeComponents;\r
361                 var ecModel = this._model;\r
362                 var excludesComponentViews = [];\r
363                 var self = this;\r
364 \r
365                 each(excludeComponents, function (componentType) {\r
366                     ecModel.eachComponent({\r
367                         mainType: componentType\r
368                     }, function (component) {\r
369                         var view = self._componentsMap[component.__viewId];\r
370                         if (!view.group.ignore) {\r
371                             excludesComponentViews.push(view);\r
372                             view.group.ignore = true;\r
373                         }\r
374                     });\r
375                 });\r
376 \r
377                 var url = this.getRenderedCanvas(opts).toDataURL(\r
378                     'image/' + (opts && opts.type || 'png')\r
379                 );\r
380 \r
381                 each(excludesComponentViews, function (view) {\r
382                     view.group.ignore = false;\r
383                 });\r
384                 return url;\r
385             };\r
386 \r
387 \r
388             /**\r
389              * @return {string}\r
390              * @param {Object} opts\r
391              * @param {string} [opts.type='png']\r
392              * @param {string} [opts.pixelRatio=1]\r
393              * @param {string} [opts.backgroundColor]\r
394              */\r
395             echartsProto.getConnectedDataURL = function (opts) {\r
396                 if (!env.canvasSupported) {\r
397                     return;\r
398                 }\r
399                 var groupId = this.group;\r
400                 var mathMin = Math.min;\r
401                 var mathMax = Math.max;\r
402                 var MAX_NUMBER = Infinity;\r
403                 if (connectedGroups[groupId]) {\r
404                     var left = MAX_NUMBER;\r
405                     var top = MAX_NUMBER;\r
406                     var right = -MAX_NUMBER;\r
407                     var bottom = -MAX_NUMBER;\r
408                     var canvasList = [];\r
409                     var dpr = (opts && opts.pixelRatio) || 1;\r
410                     for (var id in instances) {\r
411                         var chart = instances[id];\r
412                         if (chart.group === groupId) {\r
413                             var canvas = chart.getRenderedCanvas(\r
414                                 zrUtil.clone(opts)\r
415                             );\r
416                             var boundingRect = chart.getDom().getBoundingClientRect();\r
417                             left = mathMin(boundingRect.left, left);\r
418                             top = mathMin(boundingRect.top, top);\r
419                             right = mathMax(boundingRect.right, right);\r
420                             bottom = mathMax(boundingRect.bottom, bottom);\r
421                             canvasList.push({\r
422                                 dom: canvas,\r
423                                 left: boundingRect.left,\r
424                                 top: boundingRect.top\r
425                             });\r
426                         }\r
427                     }\r
428 \r
429                     left *= dpr;\r
430                     top *= dpr;\r
431                     right *= dpr;\r
432                     bottom *= dpr;\r
433                     var width = right - left;\r
434                     var height = bottom - top;\r
435                     var targetCanvas = zrUtil.createCanvas();\r
436                     targetCanvas.width = width;\r
437                     targetCanvas.height = height;\r
438                     var zr = zrender.init(targetCanvas);\r
439 \r
440                     each(canvasList, function (item) {\r
441                         var img = new graphic.Image({\r
442                             style: {\r
443                                 x: item.left * dpr - left,\r
444                                 y: item.top * dpr - top,\r
445                                 image: item.dom\r
446                             }\r
447                         });\r
448                         zr.add(img);\r
449                     });\r
450                     zr.refreshImmediately();\r
451 \r
452                     return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png'));\r
453                 }\r
454                 else {\r
455                     return this.getDataURL(opts);\r
456                 }\r
457             };\r
458 \r
459             var updateMethods = {\r
460 \r
461                 /**\r
462                  * @param {Object} payload\r
463                  * @private\r
464                  */\r
465                 update: function (payload) {\r
466                     // console.time && console.time('update');\r
467 \r
468                     var ecModel = this._model;\r
469                     var api = this._api;\r
470                     var coordSysMgr = this._coordSysMgr;\r
471                     // update before setOption\r
472                     if (!ecModel) {\r
473                         return;\r
474                     }\r
475 \r
476                     ecModel.restoreData();\r
477 \r
478                     // TODO\r
479                     // Save total ecModel here for undo/redo (after restoring data and before processing data).\r
480                     // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call.\r
481 \r
482                     // Create new coordinate system each update\r
483                     // In LineView may save the old coordinate system and use it to get the orignal point\r
484                     coordSysMgr.create(this._model, this._api);\r
485 \r
486                     processData.call(this, ecModel, api);\r
487 \r
488                     stackSeriesData.call(this, ecModel);\r
489 \r
490                     coordSysMgr.update(ecModel, api);\r
491 \r
492                     doLayout.call(this, ecModel, payload);\r
493 \r
494                     doVisualCoding.call(this, ecModel, payload);\r
495 \r
496                     doRender.call(this, ecModel, payload);\r
497 \r
498                     // Set background\r
499                     var backgroundColor = ecModel.get('backgroundColor') || 'transparent';\r
500 \r
501                     var painter = this._zr.painter;\r
502                     // TODO all use clearColor ?\r
503                     if (painter.isSingleCanvas && painter.isSingleCanvas()) {\r
504                         this._zr.configLayer(0, {\r
505                             clearColor: backgroundColor\r
506                         });\r
507                     }\r
508                     else {\r
509                         // In IE8\r
510                         if (!env.canvasSupported) {\r
511                             var colorArr = colorTool.parse(backgroundColor);\r
512                             backgroundColor = colorTool.stringify(colorArr, 'rgb');\r
513                             if (colorArr[3] === 0) {\r
514                                 backgroundColor = 'transparent';\r
515                             }\r
516                         }\r
517                         backgroundColor = backgroundColor;\r
518                         this._dom.style.backgroundColor = backgroundColor;\r
519                     }\r
520 \r
521                     // console.time && console.timeEnd('update');\r
522                 },\r
523 \r
524                 // PENDING\r
525                 /**\r
526                  * @param {Object} payload\r
527                  * @private\r
528                  */\r
529                 updateView: function (payload) {\r
530                     var ecModel = this._model;\r
531 \r
532                     // update before setOption\r
533                     if (!ecModel) {\r
534                         return;\r
535                     }\r
536 \r
537                     doLayout.call(this, ecModel, payload);\r
538 \r
539                     doVisualCoding.call(this, ecModel, payload);\r
540 \r
541                     invokeUpdateMethod.call(this, 'updateView', ecModel, payload);\r
542                 },\r
543 \r
544                 /**\r
545                  * @param {Object} payload\r
546                  * @private\r
547                  */\r
548                 updateVisual: function (payload) {\r
549                     var ecModel = this._model;\r
550 \r
551                     // update before setOption\r
552                     if (!ecModel) {\r
553                         return;\r
554                     }\r
555 \r
556                     doVisualCoding.call(this, ecModel, payload);\r
557 \r
558                     invokeUpdateMethod.call(this, 'updateVisual', ecModel, payload);\r
559                 },\r
560 \r
561                 /**\r
562                  * @param {Object} payload\r
563                  * @private\r
564                  */\r
565                 updateLayout: function (payload) {\r
566                     var ecModel = this._model;\r
567 \r
568                     // update before setOption\r
569                     if (!ecModel) {\r
570                         return;\r
571                     }\r
572 \r
573                     doLayout.call(this, ecModel, payload);\r
574 \r
575                     invokeUpdateMethod.call(this, 'updateLayout', ecModel, payload);\r
576                 },\r
577 \r
578                 /**\r
579                  * @param {Object} payload\r
580                  * @private\r
581                  */\r
582                 highlight: function (payload) {\r
583                     toggleHighlight.call(this, 'highlight', payload);\r
584                 },\r
585 \r
586                 /**\r
587                  * @param {Object} payload\r
588                  * @private\r
589                  */\r
590                 downplay: function (payload) {\r
591                     toggleHighlight.call(this, 'downplay', payload);\r
592                 },\r
593 \r
594                 /**\r
595                  * @param {Object} payload\r
596                  * @private\r
597                  */\r
598                 prepareAndUpdate: function (payload) {\r
599                     var ecModel = this._model;\r
600 \r
601                     prepareView.call(this, 'component', ecModel);\r
602 \r
603                     prepareView.call(this, 'chart', ecModel);\r
604 \r
605                     updateMethods.update.call(this, payload);\r
606                 }\r
607             };\r
608 \r
609             /**\r
610              * @param {Object} payload\r
611              * @private\r
612              */\r
613             function toggleHighlight(method, payload) {\r
614                 var ecModel = this._model;\r
615 \r
616                 // dispatchAction before setOption\r
617                 if (!ecModel) {\r
618                     return;\r
619                 }\r
620 \r
621                 ecModel.eachComponent(\r
622                     {mainType: 'series', query: payload},\r
623                     function (seriesModel, index) {\r
624                         var chartView = this._chartsMap[seriesModel.__viewId];\r
625                         if (chartView && chartView.__alive) {\r
626                             chartView[method](\r
627                                 seriesModel, ecModel, this._api, payload\r
628                             );\r
629                         }\r
630                     },\r
631                     this\r
632                 );\r
633             }\r
634 \r
635             /**\r
636              * Resize the chart\r
637              */\r
638             echartsProto.resize = function () {\r
639                 this._zr.resize();\r
640 \r
641                 var optionChanged = this._model && this._model.resetOption('media');\r
642                 updateMethods[optionChanged ? 'prepareAndUpdate' : 'update'].call(this);\r
643 \r
644                 // Resize loading effect\r
645                 this._loadingFX && this._loadingFX.resize();\r
646             };\r
647 \r
648             var defaultLoadingEffect = __webpack_require__(87);\r
649             /**\r
650              * Show loading effect\r
651              * @param  {string} [name='default']\r
652              * @param  {Object} [cfg]\r
653              */\r
654             echartsProto.showLoading = function (name, cfg) {\r
655                 if (zrUtil.isObject(name)) {\r
656                     cfg = name;\r
657                     name = 'default';\r
658                 }\r
659                 this.hideLoading();\r
660                 var el = defaultLoadingEffect(this._api, cfg);\r
661                 var zr = this._zr;\r
662                 this._loadingFX = el;\r
663 \r
664                 zr.add(el);\r
665             };\r
666 \r
667             /**\r
668              * Hide loading effect\r
669              */\r
670             echartsProto.hideLoading = function () {\r
671                 this._loadingFX && this._zr.remove(this._loadingFX);\r
672                 this._loadingFX = null;\r
673             };\r
674 \r
675             /**\r
676              * @param {Object} eventObj\r
677              * @return {Object}\r
678              */\r
679             echartsProto.makeActionFromEvent = function (eventObj) {\r
680                 var payload = zrUtil.extend({}, eventObj);\r
681                 payload.type = eventActionMap[eventObj.type];\r
682                 return payload;\r
683             };\r
684 \r
685             /**\r
686              * @pubilc\r
687              * @param {Object} payload\r
688              * @param {string} [payload.type] Action type\r
689              * @param {boolean} [silent=false] Whether trigger event.\r
690              */\r
691             echartsProto.dispatchAction = function (payload, silent) {\r
692                 var actionWrap = actions[payload.type];\r
693                 if (actionWrap) {\r
694                     var actionInfo = actionWrap.actionInfo;\r
695                     var updateMethod = actionInfo.update || 'update';\r
696 \r
697                     var payloads = [payload];\r
698                     var batched = false;\r
699                     // Batch action\r
700                     if (payload.batch) {\r
701                         batched = true;\r
702                         payloads = zrUtil.map(payload.batch, function (item) {\r
703                             item = zrUtil.defaults(zrUtil.extend({}, item), payload);\r
704                             item.batch = null;\r
705                             return item;\r
706                         });\r
707                     }\r
708 \r
709                     var eventObjBatch = [];\r
710                     var eventObj;\r
711                     var isHighlightOrDownplay = payload.type === 'highlight' || payload.type === 'downplay';\r
712                     for (var i = 0; i < payloads.length; i++) {\r
713                         var batchItem = payloads[i];\r
714                         // Action can specify the event by return it.\r
715                         eventObj = actionWrap.action(batchItem, this._model);\r
716                         // Emit event outside\r
717                         eventObj = eventObj || zrUtil.extend({}, batchItem);\r
718                         // Convert type to eventType\r
719                         eventObj.type = actionInfo.event || eventObj.type;\r
720                         eventObjBatch.push(eventObj);\r
721 \r
722                         // Highlight and downplay are special.\r
723                         isHighlightOrDownplay && updateMethods[updateMethod].call(this, batchItem);\r
724                     }\r
725 \r
726                     (updateMethod !== 'none' && !isHighlightOrDownplay)\r
727                         && updateMethods[updateMethod].call(this, payload);\r
728 \r
729                     if (!silent) {\r
730                         // Follow the rule of action batch\r
731                         if (batched) {\r
732                             eventObj = {\r
733                                 type: actionInfo.event || payload.type,\r
734                                 batch: eventObjBatch\r
735                             };\r
736                         }\r
737                         else {\r
738                             eventObj = eventObjBatch[0];\r
739                         }\r
740                         this._messageCenter.trigger(eventObj.type, eventObj);\r
741                     }\r
742                 }\r
743             };\r
744 \r
745             /**\r
746              * Register event\r
747              * @method\r
748              */\r
749             echartsProto.on = createRegisterEventWithLowercaseName('on');\r
750             echartsProto.off = createRegisterEventWithLowercaseName('off');\r
751             echartsProto.one = createRegisterEventWithLowercaseName('one');\r
752 \r
753             /**\r
754              * @param {string} methodName\r
755              * @private\r
756              */\r
757             function invokeUpdateMethod(methodName, ecModel, payload) {\r
758                 var api = this._api;\r
759 \r
760                 // Update all components\r
761                 each(this._componentsViews, function (component) {\r
762                     var componentModel = component.__model;\r
763                     component[methodName](componentModel, ecModel, api, payload);\r
764 \r
765                     updateZ(componentModel, component);\r
766                 }, this);\r
767 \r
768                 // Upate all charts\r
769                 ecModel.eachSeries(function (seriesModel, idx) {\r
770                     var chart = this._chartsMap[seriesModel.__viewId];\r
771                     chart[methodName](seriesModel, ecModel, api, payload);\r
772 \r
773                     updateZ(seriesModel, chart);\r
774                 }, this);\r
775 \r
776             }\r
777 \r
778             /**\r
779              * Prepare view instances of charts and components\r
780              * @param  {module:echarts/model/Global} ecModel\r
781              * @private\r
782              */\r
783             function prepareView(type, ecModel) {\r
784                 var isComponent = type === 'component';\r
785                 var viewList = isComponent ? this._componentsViews : this._chartsViews;\r
786                 var viewMap = isComponent ? this._componentsMap : this._chartsMap;\r
787                 var zr = this._zr;\r
788 \r
789                 for (var i = 0; i < viewList.length; i++) {\r
790                     viewList[i].__alive = false;\r
791                 }\r
792 \r
793                 ecModel[isComponent ? 'eachComponent' : 'eachSeries'](function (componentType, model) {\r
794                     if (isComponent) {\r
795                         if (componentType === 'series') {\r
796                             return;\r
797                         }\r
798                     }\r
799                     else {\r
800                         model = componentType;\r
801                     }\r
802 \r
803                     // Consider: id same and type changed.\r
804                     var viewId = model.id + '_' + model.type;\r
805                     var view = viewMap[viewId];\r
806                     if (!view) {\r
807                         var classType = ComponentModel.parseClassType(model.type);\r
808                         var Clazz = isComponent\r
809                             ? ComponentView.getClass(classType.main, classType.sub)\r
810                             : ChartView.getClass(classType.sub);\r
811                         if (Clazz) {\r
812                             view = new Clazz();\r
813                             view.init(ecModel, this._api);\r
814                             viewMap[viewId] = view;\r
815                             viewList.push(view);\r
816                             zr.add(view.group);\r
817                         }\r
818                         else {\r
819                             // Error\r
820                             return;\r
821                         }\r
822                     }\r
823 \r
824                     model.__viewId = viewId;\r
825                     view.__alive = true;\r
826                     view.__id = viewId;\r
827                     view.__model = model;\r
828                 }, this);\r
829 \r
830                 for (var i = 0; i < viewList.length;) {\r
831                     var view = viewList[i];\r
832                     if (!view.__alive) {\r
833                         zr.remove(view.group);\r
834                         view.dispose(ecModel, this._api);\r
835                         viewList.splice(i, 1);\r
836                         delete viewMap[view.__id];\r
837                     }\r
838                     else {\r
839                         i++;\r
840                     }\r
841                 }\r
842             }\r
843 \r
844             /**\r
845              * Processor data in each series\r
846              *\r
847              * @param {module:echarts/model/Global} ecModel\r
848              * @private\r
849              */\r
850             function processData(ecModel, api) {\r
851                 each(PROCESSOR_STAGES, function (stage) {\r
852                     each(dataProcessorFuncs[stage] || [], function (process) {\r
853                         process(ecModel, api);\r
854                     });\r
855                 });\r
856             }\r
857 \r
858             /**\r
859              * @private\r
860              */\r
861             function stackSeriesData(ecModel) {\r
862                 var stackedDataMap = {};\r
863                 ecModel.eachSeries(function (series) {\r
864                     var stack = series.get('stack');\r
865                     var data = series.getData();\r
866                     if (stack && data.type === 'list') {\r
867                         var previousStack = stackedDataMap[stack];\r
868                         if (previousStack) {\r
869                             data.stackedOn = previousStack;\r
870                         }\r
871                         stackedDataMap[stack] = data;\r
872                     }\r
873                 });\r
874             }\r
875 \r
876             /**\r
877              * Layout before each chart render there series, after visual coding and data processing\r
878              *\r
879              * @param {module:echarts/model/Global} ecModel\r
880              * @private\r
881              */\r
882             function doLayout(ecModel, payload) {\r
883                 var api = this._api;\r
884                 each(layoutFuncs, function (layout) {\r
885                     layout(ecModel, api, payload);\r
886                 });\r
887             }\r
888 \r
889             /**\r
890              * Code visual infomation from data after data processing\r
891              *\r
892              * @param {module:echarts/model/Global} ecModel\r
893              * @private\r
894              */\r
895             function doVisualCoding(ecModel, payload) {\r
896                 each(VISUAL_CODING_STAGES, function (stage) {\r
897                     each(visualCodingFuncs[stage] || [], function (visualCoding) {\r
898                         visualCoding(ecModel, payload);\r
899                     });\r
900                 });\r
901             }\r
902 \r
903             /**\r
904              * Render each chart and component\r
905              * @private\r
906              */\r
907             function doRender(ecModel, payload) {\r
908                 var api = this._api;\r
909                 // Render all components\r
910                 each(this._componentsViews, function (componentView) {\r
911                     var componentModel = componentView.__model;\r
912                     componentView.render(componentModel, ecModel, api, payload);\r
913 \r
914                     updateZ(componentModel, componentView);\r
915                 }, this);\r
916 \r
917                 each(this._chartsViews, function (chart) {\r
918                     chart.__alive = false;\r
919                 }, this);\r
920 \r
921                 // Render all charts\r
922                 ecModel.eachSeries(function (seriesModel, idx) {\r
923                     var chartView = this._chartsMap[seriesModel.__viewId];\r
924                     chartView.__alive = true;\r
925                     chartView.render(seriesModel, ecModel, api, payload);\r
926 \r
927                     updateZ(seriesModel, chartView);\r
928                 }, this);\r
929 \r
930                 // Remove groups of unrendered charts\r
931                 each(this._chartsViews, function (chart) {\r
932                     if (!chart.__alive) {\r
933                         chart.remove(ecModel, api);\r
934                     }\r
935                 }, this);\r
936             }\r
937 \r
938             var MOUSE_EVENT_NAMES = [\r
939                 'click', 'dblclick', 'mouseover', 'mouseout', 'mousedown', 'mouseup', 'globalout'\r
940             ];\r
941             /**\r
942              * @private\r
943              */\r
944             echartsProto._initEvents = function () {\r
945                 var zr = this._zr;\r
946                 each(MOUSE_EVENT_NAMES, function (eveName) {\r
947                     zr.on(eveName, function (e) {\r
948                         var ecModel = this.getModel();\r
949                         var el = e.target;\r
950                         if (el && el.dataIndex != null) {\r
951                             var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex);\r
952                             var params = dataModel && dataModel.getDataParams(el.dataIndex) || {};\r
953                             params.event = e;\r
954                             params.type = eveName;\r
955                             this.trigger(eveName, params);\r
956                         }\r
957                     }, this);\r
958                 }, this);\r
959 \r
960                 each(eventActionMap, function (actionType, eventType) {\r
961                     this._messageCenter.on(eventType, function (event) {\r
962                         this.trigger(eventType, event);\r
963                     }, this);\r
964                 }, this);\r
965             };\r
966 \r
967             /**\r
968              * @return {boolean}\r
969              */\r
970             echartsProto.isDisposed = function () {\r
971                 return this._disposed;\r
972             };\r
973 \r
974             /**\r
975              * Clear\r
976              */\r
977             echartsProto.clear = function () {\r
978                 this.setOption({}, true);\r
979             };\r
980             /**\r
981              * Dispose instance\r
982              */\r
983             echartsProto.dispose = function () {\r
984                 this._disposed = true;\r
985                 var api = this._api;\r
986                 var ecModel = this._model;\r
987 \r
988                 each(this._componentsViews, function (component) {\r
989                     component.dispose(ecModel, api);\r
990                 });\r
991                 each(this._chartsViews, function (chart) {\r
992                     chart.dispose(ecModel, api);\r
993                 });\r
994 \r
995                 this._zr.dispose();\r
996 \r
997                 delete instances[this.id];\r
998             };\r
999 \r
1000             zrUtil.mixin(ECharts, Eventful);\r
1001 \r
1002             /**\r
1003              * @param {module:echarts/model/Series|module:echarts/model/Component} model\r
1004              * @param {module:echarts/view/Component|module:echarts/view/Chart} view\r
1005              * @return {string}\r
1006              */\r
1007             function updateZ(model, view) {\r
1008                 var z = model.get('z');\r
1009                 var zlevel = model.get('zlevel');\r
1010                 // Set z and zlevel\r
1011                 view.group.traverse(function (el) {\r
1012                     z != null && (el.z = z);\r
1013                     zlevel != null && (el.zlevel = zlevel);\r
1014                 });\r
1015             }\r
1016             /**\r
1017              * @type {Array.<Function>}\r
1018              * @inner\r
1019              */\r
1020             var actions = [];\r
1021 \r
1022             /**\r
1023              * Map eventType to actionType\r
1024              * @type {Object}\r
1025              */\r
1026             var eventActionMap = {};\r
1027 \r
1028             /**\r
1029              * @type {Array.<Function>}\r
1030              * @inner\r
1031              */\r
1032             var layoutFuncs = [];\r
1033 \r
1034             /**\r
1035              * Data processor functions of each stage\r
1036              * @type {Array.<Object.<string, Function>>}\r
1037              * @inner\r
1038              */\r
1039             var dataProcessorFuncs = {};\r
1040 \r
1041             /**\r
1042              * @type {Array.<Function>}\r
1043              * @inner\r
1044              */\r
1045             var optionPreprocessorFuncs = [];\r
1046 \r
1047             /**\r
1048              * Visual coding functions of each stage\r
1049              * @type {Array.<Object.<string, Function>>}\r
1050              * @inner\r
1051              */\r
1052             var visualCodingFuncs = {};\r
1053             /**\r
1054              * Theme storage\r
1055              * @type {Object.<key, Object>}\r
1056              */\r
1057             var themeStorage = {};\r
1058 \r
1059 \r
1060             var instances = {};\r
1061             var connectedGroups = {};\r
1062 \r
1063             var idBase = new Date() - 0;\r
1064             var groupIdBase = new Date() - 0;\r
1065             var DOM_ATTRIBUTE_KEY = '_echarts_instance_';\r
1066             /**\r
1067              * @alias module:echarts\r
1068              */\r
1069             var echarts = {\r
1070                 /**\r
1071                  * @type {number}\r
1072                  */\r
1073                 version: '3.1.5',\r
1074                 dependencies: {\r
1075                     zrender: '3.0.6'\r
1076                 }\r
1077             };\r
1078 \r
1079             function enableConnect(chart) {\r
1080 \r
1081                 var STATUS_PENDING = 0;\r
1082                 var STATUS_UPDATING = 1;\r
1083                 var STATUS_UPDATED = 2;\r
1084                 var STATUS_KEY = '__connectUpdateStatus';\r
1085                 function updateConnectedChartsStatus(charts, status) {\r
1086                     for (var i = 0; i < charts.length; i++) {\r
1087                         var otherChart = charts[i];\r
1088                         otherChart[STATUS_KEY] = status;\r
1089                     }\r
1090                 }\r
1091                 zrUtil.each(eventActionMap, function (actionType, eventType) {\r
1092                     chart._messageCenter.on(eventType, function (event) {\r
1093                         if (connectedGroups[chart.group] && chart[STATUS_KEY] !== STATUS_PENDING) {\r
1094                             var action = chart.makeActionFromEvent(event);\r
1095                             var otherCharts = [];\r
1096                             for (var id in instances) {\r
1097                                 var otherChart = instances[id];\r
1098                                 if (otherChart !== chart && otherChart.group === chart.group) {\r
1099                                     otherCharts.push(otherChart);\r
1100                                 }\r
1101                             }\r
1102                             updateConnectedChartsStatus(otherCharts, STATUS_PENDING);\r
1103                             each(otherCharts, function (otherChart) {\r
1104                                 if (otherChart[STATUS_KEY] !== STATUS_UPDATING) {\r
1105                                     otherChart.dispatchAction(action);\r
1106                                 }\r
1107                             });\r
1108                             updateConnectedChartsStatus(otherCharts, STATUS_UPDATED);\r
1109                         }\r
1110                     });\r
1111                 });\r
1112 \r
1113             }\r
1114             /**\r
1115              * @param {HTMLDomElement} dom\r
1116              * @param {Object} [theme]\r
1117              * @param {Object} opts\r
1118              */\r
1119             echarts.init = function (dom, theme, opts) {\r
1120                 // Check version\r
1121                 if ((zrender.version.replace('.', '') - 0) < (echarts.dependencies.zrender.replace('.', '') - 0)) {\r
1122                     throw new Error(\r
1123                         'ZRender ' + zrender.version\r
1124                         + ' is too old for ECharts ' + echarts.version\r
1125                         + '. Current version need ZRender '\r
1126                         + echarts.dependencies.zrender + '+'\r
1127                     );\r
1128                 }\r
1129                 if (!dom) {\r
1130                     throw new Error('Initialize failed: invalid dom.');\r
1131                 }\r
1132 \r
1133                 var chart = new ECharts(dom, theme, opts);\r
1134                 chart.id = 'ec_' + idBase++;\r
1135                 instances[chart.id] = chart;\r
1136 \r
1137                 dom.setAttribute &&\r
1138                     dom.setAttribute(DOM_ATTRIBUTE_KEY, chart.id);\r
1139 \r
1140                 enableConnect(chart);\r
1141 \r
1142                 return chart;\r
1143             };\r
1144 \r
1145             /**\r
1146              * @return {string|Array.<module:echarts~ECharts>} groupId\r
1147              */\r
1148             echarts.connect = function (groupId) {\r
1149                 // Is array of charts\r
1150                 if (zrUtil.isArray(groupId)) {\r
1151                     var charts = groupId;\r
1152                     groupId = null;\r
1153                     // If any chart has group\r
1154                     zrUtil.each(charts, function (chart) {\r
1155                         if (chart.group != null) {\r
1156                             groupId = chart.group;\r
1157                         }\r
1158                     });\r
1159                     groupId = groupId || ('g_' + groupIdBase++);\r
1160                     zrUtil.each(charts, function (chart) {\r
1161                         chart.group = groupId;\r
1162                     });\r
1163                 }\r
1164                 connectedGroups[groupId] = true;\r
1165                 return groupId;\r
1166             };\r
1167 \r
1168             /**\r
1169              * @return {string} groupId\r
1170              */\r
1171             echarts.disConnect = function (groupId) {\r
1172                 connectedGroups[groupId] = false;\r
1173             };\r
1174 \r
1175             /**\r
1176              * Dispose a chart instance\r
1177              * @param  {module:echarts~ECharts|HTMLDomElement|string} chart\r
1178              */\r
1179             echarts.dispose = function (chart) {\r
1180                 if (zrUtil.isDom(chart)) {\r
1181                     chart = echarts.getInstanceByDom(chart);\r
1182                 }\r
1183                 else if (typeof chart === 'string') {\r
1184                     chart = instances[chart];\r
1185                 }\r
1186                 if ((chart instanceof ECharts) && !chart.isDisposed()) {\r
1187                     chart.dispose();\r
1188                 }\r
1189             };\r
1190 \r
1191             /**\r
1192              * @param  {HTMLDomElement} dom\r
1193              * @return {echarts~ECharts}\r
1194              */\r
1195             echarts.getInstanceByDom = function (dom) {\r
1196                 var key = dom.getAttribute(DOM_ATTRIBUTE_KEY);\r
1197                 return instances[key];\r
1198             };\r
1199             /**\r
1200              * @param {string} key\r
1201              * @return {echarts~ECharts}\r
1202              */\r
1203             echarts.getInstanceById = function (key) {\r
1204                 return instances[key];\r
1205             };\r
1206 \r
1207             /**\r
1208              * Register theme\r
1209              */\r
1210             echarts.registerTheme = function (name, theme) {\r
1211                 themeStorage[name] = theme;\r
1212             };\r
1213 \r
1214             /**\r
1215              * Register option preprocessor\r
1216              * @param {Function} preprocessorFunc\r
1217              */\r
1218             echarts.registerPreprocessor = function (preprocessorFunc) {\r
1219                 optionPreprocessorFuncs.push(preprocessorFunc);\r
1220             };\r
1221 \r
1222             /**\r
1223              * @param {string} stage\r
1224              * @param {Function} processorFunc\r
1225              */\r
1226             echarts.registerProcessor = function (stage, processorFunc) {\r
1227                 if (zrUtil.indexOf(PROCESSOR_STAGES, stage) < 0) {\r
1228                     throw new Error('stage should be one of ' + PROCESSOR_STAGES);\r
1229                 }\r
1230                 var funcs = dataProcessorFuncs[stage] || (dataProcessorFuncs[stage] = []);\r
1231                 funcs.push(processorFunc);\r
1232             };\r
1233 \r
1234             /**\r
1235              * Usage:\r
1236              * registerAction('someAction', 'someEvent', function () { ... });\r
1237              * registerAction('someAction', function () { ... });\r
1238              * registerAction(\r
1239              *     {type: 'someAction', event: 'someEvent', update: 'updateView'},\r
1240              *     function () { ... }\r
1241              * );\r
1242              *\r
1243              * @param {(string|Object)} actionInfo\r
1244              * @param {string} actionInfo.type\r
1245              * @param {string} [actionInfo.event]\r
1246              * @param {string} [actionInfo.update]\r
1247              * @param {string} [eventName]\r
1248              * @param {Function} action\r
1249              */\r
1250             echarts.registerAction = function (actionInfo, eventName, action) {\r
1251                 if (typeof eventName === 'function') {\r
1252                     action = eventName;\r
1253                     eventName = '';\r
1254                 }\r
1255                 var actionType = zrUtil.isObject(actionInfo)\r
1256                     ? actionInfo.type\r
1257                     : ([actionInfo, actionInfo = {\r
1258                         event: eventName\r
1259                     }][0]);\r
1260 \r
1261                 // Event name is all lowercase\r
1262                 actionInfo.event = (actionInfo.event || actionType).toLowerCase();\r
1263                 eventName = actionInfo.event;\r
1264 \r
1265                 if (!actions[actionType]) {\r
1266                     actions[actionType] = {action: action, actionInfo: actionInfo};\r
1267                 }\r
1268                 eventActionMap[eventName] = actionType;\r
1269             };\r
1270 \r
1271             /**\r
1272              * @param {string} type\r
1273              * @param {*} CoordinateSystem\r
1274              */\r
1275             echarts.registerCoordinateSystem = function (type, CoordinateSystem) {\r
1276                 CoordinateSystemManager.register(type, CoordinateSystem);\r
1277             };\r
1278 \r
1279             /**\r
1280              * @param {*} layout\r
1281              */\r
1282             echarts.registerLayout = function (layout) {\r
1283                 // PENDING All functions ?\r
1284                 if (zrUtil.indexOf(layoutFuncs, layout) < 0) {\r
1285                     layoutFuncs.push(layout);\r
1286                 }\r
1287             };\r
1288 \r
1289             /**\r
1290              * @param {string} stage\r
1291              * @param {Function} visualCodingFunc\r
1292              */\r
1293             echarts.registerVisualCoding = function (stage, visualCodingFunc) {\r
1294                 if (zrUtil.indexOf(VISUAL_CODING_STAGES, stage) < 0) {\r
1295                     throw new Error('stage should be one of ' + VISUAL_CODING_STAGES);\r
1296                 }\r
1297                 var funcs = visualCodingFuncs[stage] || (visualCodingFuncs[stage] = []);\r
1298                 funcs.push(visualCodingFunc);\r
1299             };\r
1300 \r
1301             /**\r
1302              * @param {Object} opts\r
1303              */\r
1304             echarts.extendChartView = function (opts) {\r
1305                 return ChartView.extend(opts);\r
1306             };\r
1307 \r
1308             /**\r
1309              * @param {Object} opts\r
1310              */\r
1311             echarts.extendComponentModel = function (opts) {\r
1312                 return ComponentModel.extend(opts);\r
1313             };\r
1314 \r
1315             /**\r
1316              * @param {Object} opts\r
1317              */\r
1318             echarts.extendSeriesModel = function (opts) {\r
1319                 return SeriesModel.extend(opts);\r
1320             };\r
1321 \r
1322             /**\r
1323              * @param {Object} opts\r
1324              */\r
1325             echarts.extendComponentView = function (opts) {\r
1326                 return ComponentView.extend(opts);\r
1327             };\r
1328 \r
1329             /**\r
1330              * ZRender need a canvas context to do measureText.\r
1331              * But in node environment canvas may be created by node-canvas.\r
1332              * So we need to specify how to create a canvas instead of using document.createElement('canvas')\r
1333              *\r
1334              * Be careful of using it in the browser.\r
1335              *\r
1336              * @param {Function} creator\r
1337              * @example\r
1338              *     var Canvas = require('canvas');\r
1339              *     var echarts = require('echarts');\r
1340              *     echarts.setCanvasCreator(function () {\r
1341              *         // Small size is enough.\r
1342              *         return new Canvas(32, 32);\r
1343              *     });\r
1344              */\r
1345             echarts.setCanvasCreator = function (creator) {\r
1346                 zrUtil.createCanvas = creator;\r
1347             };\r
1348 \r
1349             echarts.registerVisualCoding('echarts', zrUtil.curry(\r
1350                 __webpack_require__(88), '', 'itemStyle'\r
1351             ));\r
1352             echarts.registerPreprocessor(__webpack_require__(89));\r
1353 \r
1354             // Default action\r
1355             echarts.registerAction({\r
1356                 type: 'highlight',\r
1357                 event: 'highlight',\r
1358                 update: 'highlight'\r
1359             }, zrUtil.noop);\r
1360             echarts.registerAction({\r
1361                 type: 'downplay',\r
1362                 event: 'downplay',\r
1363                 update: 'downplay'\r
1364             }, zrUtil.noop);\r
1365 \r
1366 \r
1367             // --------\r
1368             // Exports\r
1369             // --------\r
1370 \r
1371             echarts.graphic = __webpack_require__(42);\r
1372             echarts.number = __webpack_require__(7);\r
1373             echarts.format = __webpack_require__(6);\r
1374             echarts.matrix = __webpack_require__(17);\r
1375             echarts.vector = __webpack_require__(16);\r
1376 \r
1377             echarts.util = {};\r
1378             each([\r
1379                     'map', 'each', 'filter', 'indexOf', 'inherits',\r
1380                     'reduce', 'filter', 'bind', 'curry', 'isArray',\r
1381                     'isString', 'isObject', 'isFunction', 'extend'\r
1382                 ],\r
1383                 function (name) {\r
1384                     echarts.util[name] = zrUtil[name];\r
1385                 }\r
1386             );\r
1387 \r
1388             module.exports = echarts;\r
1389 \r
1390 \r
1391 /***/ },\r
1392 /* 2 */\r
1393 /***/ function(module, exports, __webpack_require__) {\r
1394 \r
1395         /**\r
1396          * ECharts global model\r
1397          *\r
1398          * @module {echarts/model/Global}\r
1399          *\r
1400          */\r
1401 \r
1402 \r
1403 \r
1404             var zrUtil = __webpack_require__(3);\r
1405             var modelUtil = __webpack_require__(5);\r
1406             var Model = __webpack_require__(8);\r
1407             var each = zrUtil.each;\r
1408             var filter = zrUtil.filter;\r
1409             var map = zrUtil.map;\r
1410             var isArray = zrUtil.isArray;\r
1411             var indexOf = zrUtil.indexOf;\r
1412             var isObject = zrUtil.isObject;\r
1413 \r
1414             var ComponentModel = __webpack_require__(19);\r
1415 \r
1416             var globalDefault = __webpack_require__(23);\r
1417 \r
1418             var OPTION_INNER_KEY = '\0_ec_inner';\r
1419 \r
1420             /**\r
1421              * @alias module:echarts/model/Global\r
1422              *\r
1423              * @param {Object} option\r
1424              * @param {module:echarts/model/Model} parentModel\r
1425              * @param {Object} theme\r
1426              */\r
1427             var GlobalModel = Model.extend({\r
1428 \r
1429                 constructor: GlobalModel,\r
1430 \r
1431                 init: function (option, parentModel, theme, optionManager) {\r
1432                     theme = theme || {};\r
1433 \r
1434                     this.option = null; // Mark as not initialized.\r
1435 \r
1436                     /**\r
1437                      * @type {module:echarts/model/Model}\r
1438                      * @private\r
1439                      */\r
1440                     this._theme = new Model(theme);\r
1441 \r
1442                     /**\r
1443                      * @type {module:echarts/model/OptionManager}\r
1444                      */\r
1445                     this._optionManager = optionManager;\r
1446                 },\r
1447 \r
1448                 setOption: function (option, optionPreprocessorFuncs) {\r
1449                     zrUtil.assert(\r
1450                         !(OPTION_INNER_KEY in option),\r
1451                         'please use chart.getOption()'\r
1452                     );\r
1453 \r
1454                     this._optionManager.setOption(option, optionPreprocessorFuncs);\r
1455 \r
1456                     this.resetOption();\r
1457                 },\r
1458 \r
1459                 /**\r
1460                  * @param {string} type null/undefined: reset all.\r
1461                  *                      'recreate': force recreate all.\r
1462                  *                      'timeline': only reset timeline option\r
1463                  *                      'media': only reset media query option\r
1464                  * @return {boolean} Whether option changed.\r
1465                  */\r
1466                 resetOption: function (type) {\r
1467                     var optionChanged = false;\r
1468                     var optionManager = this._optionManager;\r
1469 \r
1470                     if (!type || type === 'recreate') {\r
1471                         var baseOption = optionManager.mountOption(type === 'recreate');\r
1472 \r
1473                         if (!this.option || type === 'recreate') {\r
1474                             initBase.call(this, baseOption);\r
1475                         }\r
1476                         else {\r
1477                             this.restoreData();\r
1478                             this.mergeOption(baseOption);\r
1479                         }\r
1480                         optionChanged = true;\r
1481                     }\r
1482 \r
1483                     if (type === 'timeline' || type === 'media') {\r
1484                         this.restoreData();\r
1485                     }\r
1486 \r
1487                     if (!type || type === 'recreate' || type === 'timeline') {\r
1488                         var timelineOption = optionManager.getTimelineOption(this);\r
1489                         timelineOption && (this.mergeOption(timelineOption), optionChanged = true);\r
1490                     }\r
1491 \r
1492                     if (!type || type === 'recreate' || type === 'media') {\r
1493                         var mediaOptions = optionManager.getMediaOption(this, this._api);\r
1494                         if (mediaOptions.length) {\r
1495                             each(mediaOptions, function (mediaOption) {\r
1496                                 this.mergeOption(mediaOption, optionChanged = true);\r
1497                             }, this);\r
1498                         }\r
1499                     }\r
1500 \r
1501                     return optionChanged;\r
1502                 },\r
1503 \r
1504                 /**\r
1505                  * @protected\r
1506                  */\r
1507                 mergeOption: function (newOption) {\r
1508                     var option = this.option;\r
1509                     var componentsMap = this._componentsMap;\r
1510                     var newCptTypes = [];\r
1511 \r
1512                     // 如果不存在对应的 component model 则直接 merge\r
1513                     each(newOption, function (componentOption, mainType) {\r
1514                         if (componentOption == null) {\r
1515                             return;\r
1516                         }\r
1517 \r
1518                         if (!ComponentModel.hasClass(mainType)) {\r
1519                             option[mainType] = option[mainType] == null\r
1520                                 ? zrUtil.clone(componentOption)\r
1521                                 : zrUtil.merge(option[mainType], componentOption, true);\r
1522                         }\r
1523                         else {\r
1524                             newCptTypes.push(mainType);\r
1525                         }\r
1526                     });\r
1527 \r
1528                     // FIXME OPTION 同步是否要改回原来的\r
1529                     ComponentModel.topologicalTravel(\r
1530                         newCptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this\r
1531                     );\r
1532 \r
1533                     function visitComponent(mainType, dependencies) {\r
1534                         var newCptOptionList = modelUtil.normalizeToArray(newOption[mainType]);\r
1535 \r
1536                         var mapResult = modelUtil.mappingToExists(\r
1537                             componentsMap[mainType], newCptOptionList\r
1538                         );\r
1539 \r
1540                         makeKeyInfo(mainType, mapResult);\r
1541 \r
1542                         var dependentModels = getComponentsByTypes(\r
1543                             componentsMap, dependencies\r
1544                         );\r
1545 \r
1546                         option[mainType] = [];\r
1547                         componentsMap[mainType] = [];\r
1548 \r
1549                         each(mapResult, function (resultItem, index) {\r
1550                             var componentModel = resultItem.exist;\r
1551                             var newCptOption = resultItem.option;\r
1552 \r
1553                             zrUtil.assert(\r
1554                                 isObject(newCptOption) || componentModel,\r
1555                                 'Empty component definition'\r
1556                             );\r
1557 \r
1558                             // Consider where is no new option and should be merged using {},\r
1559                             // see removeEdgeAndAdd in topologicalTravel and\r
1560                             // ComponentModel.getAllClassMainTypes.\r
1561                             if (!newCptOption) {\r
1562                                 componentModel.mergeOption({}, this);\r
1563                                 componentModel.optionUpdated(this);\r
1564                             }\r
1565                             else {\r
1566                                 var ComponentModelClass = ComponentModel.getClass(\r
1567                                     mainType, resultItem.keyInfo.subType, true\r
1568                                 );\r
1569 \r
1570                                 if (componentModel && componentModel instanceof ComponentModelClass) {\r
1571                                     componentModel.mergeOption(newCptOption, this);\r
1572                                     componentModel.optionUpdated(this);\r
1573                                 }\r
1574                                 else {\r
1575                                     // PENDING Global as parent ?\r
1576                                     componentModel = new ComponentModelClass(\r
1577                                         newCptOption, this, this,\r
1578                                         zrUtil.extend(\r
1579                                             {\r
1580                                                 dependentModels: dependentModels,\r
1581                                                 componentIndex: index\r
1582                                             },\r
1583                                             resultItem.keyInfo\r
1584                                         )\r
1585                                     );\r
1586                                     // Call optionUpdated after init\r
1587                                     componentModel.optionUpdated(this);\r
1588                                 }\r
1589                             }\r
1590 \r
1591                             componentsMap[mainType][index] = componentModel;\r
1592                             option[mainType][index] = componentModel.option;\r
1593                         }, this);\r
1594 \r
1595                         // Backup series for filtering.\r
1596                         if (mainType === 'series') {\r
1597                             this._seriesIndices = createSeriesIndices(componentsMap.series);\r
1598                         }\r
1599                     }\r
1600                 },\r
1601 \r
1602                 /**\r
1603                  * Get option for output (cloned option and inner info removed)\r
1604                  * @public\r
1605                  * @return {Object}\r
1606                  */\r
1607                 getOption: function () {\r
1608                     var option = zrUtil.clone(this.option);\r
1609 \r
1610                     each(option, function (opts, mainType) {\r
1611                         if (ComponentModel.hasClass(mainType)) {\r
1612                             var opts = modelUtil.normalizeToArray(opts);\r
1613                             for (var i = opts.length - 1; i >= 0; i--) {\r
1614                                 // Remove options with inner id.\r
1615                                 if (modelUtil.isIdInner(opts[i])) {\r
1616                                     opts.splice(i, 1);\r
1617                                 }\r
1618                             }\r
1619                             option[mainType] = opts;\r
1620                         }\r
1621                     });\r
1622 \r
1623                     delete option[OPTION_INNER_KEY];\r
1624 \r
1625                     return option;\r
1626                 },\r
1627 \r
1628                 /**\r
1629                  * @return {module:echarts/model/Model}\r
1630                  */\r
1631                 getTheme: function () {\r
1632                     return this._theme;\r
1633                 },\r
1634 \r
1635                 /**\r
1636                  * @param {string} mainType\r
1637                  * @param {number} [idx=0]\r
1638                  * @return {module:echarts/model/Component}\r
1639                  */\r
1640                 getComponent: function (mainType, idx) {\r
1641                     var list = this._componentsMap[mainType];\r
1642                     if (list) {\r
1643                         return list[idx || 0];\r
1644                     }\r
1645                 },\r
1646 \r
1647                 /**\r
1648                  * @param {Object} condition\r
1649                  * @param {string} condition.mainType\r
1650                  * @param {string} [condition.subType] If ignore, only query by mainType\r
1651                  * @param {number} [condition.index] Either input index or id or name.\r
1652                  * @param {string} [condition.id] Either input index or id or name.\r
1653                  * @param {string} [condition.name] Either input index or id or name.\r
1654                  * @return {Array.<module:echarts/model/Component>}\r
1655                  */\r
1656                 queryComponents: function (condition) {\r
1657                     var mainType = condition.mainType;\r
1658                     if (!mainType) {\r
1659                         return [];\r
1660                     }\r
1661 \r
1662                     var index = condition.index;\r
1663                     var id = condition.id;\r
1664                     var name = condition.name;\r
1665 \r
1666                     var cpts = this._componentsMap[mainType];\r
1667 \r
1668                     if (!cpts || !cpts.length) {\r
1669                         return [];\r
1670                     }\r
1671 \r
1672                     var result;\r
1673 \r
1674                     if (index != null) {\r
1675                         if (!isArray(index)) {\r
1676                             index = [index];\r
1677                         }\r
1678                         result = filter(map(index, function (idx) {\r
1679                             return cpts[idx];\r
1680                         }), function (val) {\r
1681                             return !!val;\r
1682                         });\r
1683                     }\r
1684                     else if (id != null) {\r
1685                         var isIdArray = isArray(id);\r
1686                         result = filter(cpts, function (cpt) {\r
1687                             return (isIdArray && indexOf(id, cpt.id) >= 0)\r
1688                                 || (!isIdArray && cpt.id === id);\r
1689                         });\r
1690                     }\r
1691                     else if (name != null) {\r
1692                         var isNameArray = isArray(name);\r
1693                         result = filter(cpts, function (cpt) {\r
1694                             return (isNameArray && indexOf(name, cpt.name) >= 0)\r
1695                                 || (!isNameArray && cpt.name === name);\r
1696                         });\r
1697                     }\r
1698 \r
1699                     return filterBySubType(result, condition);\r
1700                 },\r
1701 \r
1702                 /**\r
1703                  * The interface is different from queryComponents,\r
1704                  * which is convenient for inner usage.\r
1705                  *\r
1706                  * @usage\r
1707                  * findComponents(\r
1708                  *     {mainType: 'dataZoom', query: {dataZoomId: 'abc'}},\r
1709                  *     function (model, index) {...}\r
1710                  * );\r
1711                  *\r
1712                  * findComponents(\r
1713                  *     {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}},\r
1714                  *     function (model, index) {...}\r
1715                  * );\r
1716                  *\r
1717                  * var result = findComponents(\r
1718                  *     {mainType: 'series'},\r
1719                  *     function (model, index) {...}\r
1720                  * );\r
1721                  * // result like [component0, componnet1, ...]\r
1722                  *\r
1723                  * @param {Object} condition\r
1724                  * @param {string} condition.mainType Mandatory.\r
1725                  * @param {string} [condition.subType] Optional.\r
1726                  * @param {Object} [condition.query] like {xxxIndex, xxxId, xxxName},\r
1727                  *        where xxx is mainType.\r
1728                  *        If query attribute is null/undefined or has no index/id/name,\r
1729                  *        do not filtering by query conditions, which is convenient for\r
1730                  *        no-payload situations or when target of action is global.\r
1731                  * @param {Function} [condition.filter] parameter: component, return boolean.\r
1732                  * @return {Array.<module:echarts/model/Component>}\r
1733                  */\r
1734                 findComponents: function (condition) {\r
1735                     var query = condition.query;\r
1736                     var mainType = condition.mainType;\r
1737 \r
1738                     var queryCond = getQueryCond(query);\r
1739                     var result = queryCond\r
1740                         ? this.queryComponents(queryCond)\r
1741                         : this._componentsMap[mainType];\r
1742 \r
1743                     return doFilter(filterBySubType(result, condition));\r
1744 \r
1745                     function getQueryCond(q) {\r
1746                         var indexAttr = mainType + 'Index';\r
1747                         var idAttr = mainType + 'Id';\r
1748                         var nameAttr = mainType + 'Name';\r
1749                         return q && (\r
1750                                 q.hasOwnProperty(indexAttr)\r
1751                                 || q.hasOwnProperty(idAttr)\r
1752                                 || q.hasOwnProperty(nameAttr)\r
1753                             )\r
1754                             ? {\r
1755                                 mainType: mainType,\r
1756                                 // subType will be filtered finally.\r
1757                                 index: q[indexAttr],\r
1758                                 id: q[idAttr],\r
1759                                 name: q[nameAttr]\r
1760                             }\r
1761                             : null;\r
1762                     }\r
1763 \r
1764                     function doFilter(res) {\r
1765                         return condition.filter\r
1766                              ? filter(res, condition.filter)\r
1767                              : res;\r
1768                     }\r
1769                 },\r
1770 \r
1771                 /**\r
1772                  * @usage\r
1773                  * eachComponent('legend', function (legendModel, index) {\r
1774                  *     ...\r
1775                  * });\r
1776                  * eachComponent(function (componentType, model, index) {\r
1777                  *     // componentType does not include subType\r
1778                  *     // (componentType is 'xxx' but not 'xxx.aa')\r
1779                  * });\r
1780                  * eachComponent(\r
1781                  *     {mainType: 'dataZoom', query: {dataZoomId: 'abc'}},\r
1782                  *     function (model, index) {...}\r
1783                  * );\r
1784                  * eachComponent(\r
1785                  *     {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}},\r
1786                  *     function (model, index) {...}\r
1787                  * );\r
1788                  *\r
1789                  * @param {string|Object=} mainType When mainType is object, the definition\r
1790                  *                                  is the same as the method 'findComponents'.\r
1791                  * @param {Function} cb\r
1792                  * @param {*} context\r
1793                  */\r
1794                 eachComponent: function (mainType, cb, context) {\r
1795                     var componentsMap = this._componentsMap;\r
1796 \r
1797                     if (typeof mainType === 'function') {\r
1798                         context = cb;\r
1799                         cb = mainType;\r
1800                         each(componentsMap, function (components, componentType) {\r
1801                             each(components, function (component, index) {\r
1802                                 cb.call(context, componentType, component, index);\r
1803                             });\r
1804                         });\r
1805                     }\r
1806                     else if (zrUtil.isString(mainType)) {\r
1807                         each(componentsMap[mainType], cb, context);\r
1808                     }\r
1809                     else if (isObject(mainType)) {\r
1810                         var queryResult = this.findComponents(mainType);\r
1811                         each(queryResult, cb, context);\r
1812                     }\r
1813                 },\r
1814 \r
1815                 /**\r
1816                  * @param {string} name\r
1817                  * @return {Array.<module:echarts/model/Series>}\r
1818                  */\r
1819                 getSeriesByName: function (name) {\r
1820                     var series = this._componentsMap.series;\r
1821                     return filter(series, function (oneSeries) {\r
1822                         return oneSeries.name === name;\r
1823                     });\r
1824                 },\r
1825 \r
1826                 /**\r
1827                  * @param {number} seriesIndex\r
1828                  * @return {module:echarts/model/Series}\r
1829                  */\r
1830                 getSeriesByIndex: function (seriesIndex) {\r
1831                     return this._componentsMap.series[seriesIndex];\r
1832                 },\r
1833 \r
1834                 /**\r
1835                  * @param {string} subType\r
1836                  * @return {Array.<module:echarts/model/Series>}\r
1837                  */\r
1838                 getSeriesByType: function (subType) {\r
1839                     var series = this._componentsMap.series;\r
1840                     return filter(series, function (oneSeries) {\r
1841                         return oneSeries.subType === subType;\r
1842                     });\r
1843                 },\r
1844 \r
1845                 /**\r
1846                  * @return {Array.<module:echarts/model/Series>}\r
1847                  */\r
1848                 getSeries: function () {\r
1849                     return this._componentsMap.series.slice();\r
1850                 },\r
1851 \r
1852                 /**\r
1853                  * After filtering, series may be different\r
1854                  * frome raw series.\r
1855                  *\r
1856                  * @param {Function} cb\r
1857                  * @param {*} context\r
1858                  */\r
1859                 eachSeries: function (cb, context) {\r
1860                     assertSeriesInitialized(this);\r
1861                     each(this._seriesIndices, function (rawSeriesIndex) {\r
1862                         var series = this._componentsMap.series[rawSeriesIndex];\r
1863                         cb.call(context, series, rawSeriesIndex);\r
1864                     }, this);\r
1865                 },\r
1866 \r
1867                 /**\r
1868                  * Iterate raw series before filtered.\r
1869                  *\r
1870                  * @param {Function} cb\r
1871                  * @param {*} context\r
1872                  */\r
1873                 eachRawSeries: function (cb, context) {\r
1874                     each(this._componentsMap.series, cb, context);\r
1875                 },\r
1876 \r
1877                 /**\r
1878                  * After filtering, series may be different.\r
1879                  * frome raw series.\r
1880                  *\r
1881                  * @parma {string} subType\r
1882                  * @param {Function} cb\r
1883                  * @param {*} context\r
1884                  */\r
1885                 eachSeriesByType: function (subType, cb, context) {\r
1886                     assertSeriesInitialized(this);\r
1887                     each(this._seriesIndices, function (rawSeriesIndex) {\r
1888                         var series = this._componentsMap.series[rawSeriesIndex];\r
1889                         if (series.subType === subType) {\r
1890                             cb.call(context, series, rawSeriesIndex);\r
1891                         }\r
1892                     }, this);\r
1893                 },\r
1894 \r
1895                 /**\r
1896                  * Iterate raw series before filtered of given type.\r
1897                  *\r
1898                  * @parma {string} subType\r
1899                  * @param {Function} cb\r
1900                  * @param {*} context\r
1901                  */\r
1902                 eachRawSeriesByType: function (subType, cb, context) {\r
1903                     return each(this.getSeriesByType(subType), cb, context);\r
1904                 },\r
1905 \r
1906                 /**\r
1907                  * @param {module:echarts/model/Series} seriesModel\r
1908                  */\r
1909                 isSeriesFiltered: function (seriesModel) {\r
1910                     assertSeriesInitialized(this);\r
1911                     return zrUtil.indexOf(this._seriesIndices, seriesModel.componentIndex) < 0;\r
1912                 },\r
1913 \r
1914                 /**\r
1915                  * @param {Function} cb\r
1916                  * @param {*} context\r
1917                  */\r
1918                 filterSeries: function (cb, context) {\r
1919                     assertSeriesInitialized(this);\r
1920                     var filteredSeries = filter(\r
1921                         this._componentsMap.series, cb, context\r
1922                     );\r
1923                     this._seriesIndices = createSeriesIndices(filteredSeries);\r
1924                 },\r
1925 \r
1926                 restoreData: function () {\r
1927                     var componentsMap = this._componentsMap;\r
1928 \r
1929                     this._seriesIndices = createSeriesIndices(componentsMap.series);\r
1930 \r
1931                     var componentTypes = [];\r
1932                     each(componentsMap, function (components, componentType) {\r
1933                         componentTypes.push(componentType);\r
1934                     });\r
1935 \r
1936                     ComponentModel.topologicalTravel(\r
1937                         componentTypes,\r
1938                         ComponentModel.getAllClassMainTypes(),\r
1939                         function (componentType, dependencies) {\r
1940                             each(componentsMap[componentType], function (component) {\r
1941                                 component.restoreData();\r
1942                             });\r
1943                         }\r
1944                     );\r
1945                 }\r
1946 \r
1947             });\r
1948 \r
1949             /**\r
1950              * @inner\r
1951              */\r
1952             function mergeTheme(option, theme) {\r
1953                 for (var name in theme) {\r
1954                     // 如果有 component model 则把具体的 merge 逻辑交给该 model 处理\r
1955                     if (!ComponentModel.hasClass(name)) {\r
1956                         if (typeof theme[name] === 'object') {\r
1957                             option[name] = !option[name]\r
1958                                 ? zrUtil.clone(theme[name])\r
1959                                 : zrUtil.merge(option[name], theme[name], false);\r
1960                         }\r
1961                         else {\r
1962                             if (option[name] == null) {\r
1963                                 option[name] = theme[name];\r
1964                             }\r
1965                         }\r
1966                     }\r
1967                 }\r
1968             }\r
1969 \r
1970             function initBase(baseOption) {\r
1971                 baseOption = baseOption;\r
1972 \r
1973                 // Using OPTION_INNER_KEY to mark that this option can not be used outside,\r
1974                 // i.e. `chart.setOption(chart.getModel().option);` is forbiden.\r
1975                 this.option = {};\r
1976                 this.option[OPTION_INNER_KEY] = 1;\r
1977 \r
1978                 /**\r
1979                  * @type {Object.<string, Array.<module:echarts/model/Model>>}\r
1980                  * @private\r
1981                  */\r
1982                 this._componentsMap = {};\r
1983 \r
1984                 /**\r
1985                  * Mapping between filtered series list and raw series list.\r
1986                  * key: filtered series indices, value: raw series indices.\r
1987                  * @type {Array.<nubmer>}\r
1988                  * @private\r
1989                  */\r
1990                 this._seriesIndices = null;\r
1991 \r
1992                 mergeTheme(baseOption, this._theme.option);\r
1993 \r
1994                 // TODO Needs clone when merging to the unexisted property\r
1995                 zrUtil.merge(baseOption, globalDefault, false);\r
1996 \r
1997                 this.mergeOption(baseOption);\r
1998             }\r
1999 \r
2000             /**\r
2001              * @inner\r
2002              * @param {Array.<string>|string} types model types\r
2003              * @return {Object} key: {string} type, value: {Array.<Object>} models\r
2004              */\r
2005             function getComponentsByTypes(componentsMap, types) {\r
2006                 if (!zrUtil.isArray(types)) {\r
2007                     types = types ? [types] : [];\r
2008                 }\r
2009 \r
2010                 var ret = {};\r
2011                 each(types, function (type) {\r
2012                     ret[type] = (componentsMap[type] || []).slice();\r
2013                 });\r
2014 \r
2015                 return ret;\r
2016             }\r
2017 \r
2018             /**\r
2019              * @inner\r
2020              */\r
2021             function makeKeyInfo(mainType, mapResult) {\r
2022                 // We use this id to hash component models and view instances\r
2023                 // in echarts. id can be specified by user, or auto generated.\r
2024 \r
2025                 // The id generation rule ensures new view instance are able\r
2026                 // to mapped to old instance when setOption are called in\r
2027                 // no-merge mode. So we generate model id by name and plus\r
2028                 // type in view id.\r
2029 \r
2030                 // name can be duplicated among components, which is convenient\r
2031                 // to specify multi components (like series) by one name.\r
2032 \r
2033                 // Ensure that each id is distinct.\r
2034                 var idMap = {};\r
2035 \r
2036                 each(mapResult, function (item, index) {\r
2037                     var existCpt = item.exist;\r
2038                     existCpt && (idMap[existCpt.id] = item);\r
2039                 });\r
2040 \r
2041                 each(mapResult, function (item, index) {\r
2042                     var opt = item.option;\r
2043 \r
2044                     zrUtil.assert(\r
2045                         !opt || opt.id == null || !idMap[opt.id] || idMap[opt.id] === item,\r
2046                         'id duplicates: ' + (opt && opt.id)\r
2047                     );\r
2048 \r
2049                     opt && opt.id != null && (idMap[opt.id] = item);\r
2050 \r
2051                     // Complete subType\r
2052                     if (isObject(opt)) {\r
2053                         var subType = determineSubType(mainType, opt, item.exist);\r
2054                         item.keyInfo = {mainType: mainType, subType: subType};\r
2055                     }\r
2056                 });\r
2057 \r
2058                 // Make name and id.\r
2059                 each(mapResult, function (item, index) {\r
2060                     var existCpt = item.exist;\r
2061                     var opt = item.option;\r
2062                     var keyInfo = item.keyInfo;\r
2063 \r
2064                     if (!isObject(opt)) {\r
2065                         return;\r
2066                     }\r
2067 \r
2068                     // name can be overwitten. Consider case: axis.name = '20km'.\r
2069                     // But id generated by name will not be changed, which affect\r
2070                     // only in that case: setOption with 'not merge mode' and view\r
2071                     // instance will be recreated, which can be accepted.\r
2072                     keyInfo.name = opt.name != null\r
2073                         ? opt.name + ''\r
2074                         : existCpt\r
2075                         ? existCpt.name\r
2076                         : '\0-';\r
2077 \r
2078                     if (existCpt) {\r
2079                         keyInfo.id = existCpt.id;\r
2080                     }\r
2081                     else if (opt.id != null) {\r
2082                         keyInfo.id = opt.id + '';\r
2083                     }\r
2084                     else {\r
2085                         // Consider this situatoin:\r
2086                         //  optionA: [{name: 'a'}, {name: 'a'}, {..}]\r
2087                         //  optionB [{..}, {name: 'a'}, {name: 'a'}]\r
2088                         // Series with the same name between optionA and optionB\r
2089                         // should be mapped.\r
2090                         var idNum = 0;\r
2091                         do {\r
2092                             keyInfo.id = '\0' + keyInfo.name + '\0' + idNum++;\r
2093                         }\r
2094                         while (idMap[keyInfo.id]);\r
2095                     }\r
2096 \r
2097                     idMap[keyInfo.id] = item;\r
2098                 });\r
2099             }\r
2100 \r
2101             /**\r
2102              * @inner\r
2103              */\r
2104             function determineSubType(mainType, newCptOption, existComponent) {\r
2105                 var subType = newCptOption.type\r
2106                     ? newCptOption.type\r
2107                     : existComponent\r
2108                     ? existComponent.subType\r
2109                     // Use determineSubType only when there is no existComponent.\r
2110                     : ComponentModel.determineSubType(mainType, newCptOption);\r
2111 \r
2112                 // tooltip, markline, markpoint may always has no subType\r
2113                 return subType;\r
2114             }\r
2115 \r
2116             /**\r
2117              * @inner\r
2118              */\r
2119             function createSeriesIndices(seriesModels) {\r
2120                 return map(seriesModels, function (series) {\r
2121                     return series.componentIndex;\r
2122                 }) || [];\r
2123             }\r
2124 \r
2125             /**\r
2126              * @inner\r
2127              */\r
2128             function filterBySubType(components, condition) {\r
2129                 // Using hasOwnProperty for restrict. Consider\r
2130                 // subType is undefined in user payload.\r
2131                 return condition.hasOwnProperty('subType')\r
2132                     ? filter(components, function (cpt) {\r
2133                         return cpt.subType === condition.subType;\r
2134                     })\r
2135                     : components;\r
2136             }\r
2137 \r
2138             /**\r
2139              * @inner\r
2140              */\r
2141             function assertSeriesInitialized(ecModel) {\r
2142                 // Components that use _seriesIndices should depends on series component,\r
2143                 // which make sure that their initialization is after series.\r
2144                 if (!ecModel._seriesIndices) {\r
2145                     throw new Error('Series has not been initialized yet.');\r
2146                 }\r
2147             }\r
2148 \r
2149             module.exports = GlobalModel;\r
2150 \r
2151 \r
2152 /***/ },\r
2153 /* 3 */\r
2154 /***/ function(module, exports, __webpack_require__) {\r
2155 \r
2156         /**\r
2157          */\r
2158 \r
2159             var Gradient = __webpack_require__(4);\r
2160             // 用于处理merge时无法遍历Date等对象的问题\r
2161             var BUILTIN_OBJECT = {\r
2162                 '[object Function]': 1,\r
2163                 '[object RegExp]': 1,\r
2164                 '[object Date]': 1,\r
2165                 '[object Error]': 1,\r
2166                 '[object CanvasGradient]': 1\r
2167             };\r
2168 \r
2169             var objToString = Object.prototype.toString;\r
2170 \r
2171             var arrayProto = Array.prototype;\r
2172             var nativeForEach = arrayProto.forEach;\r
2173             var nativeFilter = arrayProto.filter;\r
2174             var nativeSlice = arrayProto.slice;\r
2175             var nativeMap = arrayProto.map;\r
2176             var nativeReduce = arrayProto.reduce;\r
2177 \r
2178             /**\r
2179              * @param {*} source\r
2180              * @return {*} 拷贝后的新对象\r
2181              */\r
2182             function clone(source) {\r
2183                 if (typeof source == 'object' && source !== null) {\r
2184                     var result = source;\r
2185                     if (source instanceof Array) {\r
2186                         result = [];\r
2187                         for (var i = 0, len = source.length; i < len; i++) {\r
2188                             result[i] = clone(source[i]);\r
2189                         }\r
2190                     }\r
2191                     else if (\r
2192                         !isBuildInObject(source)\r
2193                         // 是否为 dom 对象\r
2194                         && !isDom(source)\r
2195                     ) {\r
2196                         result = {};\r
2197                         for (var key in source) {\r
2198                             if (source.hasOwnProperty(key)) {\r
2199                                 result[key] = clone(source[key]);\r
2200                             }\r
2201                         }\r
2202                     }\r
2203 \r
2204                     return result;\r
2205                 }\r
2206 \r
2207                 return source;\r
2208             }\r
2209 \r
2210             /**\r
2211              * @param {*} target\r
2212              * @param {*} source\r
2213              * @param {boolean} [overwrite=false]\r
2214              */\r
2215             function merge(target, source, overwrite) {\r
2216                 // We should escapse that source is string\r
2217                 // and enter for ... in ...\r
2218                 if (!isObject(source) || !isObject(target)) {\r
2219                     return overwrite ? clone(source) : target;\r
2220                 }\r
2221 \r
2222                 for (var key in source) {\r
2223                     if (source.hasOwnProperty(key)) {\r
2224                         var targetProp = target[key];\r
2225                         var sourceProp = source[key];\r
2226 \r
2227                         if (isObject(sourceProp)\r
2228                             && isObject(targetProp)\r
2229                             && !isArray(sourceProp)\r
2230                             && !isArray(targetProp)\r
2231                             && !isDom(sourceProp)\r
2232                             && !isDom(targetProp)\r
2233                             && !isBuildInObject(sourceProp)\r
2234                             && !isBuildInObject(targetProp)\r
2235                         ) {\r
2236                             // 如果需要递归覆盖,就递归调用merge\r
2237                             merge(targetProp, sourceProp, overwrite);\r
2238                         }\r
2239                         else if (overwrite || !(key in target)) {\r
2240                             // 否则只处理overwrite为true,或者在目标对象中没有此属性的情况\r
2241                             // NOTE,在 target[key] 不存在的时候也是直接覆盖\r
2242                             target[key] = clone(source[key], true);\r
2243                         }\r
2244                     }\r
2245                 }\r
2246 \r
2247                 return target;\r
2248             }\r
2249 \r
2250             /**\r
2251              * @param {Array} targetAndSources The first item is target, and the rests are source.\r
2252              * @param {boolean} [overwrite=false]\r
2253              * @return {*} target\r
2254              */\r
2255             function mergeAll(targetAndSources, overwrite) {\r
2256                 var result = targetAndSources[0];\r
2257                 for (var i = 1, len = targetAndSources.length; i < len; i++) {\r
2258                     result = merge(result, targetAndSources[i], overwrite);\r
2259                 }\r
2260                 return result;\r
2261             }\r
2262 \r
2263             /**\r
2264              * @param {*} target\r
2265              * @param {*} source\r
2266              */\r
2267             function extend(target, source) {\r
2268                 for (var key in source) {\r
2269                     if (source.hasOwnProperty(key)) {\r
2270                         target[key] = source[key];\r
2271                     }\r
2272                 }\r
2273                 return target;\r
2274             }\r
2275 \r
2276             /**\r
2277              * @param {*} target\r
2278              * @param {*} source\r
2279              * @param {boolen} [overlay=false]\r
2280              */\r
2281             function defaults(target, source, overlay) {\r
2282                 for (var key in source) {\r
2283                     if (source.hasOwnProperty(key)\r
2284                         && (overlay ? source[key] != null : target[key] == null)\r
2285                     ) {\r
2286                         target[key] = source[key];\r
2287                     }\r
2288                 }\r
2289                 return target;\r
2290             }\r
2291 \r
2292             function createCanvas() {\r
2293                 return document.createElement('canvas');\r
2294             }\r
2295             // FIXME\r
2296             var _ctx;\r
2297             function getContext() {\r
2298                 if (!_ctx) {\r
2299                     // Use util.createCanvas instead of createCanvas\r
2300                     // because createCanvas may be overwritten in different environment\r
2301                     _ctx = util.createCanvas().getContext('2d');\r
2302                 }\r
2303                 return _ctx;\r
2304             }\r
2305 \r
2306             /**\r
2307              * 查询数组中元素的index\r
2308              */\r
2309             function indexOf(array, value) {\r
2310                 if (array) {\r
2311                     if (array.indexOf) {\r
2312                         return array.indexOf(value);\r
2313                     }\r
2314                     for (var i = 0, len = array.length; i < len; i++) {\r
2315                         if (array[i] === value) {\r
2316                             return i;\r
2317                         }\r
2318                     }\r
2319                 }\r
2320                 return -1;\r
2321             }\r
2322 \r
2323             /**\r
2324              * 构造类继承关系\r
2325              *\r
2326              * @param {Function} clazz 源类\r
2327              * @param {Function} baseClazz 基类\r
2328              */\r
2329             function inherits(clazz, baseClazz) {\r
2330                 var clazzPrototype = clazz.prototype;\r
2331                 function F() {}\r
2332                 F.prototype = baseClazz.prototype;\r
2333                 clazz.prototype = new F();\r
2334 \r
2335                 for (var prop in clazzPrototype) {\r
2336                     clazz.prototype[prop] = clazzPrototype[prop];\r
2337                 }\r
2338                 clazz.prototype.constructor = clazz;\r
2339                 clazz.superClass = baseClazz;\r
2340             }\r
2341 \r
2342             /**\r
2343              * @param {Object|Function} target\r
2344              * @param {Object|Function} sorce\r
2345              * @param {boolean} overlay\r
2346              */\r
2347             function mixin(target, source, overlay) {\r
2348                 target = 'prototype' in target ? target.prototype : target;\r
2349                 source = 'prototype' in source ? source.prototype : source;\r
2350 \r
2351                 defaults(target, source, overlay);\r
2352             }\r
2353 \r
2354             /**\r
2355              * @param {Array|TypedArray} data\r
2356              */\r
2357             function isArrayLike(data) {\r
2358                 if (! data) {\r
2359                     return;\r
2360                 }\r
2361                 if (typeof data == 'string') {\r
2362                     return false;\r
2363                 }\r
2364                 return typeof data.length == 'number';\r
2365             }\r
2366 \r
2367             /**\r
2368              * 数组或对象遍历\r
2369              * @memberOf module:zrender/tool/util\r
2370              * @param {Object|Array} obj\r
2371              * @param {Function} cb\r
2372              * @param {*} [context]\r
2373              */\r
2374             function each(obj, cb, context) {\r
2375                 if (!(obj && cb)) {\r
2376                     return;\r
2377                 }\r
2378                 if (obj.forEach && obj.forEach === nativeForEach) {\r
2379                     obj.forEach(cb, context);\r
2380                 }\r
2381                 else if (obj.length === +obj.length) {\r
2382                     for (var i = 0, len = obj.length; i < len; i++) {\r
2383                         cb.call(context, obj[i], i, obj);\r
2384                     }\r
2385                 }\r
2386                 else {\r
2387                     for (var key in obj) {\r
2388                         if (obj.hasOwnProperty(key)) {\r
2389                             cb.call(context, obj[key], key, obj);\r
2390                         }\r
2391                     }\r
2392                 }\r
2393             }\r
2394 \r
2395             /**\r
2396              * 数组映射\r
2397              * @memberOf module:zrender/tool/util\r
2398              * @param {Array} obj\r
2399              * @param {Function} cb\r
2400              * @param {*} [context]\r
2401              * @return {Array}\r
2402              */\r
2403             function map(obj, cb, context) {\r
2404                 if (!(obj && cb)) {\r
2405                     return;\r
2406                 }\r
2407                 if (obj.map && obj.map === nativeMap) {\r
2408                     return obj.map(cb, context);\r
2409                 }\r
2410                 else {\r
2411                     var result = [];\r
2412                     for (var i = 0, len = obj.length; i < len; i++) {\r
2413                         result.push(cb.call(context, obj[i], i, obj));\r
2414                     }\r
2415                     return result;\r
2416                 }\r
2417             }\r
2418 \r
2419             /**\r
2420              * @memberOf module:zrender/tool/util\r
2421              * @param {Array} obj\r
2422              * @param {Function} cb\r
2423              * @param {Object} [memo]\r
2424              * @param {*} [context]\r
2425              * @return {Array}\r
2426              */\r
2427             function reduce(obj, cb, memo, context) {\r
2428                 if (!(obj && cb)) {\r
2429                     return;\r
2430                 }\r
2431                 if (obj.reduce && obj.reduce === nativeReduce) {\r
2432                     return obj.reduce(cb, memo, context);\r
2433                 }\r
2434                 else {\r
2435                     for (var i = 0, len = obj.length; i < len; i++) {\r
2436                         memo = cb.call(context, memo, obj[i], i, obj);\r
2437                     }\r
2438                     return memo;\r
2439                 }\r
2440             }\r
2441 \r
2442             /**\r
2443              * 数组过滤\r
2444              * @memberOf module:zrender/tool/util\r
2445              * @param {Array} obj\r
2446              * @param {Function} cb\r
2447              * @param {*} [context]\r
2448              * @return {Array}\r
2449              */\r
2450             function filter(obj, cb, context) {\r
2451                 if (!(obj && cb)) {\r
2452                     return;\r
2453                 }\r
2454                 if (obj.filter && obj.filter === nativeFilter) {\r
2455                     return obj.filter(cb, context);\r
2456                 }\r
2457                 else {\r
2458                     var result = [];\r
2459                     for (var i = 0, len = obj.length; i < len; i++) {\r
2460                         if (cb.call(context, obj[i], i, obj)) {\r
2461                             result.push(obj[i]);\r
2462                         }\r
2463                     }\r
2464                     return result;\r
2465                 }\r
2466             }\r
2467 \r
2468             /**\r
2469              * 数组项查找\r
2470              * @memberOf module:zrender/tool/util\r
2471              * @param {Array} obj\r
2472              * @param {Function} cb\r
2473              * @param {*} [context]\r
2474              * @return {Array}\r
2475              */\r
2476             function find(obj, cb, context) {\r
2477                 if (!(obj && cb)) {\r
2478                     return;\r
2479                 }\r
2480                 for (var i = 0, len = obj.length; i < len; i++) {\r
2481                     if (cb.call(context, obj[i], i, obj)) {\r
2482                         return obj[i];\r
2483                     }\r
2484                 }\r
2485             }\r
2486 \r
2487             /**\r
2488              * @memberOf module:zrender/tool/util\r
2489              * @param {Function} func\r
2490              * @param {*} context\r
2491              * @return {Function}\r
2492              */\r
2493             function bind(func, context) {\r
2494                 var args = nativeSlice.call(arguments, 2);\r
2495                 return function () {\r
2496                     return func.apply(context, args.concat(nativeSlice.call(arguments)));\r
2497                 };\r
2498             }\r
2499 \r
2500             /**\r
2501              * @memberOf module:zrender/tool/util\r
2502              * @param {Function} func\r
2503              * @param {...}\r
2504              * @return {Function}\r
2505              */\r
2506             function curry(func) {\r
2507                 var args = nativeSlice.call(arguments, 1);\r
2508                 return function () {\r
2509                     return func.apply(this, args.concat(nativeSlice.call(arguments)));\r
2510                 };\r
2511             }\r
2512 \r
2513             /**\r
2514              * @memberOf module:zrender/tool/util\r
2515              * @param {*} value\r
2516              * @return {boolean}\r
2517              */\r
2518             function isArray(value) {\r
2519                 return objToString.call(value) === '[object Array]';\r
2520             }\r
2521 \r
2522             /**\r
2523              * @memberOf module:zrender/tool/util\r
2524              * @param {*} value\r
2525              * @return {boolean}\r
2526              */\r
2527             function isFunction(value) {\r
2528                 return typeof value === 'function';\r
2529             }\r
2530 \r
2531             /**\r
2532              * @memberOf module:zrender/tool/util\r
2533              * @param {*} value\r
2534              * @return {boolean}\r
2535              */\r
2536             function isString(value) {\r
2537                 return objToString.call(value) === '[object String]';\r
2538             }\r
2539 \r
2540             /**\r
2541              * @memberOf module:zrender/tool/util\r
2542              * @param {*} value\r
2543              * @return {boolean}\r
2544              */\r
2545             function isObject(value) {\r
2546                 // Avoid a V8 JIT bug in Chrome 19-20.\r
2547                 // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\r
2548                 var type = typeof value;\r
2549                 return type === 'function' || (!!value && type == 'object');\r
2550             }\r
2551 \r
2552             /**\r
2553              * @memberOf module:zrender/tool/util\r
2554              * @param {*} value\r
2555              * @return {boolean}\r
2556              */\r
2557             function isBuildInObject(value) {\r
2558                 return !!BUILTIN_OBJECT[objToString.call(value)]\r
2559                     || (value instanceof Gradient);\r
2560             }\r
2561 \r
2562             /**\r
2563              * @memberOf module:zrender/tool/util\r
2564              * @param {*} value\r
2565              * @return {boolean}\r
2566              */\r
2567             function isDom(value) {\r
2568                 return value && value.nodeType === 1\r
2569                        && typeof(value.nodeName) == 'string';\r
2570             }\r
2571 \r
2572             /**\r
2573              * If value1 is not null, then return value1, otherwise judget rest of values.\r
2574              * @param  {*...} values\r
2575              * @return {*} Final value\r
2576              */\r
2577             function retrieve(values) {\r
2578                 for (var i = 0, len = arguments.length; i < len; i++) {\r
2579                     if (arguments[i] != null) {\r
2580                         return arguments[i];\r
2581                     }\r
2582                 }\r
2583             }\r
2584 \r
2585             /**\r
2586              * @memberOf module:zrender/tool/util\r
2587              * @param {Array} arr\r
2588              * @param {number} startIndex\r
2589              * @param {number} endIndex\r
2590              * @return {Array}\r
2591              */\r
2592             function slice() {\r
2593                 return Function.call.apply(nativeSlice, arguments);\r
2594             }\r
2595 \r
2596             /**\r
2597              * @param {boolean} condition\r
2598              * @param {string} message\r
2599              */\r
2600             function assert(condition, message) {\r
2601                 if (!condition) {\r
2602                     throw new Error(message);\r
2603                 }\r
2604             }\r
2605 \r
2606             var util = {\r
2607                 inherits: inherits,\r
2608                 mixin: mixin,\r
2609                 clone: clone,\r
2610                 merge: merge,\r
2611                 mergeAll: mergeAll,\r
2612                 extend: extend,\r
2613                 defaults: defaults,\r
2614                 getContext: getContext,\r
2615                 createCanvas: createCanvas,\r
2616                 indexOf: indexOf,\r
2617                 slice: slice,\r
2618                 find: find,\r
2619                 isArrayLike: isArrayLike,\r
2620                 each: each,\r
2621                 map: map,\r
2622                 reduce: reduce,\r
2623                 filter: filter,\r
2624                 bind: bind,\r
2625                 curry: curry,\r
2626                 isArray: isArray,\r
2627                 isString: isString,\r
2628                 isObject: isObject,\r
2629                 isFunction: isFunction,\r
2630                 isBuildInObject: isBuildInObject,\r
2631                 isDom: isDom,\r
2632                 retrieve: retrieve,\r
2633                 assert: assert,\r
2634                 noop: function () {}\r
2635             };\r
2636             module.exports = util;\r
2637 \r
2638 \r
2639 \r
2640 /***/ },\r
2641 /* 4 */\r
2642 /***/ function(module, exports) {\r
2643 \r
2644         \r
2645 \r
2646             /**\r
2647              * @param {Array.<Object>} colorStops\r
2648              */\r
2649             var Gradient = function (colorStops) {\r
2650 \r
2651                 this.colorStops = colorStops || [];\r
2652             };\r
2653 \r
2654             Gradient.prototype = {\r
2655 \r
2656                 constructor: Gradient,\r
2657 \r
2658                 addColorStop: function (offset, color) {\r
2659                     this.colorStops.push({\r
2660 \r
2661                         offset: offset,\r
2662 \r
2663                         color: color\r
2664                     });\r
2665                 }\r
2666             };\r
2667 \r
2668             module.exports = Gradient;\r
2669 \r
2670 \r
2671 /***/ },\r
2672 /* 5 */\r
2673 /***/ function(module, exports, __webpack_require__) {\r
2674 \r
2675         \r
2676 \r
2677             var formatUtil = __webpack_require__(6);\r
2678             var nubmerUtil = __webpack_require__(7);\r
2679             var zrUtil = __webpack_require__(3);\r
2680 \r
2681             var Model = __webpack_require__(8);\r
2682 \r
2683             var AXIS_DIMS = ['x', 'y', 'z', 'radius', 'angle'];\r
2684 \r
2685             var modelUtil = {};\r
2686 \r
2687             /**\r
2688              * Create "each" method to iterate names.\r
2689              *\r
2690              * @pubilc\r
2691              * @param  {Array.<string>} names\r
2692              * @param  {Array.<string>=} attrs\r
2693              * @return {Function}\r
2694              */\r
2695             modelUtil.createNameEach = function (names, attrs) {\r
2696                 names = names.slice();\r
2697                 var capitalNames = zrUtil.map(names, modelUtil.capitalFirst);\r
2698                 attrs = (attrs || []).slice();\r
2699                 var capitalAttrs = zrUtil.map(attrs, modelUtil.capitalFirst);\r
2700 \r
2701                 return function (callback, context) {\r
2702                     zrUtil.each(names, function (name, index) {\r
2703                         var nameObj = {name: name, capital: capitalNames[index]};\r
2704 \r
2705                         for (var j = 0; j < attrs.length; j++) {\r
2706                             nameObj[attrs[j]] = name + capitalAttrs[j];\r
2707                         }\r
2708 \r
2709                         callback.call(context, nameObj);\r
2710                     });\r
2711                 };\r
2712             };\r
2713 \r
2714             /**\r
2715              * @public\r
2716              */\r
2717             modelUtil.capitalFirst = function (str) {\r
2718                 return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;\r
2719             };\r
2720 \r
2721             /**\r
2722              * Iterate each dimension name.\r
2723              *\r
2724              * @public\r
2725              * @param {Function} callback The parameter is like:\r
2726              *                            {\r
2727              *                                name: 'angle',\r
2728              *                                capital: 'Angle',\r
2729              *                                axis: 'angleAxis',\r
2730              *                                axisIndex: 'angleAixs',\r
2731              *                                index: 'angleIndex'\r
2732              *                            }\r
2733              * @param {Object} context\r
2734              */\r
2735             modelUtil.eachAxisDim = modelUtil.createNameEach(AXIS_DIMS, ['axisIndex', 'axis', 'index']);\r
2736 \r
2737             /**\r
2738              * If value is not array, then translate it to array.\r
2739              * @param  {*} value\r
2740              * @return {Array} [value] or value\r
2741              */\r
2742             modelUtil.normalizeToArray = function (value) {\r
2743                 return zrUtil.isArray(value)\r
2744                     ? value\r
2745                     : value == null\r
2746                     ? []\r
2747                     : [value];\r
2748             };\r
2749 \r
2750             /**\r
2751              * If tow dataZoomModels has the same axis controlled, we say that they are 'linked'.\r
2752              * dataZoomModels and 'links' make up one or more graphics.\r
2753              * This function finds the graphic where the source dataZoomModel is in.\r
2754              *\r
2755              * @public\r
2756              * @param {Function} forEachNode Node iterator.\r
2757              * @param {Function} forEachEdgeType edgeType iterator\r
2758              * @param {Function} edgeIdGetter Giving node and edgeType, return an array of edge id.\r
2759              * @return {Function} Input: sourceNode, Output: Like {nodes: [], dims: {}}\r
2760              */\r
2761             modelUtil.createLinkedNodesFinder = function (forEachNode, forEachEdgeType, edgeIdGetter) {\r
2762 \r
2763                 return function (sourceNode) {\r
2764                     var result = {\r
2765                         nodes: [],\r
2766                         records: {} // key: edgeType.name, value: Object (key: edge id, value: boolean).\r
2767                     };\r
2768 \r
2769                     forEachEdgeType(function (edgeType) {\r
2770                         result.records[edgeType.name] = {};\r
2771                     });\r
2772 \r
2773                     if (!sourceNode) {\r
2774                         return result;\r
2775                     }\r
2776 \r
2777                     absorb(sourceNode, result);\r
2778 \r
2779                     var existsLink;\r
2780                     do {\r
2781                         existsLink = false;\r
2782                         forEachNode(processSingleNode);\r
2783                     }\r
2784                     while (existsLink);\r
2785 \r
2786                     function processSingleNode(node) {\r
2787                         if (!isNodeAbsorded(node, result) && isLinked(node, result)) {\r
2788                             absorb(node, result);\r
2789                             existsLink = true;\r
2790                         }\r
2791                     }\r
2792 \r
2793                     return result;\r
2794                 };\r
2795 \r
2796                 function isNodeAbsorded(node, result) {\r
2797                     return zrUtil.indexOf(result.nodes, node) >= 0;\r
2798                 }\r
2799 \r
2800                 function isLinked(node, result) {\r
2801                     var hasLink = false;\r
2802                     forEachEdgeType(function (edgeType) {\r
2803                         zrUtil.each(edgeIdGetter(node, edgeType) || [], function (edgeId) {\r
2804                             result.records[edgeType.name][edgeId] && (hasLink = true);\r
2805                         });\r
2806                     });\r
2807                     return hasLink;\r
2808                 }\r
2809 \r
2810                 function absorb(node, result) {\r
2811                     result.nodes.push(node);\r
2812                     forEachEdgeType(function (edgeType) {\r
2813                         zrUtil.each(edgeIdGetter(node, edgeType) || [], function (edgeId) {\r
2814                             result.records[edgeType.name][edgeId] = true;\r
2815                         });\r
2816                     });\r
2817                 }\r
2818             };\r
2819 \r
2820             /**\r
2821              * Sync default option between normal and emphasis like `position` and `show`\r
2822              * In case some one will write code like\r
2823              *     label: {\r
2824              *         normal: {\r
2825              *             show: false,\r
2826              *             position: 'outside',\r
2827              *             textStyle: {\r
2828              *                 fontSize: 18\r
2829              *             }\r
2830              *         },\r
2831              *         emphasis: {\r
2832              *             show: true\r
2833              *         }\r
2834              *     }\r
2835              * @param {Object} opt\r
2836              * @param {Array.<string>} subOpts\r
2837              */\r
2838              modelUtil.defaultEmphasis = function (opt, subOpts) {\r
2839                 if (opt) {\r
2840                     var emphasisOpt = opt.emphasis = opt.emphasis || {};\r
2841                     var normalOpt = opt.normal = opt.normal || {};\r
2842 \r
2843                     // Default emphasis option from normal\r
2844                     zrUtil.each(subOpts, function (subOptName) {\r
2845                         var val = zrUtil.retrieve(emphasisOpt[subOptName], normalOpt[subOptName]);\r
2846                         if (val != null) {\r
2847                             emphasisOpt[subOptName] = val;\r
2848                         }\r
2849                     });\r
2850                 }\r
2851             };\r
2852 \r
2853             /**\r
2854              * Create a model proxy to be used in tooltip for edge data, markLine data, markPoint data.\r
2855              * @param {Object} opt\r
2856              * @param {string} [opt.seriesIndex]\r
2857              * @param {Object} [opt.name]\r
2858              * @param {module:echarts/data/List} data\r
2859              * @param {Array.<Object>} rawData\r
2860              */\r
2861             modelUtil.createDataFormatModel = function (opt, data, rawData) {\r
2862                 var model = new Model();\r
2863                 zrUtil.mixin(model, modelUtil.dataFormatMixin);\r
2864                 model.seriesIndex = opt.seriesIndex;\r
2865                 model.name = opt.name || '';\r
2866 \r
2867                 model.getData = function () {\r
2868                     return data;\r
2869                 };\r
2870                 model.getRawDataArray = function () {\r
2871                     return rawData;\r
2872                 };\r
2873                 return model;\r
2874             };\r
2875 \r
2876             /**\r
2877              * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]\r
2878              * This helper method retieves value from data.\r
2879              * @param {string|number|Date|Array|Object} dataItem\r
2880              * @return {number|string|Date|Array.<number|string|Date>}\r
2881              */\r
2882             modelUtil.getDataItemValue = function (dataItem) {\r
2883                 // Performance sensitive.\r
2884                 return dataItem && (dataItem.value == null ? dataItem : dataItem.value);\r
2885             };\r
2886 \r
2887             /**\r
2888              * This helper method convert value in data.\r
2889              * @param {string|number|Date} value\r
2890              * @param {Object|string} [dimInfo] If string (like 'x'), dimType defaults 'number'.\r
2891              */\r
2892             modelUtil.converDataValue = function (value, dimInfo) {\r
2893                 // Performance sensitive.\r
2894                 var dimType = dimInfo && dimInfo.type;\r
2895                 if (dimType === 'ordinal') {\r
2896                     return value;\r
2897                 }\r
2898 \r
2899                 if (dimType === 'time' && !isFinite(value) && value != null && value !== '-') {\r
2900                     value = +nubmerUtil.parseDate(value);\r
2901                 }\r
2902 \r
2903                 // dimType defaults 'number'.\r
2904                 // If dimType is not ordinal and value is null or undefined or NaN or '-',\r
2905                 // parse to NaN.\r
2906                 return (value == null || value === '')\r
2907                     ? NaN : +value; // If string (like '-'), using '+' parse to NaN\r
2908             };\r
2909 \r
2910             modelUtil.dataFormatMixin = {\r
2911                 /**\r
2912                  * Get params for formatter\r
2913                  * @param {number} dataIndex\r
2914                  * @return {Object}\r
2915                  */\r
2916                 getDataParams: function (dataIndex) {\r
2917                     var data = this.getData();\r
2918 \r
2919                     var seriesIndex = this.seriesIndex;\r
2920                     var seriesName = this.name;\r
2921 \r
2922                     var rawValue = this.getRawValue(dataIndex);\r
2923                     var rawDataIndex = data.getRawIndex(dataIndex);\r
2924                     var name = data.getName(dataIndex, true);\r
2925 \r
2926                     // Data may not exists in the option given by user\r
2927                     var rawDataArray = this.getRawDataArray();\r
2928                     var itemOpt = rawDataArray && rawDataArray[rawDataIndex];\r
2929 \r
2930                     return {\r
2931                         seriesIndex: seriesIndex,\r
2932                         seriesName: seriesName,\r
2933                         name: name,\r
2934                         dataIndex: rawDataIndex,\r
2935                         data: itemOpt,\r
2936                         value: rawValue,\r
2937                         color: data.getItemVisual(dataIndex, 'color'),\r
2938 \r
2939                         // Param name list for mapping `a`, `b`, `c`, `d`, `e`\r
2940                         $vars: ['seriesName', 'name', 'value']\r
2941                     };\r
2942                 },\r
2943 \r
2944                 /**\r
2945                  * Format label\r
2946                  * @param {number} dataIndex\r
2947                  * @param {string} [status='normal'] 'normal' or 'emphasis'\r
2948                  * @param {Function|string} [formatter] Default use the `itemStyle[status].label.formatter`\r
2949                  * @return {string}\r
2950                  */\r
2951                 getFormattedLabel: function (dataIndex, status, formatter) {\r
2952                     status = status || 'normal';\r
2953                     var data = this.getData();\r
2954                     var itemModel = data.getItemModel(dataIndex);\r
2955 \r
2956                     var params = this.getDataParams(dataIndex);\r
2957                     if (formatter == null) {\r
2958                         formatter = itemModel.get(['label', status, 'formatter']);\r
2959                     }\r
2960 \r
2961                     if (typeof formatter === 'function') {\r
2962                         params.status = status;\r
2963                         return formatter(params);\r
2964                     }\r
2965                     else if (typeof formatter === 'string') {\r
2966                         return formatUtil.formatTpl(formatter, params);\r
2967                     }\r
2968                 },\r
2969 \r
2970                 /**\r
2971                  * Get raw value in option\r
2972                  * @param {number} idx\r
2973                  * @return {Object}\r
2974                  */\r
2975                 getRawValue: function (idx) {\r
2976                     var itemModel = this.getData().getItemModel(idx);\r
2977                     if (itemModel && itemModel.option != null) {\r
2978                         var dataItem = itemModel.option;\r
2979                         return (zrUtil.isObject(dataItem) && !zrUtil.isArray(dataItem))\r
2980                             ? dataItem.value : dataItem;\r
2981                     }\r
2982                 }\r
2983             };\r
2984 \r
2985             /**\r
2986              * Mapping to exists for merge.\r
2987              *\r
2988              * @public\r
2989              * @param {Array.<Object>|Array.<module:echarts/model/Component>} exists\r
2990              * @param {Object|Array.<Object>} newCptOptions\r
2991              * @return {Array.<Object>} Result, like [{exist: ..., option: ...}, {}],\r
2992              *                          which order is the same as exists.\r
2993              */\r
2994             modelUtil.mappingToExists = function (exists, newCptOptions) {\r
2995                 // Mapping by the order by original option (but not order of\r
2996                 // new option) in merge mode. Because we should ensure\r
2997                 // some specified index (like xAxisIndex) is consistent with\r
2998                 // original option, which is easy to understand, espatially in\r
2999                 // media query. And in most case, merge option is used to\r
3000                 // update partial option but not be expected to change order.\r
3001                 newCptOptions = (newCptOptions || []).slice();\r
3002 \r
3003                 var result = zrUtil.map(exists || [], function (obj, index) {\r
3004                     return {exist: obj};\r
3005                 });\r
3006 \r
3007                 // Mapping by id or name if specified.\r
3008                 zrUtil.each(newCptOptions, function (cptOption, index) {\r
3009                     if (!zrUtil.isObject(cptOption)) {\r
3010                         return;\r
3011                     }\r
3012 \r
3013                     for (var i = 0; i < result.length; i++) {\r
3014                         var exist = result[i].exist;\r
3015                         if (!result[i].option // Consider name: two map to one.\r
3016                             && (\r
3017                                 // id has highest priority.\r
3018                                 (cptOption.id != null && exist.id === cptOption.id + '')\r
3019                                 || (cptOption.name != null\r
3020                                     && !modelUtil.isIdInner(cptOption)\r
3021                                     && !modelUtil.isIdInner(exist)\r
3022                                     && exist.name === cptOption.name + ''\r
3023                                 )\r
3024                             )\r
3025                         ) {\r
3026                             result[i].option = cptOption;\r
3027                             newCptOptions[index] = null;\r
3028                             break;\r
3029                         }\r
3030                     }\r
3031                 });\r
3032 \r
3033                 // Otherwise mapping by index.\r
3034                 zrUtil.each(newCptOptions, function (cptOption, index) {\r
3035                     if (!zrUtil.isObject(cptOption)) {\r
3036                         return;\r
3037                     }\r
3038 \r
3039                     var i = 0;\r
3040                     for (; i < result.length; i++) {\r
3041                         var exist = result[i].exist;\r
3042                         if (!result[i].option\r
3043                             && !modelUtil.isIdInner(exist)\r
3044                             // Caution:\r
3045                             // Do not overwrite id. But name can be overwritten,\r
3046                             // because axis use name as 'show label text'.\r
3047                             // 'exist' always has id and name and we dont\r
3048                             // need to check it.\r
3049                             && cptOption.id == null\r
3050                         ) {\r
3051                             result[i].option = cptOption;\r
3052                             break;\r
3053                         }\r
3054                     }\r
3055 \r
3056                     if (i >= result.length) {\r
3057                         result.push({option: cptOption});\r
3058                     }\r
3059                 });\r
3060 \r
3061                 return result;\r
3062             };\r
3063 \r
3064             /**\r
3065              * @public\r
3066              * @param {Object} cptOption\r
3067              * @return {boolean}\r
3068              */\r
3069             modelUtil.isIdInner = function (cptOption) {\r
3070                 return zrUtil.isObject(cptOption)\r
3071                     && cptOption.id\r
3072                     && (cptOption.id + '').indexOf('\0_ec_\0') === 0;\r
3073             };\r
3074 \r
3075             module.exports = modelUtil;\r
3076 \r
3077 \r
3078 /***/ },\r
3079 /* 6 */\r
3080 /***/ function(module, exports, __webpack_require__) {\r
3081 \r
3082         \r
3083 \r
3084             var zrUtil = __webpack_require__(3);\r
3085             var numberUtil = __webpack_require__(7);\r
3086 \r
3087             /**\r
3088              * 每三位默认加,格式化\r
3089              * @type {string|number} x\r
3090              */\r
3091             function addCommas(x) {\r
3092                 if (isNaN(x)) {\r
3093                     return '-';\r
3094                 }\r
3095                 x = (x + '').split('.');\r
3096                 return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,'$1,')\r
3097                        + (x.length > 1 ? ('.' + x[1]) : '');\r
3098             }\r
3099 \r
3100             /**\r
3101              * @param {string} str\r
3102              * @return {string} str\r
3103              */\r
3104             function toCamelCase(str) {\r
3105                 return str.toLowerCase().replace(/-(.)/g, function(match, group1) {\r
3106                     return group1.toUpperCase();\r
3107                 });\r
3108             }\r
3109 \r
3110             /**\r
3111              * Normalize css liked array configuration\r
3112              * e.g.\r
3113              *  3 => [3, 3, 3, 3]\r
3114              *  [4, 2] => [4, 2, 4, 2]\r
3115              *  [4, 3, 2] => [4, 3, 2, 3]\r
3116              * @param {number|Array.<number>} val\r
3117              */\r
3118             function normalizeCssArray(val) {\r
3119                 var len = val.length;\r
3120                 if (typeof (val) === 'number') {\r
3121                     return [val, val, val, val];\r
3122                 }\r
3123                 else if (len === 2) {\r
3124                     // vertical | horizontal\r
3125                     return [val[0], val[1], val[0], val[1]];\r
3126                 }\r
3127                 else if (len === 3) {\r
3128                     // top | horizontal | bottom\r
3129                     return [val[0], val[1], val[2], val[1]];\r
3130                 }\r
3131                 return val;\r
3132             }\r
3133 \r
3134             function encodeHTML(source) {\r
3135                 return String(source)\r
3136                     .replace(/&/g, '&amp;')\r
3137                     .replace(/</g, '&lt;')\r
3138                     .replace(/>/g, '&gt;')\r
3139                     .replace(/"/g, '&quot;')\r
3140                     .replace(/'/g, '&#39;');\r
3141             }\r
3142 \r
3143             var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];\r
3144 \r
3145             function wrapVar(varName, seriesIdx) {\r
3146                 return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}';\r
3147             }\r
3148             /**\r
3149              * Template formatter\r
3150              * @param  {string} tpl\r
3151              * @param  {Array.<Object>|Object} paramsList\r
3152              * @return {string}\r
3153              */\r
3154             function formatTpl(tpl, paramsList) {\r
3155                 if (!zrUtil.isArray(paramsList)) {\r
3156                     paramsList = [paramsList];\r
3157                 }\r
3158                 var seriesLen = paramsList.length;\r
3159                 if (!seriesLen) {\r
3160                     return '';\r
3161                 }\r
3162 \r
3163                 var $vars = paramsList[0].$vars;\r
3164                 for (var i = 0; i < $vars.length; i++) {\r
3165                     var alias = TPL_VAR_ALIAS[i];\r
3166                     tpl = tpl.replace(wrapVar(alias),  wrapVar(alias, 0));\r
3167                 }\r
3168                 for (var seriesIdx = 0; seriesIdx < seriesLen; seriesIdx++) {\r
3169                     for (var k = 0; k < $vars.length; k++) {\r
3170                         tpl = tpl.replace(\r
3171                             wrapVar(TPL_VAR_ALIAS[k], seriesIdx),\r
3172                             paramsList[seriesIdx][$vars[k]]\r
3173                         );\r
3174                     }\r
3175                 }\r
3176 \r
3177                 return tpl;\r
3178             }\r
3179 \r
3180             /**\r
3181              * ISO Date format\r
3182              * @param {string} tpl\r
3183              * @param {number} value\r
3184              * @inner\r
3185              */\r
3186             function formatTime(tpl, value) {\r
3187                 if (tpl === 'week'\r
3188                     || tpl === 'month'\r
3189                     || tpl === 'quarter'\r
3190                     || tpl === 'half-year'\r
3191                     || tpl === 'year'\r
3192                 ) {\r
3193                     tpl = 'MM-dd\nyyyy';\r
3194                 }\r
3195 \r
3196                 var date = numberUtil.parseDate(value);\r
3197                 var y = date.getFullYear();\r
3198                 var M = date.getMonth() + 1;\r
3199                 var d = date.getDate();\r
3200                 var h = date.getHours();\r
3201                 var m = date.getMinutes();\r
3202                 var s = date.getSeconds();\r
3203 \r
3204                 tpl = tpl.replace('MM', s2d(M))\r
3205                     .toLowerCase()\r
3206                     .replace('yyyy', y)\r
3207                     .replace('yy', y % 100)\r
3208                     .replace('dd', s2d(d))\r
3209                     .replace('d', d)\r
3210                     .replace('hh', s2d(h))\r
3211                     .replace('h', h)\r
3212                     .replace('mm', s2d(m))\r
3213                     .replace('m', m)\r
3214                     .replace('ss', s2d(s))\r
3215                     .replace('s', s);\r
3216 \r
3217                 return tpl;\r
3218             }\r
3219 \r
3220             /**\r
3221              * @param {string} str\r
3222              * @return {string}\r
3223              * @inner\r
3224              */\r
3225             function s2d(str) {\r
3226                 return str < 10 ? ('0' + str) : str;\r
3227             }\r
3228 \r
3229             module.exports = {\r
3230 \r
3231                 normalizeCssArray: normalizeCssArray,\r
3232 \r
3233                 addCommas: addCommas,\r
3234 \r
3235                 toCamelCase: toCamelCase,\r
3236 \r
3237                 encodeHTML: encodeHTML,\r
3238 \r
3239                 formatTpl: formatTpl,\r
3240 \r
3241                 formatTime: formatTime\r
3242             };\r
3243 \r
3244 \r
3245 /***/ },\r
3246 /* 7 */\r
3247 /***/ function(module, exports) {\r
3248 \r
3249         /**\r
3250          * 数值处理模块\r
3251          * @module echarts/util/number\r
3252          */\r
3253 \r
3254 \r
3255 \r
3256             var number = {};\r
3257 \r
3258             var RADIAN_EPSILON = 1e-4;\r
3259 \r
3260             function _trim(str) {\r
3261                 return str.replace(/^\s+/, '').replace(/\s+$/, '');\r
3262             }\r
3263 \r
3264             /**\r
3265              * Linear mapping a value from domain to range\r
3266              * @memberOf module:echarts/util/number\r
3267              * @param  {(number|Array.<number>)} val\r
3268              * @param  {Array.<number>} domain Domain extent domain[0] can be bigger than domain[1]\r
3269              * @param  {Array.<number>} range  Range extent range[0] can be bigger than range[1]\r
3270              * @param  {boolean} clamp\r
3271              * @return {(number|Array.<number>}\r
3272              */\r
3273             number.linearMap = function (val, domain, range, clamp) {\r
3274 \r
3275                 var sub = domain[1] - domain[0];\r
3276 \r
3277                 if (sub === 0) {\r
3278                     return (range[0] + range[1]) / 2;\r
3279                 }\r
3280                 var t = (val - domain[0]) / sub;\r
3281 \r
3282                 if (clamp) {\r
3283                     t = Math.min(Math.max(t, 0), 1);\r
3284                 }\r
3285 \r
3286                 return t * (range[1] - range[0]) + range[0];\r
3287             };\r
3288 \r
3289             /**\r
3290              * Convert a percent string to absolute number.\r
3291              * Returns NaN if percent is not a valid string or number\r
3292              * @memberOf module:echarts/util/number\r
3293              * @param {string|number} percent\r
3294              * @param {number} all\r
3295              * @return {number}\r
3296              */\r
3297             number.parsePercent = function(percent, all) {\r
3298                 switch (percent) {\r
3299                     case 'center':\r
3300                     case 'middle':\r
3301                         percent = '50%';\r
3302                         break;\r
3303                     case 'left':\r
3304                     case 'top':\r
3305                         percent = '0%';\r
3306                         break;\r
3307                     case 'right':\r
3308                     case 'bottom':\r
3309                         percent = '100%';\r
3310                         break;\r
3311                 }\r
3312                 if (typeof percent === 'string') {\r
3313                     if (_trim(percent).match(/%$/)) {\r
3314                         return parseFloat(percent) / 100 * all;\r
3315                     }\r
3316 \r
3317                     return parseFloat(percent);\r
3318                 }\r
3319 \r
3320                 return percent == null ? NaN : +percent;\r
3321             };\r
3322 \r
3323             /**\r
3324              * Fix rounding error of float numbers\r
3325              * @param {number} x\r
3326              * @return {number}\r
3327              */\r
3328             number.round = function (x) {\r
3329                 // PENDING\r
3330                 return +(+x).toFixed(12);\r
3331             };\r
3332 \r
3333             number.asc = function (arr) {\r
3334                 arr.sort(function (a, b) {\r
3335                     return a - b;\r
3336                 });\r
3337                 return arr;\r
3338             };\r
3339 \r
3340             /**\r
3341              * Get precision\r
3342              * @param {number} val\r
3343              */\r
3344             number.getPrecision = function (val) {\r
3345                 if (isNaN(val)) {\r
3346                     return 0;\r
3347                 }\r
3348                 // It is much faster than methods converting number to string as follows\r
3349                 //      var tmp = val.toString();\r
3350                 //      return tmp.length - 1 - tmp.indexOf('.');\r
3351                 // especially when precision is low\r
3352                 var e = 1;\r
3353                 var count = 0;\r
3354                 while (Math.round(val * e) / e !== val) {\r
3355                     e *= 10;\r
3356                     count++;\r
3357                 }\r
3358                 return count;\r
3359             };\r
3360 \r
3361             /**\r
3362              * @param {Array.<number>} dataExtent\r
3363              * @param {Array.<number>} pixelExtent\r
3364              * @return {number}  precision\r
3365              */\r
3366             number.getPixelPrecision = function (dataExtent, pixelExtent) {\r
3367                 var log = Math.log;\r
3368                 var LN10 = Math.LN10;\r
3369                 var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);\r
3370                 var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10);\r
3371                 return Math.max(\r
3372                     -dataQuantity + sizeQuantity,\r
3373                     0\r
3374                 );\r
3375             };\r
3376 \r
3377             // Number.MAX_SAFE_INTEGER, ie do not support.\r
3378             number.MAX_SAFE_INTEGER = 9007199254740991;\r
3379 \r
3380             /**\r
3381              * To 0 - 2 * PI, considering negative radian.\r
3382              * @param {number} radian\r
3383              * @return {number}\r
3384              */\r
3385             number.remRadian = function (radian) {\r
3386                 var pi2 = Math.PI * 2;\r
3387                 return (radian % pi2 + pi2) % pi2;\r
3388             };\r
3389 \r
3390             /**\r
3391              * @param {type} radian\r
3392              * @return {boolean}\r
3393              */\r
3394             number.isRadianAroundZero = function (val) {\r
3395                 return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;\r
3396             };\r
3397 \r
3398             /**\r
3399              * @param {string|Date|number} value\r
3400              * @return {number} timestamp\r
3401              */\r
3402             number.parseDate = function (value) {\r
3403                 return value instanceof Date\r
3404                     ? value\r
3405                     : new Date(\r
3406                         typeof value === 'string'\r
3407                             ? value.replace(/-/g, '/')\r
3408                             : Math.round(value)\r
3409                     );\r
3410             };\r
3411 \r
3412             // "Nice Numbers for Graph Labels" of Graphic Gems\r
3413             /**\r
3414              * find a “nice” number approximately equal to x. Round the number if round = true, take ceiling if round = false\r
3415              * The primary observation is that the “nicest” numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers.\r
3416              * @param  {number} val\r
3417              * @param  {boolean} round\r
3418              * @return {number}\r
3419              */\r
3420             number.nice = function (val, round) {\r
3421                 var exp = Math.floor(Math.log(val) / Math.LN10);\r
3422                 var exp10 = Math.pow(10, exp);\r
3423                 var f = val / exp10; // between 1 and 10\r
3424                 var nf;\r
3425                 if (round) {\r
3426                     if (f < 1.5) { nf = 1; }\r
3427                     else if (f < 2.5) { nf = 2; }\r
3428                     else if (f < 4) { nf = 3; }\r
3429                     else if (f < 7) { nf = 5; }\r
3430                     else { nf = 10; }\r
3431                 }\r
3432                 else {\r
3433                     if (f < 1) { nf = 1; }\r
3434                     else if (f < 2) { nf = 2; }\r
3435                     else if (f < 3) { nf = 3; }\r
3436                     else if (f < 5) { nf = 5; }\r
3437                     else { nf = 10; }\r
3438                 }\r
3439                 return nf * exp10;\r
3440             };\r
3441 \r
3442             module.exports = number;\r
3443 \r
3444 \r
3445 /***/ },\r
3446 /* 8 */\r
3447 /***/ function(module, exports, __webpack_require__) {\r
3448 \r
3449         /**\r
3450          * @module echarts/model/Model\r
3451          */\r
3452 \r
3453 \r
3454             var zrUtil = __webpack_require__(3);\r
3455             var clazzUtil = __webpack_require__(9);\r
3456 \r
3457             /**\r
3458              * @alias module:echarts/model/Model\r
3459              * @constructor\r
3460              * @param {Object} option\r
3461              * @param {module:echarts/model/Model} parentModel\r
3462              * @param {module:echarts/model/Global} ecModel\r
3463              * @param {Object} extraOpt\r
3464              */\r
3465             function Model(option, parentModel, ecModel, extraOpt) {\r
3466                 /**\r
3467                  * @type {module:echarts/model/Model}\r
3468                  * @readOnly\r
3469                  */\r
3470                 this.parentModel = parentModel;\r
3471 \r
3472                 /**\r
3473                  * @type {module:echarts/model/Global}\r
3474                  * @readOnly\r
3475                  */\r
3476                 this.ecModel = ecModel;\r
3477 \r
3478                 /**\r
3479                  * @type {Object}\r
3480                  * @protected\r
3481                  */\r
3482                 this.option = option;\r
3483 \r
3484                 // Simple optimization\r
3485                 if (this.init) {\r
3486                     if (arguments.length <= 4) {\r
3487                         this.init(option, parentModel, ecModel, extraOpt);\r
3488                     }\r
3489                     else {\r
3490                         this.init.apply(this, arguments);\r
3491                     }\r
3492                 }\r
3493             }\r
3494 \r
3495             Model.prototype = {\r
3496 \r
3497                 constructor: Model,\r
3498 \r
3499                 /**\r
3500                  * Model 的初始化函数\r
3501                  * @param {Object} option\r
3502                  */\r
3503                 init: null,\r
3504 \r
3505                 /**\r
3506                  * 从新的 Option merge\r
3507                  */\r
3508                 mergeOption: function (option) {\r
3509                     zrUtil.merge(this.option, option, true);\r
3510                 },\r
3511 \r
3512                 /**\r
3513                  * @param {string} path\r
3514                  * @param {boolean} [ignoreParent=false]\r
3515                  * @return {*}\r
3516                  */\r
3517                 get: function (path, ignoreParent) {\r
3518                     if (!path) {\r
3519                         return this.option;\r
3520                     }\r
3521 \r
3522                     if (typeof path === 'string') {\r
3523                         path = path.split('.');\r
3524                     }\r
3525 \r
3526                     var obj = this.option;\r
3527                     var parentModel = this.parentModel;\r
3528                     for (var i = 0; i < path.length; i++) {\r
3529                         // obj could be number/string/... (like 0)\r
3530                         obj = (obj && typeof obj === 'object') ? obj[path[i]] : null;\r
3531                         if (obj == null) {\r
3532                             break;\r
3533                         }\r
3534                     }\r
3535                     if (obj == null && parentModel && !ignoreParent) {\r
3536                         obj = parentModel.get(path);\r
3537                     }\r
3538                     return obj;\r
3539                 },\r
3540 \r
3541                 /**\r
3542                  * @param {string} key\r
3543                  * @param {boolean} [ignoreParent=false]\r
3544                  * @return {*}\r
3545                  */\r
3546                 getShallow: function (key, ignoreParent) {\r
3547                     var option = this.option;\r
3548                     var val = option && option[key];\r
3549                     var parentModel = this.parentModel;\r
3550                     if (val == null && parentModel && !ignoreParent) {\r
3551                         val = parentModel.getShallow(key);\r
3552                     }\r
3553                     return val;\r
3554                 },\r
3555 \r
3556                 /**\r
3557                  * @param {string} path\r
3558                  * @param {module:echarts/model/Model} [parentModel]\r
3559                  * @return {module:echarts/model/Model}\r
3560                  */\r
3561                 getModel: function (path, parentModel) {\r
3562                     var obj = this.get(path, true);\r
3563                     var thisParentModel = this.parentModel;\r
3564                     var model = new Model(\r
3565                         obj, parentModel || (thisParentModel && thisParentModel.getModel(path)),\r
3566                         this.ecModel\r
3567                     );\r
3568                     return model;\r
3569                 },\r
3570 \r
3571                 /**\r
3572                  * If model has option\r
3573                  */\r
3574                 isEmpty: function () {\r
3575                     return this.option == null;\r
3576                 },\r
3577 \r
3578                 restoreData: function () {},\r
3579 \r
3580                 // Pending\r
3581                 clone: function () {\r
3582                     var Ctor = this.constructor;\r
3583                     return new Ctor(zrUtil.clone(this.option));\r
3584                 },\r
3585 \r
3586                 setReadOnly: function (properties) {\r
3587                     clazzUtil.setReadOnly(this, properties);\r
3588                 }\r
3589             };\r
3590 \r
3591             // Enable Model.extend.\r
3592             clazzUtil.enableClassExtend(Model);\r
3593 \r
3594             var mixin = zrUtil.mixin;\r
3595             mixin(Model, __webpack_require__(10));\r
3596             mixin(Model, __webpack_require__(12));\r
3597             mixin(Model, __webpack_require__(13));\r
3598             mixin(Model, __webpack_require__(18));\r
3599 \r
3600             module.exports = Model;\r
3601 \r
3602 \r
3603 /***/ },\r
3604 /* 9 */\r
3605 /***/ function(module, exports, __webpack_require__) {\r
3606 \r
3607         \r
3608 \r
3609             var zrUtil = __webpack_require__(3);\r
3610 \r
3611             var clazz = {};\r
3612 \r
3613             var TYPE_DELIMITER = '.';\r
3614             var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';\r
3615             /**\r
3616              * @public\r
3617              */\r
3618             var parseClassType = clazz.parseClassType = function (componentType) {\r
3619                 var ret = {main: '', sub: ''};\r
3620                 if (componentType) {\r
3621                     componentType = componentType.split(TYPE_DELIMITER);\r
3622                     ret.main = componentType[0] || '';\r
3623                     ret.sub = componentType[1] || '';\r
3624                 }\r
3625                 return ret;\r
3626             };\r
3627             /**\r
3628              * @public\r
3629              */\r
3630             clazz.enableClassExtend = function (RootClass, preConstruct) {\r
3631                 RootClass.extend = function (proto) {\r
3632                     var ExtendedClass = function () {\r
3633                         preConstruct && preConstruct.apply(this, arguments);\r
3634                         RootClass.apply(this, arguments);\r
3635                     };\r
3636 \r
3637                     zrUtil.extend(ExtendedClass.prototype, proto);\r
3638 \r
3639                     ExtendedClass.extend = this.extend;\r
3640                     ExtendedClass.superCall = superCall;\r
3641                     ExtendedClass.superApply = superApply;\r
3642                     zrUtil.inherits(ExtendedClass, this);\r
3643                     ExtendedClass.superClass = this;\r
3644 \r
3645                     return ExtendedClass;\r
3646                 };\r
3647             };\r
3648 \r
3649             // superCall should have class info, which can not be fetch from 'this'.\r
3650             // Consider this case:\r
3651             // class A has method f,\r
3652             // class B inherits class A, overrides method f, f call superApply('f'),\r
3653             // class C inherits class B, do not overrides method f,\r
3654             // then when method of class C is called, dead loop occured.\r
3655             function superCall(context, methodName) {\r
3656                 var args = zrUtil.slice(arguments, 2);\r
3657                 return this.superClass.prototype[methodName].apply(context, args);\r
3658             }\r
3659 \r
3660             function superApply(context, methodName, args) {\r
3661                 return this.superClass.prototype[methodName].apply(context, args);\r
3662             }\r
3663 \r
3664             /**\r
3665              * @param {Object} entity\r
3666              * @param {Object} options\r
3667              * @param {boolean} [options.registerWhenExtend]\r
3668              * @public\r
3669              */\r
3670             clazz.enableClassManagement = function (entity, options) {\r
3671                 options = options || {};\r
3672 \r
3673                 /**\r
3674                  * Component model classes\r
3675                  * key: componentType,\r
3676                  * value:\r
3677                  *     componentClass, when componentType is 'xxx'\r
3678                  *     or Object.<subKey, componentClass>, when componentType is 'xxx.yy'\r
3679                  * @type {Object}\r
3680                  */\r
3681                 var storage = {};\r
3682 \r
3683                 entity.registerClass = function (Clazz, componentType) {\r
3684                     if (componentType) {\r
3685                         componentType = parseClassType(componentType);\r
3686 \r
3687                         if (!componentType.sub) {\r
3688                             if (storage[componentType.main]) {\r
3689                                 throw new Error(componentType.main + 'exists.');\r
3690                             }\r
3691                             storage[componentType.main] = Clazz;\r
3692                         }\r
3693                         else if (componentType.sub !== IS_CONTAINER) {\r
3694                             var container = makeContainer(componentType);\r
3695                             container[componentType.sub] = Clazz;\r
3696                         }\r
3697                     }\r
3698                     return Clazz;\r
3699                 };\r
3700 \r
3701                 entity.getClass = function (componentTypeMain, subType, throwWhenNotFound) {\r
3702                     var Clazz = storage[componentTypeMain];\r
3703 \r
3704                     if (Clazz && Clazz[IS_CONTAINER]) {\r
3705                         Clazz = subType ? Clazz[subType] : null;\r
3706                     }\r
3707 \r
3708                     if (throwWhenNotFound && !Clazz) {\r
3709                         throw new Error(\r
3710                             'Component ' + componentTypeMain + '.' + (subType || '') + ' not exists. Load it first.'\r
3711                         );\r
3712                     }\r
3713 \r
3714                     return Clazz;\r
3715                 };\r
3716 \r
3717                 entity.getClassesByMainType = function (componentType) {\r
3718                     componentType = parseClassType(componentType);\r
3719 \r
3720                     var result = [];\r
3721                     var obj = storage[componentType.main];\r
3722 \r
3723                     if (obj && obj[IS_CONTAINER]) {\r
3724                         zrUtil.each(obj, function (o, type) {\r
3725                             type !== IS_CONTAINER && result.push(o);\r
3726                         });\r
3727                     }\r
3728                     else {\r
3729                         result.push(obj);\r
3730                     }\r
3731 \r
3732                     return result;\r
3733                 };\r
3734 \r
3735                 entity.hasClass = function (componentType) {\r
3736                     // Just consider componentType.main.\r
3737                     componentType = parseClassType(componentType);\r
3738                     return !!storage[componentType.main];\r
3739                 };\r
3740 \r
3741                 /**\r
3742                  * @return {Array.<string>} Like ['aa', 'bb'], but can not be ['aa.xx']\r
3743                  */\r
3744                 entity.getAllClassMainTypes = function () {\r
3745                     var types = [];\r
3746                     zrUtil.each(storage, function (obj, type) {\r
3747                         types.push(type);\r
3748                     });\r
3749                     return types;\r
3750                 };\r
3751 \r
3752                 /**\r
3753                  * If a main type is container and has sub types\r
3754                  * @param  {string}  mainType\r
3755                  * @return {boolean}\r
3756                  */\r
3757                 entity.hasSubTypes = function (componentType) {\r
3758                     componentType = parseClassType(componentType);\r
3759                     var obj = storage[componentType.main];\r
3760                     return obj && obj[IS_CONTAINER];\r
3761                 };\r
3762 \r
3763                 entity.parseClassType = parseClassType;\r
3764 \r
3765                 function makeContainer(componentType) {\r
3766                     var container = storage[componentType.main];\r
3767                     if (!container || !container[IS_CONTAINER]) {\r
3768                         container = storage[componentType.main] = {};\r
3769                         container[IS_CONTAINER] = true;\r
3770                     }\r
3771                     return container;\r
3772                 }\r
3773 \r
3774                 if (options.registerWhenExtend) {\r
3775                     var originalExtend = entity.extend;\r
3776                     if (originalExtend) {\r
3777                         entity.extend = function (proto) {\r
3778                             var ExtendedClass = originalExtend.call(this, proto);\r
3779                             return entity.registerClass(ExtendedClass, proto.type);\r
3780                         };\r
3781                     }\r
3782                 }\r
3783 \r
3784                 return entity;\r
3785             };\r
3786 \r
3787             /**\r
3788              * @param {string|Array.<string>} properties\r
3789              */\r
3790             clazz.setReadOnly = function (obj, properties) {\r
3791                 // FIXME It seems broken in IE8 simulation of IE11\r
3792                 // if (!zrUtil.isArray(properties)) {\r
3793                 //     properties = properties != null ? [properties] : [];\r
3794                 // }\r
3795                 // zrUtil.each(properties, function (prop) {\r
3796                 //     var value = obj[prop];\r
3797 \r
3798                 //     Object.defineProperty\r
3799                 //         && Object.defineProperty(obj, prop, {\r
3800                 //             value: value, writable: false\r
3801                 //         });\r
3802                 //     zrUtil.isArray(obj[prop])\r
3803                 //         && Object.freeze\r
3804                 //         && Object.freeze(obj[prop]);\r
3805                 // });\r
3806             };\r
3807 \r
3808             module.exports = clazz;\r
3809 \r
3810 \r
3811 /***/ },\r
3812 /* 10 */\r
3813 /***/ function(module, exports, __webpack_require__) {\r
3814 \r
3815         \r
3816             var getLineStyle = __webpack_require__(11)(\r
3817                 [\r
3818                     ['lineWidth', 'width'],\r
3819                     ['stroke', 'color'],\r
3820                     ['opacity'],\r
3821                     ['shadowBlur'],\r
3822                     ['shadowOffsetX'],\r
3823                     ['shadowOffsetY'],\r
3824                     ['shadowColor']\r
3825                 ]\r
3826             );\r
3827             module.exports = {\r
3828                 getLineStyle: function (excludes) {\r
3829                     var style = getLineStyle.call(this, excludes);\r
3830                     var lineDash = this.getLineDash();\r
3831                     lineDash && (style.lineDash = lineDash);\r
3832                     return style;\r
3833                 },\r
3834 \r
3835                 getLineDash: function () {\r
3836                     var lineType = this.get('type');\r
3837                     return (lineType === 'solid' || lineType == null) ? null\r
3838                         : (lineType === 'dashed' ? [5, 5] : [1, 1]);\r
3839                 }\r
3840             };\r
3841 \r
3842 \r
3843 /***/ },\r
3844 /* 11 */\r
3845 /***/ function(module, exports, __webpack_require__) {\r
3846 \r
3847         // TODO Parse shadow style\r
3848         // TODO Only shallow path support\r
3849 \r
3850             var zrUtil = __webpack_require__(3);\r
3851 \r
3852             module.exports = function (properties) {\r
3853                 // Normalize\r
3854                 for (var i = 0; i < properties.length; i++) {\r
3855                     if (!properties[i][1]) {\r
3856                        properties[i][1] = properties[i][0];\r
3857                     }\r
3858                 }\r
3859                 return function (excludes) {\r
3860                     var style = {};\r
3861                     for (var i = 0; i < properties.length; i++) {\r
3862                         var propName = properties[i][1];\r
3863                         if (excludes && zrUtil.indexOf(excludes, propName) >= 0) {\r
3864                             continue;\r
3865                         }\r
3866                         var val = this.getShallow(propName);\r
3867                         if (val != null) {\r
3868                             style[properties[i][0]] = val;\r
3869                         }\r
3870                     }\r
3871                     return style;\r
3872                 };\r
3873             };\r
3874 \r
3875 \r
3876 /***/ },\r
3877 /* 12 */\r
3878 /***/ function(module, exports, __webpack_require__) {\r
3879 \r
3880         \r
3881             module.exports = {\r
3882                 getAreaStyle: __webpack_require__(11)(\r
3883                     [\r
3884                         ['fill', 'color'],\r
3885                         ['shadowBlur'],\r
3886                         ['shadowOffsetX'],\r
3887                         ['shadowOffsetY'],\r
3888                         ['opacity'],\r
3889                         ['shadowColor']\r
3890                     ]\r
3891                 )\r
3892             };\r
3893 \r
3894 \r
3895 /***/ },\r
3896 /* 13 */\r
3897 /***/ function(module, exports, __webpack_require__) {\r
3898 \r
3899         \r
3900 \r
3901             var textContain = __webpack_require__(14);\r
3902 \r
3903             function getShallow(model, path) {\r
3904                 return model && model.getShallow(path);\r
3905             }\r
3906 \r
3907             module.exports = {\r
3908                 /**\r
3909                  * Get color property or get color from option.textStyle.color\r
3910                  * @return {string}\r
3911                  */\r
3912                 getTextColor: function () {\r
3913                     var ecModel = this.ecModel;\r
3914                     return this.getShallow('color')\r
3915                         || (ecModel && ecModel.get('textStyle.color'));\r
3916                 },\r
3917 \r
3918                 /**\r
3919                  * Create font string from fontStyle, fontWeight, fontSize, fontFamily\r
3920                  * @return {string}\r
3921                  */\r
3922                 getFont: function () {\r
3923                     var ecModel = this.ecModel;\r
3924                     var gTextStyleModel = ecModel && ecModel.getModel('textStyle');\r
3925                     return [\r
3926                         // FIXME in node-canvas fontWeight is before fontStyle\r
3927                         this.getShallow('fontStyle') || getShallow(gTextStyleModel, 'fontStyle'),\r
3928                         this.getShallow('fontWeight') || getShallow(gTextStyleModel, 'fontWeight'),\r
3929                         (this.getShallow('fontSize') || getShallow(gTextStyleModel, 'fontSize') || 12) + 'px',\r
3930                         this.getShallow('fontFamily') || getShallow(gTextStyleModel, 'fontFamily') || 'sans-serif'\r
3931                     ].join(' ');\r
3932                 },\r
3933 \r
3934                 getTextRect: function (text) {\r
3935                     var textStyle = this.get('textStyle') || {};\r
3936                     return textContain.getBoundingRect(\r
3937                         text,\r
3938                         this.getFont(),\r
3939                         textStyle.align,\r
3940                         textStyle.baseline\r
3941                     );\r
3942                 },\r
3943 \r
3944                 ellipsis: function (text, containerWidth, options) {\r
3945                     return textContain.ellipsis(\r
3946                         text, this.getFont(), containerWidth, options\r
3947                     );\r
3948                 }\r
3949             };\r
3950 \r
3951 \r
3952 /***/ },\r
3953 /* 14 */\r
3954 /***/ function(module, exports, __webpack_require__) {\r
3955 \r
3956         \r
3957 \r
3958             var textWidthCache = {};\r
3959             var textWidthCacheCounter = 0;\r
3960             var TEXT_CACHE_MAX = 5000;\r
3961 \r
3962             var util = __webpack_require__(3);\r
3963             var BoundingRect = __webpack_require__(15);\r
3964 \r
3965             function getTextWidth(text, textFont) {\r
3966                 var key = text + ':' + textFont;\r
3967                 if (textWidthCache[key]) {\r
3968                     return textWidthCache[key];\r
3969                 }\r
3970 \r
3971                 var textLines = (text + '').split('\n');\r
3972                 var width = 0;\r
3973 \r
3974                 for (var i = 0, l = textLines.length; i < l; i++) {\r
3975                     // measureText 可以被覆盖以兼容不支持 Canvas 的环境\r
3976                     width =  Math.max(textContain.measureText(textLines[i], textFont).width, width);\r
3977                 }\r
3978 \r
3979                 if (textWidthCacheCounter > TEXT_CACHE_MAX) {\r
3980                     textWidthCacheCounter = 0;\r
3981                     textWidthCache = {};\r
3982                 }\r
3983                 textWidthCacheCounter++;\r
3984                 textWidthCache[key] = width;\r
3985 \r
3986                 return width;\r
3987             }\r
3988 \r
3989             function getTextRect(text, textFont, textAlign, textBaseline) {\r
3990                 var textLineLen = ((text || '') + '').split('\n').length;\r
3991 \r
3992                 var width = getTextWidth(text, textFont);\r
3993                 // FIXME 高度计算比较粗暴\r
3994                 var lineHeight = getTextWidth('国', textFont);\r
3995                 var height = textLineLen * lineHeight;\r
3996 \r
3997                 var rect = new BoundingRect(0, 0, width, height);\r
3998                 // Text has a special line height property\r
3999                 rect.lineHeight = lineHeight;\r
4000 \r
4001                 switch (textBaseline) {\r
4002                     case 'bottom':\r
4003                     case 'alphabetic':\r
4004                         rect.y -= lineHeight;\r
4005                         break;\r
4006                     case 'middle':\r
4007                         rect.y -= lineHeight / 2;\r
4008                         break;\r
4009                     // case 'hanging':\r
4010                     // case 'top':\r
4011                 }\r
4012 \r
4013                 // FIXME Right to left language\r
4014                 switch (textAlign) {\r
4015                     case 'end':\r
4016                     case 'right':\r
4017                         rect.x -= rect.width;\r
4018                         break;\r
4019                     case 'center':\r
4020                         rect.x -= rect.width / 2;\r
4021                         break;\r
4022                     // case 'start':\r
4023                     // case 'left':\r
4024                 }\r
4025 \r
4026                 return rect;\r
4027             }\r
4028 \r
4029             function adjustTextPositionOnRect(textPosition, rect, textRect, distance) {\r
4030 \r
4031                 var x = rect.x;\r
4032                 var y = rect.y;\r
4033 \r
4034                 var height = rect.height;\r
4035                 var width = rect.width;\r
4036 \r
4037                 var textHeight = textRect.height;\r
4038 \r
4039                 var halfHeight = height / 2 - textHeight / 2;\r
4040 \r
4041                 var textAlign = 'left';\r
4042 \r
4043                 switch (textPosition) {\r
4044                     case 'left':\r
4045                         x -= distance;\r
4046                         y += halfHeight;\r
4047                         textAlign = 'right';\r
4048                         break;\r
4049                     case 'right':\r
4050                         x += distance + width;\r
4051                         y += halfHeight;\r
4052                         textAlign = 'left';\r
4053                         break;\r
4054                     case 'top':\r
4055                         x += width / 2;\r
4056                         y -= distance + textHeight;\r
4057                         textAlign = 'center';\r
4058                         break;\r
4059                     case 'bottom':\r
4060                         x += width / 2;\r
4061                         y += height + distance;\r
4062                         textAlign = 'center';\r
4063                         break;\r
4064                     case 'inside':\r
4065                         x += width / 2;\r
4066                         y += halfHeight;\r
4067                         textAlign = 'center';\r
4068                         break;\r
4069                     case 'insideLeft':\r
4070                         x += distance;\r
4071                         y += halfHeight;\r
4072                         textAlign = 'left';\r
4073                         break;\r
4074                     case 'insideRight':\r
4075                         x += width - distance;\r
4076                         y += halfHeight;\r
4077                         textAlign = 'right';\r
4078                         break;\r
4079                     case 'insideTop':\r
4080                         x += width / 2;\r
4081                         y += distance;\r
4082                         textAlign = 'center';\r
4083                         break;\r
4084                     case 'insideBottom':\r
4085                         x += width / 2;\r
4086                         y += height - textHeight - distance;\r
4087                         textAlign = 'center';\r
4088                         break;\r
4089                     case 'insideTopLeft':\r
4090                         x += distance;\r
4091                         y += distance;\r
4092                         textAlign = 'left';\r
4093                         break;\r
4094                     case 'insideTopRight':\r
4095                         x += width - distance;\r
4096                         y += distance;\r
4097                         textAlign = 'right';\r
4098                         break;\r
4099                     case 'insideBottomLeft':\r
4100                         x += distance;\r
4101                         y += height - textHeight - distance;\r
4102                         break;\r
4103                     case 'insideBottomRight':\r
4104                         x += width - distance;\r
4105                         y += height - textHeight - distance;\r
4106                         textAlign = 'right';\r
4107                         break;\r
4108                 }\r
4109 \r
4110                 return {\r
4111                     x: x,\r
4112                     y: y,\r
4113                     textAlign: textAlign,\r
4114                     textBaseline: 'top'\r
4115                 };\r
4116             }\r
4117 \r
4118             /**\r
4119              * Show ellipsis if overflow.\r
4120              *\r
4121              * @param  {string} text\r
4122              * @param  {string} textFont\r
4123              * @param  {string} containerWidth\r
4124              * @param  {Object} [options]\r
4125              * @param  {number} [options.ellipsis='...']\r
4126              * @param  {number} [options.maxIterations=3]\r
4127              * @param  {number} [options.minCharacters=3]\r
4128              * @return {string}\r
4129              */\r
4130             function textEllipsis(text, textFont, containerWidth, options) {\r
4131                 if (!containerWidth) {\r
4132                     return '';\r
4133                 }\r
4134 \r
4135                 options = util.defaults({\r
4136                     ellipsis: '...',\r
4137                     minCharacters: 3,\r
4138                     maxIterations: 3,\r
4139                     cnCharWidth: getTextWidth('国', textFont),\r
4140                     // FIXME\r
4141                     // 未考虑非等宽字体\r
4142                     ascCharWidth: getTextWidth('a', textFont)\r
4143                 }, options, true);\r
4144 \r
4145                 containerWidth -= getTextWidth(options.ellipsis);\r
4146 \r
4147                 var textLines = (text + '').split('\n');\r
4148 \r
4149                 for (var i = 0, len = textLines.length; i < len; i++) {\r
4150                     textLines[i] = textLineTruncate(\r
4151                         textLines[i], textFont, containerWidth, options\r
4152                     );\r
4153                 }\r
4154 \r
4155                 return textLines.join('\n');\r
4156             }\r
4157 \r
4158             function textLineTruncate(text, textFont, containerWidth, options) {\r
4159                 // FIXME\r
4160                 // 粗糙得写的,尚未考虑性能和各种语言、字体的效果。\r
4161                 for (var i = 0;; i++) {\r
4162                     var lineWidth = getTextWidth(text, textFont);\r
4163 \r
4164                     if (lineWidth < containerWidth || i >= options.maxIterations) {\r
4165                         text += options.ellipsis;\r
4166                         break;\r
4167                     }\r
4168 \r
4169                     var subLength = i === 0\r
4170                         ? estimateLength(text, containerWidth, options)\r
4171                         : Math.floor(text.length * containerWidth / lineWidth);\r
4172 \r
4173                     if (subLength < options.minCharacters) {\r
4174                         text = '';\r
4175                         break;\r
4176                     }\r
4177 \r
4178                     text = text.substr(0, subLength);\r
4179                 }\r
4180 \r
4181                 return text;\r
4182             }\r
4183 \r
4184             function estimateLength(text, containerWidth, options) {\r
4185                 var width = 0;\r
4186                 var i = 0;\r
4187                 for (var len = text.length; i < len && width < containerWidth; i++) {\r
4188                     var charCode = text.charCodeAt(i);\r
4189                     width += (0 <= charCode && charCode <= 127)\r
4190                         ? options.ascCharWidth : options.cnCharWidth;\r
4191                 }\r
4192                 return i;\r
4193             }\r
4194 \r
4195             var textContain = {\r
4196 \r
4197                 getWidth: getTextWidth,\r
4198 \r
4199                 getBoundingRect: getTextRect,\r
4200 \r
4201                 adjustTextPositionOnRect: adjustTextPositionOnRect,\r
4202 \r
4203                 ellipsis: textEllipsis,\r
4204 \r
4205                 measureText: function (text, textFont) {\r
4206                     var ctx = util.getContext();\r
4207                     ctx.font = textFont;\r
4208                     return ctx.measureText(text);\r
4209                 }\r
4210             };\r
4211 \r
4212             module.exports = textContain;\r
4213 \r
4214 \r
4215 /***/ },\r
4216 /* 15 */\r
4217 /***/ function(module, exports, __webpack_require__) {\r
4218 \r
4219         'use strict';\r
4220         /**\r
4221          * @module echarts/core/BoundingRect\r
4222          */\r
4223 \r
4224 \r
4225             var vec2 = __webpack_require__(16);\r
4226             var matrix = __webpack_require__(17);\r
4227 \r
4228             var v2ApplyTransform = vec2.applyTransform;\r
4229             var mathMin = Math.min;\r
4230             var mathAbs = Math.abs;\r
4231             var mathMax = Math.max;\r
4232             /**\r
4233              * @alias module:echarts/core/BoundingRect\r
4234              */\r
4235             function BoundingRect(x, y, width, height) {\r
4236                 /**\r
4237                  * @type {number}\r
4238                  */\r
4239                 this.x = x;\r
4240                 /**\r
4241                  * @type {number}\r
4242                  */\r
4243                 this.y = y;\r
4244                 /**\r
4245                  * @type {number}\r
4246                  */\r
4247                 this.width = width;\r
4248                 /**\r
4249                  * @type {number}\r
4250                  */\r
4251                 this.height = height;\r
4252             }\r
4253 \r
4254             BoundingRect.prototype = {\r
4255 \r
4256                 constructor: BoundingRect,\r
4257 \r
4258                 /**\r
4259                  * @param {module:echarts/core/BoundingRect} other\r
4260                  */\r
4261                 union: function (other) {\r
4262                     var x = mathMin(other.x, this.x);\r
4263                     var y = mathMin(other.y, this.y);\r
4264 \r
4265                     this.width = mathMax(\r
4266                             other.x + other.width,\r
4267                             this.x + this.width\r
4268                         ) - x;\r
4269                     this.height = mathMax(\r
4270                             other.y + other.height,\r
4271                             this.y + this.height\r
4272                         ) - y;\r
4273                     this.x = x;\r
4274                     this.y = y;\r
4275                 },\r
4276 \r
4277                 /**\r
4278                  * @param {Array.<number>} m\r
4279                  * @methods\r
4280                  */\r
4281                 applyTransform: (function () {\r
4282                     var min = [];\r
4283                     var max = [];\r
4284                     return function (m) {\r
4285                         // In case usage like this\r
4286                         // el.getBoundingRect().applyTransform(el.transform)\r
4287                         // And element has no transform\r
4288                         if (!m) {\r
4289                             return;\r
4290                         }\r
4291                         min[0] = this.x;\r
4292                         min[1] = this.y;\r
4293                         max[0] = this.x + this.width;\r
4294                         max[1] = this.y + this.height;\r
4295 \r
4296                         v2ApplyTransform(min, min, m);\r
4297                         v2ApplyTransform(max, max, m);\r
4298 \r
4299                         this.x = mathMin(min[0], max[0]);\r
4300                         this.y = mathMin(min[1], max[1]);\r
4301                         this.width = mathAbs(max[0] - min[0]);\r
4302                         this.height = mathAbs(max[1] - min[1]);\r
4303                     };\r
4304                 })(),\r
4305 \r
4306                 /**\r
4307                  * Calculate matrix of transforming from self to target rect\r
4308                  * @param  {module:zrender/core/BoundingRect} b\r
4309                  * @return {Array.<number>}\r
4310                  */\r
4311                 calculateTransform: function (b) {\r
4312                     var a = this;\r
4313                     var sx = b.width / a.width;\r
4314                     var sy = b.height / a.height;\r
4315 \r
4316                     var m = matrix.create();\r
4317 \r
4318                     // 矩阵右乘\r
4319                     matrix.translate(m, m, [-a.x, -a.y]);\r
4320                     matrix.scale(m, m, [sx, sy]);\r
4321                     matrix.translate(m, m, [b.x, b.y]);\r
4322 \r
4323                     return m;\r
4324                 },\r
4325 \r
4326                 /**\r
4327                  * @param {(module:echarts/core/BoundingRect|Object)} b\r
4328                  * @return {boolean}\r
4329                  */\r
4330                 intersect: function (b) {\r
4331                     var a = this;\r
4332                     var ax0 = a.x;\r
4333                     var ax1 = a.x + a.width;\r
4334                     var ay0 = a.y;\r
4335                     var ay1 = a.y + a.height;\r
4336 \r
4337                     var bx0 = b.x;\r
4338                     var bx1 = b.x + b.width;\r
4339                     var by0 = b.y;\r
4340                     var by1 = b.y + b.height;\r
4341 \r
4342                     return ! (ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);\r
4343                 },\r
4344 \r
4345                 contain: function (x, y) {\r
4346                     var rect = this;\r
4347                     return x >= rect.x\r
4348                         && x <= (rect.x + rect.width)\r
4349                         && y >= rect.y\r
4350                         && y <= (rect.y + rect.height);\r
4351                 },\r
4352 \r
4353                 /**\r
4354                  * @return {module:echarts/core/BoundingRect}\r
4355                  */\r
4356                 clone: function () {\r
4357                     return new BoundingRect(this.x, this.y, this.width, this.height);\r
4358                 },\r
4359 \r
4360                 /**\r
4361                  * Copy from another rect\r
4362                  */\r
4363                 copy: function (other) {\r
4364                     this.x = other.x;\r
4365                     this.y = other.y;\r
4366                     this.width = other.width;\r
4367                     this.height = other.height;\r
4368                 }\r
4369             };\r
4370 \r
4371             module.exports = BoundingRect;\r
4372 \r
4373 \r
4374 /***/ },\r
4375 /* 16 */\r
4376 /***/ function(module, exports) {\r
4377 \r
4378         \r
4379             var ArrayCtor = typeof Float32Array === 'undefined'\r
4380                 ? Array\r
4381                 : Float32Array;\r
4382 \r
4383             /**\r
4384              * @typedef {Float32Array|Array.<number>} Vector2\r
4385              */\r
4386             /**\r
4387              * 二维向量类\r
4388              * @exports zrender/tool/vector\r
4389              */\r
4390             var vector = {\r
4391                 /**\r
4392                  * 创建一个向量\r
4393                  * @param {number} [x=0]\r
4394                  * @param {number} [y=0]\r
4395                  * @return {Vector2}\r
4396                  */\r
4397                 create: function (x, y) {\r
4398                     var out = new ArrayCtor(2);\r
4399                     out[0] = x || 0;\r
4400                     out[1] = y || 0;\r
4401                     return out;\r
4402                 },\r
4403 \r
4404                 /**\r
4405                  * 复制向量数据\r
4406                  * @param {Vector2} out\r
4407                  * @param {Vector2} v\r
4408                  * @return {Vector2}\r
4409                  */\r
4410                 copy: function (out, v) {\r
4411                     out[0] = v[0];\r
4412                     out[1] = v[1];\r
4413                     return out;\r
4414                 },\r
4415 \r
4416                 /**\r
4417                  * 克隆一个向量\r
4418                  * @param {Vector2} v\r
4419                  * @return {Vector2}\r
4420                  */\r
4421                 clone: function (v) {\r
4422                     var out = new ArrayCtor(2);\r
4423                     out[0] = v[0];\r
4424                     out[1] = v[1];\r
4425                     return out;\r
4426                 },\r
4427 \r
4428                 /**\r
4429                  * 设置向量的两个项\r
4430                  * @param {Vector2} out\r
4431                  * @param {number} a\r
4432                  * @param {number} b\r
4433                  * @return {Vector2} 结果\r
4434                  */\r
4435                 set: function (out, a, b) {\r
4436                     out[0] = a;\r
4437                     out[1] = b;\r
4438                     return out;\r
4439                 },\r
4440 \r
4441                 /**\r
4442                  * 向量相加\r
4443                  * @param {Vector2} out\r
4444                  * @param {Vector2} v1\r
4445                  * @param {Vector2} v2\r
4446                  */\r
4447                 add: function (out, v1, v2) {\r
4448                     out[0] = v1[0] + v2[0];\r
4449                     out[1] = v1[1] + v2[1];\r
4450                     return out;\r
4451                 },\r
4452 \r
4453                 /**\r
4454                  * 向量缩放后相加\r
4455                  * @param {Vector2} out\r
4456                  * @param {Vector2} v1\r
4457                  * @param {Vector2} v2\r
4458                  * @param {number} a\r
4459                  */\r
4460                 scaleAndAdd: function (out, v1, v2, a) {\r
4461                     out[0] = v1[0] + v2[0] * a;\r
4462                     out[1] = v1[1] + v2[1] * a;\r
4463                     return out;\r
4464                 },\r
4465 \r
4466                 /**\r
4467                  * 向量相减\r
4468                  * @param {Vector2} out\r
4469                  * @param {Vector2} v1\r
4470                  * @param {Vector2} v2\r
4471                  */\r
4472                 sub: function (out, v1, v2) {\r
4473                     out[0] = v1[0] - v2[0];\r
4474                     out[1] = v1[1] - v2[1];\r
4475                     return out;\r
4476                 },\r
4477 \r
4478                 /**\r
4479                  * 向量长度\r
4480                  * @param {Vector2} v\r
4481                  * @return {number}\r
4482                  */\r
4483                 len: function (v) {\r
4484                     return Math.sqrt(this.lenSquare(v));\r
4485                 },\r
4486 \r
4487                 /**\r
4488                  * 向量长度平方\r
4489                  * @param {Vector2} v\r
4490                  * @return {number}\r
4491                  */\r
4492                 lenSquare: function (v) {\r
4493                     return v[0] * v[0] + v[1] * v[1];\r
4494                 },\r
4495 \r
4496                 /**\r
4497                  * 向量乘法\r
4498                  * @param {Vector2} out\r
4499                  * @param {Vector2} v1\r
4500                  * @param {Vector2} v2\r
4501                  */\r
4502                 mul: function (out, v1, v2) {\r
4503                     out[0] = v1[0] * v2[0];\r
4504                     out[1] = v1[1] * v2[1];\r
4505                     return out;\r
4506                 },\r
4507 \r
4508                 /**\r
4509                  * 向量除法\r
4510                  * @param {Vector2} out\r
4511                  * @param {Vector2} v1\r
4512                  * @param {Vector2} v2\r
4513                  */\r
4514                 div: function (out, v1, v2) {\r
4515                     out[0] = v1[0] / v2[0];\r
4516                     out[1] = v1[1] / v2[1];\r
4517                     return out;\r
4518                 },\r
4519 \r
4520                 /**\r
4521                  * 向量点乘\r
4522                  * @param {Vector2} v1\r
4523                  * @param {Vector2} v2\r
4524                  * @return {number}\r
4525                  */\r
4526                 dot: function (v1, v2) {\r
4527                     return v1[0] * v2[0] + v1[1] * v2[1];\r
4528                 },\r
4529 \r
4530                 /**\r
4531                  * 向量缩放\r
4532                  * @param {Vector2} out\r
4533                  * @param {Vector2} v\r
4534                  * @param {number} s\r
4535                  */\r
4536                 scale: function (out, v, s) {\r
4537                     out[0] = v[0] * s;\r
4538                     out[1] = v[1] * s;\r
4539                     return out;\r
4540                 },\r
4541 \r
4542                 /**\r
4543                  * 向量归一化\r
4544                  * @param {Vector2} out\r
4545                  * @param {Vector2} v\r
4546                  */\r
4547                 normalize: function (out, v) {\r
4548                     var d = vector.len(v);\r
4549                     if (d === 0) {\r
4550                         out[0] = 0;\r
4551                         out[1] = 0;\r
4552                     }\r
4553                     else {\r
4554                         out[0] = v[0] / d;\r
4555                         out[1] = v[1] / d;\r
4556                     }\r
4557                     return out;\r
4558                 },\r
4559 \r
4560                 /**\r
4561                  * 计算向量间距离\r
4562                  * @param {Vector2} v1\r
4563                  * @param {Vector2} v2\r
4564                  * @return {number}\r
4565                  */\r
4566                 distance: function (v1, v2) {\r
4567                     return Math.sqrt(\r
4568                         (v1[0] - v2[0]) * (v1[0] - v2[0])\r
4569                         + (v1[1] - v2[1]) * (v1[1] - v2[1])\r
4570                     );\r
4571                 },\r
4572 \r
4573                 /**\r
4574                  * 向量距离平方\r
4575                  * @param {Vector2} v1\r
4576                  * @param {Vector2} v2\r
4577                  * @return {number}\r
4578                  */\r
4579                 distanceSquare: function (v1, v2) {\r
4580                     return (v1[0] - v2[0]) * (v1[0] - v2[0])\r
4581                         + (v1[1] - v2[1]) * (v1[1] - v2[1]);\r
4582                 },\r
4583 \r
4584                 /**\r
4585                  * 求负向量\r
4586                  * @param {Vector2} out\r
4587                  * @param {Vector2} v\r
4588                  */\r
4589                 negate: function (out, v) {\r
4590                     out[0] = -v[0];\r
4591                     out[1] = -v[1];\r
4592                     return out;\r
4593                 },\r
4594 \r
4595                 /**\r
4596                  * 插值两个点\r
4597                  * @param {Vector2} out\r
4598                  * @param {Vector2} v1\r
4599                  * @param {Vector2} v2\r
4600                  * @param {number} t\r
4601                  */\r
4602                 lerp: function (out, v1, v2, t) {\r
4603                     out[0] = v1[0] + t * (v2[0] - v1[0]);\r
4604                     out[1] = v1[1] + t * (v2[1] - v1[1]);\r
4605                     return out;\r
4606                 },\r
4607 \r
4608                 /**\r
4609                  * 矩阵左乘向量\r
4610                  * @param {Vector2} out\r
4611                  * @param {Vector2} v\r
4612                  * @param {Vector2} m\r
4613                  */\r
4614                 applyTransform: function (out, v, m) {\r
4615                     var x = v[0];\r
4616                     var y = v[1];\r
4617                     out[0] = m[0] * x + m[2] * y + m[4];\r
4618                     out[1] = m[1] * x + m[3] * y + m[5];\r
4619                     return out;\r
4620                 },\r
4621                 /**\r
4622                  * 求两个向量最小值\r
4623                  * @param  {Vector2} out\r
4624                  * @param  {Vector2} v1\r
4625                  * @param  {Vector2} v2\r
4626                  */\r
4627                 min: function (out, v1, v2) {\r
4628                     out[0] = Math.min(v1[0], v2[0]);\r
4629                     out[1] = Math.min(v1[1], v2[1]);\r
4630                     return out;\r
4631                 },\r
4632                 /**\r
4633                  * 求两个向量最大值\r
4634                  * @param  {Vector2} out\r
4635                  * @param  {Vector2} v1\r
4636                  * @param  {Vector2} v2\r
4637                  */\r
4638                 max: function (out, v1, v2) {\r
4639                     out[0] = Math.max(v1[0], v2[0]);\r
4640                     out[1] = Math.max(v1[1], v2[1]);\r
4641                     return out;\r
4642                 }\r
4643             };\r
4644 \r
4645             vector.length = vector.len;\r
4646             vector.lengthSquare = vector.lenSquare;\r
4647             vector.dist = vector.distance;\r
4648             vector.distSquare = vector.distanceSquare;\r
4649 \r
4650             module.exports = vector;\r
4651 \r
4652 \r
4653 \r
4654 /***/ },\r
4655 /* 17 */\r
4656 /***/ function(module, exports) {\r
4657 \r
4658         \r
4659             var ArrayCtor = typeof Float32Array === 'undefined'\r
4660                 ? Array\r
4661                 : Float32Array;\r
4662             /**\r
4663              * 3x2矩阵操作类\r
4664              * @exports zrender/tool/matrix\r
4665              */\r
4666             var matrix = {\r
4667                 /**\r
4668                  * 创建一个单位矩阵\r
4669                  * @return {Float32Array|Array.<number>}\r
4670                  */\r
4671                 create : function() {\r
4672                     var out = new ArrayCtor(6);\r
4673                     matrix.identity(out);\r
4674 \r
4675                     return out;\r
4676                 },\r
4677                 /**\r
4678                  * 设置矩阵为单位矩阵\r
4679                  * @param {Float32Array|Array.<number>} out\r
4680                  */\r
4681                 identity : function(out) {\r
4682                     out[0] = 1;\r
4683                     out[1] = 0;\r
4684                     out[2] = 0;\r
4685                     out[3] = 1;\r
4686                     out[4] = 0;\r
4687                     out[5] = 0;\r
4688                     return out;\r
4689                 },\r
4690                 /**\r
4691                  * 复制矩阵\r
4692                  * @param {Float32Array|Array.<number>} out\r
4693                  * @param {Float32Array|Array.<number>} m\r
4694                  */\r
4695                 copy: function(out, m) {\r
4696                     out[0] = m[0];\r
4697                     out[1] = m[1];\r
4698                     out[2] = m[2];\r
4699                     out[3] = m[3];\r
4700                     out[4] = m[4];\r
4701                     out[5] = m[5];\r
4702                     return out;\r
4703                 },\r
4704                 /**\r
4705                  * 矩阵相乘\r
4706                  * @param {Float32Array|Array.<number>} out\r
4707                  * @param {Float32Array|Array.<number>} m1\r
4708                  * @param {Float32Array|Array.<number>} m2\r
4709                  */\r
4710                 mul : function (out, m1, m2) {\r
4711                     // Consider matrix.mul(m, m2, m);\r
4712                     // where out is the same as m2.\r
4713                     // So use temp variable to escape error.\r
4714                     var out0 = m1[0] * m2[0] + m1[2] * m2[1];\r
4715                     var out1 = m1[1] * m2[0] + m1[3] * m2[1];\r
4716                     var out2 = m1[0] * m2[2] + m1[2] * m2[3];\r
4717                     var out3 = m1[1] * m2[2] + m1[3] * m2[3];\r
4718                     var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];\r
4719                     var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];\r
4720                     out[0] = out0;\r
4721                     out[1] = out1;\r
4722                     out[2] = out2;\r
4723                     out[3] = out3;\r
4724                     out[4] = out4;\r
4725                     out[5] = out5;\r
4726                     return out;\r
4727                 },\r
4728                 /**\r
4729                  * 平移变换\r
4730                  * @param {Float32Array|Array.<number>} out\r
4731                  * @param {Float32Array|Array.<number>} a\r
4732                  * @param {Float32Array|Array.<number>} v\r
4733                  */\r
4734                 translate : function(out, a, v) {\r
4735                     out[0] = a[0];\r
4736                     out[1] = a[1];\r
4737                     out[2] = a[2];\r
4738                     out[3] = a[3];\r
4739                     out[4] = a[4] + v[0];\r
4740                     out[5] = a[5] + v[1];\r
4741                     return out;\r
4742                 },\r
4743                 /**\r
4744                  * 旋转变换\r
4745                  * @param {Float32Array|Array.<number>} out\r
4746                  * @param {Float32Array|Array.<number>} a\r
4747                  * @param {number} rad\r
4748                  */\r
4749                 rotate : function(out, a, rad) {\r
4750                     var aa = a[0];\r
4751                     var ac = a[2];\r
4752                     var atx = a[4];\r
4753                     var ab = a[1];\r
4754                     var ad = a[3];\r
4755                     var aty = a[5];\r
4756                     var st = Math.sin(rad);\r
4757                     var ct = Math.cos(rad);\r
4758 \r
4759                     out[0] = aa * ct + ab * st;\r
4760                     out[1] = -aa * st + ab * ct;\r
4761                     out[2] = ac * ct + ad * st;\r
4762                     out[3] = -ac * st + ct * ad;\r
4763                     out[4] = ct * atx + st * aty;\r
4764                     out[5] = ct * aty - st * atx;\r
4765                     return out;\r
4766                 },\r
4767                 /**\r
4768                  * 缩放变换\r
4769                  * @param {Float32Array|Array.<number>} out\r
4770                  * @param {Float32Array|Array.<number>} a\r
4771                  * @param {Float32Array|Array.<number>} v\r
4772                  */\r
4773                 scale : function(out, a, v) {\r
4774                     var vx = v[0];\r
4775                     var vy = v[1];\r
4776                     out[0] = a[0] * vx;\r
4777                     out[1] = a[1] * vy;\r
4778                     out[2] = a[2] * vx;\r
4779                     out[3] = a[3] * vy;\r
4780                     out[4] = a[4] * vx;\r
4781                     out[5] = a[5] * vy;\r
4782                     return out;\r
4783                 },\r
4784                 /**\r
4785                  * 求逆矩阵\r
4786                  * @param {Float32Array|Array.<number>} out\r
4787                  * @param {Float32Array|Array.<number>} a\r
4788                  */\r
4789                 invert : function(out, a) {\r
4790 \r
4791                     var aa = a[0];\r
4792                     var ac = a[2];\r
4793                     var atx = a[4];\r
4794                     var ab = a[1];\r
4795                     var ad = a[3];\r
4796                     var aty = a[5];\r
4797 \r
4798                     var det = aa * ad - ab * ac;\r
4799                     if (!det) {\r
4800                         return null;\r
4801                     }\r
4802                     det = 1.0 / det;\r
4803 \r
4804                     out[0] = ad * det;\r
4805                     out[1] = -ab * det;\r
4806                     out[2] = -ac * det;\r
4807                     out[3] = aa * det;\r
4808                     out[4] = (ac * aty - ad * atx) * det;\r
4809                     out[5] = (ab * atx - aa * aty) * det;\r
4810                     return out;\r
4811                 }\r
4812             };\r
4813 \r
4814             module.exports = matrix;\r
4815 \r
4816 \r
4817 \r
4818 /***/ },\r
4819 /* 18 */\r
4820 /***/ function(module, exports, __webpack_require__) {\r
4821 \r
4822         \r
4823             module.exports = {\r
4824                 getItemStyle: __webpack_require__(11)(\r
4825                     [\r
4826                         ['fill', 'color'],\r
4827                         ['stroke', 'borderColor'],\r
4828                         ['lineWidth', 'borderWidth'],\r
4829                         ['opacity'],\r
4830                         ['shadowBlur'],\r
4831                         ['shadowOffsetX'],\r
4832                         ['shadowOffsetY'],\r
4833                         ['shadowColor']\r
4834                     ]\r
4835                 )\r
4836             };\r
4837 \r
4838 \r
4839 /***/ },\r
4840 /* 19 */\r
4841 /***/ function(module, exports, __webpack_require__) {\r
4842 \r
4843         /**\r
4844          * Component model\r
4845          *\r
4846          * @module echarts/model/Component\r
4847          */\r
4848 \r
4849 \r
4850             var Model = __webpack_require__(8);\r
4851             var zrUtil = __webpack_require__(3);\r
4852             var arrayPush = Array.prototype.push;\r
4853             var componentUtil = __webpack_require__(20);\r
4854             var clazzUtil = __webpack_require__(9);\r
4855             var layout = __webpack_require__(21);\r
4856 \r
4857             /**\r
4858              * @alias module:echarts/model/Component\r
4859              * @constructor\r
4860              * @param {Object} option\r
4861              * @param {module:echarts/model/Model} parentModel\r
4862              * @param {module:echarts/model/Model} ecModel\r
4863              */\r
4864             var ComponentModel = Model.extend({\r
4865 \r
4866                 type: 'component',\r
4867 \r
4868                 /**\r
4869                  * @readOnly\r
4870                  * @type {string}\r
4871                  */\r
4872                 id: '',\r
4873 \r
4874                 /**\r
4875                  * @readOnly\r
4876                  */\r
4877                 name: '',\r
4878 \r
4879                 /**\r
4880                  * @readOnly\r
4881                  * @type {string}\r
4882                  */\r
4883                 mainType: '',\r
4884 \r
4885                 /**\r
4886                  * @readOnly\r
4887                  * @type {string}\r
4888                  */\r
4889                 subType: '',\r
4890 \r
4891                 /**\r
4892                  * @readOnly\r
4893                  * @type {number}\r
4894                  */\r
4895                 componentIndex: 0,\r
4896 \r
4897                 /**\r
4898                  * @type {Object}\r
4899                  * @protected\r
4900                  */\r
4901                 defaultOption: null,\r
4902 \r
4903                 /**\r
4904                  * @type {module:echarts/model/Global}\r
4905                  * @readOnly\r
4906                  */\r
4907                 ecModel: null,\r
4908 \r
4909                 /**\r
4910                  * key: componentType\r
4911                  * value:  Component model list, can not be null.\r
4912                  * @type {Object.<string, Array.<module:echarts/model/Model>>}\r
4913                  * @readOnly\r
4914                  */\r
4915                 dependentModels: [],\r
4916 \r
4917                 /**\r
4918                  * @type {string}\r
4919                  * @readOnly\r
4920                  */\r
4921                 uid: null,\r
4922 \r
4923                 /**\r
4924                  * Support merge layout params.\r
4925                  * Only support 'box' now (left/right/top/bottom/width/height).\r
4926                  * @type {string|Object} Object can be {ignoreSize: true}\r
4927                  * @readOnly\r
4928                  */\r
4929                 layoutMode: null,\r
4930 \r
4931 \r
4932                 init: function (option, parentModel, ecModel, extraOpt) {\r
4933                     this.mergeDefaultAndTheme(this.option, this.ecModel);\r
4934                 },\r
4935 \r
4936                 mergeDefaultAndTheme: function (option, ecModel) {\r
4937                     var layoutMode = this.layoutMode;\r
4938                     var inputPositionParams = layoutMode\r
4939                         ? layout.getLayoutParams(option) : {};\r
4940 \r
4941                     var themeModel = ecModel.getTheme();\r
4942                     zrUtil.merge(option, themeModel.get(this.mainType));\r
4943                     zrUtil.merge(option, this.getDefaultOption());\r
4944 \r
4945                     if (layoutMode) {\r
4946                         layout.mergeLayoutParam(option, inputPositionParams, layoutMode);\r
4947                     }\r
4948                 },\r
4949 \r
4950                 mergeOption: function (option) {\r
4951                     zrUtil.merge(this.option, option, true);\r
4952 \r
4953                     var layoutMode = this.layoutMode;\r
4954                     if (layoutMode) {\r
4955                         layout.mergeLayoutParam(this.option, option, layoutMode);\r
4956                     }\r
4957                 },\r
4958 \r
4959                 // Hooker after init or mergeOption\r
4960                 optionUpdated: function (ecModel) {},\r
4961 \r
4962                 getDefaultOption: function () {\r
4963                     if (!this.hasOwnProperty('__defaultOption')) {\r
4964                         var optList = [];\r
4965                         var Class = this.constructor;\r
4966                         while (Class) {\r
4967                             var opt = Class.prototype.defaultOption;\r
4968                             opt && optList.push(opt);\r
4969                             Class = Class.superClass;\r
4970                         }\r
4971 \r
4972                         var defaultOption = {};\r
4973                         for (var i = optList.length - 1; i >= 0; i--) {\r
4974                             defaultOption = zrUtil.merge(defaultOption, optList[i], true);\r
4975                         }\r
4976                         this.__defaultOption = defaultOption;\r
4977                     }\r
4978                     return this.__defaultOption;\r
4979                 }\r
4980 \r
4981             });\r
4982 \r
4983             // Reset ComponentModel.extend, add preConstruct.\r
4984             clazzUtil.enableClassExtend(\r
4985                 ComponentModel,\r
4986                 function (option, parentModel, ecModel, extraOpt) {\r
4987                     // Set dependentModels, componentIndex, name, id, mainType, subType.\r
4988                     zrUtil.extend(this, extraOpt);\r
4989 \r
4990                     this.uid = componentUtil.getUID('componentModel');\r
4991 \r
4992                     // this.setReadOnly([\r
4993                     //     'type', 'id', 'uid', 'name', 'mainType', 'subType',\r
4994                     //     'dependentModels', 'componentIndex'\r
4995                     // ]);\r
4996                 }\r
4997             );\r
4998 \r
4999             // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.\r
5000             clazzUtil.enableClassManagement(\r
5001                 ComponentModel, {registerWhenExtend: true}\r
5002             );\r
5003             componentUtil.enableSubTypeDefaulter(ComponentModel);\r
5004 \r
5005             // Add capability of ComponentModel.topologicalTravel.\r
5006             componentUtil.enableTopologicalTravel(ComponentModel, getDependencies);\r
5007 \r
5008             function getDependencies(componentType) {\r
5009                 var deps = [];\r
5010                 zrUtil.each(ComponentModel.getClassesByMainType(componentType), function (Clazz) {\r
5011                     arrayPush.apply(deps, Clazz.prototype.dependencies || []);\r
5012                 });\r
5013                 // Ensure main type\r
5014                 return zrUtil.map(deps, function (type) {\r
5015                     return clazzUtil.parseClassType(type).main;\r
5016                 });\r
5017             }\r
5018 \r
5019             zrUtil.mixin(ComponentModel, __webpack_require__(22));\r
5020 \r
5021             module.exports = ComponentModel;\r
5022 \r
5023 \r
5024 /***/ },\r
5025 /* 20 */\r
5026 /***/ function(module, exports, __webpack_require__) {\r
5027 \r
5028         \r
5029 \r
5030             var zrUtil = __webpack_require__(3);\r
5031             var clazz = __webpack_require__(9);\r
5032 \r
5033             var parseClassType = clazz.parseClassType;\r
5034 \r
5035             var base = 0;\r
5036 \r
5037             var componentUtil = {};\r
5038 \r
5039             var DELIMITER = '_';\r
5040 \r
5041             /**\r
5042              * @public\r
5043              * @param {string} type\r
5044              * @return {string}\r
5045              */\r
5046             componentUtil.getUID = function (type) {\r
5047                 // Considering the case of crossing js context,\r
5048                 // use Math.random to make id as unique as possible.\r
5049                 return [(type || ''), base++, Math.random()].join(DELIMITER);\r
5050             };\r
5051 \r
5052             /**\r
5053              * @inner\r
5054              */\r
5055             componentUtil.enableSubTypeDefaulter = function (entity) {\r
5056 \r
5057                 var subTypeDefaulters = {};\r
5058 \r
5059                 entity.registerSubTypeDefaulter = function (componentType, defaulter) {\r
5060                     componentType = parseClassType(componentType);\r
5061                     subTypeDefaulters[componentType.main] = defaulter;\r
5062                 };\r
5063 \r
5064                 entity.determineSubType = function (componentType, option) {\r
5065                     var type = option.type;\r
5066                     if (!type) {\r
5067                         var componentTypeMain = parseClassType(componentType).main;\r
5068                         if (entity.hasSubTypes(componentType) && subTypeDefaulters[componentTypeMain]) {\r
5069                             type = subTypeDefaulters[componentTypeMain](option);\r
5070                         }\r
5071                     }\r
5072                     return type;\r
5073                 };\r
5074 \r
5075                 return entity;\r
5076             };\r
5077 \r
5078             /**\r
5079              * Topological travel on Activity Network (Activity On Vertices).\r
5080              * Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis'].\r
5081              *\r
5082              * If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology.\r
5083              *\r
5084              * If there is circle dependencey, Error will be thrown.\r
5085              *\r
5086              */\r
5087             componentUtil.enableTopologicalTravel = function (entity, dependencyGetter) {\r
5088 \r
5089                 /**\r
5090                  * @public\r
5091                  * @param {Array.<string>} targetNameList Target Component type list.\r
5092                  *                                           Can be ['aa', 'bb', 'aa.xx']\r
5093                  * @param {Array.<string>} fullNameList By which we can build dependency graph.\r
5094                  * @param {Function} callback Params: componentType, dependencies.\r
5095                  * @param {Object} context Scope of callback.\r
5096                  */\r
5097                 entity.topologicalTravel = function (targetNameList, fullNameList, callback, context) {\r
5098                     if (!targetNameList.length) {\r
5099                         return;\r
5100                     }\r
5101 \r
5102                     var result = makeDepndencyGraph(fullNameList);\r
5103                     var graph = result.graph;\r
5104                     var stack = result.noEntryList;\r
5105 \r
5106                     var targetNameSet = {};\r
5107                     zrUtil.each(targetNameList, function (name) {\r
5108                         targetNameSet[name] = true;\r
5109                     });\r
5110 \r
5111                     while (stack.length) {\r
5112                         var currComponentType = stack.pop();\r
5113                         var currVertex = graph[currComponentType];\r
5114                         var isInTargetNameSet = !!targetNameSet[currComponentType];\r
5115                         if (isInTargetNameSet) {\r
5116                             callback.call(context, currComponentType, currVertex.originalDeps.slice());\r
5117                             delete targetNameSet[currComponentType];\r
5118                         }\r
5119                         zrUtil.each(\r
5120                             currVertex.successor,\r
5121                             isInTargetNameSet ? removeEdgeAndAdd : removeEdge\r
5122                         );\r
5123                     }\r
5124 \r
5125                     zrUtil.each(targetNameSet, function () {\r
5126                         throw new Error('Circle dependency may exists');\r
5127                     });\r
5128 \r
5129                     function removeEdge(succComponentType) {\r
5130                         graph[succComponentType].entryCount--;\r
5131                         if (graph[succComponentType].entryCount === 0) {\r
5132                             stack.push(succComponentType);\r
5133                         }\r
5134                     }\r
5135 \r
5136                     // Consider this case: legend depends on series, and we call\r
5137                     // chart.setOption({series: [...]}), where only series is in option.\r
5138                     // If we do not have 'removeEdgeAndAdd', legendModel.mergeOption will\r
5139                     // not be called, but only sereis.mergeOption is called. Thus legend\r
5140                     // have no chance to update its local record about series (like which\r
5141                     // name of series is available in legend).\r
5142                     function removeEdgeAndAdd(succComponentType) {\r
5143                         targetNameSet[succComponentType] = true;\r
5144                         removeEdge(succComponentType);\r
5145                     }\r
5146                 };\r
5147 \r
5148                 /**\r
5149                  * DepndencyGraph: {Object}\r
5150                  * key: conponentType,\r
5151                  * value: {\r
5152                  *     successor: [conponentTypes...],\r
5153                  *     originalDeps: [conponentTypes...],\r
5154                  *     entryCount: {number}\r
5155                  * }\r
5156                  */\r
5157                 function makeDepndencyGraph(fullNameList) {\r
5158                     var graph = {};\r
5159                     var noEntryList = [];\r
5160 \r
5161                     zrUtil.each(fullNameList, function (name) {\r
5162 \r
5163                         var thisItem = createDependencyGraphItem(graph, name);\r
5164                         var originalDeps = thisItem.originalDeps = dependencyGetter(name);\r
5165 \r
5166                         var availableDeps = getAvailableDependencies(originalDeps, fullNameList);\r
5167                         thisItem.entryCount = availableDeps.length;\r
5168                         if (thisItem.entryCount === 0) {\r
5169                             noEntryList.push(name);\r
5170                         }\r
5171 \r
5172                         zrUtil.each(availableDeps, function (dependentName) {\r
5173                             if (zrUtil.indexOf(thisItem.predecessor, dependentName) < 0) {\r
5174                                 thisItem.predecessor.push(dependentName);\r
5175                             }\r
5176                             var thatItem = createDependencyGraphItem(graph, dependentName);\r
5177                             if (zrUtil.indexOf(thatItem.successor, dependentName) < 0) {\r
5178                                 thatItem.successor.push(name);\r
5179                             }\r
5180                         });\r
5181                     });\r
5182 \r
5183                     return {graph: graph, noEntryList: noEntryList};\r
5184                 }\r
5185 \r
5186                 function createDependencyGraphItem(graph, name) {\r
5187                     if (!graph[name]) {\r
5188                         graph[name] = {predecessor: [], successor: []};\r
5189                     }\r
5190                     return graph[name];\r
5191                 }\r
5192 \r
5193                 function getAvailableDependencies(originalDeps, fullNameList) {\r
5194                     var availableDeps = [];\r
5195                     zrUtil.each(originalDeps, function (dep) {\r
5196                         zrUtil.indexOf(fullNameList, dep) >= 0 && availableDeps.push(dep);\r
5197                     });\r
5198                     return availableDeps;\r
5199                 }\r
5200             };\r
5201 \r
5202             module.exports = componentUtil;\r
5203 \r
5204 \r
5205 /***/ },\r
5206 /* 21 */\r
5207 /***/ function(module, exports, __webpack_require__) {\r
5208 \r
5209         'use strict';\r
5210         // Layout helpers for each component positioning\r
5211 \r
5212 \r
5213             var zrUtil = __webpack_require__(3);\r
5214             var BoundingRect = __webpack_require__(15);\r
5215             var numberUtil = __webpack_require__(7);\r
5216             var formatUtil = __webpack_require__(6);\r
5217             var parsePercent = numberUtil.parsePercent;\r
5218             var each = zrUtil.each;\r
5219 \r
5220             var layout = {};\r
5221 \r
5222             var LOCATION_PARAMS = ['left', 'right', 'top', 'bottom', 'width', 'height'];\r
5223 \r
5224             function boxLayout(orient, group, gap, maxWidth, maxHeight) {\r
5225                 var x = 0;\r
5226                 var y = 0;\r
5227                 if (maxWidth == null) {\r
5228                     maxWidth = Infinity;\r
5229                 }\r
5230                 if (maxHeight == null) {\r
5231                     maxHeight = Infinity;\r
5232                 }\r
5233                 var currentLineMaxSize = 0;\r
5234                 group.eachChild(function (child, idx) {\r
5235                     var position = child.position;\r
5236                     var rect = child.getBoundingRect();\r
5237                     var nextChild = group.childAt(idx + 1);\r
5238                     var nextChildRect = nextChild && nextChild.getBoundingRect();\r
5239                     var nextX;\r
5240                     var nextY;\r
5241                     if (orient === 'horizontal') {\r
5242                         var moveX = rect.width + (nextChildRect ? (-nextChildRect.x + rect.x) : 0);\r
5243                         nextX = x + moveX;\r
5244                         // Wrap when width exceeds maxWidth or meet a `newline` group\r
5245                         if (nextX > maxWidth || child.newline) {\r
5246                             x = 0;\r
5247                             nextX = moveX;\r
5248                             y += currentLineMaxSize + gap;\r
5249                             currentLineMaxSize = rect.height;\r
5250                         }\r
5251                         else {\r
5252                             currentLineMaxSize = Math.max(currentLineMaxSize, rect.height);\r
5253                         }\r
5254                     }\r
5255                     else {\r
5256                         var moveY = rect.height + (nextChildRect ? (-nextChildRect.y + rect.y) : 0);\r
5257                         nextY = y + moveY;\r
5258                         // Wrap when width exceeds maxHeight or meet a `newline` group\r
5259                         if (nextY > maxHeight || child.newline) {\r
5260                             x += currentLineMaxSize + gap;\r
5261                             y = 0;\r
5262                             nextY = moveY;\r
5263                             currentLineMaxSize = rect.width;\r
5264                         }\r
5265                         else {\r
5266                             currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);\r
5267                         }\r
5268                     }\r
5269 \r
5270                     if (child.newline) {\r
5271                         return;\r
5272                     }\r
5273 \r
5274                     position[0] = x;\r
5275                     position[1] = y;\r
5276 \r
5277                     orient === 'horizontal'\r
5278                         ? (x = nextX + gap)\r
5279                         : (y = nextY + gap);\r
5280                 });\r
5281             }\r
5282 \r
5283             /**\r
5284              * VBox or HBox layouting\r
5285              * @param {string} orient\r
5286              * @param {module:zrender/container/Group} group\r
5287              * @param {number} gap\r
5288              * @param {number} [width=Infinity]\r
5289              * @param {number} [height=Infinity]\r
5290              */\r
5291             layout.box = boxLayout;\r
5292 \r
5293             /**\r
5294              * VBox layouting\r
5295              * @param {module:zrender/container/Group} group\r
5296              * @param {number} gap\r
5297              * @param {number} [width=Infinity]\r
5298              * @param {number} [height=Infinity]\r
5299              */\r
5300             layout.vbox = zrUtil.curry(boxLayout, 'vertical');\r
5301 \r
5302             /**\r
5303              * HBox layouting\r
5304              * @param {module:zrender/container/Group} group\r
5305              * @param {number} gap\r
5306              * @param {number} [width=Infinity]\r
5307              * @param {number} [height=Infinity]\r
5308              */\r
5309             layout.hbox = zrUtil.curry(boxLayout, 'horizontal');\r
5310 \r
5311             /**\r
5312              * If x or x2 is not specified or 'center' 'left' 'right',\r
5313              * the width would be as long as possible.\r
5314              * If y or y2 is not specified or 'middle' 'top' 'bottom',\r
5315              * the height would be as long as possible.\r
5316              *\r
5317              * @param {Object} positionInfo\r
5318              * @param {number|string} [positionInfo.x]\r
5319              * @param {number|string} [positionInfo.y]\r
5320              * @param {number|string} [positionInfo.x2]\r
5321              * @param {number|string} [positionInfo.y2]\r
5322              * @param {Object} containerRect\r
5323              * @param {string|number} margin\r
5324              * @return {Object} {width, height}\r
5325              */\r
5326             layout.getAvailableSize = function (positionInfo, containerRect, margin) {\r
5327                 var containerWidth = containerRect.width;\r
5328                 var containerHeight = containerRect.height;\r
5329 \r
5330                 var x = parsePercent(positionInfo.x, containerWidth);\r
5331                 var y = parsePercent(positionInfo.y, containerHeight);\r
5332                 var x2 = parsePercent(positionInfo.x2, containerWidth);\r
5333                 var y2 = parsePercent(positionInfo.y2, containerHeight);\r
5334 \r
5335                 (isNaN(x) || isNaN(parseFloat(positionInfo.x))) && (x = 0);\r
5336                 (isNaN(x2) || isNaN(parseFloat(positionInfo.x2))) && (x2 = containerWidth);\r
5337                 (isNaN(y) || isNaN(parseFloat(positionInfo.y))) && (y = 0);\r
5338                 (isNaN(y2) || isNaN(parseFloat(positionInfo.y2))) && (y2 = containerHeight);\r
5339 \r
5340                 margin = formatUtil.normalizeCssArray(margin || 0);\r
5341 \r
5342                 return {\r
5343                     width: Math.max(x2 - x - margin[1] - margin[3], 0),\r
5344                     height: Math.max(y2 - y - margin[0] - margin[2], 0)\r
5345                 };\r
5346             };\r
5347 \r
5348             /**\r
5349              * Parse position info.\r
5350              *\r
5351              * @param {Object} positionInfo\r
5352              * @param {number|string} [positionInfo.left]\r
5353              * @param {number|string} [positionInfo.top]\r
5354              * @param {number|string} [positionInfo.right]\r
5355              * @param {number|string} [positionInfo.bottom]\r
5356              * @param {number|string} [positionInfo.width]\r
5357              * @param {number|string} [positionInfo.height]\r
5358              * @param {number|string} [positionInfo.aspect] Aspect is width / height\r
5359              * @param {Object} containerRect\r
5360              * @param {string|number} [margin]\r
5361              *\r
5362              * @return {module:zrender/core/BoundingRect}\r
5363              */\r
5364             layout.getLayoutRect = function (\r
5365                 positionInfo, containerRect, margin\r
5366             ) {\r
5367                 margin = formatUtil.normalizeCssArray(margin || 0);\r
5368 \r
5369                 var containerWidth = containerRect.width;\r
5370                 var containerHeight = containerRect.height;\r
5371 \r
5372                 var left = parsePercent(positionInfo.left, containerWidth);\r
5373                 var top = parsePercent(positionInfo.top, containerHeight);\r
5374                 var right = parsePercent(positionInfo.right, containerWidth);\r
5375                 var bottom = parsePercent(positionInfo.bottom, containerHeight);\r
5376                 var width = parsePercent(positionInfo.width, containerWidth);\r
5377                 var height = parsePercent(positionInfo.height, containerHeight);\r
5378 \r
5379                 var verticalMargin = margin[2] + margin[0];\r
5380                 var horizontalMargin = margin[1] + margin[3];\r
5381                 var aspect = positionInfo.aspect;\r
5382 \r
5383                 // If width is not specified, calculate width from left and right\r
5384                 if (isNaN(width)) {\r
5385                     width = containerWidth - right - horizontalMargin - left;\r
5386                 }\r
5387                 if (isNaN(height)) {\r
5388                     height = containerHeight - bottom - verticalMargin - top;\r
5389                 }\r
5390 \r
5391                 // If width and height are not given\r
5392                 // 1. Graph should not exceeds the container\r
5393                 // 2. Aspect must be keeped\r
5394                 // 3. Graph should take the space as more as possible\r
5395                 if (isNaN(width) && isNaN(height)) {\r
5396                     if (aspect > containerWidth / containerHeight) {\r
5397                         width = containerWidth * 0.8;\r
5398                     }\r
5399                     else {\r
5400                         height = containerHeight * 0.8;\r
5401                     }\r
5402                 }\r
5403 \r
5404                 if (aspect != null) {\r
5405                     // Calculate width or height with given aspect\r
5406                     if (isNaN(width)) {\r
5407                         width = aspect * height;\r
5408                     }\r
5409                     if (isNaN(height)) {\r
5410                         height = width / aspect;\r
5411                     }\r
5412                 }\r
5413 \r
5414                 // If left is not specified, calculate left from right and width\r
5415                 if (isNaN(left)) {\r
5416                     left = containerWidth - right - width - horizontalMargin;\r
5417                 }\r
5418                 if (isNaN(top)) {\r
5419                     top = containerHeight - bottom - height - verticalMargin;\r
5420                 }\r
5421 \r
5422                 // Align left and top\r
5423                 switch (positionInfo.left || positionInfo.right) {\r
5424                     case 'center':\r
5425                         left = containerWidth / 2 - width / 2 - margin[3];\r
5426                         break;\r
5427                     case 'right':\r
5428                         left = containerWidth - width - horizontalMargin;\r
5429                         break;\r
5430                 }\r
5431                 switch (positionInfo.top || positionInfo.bottom) {\r
5432                     case 'middle':\r
5433                     case 'center':\r
5434                         top = containerHeight / 2 - height / 2 - margin[0];\r
5435                         break;\r
5436                     case 'bottom':\r
5437                         top = containerHeight - height - verticalMargin;\r
5438                         break;\r
5439                 }\r
5440                 // If something is wrong and left, top, width, height are calculated as NaN\r
5441                 left = left || 0;\r
5442                 top = top || 0;\r
5443                 if (isNaN(width)) {\r
5444                     // Width may be NaN if only one value is given except width\r
5445                     width = containerWidth - left - (right || 0);\r
5446                 }\r
5447                 if (isNaN(height)) {\r
5448                     // Height may be NaN if only one value is given except height\r
5449                     height = containerHeight - top - (bottom || 0);\r
5450                 }\r
5451 \r
5452                 var rect = new BoundingRect(left + margin[3], top + margin[0], width, height);\r
5453                 rect.margin = margin;\r
5454                 return rect;\r
5455             };\r
5456 \r
5457             /**\r
5458              * Position group of component in viewport\r
5459              *  Group position is specified by either\r
5460              *  {left, top}, {right, bottom}\r
5461              *  If all properties exists, right and bottom will be igonred.\r
5462              *\r
5463              * @param {module:zrender/container/Group} group\r
5464              * @param {Object} positionInfo\r
5465              * @param {number|string} [positionInfo.left]\r
5466              * @param {number|string} [positionInfo.top]\r
5467              * @param {number|string} [positionInfo.right]\r
5468              * @param {number|string} [positionInfo.bottom]\r
5469              * @param {Object} containerRect\r
5470              * @param {string|number} margin\r
5471              */\r
5472             layout.positionGroup = function (\r
5473                 group, positionInfo, containerRect, margin\r
5474             ) {\r
5475                 var groupRect = group.getBoundingRect();\r
5476 \r
5477                 positionInfo = zrUtil.extend(zrUtil.clone(positionInfo), {\r
5478                     width: groupRect.width,\r
5479                     height: groupRect.height\r
5480                 });\r
5481 \r
5482                 positionInfo = layout.getLayoutRect(\r
5483                     positionInfo, containerRect, margin\r
5484                 );\r
5485 \r
5486                 group.position = [\r
5487                     positionInfo.x - groupRect.x,\r
5488                     positionInfo.y - groupRect.y\r
5489                 ];\r
5490             };\r
5491 \r
5492             /**\r
5493              * Consider Case:\r
5494              * When defulat option has {left: 0, width: 100}, and we set {right: 0}\r
5495              * through setOption or media query, using normal zrUtil.merge will cause\r
5496              * {right: 0} does not take effect.\r
5497              *\r
5498              * @example\r
5499              * ComponentModel.extend({\r
5500              *     init: function () {\r
5501              *         ...\r
5502              *         var inputPositionParams = layout.getLayoutParams(option);\r
5503              *         this.mergeOption(inputPositionParams);\r
5504              *     },\r
5505              *     mergeOption: function (newOption) {\r
5506              *         newOption && zrUtil.merge(thisOption, newOption, true);\r
5507              *         layout.mergeLayoutParam(thisOption, newOption);\r
5508              *     }\r
5509              * });\r
5510              *\r
5511              * @param {Object} targetOption\r
5512              * @param {Object} newOption\r
5513              * @param {Object|string} [opt]\r
5514              * @param {boolean} [opt.ignoreSize=false] Some component must has width and height.\r
5515              */\r
5516             layout.mergeLayoutParam = function (targetOption, newOption, opt) {\r
5517                 !zrUtil.isObject(opt) && (opt = {});\r
5518                 var hNames = ['width', 'left', 'right']; // Order by priority.\r
5519                 var vNames = ['height', 'top', 'bottom']; // Order by priority.\r
5520                 var hResult = merge(hNames);\r
5521                 var vResult = merge(vNames);\r
5522 \r
5523                 copy(hNames, targetOption, hResult);\r
5524                 copy(vNames, targetOption, vResult);\r
5525 \r
5526                 function merge(names) {\r
5527                     var newParams = {};\r
5528                     var newValueCount = 0;\r
5529                     var merged = {};\r
5530                     var mergedValueCount = 0;\r
5531                     var enoughParamNumber = opt.ignoreSize ? 1 : 2;\r
5532 \r
5533                     each(names, function (name) {\r
5534                         merged[name] = targetOption[name];\r
5535                     });\r
5536                     each(names, function (name) {\r
5537                         // Consider case: newOption.width is null, which is\r
5538                         // set by user for removing width setting.\r
5539                         hasProp(newOption, name) && (newParams[name] = merged[name] = newOption[name]);\r
5540                         hasValue(newParams, name) && newValueCount++;\r
5541                         hasValue(merged, name) && mergedValueCount++;\r
5542                     });\r
5543 \r
5544                     // Case: newOption: {width: ..., right: ...},\r
5545                     // or targetOption: {right: ...} and newOption: {width: ...},\r
5546                     // There is no conflict when merged only has params count\r
5547                     // little than enoughParamNumber.\r
5548                     if (mergedValueCount === enoughParamNumber || !newValueCount) {\r
5549                         return merged;\r
5550                     }\r
5551                     // Case: newOption: {width: ..., right: ...},\r
5552                     // Than we can make sure user only want those two, and ignore\r
5553                     // all origin params in targetOption.\r
5554                     else if (newValueCount >= enoughParamNumber) {\r
5555                         return newParams;\r
5556                     }\r
5557                     else {\r
5558                         // Chose another param from targetOption by priority.\r
5559                         // When 'ignoreSize', enoughParamNumber is 1 and those will not happen.\r
5560                         for (var i = 0; i < names.length; i++) {\r
5561                             var name = names[i];\r
5562                             if (!hasProp(newParams, name) && hasProp(targetOption, name)) {\r
5563                                 newParams[name] = targetOption[name];\r
5564                                 break;\r
5565                             }\r
5566                         }\r
5567                         return newParams;\r
5568                     }\r
5569                 }\r
5570 \r
5571                 function hasProp(obj, name) {\r
5572                     return obj.hasOwnProperty(name);\r
5573                 }\r
5574 \r
5575                 function hasValue(obj, name) {\r
5576                     return obj[name] != null && obj[name] !== 'auto';\r
5577                 }\r
5578 \r
5579                 function copy(names, target, source) {\r
5580                     each(names, function (name) {\r
5581                         target[name] = source[name];\r
5582                     });\r
5583                 }\r
5584             };\r
5585 \r
5586             /**\r
5587              * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.\r
5588              * @param {Object} source\r
5589              * @return {Object} Result contains those props.\r
5590              */\r
5591             layout.getLayoutParams = function (source) {\r
5592                 return layout.copyLayoutParams({}, source);\r
5593             };\r
5594 \r
5595             /**\r
5596              * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.\r
5597              * @param {Object} source\r
5598              * @return {Object} Result contains those props.\r
5599              */\r
5600             layout.copyLayoutParams = function (target, source) {\r
5601                 source && target && each(LOCATION_PARAMS, function (name) {\r
5602                     source.hasOwnProperty(name) && (target[name] = source[name]);\r
5603                 });\r
5604                 return target;\r
5605             };\r
5606 \r
5607             module.exports = layout;\r
5608 \r
5609 \r
5610 /***/ },\r
5611 /* 22 */\r
5612 /***/ function(module, exports) {\r
5613 \r
5614         \r
5615 \r
5616             module.exports = {\r
5617                 getBoxLayoutParams: function () {\r
5618                     return {\r
5619                         left: this.get('left'),\r
5620                         top: this.get('top'),\r
5621                         right: this.get('right'),\r
5622                         bottom: this.get('bottom'),\r
5623                         width: this.get('width'),\r
5624                         height: this.get('height')\r
5625                     };\r
5626                 }\r
5627             };\r
5628 \r
5629 \r
5630 /***/ },\r
5631 /* 23 */\r
5632 /***/ function(module, exports) {\r
5633 \r
5634         \r
5635             var platform = '';\r
5636             // Navigator not exists in node\r
5637             if (typeof navigator !== 'undefined') {\r
5638                 platform = navigator.platform || '';\r
5639             }\r
5640             module.exports = {\r
5641                 // 全图默认背景\r
5642                 // backgroundColor: 'rgba(0,0,0,0)',\r
5643 \r
5644                 // https://dribbble.com/shots/1065960-Infographic-Pie-chart-visualization\r
5645                 // color: ['#5793f3', '#d14a61', '#fd9c35', '#675bba', '#fec42c', '#dd4444', '#d4df5a', '#cd4870'],\r
5646                 // 浅色\r
5647                 // color: ['#bcd3bb', '#e88f70', '#edc1a5', '#9dc5c8', '#e1e8c8', '#7b7c68', '#e5b5b5', '#f0b489', '#928ea8', '#bda29a'],\r
5648                 // color: ['#cc5664', '#9bd6ec', '#ea946e', '#8acaaa', '#f1ec64', '#ee8686', '#a48dc1', '#5da6bc', '#b9dcae'],\r
5649                 // 深色\r
5650                 color: ['#c23531','#2f4554', '#61a0a8', '#d48265', '#91c7ae','#749f83',  '#ca8622', '#bda29a','#6e7074', '#546570', '#c4ccd3'],\r
5651 \r
5652                 // 默认需要 Grid 配置项\r
5653                 grid: {},\r
5654                 // 主题,主题\r
5655                 textStyle: {\r
5656                     // color: '#000',\r
5657                     // decoration: 'none',\r
5658                     // PENDING\r
5659                     fontFamily: platform.match(/^Win/) ? 'Microsoft YaHei' : 'sans-serif',\r
5660                     // fontFamily: 'Arial, Verdana, sans-serif',\r
5661                     fontSize: 12,\r
5662                     fontStyle: 'normal',\r
5663                     fontWeight: 'normal'\r
5664                 },\r
5665                 // 主题,默认标志图形类型列表\r
5666                 // symbolList: [\r
5667                 //     'circle', 'rectangle', 'triangle', 'diamond',\r
5668                 //     'emptyCircle', 'emptyRectangle', 'emptyTriangle', 'emptyDiamond'\r
5669                 // ],\r
5670                 animation: true,                // 过渡动画是否开启\r
5671                 animationThreshold: 2000,       // 动画元素阀值,产生的图形原素超过2000不出动画\r
5672                 animationDuration: 1000,        // 过渡动画参数:进入\r
5673                 animationDurationUpdate: 300,   // 过渡动画参数:更新\r
5674                 animationEasing: 'exponentialOut',    //BounceOut\r
5675                 animationEasingUpdate: 'cubicOut'\r
5676             };\r
5677 \r
5678 \r
5679 /***/ },\r
5680 /* 24 */\r
5681 /***/ function(module, exports, __webpack_require__) {\r
5682 \r
5683         'use strict';\r
5684 \r
5685 \r
5686             var zrUtil = __webpack_require__(3);\r
5687 \r
5688             var echartsAPIList = [\r
5689                 'getDom', 'getZr', 'getWidth', 'getHeight', 'dispatchAction',\r
5690                 'on', 'off', 'getDataURL', 'getConnectedDataURL', 'getModel', 'getOption'\r
5691             ];\r
5692 \r
5693             function ExtensionAPI(chartInstance) {\r
5694                 zrUtil.each(echartsAPIList, function (name) {\r
5695                     this[name] = zrUtil.bind(chartInstance[name], chartInstance);\r
5696                 }, this);\r
5697             }\r
5698 \r
5699             module.exports = ExtensionAPI;\r
5700 \r
5701 \r
5702 /***/ },\r
5703 /* 25 */\r
5704 /***/ function(module, exports) {\r
5705 \r
5706         'use strict';\r
5707 \r
5708 \r
5709             // var zrUtil = require('zrender/lib/core/util');\r
5710             var coordinateSystemCreators = {};\r
5711 \r
5712             function CoordinateSystemManager() {\r
5713 \r
5714                 this._coordinateSystems = [];\r
5715             }\r
5716 \r
5717             CoordinateSystemManager.prototype = {\r
5718 \r
5719                 constructor: CoordinateSystemManager,\r
5720 \r
5721                 create: function (ecModel, api) {\r
5722                     var coordinateSystems = [];\r
5723                     for (var type in coordinateSystemCreators) {\r
5724                         var list = coordinateSystemCreators[type].create(ecModel, api);\r
5725                         list && (coordinateSystems = coordinateSystems.concat(list));\r
5726                     }\r
5727 \r
5728                     this._coordinateSystems = coordinateSystems;\r
5729                 },\r
5730 \r
5731                 update: function (ecModel, api) {\r
5732                     var coordinateSystems = this._coordinateSystems;\r
5733                     for (var i = 0; i < coordinateSystems.length; i++) {\r
5734                         // FIXME MUST have\r
5735                         coordinateSystems[i].update && coordinateSystems[i].update(ecModel, api);\r
5736                     }\r
5737                 }\r
5738             };\r
5739 \r
5740             CoordinateSystemManager.register = function (type, coordinateSystemCreator) {\r
5741                 coordinateSystemCreators[type] = coordinateSystemCreator;\r
5742             };\r
5743 \r
5744             CoordinateSystemManager.get = function (type) {\r
5745                 return coordinateSystemCreators[type];\r
5746             };\r
5747 \r
5748             module.exports = CoordinateSystemManager;\r
5749 \r
5750 \r
5751 /***/ },\r
5752 /* 26 */\r
5753 /***/ function(module, exports, __webpack_require__) {\r
5754 \r
5755         /**\r
5756          * ECharts option manager\r
5757          *\r
5758          * @module {echarts/model/OptionManager}\r
5759          */\r
5760 \r
5761 \r
5762 \r
5763             var zrUtil = __webpack_require__(3);\r
5764             var modelUtil = __webpack_require__(5);\r
5765             var ComponentModel = __webpack_require__(19);\r
5766             var each = zrUtil.each;\r
5767             var clone = zrUtil.clone;\r
5768             var map = zrUtil.map;\r
5769             var merge = zrUtil.merge;\r
5770 \r
5771             var QUERY_REG = /^(min|max)?(.+)$/;\r
5772 \r
5773             /**\r
5774              * TERM EXPLANATIONS:\r
5775              *\r
5776              * [option]:\r
5777              *\r
5778              *     An object that contains definitions of components. For example:\r
5779              *     var option = {\r
5780              *         title: {...},\r
5781              *         legend: {...},\r
5782              *         visualMap: {...},\r
5783              *         series: [\r
5784              *             {data: [...]},\r
5785              *             {data: [...]},\r
5786              *             ...\r
5787              *         ]\r
5788              *     };\r
5789              *\r
5790              * [rawOption]:\r
5791              *\r
5792              *     An object input to echarts.setOption. 'rawOption' may be an\r
5793              *     'option', or may be an object contains multi-options. For example:\r
5794              *     var option = {\r
5795              *         baseOption: {\r
5796              *             title: {...},\r
5797              *             legend: {...},\r
5798              *             series: [\r
5799              *                 {data: [...]},\r
5800              *                 {data: [...]},\r
5801              *                 ...\r
5802              *             ]\r
5803              *         },\r
5804              *         timeline: {...},\r
5805              *         options: [\r
5806              *             {title: {...}, series: {data: [...]}},\r
5807              *             {title: {...}, series: {data: [...]}},\r
5808              *             ...\r
5809              *         ],\r
5810              *         media: [\r
5811              *             {\r
5812              *                 query: {maxWidth: 320},\r
5813              *                 option: {series: {x: 20}, visualMap: {show: false}}\r
5814              *             },\r
5815              *             {\r
5816              *                 query: {minWidth: 320, maxWidth: 720},\r
5817              *                 option: {series: {x: 500}, visualMap: {show: true}}\r
5818              *             },\r
5819              *             {\r
5820              *                 option: {series: {x: 1200}, visualMap: {show: true}}\r
5821              *             }\r
5822              *         ]\r
5823              *     };\r
5824              *\r
5825              * @alias module:echarts/model/OptionManager\r
5826              * @param {module:echarts/ExtensionAPI} api\r
5827              */\r
5828             function OptionManager(api) {\r
5829 \r
5830                 /**\r
5831                  * @private\r
5832                  * @type {module:echarts/ExtensionAPI}\r
5833                  */\r
5834                 this._api = api;\r
5835 \r
5836                 /**\r
5837                  * @private\r
5838                  * @type {Array.<number>}\r
5839                  */\r
5840                 this._timelineOptions = [];\r
5841 \r
5842                 /**\r
5843                  * @private\r
5844                  * @type {Array.<Object>}\r
5845                  */\r
5846                 this._mediaList = [];\r
5847 \r
5848                 /**\r
5849                  * @private\r
5850                  * @type {Object}\r
5851                  */\r
5852                 this._mediaDefault;\r
5853 \r
5854                 /**\r
5855                  * -1, means default.\r
5856                  * empty means no media.\r
5857                  * @private\r
5858                  * @type {Array.<number>}\r
5859                  */\r
5860                 this._currentMediaIndices = [];\r
5861 \r
5862                 /**\r
5863                  * @private\r
5864                  * @type {Object}\r
5865                  */\r
5866                 this._optionBackup;\r
5867 \r
5868                 /**\r
5869                  * @private\r
5870                  * @type {Object}\r
5871                  */\r
5872                 this._newOptionBackup;\r
5873             }\r
5874 \r
5875             // timeline.notMerge is not supported in ec3. Firstly there is rearly\r
5876             // case that notMerge is needed. Secondly supporting 'notMerge' requires\r
5877             // rawOption cloned and backuped when timeline changed, which does no\r
5878             // good to performance. What's more, that both timeline and setOption\r
5879             // method supply 'notMerge' brings complex and some problems.\r
5880             // Consider this case:\r
5881             // (step1) chart.setOption({timeline: {notMerge: false}, ...}, false);\r
5882             // (step2) chart.setOption({timeline: {notMerge: true}, ...}, false);\r
5883 \r
5884             OptionManager.prototype = {\r
5885 \r
5886                 constructor: OptionManager,\r
5887 \r
5888                 /**\r
5889                  * @public\r
5890                  * @param {Object} rawOption Raw option.\r
5891                  * @param {module:echarts/model/Global} ecModel\r
5892                  * @param {Array.<Function>} optionPreprocessorFuncs\r
5893                  * @return {Object} Init option\r
5894                  */\r
5895                 setOption: function (rawOption, optionPreprocessorFuncs) {\r
5896                     rawOption = clone(rawOption, true);\r
5897 \r
5898                     // FIXME\r
5899                     // 如果 timeline options 或者 media 中设置了某个属性,而baseOption中没有设置,则进行警告。\r
5900 \r
5901                     var oldOptionBackup = this._optionBackup;\r
5902                     var newOptionBackup = this._newOptionBackup = parseRawOption.call(\r
5903                         this, rawOption, optionPreprocessorFuncs\r
5904                     );\r
5905 \r
5906                     // For setOption at second time (using merge mode);\r
5907                     if (oldOptionBackup) {\r
5908                         // Only baseOption can be merged.\r
5909                         mergeOption(oldOptionBackup.baseOption, newOptionBackup.baseOption);\r
5910 \r
5911                         if (newOptionBackup.timelineOptions.length) {\r
5912                             oldOptionBackup.timelineOptions = newOptionBackup.timelineOptions;\r
5913                         }\r
5914                         if (newOptionBackup.mediaList.length) {\r
5915                             oldOptionBackup.mediaList = newOptionBackup.mediaList;\r
5916                         }\r
5917                         if (newOptionBackup.mediaDefault) {\r
5918                             oldOptionBackup.mediaDefault = newOptionBackup.mediaDefault;\r
5919                         }\r
5920                     }\r
5921                     else {\r
5922                         this._optionBackup = newOptionBackup;\r
5923                     }\r
5924                 },\r
5925 \r
5926                 /**\r
5927                  * @param {boolean} isRecreate\r
5928                  * @return {Object}\r
5929                  */\r
5930                 mountOption: function (isRecreate) {\r
5931                     var optionBackup = isRecreate\r
5932                         // this._optionBackup can be only used when recreate.\r
5933                         // In other cases we use model.mergeOption to handle merge.\r
5934                         ? this._optionBackup : this._newOptionBackup;\r
5935 \r
5936                     // FIXME\r
5937                     // 如果没有reset功能则不clone。\r
5938 \r
5939                     this._timelineOptions = map(optionBackup.timelineOptions, clone);\r
5940                     this._mediaList = map(optionBackup.mediaList, clone);\r
5941                     this._mediaDefault = clone(optionBackup.mediaDefault);\r
5942                     this._currentMediaIndices = [];\r
5943 \r
5944                     return clone(optionBackup.baseOption);\r
5945                 },\r
5946 \r
5947                 /**\r
5948                  * @param {module:echarts/model/Global} ecModel\r
5949                  * @return {Object}\r
5950                  */\r
5951                 getTimelineOption: function (ecModel) {\r
5952                     var option;\r
5953                     var timelineOptions = this._timelineOptions;\r
5954 \r
5955                     if (timelineOptions.length) {\r
5956                         // getTimelineOption can only be called after ecModel inited,\r
5957                         // so we can get currentIndex from timelineModel.\r
5958                         var timelineModel = ecModel.getComponent('timeline');\r
5959                         if (timelineModel) {\r
5960                             option = clone(\r
5961                                 timelineOptions[timelineModel.getCurrentIndex()],\r
5962                                 true\r
5963                             );\r
5964                         }\r
5965                     }\r
5966 \r
5967                     return option;\r
5968                 },\r
5969 \r
5970                 /**\r
5971                  * @param {module:echarts/model/Global} ecModel\r
5972                  * @return {Array.<Object>}\r
5973                  */\r
5974                 getMediaOption: function (ecModel) {\r
5975                     var ecWidth = this._api.getWidth();\r
5976                     var ecHeight = this._api.getHeight();\r
5977                     var mediaList = this._mediaList;\r
5978                     var mediaDefault = this._mediaDefault;\r
5979                     var indices = [];\r
5980                     var result = [];\r
5981 \r
5982                     // No media defined.\r
5983                     if (!mediaList.length && !mediaDefault) {\r
5984                         return result;\r
5985                     }\r
5986 \r
5987                     // Multi media may be applied, the latter defined media has higher priority.\r
5988                     for (var i = 0, len = mediaList.length; i < len; i++) {\r
5989                         if (applyMediaQuery(mediaList[i].query, ecWidth, ecHeight)) {\r
5990                             indices.push(i);\r
5991                         }\r
5992                     }\r
5993 \r
5994                     // FIXME\r
5995                     // 是否mediaDefault应该强制用户设置,否则可能修改不能回归。\r
5996                     if (!indices.length && mediaDefault) {\r
5997                         indices = [-1];\r
5998                     }\r
5999 \r
6000                     if (indices.length && !indicesEquals(indices, this._currentMediaIndices)) {\r
6001                         result = map(indices, function (index) {\r
6002                             return clone(\r
6003                                 index === -1 ? mediaDefault.option : mediaList[index].option\r
6004                             );\r
6005                         });\r
6006                     }\r
6007                     // Otherwise return nothing.\r
6008 \r
6009                     this._currentMediaIndices = indices;\r
6010 \r
6011                     return result;\r
6012                 }\r
6013             };\r
6014 \r
6015             function parseRawOption(rawOption, optionPreprocessorFuncs) {\r
6016                 var timelineOptions = [];\r
6017                 var mediaList = [];\r
6018                 var mediaDefault;\r
6019                 var baseOption;\r
6020 \r
6021                 // Compatible with ec2.\r
6022                 var timelineOpt = rawOption.timeline;\r
6023 \r
6024                 if (rawOption.baseOption) {\r
6025                     baseOption = rawOption.baseOption;\r
6026                 }\r
6027 \r
6028                 // For timeline\r
6029                 if (timelineOpt || rawOption.options) {\r
6030                     baseOption = baseOption || {};\r
6031                     timelineOptions = (rawOption.options || []).slice();\r
6032                 }\r
6033                 // For media query\r
6034                 if (rawOption.media) {\r
6035                     baseOption = baseOption || {};\r
6036                     var media = rawOption.media;\r
6037                     each(media, function (singleMedia) {\r
6038                         if (singleMedia && singleMedia.option) {\r
6039                             if (singleMedia.query) {\r
6040                                 mediaList.push(singleMedia);\r
6041                             }\r
6042                             else if (!mediaDefault) {\r
6043                                 // Use the first media default.\r
6044                                 mediaDefault = singleMedia;\r
6045                             }\r
6046                         }\r
6047                     });\r
6048                 }\r
6049 \r
6050                 // For normal option\r
6051                 if (!baseOption) {\r
6052                     baseOption = rawOption;\r
6053                 }\r
6054 \r
6055                 // Set timelineOpt to baseOption in ec3,\r
6056                 // which is convenient for merge option.\r
6057                 if (!baseOption.timeline) {\r
6058                     baseOption.timeline = timelineOpt;\r
6059                 }\r
6060 \r
6061                 // Preprocess.\r
6062                 each([baseOption].concat(timelineOptions)\r
6063                     .concat(zrUtil.map(mediaList, function (media) {\r
6064                         return media.option;\r
6065                     })),\r
6066                     function (option) {\r
6067                         each(optionPreprocessorFuncs, function (preProcess) {\r
6068                             preProcess(option);\r
6069                         });\r
6070                     }\r
6071                 );\r
6072 \r
6073                 return {\r
6074                     baseOption: baseOption,\r
6075                     timelineOptions: timelineOptions,\r
6076                     mediaDefault: mediaDefault,\r
6077                     mediaList: mediaList\r
6078                 };\r
6079             }\r
6080 \r
6081             /**\r
6082              * @see <http://www.w3.org/TR/css3-mediaqueries/#media1>\r
6083              * Support: width, height, aspectRatio\r
6084              * Can use max or min as prefix.\r
6085              */\r
6086             function applyMediaQuery(query, ecWidth, ecHeight) {\r
6087                 var realMap = {\r
6088                     width: ecWidth,\r
6089                     height: ecHeight,\r
6090                     aspectratio: ecWidth / ecHeight // lowser case for convenientce.\r
6091                 };\r
6092 \r
6093                 var applicatable = true;\r
6094 \r
6095                 zrUtil.each(query, function (value, attr) {\r
6096                     var matched = attr.match(QUERY_REG);\r
6097 \r
6098                     if (!matched || !matched[1] || !matched[2]) {\r
6099                         return;\r
6100                     }\r
6101 \r
6102                     var operator = matched[1];\r
6103                     var realAttr = matched[2].toLowerCase();\r
6104 \r
6105                     if (!compare(realMap[realAttr], value, operator)) {\r
6106                         applicatable = false;\r
6107                     }\r
6108                 });\r
6109 \r
6110                 return applicatable;\r
6111             }\r
6112 \r
6113             function compare(real, expect, operator) {\r
6114                 if (operator === 'min') {\r
6115                     return real >= expect;\r
6116                 }\r
6117                 else if (operator === 'max') {\r
6118                     return real <= expect;\r
6119                 }\r
6120                 else { // Equals\r
6121                     return real === expect;\r
6122                 }\r
6123             }\r
6124 \r
6125             function indicesEquals(indices1, indices2) {\r
6126                 // indices is always order by asc and has only finite number.\r
6127                 return indices1.join(',') === indices2.join(',');\r
6128             }\r
6129 \r
6130             /**\r
6131              * Consider case:\r
6132              * `chart.setOption(opt1);`\r
6133              * Then user do some interaction like dataZoom, dataView changing.\r
6134              * `chart.setOption(opt2);`\r
6135              * Then user press 'reset button' in toolbox.\r
6136              *\r
6137              * After doing that all of the interaction effects should be reset, the\r
6138              * chart should be the same as the result of invoke\r
6139              * `chart.setOption(opt1); chart.setOption(opt2);`.\r
6140              *\r
6141              * Although it is not able ensure that\r
6142              * `chart.setOption(opt1); chart.setOption(opt2);` is equivalents to\r
6143              * `chart.setOption(merge(opt1, opt2));` exactly,\r
6144              * this might be the only simple way to implement that feature.\r
6145              *\r
6146              * MEMO: We've considered some other approaches:\r
6147              * 1. Each model handle its self restoration but not uniform treatment.\r
6148              *     (Too complex in logic and error-prone)\r
6149              * 2. Use a shadow ecModel. (Performace expensive)\r
6150              */\r
6151             function mergeOption(oldOption, newOption) {\r
6152                 newOption = newOption || {};\r
6153 \r
6154                 each(newOption, function (newCptOpt, mainType) {\r
6155                     if (newCptOpt == null) {\r
6156                         return;\r
6157                     }\r
6158 \r
6159                     var oldCptOpt = oldOption[mainType];\r
6160 \r
6161                     if (!ComponentModel.hasClass(mainType)) {\r
6162                         oldOption[mainType] = merge(oldCptOpt, newCptOpt, true);\r
6163                     }\r
6164                     else {\r
6165                         newCptOpt = modelUtil.normalizeToArray(newCptOpt);\r
6166                         oldCptOpt = modelUtil.normalizeToArray(oldCptOpt);\r
6167 \r
6168                         var mapResult = modelUtil.mappingToExists(oldCptOpt, newCptOpt);\r
6169 \r
6170                         oldOption[mainType] = map(mapResult, function (item) {\r
6171                             return (item.option && item.exist)\r
6172                                 ? merge(item.exist, item.option, true)\r
6173                                 : (item.exist || item.option);\r
6174                         });\r
6175                     }\r
6176                 });\r
6177             }\r
6178 \r
6179             module.exports = OptionManager;\r
6180 \r
6181 \r
6182 /***/ },\r
6183 /* 27 */\r
6184 /***/ function(module, exports, __webpack_require__) {\r
6185 \r
6186         'use strict';\r
6187 \r
6188 \r
6189             var zrUtil = __webpack_require__(3);\r
6190             var formatUtil = __webpack_require__(6);\r
6191             var modelUtil = __webpack_require__(5);\r
6192             var ComponentModel = __webpack_require__(19);\r
6193 \r
6194             var encodeHTML = formatUtil.encodeHTML;\r
6195             var addCommas = formatUtil.addCommas;\r
6196 \r
6197             var SeriesModel = ComponentModel.extend({\r
6198 \r
6199                 type: 'series.__base__',\r
6200 \r
6201                 /**\r
6202                  * @readOnly\r
6203                  */\r
6204                 seriesIndex: 0,\r
6205 \r
6206                 // coodinateSystem will be injected in the echarts/CoordinateSystem\r
6207                 coordinateSystem: null,\r
6208 \r
6209                 /**\r
6210                  * @type {Object}\r
6211                  * @protected\r
6212                  */\r
6213                 defaultOption: null,\r
6214 \r
6215                 /**\r
6216                  * Data provided for legend\r
6217                  * @type {Function}\r
6218                  */\r
6219                 // PENDING\r
6220                 legendDataProvider: null,\r
6221 \r
6222                 init: function (option, parentModel, ecModel, extraOpt) {\r
6223 \r
6224                     /**\r
6225                      * @type {number}\r
6226                      * @readOnly\r
6227                      */\r
6228                     this.seriesIndex = this.componentIndex;\r
6229 \r
6230                     this.mergeDefaultAndTheme(option, ecModel);\r
6231 \r
6232                     /**\r
6233                      * @type {module:echarts/data/List|module:echarts/data/Tree|module:echarts/data/Graph}\r
6234                      * @private\r
6235                      */\r
6236                     this._dataBeforeProcessed = this.getInitialData(option, ecModel);\r
6237 \r
6238                     // When using module:echarts/data/Tree or module:echarts/data/Graph,\r
6239                     // cloneShallow will cause this._data.graph.data pointing to new data list.\r
6240                     // Wo we make this._dataBeforeProcessed first, and then make this._data.\r
6241                     this._data = this._dataBeforeProcessed.cloneShallow();\r
6242                 },\r
6243 \r
6244                 /**\r
6245                  * Util for merge default and theme to option\r
6246                  * @param  {Object} option\r
6247                  * @param  {module:echarts/model/Global} ecModel\r
6248                  */\r
6249                 mergeDefaultAndTheme: function (option, ecModel) {\r
6250                     zrUtil.merge(\r
6251                         option,\r
6252                         ecModel.getTheme().get(this.subType)\r
6253                     );\r
6254                     zrUtil.merge(option, this.getDefaultOption());\r
6255 \r
6256                     // Default label emphasis `position` and `show`\r
6257                     modelUtil.defaultEmphasis(\r
6258                         option.label, ['position', 'show', 'textStyle', 'distance', 'formatter']\r
6259                     );\r
6260 \r
6261                     // Default data label emphasis `position` and `show`\r
6262                     // FIXME Tree structure data ?\r
6263                     var data = option.data || [];\r
6264                     for (var i = 0; i < data.length; i++) {\r
6265                         if (data[i] && data[i].label) {\r
6266                             modelUtil.defaultEmphasis(\r
6267                                 data[i].label, ['position', 'show', 'textStyle', 'distance', 'formatter']\r
6268                             );\r
6269                         }\r
6270                     }\r
6271                 },\r
6272 \r
6273                 mergeOption: function (newSeriesOption, ecModel) {\r
6274                     newSeriesOption = zrUtil.merge(this.option, newSeriesOption, true);\r
6275 \r
6276                     var data = this.getInitialData(newSeriesOption, ecModel);\r
6277                     // TODO Merge data?\r
6278                     if (data) {\r
6279                         this._data = data;\r
6280                         this._dataBeforeProcessed = data.cloneShallow();\r
6281                     }\r
6282                 },\r
6283 \r
6284                 /**\r
6285                  * Init a data structure from data related option in series\r
6286                  * Must be overwritten\r
6287                  */\r
6288                 getInitialData: function () {},\r
6289 \r
6290                 /**\r
6291                  * @return {module:echarts/data/List}\r
6292                  */\r
6293                 getData: function () {\r
6294                     return this._data;\r
6295                 },\r
6296 \r
6297                 /**\r
6298                  * @param {module:echarts/data/List} data\r
6299                  */\r
6300                 setData: function (data) {\r
6301                     this._data = data;\r
6302                 },\r
6303 \r
6304                 /**\r
6305                  * Get data before processed\r
6306                  * @return {module:echarts/data/List}\r
6307                  */\r
6308                 getRawData: function () {\r
6309                     return this._dataBeforeProcessed;\r
6310                 },\r
6311 \r
6312                 /**\r
6313                  * Get raw data array given by user\r
6314                  * @return {Array.<Object>}\r
6315                  */\r
6316                 getRawDataArray: function () {\r
6317                     return this.option.data;\r
6318                 },\r
6319 \r
6320                 /**\r
6321                  * Coord dimension to data dimension.\r
6322                  *\r
6323                  * By default the result is the same as dimensions of series data.\r
6324                  * But some series dimensions are different from coord dimensions (i.e.\r
6325                  * candlestick and boxplot). Override this method to handle those cases.\r
6326                  *\r
6327                  * Coord dimension to data dimension can be one-to-many\r
6328                  *\r
6329                  * @param {string} coordDim\r
6330                  * @return {Array.<string>} dimensions on the axis.\r
6331                  */\r
6332                 coordDimToDataDim: function (coordDim) {\r
6333                     return [coordDim];\r
6334                 },\r
6335 \r
6336                 /**\r
6337                  * Convert data dimension to coord dimension.\r
6338                  *\r
6339                  * @param {string|number} dataDim\r
6340                  * @return {string}\r
6341                  */\r
6342                 dataDimToCoordDim: function (dataDim) {\r
6343                     return dataDim;\r
6344                 },\r
6345 \r
6346                 /**\r
6347                  * Get base axis if has coordinate system and has axis.\r
6348                  * By default use coordSys.getBaseAxis();\r
6349                  * Can be overrided for some chart.\r
6350                  * @return {type} description\r
6351                  */\r
6352                 getBaseAxis: function () {\r
6353                     var coordSys = this.coordinateSystem;\r
6354                     return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis();\r
6355                 },\r
6356 \r
6357                 // FIXME\r
6358                 /**\r
6359                  * Default tooltip formatter\r
6360                  *\r
6361                  * @param {number} dataIndex\r
6362                  * @param {boolean} [multipleSeries=false]\r
6363                  */\r
6364                 formatTooltip: function (dataIndex, multipleSeries) {\r
6365                     var data = this._data;\r
6366                     var value = this.getRawValue(dataIndex);\r
6367                     var formattedValue = zrUtil.isArray(value)\r
6368                         ? zrUtil.map(value, addCommas).join(', ') : addCommas(value);\r
6369                     var name = data.getName(dataIndex);\r
6370                     var color = data.getItemVisual(dataIndex, 'color');\r
6371                     var colorEl = '<span style="display:inline-block;margin-right:5px;'\r
6372                         + 'border-radius:10px;width:9px;height:9px;background-color:' + color + '"></span>';\r
6373 \r
6374                     return !multipleSeries\r
6375                         ? (encodeHTML(this.name) + '<br />' + colorEl\r
6376                             + (name\r
6377                                 ? encodeHTML(name) + ' : ' + formattedValue\r
6378                                 : formattedValue)\r
6379                           )\r
6380                         : (colorEl + encodeHTML(this.name) + ' : ' + formattedValue);\r
6381                 },\r
6382 \r
6383                 restoreData: function () {\r
6384                     this._data = this._dataBeforeProcessed.cloneShallow();\r
6385                 }\r
6386             });\r
6387 \r
6388             zrUtil.mixin(SeriesModel, modelUtil.dataFormatMixin);\r
6389 \r
6390             module.exports = SeriesModel;\r
6391 \r
6392 \r
6393 /***/ },\r
6394 /* 28 */\r
6395 /***/ function(module, exports, __webpack_require__) {\r
6396 \r
6397         \r
6398 \r
6399             var Group = __webpack_require__(29);\r
6400             var componentUtil = __webpack_require__(20);\r
6401             var clazzUtil = __webpack_require__(9);\r
6402 \r
6403             var Component = function () {\r
6404                 /**\r
6405                  * @type {module:zrender/container/Group}\r
6406                  * @readOnly\r
6407                  */\r
6408                 this.group = new Group();\r
6409 \r
6410                 /**\r
6411                  * @type {string}\r
6412                  * @readOnly\r
6413                  */\r
6414                 this.uid = componentUtil.getUID('viewComponent');\r
6415             };\r
6416 \r
6417             Component.prototype = {\r
6418 \r
6419                 constructor: Component,\r
6420 \r
6421                 init: function (ecModel, api) {},\r
6422 \r
6423                 render: function (componentModel, ecModel, api, payload) {},\r
6424 \r
6425                 dispose: function () {}\r
6426             };\r
6427 \r
6428             var componentProto = Component.prototype;\r
6429             componentProto.updateView\r
6430                 = componentProto.updateLayout\r
6431                 = componentProto.updateVisual\r
6432                 = function (seriesModel, ecModel, api, payload) {\r
6433                     // Do nothing;\r
6434                 };\r
6435             // Enable Component.extend.\r
6436             clazzUtil.enableClassExtend(Component);\r
6437 \r
6438             // Enable capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.\r
6439             clazzUtil.enableClassManagement(Component, {registerWhenExtend: true});\r
6440 \r
6441             module.exports = Component;\r
6442 \r
6443 \r
6444 /***/ },\r
6445 /* 29 */\r
6446 /***/ function(module, exports, __webpack_require__) {\r
6447 \r
6448         /**\r
6449          * Group是一个容器,可以插入子节点,Group的变换也会被应用到子节点上\r
6450          * @module zrender/graphic/Group\r
6451          * @example\r
6452          *     var Group = require('zrender/lib/container/Group');\r
6453          *     var Circle = require('zrender/lib/graphic/shape/Circle');\r
6454          *     var g = new Group();\r
6455          *     g.position[0] = 100;\r
6456          *     g.position[1] = 100;\r
6457          *     g.add(new Circle({\r
6458          *         style: {\r
6459          *             x: 100,\r
6460          *             y: 100,\r
6461          *             r: 20,\r
6462          *         }\r
6463          *     }));\r
6464          *     zr.add(g);\r
6465          */\r
6466 \r
6467 \r
6468             var zrUtil = __webpack_require__(3);\r
6469             var Element = __webpack_require__(30);\r
6470             var BoundingRect = __webpack_require__(15);\r
6471 \r
6472             /**\r
6473              * @alias module:zrender/graphic/Group\r
6474              * @constructor\r
6475              * @extends module:zrender/mixin/Transformable\r
6476              * @extends module:zrender/mixin/Eventful\r
6477              */\r
6478             var Group = function (opts) {\r
6479 \r
6480                 opts = opts || {};\r
6481 \r
6482                 Element.call(this, opts);\r
6483 \r
6484                 for (var key in opts) {\r
6485                     this[key] = opts[key];\r
6486                 }\r
6487 \r
6488                 this._children = [];\r
6489 \r
6490                 this.__storage = null;\r
6491 \r
6492                 this.__dirty = true;\r
6493             };\r
6494 \r
6495             Group.prototype = {\r
6496 \r
6497                 constructor: Group,\r
6498 \r
6499                 /**\r
6500                  * @type {string}\r
6501                  */\r
6502                 type: 'group',\r
6503 \r
6504                 /**\r
6505                  * @return {Array.<module:zrender/Element>}\r
6506                  */\r
6507                 children: function () {\r
6508                     return this._children.slice();\r
6509                 },\r
6510 \r
6511                 /**\r
6512                  * 获取指定 index 的儿子节点\r
6513                  * @param  {number} idx\r
6514                  * @return {module:zrender/Element}\r
6515                  */\r
6516                 childAt: function (idx) {\r
6517                     return this._children[idx];\r
6518                 },\r
6519 \r
6520                 /**\r
6521                  * 获取指定名字的儿子节点\r
6522                  * @param  {string} name\r
6523                  * @return {module:zrender/Element}\r
6524                  */\r
6525                 childOfName: function (name) {\r
6526                     var children = this._children;\r
6527                     for (var i = 0; i < children.length; i++) {\r
6528                         if (children[i].name === name) {\r
6529                             return children[i];\r
6530                         }\r
6531                      }\r
6532                 },\r
6533 \r
6534                 /**\r
6535                  * @return {number}\r
6536                  */\r
6537                 childCount: function () {\r
6538                     return this._children.length;\r
6539                 },\r
6540 \r
6541                 /**\r
6542                  * 添加子节点到最后\r
6543                  * @param {module:zrender/Element} child\r
6544                  */\r
6545                 add: function (child) {\r
6546                     if (child && child !== this && child.parent !== this) {\r
6547 \r
6548                         this._children.push(child);\r
6549 \r
6550                         this._doAdd(child);\r
6551                     }\r
6552 \r
6553                     return this;\r
6554                 },\r
6555 \r
6556                 /**\r
6557                  * 添加子节点在 nextSibling 之前\r
6558                  * @param {module:zrender/Element} child\r
6559                  * @param {module:zrender/Element} nextSibling\r
6560                  */\r
6561                 addBefore: function (child, nextSibling) {\r
6562                     if (child && child !== this && child.parent !== this\r
6563                         && nextSibling && nextSibling.parent === this) {\r
6564 \r
6565                         var children = this._children;\r
6566                         var idx = children.indexOf(nextSibling);\r
6567 \r
6568                         if (idx >= 0) {\r
6569                             children.splice(idx, 0, child);\r
6570                             this._doAdd(child);\r
6571                         }\r
6572                     }\r
6573 \r
6574                     return this;\r
6575                 },\r
6576 \r
6577                 _doAdd: function (child) {\r
6578                     if (child.parent) {\r
6579                         child.parent.remove(child);\r
6580                     }\r
6581 \r
6582                     child.parent = this;\r
6583 \r
6584                     var storage = this.__storage;\r
6585                     var zr = this.__zr;\r
6586                     if (storage && storage !== child.__storage) {\r
6587 \r
6588                         storage.addToMap(child);\r
6589 \r
6590                         if (child instanceof Group) {\r
6591                             child.addChildrenToStorage(storage);\r
6592                         }\r
6593                     }\r
6594 \r
6595                     zr && zr.refresh();\r
6596                 },\r
6597 \r
6598                 /**\r
6599                  * 移除子节点\r
6600                  * @param {module:zrender/Element} child\r
6601                  */\r
6602                 remove: function (child) {\r
6603                     var zr = this.__zr;\r
6604                     var storage = this.__storage;\r
6605                     var children = this._children;\r
6606 \r
6607                     var idx = zrUtil.indexOf(children, child);\r
6608                     if (idx < 0) {\r
6609                         return this;\r
6610                     }\r
6611                     children.splice(idx, 1);\r
6612 \r
6613                     child.parent = null;\r
6614 \r
6615                     if (storage) {\r
6616 \r
6617                         storage.delFromMap(child.id);\r
6618 \r
6619                         if (child instanceof Group) {\r
6620                             child.delChildrenFromStorage(storage);\r
6621                         }\r
6622                     }\r
6623 \r
6624                     zr && zr.refresh();\r
6625 \r
6626                     return this;\r
6627                 },\r
6628 \r
6629                 /**\r
6630                  * 移除所有子节点\r
6631                  */\r
6632                 removeAll: function () {\r
6633                     var children = this._children;\r
6634                     var storage = this.__storage;\r
6635                     var child;\r
6636                     var i;\r
6637                     for (i = 0; i < children.length; i++) {\r
6638                         child = children[i];\r
6639                         if (storage) {\r
6640                             storage.delFromMap(child.id);\r
6641                             if (child instanceof Group) {\r
6642                                 child.delChildrenFromStorage(storage);\r
6643                             }\r
6644                         }\r
6645                         child.parent = null;\r
6646                     }\r
6647                     children.length = 0;\r
6648 \r
6649                     return this;\r
6650                 },\r
6651 \r
6652                 /**\r
6653                  * 遍历所有子节点\r
6654                  * @param  {Function} cb\r
6655                  * @param  {}   context\r
6656                  */\r
6657                 eachChild: function (cb, context) {\r
6658                     var children = this._children;\r
6659                     for (var i = 0; i < children.length; i++) {\r
6660                         var child = children[i];\r
6661                         cb.call(context, child, i);\r
6662                     }\r
6663                     return this;\r
6664                 },\r
6665 \r
6666                 /**\r
6667                  * 深度优先遍历所有子孙节点\r
6668                  * @param  {Function} cb\r
6669                  * @param  {}   context\r
6670                  */\r
6671                 traverse: function (cb, context) {\r
6672                     for (var i = 0; i < this._children.length; i++) {\r
6673                         var child = this._children[i];\r
6674                         cb.call(context, child);\r
6675 \r
6676                         if (child.type === 'group') {\r
6677                             child.traverse(cb, context);\r
6678                         }\r
6679                     }\r
6680                     return this;\r
6681                 },\r
6682 \r
6683                 addChildrenToStorage: function (storage) {\r
6684                     for (var i = 0; i < this._children.length; i++) {\r
6685                         var child = this._children[i];\r
6686                         storage.addToMap(child);\r
6687                         if (child instanceof Group) {\r
6688                             child.addChildrenToStorage(storage);\r
6689                         }\r
6690                     }\r
6691                 },\r
6692 \r
6693                 delChildrenFromStorage: function (storage) {\r
6694                     for (var i = 0; i < this._children.length; i++) {\r
6695                         var child = this._children[i];\r
6696                         storage.delFromMap(child.id);\r
6697                         if (child instanceof Group) {\r
6698                             child.delChildrenFromStorage(storage);\r
6699                         }\r
6700                     }\r
6701                 },\r
6702 \r
6703                 dirty: function () {\r
6704                     this.__dirty = true;\r
6705                     this.__zr && this.__zr.refresh();\r
6706                     return this;\r
6707                 },\r
6708 \r
6709                 /**\r
6710                  * @return {module:zrender/core/BoundingRect}\r
6711                  */\r
6712                 getBoundingRect: function (includeChildren) {\r
6713                     // TODO Caching\r
6714                     // TODO Transform\r
6715                     var rect = null;\r
6716                     var tmpRect = new BoundingRect(0, 0, 0, 0);\r
6717                     var children = includeChildren || this._children;\r
6718                     var tmpMat = [];\r
6719 \r
6720                     for (var i = 0; i < children.length; i++) {\r
6721                         var child = children[i];\r
6722                         if (child.ignore || child.invisible) {\r
6723                             continue;\r
6724                         }\r
6725 \r
6726                         var childRect = child.getBoundingRect();\r
6727                         var transform = child.getLocalTransform(tmpMat);\r
6728                         if (transform) {\r
6729                             tmpRect.copy(childRect);\r
6730                             tmpRect.applyTransform(transform);\r
6731                             rect = rect || tmpRect.clone();\r
6732                             rect.union(tmpRect);\r
6733                         }\r
6734                         else {\r
6735                             rect = rect || childRect.clone();\r
6736                             rect.union(childRect);\r
6737                         }\r
6738                     }\r
6739                     return rect || tmpRect;\r
6740                 }\r
6741             };\r
6742 \r
6743             zrUtil.inherits(Group, Element);\r
6744 \r
6745             module.exports = Group;\r
6746 \r
6747 \r
6748 /***/ },\r
6749 /* 30 */\r
6750 /***/ function(module, exports, __webpack_require__) {\r
6751 \r
6752         'use strict';\r
6753         /**\r
6754          * @module zrender/Element\r
6755          */\r
6756 \r
6757 \r
6758             var guid = __webpack_require__(31);\r
6759             var Eventful = __webpack_require__(32);\r
6760             var Transformable = __webpack_require__(33);\r
6761             var Animatable = __webpack_require__(34);\r
6762             var zrUtil = __webpack_require__(3);\r
6763 \r
6764             /**\r
6765              * @alias module:zrender/Element\r
6766              * @constructor\r
6767              * @extends {module:zrender/mixin/Animatable}\r
6768              * @extends {module:zrender/mixin/Transformable}\r
6769              * @extends {module:zrender/mixin/Eventful}\r
6770              */\r
6771             var Element = function (opts) {\r
6772 \r
6773                 Transformable.call(this, opts);\r
6774                 Eventful.call(this, opts);\r
6775                 Animatable.call(this, opts);\r
6776 \r
6777                 /**\r
6778                  * 画布元素ID\r
6779                  * @type {string}\r
6780                  */\r
6781                 this.id = opts.id || guid();\r
6782             };\r
6783 \r
6784             Element.prototype = {\r
6785 \r
6786                 /**\r
6787                  * 元素类型\r
6788                  * Element type\r
6789                  * @type {string}\r
6790                  */\r
6791                 type: 'element',\r
6792 \r
6793                 /**\r
6794                  * 元素名字\r
6795                  * Element name\r
6796                  * @type {string}\r
6797                  */\r
6798                 name: '',\r
6799 \r
6800                 /**\r
6801                  * ZRender 实例对象,会在 element 添加到 zrender 实例中后自动赋值\r
6802                  * ZRender instance will be assigned when element is associated with zrender\r
6803                  * @name module:/zrender/Element#__zr\r
6804                  * @type {module:zrender/ZRender}\r
6805                  */\r
6806                 __zr: null,\r
6807 \r
6808                 /**\r
6809                  * 图形是否忽略,为true时忽略图形的绘制以及事件触发\r
6810                  * If ignore drawing and events of the element object\r
6811                  * @name module:/zrender/Element#ignore\r
6812                  * @type {boolean}\r
6813                  * @default false\r
6814                  */\r
6815                 ignore: false,\r
6816 \r
6817                 /**\r
6818                  * 用于裁剪的路径(shape),所有 Group 内的路径在绘制时都会被这个路径裁剪\r
6819                  * 该路径会继承被裁减对象的变换\r
6820                  * @type {module:zrender/graphic/Path}\r
6821                  * @see http://www.w3.org/TR/2dcontext/#clipping-region\r
6822                  * @readOnly\r
6823                  */\r
6824                 clipPath: null,\r
6825 \r
6826                 /**\r
6827                  * Drift element\r
6828                  * @param  {number} dx dx on the global space\r
6829                  * @param  {number} dy dy on the global space\r
6830                  */\r
6831                 drift: function (dx, dy) {\r
6832                     switch (this.draggable) {\r
6833                         case 'horizontal':\r
6834                             dy = 0;\r
6835                             break;\r
6836                         case 'vertical':\r
6837                             dx = 0;\r
6838                             break;\r
6839                     }\r
6840 \r
6841                     var m = this.transform;\r
6842                     if (!m) {\r
6843                         m = this.transform = [1, 0, 0, 1, 0, 0];\r
6844                     }\r
6845                     m[4] += dx;\r
6846                     m[5] += dy;\r
6847 \r
6848                     this.decomposeTransform();\r
6849                     this.dirty();\r
6850                 },\r
6851 \r
6852                 /**\r
6853                  * Hook before update\r
6854                  */\r
6855                 beforeUpdate: function () {},\r
6856                 /**\r
6857                  * Hook after update\r
6858                  */\r
6859                 afterUpdate: function () {},\r
6860                 /**\r
6861                  * Update each frame\r
6862                  */\r
6863                 update: function () {\r
6864                     this.updateTransform();\r
6865                 },\r
6866 \r
6867                 /**\r
6868                  * @param  {Function} cb\r
6869                  * @param  {}   context\r
6870                  */\r
6871                 traverse: function (cb, context) {},\r
6872 \r
6873                 /**\r
6874                  * @protected\r
6875                  */\r
6876                 attrKV: function (key, value) {\r
6877                     if (key === 'position' || key === 'scale' || key === 'origin') {\r
6878                         // Copy the array\r
6879                         if (value) {\r
6880                             var target = this[key];\r
6881                             if (!target) {\r
6882                                 target = this[key] = [];\r
6883                             }\r
6884                             target[0] = value[0];\r
6885                             target[1] = value[1];\r
6886                         }\r
6887                     }\r
6888                     else {\r
6889                         this[key] = value;\r
6890                     }\r
6891                 },\r
6892 \r
6893                 /**\r
6894                  * Hide the element\r
6895                  */\r
6896                 hide: function () {\r
6897                     this.ignore = true;\r
6898                     this.__zr && this.__zr.refresh();\r
6899                 },\r
6900 \r
6901                 /**\r
6902                  * Show the element\r
6903                  */\r
6904                 show: function () {\r
6905                     this.ignore = false;\r
6906                     this.__zr && this.__zr.refresh();\r
6907                 },\r
6908 \r
6909                 /**\r
6910                  * @param {string|Object} key\r
6911                  * @param {*} value\r
6912                  */\r
6913                 attr: function (key, value) {\r
6914                     if (typeof key === 'string') {\r
6915                         this.attrKV(key, value);\r
6916                     }\r
6917                     else if (zrUtil.isObject(key)) {\r
6918                         for (var name in key) {\r
6919                             if (key.hasOwnProperty(name)) {\r
6920                                 this.attrKV(name, key[name]);\r
6921                             }\r
6922                         }\r
6923                     }\r
6924                     this.dirty();\r
6925 \r
6926                     return this;\r
6927                 },\r
6928 \r
6929                 /**\r
6930                  * @param {module:zrender/graphic/Path} clipPath\r
6931                  */\r
6932                 setClipPath: function (clipPath) {\r
6933                     var zr = this.__zr;\r
6934                     if (zr) {\r
6935                         clipPath.addSelfToZr(zr);\r
6936                     }\r
6937 \r
6938                     // Remove previous clip path\r
6939                     if (this.clipPath && this.clipPath !== clipPath) {\r
6940                         this.removeClipPath();\r
6941                     }\r
6942 \r
6943                     this.clipPath = clipPath;\r
6944                     clipPath.__zr = zr;\r
6945                     clipPath.__clipTarget = this;\r
6946 \r
6947                     this.dirty();\r
6948                 },\r
6949 \r
6950                 /**\r
6951                  */\r
6952                 removeClipPath: function () {\r
6953                     var clipPath = this.clipPath;\r
6954                     if (clipPath) {\r
6955                         if (clipPath.__zr) {\r
6956                             clipPath.removeSelfFromZr(clipPath.__zr);\r
6957                         }\r
6958 \r
6959                         clipPath.__zr = null;\r
6960                         clipPath.__clipTarget = null;\r
6961                         this.clipPath = null;\r
6962 \r
6963                         this.dirty();\r
6964                     }\r
6965                 },\r
6966 \r
6967                 /**\r
6968                  * Add self from zrender instance.\r
6969                  * Not recursively because it will be invoked when element added to storage.\r
6970                  * @param {module:zrender/ZRender} zr\r
6971                  */\r
6972                 addSelfToZr: function (zr) {\r
6973                     this.__zr = zr;\r
6974                     // 添加动画\r
6975                     var animators = this.animators;\r
6976                     if (animators) {\r
6977                         for (var i = 0; i < animators.length; i++) {\r
6978                             zr.animation.addAnimator(animators[i]);\r
6979                         }\r
6980                     }\r
6981 \r
6982                     if (this.clipPath) {\r
6983                         this.clipPath.addSelfToZr(zr);\r
6984                     }\r
6985                 },\r
6986 \r
6987                 /**\r
6988                  * Remove self from zrender instance.\r
6989                  * Not recursively because it will be invoked when element added to storage.\r
6990                  * @param {module:zrender/ZRender} zr\r
6991                  */\r
6992                 removeSelfFromZr: function (zr) {\r
6993                     this.__zr = null;\r
6994                     // 移除动画\r
6995                     var animators = this.animators;\r
6996                     if (animators) {\r
6997                         for (var i = 0; i < animators.length; i++) {\r
6998                             zr.animation.removeAnimator(animators[i]);\r
6999                         }\r
7000                     }\r
7001 \r
7002                     if (this.clipPath) {\r
7003                         this.clipPath.removeSelfFromZr(zr);\r
7004                     }\r
7005                 }\r
7006             };\r
7007 \r
7008             zrUtil.mixin(Element, Animatable);\r
7009             zrUtil.mixin(Element, Transformable);\r
7010             zrUtil.mixin(Element, Eventful);\r
7011 \r
7012             module.exports = Element;\r
7013 \r
7014 \r
7015 /***/ },\r
7016 /* 31 */\r
7017 /***/ function(module, exports) {\r
7018 \r
7019         /**\r
7020          * zrender: 生成唯一id\r
7021          *\r
7022          * @author errorrik (errorrik@gmail.com)\r
7023          */\r
7024 \r
7025 \r
7026                 var idStart = 0x0907;\r
7027 \r
7028                 module.exports = function () {\r
7029                     return 'zr_' + (idStart++);\r
7030                 };\r
7031             \r
7032 \r
7033 \r
7034 /***/ },\r
7035 /* 32 */\r
7036 /***/ function(module, exports, __webpack_require__) {\r
7037 \r
7038         /**\r
7039          * 事件扩展\r
7040          * @module zrender/mixin/Eventful\r
7041          * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
7042          *         pissang (https://www.github.com/pissang)\r
7043          */\r
7044 \r
7045 \r
7046             var arrySlice = Array.prototype.slice;\r
7047             var zrUtil = __webpack_require__(3);\r
7048             var indexOf = zrUtil.indexOf;\r
7049 \r
7050             /**\r
7051              * 事件分发器\r
7052              * @alias module:zrender/mixin/Eventful\r
7053              * @constructor\r
7054              */\r
7055             var Eventful = function () {\r
7056                 this._$handlers = {};\r
7057             };\r
7058 \r
7059             Eventful.prototype = {\r
7060 \r
7061                 constructor: Eventful,\r
7062 \r
7063                 /**\r
7064                  * 单次触发绑定,trigger后销毁\r
7065                  *\r
7066                  * @param {string} event 事件名\r
7067                  * @param {Function} handler 响应函数\r
7068                  * @param {Object} context\r
7069                  */\r
7070                 one: function (event, handler, context) {\r
7071                     var _h = this._$handlers;\r
7072 \r
7073                     if (!handler || !event) {\r
7074                         return this;\r
7075                     }\r
7076 \r
7077                     if (!_h[event]) {\r
7078                         _h[event] = [];\r
7079                     }\r
7080 \r
7081                     if (indexOf(_h[event], event) >= 0) {\r
7082                         return this;\r
7083                     }\r
7084 \r
7085                     _h[event].push({\r
7086                         h: handler,\r
7087                         one: true,\r
7088                         ctx: context || this\r
7089                     });\r
7090 \r
7091                     return this;\r
7092                 },\r
7093 \r
7094                 /**\r
7095                  * 绑定事件\r
7096                  * @param {string} event 事件名\r
7097                  * @param {Function} handler 事件处理函数\r
7098                  * @param {Object} [context]\r
7099                  */\r
7100                 on: function (event, handler, context) {\r
7101                     var _h = this._$handlers;\r
7102 \r
7103                     if (!handler || !event) {\r
7104                         return this;\r
7105                     }\r
7106 \r
7107                     if (!_h[event]) {\r
7108                         _h[event] = [];\r
7109                     }\r
7110 \r
7111                     _h[event].push({\r
7112                         h: handler,\r
7113                         one: false,\r
7114                         ctx: context || this\r
7115                     });\r
7116 \r
7117                     return this;\r
7118                 },\r
7119 \r
7120                 /**\r
7121                  * 是否绑定了事件\r
7122                  * @param  {string}  event\r
7123                  * @return {boolean}\r
7124                  */\r
7125                 isSilent: function (event) {\r
7126                     var _h = this._$handlers;\r
7127                     return _h[event] && _h[event].length;\r
7128                 },\r
7129 \r
7130                 /**\r
7131                  * 解绑事件\r
7132                  * @param {string} event 事件名\r
7133                  * @param {Function} [handler] 事件处理函数\r
7134                  */\r
7135                 off: function (event, handler) {\r
7136                     var _h = this._$handlers;\r
7137 \r
7138                     if (!event) {\r
7139                         this._$handlers = {};\r
7140                         return this;\r
7141                     }\r
7142 \r
7143                     if (handler) {\r
7144                         if (_h[event]) {\r
7145                             var newList = [];\r
7146                             for (var i = 0, l = _h[event].length; i < l; i++) {\r
7147                                 if (_h[event][i]['h'] != handler) {\r
7148                                     newList.push(_h[event][i]);\r
7149                                 }\r
7150                             }\r
7151                             _h[event] = newList;\r
7152                         }\r
7153 \r
7154                         if (_h[event] && _h[event].length === 0) {\r
7155                             delete _h[event];\r
7156                         }\r
7157                     }\r
7158                     else {\r
7159                         delete _h[event];\r
7160                     }\r
7161 \r
7162                     return this;\r
7163                 },\r
7164 \r
7165                 /**\r
7166                  * 事件分发\r
7167                  *\r
7168                  * @param {string} type 事件类型\r
7169                  */\r
7170                 trigger: function (type) {\r
7171                     if (this._$handlers[type]) {\r
7172                         var args = arguments;\r
7173                         var argLen = args.length;\r
7174 \r
7175                         if (argLen > 3) {\r
7176                             args = arrySlice.call(args, 1);\r
7177                         }\r
7178 \r
7179                         var _h = this._$handlers[type];\r
7180                         var len = _h.length;\r
7181                         for (var i = 0; i < len;) {\r
7182                             // Optimize advise from backbone\r
7183                             switch (argLen) {\r
7184                                 case 1:\r
7185                                     _h[i]['h'].call(_h[i]['ctx']);\r
7186                                     break;\r
7187                                 case 2:\r
7188                                     _h[i]['h'].call(_h[i]['ctx'], args[1]);\r
7189                                     break;\r
7190                                 case 3:\r
7191                                     _h[i]['h'].call(_h[i]['ctx'], args[1], args[2]);\r
7192                                     break;\r
7193                                 default:\r
7194                                     // have more than 2 given arguments\r
7195                                     _h[i]['h'].apply(_h[i]['ctx'], args);\r
7196                                     break;\r
7197                             }\r
7198 \r
7199                             if (_h[i]['one']) {\r
7200                                 _h.splice(i, 1);\r
7201                                 len--;\r
7202                             }\r
7203                             else {\r
7204                                 i++;\r
7205                             }\r
7206                         }\r
7207                     }\r
7208 \r
7209                     return this;\r
7210                 },\r
7211 \r
7212                 /**\r
7213                  * 带有context的事件分发, 最后一个参数是事件回调的context\r
7214                  * @param {string} type 事件类型\r
7215                  */\r
7216                 triggerWithContext: function (type) {\r
7217                     if (this._$handlers[type]) {\r
7218                         var args = arguments;\r
7219                         var argLen = args.length;\r
7220 \r
7221                         if (argLen > 4) {\r
7222                             args = arrySlice.call(args, 1, args.length - 1);\r
7223                         }\r
7224                         var ctx = args[args.length - 1];\r
7225 \r
7226                         var _h = this._$handlers[type];\r
7227                         var len = _h.length;\r
7228                         for (var i = 0; i < len;) {\r
7229                             // Optimize advise from backbone\r
7230                             switch (argLen) {\r
7231                                 case 1:\r
7232                                     _h[i]['h'].call(ctx);\r
7233                                     break;\r
7234                                 case 2:\r
7235                                     _h[i]['h'].call(ctx, args[1]);\r
7236                                     break;\r
7237                                 case 3:\r
7238                                     _h[i]['h'].call(ctx, args[1], args[2]);\r
7239                                     break;\r
7240                                 default:\r
7241                                     // have more than 2 given arguments\r
7242                                     _h[i]['h'].apply(ctx, args);\r
7243                                     break;\r
7244                             }\r
7245 \r
7246                             if (_h[i]['one']) {\r
7247                                 _h.splice(i, 1);\r
7248                                 len--;\r
7249                             }\r
7250                             else {\r
7251                                 i++;\r
7252                             }\r
7253                         }\r
7254                     }\r
7255 \r
7256                     return this;\r
7257                 }\r
7258             };\r
7259 \r
7260             // 对象可以通过 onxxxx 绑定事件\r
7261             /**\r
7262              * @event module:zrender/mixin/Eventful#onclick\r
7263              * @type {Function}\r
7264              * @default null\r
7265              */\r
7266             /**\r
7267              * @event module:zrender/mixin/Eventful#onmouseover\r
7268              * @type {Function}\r
7269              * @default null\r
7270              */\r
7271             /**\r
7272              * @event module:zrender/mixin/Eventful#onmouseout\r
7273              * @type {Function}\r
7274              * @default null\r
7275              */\r
7276             /**\r
7277              * @event module:zrender/mixin/Eventful#onmousemove\r
7278              * @type {Function}\r
7279              * @default null\r
7280              */\r
7281             /**\r
7282              * @event module:zrender/mixin/Eventful#onmousewheel\r
7283              * @type {Function}\r
7284              * @default null\r
7285              */\r
7286             /**\r
7287              * @event module:zrender/mixin/Eventful#onmousedown\r
7288              * @type {Function}\r
7289              * @default null\r
7290              */\r
7291             /**\r
7292              * @event module:zrender/mixin/Eventful#onmouseup\r
7293              * @type {Function}\r
7294              * @default null\r
7295              */\r
7296             /**\r
7297              * @event module:zrender/mixin/Eventful#ondragstart\r
7298              * @type {Function}\r
7299              * @default null\r
7300              */\r
7301             /**\r
7302              * @event module:zrender/mixin/Eventful#ondragend\r
7303              * @type {Function}\r
7304              * @default null\r
7305              */\r
7306             /**\r
7307              * @event module:zrender/mixin/Eventful#ondragenter\r
7308              * @type {Function}\r
7309              * @default null\r
7310              */\r
7311             /**\r
7312              * @event module:zrender/mixin/Eventful#ondragleave\r
7313              * @type {Function}\r
7314              * @default null\r
7315              */\r
7316             /**\r
7317              * @event module:zrender/mixin/Eventful#ondragover\r
7318              * @type {Function}\r
7319              * @default null\r
7320              */\r
7321             /**\r
7322              * @event module:zrender/mixin/Eventful#ondrop\r
7323              * @type {Function}\r
7324              * @default null\r
7325              */\r
7326 \r
7327             module.exports = Eventful;\r
7328 \r
7329 \r
7330 \r
7331 /***/ },\r
7332 /* 33 */\r
7333 /***/ function(module, exports, __webpack_require__) {\r
7334 \r
7335         'use strict';\r
7336         /**\r
7337          * 提供变换扩展\r
7338          * @module zrender/mixin/Transformable\r
7339          * @author pissang (https://www.github.com/pissang)\r
7340          */\r
7341 \r
7342 \r
7343             var matrix = __webpack_require__(17);\r
7344             var vector = __webpack_require__(16);\r
7345             var mIdentity = matrix.identity;\r
7346 \r
7347             var EPSILON = 5e-5;\r
7348 \r
7349             function isNotAroundZero(val) {\r
7350                 return val > EPSILON || val < -EPSILON;\r
7351             }\r
7352 \r
7353             /**\r
7354              * @alias module:zrender/mixin/Transformable\r
7355              * @constructor\r
7356              */\r
7357             var Transformable = function (opts) {\r
7358                 opts = opts || {};\r
7359                 // If there are no given position, rotation, scale\r
7360                 if (!opts.position) {\r
7361                     /**\r
7362                      * 平移\r
7363                      * @type {Array.<number>}\r
7364                      * @default [0, 0]\r
7365                      */\r
7366                     this.position = [0, 0];\r
7367                 }\r
7368                 if (opts.rotation == null) {\r
7369                     /**\r
7370                      * 旋转\r
7371                      * @type {Array.<number>}\r
7372                      * @default 0\r
7373                      */\r
7374                     this.rotation = 0;\r
7375                 }\r
7376                 if (!opts.scale) {\r
7377                     /**\r
7378                      * 缩放\r
7379                      * @type {Array.<number>}\r
7380                      * @default [1, 1]\r
7381                      */\r
7382                     this.scale = [1, 1];\r
7383                 }\r
7384                 /**\r
7385                  * 旋转和缩放的原点\r
7386                  * @type {Array.<number>}\r
7387                  * @default null\r
7388                  */\r
7389                 this.origin = this.origin || null;\r
7390             };\r
7391 \r
7392             var transformableProto = Transformable.prototype;\r
7393             transformableProto.transform = null;\r
7394 \r
7395             /**\r
7396              * 判断是否需要有坐标变换\r
7397              * 如果有坐标变换, 则从position, rotation, scale以及父节点的transform计算出自身的transform矩阵\r
7398              */\r
7399             transformableProto.needLocalTransform = function () {\r
7400                 return isNotAroundZero(this.rotation)\r
7401                     || isNotAroundZero(this.position[0])\r
7402                     || isNotAroundZero(this.position[1])\r
7403                     || isNotAroundZero(this.scale[0] - 1)\r
7404                     || isNotAroundZero(this.scale[1] - 1);\r
7405             };\r
7406 \r
7407             transformableProto.updateTransform = function () {\r
7408                 var parent = this.parent;\r
7409                 var parentHasTransform = parent && parent.transform;\r
7410                 var needLocalTransform = this.needLocalTransform();\r
7411 \r
7412                 var m = this.transform;\r
7413                 if (!(needLocalTransform || parentHasTransform)) {\r
7414                     m && mIdentity(m);\r
7415                     return;\r
7416                 }\r
7417 \r
7418                 m = m || matrix.create();\r
7419 \r
7420                 if (needLocalTransform) {\r
7421                     this.getLocalTransform(m);\r
7422                 }\r
7423                 else {\r
7424                     mIdentity(m);\r
7425                 }\r
7426 \r
7427                 // 应用父节点变换\r
7428                 if (parentHasTransform) {\r
7429                     if (needLocalTransform) {\r
7430                         matrix.mul(m, parent.transform, m);\r
7431                     }\r
7432                     else {\r
7433                         matrix.copy(m, parent.transform);\r
7434                     }\r
7435                 }\r
7436                 // 保存这个变换矩阵\r
7437                 this.transform = m;\r
7438 \r
7439                 this.invTransform = this.invTransform || matrix.create();\r
7440                 matrix.invert(this.invTransform, m);\r
7441             };\r
7442 \r
7443             transformableProto.getLocalTransform = function (m) {\r
7444                 m = m || [];\r
7445                 mIdentity(m);\r
7446 \r
7447                 var origin = this.origin;\r
7448 \r
7449                 var scale = this.scale;\r
7450                 var rotation = this.rotation;\r
7451                 var position = this.position;\r
7452                 if (origin) {\r
7453                     // Translate to origin\r
7454                     m[4] -= origin[0];\r
7455                     m[5] -= origin[1];\r
7456                 }\r
7457                 matrix.scale(m, m, scale);\r
7458                 if (rotation) {\r
7459                     matrix.rotate(m, m, rotation);\r
7460                 }\r
7461                 if (origin) {\r
7462                     // Translate back from origin\r
7463                     m[4] += origin[0];\r
7464                     m[5] += origin[1];\r
7465                 }\r
7466 \r
7467                 m[4] += position[0];\r
7468                 m[5] += position[1];\r
7469 \r
7470                 return m;\r
7471             };\r
7472             /**\r
7473              * 将自己的transform应用到context上\r
7474              * @param {Context2D} ctx\r
7475              */\r
7476             transformableProto.setTransform = function (ctx) {\r
7477                 var m = this.transform;\r
7478                 if (m) {\r
7479                     ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\r
7480                 }\r
7481             };\r
7482 \r
7483             var tmpTransform = [];\r
7484 \r
7485             /**\r
7486              * 分解`transform`矩阵到`position`, `rotation`, `scale`\r
7487              */\r
7488             transformableProto.decomposeTransform = function () {\r
7489                 if (!this.transform) {\r
7490                     return;\r
7491                 }\r
7492                 var parent = this.parent;\r
7493                 var m = this.transform;\r
7494                 if (parent && parent.transform) {\r
7495                     // Get local transform and decompose them to position, scale, rotation\r
7496                     matrix.mul(tmpTransform, parent.invTransform, m);\r
7497                     m = tmpTransform;\r
7498                 }\r
7499                 var sx = m[0] * m[0] + m[1] * m[1];\r
7500                 var sy = m[2] * m[2] + m[3] * m[3];\r
7501                 var position = this.position;\r
7502                 var scale = this.scale;\r
7503                 if (isNotAroundZero(sx - 1)) {\r
7504                     sx = Math.sqrt(sx);\r
7505                 }\r
7506                 if (isNotAroundZero(sy - 1)) {\r
7507                     sy = Math.sqrt(sy);\r
7508                 }\r
7509                 if (m[0] < 0) {\r
7510                     sx = -sx;\r
7511                 }\r
7512                 if (m[3] < 0) {\r
7513                     sy = -sy;\r
7514                 }\r
7515                 position[0] = m[4];\r
7516                 position[1] = m[5];\r
7517                 scale[0] = sx;\r
7518                 scale[1] = sy;\r
7519                 this.rotation = Math.atan2(-m[1] / sy, m[0] / sx);\r
7520             };\r
7521 \r
7522             /**\r
7523              * 变换坐标位置到 shape 的局部坐标空间\r
7524              * @method\r
7525              * @param {number} x\r
7526              * @param {number} y\r
7527              * @return {Array.<number>}\r
7528              */\r
7529             transformableProto.transformCoordToLocal = function (x, y) {\r
7530                 var v2 = [x, y];\r
7531                 var invTransform = this.invTransform;\r
7532                 if (invTransform) {\r
7533                     vector.applyTransform(v2, v2, invTransform);\r
7534                 }\r
7535                 return v2;\r
7536             };\r
7537 \r
7538             /**\r
7539              * 变换局部坐标位置到全局坐标空间\r
7540              * @method\r
7541              * @param {number} x\r
7542              * @param {number} y\r
7543              * @return {Array.<number>}\r
7544              */\r
7545             transformableProto.transformCoordToGlobal = function (x, y) {\r
7546                 var v2 = [x, y];\r
7547                 var transform = this.transform;\r
7548                 if (transform) {\r
7549                     vector.applyTransform(v2, v2, transform);\r
7550                 }\r
7551                 return v2;\r
7552             };\r
7553 \r
7554             module.exports = Transformable;\r
7555 \r
7556 \r
7557 \r
7558 /***/ },\r
7559 /* 34 */\r
7560 /***/ function(module, exports, __webpack_require__) {\r
7561 \r
7562         'use strict';\r
7563         /**\r
7564          * @module zrender/mixin/Animatable\r
7565          */\r
7566 \r
7567 \r
7568             var Animator = __webpack_require__(35);\r
7569             var util = __webpack_require__(3);\r
7570             var isString = util.isString;\r
7571             var isFunction = util.isFunction;\r
7572             var isObject = util.isObject;\r
7573             var log = __webpack_require__(39);\r
7574 \r
7575             /**\r
7576              * @alias modue:zrender/mixin/Animatable\r
7577              * @constructor\r
7578              */\r
7579             var Animatable = function () {\r
7580 \r
7581                 /**\r
7582                  * @type {Array.<module:zrender/animation/Animator>}\r
7583                  * @readOnly\r
7584                  */\r
7585                 this.animators = [];\r
7586             };\r
7587 \r
7588             Animatable.prototype = {\r
7589 \r
7590                 constructor: Animatable,\r
7591 \r
7592                 /**\r
7593                  * 动画\r
7594                  *\r
7595                  * @param {string} path 需要添加动画的属性获取路径,可以通过a.b.c来获取深层的属性\r
7596                  * @param {boolean} [loop] 动画是否循环\r
7597                  * @return {module:zrender/animation/Animator}\r
7598                  * @example:\r
7599                  *     el.animate('style', false)\r
7600                  *         .when(1000, {x: 10} )\r
7601                  *         .done(function(){ // Animation done })\r
7602                  *         .start()\r
7603                  */\r
7604                 animate: function (path, loop) {\r
7605                     var target;\r
7606                     var animatingShape = false;\r
7607                     var el = this;\r
7608                     var zr = this.__zr;\r
7609                     if (path) {\r
7610                         var pathSplitted = path.split('.');\r
7611                         var prop = el;\r
7612                         // If animating shape\r
7613                         animatingShape = pathSplitted[0] === 'shape';\r
7614                         for (var i = 0, l = pathSplitted.length; i < l; i++) {\r
7615                             if (!prop) {\r
7616                                 continue;\r
7617                             }\r
7618                             prop = prop[pathSplitted[i]];\r
7619                         }\r
7620                         if (prop) {\r
7621                             target = prop;\r
7622                         }\r
7623                     }\r
7624                     else {\r
7625                         target = el;\r
7626                     }\r
7627 \r
7628                     if (!target) {\r
7629                         log(\r
7630                             'Property "'\r
7631                             + path\r
7632                             + '" is not existed in element '\r
7633                             + el.id\r
7634                         );\r
7635                         return;\r
7636                     }\r
7637 \r
7638                     var animators = el.animators;\r
7639 \r
7640                     var animator = new Animator(target, loop);\r
7641 \r
7642                     animator.during(function (target) {\r
7643                         el.dirty(animatingShape);\r
7644                     })\r
7645                     .done(function () {\r
7646                         // FIXME Animator will not be removed if use `Animator#stop` to stop animation\r
7647                         animators.splice(util.indexOf(animators, animator), 1);\r
7648                     });\r
7649 \r
7650                     animators.push(animator);\r
7651 \r
7652                     // If animate after added to the zrender\r
7653                     if (zr) {\r
7654                         zr.animation.addAnimator(animator);\r
7655                     }\r
7656 \r
7657                     return animator;\r
7658                 },\r
7659 \r
7660                 /**\r
7661                  * 停止动画\r
7662                  * @param {boolean} forwardToLast If move to last frame before stop\r
7663                  */\r
7664                 stopAnimation: function (forwardToLast) {\r
7665                     var animators = this.animators;\r
7666                     var len = animators.length;\r
7667                     for (var i = 0; i < len; i++) {\r
7668                         animators[i].stop(forwardToLast);\r
7669                     }\r
7670                     animators.length = 0;\r
7671 \r
7672                     return this;\r
7673                 },\r
7674 \r
7675                 /**\r
7676                  * @param {Object} target\r
7677                  * @param {number} [time=500] Time in ms\r
7678                  * @param {string} [easing='linear']\r
7679                  * @param {number} [delay=0]\r
7680                  * @param {Function} [callback]\r
7681                  *\r
7682                  * @example\r
7683                  *  // Animate position\r
7684                  *  el.animateTo({\r
7685                  *      position: [10, 10]\r
7686                  *  }, function () { // done })\r
7687                  *\r
7688                  *  // Animate shape, style and position in 100ms, delayed 100ms, with cubicOut easing\r
7689                  *  el.animateTo({\r
7690                  *      shape: {\r
7691                  *          width: 500\r
7692                  *      },\r
7693                  *      style: {\r
7694                  *          fill: 'red'\r
7695                  *      }\r
7696                  *      position: [10, 10]\r
7697                  *  }, 100, 100, 'cubicOut', function () { // done })\r
7698                  */\r
7699                  // TODO Return animation key\r
7700                 animateTo: function (target, time, delay, easing, callback) {\r
7701                     // animateTo(target, time, easing, callback);\r
7702                     if (isString(delay)) {\r
7703                         callback = easing;\r
7704                         easing = delay;\r
7705                         delay = 0;\r
7706                     }\r
7707                     // animateTo(target, time, delay, callback);\r
7708                     else if (isFunction(easing)) {\r
7709                         callback = easing;\r
7710                         easing = 'linear';\r
7711                         delay = 0;\r
7712                     }\r
7713                     // animateTo(target, time, callback);\r
7714                     else if (isFunction(delay)) {\r
7715                         callback = delay;\r
7716                         delay = 0;\r
7717                     }\r
7718                     // animateTo(target, callback)\r
7719                     else if (isFunction(time)) {\r
7720                         callback = time;\r
7721                         time = 500;\r
7722                     }\r
7723                     // animateTo(target)\r
7724                     else if (!time) {\r
7725                         time = 500;\r
7726                     }\r
7727                     // Stop all previous animations\r
7728                     this.stopAnimation();\r
7729                     this._animateToShallow('', this, target, time, delay, easing, callback);\r
7730 \r
7731                     // Animators may be removed immediately after start\r
7732                     // if there is nothing to animate\r
7733                     var animators = this.animators.slice();\r
7734                     var count = animators.length;\r
7735                     function done() {\r
7736                         count--;\r
7737                         if (!count) {\r
7738                             callback && callback();\r
7739                         }\r
7740                     }\r
7741 \r
7742                     // No animators. This should be checked before animators[i].start(),\r
7743                     // because 'done' may be executed immediately if no need to animate.\r
7744                     if (!count) {\r
7745                         callback && callback();\r
7746                     }\r
7747                     // Start after all animators created\r
7748                     // Incase any animator is done immediately when all animation properties are not changed\r
7749                     for (var i = 0; i < animators.length; i++) {\r
7750                         animators[i]\r
7751                             .done(done)\r
7752                             .start(easing);\r
7753                     }\r
7754                 },\r
7755 \r
7756                 /**\r
7757                  * @private\r
7758                  * @param {string} path=''\r
7759                  * @param {Object} source=this\r
7760                  * @param {Object} target\r
7761                  * @param {number} [time=500]\r
7762                  * @param {number} [delay=0]\r
7763                  *\r
7764                  * @example\r
7765                  *  // Animate position\r
7766                  *  el._animateToShallow({\r
7767                  *      position: [10, 10]\r
7768                  *  })\r
7769                  *\r
7770                  *  // Animate shape, style and position in 100ms, delayed 100ms\r
7771                  *  el._animateToShallow({\r
7772                  *      shape: {\r
7773                  *          width: 500\r
7774                  *      },\r
7775                  *      style: {\r
7776                  *          fill: 'red'\r
7777                  *      }\r
7778                  *      position: [10, 10]\r
7779                  *  }, 100, 100)\r
7780                  */\r
7781                 _animateToShallow: function (path, source, target, time, delay) {\r
7782                     var objShallow = {};\r
7783                     var propertyCount = 0;\r
7784                     for (var name in target) {\r
7785                         if (source[name] != null) {\r
7786                             if (isObject(target[name]) && !util.isArrayLike(target[name])) {\r
7787                                 this._animateToShallow(\r
7788                                     path ? path + '.' + name : name,\r
7789                                     source[name],\r
7790                                     target[name],\r
7791                                     time,\r
7792                                     delay\r
7793                                 );\r
7794                             }\r
7795                             else {\r
7796                                 objShallow[name] = target[name];\r
7797                                 propertyCount++;\r
7798                             }\r
7799                         }\r
7800                         else if (target[name] != null) {\r
7801                             // Attr directly if not has property\r
7802                             // FIXME, if some property not needed for element ?\r
7803                             if (!path) {\r
7804                                 this.attr(name, target[name]);\r
7805                             }\r
7806                             else {  // Shape or style\r
7807                                 var props = {};\r
7808                                 props[path] = {};\r
7809                                 props[path][name] = target[name];\r
7810                                 this.attr(props);\r
7811                             }\r
7812                         }\r
7813                     }\r
7814 \r
7815                     if (propertyCount > 0) {\r
7816                         this.animate(path, false)\r
7817                             .when(time == null ? 500 : time, objShallow)\r
7818                             .delay(delay || 0);\r
7819                     }\r
7820 \r
7821                     return this;\r
7822                 }\r
7823             };\r
7824 \r
7825             module.exports = Animatable;\r
7826 \r
7827 \r
7828 /***/ },\r
7829 /* 35 */\r
7830 /***/ function(module, exports, __webpack_require__) {\r
7831 \r
7832         /**\r
7833          * @module echarts/animation/Animator\r
7834          */\r
7835 \r
7836 \r
7837             var Clip = __webpack_require__(36);\r
7838             var color = __webpack_require__(38);\r
7839             var util = __webpack_require__(3);\r
7840             var isArrayLike = util.isArrayLike;\r
7841 \r
7842             var arraySlice = Array.prototype.slice;\r
7843 \r
7844             function defaultGetter(target, key) {\r
7845                 return target[key];\r
7846             }\r
7847 \r
7848             function defaultSetter(target, key, value) {\r
7849                 target[key] = value;\r
7850             }\r
7851 \r
7852             /**\r
7853              * @param  {number} p0\r
7854              * @param  {number} p1\r
7855              * @param  {number} percent\r
7856              * @return {number}\r
7857              */\r
7858             function interpolateNumber(p0, p1, percent) {\r
7859                 return (p1 - p0) * percent + p0;\r
7860             }\r
7861 \r
7862             /**\r
7863              * @param  {string} p0\r
7864              * @param  {string} p1\r
7865              * @param  {number} percent\r
7866              * @return {string}\r
7867              */\r
7868             function interpolateString(p0, p1, percent) {\r
7869                 return percent > 0.5 ? p1 : p0;\r
7870             }\r
7871 \r
7872             /**\r
7873              * @param  {Array} p0\r
7874              * @param  {Array} p1\r
7875              * @param  {number} percent\r
7876              * @param  {Array} out\r
7877              * @param  {number} arrDim\r
7878              */\r
7879             function interpolateArray(p0, p1, percent, out, arrDim) {\r
7880                 var len = p0.length;\r
7881                 if (arrDim == 1) {\r
7882                     for (var i = 0; i < len; i++) {\r
7883                         out[i] = interpolateNumber(p0[i], p1[i], percent);\r
7884                     }\r
7885                 }\r
7886                 else {\r
7887                     var len2 = p0[0].length;\r
7888                     for (var i = 0; i < len; i++) {\r
7889                         for (var j = 0; j < len2; j++) {\r
7890                             out[i][j] = interpolateNumber(\r
7891                                 p0[i][j], p1[i][j], percent\r
7892                             );\r
7893                         }\r
7894                     }\r
7895                 }\r
7896             }\r
7897 \r
7898             function fillArr(arr0, arr1, arrDim) {\r
7899                 var arr0Len = arr0.length;\r
7900                 var arr1Len = arr1.length;\r
7901                 if (arr0Len === arr1Len) {\r
7902                     return;\r
7903                 }\r
7904                 // FIXME Not work for TypedArray\r
7905                 var isPreviousLarger = arr0Len > arr1Len;\r
7906                 if (isPreviousLarger) {\r
7907                     // Cut the previous\r
7908                     arr0.length = arr1Len;\r
7909                 }\r
7910                 else {\r
7911                     // Fill the previous\r
7912                     for (var i = arr0Len; i < arr1Len; i++) {\r
7913                         arr0.push(\r
7914                             arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i])\r
7915                         );\r
7916                     }\r
7917                 }\r
7918             }\r
7919 \r
7920             /**\r
7921              * @param  {Array} arr0\r
7922              * @param  {Array} arr1\r
7923              * @param  {number} arrDim\r
7924              * @return {boolean}\r
7925              */\r
7926             function isArraySame(arr0, arr1, arrDim) {\r
7927                 if (arr0 === arr1) {\r
7928                     return true;\r
7929                 }\r
7930                 var len = arr0.length;\r
7931                 if (len !== arr1.length) {\r
7932                     return false;\r
7933                 }\r
7934                 if (arrDim === 1) {\r
7935                     for (var i = 0; i < len; i++) {\r
7936                         if (arr0[i] !== arr1[i]) {\r
7937                             return false;\r
7938                         }\r
7939                     }\r
7940                 }\r
7941                 else {\r
7942                     var len2 = arr0[0].length;\r
7943                     for (var i = 0; i < len; i++) {\r
7944                         for (var j = 0; j < len2; j++) {\r
7945                             if (arr0[i][j] !== arr1[i][j]) {\r
7946                                 return false;\r
7947                             }\r
7948                         }\r
7949                     }\r
7950                 }\r
7951                 return true;\r
7952             }\r
7953 \r
7954             /**\r
7955              * Catmull Rom interpolate array\r
7956              * @param  {Array} p0\r
7957              * @param  {Array} p1\r
7958              * @param  {Array} p2\r
7959              * @param  {Array} p3\r
7960              * @param  {number} t\r
7961              * @param  {number} t2\r
7962              * @param  {number} t3\r
7963              * @param  {Array} out\r
7964              * @param  {number} arrDim\r
7965              */\r
7966             function catmullRomInterpolateArray(\r
7967                 p0, p1, p2, p3, t, t2, t3, out, arrDim\r
7968             ) {\r
7969                 var len = p0.length;\r
7970                 if (arrDim == 1) {\r
7971                     for (var i = 0; i < len; i++) {\r
7972                         out[i] = catmullRomInterpolate(\r
7973                             p0[i], p1[i], p2[i], p3[i], t, t2, t3\r
7974                         );\r
7975                     }\r
7976                 }\r
7977                 else {\r
7978                     var len2 = p0[0].length;\r
7979                     for (var i = 0; i < len; i++) {\r
7980                         for (var j = 0; j < len2; j++) {\r
7981                             out[i][j] = catmullRomInterpolate(\r
7982                                 p0[i][j], p1[i][j], p2[i][j], p3[i][j],\r
7983                                 t, t2, t3\r
7984                             );\r
7985                         }\r
7986                     }\r
7987                 }\r
7988             }\r
7989 \r
7990             /**\r
7991              * Catmull Rom interpolate number\r
7992              * @param  {number} p0\r
7993              * @param  {number} p1\r
7994              * @param  {number} p2\r
7995              * @param  {number} p3\r
7996              * @param  {number} t\r
7997              * @param  {number} t2\r
7998              * @param  {number} t3\r
7999              * @return {number}\r
8000              */\r
8001             function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {\r
8002                 var v0 = (p2 - p0) * 0.5;\r
8003                 var v1 = (p3 - p1) * 0.5;\r
8004                 return (2 * (p1 - p2) + v0 + v1) * t3\r
8005                         + (-3 * (p1 - p2) - 2 * v0 - v1) * t2\r
8006                         + v0 * t + p1;\r
8007             }\r
8008 \r
8009             function cloneValue(value) {\r
8010                 if (isArrayLike(value)) {\r
8011                     var len = value.length;\r
8012                     if (isArrayLike(value[0])) {\r
8013                         var ret = [];\r
8014                         for (var i = 0; i < len; i++) {\r
8015                             ret.push(arraySlice.call(value[i]));\r
8016                         }\r
8017                         return ret;\r
8018                     }\r
8019 \r
8020                     return arraySlice.call(value);\r
8021                 }\r
8022 \r
8023                 return value;\r
8024             }\r
8025 \r
8026             function rgba2String(rgba) {\r
8027                 rgba[0] = Math.floor(rgba[0]);\r
8028                 rgba[1] = Math.floor(rgba[1]);\r
8029                 rgba[2] = Math.floor(rgba[2]);\r
8030 \r
8031                 return 'rgba(' + rgba.join(',') + ')';\r
8032             }\r
8033 \r
8034             function createTrackClip (animator, easing, oneTrackDone, keyframes, propName) {\r
8035                 var getter = animator._getter;\r
8036                 var setter = animator._setter;\r
8037                 var useSpline = easing === 'spline';\r
8038 \r
8039                 var trackLen = keyframes.length;\r
8040                 if (!trackLen) {\r
8041                     return;\r
8042                 }\r
8043                 // Guess data type\r
8044                 var firstVal = keyframes[0].value;\r
8045                 var isValueArray = isArrayLike(firstVal);\r
8046                 var isValueColor = false;\r
8047                 var isValueString = false;\r
8048 \r
8049                 // For vertices morphing\r
8050                 var arrDim = (\r
8051                         isValueArray\r
8052                         && isArrayLike(firstVal[0])\r
8053                     )\r
8054                     ? 2 : 1;\r
8055                 var trackMaxTime;\r
8056                 // Sort keyframe as ascending\r
8057                 keyframes.sort(function(a, b) {\r
8058                     return a.time - b.time;\r
8059                 });\r
8060 \r
8061                 trackMaxTime = keyframes[trackLen - 1].time;\r
8062                 // Percents of each keyframe\r
8063                 var kfPercents = [];\r
8064                 // Value of each keyframe\r
8065                 var kfValues = [];\r
8066                 var prevValue = keyframes[0].value;\r
8067                 var isAllValueEqual = true;\r
8068                 for (var i = 0; i < trackLen; i++) {\r
8069                     kfPercents.push(keyframes[i].time / trackMaxTime);\r
8070                     // Assume value is a color when it is a string\r
8071                     var value = keyframes[i].value;\r
8072 \r
8073                     // Check if value is equal, deep check if value is array\r
8074                     if (!((isValueArray && isArraySame(value, prevValue, arrDim))\r
8075                         || (!isValueArray && value === prevValue))) {\r
8076                         isAllValueEqual = false;\r
8077                     }\r
8078                     prevValue = value;\r
8079 \r
8080                     // Try converting a string to a color array\r
8081                     if (typeof value == 'string') {\r
8082                         var colorArray = color.parse(value);\r
8083                         if (colorArray) {\r
8084                             value = colorArray;\r
8085                             isValueColor = true;\r
8086                         }\r
8087                         else {\r
8088                             isValueString = true;\r
8089                         }\r
8090                     }\r
8091                     kfValues.push(value);\r
8092                 }\r
8093                 if (isAllValueEqual) {\r
8094                     return;\r
8095                 }\r
8096 \r
8097                 if (isValueArray) {\r
8098                     var lastValue = kfValues[trackLen - 1];\r
8099                     // Polyfill array\r
8100                     for (var i = 0; i < trackLen - 1; i++) {\r
8101                         fillArr(kfValues[i], lastValue, arrDim);\r
8102                     }\r
8103                     fillArr(getter(animator._target, propName), lastValue, arrDim);\r
8104                 }\r
8105 \r
8106                 // Cache the key of last frame to speed up when\r
8107                 // animation playback is sequency\r
8108                 var lastFrame = 0;\r
8109                 var lastFramePercent = 0;\r
8110                 var start;\r
8111                 var w;\r
8112                 var p0;\r
8113                 var p1;\r
8114                 var p2;\r
8115                 var p3;\r
8116 \r
8117                 if (isValueColor) {\r
8118                     var rgba = [0, 0, 0, 0];\r
8119                 }\r
8120 \r
8121                 var onframe = function (target, percent) {\r
8122                     // Find the range keyframes\r
8123                     // kf1-----kf2---------current--------kf3\r
8124                     // find kf2 and kf3 and do interpolation\r
8125                     var frame;\r
8126                     if (percent < lastFramePercent) {\r
8127                         // Start from next key\r
8128                         start = Math.min(lastFrame + 1, trackLen - 1);\r
8129                         for (frame = start; frame >= 0; frame--) {\r
8130                             if (kfPercents[frame] <= percent) {\r
8131                                 break;\r
8132                             }\r
8133                         }\r
8134                         frame = Math.min(frame, trackLen - 2);\r
8135                     }\r
8136                     else {\r
8137                         for (frame = lastFrame; frame < trackLen; frame++) {\r
8138                             if (kfPercents[frame] > percent) {\r
8139                                 break;\r
8140                             }\r
8141                         }\r
8142                         frame = Math.min(frame - 1, trackLen - 2);\r
8143                     }\r
8144                     lastFrame = frame;\r
8145                     lastFramePercent = percent;\r
8146 \r
8147                     var range = (kfPercents[frame + 1] - kfPercents[frame]);\r
8148                     if (range === 0) {\r
8149                         return;\r
8150                     }\r
8151                     else {\r
8152                         w = (percent - kfPercents[frame]) / range;\r
8153                     }\r
8154                     if (useSpline) {\r
8155                         p1 = kfValues[frame];\r
8156                         p0 = kfValues[frame === 0 ? frame : frame - 1];\r
8157                         p2 = kfValues[frame > trackLen - 2 ? trackLen - 1 : frame + 1];\r
8158                         p3 = kfValues[frame > trackLen - 3 ? trackLen - 1 : frame + 2];\r
8159                         if (isValueArray) {\r
8160                             catmullRomInterpolateArray(\r
8161                                 p0, p1, p2, p3, w, w * w, w * w * w,\r
8162                                 getter(target, propName),\r
8163                                 arrDim\r
8164                             );\r
8165                         }\r
8166                         else {\r
8167                             var value;\r
8168                             if (isValueColor) {\r
8169                                 value = catmullRomInterpolateArray(\r
8170                                     p0, p1, p2, p3, w, w * w, w * w * w,\r
8171                                     rgba, 1\r
8172                                 );\r
8173                                 value = rgba2String(rgba);\r
8174                             }\r
8175                             else if (isValueString) {\r
8176                                 // String is step(0.5)\r
8177                                 return interpolateString(p1, p2, w);\r
8178                             }\r
8179                             else {\r
8180                                 value = catmullRomInterpolate(\r
8181                                     p0, p1, p2, p3, w, w * w, w * w * w\r
8182                                 );\r
8183                             }\r
8184                             setter(\r
8185                                 target,\r
8186                                 propName,\r
8187                                 value\r
8188                             );\r
8189                         }\r
8190                     }\r
8191                     else {\r
8192                         if (isValueArray) {\r
8193                             interpolateArray(\r
8194                                 kfValues[frame], kfValues[frame + 1], w,\r
8195                                 getter(target, propName),\r
8196                                 arrDim\r
8197                             );\r
8198                         }\r
8199                         else {\r
8200                             var value;\r
8201                             if (isValueColor) {\r
8202                                 interpolateArray(\r
8203                                     kfValues[frame], kfValues[frame + 1], w,\r
8204                                     rgba, 1\r
8205                                 );\r
8206                                 value = rgba2String(rgba);\r
8207                             }\r
8208                             else if (isValueString) {\r
8209                                 // String is step(0.5)\r
8210                                 return interpolateString(kfValues[frame], kfValues[frame + 1], w);\r
8211                             }\r
8212                             else {\r
8213                                 value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w);\r
8214                             }\r
8215                             setter(\r
8216                                 target,\r
8217                                 propName,\r
8218                                 value\r
8219                             );\r
8220                         }\r
8221                     }\r
8222                 };\r
8223 \r
8224                 var clip = new Clip({\r
8225                     target: animator._target,\r
8226                     life: trackMaxTime,\r
8227                     loop: animator._loop,\r
8228                     delay: animator._delay,\r
8229                     onframe: onframe,\r
8230                     ondestroy: oneTrackDone\r
8231                 });\r
8232 \r
8233                 if (easing && easing !== 'spline') {\r
8234                     clip.easing = easing;\r
8235                 }\r
8236 \r
8237                 return clip;\r
8238             }\r
8239 \r
8240             /**\r
8241              * @alias module:zrender/animation/Animator\r
8242              * @constructor\r
8243              * @param {Object} target\r
8244              * @param {boolean} loop\r
8245              * @param {Function} getter\r
8246              * @param {Function} setter\r
8247              */\r
8248             var Animator = function(target, loop, getter, setter) {\r
8249                 this._tracks = {};\r
8250                 this._target = target;\r
8251 \r
8252                 this._loop = loop || false;\r
8253 \r
8254                 this._getter = getter || defaultGetter;\r
8255                 this._setter = setter || defaultSetter;\r
8256 \r
8257                 this._clipCount = 0;\r
8258 \r
8259                 this._delay = 0;\r
8260 \r
8261                 this._doneList = [];\r
8262 \r
8263                 this._onframeList = [];\r
8264 \r
8265                 this._clipList = [];\r
8266             };\r
8267 \r
8268             Animator.prototype = {\r
8269                 /**\r
8270                  * 设置动画关键帧\r
8271                  * @param  {number} time 关键帧时间,单位是ms\r
8272                  * @param  {Object} props 关键帧的属性值,key-value表示\r
8273                  * @return {module:zrender/animation/Animator}\r
8274                  */\r
8275                 when: function(time /* ms */, props) {\r
8276                     var tracks = this._tracks;\r
8277                     for (var propName in props) {\r
8278                         if (!tracks[propName]) {\r
8279                             tracks[propName] = [];\r
8280                             // Invalid value\r
8281                             var value = this._getter(this._target, propName);\r
8282                             if (value == null) {\r
8283                                 // zrLog('Invalid property ' + propName);\r
8284                                 continue;\r
8285                             }\r
8286                             // If time is 0\r
8287                             //  Then props is given initialize value\r
8288                             // Else\r
8289                             //  Initialize value from current prop value\r
8290                             if (time !== 0) {\r
8291                                 tracks[propName].push({\r
8292                                     time: 0,\r
8293                                     value: cloneValue(value)\r
8294                                 });\r
8295                             }\r
8296                         }\r
8297                         tracks[propName].push({\r
8298                             time: time,\r
8299                             value: props[propName]\r
8300                         });\r
8301                     }\r
8302                     return this;\r
8303                 },\r
8304                 /**\r
8305                  * 添加动画每一帧的回调函数\r
8306                  * @param  {Function} callback\r
8307                  * @return {module:zrender/animation/Animator}\r
8308                  */\r
8309                 during: function (callback) {\r
8310                     this._onframeList.push(callback);\r
8311                     return this;\r
8312                 },\r
8313 \r
8314                 _doneCallback: function () {\r
8315                     // Clear all tracks\r
8316                     this._tracks = {};\r
8317                     // Clear all clips\r
8318                     this._clipList.length = 0;\r
8319 \r
8320                     var doneList = this._doneList;\r
8321                     var len = doneList.length;\r
8322                     for (var i = 0; i < len; i++) {\r
8323                         doneList[i].call(this);\r
8324                     }\r
8325                 },\r
8326                 /**\r
8327                  * 开始执行动画\r
8328                  * @param  {string|Function} easing\r
8329                  *         动画缓动函数,详见{@link module:zrender/animation/easing}\r
8330                  * @return {module:zrender/animation/Animator}\r
8331                  */\r
8332                 start: function (easing) {\r
8333 \r
8334                     var self = this;\r
8335                     var clipCount = 0;\r
8336 \r
8337                     var oneTrackDone = function() {\r
8338                         clipCount--;\r
8339                         if (!clipCount) {\r
8340                             self._doneCallback();\r
8341                         }\r
8342                     };\r
8343 \r
8344                     var lastClip;\r
8345                     for (var propName in this._tracks) {\r
8346                         var clip = createTrackClip(\r
8347                             this, easing, oneTrackDone,\r
8348                             this._tracks[propName], propName\r
8349                         );\r
8350                         if (clip) {\r
8351                             this._clipList.push(clip);\r
8352                             clipCount++;\r
8353 \r
8354                             // If start after added to animation\r
8355                             if (this.animation) {\r
8356                                 this.animation.addClip(clip);\r
8357                             }\r
8358 \r
8359                             lastClip = clip;\r
8360                         }\r
8361                     }\r
8362 \r
8363                     // Add during callback on the last clip\r
8364                     if (lastClip) {\r
8365                         var oldOnFrame = lastClip.onframe;\r
8366                         lastClip.onframe = function (target, percent) {\r
8367                             oldOnFrame(target, percent);\r
8368 \r
8369                             for (var i = 0; i < self._onframeList.length; i++) {\r
8370                                 self._onframeList[i](target, percent);\r
8371                             }\r
8372                         };\r
8373                     }\r
8374 \r
8375                     if (!clipCount) {\r
8376                         this._doneCallback();\r
8377                     }\r
8378                     return this;\r
8379                 },\r
8380                 /**\r
8381                  * 停止动画\r
8382                  * @param {boolean} forwardToLast If move to last frame before stop\r
8383                  */\r
8384                 stop: function (forwardToLast) {\r
8385                     var clipList = this._clipList;\r
8386                     var animation = this.animation;\r
8387                     for (var i = 0; i < clipList.length; i++) {\r
8388                         var clip = clipList[i];\r
8389                         if (forwardToLast) {\r
8390                             // Move to last frame before stop\r
8391                             clip.onframe(this._target, 1);\r
8392                         }\r
8393                         animation && animation.removeClip(clip);\r
8394                     }\r
8395                     clipList.length = 0;\r
8396                 },\r
8397                 /**\r
8398                  * 设置动画延迟开始的时间\r
8399                  * @param  {number} time 单位ms\r
8400                  * @return {module:zrender/animation/Animator}\r
8401                  */\r
8402                 delay: function (time) {\r
8403                     this._delay = time;\r
8404                     return this;\r
8405                 },\r
8406                 /**\r
8407                  * 添加动画结束的回调\r
8408                  * @param  {Function} cb\r
8409                  * @return {module:zrender/animation/Animator}\r
8410                  */\r
8411                 done: function(cb) {\r
8412                     if (cb) {\r
8413                         this._doneList.push(cb);\r
8414                     }\r
8415                     return this;\r
8416                 },\r
8417 \r
8418                 /**\r
8419                  * @return {Array.<module:zrender/animation/Clip>}\r
8420                  */\r
8421                 getClips: function () {\r
8422                     return this._clipList;\r
8423                 }\r
8424             };\r
8425 \r
8426             module.exports = Animator;\r
8427 \r
8428 \r
8429 /***/ },\r
8430 /* 36 */\r
8431 /***/ function(module, exports, __webpack_require__) {\r
8432 \r
8433         /**\r
8434          * 动画主控制器\r
8435          * @config target 动画对象,可以是数组,如果是数组的话会批量分发onframe等事件\r
8436          * @config life(1000) 动画时长\r
8437          * @config delay(0) 动画延迟时间\r
8438          * @config loop(true)\r
8439          * @config gap(0) 循环的间隔时间\r
8440          * @config onframe\r
8441          * @config easing(optional)\r
8442          * @config ondestroy(optional)\r
8443          * @config onrestart(optional)\r
8444          *\r
8445          * TODO pause\r
8446          */\r
8447 \r
8448 \r
8449             var easingFuncs = __webpack_require__(37);\r
8450 \r
8451             function Clip(options) {\r
8452 \r
8453                 this._target = options.target;\r
8454 \r
8455                 // 生命周期\r
8456                 this._life = options.life || 1000;\r
8457                 // 延时\r
8458                 this._delay = options.delay || 0;\r
8459                 // 开始时间\r
8460                 // this._startTime = new Date().getTime() + this._delay;// 单位毫秒\r
8461                 this._initialized = false;\r
8462 \r
8463                 // 是否循环\r
8464                 this.loop = options.loop == null ? false : options.loop;\r
8465 \r
8466                 this.gap = options.gap || 0;\r
8467 \r
8468                 this.easing = options.easing || 'Linear';\r
8469 \r
8470                 this.onframe = options.onframe;\r
8471                 this.ondestroy = options.ondestroy;\r
8472                 this.onrestart = options.onrestart;\r
8473             }\r
8474 \r
8475             Clip.prototype = {\r
8476 \r
8477                 constructor: Clip,\r
8478 \r
8479                 step: function (time) {\r
8480                     // Set startTime on first step, or _startTime may has milleseconds different between clips\r
8481                     // PENDING\r
8482                     if (!this._initialized) {\r
8483                         this._startTime = new Date().getTime() + this._delay;\r
8484                         this._initialized = true;\r
8485                     }\r
8486 \r
8487                     var percent = (time - this._startTime) / this._life;\r
8488 \r
8489                     // 还没开始\r
8490                     if (percent < 0) {\r
8491                         return;\r
8492                     }\r
8493 \r
8494                     percent = Math.min(percent, 1);\r
8495 \r
8496                     var easing = this.easing;\r
8497                     var easingFunc = typeof easing == 'string' ? easingFuncs[easing] : easing;\r
8498                     var schedule = typeof easingFunc === 'function'\r
8499                         ? easingFunc(percent)\r
8500                         : percent;\r
8501 \r
8502                     this.fire('frame', schedule);\r
8503 \r
8504                     // 结束\r
8505                     if (percent == 1) {\r
8506                         if (this.loop) {\r
8507                             this.restart();\r
8508                             // 重新开始周期\r
8509                             // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件\r
8510                             return 'restart';\r
8511                         }\r
8512 \r
8513                         // 动画完成将这个控制器标识为待删除\r
8514                         // 在Animation.update中进行批量删除\r
8515                         this._needsRemove = true;\r
8516                         return 'destroy';\r
8517                     }\r
8518 \r
8519                     return null;\r
8520                 },\r
8521 \r
8522                 restart: function() {\r
8523                     var time = new Date().getTime();\r
8524                     var remainder = (time - this._startTime) % this._life;\r
8525                     this._startTime = new Date().getTime() - remainder + this.gap;\r
8526 \r
8527                     this._needsRemove = false;\r
8528                 },\r
8529 \r
8530                 fire: function(eventType, arg) {\r
8531                     eventType = 'on' + eventType;\r
8532                     if (this[eventType]) {\r
8533                         this[eventType](this._target, arg);\r
8534                     }\r
8535                 }\r
8536             };\r
8537 \r
8538             module.exports = Clip;\r
8539 \r
8540 \r
8541 \r
8542 /***/ },\r
8543 /* 37 */\r
8544 /***/ function(module, exports) {\r
8545 \r
8546         /**\r
8547          * 缓动代码来自 https://github.com/sole/tween.js/blob/master/src/Tween.js\r
8548          * @see http://sole.github.io/tween.js/examples/03_graphs.html\r
8549          * @exports zrender/animation/easing\r
8550          */\r
8551 \r
8552             var easing = {\r
8553                 /**\r
8554                 * @param {number} k\r
8555                 * @return {number}\r
8556                 */\r
8557                 linear: function (k) {\r
8558                     return k;\r
8559                 },\r
8560 \r
8561                 /**\r
8562                 * @param {number} k\r
8563                 * @return {number}\r
8564                 */\r
8565                 quadraticIn: function (k) {\r
8566                     return k * k;\r
8567                 },\r
8568                 /**\r
8569                 * @param {number} k\r
8570                 * @return {number}\r
8571                 */\r
8572                 quadraticOut: function (k) {\r
8573                     return k * (2 - k);\r
8574                 },\r
8575                 /**\r
8576                 * @param {number} k\r
8577                 * @return {number}\r
8578                 */\r
8579                 quadraticInOut: function (k) {\r
8580                     if ((k *= 2) < 1) {\r
8581                         return 0.5 * k * k;\r
8582                     }\r
8583                     return -0.5 * (--k * (k - 2) - 1);\r
8584                 },\r
8585 \r
8586                 // 三次方的缓动(t^3)\r
8587                 /**\r
8588                 * @param {number} k\r
8589                 * @return {number}\r
8590                 */\r
8591                 cubicIn: function (k) {\r
8592                     return k * k * k;\r
8593                 },\r
8594                 /**\r
8595                 * @param {number} k\r
8596                 * @return {number}\r
8597                 */\r
8598                 cubicOut: function (k) {\r
8599                     return --k * k * k + 1;\r
8600                 },\r
8601                 /**\r
8602                 * @param {number} k\r
8603                 * @return {number}\r
8604                 */\r
8605                 cubicInOut: function (k) {\r
8606                     if ((k *= 2) < 1) {\r
8607                         return 0.5 * k * k * k;\r
8608                     }\r
8609                     return 0.5 * ((k -= 2) * k * k + 2);\r
8610                 },\r
8611 \r
8612                 // 四次方的缓动(t^4)\r
8613                 /**\r
8614                 * @param {number} k\r
8615                 * @return {number}\r
8616                 */\r
8617                 quarticIn: function (k) {\r
8618                     return k * k * k * k;\r
8619                 },\r
8620                 /**\r
8621                 * @param {number} k\r
8622                 * @return {number}\r
8623                 */\r
8624                 quarticOut: function (k) {\r
8625                     return 1 - (--k * k * k * k);\r
8626                 },\r
8627                 /**\r
8628                 * @param {number} k\r
8629                 * @return {number}\r
8630                 */\r
8631                 quarticInOut: function (k) {\r
8632                     if ((k *= 2) < 1) {\r
8633                         return 0.5 * k * k * k * k;\r
8634                     }\r
8635                     return -0.5 * ((k -= 2) * k * k * k - 2);\r
8636                 },\r
8637 \r
8638                 // 五次方的缓动(t^5)\r
8639                 /**\r
8640                 * @param {number} k\r
8641                 * @return {number}\r
8642                 */\r
8643                 quinticIn: function (k) {\r
8644                     return k * k * k * k * k;\r
8645                 },\r
8646                 /**\r
8647                 * @param {number} k\r
8648                 * @return {number}\r
8649                 */\r
8650                 quinticOut: function (k) {\r
8651                     return --k * k * k * k * k + 1;\r
8652                 },\r
8653                 /**\r
8654                 * @param {number} k\r
8655                 * @return {number}\r
8656                 */\r
8657                 quinticInOut: function (k) {\r
8658                     if ((k *= 2) < 1) {\r
8659                         return 0.5 * k * k * k * k * k;\r
8660                     }\r
8661                     return 0.5 * ((k -= 2) * k * k * k * k + 2);\r
8662                 },\r
8663 \r
8664                 // 正弦曲线的缓动(sin(t))\r
8665                 /**\r
8666                 * @param {number} k\r
8667                 * @return {number}\r
8668                 */\r
8669                 sinusoidalIn: function (k) {\r
8670                     return 1 - Math.cos(k * Math.PI / 2);\r
8671                 },\r
8672                 /**\r
8673                 * @param {number} k\r
8674                 * @return {number}\r
8675                 */\r
8676                 sinusoidalOut: function (k) {\r
8677                     return Math.sin(k * Math.PI / 2);\r
8678                 },\r
8679                 /**\r
8680                 * @param {number} k\r
8681                 * @return {number}\r
8682                 */\r
8683                 sinusoidalInOut: function (k) {\r
8684                     return 0.5 * (1 - Math.cos(Math.PI * k));\r
8685                 },\r
8686 \r
8687                 // 指数曲线的缓动(2^t)\r
8688                 /**\r
8689                 * @param {number} k\r
8690                 * @return {number}\r
8691                 */\r
8692                 exponentialIn: function (k) {\r
8693                     return k === 0 ? 0 : Math.pow(1024, k - 1);\r
8694                 },\r
8695                 /**\r
8696                 * @param {number} k\r
8697                 * @return {number}\r
8698                 */\r
8699                 exponentialOut: function (k) {\r
8700                     return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);\r
8701                 },\r
8702                 /**\r
8703                 * @param {number} k\r
8704                 * @return {number}\r
8705                 */\r
8706                 exponentialInOut: function (k) {\r
8707                     if (k === 0) {\r
8708                         return 0;\r
8709                     }\r
8710                     if (k === 1) {\r
8711                         return 1;\r
8712                     }\r
8713                     if ((k *= 2) < 1) {\r
8714                         return 0.5 * Math.pow(1024, k - 1);\r
8715                     }\r
8716                     return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);\r
8717                 },\r
8718 \r
8719                 // 圆形曲线的缓动(sqrt(1-t^2))\r
8720                 /**\r
8721                 * @param {number} k\r
8722                 * @return {number}\r
8723                 */\r
8724                 circularIn: function (k) {\r
8725                     return 1 - Math.sqrt(1 - k * k);\r
8726                 },\r
8727                 /**\r
8728                 * @param {number} k\r
8729                 * @return {number}\r
8730                 */\r
8731                 circularOut: function (k) {\r
8732                     return Math.sqrt(1 - (--k * k));\r
8733                 },\r
8734                 /**\r
8735                 * @param {number} k\r
8736                 * @return {number}\r
8737                 */\r
8738                 circularInOut: function (k) {\r
8739                     if ((k *= 2) < 1) {\r
8740                         return -0.5 * (Math.sqrt(1 - k * k) - 1);\r
8741                     }\r
8742                     return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);\r
8743                 },\r
8744 \r
8745                 // 创建类似于弹簧在停止前来回振荡的动画\r
8746                 /**\r
8747                 * @param {number} k\r
8748                 * @return {number}\r
8749                 */\r
8750                 elasticIn: function (k) {\r
8751                     var s;\r
8752                     var a = 0.1;\r
8753                     var p = 0.4;\r
8754                     if (k === 0) {\r
8755                         return 0;\r
8756                     }\r
8757                     if (k === 1) {\r
8758                         return 1;\r
8759                     }\r
8760                     if (!a || a < 1) {\r
8761                         a = 1; s = p / 4;\r
8762                     }\r
8763                     else {\r
8764                         s = p * Math.asin(1 / a) / (2 * Math.PI);\r
8765                     }\r
8766                     return -(a * Math.pow(2, 10 * (k -= 1)) *\r
8767                                 Math.sin((k - s) * (2 * Math.PI) / p));\r
8768                 },\r
8769                 /**\r
8770                 * @param {number} k\r
8771                 * @return {number}\r
8772                 */\r
8773                 elasticOut: function (k) {\r
8774                     var s;\r
8775                     var a = 0.1;\r
8776                     var p = 0.4;\r
8777                     if (k === 0) {\r
8778                         return 0;\r
8779                     }\r
8780                     if (k === 1) {\r
8781                         return 1;\r
8782                     }\r
8783                     if (!a || a < 1) {\r
8784                         a = 1; s = p / 4;\r
8785                     }\r
8786                     else {\r
8787                         s = p * Math.asin(1 / a) / (2 * Math.PI);\r
8788                     }\r
8789                     return (a * Math.pow(2, -10 * k) *\r
8790                             Math.sin((k - s) * (2 * Math.PI) / p) + 1);\r
8791                 },\r
8792                 /**\r
8793                 * @param {number} k\r
8794                 * @return {number}\r
8795                 */\r
8796                 elasticInOut: function (k) {\r
8797                     var s;\r
8798                     var a = 0.1;\r
8799                     var p = 0.4;\r
8800                     if (k === 0) {\r
8801                         return 0;\r
8802                     }\r
8803                     if (k === 1) {\r
8804                         return 1;\r
8805                     }\r
8806                     if (!a || a < 1) {\r
8807                         a = 1; s = p / 4;\r
8808                     }\r
8809                     else {\r
8810                         s = p * Math.asin(1 / a) / (2 * Math.PI);\r
8811                     }\r
8812                     if ((k *= 2) < 1) {\r
8813                         return -0.5 * (a * Math.pow(2, 10 * (k -= 1))\r
8814                             * Math.sin((k - s) * (2 * Math.PI) / p));\r
8815                     }\r
8816                     return a * Math.pow(2, -10 * (k -= 1))\r
8817                             * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;\r
8818 \r
8819                 },\r
8820 \r
8821                 // 在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动\r
8822                 /**\r
8823                 * @param {number} k\r
8824                 * @return {number}\r
8825                 */\r
8826                 backIn: function (k) {\r
8827                     var s = 1.70158;\r
8828                     return k * k * ((s + 1) * k - s);\r
8829                 },\r
8830                 /**\r
8831                 * @param {number} k\r
8832                 * @return {number}\r
8833                 */\r
8834                 backOut: function (k) {\r
8835                     var s = 1.70158;\r
8836                     return --k * k * ((s + 1) * k + s) + 1;\r
8837                 },\r
8838                 /**\r
8839                 * @param {number} k\r
8840                 * @return {number}\r
8841                 */\r
8842                 backInOut: function (k) {\r
8843                     var s = 1.70158 * 1.525;\r
8844                     if ((k *= 2) < 1) {\r
8845                         return 0.5 * (k * k * ((s + 1) * k - s));\r
8846                     }\r
8847                     return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);\r
8848                 },\r
8849 \r
8850                 // 创建弹跳效果\r
8851                 /**\r
8852                 * @param {number} k\r
8853                 * @return {number}\r
8854                 */\r
8855                 bounceIn: function (k) {\r
8856                     return 1 - easing.bounceOut(1 - k);\r
8857                 },\r
8858                 /**\r
8859                 * @param {number} k\r
8860                 * @return {number}\r
8861                 */\r
8862                 bounceOut: function (k) {\r
8863                     if (k < (1 / 2.75)) {\r
8864                         return 7.5625 * k * k;\r
8865                     }\r
8866                     else if (k < (2 / 2.75)) {\r
8867                         return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;\r
8868                     }\r
8869                     else if (k < (2.5 / 2.75)) {\r
8870                         return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;\r
8871                     }\r
8872                     else {\r
8873                         return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;\r
8874                     }\r
8875                 },\r
8876                 /**\r
8877                 * @param {number} k\r
8878                 * @return {number}\r
8879                 */\r
8880                 bounceInOut: function (k) {\r
8881                     if (k < 0.5) {\r
8882                         return easing.bounceIn(k * 2) * 0.5;\r
8883                     }\r
8884                     return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;\r
8885                 }\r
8886             };\r
8887 \r
8888             module.exports = easing;\r
8889 \r
8890 \r
8891 \r
8892 \r
8893 /***/ },\r
8894 /* 38 */\r
8895 /***/ function(module, exports) {\r
8896 \r
8897         /**\r
8898          * @module zrender/tool/color\r
8899          */\r
8900 \r
8901 \r
8902             var kCSSColorTable = {\r
8903                 'transparent': [0,0,0,0], 'aliceblue': [240,248,255,1],\r
8904                 'antiquewhite': [250,235,215,1], 'aqua': [0,255,255,1],\r
8905                 'aquamarine': [127,255,212,1], 'azure': [240,255,255,1],\r
8906                 'beige': [245,245,220,1], 'bisque': [255,228,196,1],\r
8907                 'black': [0,0,0,1], 'blanchedalmond': [255,235,205,1],\r
8908                 'blue': [0,0,255,1], 'blueviolet': [138,43,226,1],\r
8909                 'brown': [165,42,42,1], 'burlywood': [222,184,135,1],\r
8910                 'cadetblue': [95,158,160,1], 'chartreuse': [127,255,0,1],\r
8911                 'chocolate': [210,105,30,1], 'coral': [255,127,80,1],\r
8912                 'cornflowerblue': [100,149,237,1], 'cornsilk': [255,248,220,1],\r
8913                 'crimson': [220,20,60,1], 'cyan': [0,255,255,1],\r
8914                 'darkblue': [0,0,139,1], 'darkcyan': [0,139,139,1],\r
8915                 'darkgoldenrod': [184,134,11,1], 'darkgray': [169,169,169,1],\r
8916                 'darkgreen': [0,100,0,1], 'darkgrey': [169,169,169,1],\r
8917                 'darkkhaki': [189,183,107,1], 'darkmagenta': [139,0,139,1],\r
8918                 'darkolivegreen': [85,107,47,1], 'darkorange': [255,140,0,1],\r
8919                 'darkorchid': [153,50,204,1], 'darkred': [139,0,0,1],\r
8920                 'darksalmon': [233,150,122,1], 'darkseagreen': [143,188,143,1],\r
8921                 'darkslateblue': [72,61,139,1], 'darkslategray': [47,79,79,1],\r
8922                 'darkslategrey': [47,79,79,1], 'darkturquoise': [0,206,209,1],\r
8923                 'darkviolet': [148,0,211,1], 'deeppink': [255,20,147,1],\r
8924                 'deepskyblue': [0,191,255,1], 'dimgray': [105,105,105,1],\r
8925                 'dimgrey': [105,105,105,1], 'dodgerblue': [30,144,255,1],\r
8926                 'firebrick': [178,34,34,1], 'floralwhite': [255,250,240,1],\r
8927                 'forestgreen': [34,139,34,1], 'fuchsia': [255,0,255,1],\r
8928                 'gainsboro': [220,220,220,1], 'ghostwhite': [248,248,255,1],\r
8929                 'gold': [255,215,0,1], 'goldenrod': [218,165,32,1],\r
8930                 'gray': [128,128,128,1], 'green': [0,128,0,1],\r
8931                 'greenyellow': [173,255,47,1], 'grey': [128,128,128,1],\r
8932                 'honeydew': [240,255,240,1], 'hotpink': [255,105,180,1],\r
8933                 'indianred': [205,92,92,1], 'indigo': [75,0,130,1],\r
8934                 'ivory': [255,255,240,1], 'khaki': [240,230,140,1],\r
8935                 'lavender': [230,230,250,1], 'lavenderblush': [255,240,245,1],\r
8936                 'lawngreen': [124,252,0,1], 'lemonchiffon': [255,250,205,1],\r
8937                 'lightblue': [173,216,230,1], 'lightcoral': [240,128,128,1],\r
8938                 'lightcyan': [224,255,255,1], 'lightgoldenrodyellow': [250,250,210,1],\r
8939                 'lightgray': [211,211,211,1], 'lightgreen': [144,238,144,1],\r
8940                 'lightgrey': [211,211,211,1], 'lightpink': [255,182,193,1],\r
8941                 'lightsalmon': [255,160,122,1], 'lightseagreen': [32,178,170,1],\r
8942                 'lightskyblue': [135,206,250,1], 'lightslategray': [119,136,153,1],\r
8943                 'lightslategrey': [119,136,153,1], 'lightsteelblue': [176,196,222,1],\r
8944                 'lightyellow': [255,255,224,1], 'lime': [0,255,0,1],\r
8945                 'limegreen': [50,205,50,1], 'linen': [250,240,230,1],\r
8946                 'magenta': [255,0,255,1], 'maroon': [128,0,0,1],\r
8947                 'mediumaquamarine': [102,205,170,1], 'mediumblue': [0,0,205,1],\r
8948                 'mediumorchid': [186,85,211,1], 'mediumpurple': [147,112,219,1],\r
8949                 'mediumseagreen': [60,179,113,1], 'mediumslateblue': [123,104,238,1],\r
8950                 'mediumspringgreen': [0,250,154,1], 'mediumturquoise': [72,209,204,1],\r
8951                 'mediumvioletred': [199,21,133,1], 'midnightblue': [25,25,112,1],\r
8952                 'mintcream': [245,255,250,1], 'mistyrose': [255,228,225,1],\r
8953                 'moccasin': [255,228,181,1], 'navajowhite': [255,222,173,1],\r
8954                 'navy': [0,0,128,1], 'oldlace': [253,245,230,1],\r
8955                 'olive': [128,128,0,1], 'olivedrab': [107,142,35,1],\r
8956                 'orange': [255,165,0,1], 'orangered': [255,69,0,1],\r
8957                 'orchid': [218,112,214,1], 'palegoldenrod': [238,232,170,1],\r
8958                 'palegreen': [152,251,152,1], 'paleturquoise': [175,238,238,1],\r
8959                 'palevioletred': [219,112,147,1], 'papayawhip': [255,239,213,1],\r
8960                 'peachpuff': [255,218,185,1], 'peru': [205,133,63,1],\r
8961                 'pink': [255,192,203,1], 'plum': [221,160,221,1],\r
8962                 'powderblue': [176,224,230,1], 'purple': [128,0,128,1],\r
8963                 'red': [255,0,0,1], 'rosybrown': [188,143,143,1],\r
8964                 'royalblue': [65,105,225,1], 'saddlebrown': [139,69,19,1],\r
8965                 'salmon': [250,128,114,1], 'sandybrown': [244,164,96,1],\r
8966                 'seagreen': [46,139,87,1], 'seashell': [255,245,238,1],\r
8967                 'sienna': [160,82,45,1], 'silver': [192,192,192,1],\r
8968                 'skyblue': [135,206,235,1], 'slateblue': [106,90,205,1],\r
8969                 'slategray': [112,128,144,1], 'slategrey': [112,128,144,1],\r
8970                 'snow': [255,250,250,1], 'springgreen': [0,255,127,1],\r
8971                 'steelblue': [70,130,180,1], 'tan': [210,180,140,1],\r
8972                 'teal': [0,128,128,1], 'thistle': [216,191,216,1],\r
8973                 'tomato': [255,99,71,1], 'turquoise': [64,224,208,1],\r
8974                 'violet': [238,130,238,1], 'wheat': [245,222,179,1],\r
8975                 'white': [255,255,255,1], 'whitesmoke': [245,245,245,1],\r
8976                 'yellow': [255,255,0,1], 'yellowgreen': [154,205,50,1]\r
8977             };\r
8978 \r
8979             function clampCssByte(i) {  // Clamp to integer 0 .. 255.\r
8980                 i = Math.round(i);  // Seems to be what Chrome does (vs truncation).\r
8981                 return i < 0 ? 0 : i > 255 ? 255 : i;\r
8982             }\r
8983 \r
8984             function clampCssAngle(i) {  // Clamp to integer 0 .. 360.\r
8985                 i = Math.round(i);  // Seems to be what Chrome does (vs truncation).\r
8986                 return i < 0 ? 0 : i > 360 ? 360 : i;\r
8987             }\r
8988 \r
8989             function clampCssFloat(f) {  // Clamp to float 0.0 .. 1.0.\r
8990                 return f < 0 ? 0 : f > 1 ? 1 : f;\r
8991             }\r
8992 \r
8993             function parseCssInt(str) {  // int or percentage.\r
8994                 if (str.length && str.charAt(str.length - 1) === '%') {\r
8995                     return clampCssByte(parseFloat(str) / 100 * 255);\r
8996                 }\r
8997                 return clampCssByte(parseInt(str, 10));\r
8998             }\r
8999 \r
9000             function parseCssFloat(str) {  // float or percentage.\r
9001                 if (str.length && str.charAt(str.length - 1) === '%') {\r
9002                     return clampCssFloat(parseFloat(str) / 100);\r
9003                 }\r
9004                 return clampCssFloat(parseFloat(str));\r
9005             }\r
9006 \r
9007             function cssHueToRgb(m1, m2, h) {\r
9008                 if (h < 0) {\r
9009                     h += 1;\r
9010                 }\r
9011                 else if (h > 1) {\r
9012                     h -= 1;\r
9013                 }\r
9014 \r
9015                 if (h * 6 < 1) {\r
9016                     return m1 + (m2 - m1) * h * 6;\r
9017                 }\r
9018                 if (h * 2 < 1) {\r
9019                     return m2;\r
9020                 }\r
9021                 if (h * 3 < 2) {\r
9022                     return m1 + (m2 - m1) * (2/3 - h) * 6;\r
9023                 }\r
9024                 return m1;\r
9025             }\r
9026 \r
9027             function lerp(a, b, p) {\r
9028                 return a + (b - a) * p;\r
9029             }\r
9030 \r
9031             /**\r
9032              * @param {string} colorStr\r
9033              * @return {Array.<number>}\r
9034              * @memberOf module:zrender/util/color\r
9035              */\r
9036             function parse(colorStr) {\r
9037                 if (!colorStr) {\r
9038                     return;\r
9039                 }\r
9040                 // colorStr may be not string\r
9041                 colorStr = colorStr + '';\r
9042                 // Remove all whitespace, not compliant, but should just be more accepting.\r
9043                 var str = colorStr.replace(/ /g, '').toLowerCase();\r
9044 \r
9045                 // Color keywords (and transparent) lookup.\r
9046                 if (str in kCSSColorTable) {\r
9047                     return kCSSColorTable[str].slice();  // dup.\r
9048                 }\r
9049 \r
9050                 // #abc and #abc123 syntax.\r
9051                 if (str.charAt(0) === '#') {\r
9052                     if (str.length === 4) {\r
9053                         var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.\r
9054                         if (!(iv >= 0 && iv <= 0xfff)) {\r
9055                             return;  // Covers NaN.\r
9056                         }\r
9057                         return [\r
9058                             ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),\r
9059                             (iv & 0xf0) | ((iv & 0xf0) >> 4),\r
9060                             (iv & 0xf) | ((iv & 0xf) << 4),\r
9061                             1\r
9062                         ];\r
9063                     }\r
9064                     else if (str.length === 7) {\r
9065                         var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.\r
9066                         if (!(iv >= 0 && iv <= 0xffffff)) {\r
9067                             return;  // Covers NaN.\r
9068                         }\r
9069                         return [\r
9070                             (iv & 0xff0000) >> 16,\r
9071                             (iv & 0xff00) >> 8,\r
9072                             iv & 0xff,\r
9073                             1\r
9074                         ];\r
9075                     }\r
9076 \r
9077                     return;\r
9078                 }\r
9079                 var op = str.indexOf('('), ep = str.indexOf(')');\r
9080                 if (op !== -1 && ep + 1 === str.length) {\r
9081                     var fname = str.substr(0, op);\r
9082                     var params = str.substr(op + 1, ep - (op + 1)).split(',');\r
9083                     var alpha = 1;  // To allow case fallthrough.\r
9084                     switch (fname) {\r
9085                         case 'rgba':\r
9086                             if (params.length !== 4) {\r
9087                                 return;\r
9088                             }\r
9089                             alpha = parseCssFloat(params.pop()); // jshint ignore:line\r
9090                         // Fall through.\r
9091                         case 'rgb':\r
9092                             if (params.length !== 3) {\r
9093                                 return;\r
9094                             }\r
9095                             return [\r
9096                                 parseCssInt(params[0]),\r
9097                                 parseCssInt(params[1]),\r
9098                                 parseCssInt(params[2]),\r
9099                                 alpha\r
9100                             ];\r
9101                         case 'hsla':\r
9102                             if (params.length !== 4) {\r
9103                                 return;\r
9104                             }\r
9105                             params[3] = parseCssFloat(params[3]);\r
9106                             return hsla2rgba(params);\r
9107                         case 'hsl':\r
9108                             if (params.length !== 3) {\r
9109                                 return;\r
9110                             }\r
9111                             return hsla2rgba(params);\r
9112                         default:\r
9113                             return;\r
9114                     }\r
9115                 }\r
9116 \r
9117                 return;\r
9118             }\r
9119 \r
9120             /**\r
9121              * @param {Array.<number>} hsla\r
9122              * @return {Array.<number>} rgba\r
9123              */\r
9124             function hsla2rgba(hsla) {\r
9125                 var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360;  // 0 .. 1\r
9126                 // NOTE(deanm): According to the CSS spec s/l should only be\r
9127                 // percentages, but we don't bother and let float or percentage.\r
9128                 var s = parseCssFloat(hsla[1]);\r
9129                 var l = parseCssFloat(hsla[2]);\r
9130                 var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\r
9131                 var m1 = l * 2 - m2;\r
9132 \r
9133                 var rgba = [\r
9134                     clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255),\r
9135                     clampCssByte(cssHueToRgb(m1, m2, h) * 255),\r
9136                     clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255)\r
9137                 ];\r
9138 \r
9139                 if (hsla.length === 4) {\r
9140                     rgba[3] = hsla[3];\r
9141                 }\r
9142 \r
9143                 return rgba;\r
9144             }\r
9145 \r
9146             /**\r
9147              * @param {Array.<number>} rgba\r
9148              * @return {Array.<number>} hsla\r
9149              */\r
9150             function rgba2hsla(rgba) {\r
9151                 if (!rgba) {\r
9152                     return;\r
9153                 }\r
9154 \r
9155                 // RGB from 0 to 255\r
9156                 var R = rgba[0] / 255;\r
9157                 var G = rgba[1] / 255;\r
9158                 var B = rgba[2] / 255;\r
9159 \r
9160                 var vMin = Math.min(R, G, B); // Min. value of RGB\r
9161                 var vMax = Math.max(R, G, B); // Max. value of RGB\r
9162                 var delta = vMax - vMin; // Delta RGB value\r
9163 \r
9164                 var L = (vMax + vMin) / 2;\r
9165                 var H;\r
9166                 var S;\r
9167                 // HSL results from 0 to 1\r
9168                 if (delta === 0) {\r
9169                     H = 0;\r
9170                     S = 0;\r
9171                 }\r
9172                 else {\r
9173                     if (L < 0.5) {\r
9174                         S = delta / (vMax + vMin);\r
9175                     }\r
9176                     else {\r
9177                         S = delta / (2 - vMax - vMin);\r
9178                     }\r
9179 \r
9180                     var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;\r
9181                     var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;\r
9182                     var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;\r
9183 \r
9184                     if (R === vMax) {\r
9185                         H = deltaB - deltaG;\r
9186                     }\r
9187                     else if (G === vMax) {\r
9188                         H = (1 / 3) + deltaR - deltaB;\r
9189                     }\r
9190                     else if (B === vMax) {\r
9191                         H = (2 / 3) + deltaG - deltaR;\r
9192                     }\r
9193 \r
9194                     if (H < 0) {\r
9195                         H += 1;\r
9196                     }\r
9197 \r
9198                     if (H > 1) {\r
9199                         H -= 1;\r
9200                     }\r
9201                 }\r
9202 \r
9203                 var hsla = [H * 360, S, L];\r
9204 \r
9205                 if (rgba[3] != null) {\r
9206                     hsla.push(rgba[3]);\r
9207                 }\r
9208 \r
9209                 return hsla;\r
9210             }\r
9211 \r
9212             /**\r
9213              * @param {string} color\r
9214              * @param {number} level\r
9215              * @return {string}\r
9216              * @memberOf module:zrender/util/color\r
9217              */\r
9218             function lift(color, level) {\r
9219                 var colorArr = parse(color);\r
9220                 if (colorArr) {\r
9221                     for (var i = 0; i < 3; i++) {\r
9222                         if (level < 0) {\r
9223                             colorArr[i] = colorArr[i] * (1 - level) | 0;\r
9224                         }\r
9225                         else {\r
9226                             colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;\r
9227                         }\r
9228                     }\r
9229                     return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');\r
9230                 }\r
9231             }\r
9232 \r
9233             /**\r
9234              * @param {string} color\r
9235              * @return {string}\r
9236              * @memberOf module:zrender/util/color\r
9237              */\r
9238             function toHex(color, level) {\r
9239                 var colorArr = parse(color);\r
9240                 if (colorArr) {\r
9241                     return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);\r
9242                 }\r
9243             }\r
9244 \r
9245             /**\r
9246              * Map value to color. Faster than mapToColor methods because color is represented by rgba array\r
9247              * @param {number} normalizedValue A float between 0 and 1.\r
9248              * @param {Array.<Array.<number>>} colors List of rgba color array\r
9249              * @param {Array.<number>} [out] Mapped gba color array\r
9250              * @return {Array.<number>}\r
9251              */\r
9252             function fastMapToColor(normalizedValue, colors, out) {\r
9253                 if (!(colors && colors.length)\r
9254                     || !(normalizedValue >= 0 && normalizedValue <= 1)\r
9255                 ) {\r
9256                     return;\r
9257                 }\r
9258                 out = out || [0, 0, 0, 0];\r
9259                 var value = normalizedValue * (colors.length - 1);\r
9260                 var leftIndex = Math.floor(value);\r
9261                 var rightIndex = Math.ceil(value);\r
9262                 var leftColor = colors[leftIndex];\r
9263                 var rightColor = colors[rightIndex];\r
9264                 var dv = value - leftIndex;\r
9265                 out[0] = clampCssByte(lerp(leftColor[0], rightColor[0], dv));\r
9266                 out[1] = clampCssByte(lerp(leftColor[1], rightColor[1], dv));\r
9267                 out[2] = clampCssByte(lerp(leftColor[2], rightColor[2], dv));\r
9268                 out[3] = clampCssByte(lerp(leftColor[3], rightColor[3], dv));\r
9269                 return out;\r
9270             }\r
9271             /**\r
9272              * @param {number} normalizedValue A float between 0 and 1.\r
9273              * @param {Array.<string>} colors Color list.\r
9274              * @param {boolean=} fullOutput Default false.\r
9275              * @return {(string|Object)} Result color. If fullOutput,\r
9276              *                           return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},\r
9277              * @memberOf module:zrender/util/color\r
9278              */\r
9279             function mapToColor(normalizedValue, colors, fullOutput) {\r
9280                 if (!(colors && colors.length)\r
9281                     || !(normalizedValue >= 0 && normalizedValue <= 1)\r
9282                 ) {\r
9283                     return;\r
9284                 }\r
9285 \r
9286                 var value = normalizedValue * (colors.length - 1);\r
9287                 var leftIndex = Math.floor(value);\r
9288                 var rightIndex = Math.ceil(value);\r
9289                 var leftColor = parse(colors[leftIndex]);\r
9290                 var rightColor = parse(colors[rightIndex]);\r
9291                 var dv = value - leftIndex;\r
9292 \r
9293                 var color = stringify(\r
9294                     [\r
9295                         clampCssByte(lerp(leftColor[0], rightColor[0], dv)),\r
9296                         clampCssByte(lerp(leftColor[1], rightColor[1], dv)),\r
9297                         clampCssByte(lerp(leftColor[2], rightColor[2], dv)),\r
9298                         clampCssFloat(lerp(leftColor[3], rightColor[3], dv))\r
9299                     ],\r
9300                     'rgba'\r
9301                 );\r
9302 \r
9303                 return fullOutput\r
9304                     ? {\r
9305                         color: color,\r
9306                         leftIndex: leftIndex,\r
9307                         rightIndex: rightIndex,\r
9308                         value: value\r
9309                     }\r
9310                     : color;\r
9311             }\r
9312 \r
9313             /**\r
9314              * @param {Array<number>} interval  Array length === 2,\r
9315              *                                  each item is normalized value ([0, 1]).\r
9316              * @param {Array.<string>} colors Color list.\r
9317              * @return {Array.<Object>} colors corresponding to the interval,\r
9318              *                          each item is {color: 'xxx', offset: ...}\r
9319              *                          where offset is between 0 and 1.\r
9320              * @memberOf module:zrender/util/color\r
9321              */\r
9322             function mapIntervalToColor(interval, colors) {\r
9323                 if (interval.length !== 2 || interval[1] < interval[0]) {\r
9324                     return;\r
9325                 }\r
9326 \r
9327                 var info0 = mapToColor(interval[0], colors, true);\r
9328                 var info1 = mapToColor(interval[1], colors, true);\r
9329 \r
9330                 var result = [{color: info0.color, offset: 0}];\r
9331 \r
9332                 var during = info1.value - info0.value;\r
9333                 var start = Math.max(info0.value, info0.rightIndex);\r
9334                 var end = Math.min(info1.value, info1.leftIndex);\r
9335 \r
9336                 for (var i = start; during > 0 && i <= end; i++) {\r
9337                     result.push({\r
9338                         color: colors[i],\r
9339                         offset: (i - info0.value) / during\r
9340                     });\r
9341                 }\r
9342                 result.push({color: info1.color, offset: 1});\r
9343 \r
9344                 return result;\r
9345             }\r
9346 \r
9347             /**\r
9348              * @param {string} color\r
9349              * @param {number=} h 0 ~ 360, ignore when null.\r
9350              * @param {number=} s 0 ~ 1, ignore when null.\r
9351              * @param {number=} l 0 ~ 1, ignore when null.\r
9352              * @return {string} Color string in rgba format.\r
9353              * @memberOf module:zrender/util/color\r
9354              */\r
9355             function modifyHSL(color, h, s, l) {\r
9356                 color = parse(color);\r
9357 \r
9358                 if (color) {\r
9359                     color = rgba2hsla(color);\r
9360                     h != null && (color[0] = clampCssAngle(h));\r
9361                     s != null && (color[1] = parseCssFloat(s));\r
9362                     l != null && (color[2] = parseCssFloat(l));\r
9363 \r
9364                     return stringify(hsla2rgba(color), 'rgba');\r
9365                 }\r
9366             }\r
9367 \r
9368             /**\r
9369              * @param {string} color\r
9370              * @param {number=} alpha 0 ~ 1\r
9371              * @return {string} Color string in rgba format.\r
9372              * @memberOf module:zrender/util/color\r
9373              */\r
9374             function modifyAlpha(color, alpha) {\r
9375                 color = parse(color);\r
9376 \r
9377                 if (color && alpha != null) {\r
9378                     color[3] = clampCssFloat(alpha);\r
9379                     return stringify(color, 'rgba');\r
9380                 }\r
9381             }\r
9382 \r
9383             /**\r
9384              * @param {Array.<string>} colors Color list.\r
9385              * @param {string} type 'rgba', 'hsva', ...\r
9386              * @return {string} Result color.\r
9387              */\r
9388             function stringify(arrColor, type) {\r
9389                 if (type === 'rgb' || type === 'hsv' || type === 'hsl') {\r
9390                     arrColor = arrColor.slice(0, 3);\r
9391                 }\r
9392                 return type + '(' + arrColor.join(',') + ')';\r
9393             }\r
9394 \r
9395             module.exports = {\r
9396                 parse: parse,\r
9397                 lift: lift,\r
9398                 toHex: toHex,\r
9399                 fastMapToColor: fastMapToColor,\r
9400                 mapToColor: mapToColor,\r
9401                 mapIntervalToColor: mapIntervalToColor,\r
9402                 modifyHSL: modifyHSL,\r
9403                 modifyAlpha: modifyAlpha,\r
9404                 stringify: stringify\r
9405             };\r
9406 \r
9407 \r
9408 \r
9409 \r
9410 /***/ },\r
9411 /* 39 */\r
9412 /***/ function(module, exports, __webpack_require__) {\r
9413 \r
9414         \r
9415                 var config = __webpack_require__(40);\r
9416 \r
9417                 /**\r
9418                  * @exports zrender/tool/log\r
9419                  * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
9420                  */\r
9421                 module.exports = function() {\r
9422                     if (config.debugMode === 0) {\r
9423                         return;\r
9424                     }\r
9425                     else if (config.debugMode == 1) {\r
9426                         for (var k in arguments) {\r
9427                             throw new Error(arguments[k]);\r
9428                         }\r
9429                     }\r
9430                     else if (config.debugMode > 1) {\r
9431                         for (var k in arguments) {\r
9432                             console.log(arguments[k]);\r
9433                         }\r
9434                     }\r
9435                 };\r
9436 \r
9437                 /* for debug\r
9438                 return function(mes) {\r
9439                     document.getElementById('wrong-message').innerHTML =\r
9440                         mes + ' ' + (new Date() - 0)\r
9441                         + '<br/>' \r
9442                         + document.getElementById('wrong-message').innerHTML;\r
9443                 };\r
9444                 */\r
9445             \r
9446 \r
9447 \r
9448 /***/ },\r
9449 /* 40 */\r
9450 /***/ function(module, exports) {\r
9451 \r
9452         \r
9453             var dpr = 1;\r
9454             // If in browser environment\r
9455             if (typeof window !== 'undefined') {\r
9456                 dpr = Math.max(window.devicePixelRatio || 1, 1);\r
9457             }\r
9458             /**\r
9459              * config默认配置项\r
9460              * @exports zrender/config\r
9461              * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
9462              */\r
9463             var config = {\r
9464                 /**\r
9465                  * debug日志选项:catchBrushException为true下有效\r
9466                  * 0 : 不生成debug数据,发布用\r
9467                  * 1 : 异常抛出,调试用\r
9468                  * 2 : 控制台输出,调试用\r
9469                  */\r
9470                 debugMode: 0,\r
9471 \r
9472                 // retina 屏幕优化\r
9473                 devicePixelRatio: dpr\r
9474             };\r
9475             module.exports = config;\r
9476 \r
9477 \r
9478 \r
9479 \r
9480 /***/ },\r
9481 /* 41 */\r
9482 /***/ function(module, exports, __webpack_require__) {\r
9483 \r
9484         \r
9485 \r
9486             var Group = __webpack_require__(29);\r
9487             var componentUtil = __webpack_require__(20);\r
9488             var clazzUtil = __webpack_require__(9);\r
9489 \r
9490             function Chart() {\r
9491 \r
9492                 /**\r
9493                  * @type {module:zrender/container/Group}\r
9494                  * @readOnly\r
9495                  */\r
9496                 this.group = new Group();\r
9497 \r
9498                 /**\r
9499                  * @type {string}\r
9500                  * @readOnly\r
9501                  */\r
9502                 this.uid = componentUtil.getUID('viewChart');\r
9503             }\r
9504 \r
9505             Chart.prototype = {\r
9506 \r
9507                 type: 'chart',\r
9508 \r
9509                 /**\r
9510                  * Init the chart\r
9511                  * @param  {module:echarts/model/Global} ecModel\r
9512                  * @param  {module:echarts/ExtensionAPI} api\r
9513                  */\r
9514                 init: function (ecModel, api) {},\r
9515 \r
9516                 /**\r
9517                  * Render the chart\r
9518                  * @param  {module:echarts/model/Series} seriesModel\r
9519                  * @param  {module:echarts/model/Global} ecModel\r
9520                  * @param  {module:echarts/ExtensionAPI} api\r
9521                  * @param  {Object} payload\r
9522                  */\r
9523                 render: function (seriesModel, ecModel, api, payload) {},\r
9524 \r
9525                 /**\r
9526                  * Highlight series or specified data item\r
9527                  * @param  {module:echarts/model/Series} seriesModel\r
9528                  * @param  {module:echarts/model/Global} ecModel\r
9529                  * @param  {module:echarts/ExtensionAPI} api\r
9530                  * @param  {Object} payload\r
9531                  */\r
9532                 highlight: function (seriesModel, ecModel, api, payload) {\r
9533                     toggleHighlight(seriesModel.getData(), payload, 'emphasis');\r
9534                 },\r
9535 \r
9536                 /**\r
9537                  * Downplay series or specified data item\r
9538                  * @param  {module:echarts/model/Series} seriesModel\r
9539                  * @param  {module:echarts/model/Global} ecModel\r
9540                  * @param  {module:echarts/ExtensionAPI} api\r
9541                  * @param  {Object} payload\r
9542                  */\r
9543                 downplay: function (seriesModel, ecModel, api, payload) {\r
9544                     toggleHighlight(seriesModel.getData(), payload, 'normal');\r
9545                 },\r
9546 \r
9547                 /**\r
9548                  * Remove self\r
9549                  * @param  {module:echarts/model/Global} ecModel\r
9550                  * @param  {module:echarts/ExtensionAPI} api\r
9551                  */\r
9552                 remove: function (ecModel, api) {\r
9553                     this.group.removeAll();\r
9554                 },\r
9555 \r
9556                 /**\r
9557                  * Dispose self\r
9558                  * @param  {module:echarts/model/Global} ecModel\r
9559                  * @param  {module:echarts/ExtensionAPI} api\r
9560                  */\r
9561                 dispose: function () {}\r
9562             };\r
9563 \r
9564             var chartProto = Chart.prototype;\r
9565             chartProto.updateView\r
9566                 = chartProto.updateLayout\r
9567                 = chartProto.updateVisual\r
9568                 = function (seriesModel, ecModel, api, payload) {\r
9569                     this.render(seriesModel, ecModel, api, payload);\r
9570                 };\r
9571 \r
9572             /**\r
9573              * Set state of single element\r
9574              * @param  {module:zrender/Element} el\r
9575              * @param  {string} state\r
9576              */\r
9577             function elSetState(el, state) {\r
9578                 if (el) {\r
9579                     el.trigger(state);\r
9580                     if (el.type === 'group') {\r
9581                         for (var i = 0; i < el.childCount(); i++) {\r
9582                             elSetState(el.childAt(i), state);\r
9583                         }\r
9584                     }\r
9585                 }\r
9586             }\r
9587             /**\r
9588              * @param  {module:echarts/data/List} data\r
9589              * @param  {Object} payload\r
9590              * @param  {string} state 'normal'|'emphasis'\r
9591              * @inner\r
9592              */\r
9593             function toggleHighlight(data, payload, state) {\r
9594                 if (payload.dataIndex != null) {\r
9595                     var el = data.getItemGraphicEl(payload.dataIndex);\r
9596                     elSetState(el, state);\r
9597                 }\r
9598                 else if (payload.name) {\r
9599                     var dataIndex = data.indexOfName(payload.name);\r
9600                     var el = data.getItemGraphicEl(dataIndex);\r
9601                     elSetState(el, state);\r
9602                 }\r
9603                 else {\r
9604                     data.eachItemGraphicEl(function (el) {\r
9605                         elSetState(el, state);\r
9606                     });\r
9607                 }\r
9608             }\r
9609 \r
9610             // Enable Chart.extend.\r
9611             clazzUtil.enableClassExtend(Chart);\r
9612 \r
9613             // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.\r
9614             clazzUtil.enableClassManagement(Chart, {registerWhenExtend: true});\r
9615 \r
9616             module.exports = Chart;\r
9617 \r
9618 \r
9619 /***/ },\r
9620 /* 42 */\r
9621 /***/ function(module, exports, __webpack_require__) {\r
9622 \r
9623         'use strict';\r
9624 \r
9625 \r
9626             var zrUtil = __webpack_require__(3);\r
9627 \r
9628             var pathTool = __webpack_require__(43);\r
9629             var round = Math.round;\r
9630             var Path = __webpack_require__(44);\r
9631             var colorTool = __webpack_require__(38);\r
9632             var matrix = __webpack_require__(17);\r
9633             var vector = __webpack_require__(16);\r
9634             var Gradient = __webpack_require__(4);\r
9635 \r
9636             var graphic = {};\r
9637 \r
9638             graphic.Group = __webpack_require__(29);\r
9639 \r
9640             graphic.Image = __webpack_require__(59);\r
9641 \r
9642             graphic.Text = __webpack_require__(62);\r
9643 \r
9644             graphic.Circle = __webpack_require__(63);\r
9645 \r
9646             graphic.Sector = __webpack_require__(64);\r
9647 \r
9648             graphic.Ring = __webpack_require__(65);\r
9649 \r
9650             graphic.Polygon = __webpack_require__(66);\r
9651 \r
9652             graphic.Polyline = __webpack_require__(70);\r
9653 \r
9654             graphic.Rect = __webpack_require__(71);\r
9655 \r
9656             graphic.Line = __webpack_require__(72);\r
9657 \r
9658             graphic.BezierCurve = __webpack_require__(73);\r
9659 \r
9660             graphic.Arc = __webpack_require__(74);\r
9661 \r
9662             graphic.LinearGradient = __webpack_require__(75);\r
9663 \r
9664             graphic.RadialGradient = __webpack_require__(76);\r
9665 \r
9666             graphic.BoundingRect = __webpack_require__(15);\r
9667 \r
9668             /**\r
9669              * Extend shape with parameters\r
9670              */\r
9671             graphic.extendShape = function (opts) {\r
9672                 return Path.extend(opts);\r
9673             };\r
9674 \r
9675             /**\r
9676              * Extend path\r
9677              */\r
9678             graphic.extendPath = function (pathData, opts) {\r
9679                 return pathTool.extendFromString(pathData, opts);\r
9680             };\r
9681 \r
9682             /**\r
9683              * Create a path element from path data string\r
9684              * @param {string} pathData\r
9685              * @param {Object} opts\r
9686              * @param {module:zrender/core/BoundingRect} rect\r
9687              * @param {string} [layout=cover] 'center' or 'cover'\r
9688              */\r
9689             graphic.makePath = function (pathData, opts, rect, layout) {\r
9690                 var path = pathTool.createFromString(pathData, opts);\r
9691                 var boundingRect = path.getBoundingRect();\r
9692                 if (rect) {\r
9693                     var aspect = boundingRect.width / boundingRect.height;\r
9694 \r
9695                     if (layout === 'center') {\r
9696                         // Set rect to center, keep width / height ratio.\r
9697                         var width = rect.height * aspect;\r
9698                         var height;\r
9699                         if (width <= rect.width) {\r
9700                             height = rect.height;\r
9701                         }\r
9702                         else {\r
9703                             width = rect.width;\r
9704                             height = width / aspect;\r
9705                         }\r
9706                         var cx = rect.x + rect.width / 2;\r
9707                         var cy = rect.y + rect.height / 2;\r
9708 \r
9709                         rect.x = cx - width / 2;\r
9710                         rect.y = cy - height / 2;\r
9711                         rect.width = width;\r
9712                         rect.height = height;\r
9713                     }\r
9714 \r
9715                     this.resizePath(path, rect);\r
9716                 }\r
9717                 return path;\r
9718             };\r
9719 \r
9720             graphic.mergePath = pathTool.mergePath,\r
9721 \r
9722             /**\r
9723              * Resize a path to fit the rect\r
9724              * @param {module:zrender/graphic/Path} path\r
9725              * @param {Object} rect\r
9726              */\r
9727             graphic.resizePath = function (path, rect) {\r
9728                 if (!path.applyTransform) {\r
9729                     return;\r
9730                 }\r
9731 \r
9732                 var pathRect = path.getBoundingRect();\r
9733 \r
9734                 var m = pathRect.calculateTransform(rect);\r
9735 \r
9736                 path.applyTransform(m);\r
9737             };\r
9738 \r
9739             /**\r
9740              * Sub pixel optimize line for canvas\r
9741              *\r
9742              * @param {Object} param\r
9743              * @param {Object} [param.shape]\r
9744              * @param {number} [param.shape.x1]\r
9745              * @param {number} [param.shape.y1]\r
9746              * @param {number} [param.shape.x2]\r
9747              * @param {number} [param.shape.y2]\r
9748              * @param {Object} [param.style]\r
9749              * @param {number} [param.style.lineWidth]\r
9750              * @return {Object} Modified param\r
9751              */\r
9752             graphic.subPixelOptimizeLine = function (param) {\r
9753                 var subPixelOptimize = graphic.subPixelOptimize;\r
9754                 var shape = param.shape;\r
9755                 var lineWidth = param.style.lineWidth;\r
9756 \r
9757                 if (round(shape.x1 * 2) === round(shape.x2 * 2)) {\r
9758                     shape.x1 = shape.x2 = subPixelOptimize(shape.x1, lineWidth, true);\r
9759                 }\r
9760                 if (round(shape.y1 * 2) === round(shape.y2 * 2)) {\r
9761                     shape.y1 = shape.y2 = subPixelOptimize(shape.y1, lineWidth, true);\r
9762                 }\r
9763                 return param;\r
9764             };\r
9765 \r
9766             /**\r
9767              * Sub pixel optimize rect for canvas\r
9768              *\r
9769              * @param {Object} param\r
9770              * @param {Object} [param.shape]\r
9771              * @param {number} [param.shape.x]\r
9772              * @param {number} [param.shape.y]\r
9773              * @param {number} [param.shape.width]\r
9774              * @param {number} [param.shape.height]\r
9775              * @param {Object} [param.style]\r
9776              * @param {number} [param.style.lineWidth]\r
9777              * @return {Object} Modified param\r
9778              */\r
9779             graphic.subPixelOptimizeRect = function (param) {\r
9780                 var subPixelOptimize = graphic.subPixelOptimize;\r
9781                 var shape = param.shape;\r
9782                 var lineWidth = param.style.lineWidth;\r
9783                 var originX = shape.x;\r
9784                 var originY = shape.y;\r
9785                 var originWidth = shape.width;\r
9786                 var originHeight = shape.height;\r
9787                 shape.x = subPixelOptimize(shape.x, lineWidth, true);\r
9788                 shape.y = subPixelOptimize(shape.y, lineWidth, true);\r
9789                 shape.width = Math.max(\r
9790                     subPixelOptimize(originX + originWidth, lineWidth, false) - shape.x,\r
9791                     originWidth === 0 ? 0 : 1\r
9792                 );\r
9793                 shape.height = Math.max(\r
9794                     subPixelOptimize(originY + originHeight, lineWidth, false) - shape.y,\r
9795                     originHeight === 0 ? 0 : 1\r
9796                 );\r
9797                 return param;\r
9798             };\r
9799 \r
9800             /**\r
9801              * Sub pixel optimize for canvas\r
9802              *\r
9803              * @param {number} position Coordinate, such as x, y\r
9804              * @param {number} lineWidth Should be nonnegative integer.\r
9805              * @param {boolean=} positiveOrNegative Default false (negative).\r
9806              * @return {number} Optimized position.\r
9807              */\r
9808             graphic.subPixelOptimize = function (position, lineWidth, positiveOrNegative) {\r
9809                 // Assure that (position + lineWidth / 2) is near integer edge,\r
9810                 // otherwise line will be fuzzy in canvas.\r
9811                 var doubledPosition = round(position * 2);\r
9812                 return (doubledPosition + round(lineWidth)) % 2 === 0\r
9813                     ? doubledPosition / 2\r
9814                     : (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2;\r
9815             };\r
9816 \r
9817             /**\r
9818              * @private\r
9819              */\r
9820             function doSingleEnterHover(el) {\r
9821                 if (el.__isHover) {\r
9822                     return;\r
9823                 }\r
9824                 if (el.__hoverStlDirty) {\r
9825                     var stroke = el.style.stroke;\r
9826                     var fill = el.style.fill;\r
9827 \r
9828                     // Create hoverStyle on mouseover\r
9829                     var hoverStyle = el.__hoverStl;\r
9830                     var lift = colorTool.lift;\r
9831                     hoverStyle.fill = hoverStyle.fill\r
9832                         || (fill && (fill instanceof Gradient ? fill : lift(fill, -0.1)));\r
9833                     hoverStyle.stroke = hoverStyle.stroke\r
9834                         || (stroke && (stroke instanceof Gradient ? stroke : lift(stroke, -0.1)));\r
9835 \r
9836                     var normalStyle = {};\r
9837                     for (var name in hoverStyle) {\r
9838                         if (hoverStyle.hasOwnProperty(name)) {\r
9839                             normalStyle[name] = el.style[name];\r
9840                         }\r
9841                     }\r
9842 \r
9843                     el.__normalStl = normalStyle;\r
9844 \r
9845                     el.__hoverStlDirty = false;\r
9846                 }\r
9847                 el.setStyle(el.__hoverStl);\r
9848                 el.z2 += 1;\r
9849 \r
9850                 el.__isHover = true;\r
9851             }\r
9852 \r
9853             /**\r
9854              * @inner\r
9855              */\r
9856             function doSingleLeaveHover(el) {\r
9857                 if (!el.__isHover) {\r
9858                     return;\r
9859                 }\r
9860 \r
9861                 var normalStl = el.__normalStl;\r
9862                 normalStl && el.setStyle(normalStl);\r
9863                 el.z2 -= 1;\r
9864 \r
9865                 el.__isHover = false;\r
9866             }\r
9867 \r
9868             /**\r
9869              * @inner\r
9870              */\r
9871             function doEnterHover(el) {\r
9872                 el.type === 'group'\r
9873                     ? el.traverse(function (child) {\r
9874                         if (child.type !== 'group') {\r
9875                             doSingleEnterHover(child);\r
9876                         }\r
9877                     })\r
9878                     : doSingleEnterHover(el);\r
9879             }\r
9880 \r
9881             function doLeaveHover(el) {\r
9882                 el.type === 'group'\r
9883                     ? el.traverse(function (child) {\r
9884                         if (child.type !== 'group') {\r
9885                             doSingleLeaveHover(child);\r
9886                         }\r
9887                     })\r
9888                     : doSingleLeaveHover(el);\r
9889             }\r
9890 \r
9891             /**\r
9892              * @inner\r
9893              */\r
9894             function setElementHoverStl(el, hoverStl) {\r
9895                 // If element has sepcified hoverStyle, then use it instead of given hoverStyle\r
9896                 // Often used when item group has a label element and it's hoverStyle is different\r
9897                 el.__hoverStl = el.hoverStyle || hoverStl || {};\r
9898                 el.__hoverStlDirty = true;\r
9899             }\r
9900 \r
9901             /**\r
9902              * @inner\r
9903              */\r
9904             function onElementMouseOver() {\r
9905                 // Only if element is not in emphasis status\r
9906                 !this.__isEmphasis && doEnterHover(this);\r
9907             }\r
9908 \r
9909             /**\r
9910              * @inner\r
9911              */\r
9912             function onElementMouseOut() {\r
9913                 // Only if element is not in emphasis status\r
9914                 !this.__isEmphasis && doLeaveHover(this);\r
9915             }\r
9916 \r
9917             /**\r
9918              * @inner\r
9919              */\r
9920             function enterEmphasis() {\r
9921                 this.__isEmphasis = true;\r
9922                 doEnterHover(this);\r
9923             }\r
9924 \r
9925             /**\r
9926              * @inner\r
9927              */\r
9928             function leaveEmphasis() {\r
9929                 this.__isEmphasis = false;\r
9930                 doLeaveHover(this);\r
9931             }\r
9932 \r
9933             /**\r
9934              * Set hover style of element\r
9935              * @param {module:zrender/Element} el\r
9936              * @param {Object} [hoverStyle]\r
9937              */\r
9938             graphic.setHoverStyle = function (el, hoverStyle) {\r
9939                 el.type === 'group'\r
9940                     ? el.traverse(function (child) {\r
9941                         if (child.type !== 'group') {\r
9942                             setElementHoverStl(child, hoverStyle);\r
9943                         }\r
9944                     })\r
9945                     : setElementHoverStl(el, hoverStyle);\r
9946                 // Remove previous bound handlers\r
9947                 el.on('mouseover', onElementMouseOver)\r
9948                   .on('mouseout', onElementMouseOut);\r
9949 \r
9950                 // Emphasis, normal can be triggered manually\r
9951                 el.on('emphasis', enterEmphasis)\r
9952                   .on('normal', leaveEmphasis);\r
9953             };\r
9954 \r
9955             /**\r
9956              * Set text option in the style\r
9957              * @param {Object} textStyle\r
9958              * @param {module:echarts/model/Model} labelModel\r
9959              * @param {string} color\r
9960              */\r
9961             graphic.setText = function (textStyle, labelModel, color) {\r
9962                 var labelPosition = labelModel.getShallow('position') || 'inside';\r
9963                 var labelColor = labelPosition.indexOf('inside') >= 0 ? 'white' : color;\r
9964                 var textStyleModel = labelModel.getModel('textStyle');\r
9965                 zrUtil.extend(textStyle, {\r
9966                     textDistance: labelModel.getShallow('distance') || 5,\r
9967                     textFont: textStyleModel.getFont(),\r
9968                     textPosition: labelPosition,\r
9969                     textFill: textStyleModel.getTextColor() || labelColor\r
9970                 });\r
9971             };\r
9972 \r
9973             function animateOrSetProps(isUpdate, el, props, animatableModel, cb) {\r
9974                 var postfix = isUpdate ? 'Update' : '';\r
9975                 var duration = animatableModel\r
9976                     && animatableModel.getShallow('animationDuration' + postfix);\r
9977                 var animationEasing = animatableModel\r
9978                     && animatableModel.getShallow('animationEasing' + postfix);\r
9979 \r
9980                 animatableModel && animatableModel.getShallow('animation')\r
9981                     ? el.animateTo(props, duration, animationEasing, cb)\r
9982                     : (el.attr(props), cb && cb());\r
9983             }\r
9984             /**\r
9985              * Update graphic element properties with or without animation according to the configuration in series\r
9986              * @param {module:zrender/Element} el\r
9987              * @param {Object} props\r
9988              * @param {module:echarts/model/Model} [animatableModel]\r
9989              * @param {Function} cb\r
9990              */\r
9991             graphic.updateProps = zrUtil.curry(animateOrSetProps, true);\r
9992 \r
9993             /**\r
9994              * Init graphic element properties with or without animation according to the configuration in series\r
9995              * @param {module:zrender/Element} el\r
9996              * @param {Object} props\r
9997              * @param {module:echarts/model/Model} [animatableModel]\r
9998              * @param {Function} cb\r
9999              */\r
10000             graphic.initProps = zrUtil.curry(animateOrSetProps, false);\r
10001 \r
10002             /**\r
10003              * Get transform matrix of target (param target),\r
10004              * in coordinate of its ancestor (param ancestor)\r
10005              *\r
10006              * @param {module:zrender/mixin/Transformable} target\r
10007              * @param {module:zrender/mixin/Transformable} ancestor\r
10008              */\r
10009             graphic.getTransform = function (target, ancestor) {\r
10010                 var mat = matrix.identity([]);\r
10011 \r
10012                 while (target && target !== ancestor) {\r
10013                     matrix.mul(mat, target.getLocalTransform(), mat);\r
10014                     target = target.parent;\r
10015                 }\r
10016 \r
10017                 return mat;\r
10018             };\r
10019 \r
10020             /**\r
10021              * Apply transform to an vertex.\r
10022              * @param {Array.<number>} vertex [x, y]\r
10023              * @param {Array.<number>} transform Transform matrix: like [1, 0, 0, 1, 0, 0]\r
10024              * @param {boolean=} invert Whether use invert matrix.\r
10025              * @return {Array.<number>} [x, y]\r
10026              */\r
10027             graphic.applyTransform = function (vertex, transform, invert) {\r
10028                 if (invert) {\r
10029                     transform = matrix.invert([], transform);\r
10030                 }\r
10031                 return vector.applyTransform([], vertex, transform);\r
10032             };\r
10033 \r
10034             /**\r
10035              * @param {string} direction 'left' 'right' 'top' 'bottom'\r
10036              * @param {Array.<number>} transform Transform matrix: like [1, 0, 0, 1, 0, 0]\r
10037              * @param {boolean=} invert Whether use invert matrix.\r
10038              * @return {string} Transformed direction. 'left' 'right' 'top' 'bottom'\r
10039              */\r
10040             graphic.transformDirection = function (direction, transform, invert) {\r
10041 \r
10042                 // Pick a base, ensure that transform result will not be (0, 0).\r
10043                 var hBase = (transform[4] === 0 || transform[5] === 0 || transform[0] === 0)\r
10044                     ? 1 : Math.abs(2 * transform[4] / transform[0]);\r
10045                 var vBase = (transform[4] === 0 || transform[5] === 0 || transform[2] === 0)\r
10046                     ? 1 : Math.abs(2 * transform[4] / transform[2]);\r
10047 \r
10048                 var vertex = [\r
10049                     direction === 'left' ? -hBase : direction === 'right' ? hBase : 0,\r
10050                     direction === 'top' ? -vBase : direction === 'bottom' ? vBase : 0\r
10051                 ];\r
10052 \r
10053                 vertex = graphic.applyTransform(vertex, transform, invert);\r
10054 \r
10055                 return Math.abs(vertex[0]) > Math.abs(vertex[1])\r
10056                     ? (vertex[0] > 0 ? 'right' : 'left')\r
10057                     : (vertex[1] > 0 ? 'bottom' : 'top');\r
10058             };\r
10059 \r
10060             module.exports = graphic;\r
10061 \r
10062 \r
10063 /***/ },\r
10064 /* 43 */\r
10065 /***/ function(module, exports, __webpack_require__) {\r
10066 \r
10067         \r
10068 \r
10069             var Path = __webpack_require__(44);\r
10070             var PathProxy = __webpack_require__(48);\r
10071             var transformPath = __webpack_require__(58);\r
10072             var matrix = __webpack_require__(17);\r
10073 \r
10074             // command chars\r
10075             var cc = [\r
10076                 'm', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z',\r
10077                 'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A'\r
10078             ];\r
10079 \r
10080             var mathSqrt = Math.sqrt;\r
10081             var mathSin = Math.sin;\r
10082             var mathCos = Math.cos;\r
10083             var PI = Math.PI;\r
10084 \r
10085             var vMag = function(v) {\r
10086                 return Math.sqrt(v[0] * v[0] + v[1] * v[1]);\r
10087             };\r
10088             var vRatio = function(u, v) {\r
10089                 return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v));\r
10090             };\r
10091             var vAngle = function(u, v) {\r
10092                 return (u[0] * v[1] < u[1] * v[0] ? -1 : 1)\r
10093                         * Math.acos(vRatio(u, v));\r
10094             };\r
10095 \r
10096             function processArc(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg, cmd, path) {\r
10097                 var psi = psiDeg * (PI / 180.0);\r
10098                 var xp = mathCos(psi) * (x1 - x2) / 2.0\r
10099                          + mathSin(psi) * (y1 - y2) / 2.0;\r
10100                 var yp = -1 * mathSin(psi) * (x1 - x2) / 2.0\r
10101                          + mathCos(psi) * (y1 - y2) / 2.0;\r
10102 \r
10103                 var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry);\r
10104 \r
10105                 if (lambda > 1) {\r
10106                     rx *= mathSqrt(lambda);\r
10107                     ry *= mathSqrt(lambda);\r
10108                 }\r
10109 \r
10110                 var f = (fa === fs ? -1 : 1)\r
10111                     * mathSqrt((((rx * rx) * (ry * ry))\r
10112                             - ((rx * rx) * (yp * yp))\r
10113                             - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp)\r
10114                             + (ry * ry) * (xp * xp))\r
10115                         ) || 0;\r
10116 \r
10117                 var cxp = f * rx * yp / ry;\r
10118                 var cyp = f * -ry * xp / rx;\r
10119 \r
10120                 var cx = (x1 + x2) / 2.0\r
10121                          + mathCos(psi) * cxp\r
10122                          - mathSin(psi) * cyp;\r
10123                 var cy = (y1 + y2) / 2.0\r
10124                         + mathSin(psi) * cxp\r
10125                         + mathCos(psi) * cyp;\r
10126 \r
10127                 var theta = vAngle([ 1, 0 ], [ (xp - cxp) / rx, (yp - cyp) / ry ]);\r
10128                 var u = [ (xp - cxp) / rx, (yp - cyp) / ry ];\r
10129                 var v = [ (-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry ];\r
10130                 var dTheta = vAngle(u, v);\r
10131 \r
10132                 if (vRatio(u, v) <= -1) {\r
10133                     dTheta = PI;\r
10134                 }\r
10135                 if (vRatio(u, v) >= 1) {\r
10136                     dTheta = 0;\r
10137                 }\r
10138                 if (fs === 0 && dTheta > 0) {\r
10139                     dTheta = dTheta - 2 * PI;\r
10140                 }\r
10141                 if (fs === 1 && dTheta < 0) {\r
10142                     dTheta = dTheta + 2 * PI;\r
10143                 }\r
10144 \r
10145                 path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs);\r
10146             }\r
10147 \r
10148             function createPathProxyFromString(data) {\r
10149                 if (!data) {\r
10150                     return [];\r
10151                 }\r
10152 \r
10153                 // command string\r
10154                 var cs = data.replace(/-/g, ' -')\r
10155                     .replace(/  /g, ' ')\r
10156                     .replace(/ /g, ',')\r
10157                     .replace(/,,/g, ',');\r
10158 \r
10159                 var n;\r
10160                 // create pipes so that we can split the data\r
10161                 for (n = 0; n < cc.length; n++) {\r
10162                     cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);\r
10163                 }\r
10164 \r
10165                 // create array\r
10166                 var arr = cs.split('|');\r
10167                 // init context point\r
10168                 var cpx = 0;\r
10169                 var cpy = 0;\r
10170 \r
10171                 var path = new PathProxy();\r
10172                 var CMD = PathProxy.CMD;\r
10173 \r
10174                 var prevCmd;\r
10175                 for (n = 1; n < arr.length; n++) {\r
10176                     var str = arr[n];\r
10177                     var c = str.charAt(0);\r
10178                     var off = 0;\r
10179                     var p = str.slice(1).replace(/e,-/g, 'e-').split(',');\r
10180                     var cmd;\r
10181 \r
10182                     if (p.length > 0 && p[0] === '') {\r
10183                         p.shift();\r
10184                     }\r
10185 \r
10186                     for (var i = 0; i < p.length; i++) {\r
10187                         p[i] = parseFloat(p[i]);\r
10188                     }\r
10189                     while (off < p.length && !isNaN(p[off])) {\r
10190                         if (isNaN(p[0])) {\r
10191                             break;\r
10192                         }\r
10193                         var ctlPtx;\r
10194                         var ctlPty;\r
10195 \r
10196                         var rx;\r
10197                         var ry;\r
10198                         var psi;\r
10199                         var fa;\r
10200                         var fs;\r
10201 \r
10202                         var x1 = cpx;\r
10203                         var y1 = cpy;\r
10204 \r
10205                         // convert l, H, h, V, and v to L\r
10206                         switch (c) {\r
10207                             case 'l':\r
10208                                 cpx += p[off++];\r
10209                                 cpy += p[off++];\r
10210                                 cmd = CMD.L;\r
10211                                 path.addData(cmd, cpx, cpy);\r
10212                                 break;\r
10213                             case 'L':\r
10214                                 cpx = p[off++];\r
10215                                 cpy = p[off++];\r
10216                                 cmd = CMD.L;\r
10217                                 path.addData(cmd, cpx, cpy);\r
10218                                 break;\r
10219                             case 'm':\r
10220                                 cpx += p[off++];\r
10221                                 cpy += p[off++];\r
10222                                 cmd = CMD.M;\r
10223                                 path.addData(cmd, cpx, cpy);\r
10224                                 c = 'l';\r
10225                                 break;\r
10226                             case 'M':\r
10227                                 cpx = p[off++];\r
10228                                 cpy = p[off++];\r
10229                                 cmd = CMD.M;\r
10230                                 path.addData(cmd, cpx, cpy);\r
10231                                 c = 'L';\r
10232                                 break;\r
10233                             case 'h':\r
10234                                 cpx += p[off++];\r
10235                                 cmd = CMD.L;\r
10236                                 path.addData(cmd, cpx, cpy);\r
10237                                 break;\r
10238                             case 'H':\r
10239                                 cpx = p[off++];\r
10240                                 cmd = CMD.L;\r
10241                                 path.addData(cmd, cpx, cpy);\r
10242                                 break;\r
10243                             case 'v':\r
10244                                 cpy += p[off++];\r
10245                                 cmd = CMD.L;\r
10246                                 path.addData(cmd, cpx, cpy);\r
10247                                 break;\r
10248                             case 'V':\r
10249                                 cpy = p[off++];\r
10250                                 cmd = CMD.L;\r
10251                                 path.addData(cmd, cpx, cpy);\r
10252                                 break;\r
10253                             case 'C':\r
10254                                 cmd = CMD.C;\r
10255                                 path.addData(\r
10256                                     cmd, p[off++], p[off++], p[off++], p[off++], p[off++], p[off++]\r
10257                                 );\r
10258                                 cpx = p[off - 2];\r
10259                                 cpy = p[off - 1];\r
10260                                 break;\r
10261                             case 'c':\r
10262                                 cmd = CMD.C;\r
10263                                 path.addData(\r
10264                                     cmd,\r
10265                                     p[off++] + cpx, p[off++] + cpy,\r
10266                                     p[off++] + cpx, p[off++] + cpy,\r
10267                                     p[off++] + cpx, p[off++] + cpy\r
10268                                 );\r
10269                                 cpx += p[off - 2];\r
10270                                 cpy += p[off - 1];\r
10271                                 break;\r
10272                             case 'S':\r
10273                                 ctlPtx = cpx;\r
10274                                 ctlPty = cpy;\r
10275                                 var len = path.len();\r
10276                                 var pathData = path.data;\r
10277                                 if (prevCmd === CMD.C) {\r
10278                                     ctlPtx += cpx - pathData[len - 4];\r
10279                                     ctlPty += cpy - pathData[len - 3];\r
10280                                 }\r
10281                                 cmd = CMD.C;\r
10282                                 x1 = p[off++];\r
10283                                 y1 = p[off++];\r
10284                                 cpx = p[off++];\r
10285                                 cpy = p[off++];\r
10286                                 path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);\r
10287                                 break;\r
10288                             case 's':\r
10289                                 ctlPtx = cpx;\r
10290                                 ctlPty = cpy;\r
10291                                 var len = path.len();\r
10292                                 var pathData = path.data;\r
10293                                 if (prevCmd === CMD.C) {\r
10294                                     ctlPtx += cpx - pathData[len - 4];\r
10295                                     ctlPty += cpy - pathData[len - 3];\r
10296                                 }\r
10297                                 cmd = CMD.C;\r
10298                                 x1 = cpx + p[off++];\r
10299                                 y1 = cpy + p[off++];\r
10300                                 cpx += p[off++];\r
10301                                 cpy += p[off++];\r
10302                                 path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);\r
10303                                 break;\r
10304                             case 'Q':\r
10305                                 x1 = p[off++];\r
10306                                 y1 = p[off++];\r
10307                                 cpx = p[off++];\r
10308                                 cpy = p[off++];\r
10309                                 cmd = CMD.Q;\r
10310                                 path.addData(cmd, x1, y1, cpx, cpy);\r
10311                                 break;\r
10312                             case 'q':\r
10313                                 x1 = p[off++] + cpx;\r
10314                                 y1 = p[off++] + cpy;\r
10315                                 cpx += p[off++];\r
10316                                 cpy += p[off++];\r
10317                                 cmd = CMD.Q;\r
10318                                 path.addData(cmd, x1, y1, cpx, cpy);\r
10319                                 break;\r
10320                             case 'T':\r
10321                                 ctlPtx = cpx;\r
10322                                 ctlPty = cpy;\r
10323                                 var len = path.len();\r
10324                                 var pathData = path.data;\r
10325                                 if (prevCmd === CMD.Q) {\r
10326                                     ctlPtx += cpx - pathData[len - 4];\r
10327                                     ctlPty += cpy - pathData[len - 3];\r
10328                                 }\r
10329                                 cpx = p[off++];\r
10330                                 cpy = p[off++];\r
10331                                 cmd = CMD.Q;\r
10332                                 path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);\r
10333                                 break;\r
10334                             case 't':\r
10335                                 ctlPtx = cpx;\r
10336                                 ctlPty = cpy;\r
10337                                 var len = path.len();\r
10338                                 var pathData = path.data;\r
10339                                 if (prevCmd === CMD.Q) {\r
10340                                     ctlPtx += cpx - pathData[len - 4];\r
10341                                     ctlPty += cpy - pathData[len - 3];\r
10342                                 }\r
10343                                 cpx += p[off++];\r
10344                                 cpy += p[off++];\r
10345                                 cmd = CMD.Q;\r
10346                                 path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);\r
10347                                 break;\r
10348                             case 'A':\r
10349                                 rx = p[off++];\r
10350                                 ry = p[off++];\r
10351                                 psi = p[off++];\r
10352                                 fa = p[off++];\r
10353                                 fs = p[off++];\r
10354 \r
10355                                 x1 = cpx, y1 = cpy;\r
10356                                 cpx = p[off++];\r
10357                                 cpy = p[off++];\r
10358                                 cmd = CMD.A;\r
10359                                 processArc(\r
10360                                     x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path\r
10361                                 );\r
10362                                 break;\r
10363                             case 'a':\r
10364                                 rx = p[off++];\r
10365                                 ry = p[off++];\r
10366                                 psi = p[off++];\r
10367                                 fa = p[off++];\r
10368                                 fs = p[off++];\r
10369 \r
10370                                 x1 = cpx, y1 = cpy;\r
10371                                 cpx += p[off++];\r
10372                                 cpy += p[off++];\r
10373                                 cmd = CMD.A;\r
10374                                 processArc(\r
10375                                     x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path\r
10376                                 );\r
10377                                 break;\r
10378                         }\r
10379                     }\r
10380 \r
10381                     if (c === 'z' || c === 'Z') {\r
10382                         cmd = CMD.Z;\r
10383                         path.addData(cmd);\r
10384                     }\r
10385 \r
10386                     prevCmd = cmd;\r
10387                 }\r
10388 \r
10389                 path.toStatic();\r
10390 \r
10391                 return path;\r
10392             }\r
10393 \r
10394             // TODO Optimize double memory cost problem\r
10395             function createPathOptions(str, opts) {\r
10396                 var pathProxy = createPathProxyFromString(str);\r
10397                 var transform;\r
10398                 opts = opts || {};\r
10399                 opts.buildPath = function (path) {\r
10400                     path.setData(pathProxy.data);\r
10401                     transform && transformPath(path, transform);\r
10402                     // Svg and vml renderer don't have context\r
10403                     var ctx = path.getContext();\r
10404                     if (ctx) {\r
10405                         path.rebuildPath(ctx);\r
10406                     }\r
10407                 };\r
10408 \r
10409                 opts.applyTransform = function (m) {\r
10410                     if (!transform) {\r
10411                         transform = matrix.create();\r
10412                     }\r
10413                     matrix.mul(transform, m, transform);\r
10414                 };\r
10415 \r
10416                 return opts;\r
10417             }\r
10418 \r
10419             module.exports = {\r
10420                 /**\r
10421                  * Create a Path object from path string data\r
10422                  * http://www.w3.org/TR/SVG/paths.html#PathData\r
10423                  * @param  {Object} opts Other options\r
10424                  */\r
10425                 createFromString: function (str, opts) {\r
10426                     return new Path(createPathOptions(str, opts));\r
10427                 },\r
10428 \r
10429                 /**\r
10430                  * Create a Path class from path string data\r
10431                  * @param  {string} str\r
10432                  * @param  {Object} opts Other options\r
10433                  */\r
10434                 extendFromString: function (str, opts) {\r
10435                     return Path.extend(createPathOptions(str, opts));\r
10436                 },\r
10437 \r
10438                 /**\r
10439                  * Merge multiple paths\r
10440                  */\r
10441                 // TODO Apply transform\r
10442                 // TODO stroke dash\r
10443                 // TODO Optimize double memory cost problem\r
10444                 mergePath: function (pathEls, opts) {\r
10445                     var pathList = [];\r
10446                     var len = pathEls.length;\r
10447                     var pathEl;\r
10448                     var i;\r
10449                     for (i = 0; i < len; i++) {\r
10450                         pathEl = pathEls[i];\r
10451                         if (pathEl.__dirty) {\r
10452                             pathEl.buildPath(pathEl.path, pathEl.shape);\r
10453                         }\r
10454                         pathList.push(pathEl.path);\r
10455                     }\r
10456 \r
10457                     var pathBundle = new Path(opts);\r
10458                     pathBundle.buildPath = function (path) {\r
10459                         path.appendPath(pathList);\r
10460                         // Svg and vml renderer don't have context\r
10461                         var ctx = path.getContext();\r
10462                         if (ctx) {\r
10463                             path.rebuildPath(ctx);\r
10464                         }\r
10465                     };\r
10466 \r
10467                     return pathBundle;\r
10468                 }\r
10469             };\r
10470 \r
10471 \r
10472 /***/ },\r
10473 /* 44 */\r
10474 /***/ function(module, exports, __webpack_require__) {\r
10475 \r
10476         /**\r
10477          * Path element\r
10478          * @module zrender/graphic/Path\r
10479          */\r
10480 \r
10481 \r
10482 \r
10483             var Displayable = __webpack_require__(45);\r
10484             var zrUtil = __webpack_require__(3);\r
10485             var PathProxy = __webpack_require__(48);\r
10486             var pathContain = __webpack_require__(51);\r
10487 \r
10488             var Gradient = __webpack_require__(4);\r
10489 \r
10490             function pathHasFill(style) {\r
10491                 var fill = style.fill;\r
10492                 return fill != null && fill !== 'none';\r
10493             }\r
10494 \r
10495             function pathHasStroke(style) {\r
10496                 var stroke = style.stroke;\r
10497                 return stroke != null && stroke !== 'none' && style.lineWidth > 0;\r
10498             }\r
10499 \r
10500             var abs = Math.abs;\r
10501 \r
10502             /**\r
10503              * @alias module:zrender/graphic/Path\r
10504              * @extends module:zrender/graphic/Displayable\r
10505              * @constructor\r
10506              * @param {Object} opts\r
10507              */\r
10508             function Path(opts) {\r
10509                 Displayable.call(this, opts);\r
10510 \r
10511                 /**\r
10512                  * @type {module:zrender/core/PathProxy}\r
10513                  * @readOnly\r
10514                  */\r
10515                 this.path = new PathProxy();\r
10516             }\r
10517 \r
10518             Path.prototype = {\r
10519 \r
10520                 constructor: Path,\r
10521 \r
10522                 type: 'path',\r
10523 \r
10524                 __dirtyPath: true,\r
10525 \r
10526                 strokeContainThreshold: 5,\r
10527 \r
10528                 brush: function (ctx) {\r
10529                     ctx.save();\r
10530 \r
10531                     var style = this.style;\r
10532                     var path = this.path;\r
10533                     var hasStroke = pathHasStroke(style);\r
10534                     var hasFill = pathHasFill(style);\r
10535 \r
10536                     if (this.__dirtyPath) {\r
10537                         // Update gradient because bounding rect may changed\r
10538                         if (hasFill && (style.fill instanceof Gradient)) {\r
10539                             style.fill.updateCanvasGradient(this, ctx);\r
10540                         }\r
10541                         if (hasStroke && (style.stroke instanceof Gradient)) {\r
10542                             style.stroke.updateCanvasGradient(this, ctx);\r
10543                         }\r
10544                     }\r
10545 \r
10546                     style.bind(ctx, this);\r
10547                     this.setTransform(ctx);\r
10548 \r
10549                     var lineDash = style.lineDash;\r
10550                     var lineDashOffset = style.lineDashOffset;\r
10551 \r
10552                     var ctxLineDash = !!ctx.setLineDash;\r
10553 \r
10554                     // Proxy context\r
10555                     // Rebuild path in following 2 cases\r
10556                     // 1. Path is dirty\r
10557                     // 2. Path needs javascript implemented lineDash stroking.\r
10558                     //    In this case, lineDash information will not be saved in PathProxy\r
10559                     if (this.__dirtyPath || (\r
10560                         lineDash && !ctxLineDash && hasStroke\r
10561                     )) {\r
10562                         path = this.path.beginPath(ctx);\r
10563 \r
10564                         // Setting line dash before build path\r
10565                         if (lineDash && !ctxLineDash) {\r
10566                             path.setLineDash(lineDash);\r
10567                             path.setLineDashOffset(lineDashOffset);\r
10568                         }\r
10569 \r
10570                         this.buildPath(path, this.shape);\r
10571 \r
10572                         // Clear path dirty flag\r
10573                         this.__dirtyPath = false;\r
10574                     }\r
10575                     else {\r
10576                         // Replay path building\r
10577                         ctx.beginPath();\r
10578                         this.path.rebuildPath(ctx);\r
10579                     }\r
10580 \r
10581                     hasFill && path.fill(ctx);\r
10582 \r
10583                     if (lineDash && ctxLineDash) {\r
10584                         ctx.setLineDash(lineDash);\r
10585                         ctx.lineDashOffset = lineDashOffset;\r
10586                     }\r
10587 \r
10588                     hasStroke && path.stroke(ctx);\r
10589 \r
10590                     // Draw rect text\r
10591                     if (style.text != null) {\r
10592                         // var rect = this.getBoundingRect();\r
10593                         this.drawRectText(ctx, this.getBoundingRect());\r
10594                     }\r
10595 \r
10596                     ctx.restore();\r
10597                 },\r
10598 \r
10599                 buildPath: function (ctx, shapeCfg) {},\r
10600 \r
10601                 getBoundingRect: function () {\r
10602                     var rect = this._rect;\r
10603                     var style = this.style;\r
10604                     var needsUpdateRect = !rect;\r
10605                     if (needsUpdateRect) {\r
10606                         var path = this.path;\r
10607                         if (this.__dirtyPath) {\r
10608                             path.beginPath();\r
10609                             this.buildPath(path, this.shape);\r
10610                         }\r
10611                         rect = path.getBoundingRect();\r
10612                     }\r
10613                     this._rect = rect;\r
10614 \r
10615                     if (pathHasStroke(style)) {\r
10616                         // Needs update rect with stroke lineWidth when\r
10617                         // 1. Element changes scale or lineWidth\r
10618                         // 2. Shape is changed\r
10619                         var rectWithStroke = this._rectWithStroke;\r
10620                         if (this.__dirty || needsUpdateRect) {\r
10621                             var rectWithStroke = this._rectWithStroke\r
10622                                 || (this._rectWithStroke = rect.clone());\r
10623                             rectWithStroke.copy(rect);\r
10624                             // FIXME Must after updateTransform\r
10625                             var w = style.lineWidth;\r
10626                             // PENDING, Min line width is needed when line is horizontal or vertical\r
10627                             var lineScale = style.strokeNoScale ? this.getLineScale() : 1;\r
10628 \r
10629                             // Only add extra hover lineWidth when there are no fill\r
10630                             if (!pathHasFill(style)) {\r
10631                                 w = Math.max(w, this.strokeContainThreshold);\r
10632                             }\r
10633                             // Consider line width\r
10634                             // Line scale can't be 0;\r
10635                             if (lineScale > 1e-10) {\r
10636                                 rectWithStroke.width += w / lineScale;\r
10637                                 rectWithStroke.height += w / lineScale;\r
10638                                 rectWithStroke.x -= w / lineScale / 2;\r
10639                                 rectWithStroke.y -= w / lineScale / 2;\r
10640                             }\r
10641                         }\r
10642 \r
10643                         // Return rect with stroke\r
10644                         return rectWithStroke;\r
10645                     }\r
10646 \r
10647                     return rect;\r
10648                 },\r
10649 \r
10650                 contain: function (x, y) {\r
10651                     var localPos = this.transformCoordToLocal(x, y);\r
10652                     var rect = this.getBoundingRect();\r
10653                     var style = this.style;\r
10654                     x = localPos[0];\r
10655                     y = localPos[1];\r
10656 \r
10657                     if (rect.contain(x, y)) {\r
10658                         var pathData = this.path.data;\r
10659                         if (pathHasStroke(style)) {\r
10660                             var lineWidth = style.lineWidth;\r
10661                             var lineScale = style.strokeNoScale ? this.getLineScale() : 1;\r
10662                             // Line scale can't be 0;\r
10663                             if (lineScale > 1e-10) {\r
10664                                 // Only add extra hover lineWidth when there are no fill\r
10665                                 if (!pathHasFill(style)) {\r
10666                                     lineWidth = Math.max(lineWidth, this.strokeContainThreshold);\r
10667                                 }\r
10668                                 if (pathContain.containStroke(\r
10669                                     pathData, lineWidth / lineScale, x, y\r
10670                                 )) {\r
10671                                     return true;\r
10672                                 }\r
10673                             }\r
10674                         }\r
10675                         if (pathHasFill(style)) {\r
10676                             return pathContain.contain(pathData, x, y);\r
10677                         }\r
10678                     }\r
10679                     return false;\r
10680                 },\r
10681 \r
10682                 /**\r
10683                  * @param  {boolean} dirtyPath\r
10684                  */\r
10685                 dirty: function (dirtyPath) {\r
10686                     if (arguments.length ===0) {\r
10687                         dirtyPath = true;\r
10688                     }\r
10689                     // Only mark dirty, not mark clean\r
10690                     if (dirtyPath) {\r
10691                         this.__dirtyPath = dirtyPath;\r
10692                         this._rect = null;\r
10693                     }\r
10694 \r
10695                     this.__dirty = true;\r
10696 \r
10697                     this.__zr && this.__zr.refresh();\r
10698 \r
10699                     // Used as a clipping path\r
10700                     if (this.__clipTarget) {\r
10701                         this.__clipTarget.dirty();\r
10702                     }\r
10703                 },\r
10704 \r
10705                 /**\r
10706                  * Alias for animate('shape')\r
10707                  * @param {boolean} loop\r
10708                  */\r
10709                 animateShape: function (loop) {\r
10710                     return this.animate('shape', loop);\r
10711                 },\r
10712 \r
10713                 // Overwrite attrKV\r
10714                 attrKV: function (key, value) {\r
10715                     // FIXME\r
10716                     if (key === 'shape') {\r
10717                         this.setShape(value);\r
10718                     }\r
10719                     else {\r
10720                         Displayable.prototype.attrKV.call(this, key, value);\r
10721                     }\r
10722                 },\r
10723 \r
10724                 /**\r
10725                  * @param {Object|string} key\r
10726                  * @param {*} value\r
10727                  */\r
10728                 setShape: function (key, value) {\r
10729                     var shape = this.shape;\r
10730                     // Path from string may not have shape\r
10731                     if (shape) {\r
10732                         if (zrUtil.isObject(key)) {\r
10733                             for (var name in key) {\r
10734                                 shape[name] = key[name];\r
10735                             }\r
10736                         }\r
10737                         else {\r
10738                             shape[key] = value;\r
10739                         }\r
10740                         this.dirty(true);\r
10741                     }\r
10742                     return this;\r
10743                 },\r
10744 \r
10745                 getLineScale: function () {\r
10746                     var m = this.transform;\r
10747                     // Get the line scale.\r
10748                     // Determinant of `m` means how much the area is enlarged by the\r
10749                     // transformation. So its square root can be used as a scale factor\r
10750                     // for width.\r
10751                     return m && abs(m[0] - 1) > 1e-10 && abs(m[3] - 1) > 1e-10\r
10752                         ? Math.sqrt(abs(m[0] * m[3] - m[2] * m[1]))\r
10753                         : 1;\r
10754                 }\r
10755             };\r
10756 \r
10757             /**\r
10758              * 扩展一个 Path element, 比如星形,圆等。\r
10759              * Extend a path element\r
10760              * @param {Object} props\r
10761              * @param {string} props.type Path type\r
10762              * @param {Function} props.init Initialize\r
10763              * @param {Function} props.buildPath Overwrite buildPath method\r
10764              * @param {Object} [props.style] Extended default style config\r
10765              * @param {Object} [props.shape] Extended default shape config\r
10766              */\r
10767             Path.extend = function (defaults) {\r
10768                 var Sub = function (opts) {\r
10769                     Path.call(this, opts);\r
10770 \r
10771                     if (defaults.style) {\r
10772                         // Extend default style\r
10773                         this.style.extendFrom(defaults.style, false);\r
10774                     }\r
10775 \r
10776                     // Extend default shape\r
10777                     var defaultShape = defaults.shape;\r
10778                     if (defaultShape) {\r
10779                         this.shape = this.shape || {};\r
10780                         var thisShape = this.shape;\r
10781                         for (var name in defaultShape) {\r
10782                             if (\r
10783                                 ! thisShape.hasOwnProperty(name)\r
10784                                 && defaultShape.hasOwnProperty(name)\r
10785                             ) {\r
10786                                 thisShape[name] = defaultShape[name];\r
10787                             }\r
10788                         }\r
10789                     }\r
10790 \r
10791                     defaults.init && defaults.init.call(this, opts);\r
10792                 };\r
10793 \r
10794                 zrUtil.inherits(Sub, Path);\r
10795 \r
10796                 // FIXME 不能 extend position, rotation 等引用对象\r
10797                 for (var name in defaults) {\r
10798                     // Extending prototype values and methods\r
10799                     if (name !== 'style' && name !== 'shape') {\r
10800                         Sub.prototype[name] = defaults[name];\r
10801                     }\r
10802                 }\r
10803 \r
10804                 return Sub;\r
10805             };\r
10806 \r
10807             zrUtil.inherits(Path, Displayable);\r
10808 \r
10809             module.exports = Path;\r
10810 \r
10811 \r
10812 /***/ },\r
10813 /* 45 */\r
10814 /***/ function(module, exports, __webpack_require__) {\r
10815 \r
10816         /**\r
10817          * 可绘制的图形基类\r
10818          * Base class of all displayable graphic objects\r
10819          * @module zrender/graphic/Displayable\r
10820          */\r
10821 \r
10822 \r
10823 \r
10824             var zrUtil = __webpack_require__(3);\r
10825 \r
10826             var Style = __webpack_require__(46);\r
10827 \r
10828             var Element = __webpack_require__(30);\r
10829             var RectText = __webpack_require__(47);\r
10830             // var Stateful = require('./mixin/Stateful');\r
10831 \r
10832             /**\r
10833              * @alias module:zrender/graphic/Displayable\r
10834              * @extends module:zrender/Element\r
10835              * @extends module:zrender/graphic/mixin/RectText\r
10836              */\r
10837             function Displayable(opts) {\r
10838 \r
10839                 opts = opts || {};\r
10840 \r
10841                 Element.call(this, opts);\r
10842 \r
10843                 // Extend properties\r
10844                 for (var name in opts) {\r
10845                     if (\r
10846                         opts.hasOwnProperty(name) &&\r
10847                         name !== 'style'\r
10848                     ) {\r
10849                         this[name] = opts[name];\r
10850                     }\r
10851                 }\r
10852 \r
10853                 /**\r
10854                  * @type {module:zrender/graphic/Style}\r
10855                  */\r
10856                 this.style = new Style(opts.style);\r
10857 \r
10858                 this._rect = null;\r
10859                 // Shapes for cascade clipping.\r
10860                 this.__clipPaths = [];\r
10861 \r
10862                 // FIXME Stateful must be mixined after style is setted\r
10863                 // Stateful.call(this, opts);\r
10864             }\r
10865 \r
10866             Displayable.prototype = {\r
10867 \r
10868                 constructor: Displayable,\r
10869 \r
10870                 type: 'displayable',\r
10871 \r
10872                 /**\r
10873                  * Displayable 是否为脏,Painter 中会根据该标记判断是否需要是否需要重新绘制\r
10874                  * Dirty flag. From which painter will determine if this displayable object needs brush\r
10875                  * @name module:zrender/graphic/Displayable#__dirty\r
10876                  * @type {boolean}\r
10877                  */\r
10878                 __dirty: true,\r
10879 \r
10880                 /**\r
10881                  * 图形是否可见,为true时不绘制图形,但是仍能触发鼠标事件\r
10882                  * If ignore drawing of the displayable object. Mouse event will still be triggered\r
10883                  * @name module:/zrender/graphic/Displayable#invisible\r
10884                  * @type {boolean}\r
10885                  * @default false\r
10886                  */\r
10887                 invisible: false,\r
10888 \r
10889                 /**\r
10890                  * @name module:/zrender/graphic/Displayable#z\r
10891                  * @type {number}\r
10892                  * @default 0\r
10893                  */\r
10894                 z: 0,\r
10895 \r
10896                 /**\r
10897                  * @name module:/zrender/graphic/Displayable#z\r
10898                  * @type {number}\r
10899                  * @default 0\r
10900                  */\r
10901                 z2: 0,\r
10902 \r
10903                 /**\r
10904                  * z层level,决定绘画在哪层canvas中\r
10905                  * @name module:/zrender/graphic/Displayable#zlevel\r
10906                  * @type {number}\r
10907                  * @default 0\r
10908                  */\r
10909                 zlevel: 0,\r
10910 \r
10911                 /**\r
10912                  * 是否可拖拽\r
10913                  * @name module:/zrender/graphic/Displayable#draggable\r
10914                  * @type {boolean}\r
10915                  * @default false\r
10916                  */\r
10917                 draggable: false,\r
10918 \r
10919                 /**\r
10920                  * 是否正在拖拽\r
10921                  * @name module:/zrender/graphic/Displayable#draggable\r
10922                  * @type {boolean}\r
10923                  * @default false\r
10924                  */\r
10925                 dragging: false,\r
10926 \r
10927                 /**\r
10928                  * 是否相应鼠标事件\r
10929                  * @name module:/zrender/graphic/Displayable#silent\r
10930                  * @type {boolean}\r
10931                  * @default false\r
10932                  */\r
10933                 silent: false,\r
10934 \r
10935                 /**\r
10936                  * If enable culling\r
10937                  * @type {boolean}\r
10938                  * @default false\r
10939                  */\r
10940                 culling: false,\r
10941 \r
10942                 /**\r
10943                  * Mouse cursor when hovered\r
10944                  * @name module:/zrender/graphic/Displayable#cursor\r
10945                  * @type {string}\r
10946                  */\r
10947                 cursor: 'pointer',\r
10948 \r
10949                 /**\r
10950                  * If hover area is bounding rect\r
10951                  * @name module:/zrender/graphic/Displayable#rectHover\r
10952                  * @type {string}\r
10953                  */\r
10954                 rectHover: false,\r
10955 \r
10956                 beforeBrush: function (ctx) {},\r
10957 \r
10958                 afterBrush: function (ctx) {},\r
10959 \r
10960                 /**\r
10961                  * 图形绘制方法\r
10962                  * @param {Canvas2DRenderingContext} ctx\r
10963                  */\r
10964                 // Interface\r
10965                 brush: function (ctx) {},\r
10966 \r
10967                 /**\r
10968                  * 获取最小包围盒\r
10969                  * @return {module:zrender/core/BoundingRect}\r
10970                  */\r
10971                 // Interface\r
10972                 getBoundingRect: function () {},\r
10973 \r
10974                 /**\r
10975                  * 判断坐标 x, y 是否在图形上\r
10976                  * If displayable element contain coord x, y\r
10977                  * @param  {number} x\r
10978                  * @param  {number} y\r
10979                  * @return {boolean}\r
10980                  */\r
10981                 contain: function (x, y) {\r
10982                     return this.rectContain(x, y);\r
10983                 },\r
10984 \r
10985                 /**\r
10986                  * @param  {Function} cb\r
10987                  * @param  {}   context\r
10988                  */\r
10989                 traverse: function (cb, context) {\r
10990                     cb.call(context, this);\r
10991                 },\r
10992 \r
10993                 /**\r
10994                  * 判断坐标 x, y 是否在图形的包围盒上\r
10995                  * If bounding rect of element contain coord x, y\r
10996                  * @param  {number} x\r
10997                  * @param  {number} y\r
10998                  * @return {boolean}\r
10999                  */\r
11000                 rectContain: function (x, y) {\r
11001                     var coord = this.transformCoordToLocal(x, y);\r
11002                     var rect = this.getBoundingRect();\r
11003                     return rect.contain(coord[0], coord[1]);\r
11004                 },\r
11005 \r
11006                 /**\r
11007                  * 标记图形元素为脏,并且在下一帧重绘\r
11008                  * Mark displayable element dirty and refresh next frame\r
11009                  */\r
11010                 dirty: function () {\r
11011                     this.__dirty = true;\r
11012 \r
11013                     this._rect = null;\r
11014 \r
11015                     this.__zr && this.__zr.refresh();\r
11016                 },\r
11017 \r
11018                 /**\r
11019                  * 图形是否会触发事件\r
11020                  * If displayable object binded any event\r
11021                  * @return {boolean}\r
11022                  */\r
11023                 // TODO, 通过 bind 绑定的事件\r
11024                 // isSilent: function () {\r
11025                 //     return !(\r
11026                 //         this.hoverable || this.draggable\r
11027                 //         || this.onmousemove || this.onmouseover || this.onmouseout\r
11028                 //         || this.onmousedown || this.onmouseup || this.onclick\r
11029                 //         || this.ondragenter || this.ondragover || this.ondragleave\r
11030                 //         || this.ondrop\r
11031                 //     );\r
11032                 // },\r
11033                 /**\r
11034                  * Alias for animate('style')\r
11035                  * @param {boolean} loop\r
11036                  */\r
11037                 animateStyle: function (loop) {\r
11038                     return this.animate('style', loop);\r
11039                 },\r
11040 \r
11041                 attrKV: function (key, value) {\r
11042                     if (key !== 'style') {\r
11043                         Element.prototype.attrKV.call(this, key, value);\r
11044                     }\r
11045                     else {\r
11046                         this.style.set(value);\r
11047                     }\r
11048                 },\r
11049 \r
11050                 /**\r
11051                  * @param {Object|string} key\r
11052                  * @param {*} value\r
11053                  */\r
11054                 setStyle: function (key, value) {\r
11055                     this.style.set(key, value);\r
11056                     this.dirty(false);\r
11057                     return this;\r
11058                 }\r
11059             };\r
11060 \r
11061             zrUtil.inherits(Displayable, Element);\r
11062 \r
11063             zrUtil.mixin(Displayable, RectText);\r
11064             // zrUtil.mixin(Displayable, Stateful);\r
11065 \r
11066             module.exports = Displayable;\r
11067 \r
11068 \r
11069 /***/ },\r
11070 /* 46 */\r
11071 /***/ function(module, exports) {\r
11072 \r
11073         /**\r
11074          * @module zrender/graphic/Style\r
11075          */\r
11076 \r
11077 \r
11078 \r
11079             var STYLE_LIST_COMMON = [\r
11080                 'lineCap', 'lineJoin', 'miterLimit',\r
11081                 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'shadowColor'\r
11082             ];\r
11083 \r
11084             var Style = function (opts) {\r
11085                 this.extendFrom(opts);\r
11086             };\r
11087 \r
11088             Style.prototype = {\r
11089 \r
11090                 constructor: Style,\r
11091 \r
11092                 /**\r
11093                  * @type {string}\r
11094                  */\r
11095                 fill: '#000000',\r
11096 \r
11097                 /**\r
11098                  * @type {string}\r
11099                  */\r
11100                 stroke: null,\r
11101 \r
11102                 /**\r
11103                  * @type {number}\r
11104                  */\r
11105                 opacity: 1,\r
11106 \r
11107                 /**\r
11108                  * @type {Array.<number>}\r
11109                  */\r
11110                 lineDash: null,\r
11111 \r
11112                 /**\r
11113                  * @type {number}\r
11114                  */\r
11115                 lineDashOffset: 0,\r
11116 \r
11117                 /**\r
11118                  * @type {number}\r
11119                  */\r
11120                 shadowBlur: 0,\r
11121 \r
11122                 /**\r
11123                  * @type {number}\r
11124                  */\r
11125                 shadowOffsetX: 0,\r
11126 \r
11127                 /**\r
11128                  * @type {number}\r
11129                  */\r
11130                 shadowOffsetY: 0,\r
11131 \r
11132                 /**\r
11133                  * @type {number}\r
11134                  */\r
11135                 lineWidth: 1,\r
11136 \r
11137                 /**\r
11138                  * If stroke ignore scale\r
11139                  * @type {Boolean}\r
11140                  */\r
11141                 strokeNoScale: false,\r
11142 \r
11143                 // Bounding rect text configuration\r
11144                 // Not affected by element transform\r
11145                 /**\r
11146                  * @type {string}\r
11147                  */\r
11148                 text: null,\r
11149 \r
11150                 /**\r
11151                  * @type {string}\r
11152                  */\r
11153                 textFill: '#000',\r
11154 \r
11155                 /**\r
11156                  * @type {string}\r
11157                  */\r
11158                 textStroke: null,\r
11159 \r
11160                 /**\r
11161                  * 'inside', 'left', 'right', 'top', 'bottom'\r
11162                  * [x, y]\r
11163                  * @type {string|Array.<number>}\r
11164                  * @default 'inside'\r
11165                  */\r
11166                 textPosition: 'inside',\r
11167 \r
11168                 /**\r
11169                  * @type {string}\r
11170                  */\r
11171                 textBaseline: null,\r
11172 \r
11173                 /**\r
11174                  * @type {string}\r
11175                  */\r
11176                 textAlign: null,\r
11177 \r
11178                 /**\r
11179                  * @type {string}\r
11180                  */\r
11181                 textVerticalAlign: null,\r
11182 \r
11183                 /**\r
11184                  * @type {number}\r
11185                  */\r
11186                 textDistance: 5,\r
11187 \r
11188                 /**\r
11189                  * @type {number}\r
11190                  */\r
11191                 textShadowBlur: 0,\r
11192 \r
11193                 /**\r
11194                  * @type {number}\r
11195                  */\r
11196                 textShadowOffsetX: 0,\r
11197 \r
11198                 /**\r
11199                  * @type {number}\r
11200                  */\r
11201                 textShadowOffsetY: 0,\r
11202 \r
11203                 /**\r
11204                  * @param {CanvasRenderingContext2D} ctx\r
11205                  */\r
11206                 bind: function (ctx, el) {\r
11207                     var fill = this.fill;\r
11208                     var stroke = this.stroke;\r
11209                     for (var i = 0; i < STYLE_LIST_COMMON.length; i++) {\r
11210                         var styleName = STYLE_LIST_COMMON[i];\r
11211 \r
11212                         if (this[styleName] != null) {\r
11213                             ctx[styleName] = this[styleName];\r
11214                         }\r
11215                     }\r
11216                     if (stroke != null) {\r
11217                         var lineWidth = this.lineWidth;\r
11218                         ctx.lineWidth = lineWidth / (\r
11219                             (this.strokeNoScale && el && el.getLineScale) ? el.getLineScale() : 1\r
11220                         );\r
11221                     }\r
11222                     if (fill != null) {\r
11223                          // Use canvas gradient if has\r
11224                         ctx.fillStyle = fill.canvasGradient ? fill.canvasGradient : fill;\r
11225                     }\r
11226                     if (stroke != null) {\r
11227                          // Use canvas gradient if has\r
11228                         ctx.strokeStyle = stroke.canvasGradient ? stroke.canvasGradient : stroke;\r
11229                     }\r
11230                     this.opacity != null && (ctx.globalAlpha = this.opacity);\r
11231                 },\r
11232 \r
11233                 /**\r
11234                  * Extend from other style\r
11235                  * @param {zrender/graphic/Style} otherStyle\r
11236                  * @param {boolean} overwrite\r
11237                  */\r
11238                 extendFrom: function (otherStyle, overwrite) {\r
11239                     if (otherStyle) {\r
11240                         var target = this;\r
11241                         for (var name in otherStyle) {\r
11242                             if (otherStyle.hasOwnProperty(name)\r
11243                                 && (overwrite || ! target.hasOwnProperty(name))\r
11244                             ) {\r
11245                                 target[name] = otherStyle[name];\r
11246                             }\r
11247                         }\r
11248                     }\r
11249                 },\r
11250 \r
11251                 /**\r
11252                  * Batch setting style with a given object\r
11253                  * @param {Object|string} obj\r
11254                  * @param {*} [obj]\r
11255                  */\r
11256                 set: function (obj, value) {\r
11257                     if (typeof obj === 'string') {\r
11258                         this[obj] = value;\r
11259                     }\r
11260                     else {\r
11261                         this.extendFrom(obj, true);\r
11262                     }\r
11263                 },\r
11264 \r
11265                 /**\r
11266                  * Clone\r
11267                  * @return {zrender/graphic/Style} [description]\r
11268                  */\r
11269                 clone: function () {\r
11270                     var newStyle = new this.constructor();\r
11271                     newStyle.extendFrom(this, true);\r
11272                     return newStyle;\r
11273                 }\r
11274             };\r
11275 \r
11276             var styleProto = Style.prototype;\r
11277             var name;\r
11278             var i;\r
11279             for (i = 0; i < STYLE_LIST_COMMON.length; i++) {\r
11280                 name = STYLE_LIST_COMMON[i];\r
11281                 if (!(name in styleProto)) {\r
11282                     styleProto[name] = null;\r
11283                 }\r
11284             }\r
11285 \r
11286             module.exports = Style;\r
11287 \r
11288 \r
11289 /***/ },\r
11290 /* 47 */\r
11291 /***/ function(module, exports, __webpack_require__) {\r
11292 \r
11293         /**\r
11294          * Mixin for drawing text in a element bounding rect\r
11295          * @module zrender/mixin/RectText\r
11296          */\r
11297 \r
11298 \r
11299 \r
11300             var textContain = __webpack_require__(14);\r
11301             var BoundingRect = __webpack_require__(15);\r
11302 \r
11303             var tmpRect = new BoundingRect();\r
11304 \r
11305             var RectText = function () {};\r
11306 \r
11307             function parsePercent(value, maxValue) {\r
11308                 if (typeof value === 'string') {\r
11309                     if (value.lastIndexOf('%') >= 0) {\r
11310                         return parseFloat(value) / 100 * maxValue;\r
11311                     }\r
11312                     return parseFloat(value);\r
11313                 }\r
11314                 return value;\r
11315             }\r
11316 \r
11317             function setTransform(ctx, m) {\r
11318                 ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\r
11319             }\r
11320 \r
11321             RectText.prototype = {\r
11322 \r
11323                 constructor: RectText,\r
11324 \r
11325                 /**\r
11326                  * Draw text in a rect with specified position.\r
11327                  * @param  {CanvasRenderingContext} ctx\r
11328                  * @param  {Object} rect Displayable rect\r
11329                  * @return {Object} textRect Alternative precalculated text bounding rect\r
11330                  */\r
11331                 drawRectText: function (ctx, rect, textRect) {\r
11332                     var style = this.style;\r
11333                     var text = style.text;\r
11334                     // Convert to string\r
11335                     text != null && (text += '');\r
11336                     if (!text) {\r
11337                         return;\r
11338                     }\r
11339                     var x;\r
11340                     var y;\r
11341                     var textPosition = style.textPosition;\r
11342                     var distance = style.textDistance;\r
11343                     var align = style.textAlign;\r
11344                     var font = style.textFont || style.font;\r
11345                     var baseline = style.textBaseline;\r
11346                     var verticalAlign = style.textVerticalAlign;\r
11347 \r
11348                     textRect = textRect || textContain.getBoundingRect(text, font, align, baseline);\r
11349 \r
11350                     // Transform rect to view space\r
11351                     var transform = this.transform;\r
11352                     var invTransform = this.invTransform;\r
11353                     if (transform) {\r
11354                         tmpRect.copy(rect);\r
11355                         tmpRect.applyTransform(transform);\r
11356                         rect = tmpRect;\r
11357                         // Transform back\r
11358                         setTransform(ctx, invTransform);\r
11359                     }\r
11360 \r
11361                     // Text position represented by coord\r
11362                     if (textPosition instanceof Array) {\r
11363                         // Percent\r
11364                         x = rect.x + parsePercent(textPosition[0], rect.width);\r
11365                         y = rect.y + parsePercent(textPosition[1], rect.height);\r
11366                         align = align || 'left';\r
11367                         baseline = baseline || 'top';\r
11368                     }\r
11369                     else {\r
11370                         var res = textContain.adjustTextPositionOnRect(\r
11371                             textPosition, rect, textRect, distance\r
11372                         );\r
11373                         x = res.x;\r
11374                         y = res.y;\r
11375                         // Default align and baseline when has textPosition\r
11376                         align = align || res.textAlign;\r
11377                         baseline = baseline || res.textBaseline;\r
11378                     }\r
11379 \r
11380                     ctx.textAlign = align;\r
11381                     if (verticalAlign) {\r
11382                         switch (verticalAlign) {\r
11383                             case 'middle':\r
11384                                 y -= textRect.height / 2;\r
11385                                 break;\r
11386                             case 'bottom':\r
11387                                 y -= textRect.height;\r
11388                                 break;\r
11389                             // 'top'\r
11390                         }\r
11391                         // Ignore baseline\r
11392                         ctx.textBaseline = 'top';\r
11393                     }\r
11394                     else {\r
11395                         ctx.textBaseline = baseline;\r
11396                     }\r
11397 \r
11398                     var textFill = style.textFill;\r
11399                     var textStroke = style.textStroke;\r
11400                     textFill && (ctx.fillStyle = textFill);\r
11401                     textStroke && (ctx.strokeStyle = textStroke);\r
11402                     ctx.font = font;\r
11403 \r
11404                     // Text shadow\r
11405                     ctx.shadowColor = style.textShadowColor;\r
11406                     ctx.shadowBlur = style.textShadowBlur;\r
11407                     ctx.shadowOffsetX = style.textShadowOffsetX;\r
11408                     ctx.shadowOffsetY = style.textShadowOffsetY;\r
11409 \r
11410                     var textLines = text.split('\n');\r
11411                     for (var i = 0; i < textLines.length; i++) {\r
11412                         textFill && ctx.fillText(textLines[i], x, y);\r
11413                         textStroke && ctx.strokeText(textLines[i], x, y);\r
11414                         y += textRect.lineHeight;\r
11415                     }\r
11416 \r
11417                     // Transform again\r
11418                     transform && setTransform(ctx, transform);\r
11419                 }\r
11420             };\r
11421 \r
11422             module.exports = RectText;\r
11423 \r
11424 \r
11425 /***/ },\r
11426 /* 48 */\r
11427 /***/ function(module, exports, __webpack_require__) {\r
11428 \r
11429         'use strict';\r
11430         /**\r
11431          * Path 代理,可以在`buildPath`中用于替代`ctx`, 会保存每个path操作的命令到pathCommands属性中\r
11432          * 可以用于 isInsidePath 判断以及获取boundingRect\r
11433          *\r
11434          * @module zrender/core/PathProxy\r
11435          * @author Yi Shen (http://www.github.com/pissang)\r
11436          */\r
11437 \r
11438          // TODO getTotalLength, getPointAtLength\r
11439 \r
11440 \r
11441             var curve = __webpack_require__(49);\r
11442             var vec2 = __webpack_require__(16);\r
11443             var bbox = __webpack_require__(50);\r
11444             var BoundingRect = __webpack_require__(15);\r
11445 \r
11446             var CMD = {\r
11447                 M: 1,\r
11448                 L: 2,\r
11449                 C: 3,\r
11450                 Q: 4,\r
11451                 A: 5,\r
11452                 Z: 6,\r
11453                 // Rect\r
11454                 R: 7\r
11455             };\r
11456 \r
11457             var min = [];\r
11458             var max = [];\r
11459             var min2 = [];\r
11460             var max2 = [];\r
11461             var mathMin = Math.min;\r
11462             var mathMax = Math.max;\r
11463             var mathCos = Math.cos;\r
11464             var mathSin = Math.sin;\r
11465             var mathSqrt = Math.sqrt;\r
11466 \r
11467             var hasTypedArray = typeof Float32Array != 'undefined';\r
11468 \r
11469             /**\r
11470              * @alias module:zrender/core/PathProxy\r
11471              * @constructor\r
11472              */\r
11473             var PathProxy = function () {\r
11474 \r
11475                 /**\r
11476                  * Path data. Stored as flat array\r
11477                  * @type {Array.<Object>}\r
11478                  */\r
11479                 this.data = [];\r
11480 \r
11481                 this._len = 0;\r
11482 \r
11483                 this._ctx = null;\r
11484 \r
11485                 this._xi = 0;\r
11486                 this._yi = 0;\r
11487 \r
11488                 this._x0 = 0;\r
11489                 this._y0 = 0;\r
11490             };\r
11491 \r
11492             /**\r
11493              * 快速计算Path包围盒(并不是最小包围盒)\r
11494              * @return {Object}\r
11495              */\r
11496             PathProxy.prototype = {\r
11497 \r
11498                 constructor: PathProxy,\r
11499 \r
11500                 _lineDash: null,\r
11501 \r
11502                 _dashOffset: 0,\r
11503 \r
11504                 _dashIdx: 0,\r
11505 \r
11506                 _dashSum: 0,\r
11507 \r
11508                 getContext: function () {\r
11509                     return this._ctx;\r
11510                 },\r
11511 \r
11512                 /**\r
11513                  * @param  {CanvasRenderingContext2D} ctx\r
11514                  * @return {module:zrender/core/PathProxy}\r
11515                  */\r
11516                 beginPath: function (ctx) {\r
11517                     this._ctx = ctx;\r
11518 \r
11519                     ctx && ctx.beginPath();\r
11520 \r
11521                     // Reset\r
11522                     this._len = 0;\r
11523 \r
11524                     if (this._lineDash) {\r
11525                         this._lineDash = null;\r
11526 \r
11527                         this._dashOffset = 0;\r
11528                     }\r
11529 \r
11530                     return this;\r
11531                 },\r
11532 \r
11533                 /**\r
11534                  * @param  {number} x\r
11535                  * @param  {number} y\r
11536                  * @return {module:zrender/core/PathProxy}\r
11537                  */\r
11538                 moveTo: function (x, y) {\r
11539                     this.addData(CMD.M, x, y);\r
11540                     this._ctx && this._ctx.moveTo(x, y);\r
11541 \r
11542                     // x0, y0, xi, yi 是记录在 _dashedXXXXTo 方法中使用\r
11543                     // xi, yi 记录当前点, x0, y0 在 closePath 的时候回到起始点。\r
11544                     // 有可能在 beginPath 之后直接调用 lineTo,这时候 x0, y0 需要\r
11545                     // 在 lineTo 方法中记录,这里先不考虑这种情况,dashed line 也只在 IE10- 中不支持\r
11546                     this._x0 = x;\r
11547                     this._y0 = y;\r
11548 \r
11549                     this._xi = x;\r
11550                     this._yi = y;\r
11551 \r
11552                     return this;\r
11553                 },\r
11554 \r
11555                 /**\r
11556                  * @param  {number} x\r
11557                  * @param  {number} y\r
11558                  * @return {module:zrender/core/PathProxy}\r
11559                  */\r
11560                 lineTo: function (x, y) {\r
11561                     this.addData(CMD.L, x, y);\r
11562                     if (this._ctx) {\r
11563                         this._needsDash() ? this._dashedLineTo(x, y)\r
11564                             : this._ctx.lineTo(x, y);\r
11565                     }\r
11566                     this._xi = x;\r
11567                     this._yi = y;\r
11568                     return this;\r
11569                 },\r
11570 \r
11571                 /**\r
11572                  * @param  {number} x1\r
11573                  * @param  {number} y1\r
11574                  * @param  {number} x2\r
11575                  * @param  {number} y2\r
11576                  * @param  {number} x3\r
11577                  * @param  {number} y3\r
11578                  * @return {module:zrender/core/PathProxy}\r
11579                  */\r
11580                 bezierCurveTo: function (x1, y1, x2, y2, x3, y3) {\r
11581                     this.addData(CMD.C, x1, y1, x2, y2, x3, y3);\r
11582                     if (this._ctx) {\r
11583                         this._needsDash() ? this._dashedBezierTo(x1, y1, x2, y2, x3, y3)\r
11584                             : this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);\r
11585                     }\r
11586                     this._xi = x3;\r
11587                     this._yi = y3;\r
11588                     return this;\r
11589                 },\r
11590 \r
11591                 /**\r
11592                  * @param  {number} x1\r
11593                  * @param  {number} y1\r
11594                  * @param  {number} x2\r
11595                  * @param  {number} y2\r
11596                  * @return {module:zrender/core/PathProxy}\r
11597                  */\r
11598                 quadraticCurveTo: function (x1, y1, x2, y2) {\r
11599                     this.addData(CMD.Q, x1, y1, x2, y2);\r
11600                     if (this._ctx) {\r
11601                         this._needsDash() ? this._dashedQuadraticTo(x1, y1, x2, y2)\r
11602                             : this._ctx.quadraticCurveTo(x1, y1, x2, y2);\r
11603                     }\r
11604                     this._xi = x2;\r
11605                     this._yi = y2;\r
11606                     return this;\r
11607                 },\r
11608 \r
11609                 /**\r
11610                  * @param  {number} cx\r
11611                  * @param  {number} cy\r
11612                  * @param  {number} r\r
11613                  * @param  {number} startAngle\r
11614                  * @param  {number} endAngle\r
11615                  * @param  {boolean} anticlockwise\r
11616                  * @return {module:zrender/core/PathProxy}\r
11617                  */\r
11618                 arc: function (cx, cy, r, startAngle, endAngle, anticlockwise) {\r
11619                     this.addData(\r
11620                         CMD.A, cx, cy, r, r, startAngle, endAngle - startAngle, 0, anticlockwise ? 0 : 1\r
11621                     );\r
11622                     this._ctx && this._ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);\r
11623 \r
11624                     this._xi = mathCos(endAngle) * r + cx;\r
11625                     this._xi = mathSin(endAngle) * r + cx;\r
11626                     return this;\r
11627                 },\r
11628 \r
11629                 // TODO\r
11630                 arcTo: function (x1, y1, x2, y2, radius) {\r
11631                     if (this._ctx) {\r
11632                         this._ctx.arcTo(x1, y1, x2, y2, radius);\r
11633                     }\r
11634                     return this;\r
11635                 },\r
11636 \r
11637                 // TODO\r
11638                 rect: function (x, y, w, h) {\r
11639                     this._ctx && this._ctx.rect(x, y, w, h);\r
11640                     this.addData(CMD.R, x, y, w, h);\r
11641                     return this;\r
11642                 },\r
11643 \r
11644                 /**\r
11645                  * @return {module:zrender/core/PathProxy}\r
11646                  */\r
11647                 closePath: function () {\r
11648                     this.addData(CMD.Z);\r
11649 \r
11650                     var ctx = this._ctx;\r
11651                     var x0 = this._x0;\r
11652                     var y0 = this._y0;\r
11653                     if (ctx) {\r
11654                         this._needsDash() && this._dashedLineTo(x0, y0);\r
11655                         ctx.closePath();\r
11656                     }\r
11657 \r
11658                     this._xi = x0;\r
11659                     this._yi = y0;\r
11660                     return this;\r
11661                 },\r
11662 \r
11663                 /**\r
11664                  * Context 从外部传入,因为有可能是 rebuildPath 完之后再 fill。\r
11665                  * stroke 同样\r
11666                  * @param {CanvasRenderingContext2D} ctx\r
11667                  * @return {module:zrender/core/PathProxy}\r
11668                  */\r
11669                 fill: function (ctx) {\r
11670                     ctx && ctx.fill();\r
11671                     this.toStatic();\r
11672                 },\r
11673 \r
11674                 /**\r
11675                  * @param {CanvasRenderingContext2D} ctx\r
11676                  * @return {module:zrender/core/PathProxy}\r
11677                  */\r
11678                 stroke: function (ctx) {\r
11679                     ctx && ctx.stroke();\r
11680                     this.toStatic();\r
11681                 },\r
11682 \r
11683                 /**\r
11684                  * 必须在其它绘制命令前调用\r
11685                  * Must be invoked before all other path drawing methods\r
11686                  * @return {module:zrender/core/PathProxy}\r
11687                  */\r
11688                 setLineDash: function (lineDash) {\r
11689                     if (lineDash instanceof Array) {\r
11690                         this._lineDash = lineDash;\r
11691 \r
11692                         this._dashIdx = 0;\r
11693 \r
11694                         var lineDashSum = 0;\r
11695                         for (var i = 0; i < lineDash.length; i++) {\r
11696                             lineDashSum += lineDash[i];\r
11697                         }\r
11698                         this._dashSum = lineDashSum;\r
11699                     }\r
11700                     return this;\r
11701                 },\r
11702 \r
11703                 /**\r
11704                  * 必须在其它绘制命令前调用\r
11705                  * Must be invoked before all other path drawing methods\r
11706                  * @return {module:zrender/core/PathProxy}\r
11707                  */\r
11708                 setLineDashOffset: function (offset) {\r
11709                     this._dashOffset = offset;\r
11710                     return this;\r
11711                 },\r
11712 \r
11713                 /**\r
11714                  *\r
11715                  * @return {boolean}\r
11716                  */\r
11717                 len: function () {\r
11718                     return this._len;\r
11719                 },\r
11720 \r
11721                 /**\r
11722                  * 直接设置 Path 数据\r
11723                  */\r
11724                 setData: function (data) {\r
11725 \r
11726                     var len = data.length;\r
11727 \r
11728                     if (! (this.data && this.data.length == len) && hasTypedArray) {\r
11729                         this.data = new Float32Array(len);\r
11730                     }\r
11731 \r
11732                     for (var i = 0; i < len; i++) {\r
11733                         this.data[i] = data[i];\r
11734                     }\r
11735 \r
11736                     this._len = len;\r
11737                 },\r
11738 \r
11739                 /**\r
11740                  * 添加子路径\r
11741                  * @param {module:zrender/core/PathProxy|Array.<module:zrender/core/PathProxy>} path\r
11742                  */\r
11743                 appendPath: function (path) {\r
11744                     if (!(path instanceof Array)) {\r
11745                         path = [path];\r
11746                     }\r
11747                     var len = path.length;\r
11748                     var appendSize = 0;\r
11749                     var offset = this._len;\r
11750                     for (var i = 0; i < len; i++) {\r
11751                         appendSize += path[i].len();\r
11752                     }\r
11753                     if (hasTypedArray && (this.data instanceof Float32Array)) {\r
11754                         this.data = new Float32Array(offset + appendSize);\r
11755                     }\r
11756                     for (var i = 0; i < len; i++) {\r
11757                         var appendPathData = path[i].data;\r
11758                         for (var k = 0; k < appendPathData.length; k++) {\r
11759                             this.data[offset++] = appendPathData[k];\r
11760                         }\r
11761                     }\r
11762                     this._len = offset;\r
11763                 },\r
11764 \r
11765                 /**\r
11766                  * 填充 Path 数据。\r
11767                  * 尽量复用而不申明新的数组。大部分图形重绘的指令数据长度都是不变的。\r
11768                  */\r
11769                 addData: function (cmd) {\r
11770                     var data = this.data;\r
11771                     if (this._len + arguments.length > data.length) {\r
11772                         // 因为之前的数组已经转换成静态的 Float32Array\r
11773                         // 所以不够用时需要扩展一个新的动态数组\r
11774                         this._expandData();\r
11775                         data = this.data;\r
11776                     }\r
11777                     for (var i = 0; i < arguments.length; i++) {\r
11778                         data[this._len++] = arguments[i];\r
11779                     }\r
11780 \r
11781                     this._prevCmd = cmd;\r
11782                 },\r
11783 \r
11784                 _expandData: function () {\r
11785                     // Only if data is Float32Array\r
11786                     if (!(this.data instanceof Array)) {\r
11787                         var newData = [];\r
11788                         for (var i = 0; i < this._len; i++) {\r
11789                             newData[i] = this.data[i];\r
11790                         }\r
11791                         this.data = newData;\r
11792                     }\r
11793                 },\r
11794 \r
11795                 /**\r
11796                  * If needs js implemented dashed line\r
11797                  * @return {boolean}\r
11798                  * @private\r
11799                  */\r
11800                 _needsDash: function () {\r
11801                     return this._lineDash;\r
11802                 },\r
11803 \r
11804                 _dashedLineTo: function (x1, y1) {\r
11805                     var dashSum = this._dashSum;\r
11806                     var offset = this._dashOffset;\r
11807                     var lineDash = this._lineDash;\r
11808                     var ctx = this._ctx;\r
11809 \r
11810                     var x0 = this._xi;\r
11811                     var y0 = this._yi;\r
11812                     var dx = x1 - x0;\r
11813                     var dy = y1 - y0;\r
11814                     var dist = mathSqrt(dx * dx + dy * dy);\r
11815                     var x = x0;\r
11816                     var y = y0;\r
11817                     var dash;\r
11818                     var nDash = lineDash.length;\r
11819                     var idx;\r
11820                     dx /= dist;\r
11821                     dy /= dist;\r
11822 \r
11823                     if (offset < 0) {\r
11824                         // Convert to positive offset\r
11825                         offset = dashSum + offset;\r
11826                     }\r
11827                     offset %= dashSum;\r
11828                     x -= offset * dx;\r
11829                     y -= offset * dy;\r
11830 \r
11831                     while ((dx >= 0 && x <= x1) || (dx < 0 && x > x1)) {\r
11832                         idx = this._dashIdx;\r
11833                         dash = lineDash[idx];\r
11834                         x += dx * dash;\r
11835                         y += dy * dash;\r
11836                         this._dashIdx = (idx + 1) % nDash;\r
11837                         // Skip positive offset\r
11838                         if ((dx > 0 && x < x0) || (dx < 0 && x > x0)) {\r
11839                             continue;\r
11840                         }\r
11841                         ctx[idx % 2 ? 'moveTo' : 'lineTo'](\r
11842                             dx >= 0 ? mathMin(x, x1) : mathMax(x, x1),\r
11843                             dy >= 0 ? mathMin(y, y1) : mathMax(y, y1)\r
11844                         );\r
11845                     }\r
11846                     // Offset for next lineTo\r
11847                     dx = x - x1;\r
11848                     dy = y - y1;\r
11849                     this._dashOffset = -mathSqrt(dx * dx + dy * dy);\r
11850                 },\r
11851 \r
11852                 // Not accurate dashed line to\r
11853                 _dashedBezierTo: function (x1, y1, x2, y2, x3, y3) {\r
11854                     var dashSum = this._dashSum;\r
11855                     var offset = this._dashOffset;\r
11856                     var lineDash = this._lineDash;\r
11857                     var ctx = this._ctx;\r
11858 \r
11859                     var x0 = this._xi;\r
11860                     var y0 = this._yi;\r
11861                     var t;\r
11862                     var dx;\r
11863                     var dy;\r
11864                     var cubicAt = curve.cubicAt;\r
11865                     var bezierLen = 0;\r
11866                     var idx = this._dashIdx;\r
11867                     var nDash = lineDash.length;\r
11868 \r
11869                     var x;\r
11870                     var y;\r
11871 \r
11872                     var tmpLen = 0;\r
11873 \r
11874                     if (offset < 0) {\r
11875                         // Convert to positive offset\r
11876                         offset = dashSum + offset;\r
11877                     }\r
11878                     offset %= dashSum;\r
11879                     // Bezier approx length\r
11880                     for (t = 0; t < 1; t += 0.1) {\r
11881                         dx = cubicAt(x0, x1, x2, x3, t + 0.1)\r
11882                             - cubicAt(x0, x1, x2, x3, t);\r
11883                         dy = cubicAt(y0, y1, y2, y3, t + 0.1)\r
11884                             - cubicAt(y0, y1, y2, y3, t);\r
11885                         bezierLen += mathSqrt(dx * dx + dy * dy);\r
11886                     }\r
11887 \r
11888                     // Find idx after add offset\r
11889                     for (; idx < nDash; idx++) {\r
11890                         tmpLen += lineDash[idx];\r
11891                         if (tmpLen > offset) {\r
11892                             break;\r
11893                         }\r
11894                     }\r
11895                     t = (tmpLen - offset) / bezierLen;\r
11896 \r
11897                     while (t <= 1) {\r
11898 \r
11899                         x = cubicAt(x0, x1, x2, x3, t);\r
11900                         y = cubicAt(y0, y1, y2, y3, t);\r
11901 \r
11902                         // Use line to approximate dashed bezier\r
11903                         // Bad result if dash is long\r
11904                         idx % 2 ? ctx.moveTo(x, y)\r
11905                             : ctx.lineTo(x, y);\r
11906 \r
11907                         t += lineDash[idx] / bezierLen;\r
11908 \r
11909                         idx = (idx + 1) % nDash;\r
11910                     }\r
11911 \r
11912                     // Finish the last segment and calculate the new offset\r
11913                     (idx % 2 !== 0) && ctx.lineTo(x3, y3);\r
11914                     dx = x3 - x;\r
11915                     dy = y3 - y;\r
11916                     this._dashOffset = -mathSqrt(dx * dx + dy * dy);\r
11917                 },\r
11918 \r
11919                 _dashedQuadraticTo: function (x1, y1, x2, y2) {\r
11920                     // Convert quadratic to cubic using degree elevation\r
11921                     var x3 = x2;\r
11922                     var y3 = y2;\r
11923                     x2 = (x2 + 2 * x1) / 3;\r
11924                     y2 = (y2 + 2 * y1) / 3;\r
11925                     x1 = (this._xi + 2 * x1) / 3;\r
11926                     y1 = (this._yi + 2 * y1) / 3;\r
11927 \r
11928                     this._dashedBezierTo(x1, y1, x2, y2, x3, y3);\r
11929                 },\r
11930 \r
11931                 /**\r
11932                  * 转成静态的 Float32Array 减少堆内存占用\r
11933                  * Convert dynamic array to static Float32Array\r
11934                  */\r
11935                 toStatic: function () {\r
11936                     var data = this.data;\r
11937                     if (data instanceof Array) {\r
11938                         data.length = this._len;\r
11939                         if (hasTypedArray) {\r
11940                             this.data = new Float32Array(data);\r
11941                         }\r
11942                     }\r
11943                 },\r
11944 \r
11945                 /**\r
11946                  * @return {module:zrender/core/BoundingRect}\r
11947                  */\r
11948                 getBoundingRect: function () {\r
11949                     min[0] = min[1] = min2[0] = min2[1] = Number.MAX_VALUE;\r
11950                     max[0] = max[1] = max2[0] = max2[1] = -Number.MAX_VALUE;\r
11951 \r
11952                     var data = this.data;\r
11953                     var xi = 0;\r
11954                     var yi = 0;\r
11955                     var x0 = 0;\r
11956                     var y0 = 0;\r
11957 \r
11958                     for (var i = 0; i < data.length;) {\r
11959                         var cmd = data[i++];\r
11960 \r
11961                         if (i == 1) {\r
11962                             // 如果第一个命令是 L, C, Q\r
11963                             // 则 previous point 同绘制命令的第一个 point\r
11964                             //\r
11965                             // 第一个命令为 Arc 的情况下会在后面特殊处理\r
11966                             xi = data[i];\r
11967                             yi = data[i + 1];\r
11968 \r
11969                             x0 = xi;\r
11970                             y0 = yi;\r
11971                         }\r
11972 \r
11973                         switch (cmd) {\r
11974                             case CMD.M:\r
11975                                 // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点\r
11976                                 // 在 closePath 的时候使用\r
11977                                 x0 = data[i++];\r
11978                                 y0 = data[i++];\r
11979                                 xi = x0;\r
11980                                 yi = y0;\r
11981                                 min2[0] = x0;\r
11982                                 min2[1] = y0;\r
11983                                 max2[0] = x0;\r
11984                                 max2[1] = y0;\r
11985                                 break;\r
11986                             case CMD.L:\r
11987                                 bbox.fromLine(xi, yi, data[i], data[i + 1], min2, max2);\r
11988                                 xi = data[i++];\r
11989                                 yi = data[i++];\r
11990                                 break;\r
11991                             case CMD.C:\r
11992                                 bbox.fromCubic(\r
11993                                     xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1],\r
11994                                     min2, max2\r
11995                                 );\r
11996                                 xi = data[i++];\r
11997                                 yi = data[i++];\r
11998                                 break;\r
11999                             case CMD.Q:\r
12000                                 bbox.fromQuadratic(\r
12001                                     xi, yi, data[i++], data[i++], data[i], data[i + 1],\r
12002                                     min2, max2\r
12003                                 );\r
12004                                 xi = data[i++];\r
12005                                 yi = data[i++];\r
12006                                 break;\r
12007                             case CMD.A:\r
12008                                 // TODO Arc 判断的开销比较大\r
12009                                 var cx = data[i++];\r
12010                                 var cy = data[i++];\r
12011                                 var rx = data[i++];\r
12012                                 var ry = data[i++];\r
12013                                 var startAngle = data[i++];\r
12014                                 var endAngle = data[i++] + startAngle;\r
12015                                 // TODO Arc 旋转\r
12016                                 var psi = data[i++];\r
12017                                 var anticlockwise = 1 - data[i++];\r
12018 \r
12019                                 if (i == 1) {\r
12020                                     // 直接使用 arc 命令\r
12021                                     // 第一个命令起点还未定义\r
12022                                     x0 = mathCos(startAngle) * rx + cx;\r
12023                                     y0 = mathSin(startAngle) * ry + cy;\r
12024                                 }\r
12025 \r
12026                                 bbox.fromArc(\r
12027                                     cx, cy, rx, ry, startAngle, endAngle,\r
12028                                     anticlockwise, min2, max2\r
12029                                 );\r
12030 \r
12031                                 xi = mathCos(endAngle) * rx + cx;\r
12032                                 yi = mathSin(endAngle) * ry + cy;\r
12033                                 break;\r
12034                             case CMD.R:\r
12035                                 x0 = xi = data[i++];\r
12036                                 y0 = yi = data[i++];\r
12037                                 var width = data[i++];\r
12038                                 var height = data[i++];\r
12039                                 // Use fromLine\r
12040                                 bbox.fromLine(x0, y0, x0 + width, y0 + height, min2, max2);\r
12041                                 break;\r
12042                             case CMD.Z:\r
12043                                 xi = x0;\r
12044                                 yi = y0;\r
12045                                 break;\r
12046                         }\r
12047 \r
12048                         // Union\r
12049                         vec2.min(min, min, min2);\r
12050                         vec2.max(max, max, max2);\r
12051                     }\r
12052 \r
12053                     // No data\r
12054                     if (i === 0) {\r
12055                         min[0] = min[1] = max[0] = max[1] = 0;\r
12056                     }\r
12057 \r
12058                     return new BoundingRect(\r
12059                         min[0], min[1], max[0] - min[0], max[1] - min[1]\r
12060                     );\r
12061                 },\r
12062 \r
12063                 /**\r
12064                  * Rebuild path from current data\r
12065                  * Rebuild path will not consider javascript implemented line dash.\r
12066                  * @param {CanvasRenderingContext} ctx\r
12067                  */\r
12068                 rebuildPath: function (ctx) {\r
12069                     var d = this.data;\r
12070                     for (var i = 0; i < this._len;) {\r
12071                         var cmd = d[i++];\r
12072                         switch (cmd) {\r
12073                             case CMD.M:\r
12074                                 ctx.moveTo(d[i++], d[i++]);\r
12075                                 break;\r
12076                             case CMD.L:\r
12077                                 ctx.lineTo(d[i++], d[i++]);\r
12078                                 break;\r
12079                             case CMD.C:\r
12080                                 ctx.bezierCurveTo(\r
12081                                     d[i++], d[i++], d[i++], d[i++], d[i++], d[i++]\r
12082                                 );\r
12083                                 break;\r
12084                             case CMD.Q:\r
12085                                 ctx.quadraticCurveTo(d[i++], d[i++], d[i++], d[i++]);\r
12086                                 break;\r
12087                             case CMD.A:\r
12088                                 var cx = d[i++];\r
12089                                 var cy = d[i++];\r
12090                                 var rx = d[i++];\r
12091                                 var ry = d[i++];\r
12092                                 var theta = d[i++];\r
12093                                 var dTheta = d[i++];\r
12094                                 var psi = d[i++];\r
12095                                 var fs = d[i++];\r
12096                                 var r = (rx > ry) ? rx : ry;\r
12097                                 var scaleX = (rx > ry) ? 1 : rx / ry;\r
12098                                 var scaleY = (rx > ry) ? ry / rx : 1;\r
12099                                 var isEllipse = Math.abs(rx - ry) > 1e-3;\r
12100                                 if (isEllipse) {\r
12101                                     ctx.translate(cx, cy);\r
12102                                     ctx.rotate(psi);\r
12103                                     ctx.scale(scaleX, scaleY);\r
12104                                     ctx.arc(0, 0, r, theta, theta + dTheta, 1 - fs);\r
12105                                     ctx.scale(1 / scaleX, 1 / scaleY);\r
12106                                     ctx.rotate(-psi);\r
12107                                     ctx.translate(-cx, -cy);\r
12108                                 }\r
12109                                 else {\r
12110                                     ctx.arc(cx, cy, r, theta, theta + dTheta, 1 - fs);\r
12111                                 }\r
12112                                 break;\r
12113                             case CMD.R:\r
12114                                 ctx.rect(d[i++], d[i++], d[i++], d[i++]);\r
12115                                 break;\r
12116                             case CMD.Z:\r
12117                                 ctx.closePath();\r
12118                         }\r
12119                     }\r
12120                 }\r
12121             };\r
12122 \r
12123             PathProxy.CMD = CMD;\r
12124 \r
12125             module.exports = PathProxy;\r
12126 \r
12127 \r
12128 /***/ },\r
12129 /* 49 */\r
12130 /***/ function(module, exports, __webpack_require__) {\r
12131 \r
12132         'use strict';\r
12133         /**\r
12134          * 曲线辅助模块\r
12135          * @module zrender/core/curve\r
12136          * @author pissang(https://www.github.com/pissang)\r
12137          */\r
12138 \r
12139 \r
12140             var vec2 = __webpack_require__(16);\r
12141             var v2Create = vec2.create;\r
12142             var v2DistSquare = vec2.distSquare;\r
12143             var mathPow = Math.pow;\r
12144             var mathSqrt = Math.sqrt;\r
12145 \r
12146             var EPSILON = 1e-8;\r
12147             var EPSILON_NUMERIC = 1e-4;\r
12148 \r
12149             var THREE_SQRT = mathSqrt(3);\r
12150             var ONE_THIRD = 1 / 3;\r
12151 \r
12152             // 临时变量\r
12153             var _v0 = v2Create();\r
12154             var _v1 = v2Create();\r
12155             var _v2 = v2Create();\r
12156             // var _v3 = vec2.create();\r
12157 \r
12158             function isAroundZero(val) {\r
12159                 return val > -EPSILON && val < EPSILON;\r
12160             }\r
12161             function isNotAroundZero(val) {\r
12162                 return val > EPSILON || val < -EPSILON;\r
12163             }\r
12164             /**\r
12165              * 计算三次贝塞尔值\r
12166              * @memberOf module:zrender/core/curve\r
12167              * @param  {number} p0\r
12168              * @param  {number} p1\r
12169              * @param  {number} p2\r
12170              * @param  {number} p3\r
12171              * @param  {number} t\r
12172              * @return {number}\r
12173              */\r
12174             function cubicAt(p0, p1, p2, p3, t) {\r
12175                 var onet = 1 - t;\r
12176                 return onet * onet * (onet * p0 + 3 * t * p1)\r
12177                      + t * t * (t * p3 + 3 * onet * p2);\r
12178             }\r
12179 \r
12180             /**\r
12181              * 计算三次贝塞尔导数值\r
12182              * @memberOf module:zrender/core/curve\r
12183              * @param  {number} p0\r
12184              * @param  {number} p1\r
12185              * @param  {number} p2\r
12186              * @param  {number} p3\r
12187              * @param  {number} t\r
12188              * @return {number}\r
12189              */\r
12190             function cubicDerivativeAt(p0, p1, p2, p3, t) {\r
12191                 var onet = 1 - t;\r
12192                 return 3 * (\r
12193                     ((p1 - p0) * onet + 2 * (p2 - p1) * t) * onet\r
12194                     + (p3 - p2) * t * t\r
12195                 );\r
12196             }\r
12197 \r
12198             /**\r
12199              * 计算三次贝塞尔方程根,使用盛金公式\r
12200              * @memberOf module:zrender/core/curve\r
12201              * @param  {number} p0\r
12202              * @param  {number} p1\r
12203              * @param  {number} p2\r
12204              * @param  {number} p3\r
12205              * @param  {number} val\r
12206              * @param  {Array.<number>} roots\r
12207              * @return {number} 有效根数目\r
12208              */\r
12209             function cubicRootAt(p0, p1, p2, p3, val, roots) {\r
12210                 // Evaluate roots of cubic functions\r
12211                 var a = p3 + 3 * (p1 - p2) - p0;\r
12212                 var b = 3 * (p2 - p1 * 2 + p0);\r
12213                 var c = 3 * (p1  - p0);\r
12214                 var d = p0 - val;\r
12215 \r
12216                 var A = b * b - 3 * a * c;\r
12217                 var B = b * c - 9 * a * d;\r
12218                 var C = c * c - 3 * b * d;\r
12219 \r
12220                 var n = 0;\r
12221 \r
12222                 if (isAroundZero(A) && isAroundZero(B)) {\r
12223                     if (isAroundZero(b)) {\r
12224                         roots[0] = 0;\r
12225                     }\r
12226                     else {\r
12227                         var t1 = -c / b;  //t1, t2, t3, b is not zero\r
12228                         if (t1 >= 0 && t1 <= 1) {\r
12229                             roots[n++] = t1;\r
12230                         }\r
12231                     }\r
12232                 }\r
12233                 else {\r
12234                     var disc = B * B - 4 * A * C;\r
12235 \r
12236                     if (isAroundZero(disc)) {\r
12237                         var K = B / A;\r
12238                         var t1 = -b / a + K;  // t1, a is not zero\r
12239                         var t2 = -K / 2;  // t2, t3\r
12240                         if (t1 >= 0 && t1 <= 1) {\r
12241                             roots[n++] = t1;\r
12242                         }\r
12243                         if (t2 >= 0 && t2 <= 1) {\r
12244                             roots[n++] = t2;\r
12245                         }\r
12246                     }\r
12247                     else if (disc > 0) {\r
12248                         var discSqrt = mathSqrt(disc);\r
12249                         var Y1 = A * b + 1.5 * a * (-B + discSqrt);\r
12250                         var Y2 = A * b + 1.5 * a * (-B - discSqrt);\r
12251                         if (Y1 < 0) {\r
12252                             Y1 = -mathPow(-Y1, ONE_THIRD);\r
12253                         }\r
12254                         else {\r
12255                             Y1 = mathPow(Y1, ONE_THIRD);\r
12256                         }\r
12257                         if (Y2 < 0) {\r
12258                             Y2 = -mathPow(-Y2, ONE_THIRD);\r
12259                         }\r
12260                         else {\r
12261                             Y2 = mathPow(Y2, ONE_THIRD);\r
12262                         }\r
12263                         var t1 = (-b - (Y1 + Y2)) / (3 * a);\r
12264                         if (t1 >= 0 && t1 <= 1) {\r
12265                             roots[n++] = t1;\r
12266                         }\r
12267                     }\r
12268                     else {\r
12269                         var T = (2 * A * b - 3 * a * B) / (2 * mathSqrt(A * A * A));\r
12270                         var theta = Math.acos(T) / 3;\r
12271                         var ASqrt = mathSqrt(A);\r
12272                         var tmp = Math.cos(theta);\r
12273 \r
12274                         var t1 = (-b - 2 * ASqrt * tmp) / (3 * a);\r
12275                         var t2 = (-b + ASqrt * (tmp + THREE_SQRT * Math.sin(theta))) / (3 * a);\r
12276                         var t3 = (-b + ASqrt * (tmp - THREE_SQRT * Math.sin(theta))) / (3 * a);\r
12277                         if (t1 >= 0 && t1 <= 1) {\r
12278                             roots[n++] = t1;\r
12279                         }\r
12280                         if (t2 >= 0 && t2 <= 1) {\r
12281                             roots[n++] = t2;\r
12282                         }\r
12283                         if (t3 >= 0 && t3 <= 1) {\r
12284                             roots[n++] = t3;\r
12285                         }\r
12286                     }\r
12287                 }\r
12288                 return n;\r
12289             }\r
12290 \r
12291             /**\r
12292              * 计算三次贝塞尔方程极限值的位置\r
12293              * @memberOf module:zrender/core/curve\r
12294              * @param  {number} p0\r
12295              * @param  {number} p1\r
12296              * @param  {number} p2\r
12297              * @param  {number} p3\r
12298              * @param  {Array.<number>} extrema\r
12299              * @return {number} 有效数目\r
12300              */\r
12301             function cubicExtrema(p0, p1, p2, p3, extrema) {\r
12302                 var b = 6 * p2 - 12 * p1 + 6 * p0;\r
12303                 var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2;\r
12304                 var c = 3 * p1 - 3 * p0;\r
12305 \r
12306                 var n = 0;\r
12307                 if (isAroundZero(a)) {\r
12308                     if (isNotAroundZero(b)) {\r
12309                         var t1 = -c / b;\r
12310                         if (t1 >= 0 && t1 <=1) {\r
12311                             extrema[n++] = t1;\r
12312                         }\r
12313                     }\r
12314                 }\r
12315                 else {\r
12316                     var disc = b * b - 4 * a * c;\r
12317                     if (isAroundZero(disc)) {\r
12318                         extrema[0] = -b / (2 * a);\r
12319                     }\r
12320                     else if (disc > 0) {\r
12321                         var discSqrt = mathSqrt(disc);\r
12322                         var t1 = (-b + discSqrt) / (2 * a);\r
12323                         var t2 = (-b - discSqrt) / (2 * a);\r
12324                         if (t1 >= 0 && t1 <= 1) {\r
12325                             extrema[n++] = t1;\r
12326                         }\r
12327                         if (t2 >= 0 && t2 <= 1) {\r
12328                             extrema[n++] = t2;\r
12329                         }\r
12330                     }\r
12331                 }\r
12332                 return n;\r
12333             }\r
12334 \r
12335             /**\r
12336              * 细分三次贝塞尔曲线\r
12337              * @memberOf module:zrender/core/curve\r
12338              * @param  {number} p0\r
12339              * @param  {number} p1\r
12340              * @param  {number} p2\r
12341              * @param  {number} p3\r
12342              * @param  {number} t\r
12343              * @param  {Array.<number>} out\r
12344              */\r
12345             function cubicSubdivide(p0, p1, p2, p3, t, out) {\r
12346                 var p01 = (p1 - p0) * t + p0;\r
12347                 var p12 = (p2 - p1) * t + p1;\r
12348                 var p23 = (p3 - p2) * t + p2;\r
12349 \r
12350                 var p012 = (p12 - p01) * t + p01;\r
12351                 var p123 = (p23 - p12) * t + p12;\r
12352 \r
12353                 var p0123 = (p123 - p012) * t + p012;\r
12354                 // Seg0\r
12355                 out[0] = p0;\r
12356                 out[1] = p01;\r
12357                 out[2] = p012;\r
12358                 out[3] = p0123;\r
12359                 // Seg1\r
12360                 out[4] = p0123;\r
12361                 out[5] = p123;\r
12362                 out[6] = p23;\r
12363                 out[7] = p3;\r
12364             }\r
12365 \r
12366             /**\r
12367              * 投射点到三次贝塞尔曲线上,返回投射距离。\r
12368              * 投射点有可能会有一个或者多个,这里只返回其中距离最短的一个。\r
12369              * @param {number} x0\r
12370              * @param {number} y0\r
12371              * @param {number} x1\r
12372              * @param {number} y1\r
12373              * @param {number} x2\r
12374              * @param {number} y2\r
12375              * @param {number} x3\r
12376              * @param {number} y3\r
12377              * @param {number} x\r
12378              * @param {number} y\r
12379              * @param {Array.<number>} [out] 投射点\r
12380              * @return {number}\r
12381              */\r
12382             function cubicProjectPoint(\r
12383                 x0, y0, x1, y1, x2, y2, x3, y3,\r
12384                 x, y, out\r
12385             ) {\r
12386                 // http://pomax.github.io/bezierinfo/#projections\r
12387                 var t;\r
12388                 var interval = 0.005;\r
12389                 var d = Infinity;\r
12390                 var prev;\r
12391                 var next;\r
12392                 var d1;\r
12393                 var d2;\r
12394 \r
12395                 _v0[0] = x;\r
12396                 _v0[1] = y;\r
12397 \r
12398                 // 先粗略估计一下可能的最小距离的 t 值\r
12399                 // PENDING\r
12400                 for (var _t = 0; _t < 1; _t += 0.05) {\r
12401                     _v1[0] = cubicAt(x0, x1, x2, x3, _t);\r
12402                     _v1[1] = cubicAt(y0, y1, y2, y3, _t);\r
12403                     d1 = v2DistSquare(_v0, _v1);\r
12404                     if (d1 < d) {\r
12405                         t = _t;\r
12406                         d = d1;\r
12407                     }\r
12408                 }\r
12409                 d = Infinity;\r
12410 \r
12411                 // At most 32 iteration\r
12412                 for (var i = 0; i < 32; i++) {\r
12413                     if (interval < EPSILON_NUMERIC) {\r
12414                         break;\r
12415                     }\r
12416                     prev = t - interval;\r
12417                     next = t + interval;\r
12418                     // t - interval\r
12419                     _v1[0] = cubicAt(x0, x1, x2, x3, prev);\r
12420                     _v1[1] = cubicAt(y0, y1, y2, y3, prev);\r
12421 \r
12422                     d1 = v2DistSquare(_v1, _v0);\r
12423 \r
12424                     if (prev >= 0 && d1 < d) {\r
12425                         t = prev;\r
12426                         d = d1;\r
12427                     }\r
12428                     else {\r
12429                         // t + interval\r
12430                         _v2[0] = cubicAt(x0, x1, x2, x3, next);\r
12431                         _v2[1] = cubicAt(y0, y1, y2, y3, next);\r
12432                         d2 = v2DistSquare(_v2, _v0);\r
12433 \r
12434                         if (next <= 1 && d2 < d) {\r
12435                             t = next;\r
12436                             d = d2;\r
12437                         }\r
12438                         else {\r
12439                             interval *= 0.5;\r
12440                         }\r
12441                     }\r
12442                 }\r
12443                 // t\r
12444                 if (out) {\r
12445                     out[0] = cubicAt(x0, x1, x2, x3, t);\r
12446                     out[1] = cubicAt(y0, y1, y2, y3, t);\r
12447                 }\r
12448                 // console.log(interval, i);\r
12449                 return mathSqrt(d);\r
12450             }\r
12451 \r
12452             /**\r
12453              * 计算二次方贝塞尔值\r
12454              * @param  {number} p0\r
12455              * @param  {number} p1\r
12456              * @param  {number} p2\r
12457              * @param  {number} t\r
12458              * @return {number}\r
12459              */\r
12460             function quadraticAt(p0, p1, p2, t) {\r
12461                 var onet = 1 - t;\r
12462                 return onet * (onet * p0 + 2 * t * p1) + t * t * p2;\r
12463             }\r
12464 \r
12465             /**\r
12466              * 计算二次方贝塞尔导数值\r
12467              * @param  {number} p0\r
12468              * @param  {number} p1\r
12469              * @param  {number} p2\r
12470              * @param  {number} t\r
12471              * @return {number}\r
12472              */\r
12473             function quadraticDerivativeAt(p0, p1, p2, t) {\r
12474                 return 2 * ((1 - t) * (p1 - p0) + t * (p2 - p1));\r
12475             }\r
12476 \r
12477             /**\r
12478              * 计算二次方贝塞尔方程根\r
12479              * @param  {number} p0\r
12480              * @param  {number} p1\r
12481              * @param  {number} p2\r
12482              * @param  {number} t\r
12483              * @param  {Array.<number>} roots\r
12484              * @return {number} 有效根数目\r
12485              */\r
12486             function quadraticRootAt(p0, p1, p2, val, roots) {\r
12487                 var a = p0 - 2 * p1 + p2;\r
12488                 var b = 2 * (p1 - p0);\r
12489                 var c = p0 - val;\r
12490 \r
12491                 var n = 0;\r
12492                 if (isAroundZero(a)) {\r
12493                     if (isNotAroundZero(b)) {\r
12494                         var t1 = -c / b;\r
12495                         if (t1 >= 0 && t1 <= 1) {\r
12496                             roots[n++] = t1;\r
12497                         }\r
12498                     }\r
12499                 }\r
12500                 else {\r
12501                     var disc = b * b - 4 * a * c;\r
12502                     if (isAroundZero(disc)) {\r
12503                         var t1 = -b / (2 * a);\r
12504                         if (t1 >= 0 && t1 <= 1) {\r
12505                             roots[n++] = t1;\r
12506                         }\r
12507                     }\r
12508                     else if (disc > 0) {\r
12509                         var discSqrt = mathSqrt(disc);\r
12510                         var t1 = (-b + discSqrt) / (2 * a);\r
12511                         var t2 = (-b - discSqrt) / (2 * a);\r
12512                         if (t1 >= 0 && t1 <= 1) {\r
12513                             roots[n++] = t1;\r
12514                         }\r
12515                         if (t2 >= 0 && t2 <= 1) {\r
12516                             roots[n++] = t2;\r
12517                         }\r
12518                     }\r
12519                 }\r
12520                 return n;\r
12521             }\r
12522 \r
12523             /**\r
12524              * 计算二次贝塞尔方程极限值\r
12525              * @memberOf module:zrender/core/curve\r
12526              * @param  {number} p0\r
12527              * @param  {number} p1\r
12528              * @param  {number} p2\r
12529              * @return {number}\r
12530              */\r
12531             function quadraticExtremum(p0, p1, p2) {\r
12532                 var divider = p0 + p2 - 2 * p1;\r
12533                 if (divider === 0) {\r
12534                     // p1 is center of p0 and p2\r
12535                     return 0.5;\r
12536                 }\r
12537                 else {\r
12538                     return (p0 - p1) / divider;\r
12539                 }\r
12540             }\r
12541 \r
12542             /**\r
12543              * 细分二次贝塞尔曲线\r
12544              * @memberOf module:zrender/core/curve\r
12545              * @param  {number} p0\r
12546              * @param  {number} p1\r
12547              * @param  {number} p2\r
12548              * @param  {number} t\r
12549              * @param  {Array.<number>} out\r
12550              */\r
12551             function quadraticSubdivide(p0, p1, p2, t, out) {\r
12552                 var p01 = (p1 - p0) * t + p0;\r
12553                 var p12 = (p2 - p1) * t + p1;\r
12554                 var p012 = (p12 - p01) * t + p01;\r
12555 \r
12556                 // Seg0\r
12557                 out[0] = p0;\r
12558                 out[1] = p01;\r
12559                 out[2] = p012;\r
12560 \r
12561                 // Seg1\r
12562                 out[3] = p012;\r
12563                 out[4] = p12;\r
12564                 out[5] = p2;\r
12565             }\r
12566 \r
12567             /**\r
12568              * 投射点到二次贝塞尔曲线上,返回投射距离。\r
12569              * 投射点有可能会有一个或者多个,这里只返回其中距离最短的一个。\r
12570              * @param {number} x0\r
12571              * @param {number} y0\r
12572              * @param {number} x1\r
12573              * @param {number} y1\r
12574              * @param {number} x2\r
12575              * @param {number} y2\r
12576              * @param {number} x\r
12577              * @param {number} y\r
12578              * @param {Array.<number>} out 投射点\r
12579              * @return {number}\r
12580              */\r
12581             function quadraticProjectPoint(\r
12582                 x0, y0, x1, y1, x2, y2,\r
12583                 x, y, out\r
12584             ) {\r
12585                 // http://pomax.github.io/bezierinfo/#projections\r
12586                 var t;\r
12587                 var interval = 0.005;\r
12588                 var d = Infinity;\r
12589 \r
12590                 _v0[0] = x;\r
12591                 _v0[1] = y;\r
12592 \r
12593                 // 先粗略估计一下可能的最小距离的 t 值\r
12594                 // PENDING\r
12595                 for (var _t = 0; _t < 1; _t += 0.05) {\r
12596                     _v1[0] = quadraticAt(x0, x1, x2, _t);\r
12597                     _v1[1] = quadraticAt(y0, y1, y2, _t);\r
12598                     var d1 = v2DistSquare(_v0, _v1);\r
12599                     if (d1 < d) {\r
12600                         t = _t;\r
12601                         d = d1;\r
12602                     }\r
12603                 }\r
12604                 d = Infinity;\r
12605 \r
12606                 // At most 32 iteration\r
12607                 for (var i = 0; i < 32; i++) {\r
12608                     if (interval < EPSILON_NUMERIC) {\r
12609                         break;\r
12610                     }\r
12611                     var prev = t - interval;\r
12612                     var next = t + interval;\r
12613                     // t - interval\r
12614                     _v1[0] = quadraticAt(x0, x1, x2, prev);\r
12615                     _v1[1] = quadraticAt(y0, y1, y2, prev);\r
12616 \r
12617                     var d1 = v2DistSquare(_v1, _v0);\r
12618 \r
12619                     if (prev >= 0 && d1 < d) {\r
12620                         t = prev;\r
12621                         d = d1;\r
12622                     }\r
12623                     else {\r
12624                         // t + interval\r
12625                         _v2[0] = quadraticAt(x0, x1, x2, next);\r
12626                         _v2[1] = quadraticAt(y0, y1, y2, next);\r
12627                         var d2 = v2DistSquare(_v2, _v0);\r
12628                         if (next <= 1 && d2 < d) {\r
12629                             t = next;\r
12630                             d = d2;\r
12631                         }\r
12632                         else {\r
12633                             interval *= 0.5;\r
12634                         }\r
12635                     }\r
12636                 }\r
12637                 // t\r
12638                 if (out) {\r
12639                     out[0] = quadraticAt(x0, x1, x2, t);\r
12640                     out[1] = quadraticAt(y0, y1, y2, t);\r
12641                 }\r
12642                 // console.log(interval, i);\r
12643                 return mathSqrt(d);\r
12644             }\r
12645 \r
12646             module.exports = {\r
12647 \r
12648                 cubicAt: cubicAt,\r
12649 \r
12650                 cubicDerivativeAt: cubicDerivativeAt,\r
12651 \r
12652                 cubicRootAt: cubicRootAt,\r
12653 \r
12654                 cubicExtrema: cubicExtrema,\r
12655 \r
12656                 cubicSubdivide: cubicSubdivide,\r
12657 \r
12658                 cubicProjectPoint: cubicProjectPoint,\r
12659 \r
12660                 quadraticAt: quadraticAt,\r
12661 \r
12662                 quadraticDerivativeAt: quadraticDerivativeAt,\r
12663 \r
12664                 quadraticRootAt: quadraticRootAt,\r
12665 \r
12666                 quadraticExtremum: quadraticExtremum,\r
12667 \r
12668                 quadraticSubdivide: quadraticSubdivide,\r
12669 \r
12670                 quadraticProjectPoint: quadraticProjectPoint\r
12671             };\r
12672 \r
12673 \r
12674 /***/ },\r
12675 /* 50 */\r
12676 /***/ function(module, exports, __webpack_require__) {\r
12677 \r
12678         /**\r
12679          * @author Yi Shen(https://github.com/pissang)\r
12680          */\r
12681 \r
12682 \r
12683             var vec2 = __webpack_require__(16);\r
12684             var curve = __webpack_require__(49);\r
12685 \r
12686             var bbox = {};\r
12687             var mathMin = Math.min;\r
12688             var mathMax = Math.max;\r
12689             var mathSin = Math.sin;\r
12690             var mathCos = Math.cos;\r
12691 \r
12692             var start = vec2.create();\r
12693             var end = vec2.create();\r
12694             var extremity = vec2.create();\r
12695 \r
12696             var PI2 = Math.PI * 2;\r
12697             /**\r
12698              * 从顶点数组中计算出最小包围盒,写入`min`和`max`中\r
12699              * @module zrender/core/bbox\r
12700              * @param {Array<Object>} points 顶点数组\r
12701              * @param {number} min\r
12702              * @param {number} max\r
12703              */\r
12704             bbox.fromPoints = function(points, min, max) {\r
12705                 if (points.length === 0) {\r
12706                     return;\r
12707                 }\r
12708                 var p = points[0];\r
12709                 var left = p[0];\r
12710                 var right = p[0];\r
12711                 var top = p[1];\r
12712                 var bottom = p[1];\r
12713                 var i;\r
12714 \r
12715                 for (i = 1; i < points.length; i++) {\r
12716                     p = points[i];\r
12717                     left = mathMin(left, p[0]);\r
12718                     right = mathMax(right, p[0]);\r
12719                     top = mathMin(top, p[1]);\r
12720                     bottom = mathMax(bottom, p[1]);\r
12721                 }\r
12722 \r
12723                 min[0] = left;\r
12724                 min[1] = top;\r
12725                 max[0] = right;\r
12726                 max[1] = bottom;\r
12727             };\r
12728 \r
12729             /**\r
12730              * @memberOf module:zrender/core/bbox\r
12731              * @param {number} x0\r
12732              * @param {number} y0\r
12733              * @param {number} x1\r
12734              * @param {number} y1\r
12735              * @param {Array.<number>} min\r
12736              * @param {Array.<number>} max\r
12737              */\r
12738             bbox.fromLine = function (x0, y0, x1, y1, min, max) {\r
12739                 min[0] = mathMin(x0, x1);\r
12740                 min[1] = mathMin(y0, y1);\r
12741                 max[0] = mathMax(x0, x1);\r
12742                 max[1] = mathMax(y0, y1);\r
12743             };\r
12744 \r
12745             var xDim = [];\r
12746             var yDim = [];\r
12747             /**\r
12748              * 从三阶贝塞尔曲线(p0, p1, p2, p3)中计算出最小包围盒,写入`min`和`max`中\r
12749              * @memberOf module:zrender/core/bbox\r
12750              * @param {number} x0\r
12751              * @param {number} y0\r
12752              * @param {number} x1\r
12753              * @param {number} y1\r
12754              * @param {number} x2\r
12755              * @param {number} y2\r
12756              * @param {number} x3\r
12757              * @param {number} y3\r
12758              * @param {Array.<number>} min\r
12759              * @param {Array.<number>} max\r
12760              */\r
12761             bbox.fromCubic = function(\r
12762                 x0, y0, x1, y1, x2, y2, x3, y3, min, max\r
12763             ) {\r
12764                 var cubicExtrema = curve.cubicExtrema;\r
12765                 var cubicAt = curve.cubicAt;\r
12766                 var i;\r
12767                 var n = cubicExtrema(x0, x1, x2, x3, xDim);\r
12768                 min[0] = Infinity;\r
12769                 min[1] = Infinity;\r
12770                 max[0] = -Infinity;\r
12771                 max[1] = -Infinity;\r
12772 \r
12773                 for (i = 0; i < n; i++) {\r
12774                     var x = cubicAt(x0, x1, x2, x3, xDim[i]);\r
12775                     min[0] = mathMin(x, min[0]);\r
12776                     max[0] = mathMax(x, max[0]);\r
12777                 }\r
12778                 n = cubicExtrema(y0, y1, y2, y3, yDim);\r
12779                 for (i = 0; i < n; i++) {\r
12780                     var y = cubicAt(y0, y1, y2, y3, yDim[i]);\r
12781                     min[1] = mathMin(y, min[1]);\r
12782                     max[1] = mathMax(y, max[1]);\r
12783                 }\r
12784 \r
12785                 min[0] = mathMin(x0, min[0]);\r
12786                 max[0] = mathMax(x0, max[0]);\r
12787                 min[0] = mathMin(x3, min[0]);\r
12788                 max[0] = mathMax(x3, max[0]);\r
12789 \r
12790                 min[1] = mathMin(y0, min[1]);\r
12791                 max[1] = mathMax(y0, max[1]);\r
12792                 min[1] = mathMin(y3, min[1]);\r
12793                 max[1] = mathMax(y3, max[1]);\r
12794             };\r
12795 \r
12796             /**\r
12797              * 从二阶贝塞尔曲线(p0, p1, p2)中计算出最小包围盒,写入`min`和`max`中\r
12798              * @memberOf module:zrender/core/bbox\r
12799              * @param {number} x0\r
12800              * @param {number} y0\r
12801              * @param {number} x1\r
12802              * @param {number} y1\r
12803              * @param {number} x2\r
12804              * @param {number} y2\r
12805              * @param {Array.<number>} min\r
12806              * @param {Array.<number>} max\r
12807              */\r
12808             bbox.fromQuadratic = function(x0, y0, x1, y1, x2, y2, min, max) {\r
12809                 var quadraticExtremum = curve.quadraticExtremum;\r
12810                 var quadraticAt = curve.quadraticAt;\r
12811                 // Find extremities, where derivative in x dim or y dim is zero\r
12812                 var tx =\r
12813                     mathMax(\r
12814                         mathMin(quadraticExtremum(x0, x1, x2), 1), 0\r
12815                     );\r
12816                 var ty =\r
12817                     mathMax(\r
12818                         mathMin(quadraticExtremum(y0, y1, y2), 1), 0\r
12819                     );\r
12820 \r
12821                 var x = quadraticAt(x0, x1, x2, tx);\r
12822                 var y = quadraticAt(y0, y1, y2, ty);\r
12823 \r
12824                 min[0] = mathMin(x0, x2, x);\r
12825                 min[1] = mathMin(y0, y2, y);\r
12826                 max[0] = mathMax(x0, x2, x);\r
12827                 max[1] = mathMax(y0, y2, y);\r
12828             };\r
12829 \r
12830             /**\r
12831              * 从圆弧中计算出最小包围盒,写入`min`和`max`中\r
12832              * @method\r
12833              * @memberOf module:zrender/core/bbox\r
12834              * @param {number} x\r
12835              * @param {number} y\r
12836              * @param {number} rx\r
12837              * @param {number} ry\r
12838              * @param {number} startAngle\r
12839              * @param {number} endAngle\r
12840              * @param {number} anticlockwise\r
12841              * @param {Array.<number>} min\r
12842              * @param {Array.<number>} max\r
12843              */\r
12844             bbox.fromArc = function (\r
12845                 x, y, rx, ry, startAngle, endAngle, anticlockwise, min, max\r
12846             ) {\r
12847                 var vec2Min = vec2.min;\r
12848                 var vec2Max = vec2.max;\r
12849 \r
12850                 var diff = Math.abs(startAngle - endAngle);\r
12851 \r
12852 \r
12853                 if (diff % PI2 < 1e-4 && diff > 1e-4) {\r
12854                     // Is a circle\r
12855                     min[0] = x - rx;\r
12856                     min[1] = y - ry;\r
12857                     max[0] = x + rx;\r
12858                     max[1] = y + ry;\r
12859                     return;\r
12860                 }\r
12861 \r
12862                 start[0] = mathCos(startAngle) * rx + x;\r
12863                 start[1] = mathSin(startAngle) * ry + y;\r
12864 \r
12865                 end[0] = mathCos(endAngle) * rx + x;\r
12866                 end[1] = mathSin(endAngle) * ry + y;\r
12867 \r
12868                 vec2Min(min, start, end);\r
12869                 vec2Max(max, start, end);\r
12870 \r
12871                 // Thresh to [0, Math.PI * 2]\r
12872                 startAngle = startAngle % (PI2);\r
12873                 if (startAngle < 0) {\r
12874                     startAngle = startAngle + PI2;\r
12875                 }\r
12876                 endAngle = endAngle % (PI2);\r
12877                 if (endAngle < 0) {\r
12878                     endAngle = endAngle + PI2;\r
12879                 }\r
12880 \r
12881                 if (startAngle > endAngle && !anticlockwise) {\r
12882                     endAngle += PI2;\r
12883                 }\r
12884                 else if (startAngle < endAngle && anticlockwise) {\r
12885                     startAngle += PI2;\r
12886                 }\r
12887                 if (anticlockwise) {\r
12888                     var tmp = endAngle;\r
12889                     endAngle = startAngle;\r
12890                     startAngle = tmp;\r
12891                 }\r
12892 \r
12893                 // var number = 0;\r
12894                 // var step = (anticlockwise ? -Math.PI : Math.PI) / 2;\r
12895                 for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {\r
12896                     if (angle > startAngle) {\r
12897                         extremity[0] = mathCos(angle) * rx + x;\r
12898                         extremity[1] = mathSin(angle) * ry + y;\r
12899 \r
12900                         vec2Min(min, extremity, min);\r
12901                         vec2Max(max, extremity, max);\r
12902                     }\r
12903                 }\r
12904             };\r
12905 \r
12906             module.exports = bbox;\r
12907 \r
12908 \r
12909 \r
12910 /***/ },\r
12911 /* 51 */\r
12912 /***/ function(module, exports, __webpack_require__) {\r
12913 \r
12914         'use strict';\r
12915 \r
12916 \r
12917             var CMD = __webpack_require__(48).CMD;\r
12918             var line = __webpack_require__(52);\r
12919             var cubic = __webpack_require__(53);\r
12920             var quadratic = __webpack_require__(54);\r
12921             var arc = __webpack_require__(55);\r
12922             var normalizeRadian = __webpack_require__(56).normalizeRadian;\r
12923             var curve = __webpack_require__(49);\r
12924 \r
12925             var windingLine = __webpack_require__(57);\r
12926 \r
12927             var containStroke = line.containStroke;\r
12928 \r
12929             var PI2 = Math.PI * 2;\r
12930 \r
12931             var EPSILON = 1e-4;\r
12932 \r
12933             function isAroundEqual(a, b) {\r
12934                 return Math.abs(a - b) < EPSILON;\r
12935             }\r
12936 \r
12937             // 临时数组\r
12938             var roots = [-1, -1, -1];\r
12939             var extrema = [-1, -1];\r
12940 \r
12941             function swapExtrema() {\r
12942                 var tmp = extrema[0];\r
12943                 extrema[0] = extrema[1];\r
12944                 extrema[1] = tmp;\r
12945             }\r
12946 \r
12947             function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) {\r
12948                 // Quick reject\r
12949                 if (\r
12950                     (y > y0 && y > y1 && y > y2 && y > y3)\r
12951                     || (y < y0 && y < y1 && y < y2 && y < y3)\r
12952                 ) {\r
12953                     return 0;\r
12954                 }\r
12955                 var nRoots = curve.cubicRootAt(y0, y1, y2, y3, y, roots);\r
12956                 if (nRoots === 0) {\r
12957                     return 0;\r
12958                 }\r
12959                 else {\r
12960                     var w = 0;\r
12961                     var nExtrema = -1;\r
12962                     var y0_, y1_;\r
12963                     for (var i = 0; i < nRoots; i++) {\r
12964                         var t = roots[i];\r
12965                         var x_ = curve.cubicAt(x0, x1, x2, x3, t);\r
12966                         if (x_ < x) { // Quick reject\r
12967                             continue;\r
12968                         }\r
12969                         if (nExtrema < 0) {\r
12970                             nExtrema = curve.cubicExtrema(y0, y1, y2, y3, extrema);\r
12971                             if (extrema[1] < extrema[0] && nExtrema > 1) {\r
12972                                 swapExtrema();\r
12973                             }\r
12974                             y0_ = curve.cubicAt(y0, y1, y2, y3, extrema[0]);\r
12975                             if (nExtrema > 1) {\r
12976                                 y1_ = curve.cubicAt(y0, y1, y2, y3, extrema[1]);\r
12977                             }\r
12978                         }\r
12979                         if (nExtrema == 2) {\r
12980                             // 分成三段单调函数\r
12981                             if (t < extrema[0]) {\r
12982                                 w += y0_ < y0 ? 1 : -1;\r
12983                             }\r
12984                             else if (t < extrema[1]) {\r
12985                                 w += y1_ < y0_ ? 1 : -1;\r
12986                             }\r
12987                             else {\r
12988                                 w += y3 < y1_ ? 1 : -1;\r
12989                             }\r
12990                         }\r
12991                         else {\r
12992                             // 分成两段单调函数\r
12993                             if (t < extrema[0]) {\r
12994                                 w += y0_ < y0 ? 1 : -1;\r
12995                             }\r
12996                             else {\r
12997                                 w += y3 < y0_ ? 1 : -1;\r
12998                             }\r
12999                         }\r
13000                     }\r
13001                     return w;\r
13002                 }\r
13003             }\r
13004 \r
13005             function windingQuadratic(x0, y0, x1, y1, x2, y2, x, y) {\r
13006                 // Quick reject\r
13007                 if (\r
13008                     (y > y0 && y > y1 && y > y2)\r
13009                     || (y < y0 && y < y1 && y < y2)\r
13010                 ) {\r
13011                     return 0;\r
13012                 }\r
13013                 var nRoots = curve.quadraticRootAt(y0, y1, y2, y, roots);\r
13014                 if (nRoots === 0) {\r
13015                     return 0;\r
13016                 }\r
13017                 else {\r
13018                     var t = curve.quadraticExtremum(y0, y1, y2);\r
13019                     if (t >= 0 && t <= 1) {\r
13020                         var w = 0;\r
13021                         var y_ = curve.quadraticAt(y0, y1, y2, t);\r
13022                         for (var i = 0; i < nRoots; i++) {\r
13023                             var x_ = curve.quadraticAt(x0, x1, x2, roots[i]);\r
13024                             if (x_ < x) {   // Quick reject\r
13025                                 continue;\r
13026                             }\r
13027                             if (roots[i] < t) {\r
13028                                 w += y_ < y0 ? 1 : -1;\r
13029                             }\r
13030                             else {\r
13031                                 w += y2 < y_ ? 1 : -1;\r
13032                             }\r
13033                         }\r
13034                         return w;\r
13035                     }\r
13036                     else {\r
13037                         var x_ = curve.quadraticAt(x0, x1, x2, roots[0]);\r
13038                         if (x_ < x) {   // Quick reject\r
13039                             return 0;\r
13040                         }\r
13041                         return y2 < y0 ? 1 : -1;\r
13042                     }\r
13043                 }\r
13044             }\r
13045 \r
13046             // TODO\r
13047             // Arc 旋转\r
13048             function windingArc(\r
13049                 cx, cy, r, startAngle, endAngle, anticlockwise, x, y\r
13050             ) {\r
13051                 y -= cy;\r
13052                 if (y > r || y < -r) {\r
13053                     return 0;\r
13054                 }\r
13055                 var tmp = Math.sqrt(r * r - y * y);\r
13056                 roots[0] = -tmp;\r
13057                 roots[1] = tmp;\r
13058 \r
13059                 var diff = Math.abs(startAngle - endAngle);\r
13060                 if (diff < 1e-4) {\r
13061                     return 0;\r
13062                 }\r
13063                 if (diff % PI2 < 1e-4) {\r
13064                     // Is a circle\r
13065                     startAngle = 0;\r
13066                     endAngle = PI2;\r
13067                     var dir = anticlockwise ? 1 : -1;\r
13068                     if (x >= roots[0] + cx && x <= roots[1] + cx) {\r
13069                         return dir;\r
13070                     } else {\r
13071                         return 0;\r
13072                     }\r
13073                 }\r
13074 \r
13075                 if (anticlockwise) {\r
13076                     var tmp = startAngle;\r
13077                     startAngle = normalizeRadian(endAngle);\r
13078                     endAngle = normalizeRadian(tmp);\r
13079                 }\r
13080                 else {\r
13081                     startAngle = normalizeRadian(startAngle);\r
13082                     endAngle = normalizeRadian(endAngle);\r
13083                 }\r
13084                 if (startAngle > endAngle) {\r
13085                     endAngle += PI2;\r
13086                 }\r
13087 \r
13088                 var w = 0;\r
13089                 for (var i = 0; i < 2; i++) {\r
13090                     var x_ = roots[i];\r
13091                     if (x_ + cx > x) {\r
13092                         var angle = Math.atan2(y, x_);\r
13093                         var dir = anticlockwise ? 1 : -1;\r
13094                         if (angle < 0) {\r
13095                             angle = PI2 + angle;\r
13096                         }\r
13097                         if (\r
13098                             (angle >= startAngle && angle <= endAngle)\r
13099                             || (angle + PI2 >= startAngle && angle + PI2 <= endAngle)\r
13100                         ) {\r
13101                             if (angle > Math.PI / 2 && angle < Math.PI * 1.5) {\r
13102                                 dir = -dir;\r
13103                             }\r
13104                             w += dir;\r
13105                         }\r
13106                     }\r
13107                 }\r
13108                 return w;\r
13109             }\r
13110 \r
13111             function containPath(data, lineWidth, isStroke, x, y) {\r
13112                 var w = 0;\r
13113                 var xi = 0;\r
13114                 var yi = 0;\r
13115                 var x0 = 0;\r
13116                 var y0 = 0;\r
13117 \r
13118                 for (var i = 0; i < data.length;) {\r
13119                     var cmd = data[i++];\r
13120                     // Begin a new subpath\r
13121                     if (cmd === CMD.M && i > 1) {\r
13122                         // Close previous subpath\r
13123                         if (!isStroke) {\r
13124                             w += windingLine(xi, yi, x0, y0, x, y);\r
13125                         }\r
13126                         // 如果被任何一个 subpath 包含\r
13127                         if (w !== 0) {\r
13128                             return true;\r
13129                         }\r
13130                     }\r
13131 \r
13132                     if (i == 1) {\r
13133                         // 如果第一个命令是 L, C, Q\r
13134                         // 则 previous point 同绘制命令的第一个 point\r
13135                         //\r
13136                         // 第一个命令为 Arc 的情况下会在后面特殊处理\r
13137                         xi = data[i];\r
13138                         yi = data[i + 1];\r
13139 \r
13140                         x0 = xi;\r
13141                         y0 = yi;\r
13142                     }\r
13143 \r
13144                     switch (cmd) {\r
13145                         case CMD.M:\r
13146                             // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点\r
13147                             // 在 closePath 的时候使用\r
13148                             x0 = data[i++];\r
13149                             y0 = data[i++];\r
13150                             xi = x0;\r
13151                             yi = y0;\r
13152                             break;\r
13153                         case CMD.L:\r
13154                             if (isStroke) {\r
13155                                 if (containStroke(xi, yi, data[i], data[i + 1], lineWidth, x, y)) {\r
13156                                     return true;\r
13157                                 }\r
13158                             }\r
13159                             else {\r
13160                                 // NOTE 在第一个命令为 L, C, Q 的时候会计算出 NaN\r
13161                                 w += windingLine(xi, yi, data[i], data[i + 1], x, y) || 0;\r
13162                             }\r
13163                             xi = data[i++];\r
13164                             yi = data[i++];\r
13165                             break;\r
13166                         case CMD.C:\r
13167                             if (isStroke) {\r
13168                                 if (cubic.containStroke(xi, yi,\r
13169                                     data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1],\r
13170                                     lineWidth, x, y\r
13171                                 )) {\r
13172                                     return true;\r
13173                                 }\r
13174                             }\r
13175                             else {\r
13176                                 w += windingCubic(\r
13177                                     xi, yi,\r
13178                                     data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1],\r
13179                                     x, y\r
13180                                 ) || 0;\r
13181                             }\r
13182                             xi = data[i++];\r
13183                             yi = data[i++];\r
13184                             break;\r
13185                         case CMD.Q:\r
13186                             if (isStroke) {\r
13187                                 if (quadratic.containStroke(xi, yi,\r
13188                                     data[i++], data[i++], data[i], data[i + 1],\r
13189                                     lineWidth, x, y\r
13190                                 )) {\r
13191                                     return true;\r
13192                                 }\r
13193                             }\r
13194                             else {\r
13195                                 w += windingQuadratic(\r
13196                                     xi, yi,\r
13197                                     data[i++], data[i++], data[i], data[i + 1],\r
13198                                     x, y\r
13199                                 ) || 0;\r
13200                             }\r
13201                             xi = data[i++];\r
13202                             yi = data[i++];\r
13203                             break;\r
13204                         case CMD.A:\r
13205                             // TODO Arc 判断的开销比较大\r
13206                             var cx = data[i++];\r
13207                             var cy = data[i++];\r
13208                             var rx = data[i++];\r
13209                             var ry = data[i++];\r
13210                             var theta = data[i++];\r
13211                             var dTheta = data[i++];\r
13212                             // TODO Arc 旋转\r
13213                             var psi = data[i++];\r
13214                             var anticlockwise = 1 - data[i++];\r
13215                             var x1 = Math.cos(theta) * rx + cx;\r
13216                             var y1 = Math.sin(theta) * ry + cy;\r
13217                             // 不是直接使用 arc 命令\r
13218                             if (i > 1) {\r
13219                                 w += windingLine(xi, yi, x1, y1, x, y);\r
13220                             }\r
13221                             else {\r
13222                                 // 第一个命令起点还未定义\r
13223                                 x0 = x1;\r
13224                                 y0 = y1;\r
13225                             }\r
13226                             // zr 使用scale来模拟椭圆, 这里也对x做一定的缩放\r
13227                             var _x = (x - cx) * ry / rx + cx;\r
13228                             if (isStroke) {\r
13229                                 if (arc.containStroke(\r
13230                                     cx, cy, ry, theta, theta + dTheta, anticlockwise,\r
13231                                     lineWidth, _x, y\r
13232                                 )) {\r
13233                                     return true;\r
13234                                 }\r
13235                             }\r
13236                             else {\r
13237                                 w += windingArc(\r
13238                                     cx, cy, ry, theta, theta + dTheta, anticlockwise,\r
13239                                     _x, y\r
13240                                 );\r
13241                             }\r
13242                             xi = Math.cos(theta + dTheta) * rx + cx;\r
13243                             yi = Math.sin(theta + dTheta) * ry + cy;\r
13244                             break;\r
13245                         case CMD.R:\r
13246                             x0 = xi = data[i++];\r
13247                             y0 = yi = data[i++];\r
13248                             var width = data[i++];\r
13249                             var height = data[i++];\r
13250                             var x1 = x0 + width;\r
13251                             var y1 = y0 + height;\r
13252                             if (isStroke) {\r
13253                                 if (containStroke(x0, y0, x1, y0, lineWidth, x, y)\r
13254                                   || containStroke(x1, y0, x1, y1, lineWidth, x, y)\r
13255                                   || containStroke(x1, y1, x0, y1, lineWidth, x, y)\r
13256                                   || containStroke(x0, y1, x1, y1, lineWidth, x, y)\r
13257                                 ) {\r
13258                                     return true;\r
13259                                 }\r
13260                             }\r
13261                             else {\r
13262                                 // FIXME Clockwise ?\r
13263                                 w += windingLine(x1, y0, x1, y1, x, y);\r
13264                                 w += windingLine(x0, y1, x0, y0, x, y);\r
13265                             }\r
13266                             break;\r
13267                         case CMD.Z:\r
13268                             if (isStroke) {\r
13269                                 if (containStroke(\r
13270                                     xi, yi, x0, y0, lineWidth, x, y\r
13271                                 )) {\r
13272                                     return true;\r
13273                                 }\r
13274                             }\r
13275                             else {\r
13276                                 // Close a subpath\r
13277                                 w += windingLine(xi, yi, x0, y0, x, y);\r
13278                                 // 如果被任何一个 subpath 包含\r
13279                                 if (w !== 0) {\r
13280                                     return true;\r
13281                                 }\r
13282                             }\r
13283                             xi = x0;\r
13284                             yi = y0;\r
13285                             break;\r
13286                     }\r
13287                 }\r
13288                 if (!isStroke && !isAroundEqual(yi, y0)) {\r
13289                     w += windingLine(xi, yi, x0, y0, x, y) || 0;\r
13290                 }\r
13291                 return w !== 0;\r
13292             }\r
13293 \r
13294             module.exports = {\r
13295                 contain: function (pathData, x, y) {\r
13296                     return containPath(pathData, 0, false, x, y);\r
13297                 },\r
13298 \r
13299                 containStroke: function (pathData, lineWidth, x, y) {\r
13300                     return containPath(pathData, lineWidth, true, x, y);\r
13301                 }\r
13302             };\r
13303 \r
13304 \r
13305 /***/ },\r
13306 /* 52 */\r
13307 /***/ function(module, exports) {\r
13308 \r
13309         \r
13310             module.exports = {\r
13311                 /**\r
13312                  * 线段包含判断\r
13313                  * @param  {number}  x0\r
13314                  * @param  {number}  y0\r
13315                  * @param  {number}  x1\r
13316                  * @param  {number}  y1\r
13317                  * @param  {number}  lineWidth\r
13318                  * @param  {number}  x\r
13319                  * @param  {number}  y\r
13320                  * @return {boolean}\r
13321                  */\r
13322                 containStroke: function (x0, y0, x1, y1, lineWidth, x, y) {\r
13323                     if (lineWidth === 0) {\r
13324                         return false;\r
13325                     }\r
13326                     var _l = lineWidth;\r
13327                     var _a = 0;\r
13328                     var _b = x0;\r
13329                     // Quick reject\r
13330                     if (\r
13331                         (y > y0 + _l && y > y1 + _l)\r
13332                         || (y < y0 - _l && y < y1 - _l)\r
13333                         || (x > x0 + _l && x > x1 + _l)\r
13334                         || (x < x0 - _l && x < x1 - _l)\r
13335                     ) {\r
13336                         return false;\r
13337                     }\r
13338 \r
13339                     if (x0 !== x1) {\r
13340                         _a = (y0 - y1) / (x0 - x1);\r
13341                         _b = (x0 * y1 - x1 * y0) / (x0 - x1) ;\r
13342                     }\r
13343                     else {\r
13344                         return Math.abs(x - x0) <= _l / 2;\r
13345                     }\r
13346                     var tmp = _a * x - y + _b;\r
13347                     var _s = tmp * tmp / (_a * _a + 1);\r
13348                     return _s <= _l / 2 * _l / 2;\r
13349                 }\r
13350             };\r
13351 \r
13352 \r
13353 /***/ },\r
13354 /* 53 */\r
13355 /***/ function(module, exports, __webpack_require__) {\r
13356 \r
13357         \r
13358 \r
13359             var curve = __webpack_require__(49);\r
13360 \r
13361             module.exports = {\r
13362                 /**\r
13363                  * 三次贝塞尔曲线描边包含判断\r
13364                  * @param  {number}  x0\r
13365                  * @param  {number}  y0\r
13366                  * @param  {number}  x1\r
13367                  * @param  {number}  y1\r
13368                  * @param  {number}  x2\r
13369                  * @param  {number}  y2\r
13370                  * @param  {number}  x3\r
13371                  * @param  {number}  y3\r
13372                  * @param  {number}  lineWidth\r
13373                  * @param  {number}  x\r
13374                  * @param  {number}  y\r
13375                  * @return {boolean}\r
13376                  */\r
13377                 containStroke: function(x0, y0, x1, y1, x2, y2, x3, y3, lineWidth, x, y) {\r
13378                     if (lineWidth === 0) {\r
13379                         return false;\r
13380                     }\r
13381                     var _l = lineWidth;\r
13382                     // Quick reject\r
13383                     if (\r
13384                         (y > y0 + _l && y > y1 + _l && y > y2 + _l && y > y3 + _l)\r
13385                         || (y < y0 - _l && y < y1 - _l && y < y2 - _l && y < y3 - _l)\r
13386                         || (x > x0 + _l && x > x1 + _l && x > x2 + _l && x > x3 + _l)\r
13387                         || (x < x0 - _l && x < x1 - _l && x < x2 - _l && x < x3 - _l)\r
13388                     ) {\r
13389                         return false;\r
13390                     }\r
13391                     var d = curve.cubicProjectPoint(\r
13392                         x0, y0, x1, y1, x2, y2, x3, y3,\r
13393                         x, y, null\r
13394                     );\r
13395                     return d <= _l / 2;\r
13396                 }\r
13397             };\r
13398 \r
13399 \r
13400 /***/ },\r
13401 /* 54 */\r
13402 /***/ function(module, exports, __webpack_require__) {\r
13403 \r
13404         \r
13405 \r
13406             var curve = __webpack_require__(49);\r
13407 \r
13408             module.exports = {\r
13409                 /**\r
13410                  * 二次贝塞尔曲线描边包含判断\r
13411                  * @param  {number}  x0\r
13412                  * @param  {number}  y0\r
13413                  * @param  {number}  x1\r
13414                  * @param  {number}  y1\r
13415                  * @param  {number}  x2\r
13416                  * @param  {number}  y2\r
13417                  * @param  {number}  lineWidth\r
13418                  * @param  {number}  x\r
13419                  * @param  {number}  y\r
13420                  * @return {boolean}\r
13421                  */\r
13422                 containStroke: function (x0, y0, x1, y1, x2, y2, lineWidth, x, y) {\r
13423                     if (lineWidth === 0) {\r
13424                         return false;\r
13425                     }\r
13426                     var _l = lineWidth;\r
13427                     // Quick reject\r
13428                     if (\r
13429                         (y > y0 + _l && y > y1 + _l && y > y2 + _l)\r
13430                         || (y < y0 - _l && y < y1 - _l && y < y2 - _l)\r
13431                         || (x > x0 + _l && x > x1 + _l && x > x2 + _l)\r
13432                         || (x < x0 - _l && x < x1 - _l && x < x2 - _l)\r
13433                     ) {\r
13434                         return false;\r
13435                     }\r
13436                     var d = curve.quadraticProjectPoint(\r
13437                         x0, y0, x1, y1, x2, y2,\r
13438                         x, y, null\r
13439                     );\r
13440                     return d <= _l / 2;\r
13441                 }\r
13442             };\r
13443 \r
13444 \r
13445 /***/ },\r
13446 /* 55 */\r
13447 /***/ function(module, exports, __webpack_require__) {\r
13448 \r
13449         \r
13450 \r
13451             var normalizeRadian = __webpack_require__(56).normalizeRadian;\r
13452             var PI2 = Math.PI * 2;\r
13453 \r
13454             module.exports = {\r
13455                 /**\r
13456                  * 圆弧描边包含判断\r
13457                  * @param  {number}  cx\r
13458                  * @param  {number}  cy\r
13459                  * @param  {number}  r\r
13460                  * @param  {number}  startAngle\r
13461                  * @param  {number}  endAngle\r
13462                  * @param  {boolean}  anticlockwise\r
13463                  * @param  {number} lineWidth\r
13464                  * @param  {number}  x\r
13465                  * @param  {number}  y\r
13466                  * @return {Boolean}\r
13467                  */\r
13468                 containStroke: function (\r
13469                     cx, cy, r, startAngle, endAngle, anticlockwise,\r
13470                     lineWidth, x, y\r
13471                 ) {\r
13472 \r
13473                     if (lineWidth === 0) {\r
13474                         return false;\r
13475                     }\r
13476                     var _l = lineWidth;\r
13477 \r
13478                     x -= cx;\r
13479                     y -= cy;\r
13480                     var d = Math.sqrt(x * x + y * y);\r
13481 \r
13482                     if ((d - _l > r) || (d + _l < r)) {\r
13483                         return false;\r
13484                     }\r
13485                     if (Math.abs(startAngle - endAngle) % PI2 < 1e-4) {\r
13486                         // Is a circle\r
13487                         return true;\r
13488                     }\r
13489                     if (anticlockwise) {\r
13490                         var tmp = startAngle;\r
13491                         startAngle = normalizeRadian(endAngle);\r
13492                         endAngle = normalizeRadian(tmp);\r
13493                     } else {\r
13494                         startAngle = normalizeRadian(startAngle);\r
13495                         endAngle = normalizeRadian(endAngle);\r
13496                     }\r
13497                     if (startAngle > endAngle) {\r
13498                         endAngle += PI2;\r
13499                     }\r
13500 \r
13501                     var angle = Math.atan2(y, x);\r
13502                     if (angle < 0) {\r
13503                         angle += PI2;\r
13504                     }\r
13505                     return (angle >= startAngle && angle <= endAngle)\r
13506                         || (angle + PI2 >= startAngle && angle + PI2 <= endAngle);\r
13507                 }\r
13508             };\r
13509 \r
13510 \r
13511 /***/ },\r
13512 /* 56 */\r
13513 /***/ function(module, exports) {\r
13514 \r
13515         \r
13516 \r
13517             var PI2 = Math.PI * 2;\r
13518             module.exports = {\r
13519                 normalizeRadian: function(angle) {\r
13520                     angle %= PI2;\r
13521                     if (angle < 0) {\r
13522                         angle += PI2;\r
13523                     }\r
13524                     return angle;\r
13525                 }\r
13526             };\r
13527 \r
13528 \r
13529 /***/ },\r
13530 /* 57 */\r
13531 /***/ function(module, exports) {\r
13532 \r
13533         \r
13534             module.exports = function windingLine(x0, y0, x1, y1, x, y) {\r
13535                 if ((y > y0 && y > y1) || (y < y0 && y < y1)) {\r
13536                     return 0;\r
13537                 }\r
13538                 if (y1 === y0) {\r
13539                     return 0;\r
13540                 }\r
13541                 var dir = y1 < y0 ? 1 : -1;\r
13542                 var t = (y - y0) / (y1 - y0);\r
13543                 var x_ = t * (x1 - x0) + x0;\r
13544 \r
13545                 return x_ > x ? dir : 0;\r
13546             };\r
13547 \r
13548 \r
13549 /***/ },\r
13550 /* 58 */\r
13551 /***/ function(module, exports, __webpack_require__) {\r
13552 \r
13553         \r
13554 \r
13555             var CMD = __webpack_require__(48).CMD;\r
13556             var vec2 = __webpack_require__(16);\r
13557             var v2ApplyTransform = vec2.applyTransform;\r
13558 \r
13559             var points = [[], [], []];\r
13560             var mathSqrt = Math.sqrt;\r
13561             var mathAtan2 = Math.atan2;\r
13562             function transformPath(path, m) {\r
13563                 var data = path.data;\r
13564                 var cmd;\r
13565                 var nPoint;\r
13566                 var i;\r
13567                 var j;\r
13568                 var k;\r
13569                 var p;\r
13570 \r
13571                 var M = CMD.M;\r
13572                 var C = CMD.C;\r
13573                 var L = CMD.L;\r
13574                 var R = CMD.R;\r
13575                 var A = CMD.A;\r
13576                 var Q = CMD.Q;\r
13577 \r
13578                 for (i = 0, j = 0; i < data.length;) {\r
13579                     cmd = data[i++];\r
13580                     j = i;\r
13581                     nPoint = 0;\r
13582 \r
13583                     switch (cmd) {\r
13584                         case M:\r
13585                             nPoint = 1;\r
13586                             break;\r
13587                         case L:\r
13588                             nPoint = 1;\r
13589                             break;\r
13590                         case C:\r
13591                             nPoint = 3;\r
13592                             break;\r
13593                         case Q:\r
13594                             nPoint = 2;\r
13595                             break;\r
13596                         case A:\r
13597                             var x = m[4];\r
13598                             var y = m[5];\r
13599                             var sx = mathSqrt(m[0] * m[0] + m[1] * m[1]);\r
13600                             var sy = mathSqrt(m[2] * m[2] + m[3] * m[3]);\r
13601                             var angle = mathAtan2(-m[1] / sy, m[0] / sx);\r
13602                             // cx\r
13603                             data[i++] += x;\r
13604                             // cy\r
13605                             data[i++] += y;\r
13606                             // Scale rx and ry\r
13607                             // FIXME Assume psi is 0 here\r
13608                             data[i++] *= sx;\r
13609                             data[i++] *= sy;\r
13610 \r
13611                             // Start angle\r
13612                             data[i++] += angle;\r
13613                             // end angle\r
13614                             data[i++] += angle;\r
13615                             // FIXME psi\r
13616                             i += 2;\r
13617                             j = i;\r
13618                             break;\r
13619                         case R:\r
13620                             // x0, y0\r
13621                             p[0] = data[i++];\r
13622                             p[1] = data[i++];\r
13623                             v2ApplyTransform(p, p, m);\r
13624                             data[j++] = p[0];\r
13625                             data[j++] = p[1];\r
13626                             // x1, y1\r
13627                             p[0] += data[i++];\r
13628                             p[1] += data[i++];\r
13629                             v2ApplyTransform(p, p, m);\r
13630                             data[j++] = p[0];\r
13631                             data[j++] = p[1];\r
13632                     }\r
13633 \r
13634                     for (k = 0; k < nPoint; k++) {\r
13635                         var p = points[k];\r
13636                         p[0] = data[i++];\r
13637                         p[1] = data[i++];\r
13638 \r
13639                         v2ApplyTransform(p, p, m);\r
13640                         // Write back\r
13641                         data[j++] = p[0];\r
13642                         data[j++] = p[1];\r
13643                     }\r
13644                 }\r
13645             }\r
13646 \r
13647             module.exports = transformPath;\r
13648 \r
13649 \r
13650 /***/ },\r
13651 /* 59 */\r
13652 /***/ function(module, exports, __webpack_require__) {\r
13653 \r
13654         /**\r
13655          * Image element\r
13656          * @module zrender/graphic/Image\r
13657          */\r
13658 \r
13659 \r
13660 \r
13661             var Displayable = __webpack_require__(45);\r
13662             var BoundingRect = __webpack_require__(15);\r
13663             var zrUtil = __webpack_require__(3);\r
13664             var roundRectHelper = __webpack_require__(60);\r
13665 \r
13666             var LRU = __webpack_require__(61);\r
13667             var globalImageCache = new LRU(50);\r
13668             /**\r
13669              * @alias zrender/graphic/Image\r
13670              * @extends module:zrender/graphic/Displayable\r
13671              * @constructor\r
13672              * @param {Object} opts\r
13673              */\r
13674             function ZImage(opts) {\r
13675                 Displayable.call(this, opts);\r
13676             }\r
13677 \r
13678             ZImage.prototype = {\r
13679 \r
13680                 constructor: ZImage,\r
13681 \r
13682                 type: 'image',\r
13683 \r
13684                 brush: function (ctx) {\r
13685                     var style = this.style;\r
13686                     var src = style.image;\r
13687                     var image;\r
13688                     // style.image is a url string\r
13689                     if (typeof src === 'string') {\r
13690                         image = this._image;\r
13691                     }\r
13692                     // style.image is an HTMLImageElement or HTMLCanvasElement or Canvas\r
13693                     else {\r
13694                         image = src;\r
13695                     }\r
13696                     // FIXME Case create many images with src\r
13697                     if (!image && src) {\r
13698                         // Try get from global image cache\r
13699                         var cachedImgObj = globalImageCache.get(src);\r
13700                         if (!cachedImgObj) {\r
13701                             // Create a new image\r
13702                             image = new Image();\r
13703                             image.onload = function () {\r
13704                                 image.onload = null;\r
13705                                 for (var i = 0; i < cachedImgObj.pending.length; i++) {\r
13706                                     cachedImgObj.pending[i].dirty();\r
13707                                 }\r
13708                             };\r
13709                             cachedImgObj = {\r
13710                                 image: image,\r
13711                                 pending: [this]\r
13712                             };\r
13713                             image.src = src;\r
13714                             globalImageCache.put(src, cachedImgObj);\r
13715                             this._image = image;\r
13716                             return;\r
13717                         }\r
13718                         else {\r
13719                             image = cachedImgObj.image;\r
13720                             this._image = image;\r
13721                             // Image is not complete finish, add to pending list\r
13722                             if (!image.width || !image.height) {\r
13723                                 cachedImgObj.pending.push(this);\r
13724                                 return;\r
13725                             }\r
13726                         }\r
13727                     }\r
13728 \r
13729                     if (image) {\r
13730                         // 图片已经加载完成\r
13731                         // if (image.nodeName.toUpperCase() == 'IMG') {\r
13732                         //     if (!image.complete) {\r
13733                         //         return;\r
13734                         //     }\r
13735                         // }\r
13736                         // Else is canvas\r
13737 \r
13738                         var width = style.width || image.width;\r
13739                         var height = style.height || image.height;\r
13740                         var x = style.x || 0;\r
13741                         var y = style.y || 0;\r
13742                         // 图片加载失败\r
13743                         if (!image.width || !image.height) {\r
13744                             return;\r
13745                         }\r
13746 \r
13747                         ctx.save();\r
13748 \r
13749                         style.bind(ctx);\r
13750 \r
13751                         // 设置transform\r
13752                         this.setTransform(ctx);\r
13753 \r
13754                         if (style.r) {\r
13755                             // Border radius clipping\r
13756                             // FIXME\r
13757                             ctx.beginPath();\r
13758                             roundRectHelper.buildPath(ctx, style);\r
13759                             ctx.clip();\r
13760                         }\r
13761 \r
13762                         if (style.sWidth && style.sHeight) {\r
13763                             var sx = style.sx || 0;\r
13764                             var sy = style.sy || 0;\r
13765                             ctx.drawImage(\r
13766                                 image,\r
13767                                 sx, sy, style.sWidth, style.sHeight,\r
13768                                 x, y, width, height\r
13769                             );\r
13770                         }\r
13771                         else if (style.sx && style.sy) {\r
13772                             var sx = style.sx;\r
13773                             var sy = style.sy;\r
13774                             var sWidth = width - sx;\r
13775                             var sHeight = height - sy;\r
13776                             ctx.drawImage(\r
13777                                 image,\r
13778                                 sx, sy, sWidth, sHeight,\r
13779                                 x, y, width, height\r
13780                             );\r
13781                         }\r
13782                         else {\r
13783                             ctx.drawImage(image, x, y, width, height);\r
13784                         }\r
13785 \r
13786                         // 如果没设置宽和高的话自动根据图片宽高设置\r
13787                         if (style.width == null) {\r
13788                             style.width = width;\r
13789                         }\r
13790                         if (style.height == null) {\r
13791                             style.height = height;\r
13792                         }\r
13793 \r
13794                         // Draw rect text\r
13795                         if (style.text != null) {\r
13796                             this.drawRectText(ctx, this.getBoundingRect());\r
13797                         }\r
13798 \r
13799                         ctx.restore();\r
13800                     }\r
13801                 },\r
13802 \r
13803                 getBoundingRect: function () {\r
13804                     var style = this.style;\r
13805                     if (! this._rect) {\r
13806                         this._rect = new BoundingRect(\r
13807                             style.x || 0, style.y || 0, style.width || 0, style.height || 0\r
13808                         );\r
13809                     }\r
13810                     return this._rect;\r
13811                 }\r
13812             };\r
13813 \r
13814             zrUtil.inherits(ZImage, Displayable);\r
13815 \r
13816             module.exports = ZImage;\r
13817 \r
13818 \r
13819 /***/ },\r
13820 /* 60 */\r
13821 /***/ function(module, exports) {\r
13822 \r
13823         \r
13824 \r
13825             module.exports = {\r
13826                 buildPath: function (ctx, shape) {\r
13827                     var x = shape.x;\r
13828                     var y = shape.y;\r
13829                     var width = shape.width;\r
13830                     var height = shape.height;\r
13831                     var r = shape.r;\r
13832                     var r1;\r
13833                     var r2;\r
13834                     var r3;\r
13835                     var r4;\r
13836 \r
13837                     // Convert width and height to positive for better borderRadius\r
13838                     if (width < 0) {\r
13839                         x = x + width;\r
13840                         width = -width;\r
13841                     }\r
13842                     if (height < 0) {\r
13843                         y = y + height;\r
13844                         height = -height;\r
13845                     }\r
13846 \r
13847                     if (typeof r === 'number') {\r
13848                         r1 = r2 = r3 = r4 = r;\r
13849                     }\r
13850                     else if (r instanceof Array) {\r
13851                         if (r.length === 1) {\r
13852                             r1 = r2 = r3 = r4 = r[0];\r
13853                         }\r
13854                         else if (r.length === 2) {\r
13855                             r1 = r3 = r[0];\r
13856                             r2 = r4 = r[1];\r
13857                         }\r
13858                         else if (r.length === 3) {\r
13859                             r1 = r[0];\r
13860                             r2 = r4 = r[1];\r
13861                             r3 = r[2];\r
13862                         }\r
13863                         else {\r
13864                             r1 = r[0];\r
13865                             r2 = r[1];\r
13866                             r3 = r[2];\r
13867                             r4 = r[3];\r
13868                         }\r
13869                     }\r
13870                     else {\r
13871                         r1 = r2 = r3 = r4 = 0;\r
13872                     }\r
13873 \r
13874                     var total;\r
13875                     if (r1 + r2 > width) {\r
13876                         total = r1 + r2;\r
13877                         r1 *= width / total;\r
13878                         r2 *= width / total;\r
13879                     }\r
13880                     if (r3 + r4 > width) {\r
13881                         total = r3 + r4;\r
13882                         r3 *= width / total;\r
13883                         r4 *= width / total;\r
13884                     }\r
13885                     if (r2 + r3 > height) {\r
13886                         total = r2 + r3;\r
13887                         r2 *= height / total;\r
13888                         r3 *= height / total;\r
13889                     }\r
13890                     if (r1 + r4 > height) {\r
13891                         total = r1 + r4;\r
13892                         r1 *= height / total;\r
13893                         r4 *= height / total;\r
13894                     }\r
13895                     ctx.moveTo(x + r1, y);\r
13896                     ctx.lineTo(x + width - r2, y);\r
13897                     r2 !== 0 && ctx.quadraticCurveTo(\r
13898                         x + width, y, x + width, y + r2\r
13899                     );\r
13900                     ctx.lineTo(x + width, y + height - r3);\r
13901                     r3 !== 0 && ctx.quadraticCurveTo(\r
13902                         x + width, y + height, x + width - r3, y + height\r
13903                     );\r
13904                     ctx.lineTo(x + r4, y + height);\r
13905                     r4 !== 0 && ctx.quadraticCurveTo(\r
13906                         x, y + height, x, y + height - r4\r
13907                     );\r
13908                     ctx.lineTo(x, y + r1);\r
13909                     r1 !== 0 && ctx.quadraticCurveTo(x, y, x + r1, y);\r
13910                 }\r
13911             };\r
13912 \r
13913 \r
13914 /***/ },\r
13915 /* 61 */\r
13916 /***/ function(module, exports) {\r
13917 \r
13918         // Simple LRU cache use doubly linked list\r
13919         // @module zrender/core/LRU\r
13920 \r
13921 \r
13922             /**\r
13923              * Simple double linked list. Compared with array, it has O(1) remove operation.\r
13924              * @constructor\r
13925              */\r
13926             var LinkedList = function() {\r
13927 \r
13928                 /**\r
13929                  * @type {module:zrender/core/LRU~Entry}\r
13930                  */\r
13931                 this.head = null;\r
13932 \r
13933                 /**\r
13934                  * @type {module:zrender/core/LRU~Entry}\r
13935                  */\r
13936                 this.tail = null;\r
13937 \r
13938                 this._len = 0;\r
13939             };\r
13940 \r
13941             var linkedListProto = LinkedList.prototype;\r
13942             /**\r
13943              * Insert a new value at the tail\r
13944              * @param  {} val\r
13945              * @return {module:zrender/core/LRU~Entry}\r
13946              */\r
13947             linkedListProto.insert = function(val) {\r
13948                 var entry = new Entry(val);\r
13949                 this.insertEntry(entry);\r
13950                 return entry;\r
13951             };\r
13952 \r
13953             /**\r
13954              * Insert an entry at the tail\r
13955              * @param  {module:zrender/core/LRU~Entry} entry\r
13956              */\r
13957             linkedListProto.insertEntry = function(entry) {\r
13958                 if (!this.head) {\r
13959                     this.head = this.tail = entry;\r
13960                 }\r
13961                 else {\r
13962                     this.tail.next = entry;\r
13963                     entry.prev = this.tail;\r
13964                     this.tail = entry;\r
13965                 }\r
13966                 this._len++;\r
13967             };\r
13968 \r
13969             /**\r
13970              * Remove entry.\r
13971              * @param  {module:zrender/core/LRU~Entry} entry\r
13972              */\r
13973             linkedListProto.remove = function(entry) {\r
13974                 var prev = entry.prev;\r
13975                 var next = entry.next;\r
13976                 if (prev) {\r
13977                     prev.next = next;\r
13978                 }\r
13979                 else {\r
13980                     // Is head\r
13981                     this.head = next;\r
13982                 }\r
13983                 if (next) {\r
13984                     next.prev = prev;\r
13985                 }\r
13986                 else {\r
13987                     // Is tail\r
13988                     this.tail = prev;\r
13989                 }\r
13990                 entry.next = entry.prev = null;\r
13991                 this._len--;\r
13992             };\r
13993 \r
13994             /**\r
13995              * @return {number}\r
13996              */\r
13997             linkedListProto.len = function() {\r
13998                 return this._len;\r
13999             };\r
14000 \r
14001             /**\r
14002              * @constructor\r
14003              * @param {} val\r
14004              */\r
14005             var Entry = function(val) {\r
14006                 /**\r
14007                  * @type {}\r
14008                  */\r
14009                 this.value = val;\r
14010 \r
14011                 /**\r
14012                  * @type {module:zrender/core/LRU~Entry}\r
14013                  */\r
14014                 this.next;\r
14015 \r
14016                 /**\r
14017                  * @type {module:zrender/core/LRU~Entry}\r
14018                  */\r
14019                 this.prev;\r
14020             };\r
14021 \r
14022             /**\r
14023              * LRU Cache\r
14024              * @constructor\r
14025              * @alias module:zrender/core/LRU\r
14026              */\r
14027             var LRU = function(maxSize) {\r
14028 \r
14029                 this._list = new LinkedList();\r
14030 \r
14031                 this._map = {};\r
14032 \r
14033                 this._maxSize = maxSize || 10;\r
14034             };\r
14035 \r
14036             var LRUProto = LRU.prototype;\r
14037 \r
14038             /**\r
14039              * @param  {string} key\r
14040              * @param  {} value\r
14041              */\r
14042             LRUProto.put = function(key, value) {\r
14043                 var list = this._list;\r
14044                 var map = this._map;\r
14045                 if (map[key] == null) {\r
14046                     var len = list.len();\r
14047                     if (len >= this._maxSize && len > 0) {\r
14048                         // Remove the least recently used\r
14049                         var leastUsedEntry = list.head;\r
14050                         list.remove(leastUsedEntry);\r
14051                         delete map[leastUsedEntry.key];\r
14052                     }\r
14053 \r
14054                     var entry = list.insert(value);\r
14055                     entry.key = key;\r
14056                     map[key] = entry;\r
14057                 }\r
14058             };\r
14059 \r
14060             /**\r
14061              * @param  {string} key\r
14062              * @return {}\r
14063              */\r
14064             LRUProto.get = function(key) {\r
14065                 var entry = this._map[key];\r
14066                 var list = this._list;\r
14067                 if (entry != null) {\r
14068                     // Put the latest used entry in the tail\r
14069                     if (entry !== list.tail) {\r
14070                         list.remove(entry);\r
14071                         list.insertEntry(entry);\r
14072                     }\r
14073 \r
14074                     return entry.value;\r
14075                 }\r
14076             };\r
14077 \r
14078             /**\r
14079              * Clear the cache\r
14080              */\r
14081             LRUProto.clear = function() {\r
14082                 this._list.clear();\r
14083                 this._map = {};\r
14084             };\r
14085 \r
14086             module.exports = LRU;\r
14087 \r
14088 \r
14089 /***/ },\r
14090 /* 62 */\r
14091 /***/ function(module, exports, __webpack_require__) {\r
14092 \r
14093         /**\r
14094          * Text element\r
14095          * @module zrender/graphic/Text\r
14096          *\r
14097          * TODO Wrapping\r
14098          */\r
14099 \r
14100 \r
14101 \r
14102             var Displayable = __webpack_require__(45);\r
14103             var zrUtil = __webpack_require__(3);\r
14104             var textContain = __webpack_require__(14);\r
14105 \r
14106             /**\r
14107              * @alias zrender/graphic/Text\r
14108              * @extends module:zrender/graphic/Displayable\r
14109              * @constructor\r
14110              * @param {Object} opts\r
14111              */\r
14112             var Text = function (opts) {\r
14113                 Displayable.call(this, opts);\r
14114             };\r
14115 \r
14116             Text.prototype = {\r
14117 \r
14118                 constructor: Text,\r
14119 \r
14120                 type: 'text',\r
14121 \r
14122                 brush: function (ctx) {\r
14123                     var style = this.style;\r
14124                     var x = style.x || 0;\r
14125                     var y = style.y || 0;\r
14126                     // Convert to string\r
14127                     var text = style.text;\r
14128                     var textFill = style.fill;\r
14129                     var textStroke = style.stroke;\r
14130 \r
14131                     // Convert to string\r
14132                     text != null && (text += '');\r
14133 \r
14134                     if (text) {\r
14135                         ctx.save();\r
14136 \r
14137                         this.style.bind(ctx);\r
14138                         this.setTransform(ctx);\r
14139 \r
14140                         textFill && (ctx.fillStyle = textFill);\r
14141                         textStroke && (ctx.strokeStyle = textStroke);\r
14142 \r
14143                         ctx.font = style.textFont || style.font;\r
14144                         ctx.textAlign = style.textAlign;\r
14145 \r
14146                         if (style.textVerticalAlign) {\r
14147                             var rect = textContain.getBoundingRect(\r
14148                                 text, ctx.font, style.textAlign, 'top'\r
14149                             );\r
14150                             // Ignore textBaseline\r
14151                             ctx.textBaseline = 'top';\r
14152                             switch (style.textVerticalAlign) {\r
14153                                 case 'middle':\r
14154                                     y -= rect.height / 2;\r
14155                                     break;\r
14156                                 case 'bottom':\r
14157                                     y -= rect.height;\r
14158                                     break;\r
14159                                 // 'top'\r
14160                             }\r
14161                         }\r
14162                         else {\r
14163                             ctx.textBaseline = style.textBaseline;\r
14164                         }\r
14165                         var lineHeight = textContain.measureText('国', ctx.font).width;\r
14166 \r
14167                         var textLines = text.split('\n');\r
14168                         for (var i = 0; i < textLines.length; i++) {\r
14169                             textFill && ctx.fillText(textLines[i], x, y);\r
14170                             textStroke && ctx.strokeText(textLines[i], x, y);\r
14171                             y += lineHeight;\r
14172                         }\r
14173 \r
14174                         ctx.restore();\r
14175                     }\r
14176                 },\r
14177 \r
14178                 getBoundingRect: function () {\r
14179                     if (!this._rect) {\r
14180                         var style = this.style;\r
14181                         var textVerticalAlign = style.textVerticalAlign;\r
14182                         var rect = textContain.getBoundingRect(\r
14183                             style.text + '', style.textFont || style.font, style.textAlign,\r
14184                             textVerticalAlign ? 'top' : style.textBaseline\r
14185                         );\r
14186                         switch (textVerticalAlign) {\r
14187                             case 'middle':\r
14188                                 rect.y -= rect.height / 2;\r
14189                                 break;\r
14190                             case 'bottom':\r
14191                                 rect.y -= rect.height;\r
14192                                 break;\r
14193                         }\r
14194                         rect.x += style.x || 0;\r
14195                         rect.y += style.y || 0;\r
14196                         this._rect = rect;\r
14197                     }\r
14198                     return this._rect;\r
14199                 }\r
14200             };\r
14201 \r
14202             zrUtil.inherits(Text, Displayable);\r
14203 \r
14204             module.exports = Text;\r
14205 \r
14206 \r
14207 /***/ },\r
14208 /* 63 */\r
14209 /***/ function(module, exports, __webpack_require__) {\r
14210 \r
14211         'use strict';\r
14212         /**\r
14213          * 圆形\r
14214          * @module zrender/shape/Circle\r
14215          */\r
14216 \r
14217 \r
14218 \r
14219             module.exports = __webpack_require__(44).extend({\r
14220                 \r
14221                 type: 'circle',\r
14222 \r
14223                 shape: {\r
14224                     cx: 0,\r
14225                     cy: 0,\r
14226                     r: 0\r
14227                 },\r
14228 \r
14229                 buildPath : function (ctx, shape) {\r
14230                     // Better stroking in ShapeBundle\r
14231                     ctx.moveTo(shape.cx + shape.r, shape.cy);\r
14232                     ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2, true);\r
14233                     return;\r
14234                 }\r
14235             });\r
14236 \r
14237 \r
14238 \r
14239 /***/ },\r
14240 /* 64 */\r
14241 /***/ function(module, exports, __webpack_require__) {\r
14242 \r
14243         /**\r
14244          * 扇形\r
14245          * @module zrender/graphic/shape/Sector\r
14246          */\r
14247 \r
14248         // FIXME clockwise seems wrong\r
14249 \r
14250 \r
14251             module.exports = __webpack_require__(44).extend({\r
14252 \r
14253                 type: 'sector',\r
14254 \r
14255                 shape: {\r
14256 \r
14257                     cx: 0,\r
14258 \r
14259                     cy: 0,\r
14260 \r
14261                     r0: 0,\r
14262 \r
14263                     r: 0,\r
14264 \r
14265                     startAngle: 0,\r
14266 \r
14267                     endAngle: Math.PI * 2,\r
14268 \r
14269                     clockwise: true\r
14270                 },\r
14271 \r
14272                 buildPath: function (ctx, shape) {\r
14273 \r
14274                     var x = shape.cx;\r
14275                     var y = shape.cy;\r
14276                     var r0 = Math.max(shape.r0 || 0, 0);\r
14277                     var r = Math.max(shape.r, 0);\r
14278                     var startAngle = shape.startAngle;\r
14279                     var endAngle = shape.endAngle;\r
14280                     var clockwise = shape.clockwise;\r
14281 \r
14282                     var unitX = Math.cos(startAngle);\r
14283                     var unitY = Math.sin(startAngle);\r
14284 \r
14285                     ctx.moveTo(unitX * r0 + x, unitY * r0 + y);\r
14286 \r
14287                     ctx.lineTo(unitX * r + x, unitY * r + y);\r
14288 \r
14289                     ctx.arc(x, y, r, startAngle, endAngle, !clockwise);\r
14290 \r
14291                     ctx.lineTo(\r
14292                         Math.cos(endAngle) * r0 + x,\r
14293                         Math.sin(endAngle) * r0 + y\r
14294                     );\r
14295 \r
14296                     if (r0 !== 0) {\r
14297                         ctx.arc(x, y, r0, endAngle, startAngle, clockwise);\r
14298                     }\r
14299 \r
14300                     ctx.closePath();\r
14301                 }\r
14302             });\r
14303 \r
14304 \r
14305 \r
14306 /***/ },\r
14307 /* 65 */\r
14308 /***/ function(module, exports, __webpack_require__) {\r
14309 \r
14310         /**\r
14311          * 圆环\r
14312          * @module zrender/graphic/shape/Ring\r
14313          */\r
14314 \r
14315 \r
14316             module.exports = __webpack_require__(44).extend({\r
14317 \r
14318                 type: 'ring',\r
14319 \r
14320                 shape: {\r
14321                     cx: 0,\r
14322                     cy: 0,\r
14323                     r: 0,\r
14324                     r0: 0\r
14325                 },\r
14326 \r
14327                 buildPath: function (ctx, shape) {\r
14328                     var x = shape.cx;\r
14329                     var y = shape.cy;\r
14330                     var PI2 = Math.PI * 2;\r
14331                     ctx.moveTo(x + shape.r, y);\r
14332                     ctx.arc(x, y, shape.r, 0, PI2, false);\r
14333                     ctx.moveTo(x + shape.r0, y);\r
14334                     ctx.arc(x, y, shape.r0, 0, PI2, true);\r
14335                 }\r
14336             });\r
14337 \r
14338 \r
14339 \r
14340 /***/ },\r
14341 /* 66 */\r
14342 /***/ function(module, exports, __webpack_require__) {\r
14343 \r
14344         /**\r
14345          * 多边形\r
14346          * @module zrender/shape/Polygon\r
14347          */\r
14348 \r
14349 \r
14350             var polyHelper = __webpack_require__(67);\r
14351 \r
14352             module.exports = __webpack_require__(44).extend({\r
14353                 \r
14354                 type: 'polygon',\r
14355 \r
14356                 shape: {\r
14357                     points: null,\r
14358 \r
14359                     smooth: false,\r
14360 \r
14361                     smoothConstraint: null\r
14362                 },\r
14363 \r
14364                 buildPath: function (ctx, shape) {\r
14365                     polyHelper.buildPath(ctx, shape, true);\r
14366                 }\r
14367             });\r
14368 \r
14369 \r
14370 /***/ },\r
14371 /* 67 */\r
14372 /***/ function(module, exports, __webpack_require__) {\r
14373 \r
14374         \r
14375 \r
14376             var smoothSpline = __webpack_require__(68);\r
14377             var smoothBezier = __webpack_require__(69);\r
14378 \r
14379             module.exports = {\r
14380                 buildPath: function (ctx, shape, closePath) {\r
14381                     var points = shape.points;\r
14382                     var smooth = shape.smooth;\r
14383                     if (points && points.length >= 2) {\r
14384                         if (smooth && smooth !== 'spline') {\r
14385                             var controlPoints = smoothBezier(\r
14386                                 points, smooth, closePath, shape.smoothConstraint\r
14387                             );\r
14388 \r
14389                             ctx.moveTo(points[0][0], points[0][1]);\r
14390                             var len = points.length;\r
14391                             for (var i = 0; i < (closePath ? len : len - 1); i++) {\r
14392                                 var cp1 = controlPoints[i * 2];\r
14393                                 var cp2 = controlPoints[i * 2 + 1];\r
14394                                 var p = points[(i + 1) % len];\r
14395                                 ctx.bezierCurveTo(\r
14396                                     cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]\r
14397                                 );\r
14398                             }\r
14399                         }\r
14400                         else {\r
14401                             if (smooth === 'spline') {\r
14402                                 points = smoothSpline(points, closePath);\r
14403                             }\r
14404 \r
14405                             ctx.moveTo(points[0][0], points[0][1]);\r
14406                             for (var i = 1, l = points.length; i < l; i++) {\r
14407                                 ctx.lineTo(points[i][0], points[i][1]);\r
14408                             }\r
14409                         }\r
14410 \r
14411                         closePath && ctx.closePath();\r
14412                     }\r
14413                 }\r
14414             };\r
14415 \r
14416 \r
14417 /***/ },\r
14418 /* 68 */\r
14419 /***/ function(module, exports, __webpack_require__) {\r
14420 \r
14421         /**\r
14422          * Catmull-Rom spline 插值折线\r
14423          * @module zrender/shape/util/smoothSpline\r
14424          * @author pissang (https://www.github.com/pissang)\r
14425          *         Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
14426          *         errorrik (errorrik@gmail.com)\r
14427          */\r
14428 \r
14429             var vec2 = __webpack_require__(16);\r
14430 \r
14431             /**\r
14432              * @inner\r
14433              */\r
14434             function interpolate(p0, p1, p2, p3, t, t2, t3) {\r
14435                 var v0 = (p2 - p0) * 0.5;\r
14436                 var v1 = (p3 - p1) * 0.5;\r
14437                 return (2 * (p1 - p2) + v0 + v1) * t3\r
14438                         + (-3 * (p1 - p2) - 2 * v0 - v1) * t2\r
14439                         + v0 * t + p1;\r
14440             }\r
14441 \r
14442             /**\r
14443              * @alias module:zrender/shape/util/smoothSpline\r
14444              * @param {Array} points 线段顶点数组\r
14445              * @param {boolean} isLoop\r
14446              * @return {Array}\r
14447              */\r
14448             module.exports = function (points, isLoop) {\r
14449                 var len = points.length;\r
14450                 var ret = [];\r
14451 \r
14452                 var distance = 0;\r
14453                 for (var i = 1; i < len; i++) {\r
14454                     distance += vec2.distance(points[i - 1], points[i]);\r
14455                 }\r
14456 \r
14457                 var segs = distance / 2;\r
14458                 segs = segs < len ? len : segs;\r
14459                 for (var i = 0; i < segs; i++) {\r
14460                     var pos = i / (segs - 1) * (isLoop ? len : len - 1);\r
14461                     var idx = Math.floor(pos);\r
14462 \r
14463                     var w = pos - idx;\r
14464 \r
14465                     var p0;\r
14466                     var p1 = points[idx % len];\r
14467                     var p2;\r
14468                     var p3;\r
14469                     if (!isLoop) {\r
14470                         p0 = points[idx === 0 ? idx : idx - 1];\r
14471                         p2 = points[idx > len - 2 ? len - 1 : idx + 1];\r
14472                         p3 = points[idx > len - 3 ? len - 1 : idx + 2];\r
14473                     }\r
14474                     else {\r
14475                         p0 = points[(idx - 1 + len) % len];\r
14476                         p2 = points[(idx + 1) % len];\r
14477                         p3 = points[(idx + 2) % len];\r
14478                     }\r
14479 \r
14480                     var w2 = w * w;\r
14481                     var w3 = w * w2;\r
14482 \r
14483                     ret.push([\r
14484                         interpolate(p0[0], p1[0], p2[0], p3[0], w, w2, w3),\r
14485                         interpolate(p0[1], p1[1], p2[1], p3[1], w, w2, w3)\r
14486                     ]);\r
14487                 }\r
14488                 return ret;\r
14489             };\r
14490 \r
14491 \r
14492 \r
14493 /***/ },\r
14494 /* 69 */\r
14495 /***/ function(module, exports, __webpack_require__) {\r
14496 \r
14497         /**\r
14498          * 贝塞尔平滑曲线\r
14499          * @module zrender/shape/util/smoothBezier\r
14500          * @author pissang (https://www.github.com/pissang)\r
14501          *         Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
14502          *         errorrik (errorrik@gmail.com)\r
14503          */\r
14504 \r
14505 \r
14506             var vec2 = __webpack_require__(16);\r
14507             var v2Min = vec2.min;\r
14508             var v2Max = vec2.max;\r
14509             var v2Scale = vec2.scale;\r
14510             var v2Distance = vec2.distance;\r
14511             var v2Add = vec2.add;\r
14512 \r
14513             /**\r
14514              * 贝塞尔平滑曲线\r
14515              * @alias module:zrender/shape/util/smoothBezier\r
14516              * @param {Array} points 线段顶点数组\r
14517              * @param {number} smooth 平滑等级, 0-1\r
14518              * @param {boolean} isLoop\r
14519              * @param {Array} constraint 将计算出来的控制点约束在一个包围盒内\r
14520              *                           比如 [[0, 0], [100, 100]], 这个包围盒会与\r
14521              *                           整个折线的包围盒做一个并集用来约束控制点。\r
14522              * @param {Array} 计算出来的控制点数组\r
14523              */\r
14524             module.exports = function (points, smooth, isLoop, constraint) {\r
14525                 var cps = [];\r
14526 \r
14527                 var v = [];\r
14528                 var v1 = [];\r
14529                 var v2 = [];\r
14530                 var prevPoint;\r
14531                 var nextPoint;\r
14532 \r
14533                 var min, max;\r
14534                 if (constraint) {\r
14535                     min = [Infinity, Infinity];\r
14536                     max = [-Infinity, -Infinity];\r
14537                     for (var i = 0, len = points.length; i < len; i++) {\r
14538                         v2Min(min, min, points[i]);\r
14539                         v2Max(max, max, points[i]);\r
14540                     }\r
14541                     // 与指定的包围盒做并集\r
14542                     v2Min(min, min, constraint[0]);\r
14543                     v2Max(max, max, constraint[1]);\r
14544                 }\r
14545 \r
14546                 for (var i = 0, len = points.length; i < len; i++) {\r
14547                     var point = points[i];\r
14548 \r
14549                     if (isLoop) {\r
14550                         prevPoint = points[i ? i - 1 : len - 1];\r
14551                         nextPoint = points[(i + 1) % len];\r
14552                     }\r
14553                     else {\r
14554                         if (i === 0 || i === len - 1) {\r
14555                             cps.push(vec2.clone(points[i]));\r
14556                             continue;\r
14557                         }\r
14558                         else {\r
14559                             prevPoint = points[i - 1];\r
14560                             nextPoint = points[i + 1];\r
14561                         }\r
14562                     }\r
14563 \r
14564                     vec2.sub(v, nextPoint, prevPoint);\r
14565 \r
14566                     // use degree to scale the handle length\r
14567                     v2Scale(v, v, smooth);\r
14568 \r
14569                     var d0 = v2Distance(point, prevPoint);\r
14570                     var d1 = v2Distance(point, nextPoint);\r
14571                     var sum = d0 + d1;\r
14572                     if (sum !== 0) {\r
14573                         d0 /= sum;\r
14574                         d1 /= sum;\r
14575                     }\r
14576 \r
14577                     v2Scale(v1, v, -d0);\r
14578                     v2Scale(v2, v, d1);\r
14579                     var cp0 = v2Add([], point, v1);\r
14580                     var cp1 = v2Add([], point, v2);\r
14581                     if (constraint) {\r
14582                         v2Max(cp0, cp0, min);\r
14583                         v2Min(cp0, cp0, max);\r
14584                         v2Max(cp1, cp1, min);\r
14585                         v2Min(cp1, cp1, max);\r
14586                     }\r
14587                     cps.push(cp0);\r
14588                     cps.push(cp1);\r
14589                 }\r
14590 \r
14591                 if (isLoop) {\r
14592                     cps.push(cps.shift());\r
14593                 }\r
14594 \r
14595                 return cps;\r
14596             };\r
14597 \r
14598 \r
14599 \r
14600 /***/ },\r
14601 /* 70 */\r
14602 /***/ function(module, exports, __webpack_require__) {\r
14603 \r
14604         /**\r
14605          * @module zrender/graphic/shape/Polyline\r
14606          */\r
14607 \r
14608 \r
14609             var polyHelper = __webpack_require__(67);\r
14610 \r
14611             module.exports = __webpack_require__(44).extend({\r
14612                 \r
14613                 type: 'polyline',\r
14614 \r
14615                 shape: {\r
14616                     points: null,\r
14617 \r
14618                     smooth: false,\r
14619 \r
14620                     smoothConstraint: null\r
14621                 },\r
14622 \r
14623                 style: {\r
14624                     stroke: '#000',\r
14625 \r
14626                     fill: null\r
14627                 },\r
14628 \r
14629                 buildPath: function (ctx, shape) {\r
14630                     polyHelper.buildPath(ctx, shape, false);\r
14631                 }\r
14632             });\r
14633 \r
14634 \r
14635 /***/ },\r
14636 /* 71 */\r
14637 /***/ function(module, exports, __webpack_require__) {\r
14638 \r
14639         /**\r
14640          * 矩形\r
14641          * @module zrender/graphic/shape/Rect\r
14642          */\r
14643 \r
14644 \r
14645             var roundRectHelper = __webpack_require__(60);\r
14646 \r
14647             module.exports = __webpack_require__(44).extend({\r
14648 \r
14649                 type: 'rect',\r
14650 \r
14651                 shape: {\r
14652                     // 左上、右上、右下、左下角的半径依次为r1、r2、r3、r4\r
14653                     // r缩写为1         相当于 [1, 1, 1, 1]\r
14654                     // r缩写为[1]       相当于 [1, 1, 1, 1]\r
14655                     // r缩写为[1, 2]    相当于 [1, 2, 1, 2]\r
14656                     // r缩写为[1, 2, 3] 相当于 [1, 2, 3, 2]\r
14657                     r: 0,\r
14658 \r
14659                     x: 0,\r
14660                     y: 0,\r
14661                     width: 0,\r
14662                     height: 0\r
14663                 },\r
14664 \r
14665                 buildPath: function (ctx, shape) {\r
14666                     var x = shape.x;\r
14667                     var y = shape.y;\r
14668                     var width = shape.width;\r
14669                     var height = shape.height;\r
14670                     if (!shape.r) {\r
14671                         ctx.rect(x, y, width, height);\r
14672                     }\r
14673                     else {\r
14674                         roundRectHelper.buildPath(ctx, shape);\r
14675                     }\r
14676                     ctx.closePath();\r
14677                     return;\r
14678                 }\r
14679             });\r
14680 \r
14681 \r
14682 \r
14683 /***/ },\r
14684 /* 72 */\r
14685 /***/ function(module, exports, __webpack_require__) {\r
14686 \r
14687         /**\r
14688          * 直线\r
14689          * @module zrender/graphic/shape/Line\r
14690          */\r
14691 \r
14692             module.exports = __webpack_require__(44).extend({\r
14693 \r
14694                 type: 'line',\r
14695 \r
14696                 shape: {\r
14697                     // Start point\r
14698                     x1: 0,\r
14699                     y1: 0,\r
14700                     // End point\r
14701                     x2: 0,\r
14702                     y2: 0,\r
14703 \r
14704                     percent: 1\r
14705                 },\r
14706 \r
14707                 style: {\r
14708                     stroke: '#000',\r
14709                     fill: null\r
14710                 },\r
14711 \r
14712                 buildPath: function (ctx, shape) {\r
14713                     var x1 = shape.x1;\r
14714                     var y1 = shape.y1;\r
14715                     var x2 = shape.x2;\r
14716                     var y2 = shape.y2;\r
14717                     var percent = shape.percent;\r
14718 \r
14719                     if (percent === 0) {\r
14720                         return;\r
14721                     }\r
14722 \r
14723                     ctx.moveTo(x1, y1);\r
14724 \r
14725                     if (percent < 1) {\r
14726                         x2 = x1 * (1 - percent) + x2 * percent;\r
14727                         y2 = y1 * (1 - percent) + y2 * percent;\r
14728                     }\r
14729                     ctx.lineTo(x2, y2);\r
14730                 },\r
14731 \r
14732                 /**\r
14733                  * Get point at percent\r
14734                  * @param  {number} percent\r
14735                  * @return {Array.<number>}\r
14736                  */\r
14737                 pointAt: function (p) {\r
14738                     var shape = this.shape;\r
14739                     return [\r
14740                         shape.x1 * (1 - p) + shape.x2 * p,\r
14741                         shape.y1 * (1 - p) + shape.y2 * p\r
14742                     ];\r
14743                 }\r
14744             });\r
14745 \r
14746 \r
14747 \r
14748 /***/ },\r
14749 /* 73 */\r
14750 /***/ function(module, exports, __webpack_require__) {\r
14751 \r
14752         'use strict';\r
14753         /**\r
14754          * 贝塞尔曲线\r
14755          * @module zrender/shape/BezierCurve\r
14756          */\r
14757 \r
14758 \r
14759             var curveTool = __webpack_require__(49);\r
14760             var quadraticSubdivide = curveTool.quadraticSubdivide;\r
14761             var cubicSubdivide = curveTool.cubicSubdivide;\r
14762             var quadraticAt = curveTool.quadraticAt;\r
14763             var cubicAt = curveTool.cubicAt;\r
14764 \r
14765             var out = [];\r
14766             module.exports = __webpack_require__(44).extend({\r
14767 \r
14768                 type: 'bezier-curve',\r
14769 \r
14770                 shape: {\r
14771                     x1: 0,\r
14772                     y1: 0,\r
14773                     x2: 0,\r
14774                     y2: 0,\r
14775                     cpx1: 0,\r
14776                     cpy1: 0,\r
14777                     // cpx2: 0,\r
14778                     // cpy2: 0\r
14779 \r
14780                     // Curve show percent, for animating\r
14781                     percent: 1\r
14782                 },\r
14783 \r
14784                 style: {\r
14785                     stroke: '#000',\r
14786                     fill: null\r
14787                 },\r
14788 \r
14789                 buildPath: function (ctx, shape) {\r
14790                     var x1 = shape.x1;\r
14791                     var y1 = shape.y1;\r
14792                     var x2 = shape.x2;\r
14793                     var y2 = shape.y2;\r
14794                     var cpx1 = shape.cpx1;\r
14795                     var cpy1 = shape.cpy1;\r
14796                     var cpx2 = shape.cpx2;\r
14797                     var cpy2 = shape.cpy2;\r
14798                     var percent = shape.percent;\r
14799                     if (percent === 0) {\r
14800                         return;\r
14801                     }\r
14802 \r
14803                     ctx.moveTo(x1, y1);\r
14804 \r
14805                     if (cpx2 == null || cpy2 == null) {\r
14806                         if (percent < 1) {\r
14807                             quadraticSubdivide(\r
14808                                 x1, cpx1, x2, percent, out\r
14809                             );\r
14810                             cpx1 = out[1];\r
14811                             x2 = out[2];\r
14812                             quadraticSubdivide(\r
14813                                 y1, cpy1, y2, percent, out\r
14814                             );\r
14815                             cpy1 = out[1];\r
14816                             y2 = out[2];\r
14817                         }\r
14818 \r
14819                         ctx.quadraticCurveTo(\r
14820                             cpx1, cpy1,\r
14821                             x2, y2\r
14822                         );\r
14823                     }\r
14824                     else {\r
14825                         if (percent < 1) {\r
14826                             cubicSubdivide(\r
14827                                 x1, cpx1, cpx2, x2, percent, out\r
14828                             );\r
14829                             cpx1 = out[1];\r
14830                             cpx2 = out[2];\r
14831                             x2 = out[3];\r
14832                             cubicSubdivide(\r
14833                                 y1, cpy1, cpy2, y2, percent, out\r
14834                             );\r
14835                             cpy1 = out[1];\r
14836                             cpy2 = out[2];\r
14837                             y2 = out[3];\r
14838                         }\r
14839                         ctx.bezierCurveTo(\r
14840                             cpx1, cpy1,\r
14841                             cpx2, cpy2,\r
14842                             x2, y2\r
14843                         );\r
14844                     }\r
14845                 },\r
14846 \r
14847                 /**\r
14848                  * Get point at percent\r
14849                  * @param  {number} percent\r
14850                  * @return {Array.<number>}\r
14851                  */\r
14852                 pointAt: function (p) {\r
14853                     var shape = this.shape;\r
14854                     var cpx2 = shape.cpx2;\r
14855                     var cpy2 = shape.cpy2;\r
14856                     if (cpx2 === null || cpy2 === null) {\r
14857                         return [\r
14858                             quadraticAt(shape.x1, shape.cpx1, shape.x2, p),\r
14859                             quadraticAt(shape.y1, shape.cpy1, shape.y2, p)\r
14860                         ];\r
14861                     }\r
14862                     else {\r
14863                         return [\r
14864                             cubicAt(shape.x1, shape.cpx1, shape.cpx1, shape.x2, p),\r
14865                             cubicAt(shape.y1, shape.cpy1, shape.cpy1, shape.y2, p)\r
14866                         ];\r
14867                     }\r
14868                 }\r
14869             });\r
14870 \r
14871 \r
14872 \r
14873 /***/ },\r
14874 /* 74 */\r
14875 /***/ function(module, exports, __webpack_require__) {\r
14876 \r
14877         /**\r
14878          * 圆弧\r
14879          * @module zrender/graphic/shape/Arc\r
14880          */\r
14881          \r
14882 \r
14883             module.exports = __webpack_require__(44).extend({\r
14884 \r
14885                 type: 'arc',\r
14886 \r
14887                 shape: {\r
14888 \r
14889                     cx: 0,\r
14890 \r
14891                     cy: 0,\r
14892 \r
14893                     r: 0,\r
14894 \r
14895                     startAngle: 0,\r
14896 \r
14897                     endAngle: Math.PI * 2,\r
14898 \r
14899                     clockwise: true\r
14900                 },\r
14901 \r
14902                 style: {\r
14903 \r
14904                     stroke: '#000',\r
14905 \r
14906                     fill: null\r
14907                 },\r
14908 \r
14909                 buildPath: function (ctx, shape) {\r
14910 \r
14911                     var x = shape.cx;\r
14912                     var y = shape.cy;\r
14913                     var r = Math.max(shape.r, 0);\r
14914                     var startAngle = shape.startAngle;\r
14915                     var endAngle = shape.endAngle;\r
14916                     var clockwise = shape.clockwise;\r
14917 \r
14918                     var unitX = Math.cos(startAngle);\r
14919                     var unitY = Math.sin(startAngle);\r
14920 \r
14921                     ctx.moveTo(unitX * r + x, unitY * r + y);\r
14922                     ctx.arc(x, y, r, startAngle, endAngle, !clockwise);\r
14923                 }\r
14924             });\r
14925 \r
14926 \r
14927 /***/ },\r
14928 /* 75 */\r
14929 /***/ function(module, exports, __webpack_require__) {\r
14930 \r
14931         'use strict';\r
14932 \r
14933 \r
14934             var zrUtil = __webpack_require__(3);\r
14935 \r
14936             var Gradient = __webpack_require__(4);\r
14937 \r
14938             /**\r
14939              * x, y, x2, y2 are all percent from 0 to 1\r
14940              * @param {number} [x=0]\r
14941              * @param {number} [y=0]\r
14942              * @param {number} [x2=1]\r
14943              * @param {number} [y2=0]\r
14944              * @param {Array.<Object>} colorStops\r
14945              */\r
14946             var LinearGradient = function (x, y, x2, y2, colorStops) {\r
14947                 this.x = x == null ? 0 : x;\r
14948 \r
14949                 this.y = y == null ? 0 : y;\r
14950 \r
14951                 this.x2 = x2 == null ? 1 : x2;\r
14952 \r
14953                 this.y2 = y2 == null ? 0 : y2;\r
14954 \r
14955                 Gradient.call(this, colorStops);\r
14956             };\r
14957 \r
14958             LinearGradient.prototype = {\r
14959 \r
14960                 constructor: LinearGradient,\r
14961 \r
14962                 type: 'linear',\r
14963 \r
14964                 updateCanvasGradient: function (shape, ctx) {\r
14965                     var rect = shape.getBoundingRect();\r
14966                     // var size =\r
14967                     var x = this.x * rect.width + rect.x;\r
14968                     var x2 = this.x2 * rect.width + rect.x;\r
14969                     var y = this.y * rect.height + rect.y;\r
14970                     var y2 = this.y2 * rect.height + rect.y;\r
14971 \r
14972                     var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);\r
14973 \r
14974                     var colorStops = this.colorStops;\r
14975                     for (var i = 0; i < colorStops.length; i++) {\r
14976                         canvasGradient.addColorStop(\r
14977                             colorStops[i].offset, colorStops[i].color\r
14978                         );\r
14979                     }\r
14980 \r
14981                     this.canvasGradient = canvasGradient;\r
14982                 }\r
14983 \r
14984             };\r
14985 \r
14986             zrUtil.inherits(LinearGradient, Gradient);\r
14987 \r
14988             module.exports = LinearGradient;\r
14989 \r
14990 \r
14991 /***/ },\r
14992 /* 76 */\r
14993 /***/ function(module, exports, __webpack_require__) {\r
14994 \r
14995         'use strict';\r
14996 \r
14997 \r
14998             var zrUtil = __webpack_require__(3);\r
14999 \r
15000             var Gradient = __webpack_require__(4);\r
15001 \r
15002             /**\r
15003              * x, y, r are all percent from 0 to 1\r
15004              * @param {number} [x=0.5]\r
15005              * @param {number} [y=0.5]\r
15006              * @param {number} [r=0.5]\r
15007              * @param {Array.<Object>} [colorStops]\r
15008              */\r
15009             var RadialGradient = function (x, y, r, colorStops) {\r
15010                 this.x = x == null ? 0.5 : x;\r
15011 \r
15012                 this.y = y == null ? 0.5 : y;\r
15013 \r
15014                 this.r = r == null ? 0.5 : r;\r
15015 \r
15016                 Gradient.call(this, colorStops);\r
15017             };\r
15018 \r
15019             RadialGradient.prototype = {\r
15020 \r
15021                 constructor: RadialGradient,\r
15022 \r
15023                 type: 'radial',\r
15024 \r
15025                 updateCanvasGradient: function (shape, ctx) {\r
15026                     var rect = shape.getBoundingRect();\r
15027 \r
15028                     var width = rect.width;\r
15029                     var height = rect.height;\r
15030                     var min = Math.min(width, height);\r
15031                     // var max = Math.max(width, height);\r
15032 \r
15033                     var x = this.x * width + rect.x;\r
15034                     var y = this.y * height + rect.y;\r
15035                     var r = this.r * min;\r
15036 \r
15037                     var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);\r
15038 \r
15039                     var colorStops = this.colorStops;\r
15040                     for (var i = 0; i < colorStops.length; i++) {\r
15041                         canvasGradient.addColorStop(\r
15042                             colorStops[i].offset, colorStops[i].color\r
15043                         );\r
15044                     }\r
15045 \r
15046                     this.canvasGradient = canvasGradient;\r
15047                 }\r
15048             };\r
15049 \r
15050             zrUtil.inherits(RadialGradient, Gradient);\r
15051 \r
15052             module.exports = RadialGradient;\r
15053 \r
15054 \r
15055 /***/ },\r
15056 /* 77 */\r
15057 /***/ function(module, exports, __webpack_require__) {\r
15058 \r
15059         /*!\r
15060          * ZRender, a high performance 2d drawing library.\r
15061          *\r
15062          * Copyright (c) 2013, Baidu Inc.\r
15063          * All rights reserved.\r
15064          *\r
15065          * LICENSE\r
15066          * https://github.com/ecomfe/zrender/blob/master/LICENSE.txt\r
15067          */\r
15068         // Global defines\r
15069 \r
15070             var guid = __webpack_require__(31);\r
15071             var env = __webpack_require__(78);\r
15072 \r
15073             var Handler = __webpack_require__(79);\r
15074             var Storage = __webpack_require__(83);\r
15075             var Animation = __webpack_require__(84);\r
15076 \r
15077             var useVML = !env.canvasSupported;\r
15078 \r
15079             var painterCtors = {\r
15080                 canvas: __webpack_require__(85)\r
15081             };\r
15082 \r
15083             var instances = {};    // ZRender实例map索引\r
15084 \r
15085             var zrender = {};\r
15086             /**\r
15087              * @type {string}\r
15088              */\r
15089             zrender.version = '3.0.6';\r
15090 \r
15091             /**\r
15092              * @param {HTMLElement} dom\r
15093              * @param {Object} opts\r
15094              * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg'\r
15095              * @param {number} [opts.devicePixelRatio]\r
15096              * @return {module:zrender/ZRender}\r
15097              */\r
15098             zrender.init = function(dom, opts) {\r
15099                 var zr = new ZRender(guid(), dom, opts);\r
15100                 instances[zr.id] = zr;\r
15101                 return zr;\r
15102             };\r
15103 \r
15104             /**\r
15105              * Dispose zrender instance\r
15106              * @param {module:zrender/ZRender} zr\r
15107              */\r
15108             zrender.dispose = function (zr) {\r
15109                 if (zr) {\r
15110                     zr.dispose();\r
15111                 }\r
15112                 else {\r
15113                     for (var key in instances) {\r
15114                         instances[key].dispose();\r
15115                     }\r
15116                     instances = {};\r
15117                 }\r
15118 \r
15119                 return zrender;\r
15120             };\r
15121 \r
15122             /**\r
15123              * 获取zrender实例\r
15124              * @param {string} id ZRender对象索引\r
15125              * @return {module:zrender/ZRender}\r
15126              */\r
15127             zrender.getInstance = function (id) {\r
15128                 return instances[id];\r
15129             };\r
15130 \r
15131             zrender.registerPainter = function (name, Ctor) {\r
15132                 painterCtors[name] = Ctor;\r
15133             };\r
15134 \r
15135             function delInstance(id) {\r
15136                 delete instances[id];\r
15137             }\r
15138 \r
15139             /**\r
15140              * @module zrender/ZRender\r
15141              */\r
15142             /**\r
15143              * @constructor\r
15144              * @alias module:zrender/ZRender\r
15145              * @param {string} id\r
15146              * @param {HTMLDomElement} dom\r
15147              * @param {Object} opts\r
15148              * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg'\r
15149              * @param {number} [opts.devicePixelRatio]\r
15150              */\r
15151             var ZRender = function(id, dom, opts) {\r
15152 \r
15153                 opts = opts || {};\r
15154 \r
15155                 /**\r
15156                  * @type {HTMLDomElement}\r
15157                  */\r
15158                 this.dom = dom;\r
15159 \r
15160                 /**\r
15161                  * @type {string}\r
15162                  */\r
15163                 this.id = id;\r
15164 \r
15165                 var self = this;\r
15166                 var storage = new Storage();\r
15167 \r
15168                 var rendererType = opts.renderer;\r
15169                 if (useVML) {\r
15170                     if (!painterCtors.vml) {\r
15171                         throw new Error('You need to require \'zrender/vml/vml\' to support IE8');\r
15172                     }\r
15173                     rendererType = 'vml';\r
15174                 }\r
15175                 else if (!rendererType || !painterCtors[rendererType]) {\r
15176                     rendererType = 'canvas';\r
15177                 }\r
15178                 var painter = new painterCtors[rendererType](dom, storage, opts);\r
15179 \r
15180                 this.storage = storage;\r
15181                 this.painter = painter;\r
15182                 if (!env.node) {\r
15183                     this.handler = new Handler(painter.getViewportRoot(), storage, painter);\r
15184                 }\r
15185 \r
15186                 /**\r
15187                  * @type {module:zrender/animation/Animation}\r
15188                  */\r
15189                 this.animation = new Animation({\r
15190                     stage: {\r
15191                         update: function () {\r
15192                             if (self._needsRefresh) {\r
15193                                 self.refreshImmediately();\r
15194                             }\r
15195                         }\r
15196                     }\r
15197                 });\r
15198                 this.animation.start();\r
15199 \r
15200                 /**\r
15201                  * @type {boolean}\r
15202                  * @private\r
15203                  */\r
15204                 this._needsRefresh;\r
15205 \r
15206                 // 修改 storage.delFromMap, 每次删除元素之前删除动画\r
15207                 // FIXME 有点ugly\r
15208                 var oldDelFromMap = storage.delFromMap;\r
15209                 var oldAddToMap = storage.addToMap;\r
15210 \r
15211                 storage.delFromMap = function (elId) {\r
15212                     var el = storage.get(elId);\r
15213 \r
15214                     oldDelFromMap.call(storage, elId);\r
15215 \r
15216                     el && el.removeSelfFromZr(self);\r
15217                 };\r
15218 \r
15219                 storage.addToMap = function (el) {\r
15220                     oldAddToMap.call(storage, el);\r
15221 \r
15222                     el.addSelfToZr(self);\r
15223                 };\r
15224             };\r
15225 \r
15226             ZRender.prototype = {\r
15227 \r
15228                 constructor: ZRender,\r
15229                 /**\r
15230                  * 获取实例唯一标识\r
15231                  * @return {string}\r
15232                  */\r
15233                 getId: function () {\r
15234                     return this.id;\r
15235                 },\r
15236 \r
15237                 /**\r
15238                  * 添加元素\r
15239                  * @param  {string|module:zrender/Element} el\r
15240                  */\r
15241                 add: function (el) {\r
15242                     this.storage.addRoot(el);\r
15243                     this._needsRefresh = true;\r
15244                 },\r
15245 \r
15246                 /**\r
15247                  * 删除元素\r
15248                  * @param  {string|module:zrender/Element} el\r
15249                  */\r
15250                 remove: function (el) {\r
15251                     this.storage.delRoot(el);\r
15252                     this._needsRefresh = true;\r
15253                 },\r
15254 \r
15255                 /**\r
15256                  * 修改指定zlevel的绘制配置项\r
15257                  *\r
15258                  * @param {string} zLevel\r
15259                  * @param {Object} config 配置对象\r
15260                  * @param {string} [config.clearColor=0] 每次清空画布的颜色\r
15261                  * @param {string} [config.motionBlur=false] 是否开启动态模糊\r
15262                  * @param {number} [config.lastFrameAlpha=0.7]\r
15263                  *                 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显\r
15264                 */\r
15265                 configLayer: function (zLevel, config) {\r
15266                     this.painter.configLayer(zLevel, config);\r
15267                     this._needsRefresh = true;\r
15268                 },\r
15269 \r
15270                 /**\r
15271                  * 视图更新\r
15272                  */\r
15273                 refreshImmediately: function () {\r
15274                     // Clear needsRefresh ahead to avoid something wrong happens in refresh\r
15275                     // Or it will cause zrender refreshes again and again.\r
15276                     this._needsRefresh = false;\r
15277                     this.painter.refresh();\r
15278                     /**\r
15279                      * Avoid trigger zr.refresh in Element#beforeUpdate hook\r
15280                      */\r
15281                     this._needsRefresh = false;\r
15282                 },\r
15283 \r
15284                 /**\r
15285                  * 标记视图在浏览器下一帧需要绘制\r
15286                  */\r
15287                 refresh: function() {\r
15288                     this._needsRefresh = true;\r
15289                 },\r
15290 \r
15291                 /**\r
15292                  * 调整视图大小\r
15293                  */\r
15294                 resize: function() {\r
15295                     this.painter.resize();\r
15296                     this.handler && this.handler.resize();\r
15297                 },\r
15298 \r
15299                 /**\r
15300                  * 停止所有动画\r
15301                  */\r
15302                 clearAnimation: function () {\r
15303                     this.animation.clear();\r
15304                 },\r
15305 \r
15306                 /**\r
15307                  * 获取视图宽度\r
15308                  */\r
15309                 getWidth: function() {\r
15310                     return this.painter.getWidth();\r
15311                 },\r
15312 \r
15313                 /**\r
15314                  * 获取视图高度\r
15315                  */\r
15316                 getHeight: function() {\r
15317                     return this.painter.getHeight();\r
15318                 },\r
15319 \r
15320                 /**\r
15321                  * 图像导出\r
15322                  * @param {string} type\r
15323                  * @param {string} [backgroundColor='#fff'] 背景色\r
15324                  * @return {string} 图片的Base64 url\r
15325                  */\r
15326                 toDataURL: function(type, backgroundColor, args) {\r
15327                     return this.painter.toDataURL(type, backgroundColor, args);\r
15328                 },\r
15329 \r
15330                 /**\r
15331                  * 将常规shape转成image shape\r
15332                  * @param {module:zrender/graphic/Path} e\r
15333                  * @param {number} width\r
15334                  * @param {number} height\r
15335                  */\r
15336                 pathToImage: function(e, width, height) {\r
15337                     var id = guid();\r
15338                     return this.painter.pathToImage(id, e, width, height);\r
15339                 },\r
15340 \r
15341                 /**\r
15342                  * 设置默认的cursor style\r
15343                  * @param {string} cursorStyle 例如 crosshair\r
15344                  */\r
15345                 setDefaultCursorStyle: function (cursorStyle) {\r
15346                     this.handler.setDefaultCursorStyle(cursorStyle);\r
15347                 },\r
15348 \r
15349                 /**\r
15350                  * 事件绑定\r
15351                  *\r
15352                  * @param {string} eventName 事件名称\r
15353                  * @param {Function} eventHandler 响应函数\r
15354                  * @param {Object} [context] 响应函数\r
15355                  */\r
15356                 on: function(eventName, eventHandler, context) {\r
15357                     this.handler && this.handler.on(eventName, eventHandler, context);\r
15358                 },\r
15359 \r
15360                 /**\r
15361                  * 事件解绑定,参数为空则解绑所有自定义事件\r
15362                  *\r
15363                  * @param {string} eventName 事件名称\r
15364                  * @param {Function} eventHandler 响应函数\r
15365                  */\r
15366                 off: function(eventName, eventHandler) {\r
15367                     this.handler && this.handler.off(eventName, eventHandler);\r
15368                 },\r
15369 \r
15370                 /**\r
15371                  * 事件触发\r
15372                  *\r
15373                  * @param {string} eventName 事件名称,resize,hover,drag,etc\r
15374                  * @param {event=} event event dom事件对象\r
15375                  */\r
15376                 trigger: function (eventName, event) {\r
15377                     this.handler && this.handler.trigger(eventName, event);\r
15378                 },\r
15379 \r
15380 \r
15381                 /**\r
15382                  * 清除当前ZRender下所有类图的数据和显示,clear后MVC和已绑定事件均还存在在,ZRender可用\r
15383                  */\r
15384                 clear: function () {\r
15385                     this.storage.delRoot();\r
15386                     this.painter.clear();\r
15387                 },\r
15388 \r
15389                 /**\r
15390                  * 释放当前ZR实例(删除包括dom,数据、显示和事件绑定),dispose后ZR不可用\r
15391                  */\r
15392                 dispose: function () {\r
15393                     this.animation.stop();\r
15394 \r
15395                     this.clear();\r
15396                     this.storage.dispose();\r
15397                     this.painter.dispose();\r
15398                     this.handler && this.handler.dispose();\r
15399 \r
15400                     this.animation =\r
15401                     this.storage =\r
15402                     this.painter =\r
15403                     this.handler = null;\r
15404 \r
15405                     delInstance(this.id);\r
15406                 }\r
15407             };\r
15408 \r
15409             module.exports = zrender;\r
15410 \r
15411 \r
15412 \r
15413 /***/ },\r
15414 /* 78 */\r
15415 /***/ function(module, exports) {\r
15416 \r
15417         /**\r
15418          * echarts设备环境识别\r
15419          *\r
15420          * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。\r
15421          * @author firede[firede@firede.us]\r
15422          * @desc thanks zepto.\r
15423          */\r
15424 \r
15425             var env = {};\r
15426             if (typeof navigator === 'undefined') {\r
15427                 // In node\r
15428                 env = {\r
15429                     browser: {},\r
15430                     os: {},\r
15431                     node: true,\r
15432                     // Assume canvas is supported\r
15433                     canvasSupported: true\r
15434                 };\r
15435             }\r
15436             else {\r
15437                 env = detect(navigator.userAgent);\r
15438             }\r
15439 \r
15440             module.exports = env;\r
15441 \r
15442             // Zepto.js\r
15443             // (c) 2010-2013 Thomas Fuchs\r
15444             // Zepto.js may be freely distributed under the MIT license.\r
15445 \r
15446             function detect(ua) {\r
15447                 var os = {};\r
15448                 var browser = {};\r
15449                 var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);\r
15450                 var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);\r
15451                 var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);\r
15452                 var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);\r
15453                 var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);\r
15454                 var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);\r
15455                 var touchpad = webos && ua.match(/TouchPad/);\r
15456                 var kindle = ua.match(/Kindle\/([\d.]+)/);\r
15457                 var silk = ua.match(/Silk\/([\d._]+)/);\r
15458                 var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);\r
15459                 var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);\r
15460                 var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);\r
15461                 var playbook = ua.match(/PlayBook/);\r
15462                 var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);\r
15463                 var firefox = ua.match(/Firefox\/([\d.]+)/);\r
15464                 var safari = webkit && ua.match(/Mobile\//) && !chrome;\r
15465                 var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;\r
15466                 var ie = ua.match(/MSIE\s([\d.]+)/)\r
15467                     // IE 11 Trident/7.0; rv:11.0\r
15468                     || ua.match(/Trident\/.+?rv:(([\d.]+))/);\r
15469                 var edge = ua.match(/Edge\/([\d.]+)/); // IE 12 and 12+\r
15470 \r
15471                 // Todo: clean this up with a better OS/browser seperation:\r
15472                 // - discern (more) between multiple browsers on android\r
15473                 // - decide if kindle fire in silk mode is android or not\r
15474                 // - Firefox on Android doesn't specify the Android version\r
15475                 // - possibly devide in os, device and browser hashes\r
15476 \r
15477                 if (browser.webkit = !!webkit) browser.version = webkit[1];\r
15478 \r
15479                 if (android) os.android = true, os.version = android[2];\r
15480                 if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.');\r
15481                 if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.');\r
15482                 if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;\r
15483                 if (webos) os.webos = true, os.version = webos[2];\r
15484                 if (touchpad) os.touchpad = true;\r
15485                 if (blackberry) os.blackberry = true, os.version = blackberry[2];\r
15486                 if (bb10) os.bb10 = true, os.version = bb10[2];\r
15487                 if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];\r
15488                 if (playbook) browser.playbook = true;\r
15489                 if (kindle) os.kindle = true, os.version = kindle[1];\r
15490                 if (silk) browser.silk = true, browser.version = silk[1];\r
15491                 if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;\r
15492                 if (chrome) browser.chrome = true, browser.version = chrome[1];\r
15493                 if (firefox) browser.firefox = true, browser.version = firefox[1];\r
15494                 if (ie) browser.ie = true, browser.version = ie[1];\r
15495                 if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;\r
15496                 if (webview) browser.webview = true;\r
15497                 if (ie) browser.ie = true, browser.version = ie[1];\r
15498                 if (edge) browser.edge = true, browser.version = edge[1];\r
15499 \r
15500                 os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||\r
15501                     (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));\r
15502                 os.phone  = !!(!os.tablet && !os.ipod && (android || iphone || webos || blackberry || bb10 ||\r
15503                     (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||\r
15504                     (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));\r
15505 \r
15506                 return {\r
15507                     browser: browser,\r
15508                     os: os,\r
15509                     node: false,\r
15510                     // 原生canvas支持,改极端点了\r
15511                     // canvasSupported : !(browser.ie && parseFloat(browser.version) < 9)\r
15512                     canvasSupported : document.createElement('canvas').getContext ? true : false,\r
15513                     // @see <http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript>\r
15514                     // works on most browsers\r
15515                     // IE10/11 does not support touch event, and MS Edge supports them but not by\r
15516                     // default, so we dont check navigator.maxTouchPoints for them here.\r
15517                     touchEventsSupported: 'ontouchstart' in window && !browser.ie && !browser.edge,\r
15518                     // <http://caniuse.com/#search=pointer%20event>.\r
15519                     pointerEventsSupported: 'onpointerdown' in window\r
15520                         // Firefox supports pointer but not by default,\r
15521                         // only MS browsers are reliable on pointer events currently.\r
15522                         && (browser.edge || (browser.ie && browser.version >= 10))\r
15523                 };\r
15524             }\r
15525 \r
15526 \r
15527 /***/ },\r
15528 /* 79 */\r
15529 /***/ function(module, exports, __webpack_require__) {\r
15530 \r
15531         'use strict';\r
15532         /**\r
15533          * Handler控制模块\r
15534          * @module zrender/Handler\r
15535          * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
15536          *         errorrik (errorrik@gmail.com)\r
15537          *         pissang (shenyi.914@gmail.com)\r
15538          */\r
15539 \r
15540 \r
15541             var env = __webpack_require__(78);\r
15542             var eventTool = __webpack_require__(80);\r
15543             var util = __webpack_require__(3);\r
15544             var Draggable = __webpack_require__(81);\r
15545             var GestureMgr = __webpack_require__(82);\r
15546 \r
15547             var Eventful = __webpack_require__(32);\r
15548 \r
15549             var mouseHandlerNames = [\r
15550                 'click', 'dblclick', 'mousewheel', 'mouseout'\r
15551             ];\r
15552             !usePointerEvent() && mouseHandlerNames.push(\r
15553                 'mouseup', 'mousedown', 'mousemove'\r
15554             );\r
15555 \r
15556             var touchHandlerNames = [\r
15557                 'touchstart', 'touchend', 'touchmove'\r
15558             ];\r
15559 \r
15560             var pointerHandlerNames = [\r
15561                 'pointerdown', 'pointerup', 'pointermove'\r
15562             ];\r
15563 \r
15564             var TOUCH_CLICK_DELAY = 300;\r
15565 \r
15566             // touch指尖错觉的尝试偏移量配置\r
15567             // var MOBILE_TOUCH_OFFSETS = [\r
15568             //     { x: 10 },\r
15569             //     { x: -20 },\r
15570             //     { x: 10, y: 10 },\r
15571             //     { y: -20 }\r
15572             // ];\r
15573 \r
15574             var addEventListener = eventTool.addEventListener;\r
15575             var removeEventListener = eventTool.removeEventListener;\r
15576             var normalizeEvent = eventTool.normalizeEvent;\r
15577 \r
15578             function makeEventPacket(eveType, target, event) {\r
15579                 return {\r
15580                     type: eveType,\r
15581                     event: event,\r
15582                     target: target,\r
15583                     cancelBubble: false,\r
15584                     offsetX: event.zrX,\r
15585                     offsetY: event.zrY,\r
15586                     gestureEvent: event.gestureEvent,\r
15587                     pinchX: event.pinchX,\r
15588                     pinchY: event.pinchY,\r
15589                     pinchScale: event.pinchScale,\r
15590                     wheelDelta: event.zrDelta\r
15591                 };\r
15592             }\r
15593 \r
15594             var domHandlers = {\r
15595                 /**\r
15596                  * Mouse move handler\r
15597                  * @inner\r
15598                  * @param {Event} event\r
15599                  */\r
15600                 mousemove: function (event) {\r
15601                     event = normalizeEvent(this.root, event);\r
15602 \r
15603                     var x = event.zrX;\r
15604                     var y = event.zrY;\r
15605 \r
15606                     var hovered = this.findHover(x, y, null);\r
15607                     var lastHovered = this._hovered;\r
15608 \r
15609                     this._hovered = hovered;\r
15610 \r
15611                     this.root.style.cursor = hovered ? hovered.cursor : this._defaultCursorStyle;\r
15612                     // Mouse out on previous hovered element\r
15613                     if (lastHovered && hovered !== lastHovered && lastHovered.__zr) {\r
15614                         this._dispatchProxy(lastHovered, 'mouseout', event);\r
15615                     }\r
15616 \r
15617                     // Mouse moving on one element\r
15618                     this._dispatchProxy(hovered, 'mousemove', event);\r
15619 \r
15620                     // Mouse over on a new element\r
15621                     if (hovered && hovered !== lastHovered) {\r
15622                         this._dispatchProxy(hovered, 'mouseover', event);\r
15623                     }\r
15624                 },\r
15625 \r
15626                 /**\r
15627                  * Mouse out handler\r
15628                  * @inner\r
15629                  * @param {Event} event\r
15630                  */\r
15631                 mouseout: function (event) {\r
15632                     event = normalizeEvent(this.root, event);\r
15633 \r
15634                     var element = event.toElement || event.relatedTarget;\r
15635                     if (element != this.root) {\r
15636                         while (element && element.nodeType != 9) {\r
15637                             // 忽略包含在root中的dom引起的mouseOut\r
15638                             if (element === this.root) {\r
15639                                 return;\r
15640                             }\r
15641 \r
15642                             element = element.parentNode;\r
15643                         }\r
15644                     }\r
15645 \r
15646                     this._dispatchProxy(this._hovered, 'mouseout', event);\r
15647 \r
15648                     this.trigger('globalout', {\r
15649                         event: event\r
15650                     });\r
15651                 },\r
15652 \r
15653                 /**\r
15654                  * Touch开始响应函数\r
15655                  * @inner\r
15656                  * @param {Event} event\r
15657                  */\r
15658                 touchstart: function (event) {\r
15659                     // FIXME\r
15660                     // 移动端可能需要default行为,例如静态图表时。\r
15661                     // eventTool.stop(event);// 阻止浏览器默认事件,重要\r
15662                     event = normalizeEvent(this.root, event);\r
15663 \r
15664                     this._lastTouchMoment = new Date();\r
15665 \r
15666                     processGesture(this, event, 'start');\r
15667 \r
15668                     // 平板补充一次findHover\r
15669                     // this._mobileFindFixed(event);\r
15670                     // Trigger mousemove and mousedown\r
15671                     domHandlers.mousemove.call(this, event);\r
15672 \r
15673                     domHandlers.mousedown.call(this, event);\r
15674 \r
15675                     setTouchTimer(this);\r
15676                 },\r
15677 \r
15678                 /**\r
15679                  * Touch移动响应函数\r
15680                  * @inner\r
15681                  * @param {Event} event\r
15682                  */\r
15683                 touchmove: function (event) {\r
15684                     // eventTool.stop(event);// 阻止浏览器默认事件,重要\r
15685                     event = normalizeEvent(this.root, event);\r
15686 \r
15687                     processGesture(this, event, 'change');\r
15688 \r
15689                     // Mouse move should always be triggered no matter whether\r
15690                     // there is gestrue event, because mouse move and pinch may\r
15691                     // be used at the same time.\r
15692                     domHandlers.mousemove.call(this, event);\r
15693 \r
15694                     setTouchTimer(this);\r
15695                 },\r
15696 \r
15697                 /**\r
15698                  * Touch结束响应函数\r
15699                  * @inner\r
15700                  * @param {Event} event\r
15701                  */\r
15702                 touchend: function (event) {\r
15703                     // eventTool.stop(event);// 阻止浏览器默认事件,重要\r
15704                     event = normalizeEvent(this.root, event);\r
15705 \r
15706                     processGesture(this, event, 'end');\r
15707 \r
15708                     domHandlers.mouseup.call(this, event);\r
15709 \r
15710                     // click event should always be triggered no matter whether\r
15711                     // there is gestrue event. System click can not be prevented.\r
15712                     if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {\r
15713                         // this._mobileFindFixed(event);\r
15714                         domHandlers.click.call(this, event);\r
15715                     }\r
15716 \r
15717                     setTouchTimer(this);\r
15718                 }\r
15719             };\r
15720 \r
15721             // Common handlers\r
15722             util.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick'], function (name) {\r
15723                 domHandlers[name] = function (event) {\r
15724                     event = normalizeEvent(this.root, event);\r
15725                     // Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover\r
15726                     var hovered = this.findHover(event.zrX, event.zrY, null);\r
15727                     this._dispatchProxy(hovered, name, event);\r
15728                 };\r
15729             });\r
15730 \r
15731             // Pointer event handlers\r
15732             // util.each(['pointerdown', 'pointermove', 'pointerup'], function (name) {\r
15733             //     domHandlers[name] = function (event) {\r
15734             //         var mouseName = name.replace('pointer', 'mouse');\r
15735             //         domHandlers[mouseName].call(this, event);\r
15736             //     };\r
15737             // });\r
15738 \r
15739             function processGesture(zrHandler, event, stage) {\r
15740                 var gestureMgr = zrHandler._gestureMgr;\r
15741 \r
15742                 stage === 'start' && gestureMgr.clear();\r
15743 \r
15744                 var gestureInfo = gestureMgr.recognize(\r
15745                     event,\r
15746                     zrHandler.findHover(event.zrX, event.zrY, null)\r
15747                 );\r
15748 \r
15749                 stage === 'end' && gestureMgr.clear();\r
15750 \r
15751                 if (gestureInfo) {\r
15752                     // eventTool.stop(event);\r
15753                     var type = gestureInfo.type;\r
15754                     event.gestureEvent = type;\r
15755 \r
15756                     zrHandler._dispatchProxy(gestureInfo.target, type, gestureInfo.event);\r
15757                 }\r
15758             }\r
15759 \r
15760             /**\r
15761              * 为控制类实例初始化dom 事件处理函数\r
15762              *\r
15763              * @inner\r
15764              * @param {module:zrender/Handler} instance 控制类实例\r
15765              */\r
15766             function initDomHandler(instance) {\r
15767                 var handlerNames = touchHandlerNames.concat(pointerHandlerNames);\r
15768                 for (var i = 0; i < handlerNames.length; i++) {\r
15769                     var name = handlerNames[i];\r
15770                     instance._handlers[name] = util.bind(domHandlers[name], instance);\r
15771                 }\r
15772 \r
15773                 for (var i = 0; i < mouseHandlerNames.length; i++) {\r
15774                     var name = mouseHandlerNames[i];\r
15775                     instance._handlers[name] = makeMouseHandler(domHandlers[name], instance);\r
15776                 }\r
15777 \r
15778                 function makeMouseHandler(fn, instance) {\r
15779                     return function () {\r
15780                         if (instance._touching) {\r
15781                             return;\r
15782                         }\r
15783                         return fn.apply(instance, arguments);\r
15784                     };\r
15785                 }\r
15786             }\r
15787 \r
15788             /**\r
15789              * @alias module:zrender/Handler\r
15790              * @constructor\r
15791              * @extends module:zrender/mixin/Eventful\r
15792              * @param {HTMLElement} root Main HTML element for painting.\r
15793              * @param {module:zrender/Storage} storage Storage instance.\r
15794              * @param {module:zrender/Painter} painter Painter instance.\r
15795              */\r
15796             var Handler = function(root, storage, painter) {\r
15797                 Eventful.call(this);\r
15798 \r
15799                 this.root = root;\r
15800                 this.storage = storage;\r
15801                 this.painter = painter;\r
15802 \r
15803                 /**\r
15804                  * @private\r
15805                  * @type {boolean}\r
15806                  */\r
15807                 this._hovered;\r
15808 \r
15809                 /**\r
15810                  * @private\r
15811                  * @type {Date}\r
15812                  */\r
15813                 this._lastTouchMoment;\r
15814 \r
15815                 /**\r
15816                  * @private\r
15817                  * @type {number}\r
15818                  */\r
15819                 this._lastX;\r
15820 \r
15821                 /**\r
15822                  * @private\r
15823                  * @type {number}\r
15824                  */\r
15825                 this._lastY;\r
15826 \r
15827                 /**\r
15828                  * @private\r
15829                  * @type {string}\r
15830                  */\r
15831                 this._defaultCursorStyle = 'default';\r
15832 \r
15833                 /**\r
15834                  * @private\r
15835                  * @type {module:zrender/core/GestureMgr}\r
15836                  */\r
15837                 this._gestureMgr = new GestureMgr();\r
15838 \r
15839                 /**\r
15840                  * @private\r
15841                  * @type {Array.<Function>}\r
15842                  */\r
15843                 this._handlers = [];\r
15844 \r
15845                 /**\r
15846                  * @private\r
15847                  * @type {boolean}\r
15848                  */\r
15849                 this._touching = false;\r
15850 \r
15851                 /**\r
15852                  * @private\r
15853                  * @type {number}\r
15854                  */\r
15855                 this._touchTimer;\r
15856 \r
15857                 initDomHandler(this);\r
15858 \r
15859                 if (usePointerEvent()) {\r
15860                     mountHandlers(pointerHandlerNames, this);\r
15861                 }\r
15862                 else if (useTouchEvent()) {\r
15863                     mountHandlers(touchHandlerNames, this);\r
15864 \r
15865                     // Handler of 'mouseout' event is needed in touch mode, which will be mounted below.\r
15866                     // addEventListener(root, 'mouseout', this._mouseoutHandler);\r
15867                 }\r
15868 \r
15869                 // Considering some devices that both enable touch and mouse event (like MS Surface\r
15870                 // and lenovo X240, @see #2350), we make mouse event be always listened, otherwise\r
15871                 // mouse event can not be handle in those devices.\r
15872                 mountHandlers(mouseHandlerNames, this);\r
15873 \r
15874                 Draggable.call(this);\r
15875 \r
15876                 function mountHandlers(handlerNames, instance) {\r
15877                     util.each(handlerNames, function (name) {\r
15878                         addEventListener(root, eventNameFix(name), instance._handlers[name]);\r
15879                     }, instance);\r
15880                 }\r
15881             };\r
15882 \r
15883             Handler.prototype = {\r
15884 \r
15885                 constructor: Handler,\r
15886 \r
15887                 /**\r
15888                  * Resize\r
15889                  */\r
15890                 resize: function (event) {\r
15891                     this._hovered = null;\r
15892                 },\r
15893 \r
15894                 /**\r
15895                  * Dispatch event\r
15896                  * @param {string} eventName\r
15897                  * @param {event=} eventArgs\r
15898                  */\r
15899                 dispatch: function (eventName, eventArgs) {\r
15900                     var handler = this._handlers[eventName];\r
15901                     handler && handler.call(this, eventArgs);\r
15902                 },\r
15903 \r
15904                 /**\r
15905                  * Dispose\r
15906                  */\r
15907                 dispose: function () {\r
15908                     var root = this.root;\r
15909 \r
15910                     var handlerNames = mouseHandlerNames.concat(touchHandlerNames);\r
15911 \r
15912                     for (var i = 0; i < handlerNames.length; i++) {\r
15913                         var name = handlerNames[i];\r
15914                         removeEventListener(root, eventNameFix(name), this._handlers[name]);\r
15915                     }\r
15916 \r
15917                     this.root =\r
15918                     this.storage =\r
15919                     this.painter = null;\r
15920                 },\r
15921 \r
15922                 /**\r
15923                  * 设置默认的cursor style\r
15924                  * @param {string} cursorStyle 例如 crosshair\r
15925                  */\r
15926                 setDefaultCursorStyle: function (cursorStyle) {\r
15927                     this._defaultCursorStyle = cursorStyle;\r
15928                 },\r
15929 \r
15930                 /**\r
15931                  * 事件分发代理\r
15932                  *\r
15933                  * @private\r
15934                  * @param {Object} targetEl 目标图形元素\r
15935                  * @param {string} eventName 事件名称\r
15936                  * @param {Object} event 事件对象\r
15937                  */\r
15938                 _dispatchProxy: function (targetEl, eventName, event) {\r
15939                     var eventHandler = 'on' + eventName;\r
15940                     var eventPacket = makeEventPacket(eventName, targetEl, event);\r
15941 \r
15942                     var el = targetEl;\r
15943 \r
15944                     while (el) {\r
15945                         el[eventHandler]\r
15946                             && (eventPacket.cancelBubble = el[eventHandler].call(el, eventPacket));\r
15947 \r
15948                         el.trigger(eventName, eventPacket);\r
15949 \r
15950                         el = el.parent;\r
15951 \r
15952                         if (eventPacket.cancelBubble) {\r
15953                             break;\r
15954                         }\r
15955                     }\r
15956 \r
15957                     if (!eventPacket.cancelBubble) {\r
15958                         // 冒泡到顶级 zrender 对象\r
15959                         this.trigger(eventName, eventPacket);\r
15960                         // 分发事件到用户自定义层\r
15961                         // 用户有可能在全局 click 事件中 dispose,所以需要判断下 painter 是否存在\r
15962                         this.painter && this.painter.eachOtherLayer(function (layer) {\r
15963                             if (typeof(layer[eventHandler]) == 'function') {\r
15964                                 layer[eventHandler].call(layer, eventPacket);\r
15965                             }\r
15966                             if (layer.trigger) {\r
15967                                 layer.trigger(eventName, eventPacket);\r
15968                             }\r
15969                         });\r
15970                     }\r
15971                 },\r
15972 \r
15973                 /**\r
15974                  * @private\r
15975                  * @param {number} x\r
15976                  * @param {number} y\r
15977                  * @param {module:zrender/graphic/Displayable} exclude\r
15978                  * @method\r
15979                  */\r
15980                 findHover: function(x, y, exclude) {\r
15981                     var list = this.storage.getDisplayList();\r
15982                     for (var i = list.length - 1; i >= 0 ; i--) {\r
15983                         if (!list[i].silent\r
15984                          && list[i] !== exclude\r
15985                          // getDisplayList may include ignored item in VML mode\r
15986                          && !list[i].ignore\r
15987                          && isHover(list[i], x, y)) {\r
15988                             return list[i];\r
15989                         }\r
15990                     }\r
15991                 }\r
15992             };\r
15993 \r
15994             function isHover(displayable, x, y) {\r
15995                 if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {\r
15996                     var p = displayable.parent;\r
15997                     while (p) {\r
15998                         if (p.clipPath && !p.clipPath.contain(x, y))  {\r
15999                             // Clipped by parents\r
16000                             return false;\r
16001                         }\r
16002                         p = p.parent;\r
16003                     }\r
16004                     return true;\r
16005                 }\r
16006 \r
16007                 return false;\r
16008             }\r
16009 \r
16010             /**\r
16011              * Prevent mouse event from being dispatched after Touch Events action\r
16012              * @see <https://github.com/deltakosh/handjs/blob/master/src/hand.base.js>\r
16013              * 1. Mobile browsers dispatch mouse events 300ms after touchend.\r
16014              * 2. Chrome for Android dispatch mousedown for long-touch about 650ms\r
16015              * Result: Blocking Mouse Events for 700ms.\r
16016              */\r
16017             function setTouchTimer(instance) {\r
16018                 instance._touching = true;\r
16019                 clearTimeout(instance._touchTimer);\r
16020                 instance._touchTimer = setTimeout(function () {\r
16021                     instance._touching = false;\r
16022                 }, 700);\r
16023             }\r
16024 \r
16025             /**\r
16026              * Althought MS Surface support screen touch, IE10/11 do not support\r
16027              * touch event and MS Edge supported them but not by default (but chrome\r
16028              * and firefox do). Thus we use Pointer event on MS browsers to handle touch.\r
16029              */\r
16030             function usePointerEvent() {\r
16031                 // TODO\r
16032                 // pointermove event dont trigger when using finger.\r
16033                 // We may figger it out latter.\r
16034                 return false;\r
16035                 // return env.pointerEventsSupported\r
16036                     // In no-touch device we dont use pointer evnets but just\r
16037                     // use mouse event for avoiding problems.\r
16038                     // && window.navigator.maxTouchPoints;\r
16039             }\r
16040 \r
16041             function useTouchEvent() {\r
16042                 return env.touchEventsSupported;\r
16043             }\r
16044 \r
16045             function eventNameFix(name) {\r
16046                 return (name === 'mousewheel' && env.browser.firefox) ? 'DOMMouseScroll' : name;\r
16047             }\r
16048 \r
16049             util.mixin(Handler, Eventful);\r
16050             util.mixin(Handler, Draggable);\r
16051 \r
16052             module.exports = Handler;\r
16053 \r
16054 \r
16055 /***/ },\r
16056 /* 80 */\r
16057 /***/ function(module, exports, __webpack_require__) {\r
16058 \r
16059         'use strict';\r
16060         /**\r
16061          * 事件辅助类\r
16062          * @module zrender/core/event\r
16063          * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
16064          */\r
16065 \r
16066 \r
16067             var Eventful = __webpack_require__(32);\r
16068 \r
16069             var isDomLevel2 = (typeof window !== 'undefined') && !!window.addEventListener;\r
16070 \r
16071             function getBoundingClientRect(el) {\r
16072                 // BlackBerry 5, iOS 3 (original iPhone) don't have getBoundingRect\r
16073                 return el.getBoundingClientRect ? el.getBoundingClientRect() : { left: 0, top: 0};\r
16074             }\r
16075             /**\r
16076              * 如果存在第三方嵌入的一些dom触发的事件,或touch事件,需要转换一下事件坐标\r
16077              */\r
16078             function normalizeEvent(el, e) {\r
16079 \r
16080                 e = e || window.event;\r
16081 \r
16082                 if (e.zrX != null) {\r
16083                     return e;\r
16084                 }\r
16085 \r
16086                 var eventType = e.type;\r
16087                 var isTouch = eventType && eventType.indexOf('touch') >= 0;\r
16088 \r
16089                 if (!isTouch) {\r
16090                     var box = getBoundingClientRect(el);\r
16091                     e.zrX = e.clientX - box.left;\r
16092                     e.zrY = e.clientY - box.top;\r
16093                     e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;\r
16094                 }\r
16095                 else {\r
16096                     var touch = eventType != 'touchend'\r
16097                                     ? e.targetTouches[0]\r
16098                                     : e.changedTouches[0];\r
16099                     if (touch) {\r
16100                         var rBounding = getBoundingClientRect(el);\r
16101                         // touch事件坐标是全屏的~\r
16102                         e.zrX = touch.clientX - rBounding.left;\r
16103                         e.zrY = touch.clientY - rBounding.top;\r
16104                     }\r
16105                 }\r
16106 \r
16107                 return e;\r
16108             }\r
16109 \r
16110             function addEventListener(el, name, handler) {\r
16111                 if (isDomLevel2) {\r
16112                     el.addEventListener(name, handler);\r
16113                 }\r
16114                 else {\r
16115                     el.attachEvent('on' + name, handler);\r
16116                 }\r
16117             }\r
16118 \r
16119             function removeEventListener(el, name, handler) {\r
16120                 if (isDomLevel2) {\r
16121                     el.removeEventListener(name, handler);\r
16122                 }\r
16123                 else {\r
16124                     el.detachEvent('on' + name, handler);\r
16125                 }\r
16126             }\r
16127 \r
16128             /**\r
16129              * 停止冒泡和阻止默认行为\r
16130              * @memberOf module:zrender/core/event\r
16131              * @method\r
16132              * @param {Event} e : event对象\r
16133              */\r
16134             var stop = isDomLevel2\r
16135                 ? function (e) {\r
16136                     e.preventDefault();\r
16137                     e.stopPropagation();\r
16138                     e.cancelBubble = true;\r
16139                 }\r
16140                 : function (e) {\r
16141                     e.returnValue = false;\r
16142                     e.cancelBubble = true;\r
16143                 };\r
16144 \r
16145             module.exports = {\r
16146                 normalizeEvent: normalizeEvent,\r
16147                 addEventListener: addEventListener,\r
16148                 removeEventListener: removeEventListener,\r
16149 \r
16150                 stop: stop,\r
16151                 // 做向上兼容\r
16152                 Dispatcher: Eventful\r
16153             };\r
16154 \r
16155 \r
16156 \r
16157 /***/ },\r
16158 /* 81 */\r
16159 /***/ function(module, exports) {\r
16160 \r
16161         // TODO Draggable for group\r
16162         // FIXME Draggable on element which has parent rotation or scale\r
16163 \r
16164             function Draggable() {\r
16165 \r
16166                 this.on('mousedown', this._dragStart, this);\r
16167                 this.on('mousemove', this._drag, this);\r
16168                 this.on('mouseup', this._dragEnd, this);\r
16169                 this.on('globalout', this._dragEnd, this);\r
16170                 // this._dropTarget = null;\r
16171                 // this._draggingTarget = null;\r
16172 \r
16173                 // this._x = 0;\r
16174                 // this._y = 0;\r
16175             }\r
16176 \r
16177             Draggable.prototype = {\r
16178 \r
16179                 constructor: Draggable,\r
16180 \r
16181                 _dragStart: function (e) {\r
16182                     var draggingTarget = e.target;\r
16183                     if (draggingTarget && draggingTarget.draggable) {\r
16184                         this._draggingTarget = draggingTarget;\r
16185                         draggingTarget.dragging = true;\r
16186                         this._x = e.offsetX;\r
16187                         this._y = e.offsetY;\r
16188 \r
16189                         this._dispatchProxy(draggingTarget, 'dragstart', e.event);\r
16190                     }\r
16191                 },\r
16192 \r
16193                 _drag: function (e) {\r
16194                     var draggingTarget = this._draggingTarget;\r
16195                     if (draggingTarget) {\r
16196 \r
16197                         var x = e.offsetX;\r
16198                         var y = e.offsetY;\r
16199 \r
16200                         var dx = x - this._x;\r
16201                         var dy = y - this._y;\r
16202                         this._x = x;\r
16203                         this._y = y;\r
16204 \r
16205                         draggingTarget.drift(dx, dy, e);\r
16206                         this._dispatchProxy(draggingTarget, 'drag', e.event);\r
16207 \r
16208                         var dropTarget = this.findHover(x, y, draggingTarget);\r
16209                         var lastDropTarget = this._dropTarget;\r
16210                         this._dropTarget = dropTarget;\r
16211 \r
16212                         if (draggingTarget !== dropTarget) {\r
16213                             if (lastDropTarget && dropTarget !== lastDropTarget) {\r
16214                                 this._dispatchProxy(lastDropTarget, 'dragleave', e.event);\r
16215                             }\r
16216                             if (dropTarget && dropTarget !== lastDropTarget) {\r
16217                                 this._dispatchProxy(dropTarget, 'dragenter', e.event);\r
16218                             }\r
16219                         }\r
16220                     }\r
16221                 },\r
16222 \r
16223                 _dragEnd: function (e) {\r
16224                     var draggingTarget = this._draggingTarget;\r
16225 \r
16226                     if (draggingTarget) {\r
16227                         draggingTarget.dragging = false;\r
16228                     }\r
16229 \r
16230                     this._dispatchProxy(draggingTarget, 'dragend', e.event);\r
16231 \r
16232                     if (this._dropTarget) {\r
16233                         this._dispatchProxy(this._dropTarget, 'drop', e.event);\r
16234                     }\r
16235 \r
16236                     this._draggingTarget = null;\r
16237                     this._dropTarget = null;\r
16238                 }\r
16239 \r
16240             };\r
16241 \r
16242             module.exports = Draggable;\r
16243 \r
16244 \r
16245 /***/ },\r
16246 /* 82 */\r
16247 /***/ function(module, exports) {\r
16248 \r
16249         'use strict';\r
16250         /**\r
16251          * Only implements needed gestures for mobile.\r
16252          */\r
16253 \r
16254 \r
16255             var GestureMgr = function () {\r
16256 \r
16257                 /**\r
16258                  * @private\r
16259                  * @type {Array.<Object>}\r
16260                  */\r
16261                 this._track = [];\r
16262             };\r
16263 \r
16264             GestureMgr.prototype = {\r
16265 \r
16266                 constructor: GestureMgr,\r
16267 \r
16268                 recognize: function (event, target) {\r
16269                     this._doTrack(event, target);\r
16270                     return this._recognize(event);\r
16271                 },\r
16272 \r
16273                 clear: function () {\r
16274                     this._track.length = 0;\r
16275                     return this;\r
16276                 },\r
16277 \r
16278                 _doTrack: function (event, target) {\r
16279                     var touches = event.touches;\r
16280 \r
16281                     if (!touches) {\r
16282                         return;\r
16283                     }\r
16284 \r
16285                     var trackItem = {\r
16286                         points: [],\r
16287                         touches: [],\r
16288                         target: target,\r
16289                         event: event\r
16290                     };\r
16291 \r
16292                     for (var i = 0, len = touches.length; i < len; i++) {\r
16293                         var touch = touches[i];\r
16294                         trackItem.points.push([touch.clientX, touch.clientY]);\r
16295                         trackItem.touches.push(touch);\r
16296                     }\r
16297 \r
16298                     this._track.push(trackItem);\r
16299                 },\r
16300 \r
16301                 _recognize: function (event) {\r
16302                     for (var eventName in recognizers) {\r
16303                         if (recognizers.hasOwnProperty(eventName)) {\r
16304                             var gestureInfo = recognizers[eventName](this._track, event);\r
16305                             if (gestureInfo) {\r
16306                                 return gestureInfo;\r
16307                             }\r
16308                         }\r
16309                     }\r
16310                 }\r
16311             };\r
16312 \r
16313             function dist(pointPair) {\r
16314                 var dx = pointPair[1][0] - pointPair[0][0];\r
16315                 var dy = pointPair[1][1] - pointPair[0][1];\r
16316 \r
16317                 return Math.sqrt(dx * dx + dy * dy);\r
16318             }\r
16319 \r
16320             function center(pointPair) {\r
16321                 return [\r
16322                     (pointPair[0][0] + pointPair[1][0]) / 2,\r
16323                     (pointPair[0][1] + pointPair[1][1]) / 2\r
16324                 ];\r
16325             }\r
16326 \r
16327             var recognizers = {\r
16328 \r
16329                 pinch: function (track, event) {\r
16330                     var trackLen = track.length;\r
16331 \r
16332                     if (!trackLen) {\r
16333                         return;\r
16334                     }\r
16335 \r
16336                     var pinchEnd = (track[trackLen - 1] || {}).points;\r
16337                     var pinchPre = (track[trackLen - 2] || {}).points || pinchEnd;\r
16338 \r
16339                     if (pinchPre\r
16340                         && pinchPre.length > 1\r
16341                         && pinchEnd\r
16342                         && pinchEnd.length > 1\r
16343                     ) {\r
16344                         var pinchScale = dist(pinchEnd) / dist(pinchPre);\r
16345                         !isFinite(pinchScale) && (pinchScale = 1);\r
16346 \r
16347                         event.pinchScale = pinchScale;\r
16348 \r
16349                         var pinchCenter = center(pinchEnd);\r
16350                         event.pinchX = pinchCenter[0];\r
16351                         event.pinchY = pinchCenter[1];\r
16352 \r
16353                         return {\r
16354                             type: 'pinch',\r
16355                             target: track[0].target,\r
16356                             event: event\r
16357                         };\r
16358                     }\r
16359                 }\r
16360 \r
16361                 // Only pinch currently.\r
16362             };\r
16363 \r
16364             module.exports = GestureMgr;\r
16365 \r
16366 \r
16367 \r
16368 /***/ },\r
16369 /* 83 */\r
16370 /***/ function(module, exports, __webpack_require__) {\r
16371 \r
16372         'use strict';\r
16373         /**\r
16374          * Storage内容仓库模块\r
16375          * @module zrender/Storage\r
16376          * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
16377          * @author errorrik (errorrik@gmail.com)\r
16378          * @author pissang (https://github.com/pissang/)\r
16379          */\r
16380 \r
16381 \r
16382             var util = __webpack_require__(3);\r
16383 \r
16384             var Group = __webpack_require__(29);\r
16385 \r
16386             function shapeCompareFunc(a, b) {\r
16387                 if (a.zlevel === b.zlevel) {\r
16388                     if (a.z === b.z) {\r
16389                         if (a.z2 === b.z2) {\r
16390                             return a.__renderidx - b.__renderidx;\r
16391                         }\r
16392                         return a.z2 - b.z2;\r
16393                     }\r
16394                     return a.z - b.z;\r
16395                 }\r
16396                 return a.zlevel - b.zlevel;\r
16397             }\r
16398             /**\r
16399              * 内容仓库 (M)\r
16400              * @alias module:zrender/Storage\r
16401              * @constructor\r
16402              */\r
16403             var Storage = function () {\r
16404                 // 所有常规形状,id索引的map\r
16405                 this._elements = {};\r
16406 \r
16407                 this._roots = [];\r
16408 \r
16409                 this._displayList = [];\r
16410 \r
16411                 this._displayListLen = 0;\r
16412             };\r
16413 \r
16414             Storage.prototype = {\r
16415 \r
16416                 constructor: Storage,\r
16417 \r
16418                 /**\r
16419                  * 返回所有图形的绘制队列\r
16420                  * @param {boolean} [update=false] 是否在返回前更新该数组\r
16421                  * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组, 在 update 为 true 的时候有效\r
16422                  *\r
16423                  * 详见{@link module:zrender/graphic/Displayable.prototype.updateDisplayList}\r
16424                  * @return {Array.<module:zrender/graphic/Displayable>}\r
16425                  */\r
16426                 getDisplayList: function (update, includeIgnore) {\r
16427                     includeIgnore = includeIgnore || false;\r
16428                     if (update) {\r
16429                         this.updateDisplayList(includeIgnore);\r
16430                     }\r
16431                     return this._displayList;\r
16432                 },\r
16433 \r
16434                 /**\r
16435                  * 更新图形的绘制队列。\r
16436                  * 每次绘制前都会调用,该方法会先深度优先遍历整个树,更新所有Group和Shape的变换并且把所有可见的Shape保存到数组中,\r
16437                  * 最后根据绘制的优先级(zlevel > z > 插入顺序)排序得到绘制队列\r
16438                  * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组\r
16439                  */\r
16440                 updateDisplayList: function (includeIgnore) {\r
16441                     this._displayListLen = 0;\r
16442                     var roots = this._roots;\r
16443                     var displayList = this._displayList;\r
16444                     for (var i = 0, len = roots.length; i < len; i++) {\r
16445                         this._updateAndAddDisplayable(roots[i], null, includeIgnore);\r
16446                     }\r
16447                     displayList.length = this._displayListLen;\r
16448 \r
16449                     for (var i = 0, len = displayList.length; i < len; i++) {\r
16450                         displayList[i].__renderidx = i;\r
16451                     }\r
16452 \r
16453                     displayList.sort(shapeCompareFunc);\r
16454                 },\r
16455 \r
16456                 _updateAndAddDisplayable: function (el, clipPaths, includeIgnore) {\r
16457 \r
16458                     if (el.ignore && !includeIgnore) {\r
16459                         return;\r
16460                     }\r
16461 \r
16462                     el.beforeUpdate();\r
16463 \r
16464                     el.update();\r
16465 \r
16466                     el.afterUpdate();\r
16467 \r
16468                     var clipPath = el.clipPath;\r
16469                     if (clipPath) {\r
16470                         // clipPath 的变换是基于 group 的变换\r
16471                         clipPath.parent = el;\r
16472                         clipPath.updateTransform();\r
16473 \r
16474                         // FIXME 效率影响\r
16475                         if (clipPaths) {\r
16476                             clipPaths = clipPaths.slice();\r
16477                             clipPaths.push(clipPath);\r
16478                         }\r
16479                         else {\r
16480                             clipPaths = [clipPath];\r
16481                         }\r
16482                     }\r
16483 \r
16484                     if (el.type == 'group') {\r
16485                         var children = el._children;\r
16486 \r
16487                         for (var i = 0; i < children.length; i++) {\r
16488                             var child = children[i];\r
16489 \r
16490                             // Force to mark as dirty if group is dirty\r
16491                             // FIXME __dirtyPath ?\r
16492                             child.__dirty = el.__dirty || child.__dirty;\r
16493 \r
16494                             this._updateAndAddDisplayable(child, clipPaths, includeIgnore);\r
16495                         }\r
16496 \r
16497                         // Mark group clean here\r
16498                         el.__dirty = false;\r
16499 \r
16500                     }\r
16501                     else {\r
16502                         el.__clipPaths = clipPaths;\r
16503 \r
16504                         this._displayList[this._displayListLen++] = el;\r
16505                     }\r
16506                 },\r
16507 \r
16508                 /**\r
16509                  * 添加图形(Shape)或者组(Group)到根节点\r
16510                  * @param {module:zrender/Element} el\r
16511                  */\r
16512                 addRoot: function (el) {\r
16513                     // Element has been added\r
16514                     if (this._elements[el.id]) {\r
16515                         return;\r
16516                     }\r
16517 \r
16518                     if (el instanceof Group) {\r
16519                         el.addChildrenToStorage(this);\r
16520                     }\r
16521 \r
16522                     this.addToMap(el);\r
16523                     this._roots.push(el);\r
16524                 },\r
16525 \r
16526                 /**\r
16527                  * 删除指定的图形(Shape)或者组(Group)\r
16528                  * @param {string|Array.<string>} [elId] 如果为空清空整个Storage\r
16529                  */\r
16530                 delRoot: function (elId) {\r
16531                     if (elId == null) {\r
16532                         // 不指定elId清空\r
16533                         for (var i = 0; i < this._roots.length; i++) {\r
16534                             var root = this._roots[i];\r
16535                             if (root instanceof Group) {\r
16536                                 root.delChildrenFromStorage(this);\r
16537                             }\r
16538                         }\r
16539 \r
16540                         this._elements = {};\r
16541                         this._roots = [];\r
16542                         this._displayList = [];\r
16543                         this._displayListLen = 0;\r
16544 \r
16545                         return;\r
16546                     }\r
16547 \r
16548                     if (elId instanceof Array) {\r
16549                         for (var i = 0, l = elId.length; i < l; i++) {\r
16550                             this.delRoot(elId[i]);\r
16551                         }\r
16552                         return;\r
16553                     }\r
16554 \r
16555                     var el;\r
16556                     if (typeof(elId) == 'string') {\r
16557                         el = this._elements[elId];\r
16558                     }\r
16559                     else {\r
16560                         el = elId;\r
16561                     }\r
16562 \r
16563                     var idx = util.indexOf(this._roots, el);\r
16564                     if (idx >= 0) {\r
16565                         this.delFromMap(el.id);\r
16566                         this._roots.splice(idx, 1);\r
16567                         if (el instanceof Group) {\r
16568                             el.delChildrenFromStorage(this);\r
16569                         }\r
16570                     }\r
16571                 },\r
16572 \r
16573                 addToMap: function (el) {\r
16574                     if (el instanceof Group) {\r
16575                         el.__storage = this;\r
16576                     }\r
16577                     el.dirty();\r
16578 \r
16579                     this._elements[el.id] = el;\r
16580 \r
16581                     return this;\r
16582                 },\r
16583 \r
16584                 get: function (elId) {\r
16585                     return this._elements[elId];\r
16586                 },\r
16587 \r
16588                 delFromMap: function (elId) {\r
16589                     var elements = this._elements;\r
16590                     var el = elements[elId];\r
16591                     if (el) {\r
16592                         delete elements[elId];\r
16593                         if (el instanceof Group) {\r
16594                             el.__storage = null;\r
16595                         }\r
16596                     }\r
16597 \r
16598                     return this;\r
16599                 },\r
16600 \r
16601                 /**\r
16602                  * 清空并且释放Storage\r
16603                  */\r
16604                 dispose: function () {\r
16605                     this._elements =\r
16606                     this._renderList =\r
16607                     this._roots = null;\r
16608                 }\r
16609             };\r
16610 \r
16611             module.exports = Storage;\r
16612 \r
16613 \r
16614 \r
16615 /***/ },\r
16616 /* 84 */\r
16617 /***/ function(module, exports, __webpack_require__) {\r
16618 \r
16619         'use strict';\r
16620         /**\r
16621          * 动画主类, 调度和管理所有动画控制器\r
16622          *\r
16623          * @module zrender/animation/Animation\r
16624          * @author pissang(https://github.com/pissang)\r
16625          */\r
16626         // TODO Additive animation\r
16627         // http://iosoteric.com/additive-animations-animatewithduration-in-ios-8/\r
16628         // https://developer.apple.com/videos/wwdc2014/#236\r
16629 \r
16630 \r
16631             var util = __webpack_require__(3);\r
16632             var Dispatcher = __webpack_require__(80).Dispatcher;\r
16633 \r
16634             var requestAnimationFrame = (typeof window !== 'undefined' &&\r
16635                                             (window.requestAnimationFrame\r
16636                                             || window.msRequestAnimationFrame\r
16637                                             || window.mozRequestAnimationFrame\r
16638                                             || window.webkitRequestAnimationFrame))\r
16639                                         || function (func) {\r
16640                                             setTimeout(func, 16);\r
16641                                         };\r
16642 \r
16643             var Animator = __webpack_require__(35);\r
16644             /**\r
16645              * @typedef {Object} IZRenderStage\r
16646              * @property {Function} update\r
16647              */\r
16648 \r
16649             /**\r
16650              * @alias module:zrender/animation/Animation\r
16651              * @constructor\r
16652              * @param {Object} [options]\r
16653              * @param {Function} [options.onframe]\r
16654              * @param {IZRenderStage} [options.stage]\r
16655              * @example\r
16656              *     var animation = new Animation();\r
16657              *     var obj = {\r
16658              *         x: 100,\r
16659              *         y: 100\r
16660              *     };\r
16661              *     animation.animate(node.position)\r
16662              *         .when(1000, {\r
16663              *             x: 500,\r
16664              *             y: 500\r
16665              *         })\r
16666              *         .when(2000, {\r
16667              *             x: 100,\r
16668              *             y: 100\r
16669              *         })\r
16670              *         .start('spline');\r
16671              */\r
16672             var Animation = function (options) {\r
16673 \r
16674                 options = options || {};\r
16675 \r
16676                 this.stage = options.stage || {};\r
16677 \r
16678                 this.onframe = options.onframe || function() {};\r
16679 \r
16680                 // private properties\r
16681                 this._clips = [];\r
16682 \r
16683                 this._running = false;\r
16684 \r
16685                 this._time = 0;\r
16686 \r
16687                 Dispatcher.call(this);\r
16688             };\r
16689 \r
16690             Animation.prototype = {\r
16691 \r
16692                 constructor: Animation,\r
16693                 /**\r
16694                  * 添加 clip\r
16695                  * @param {module:zrender/animation/Clip} clip\r
16696                  */\r
16697                 addClip: function (clip) {\r
16698                     this._clips.push(clip);\r
16699                 },\r
16700                 /**\r
16701                  * 添加 animator\r
16702                  * @param {module:zrender/animation/Animator} animator\r
16703                  */\r
16704                 addAnimator: function (animator) {\r
16705                     animator.animation = this;\r
16706                     var clips = animator.getClips();\r
16707                     for (var i = 0; i < clips.length; i++) {\r
16708                         this.addClip(clips[i]);\r
16709                     }\r
16710                 },\r
16711                 /**\r
16712                  * 删除动画片段\r
16713                  * @param {module:zrender/animation/Clip} clip\r
16714                  */\r
16715                 removeClip: function(clip) {\r
16716                     var idx = util.indexOf(this._clips, clip);\r
16717                     if (idx >= 0) {\r
16718                         this._clips.splice(idx, 1);\r
16719                     }\r
16720                 },\r
16721 \r
16722                 /**\r
16723                  * 删除动画片段\r
16724                  * @param {module:zrender/animation/Animator} animator\r
16725                  */\r
16726                 removeAnimator: function (animator) {\r
16727                     var clips = animator.getClips();\r
16728                     for (var i = 0; i < clips.length; i++) {\r
16729                         this.removeClip(clips[i]);\r
16730                     }\r
16731                     animator.animation = null;\r
16732                 },\r
16733 \r
16734                 _update: function() {\r
16735 \r
16736                     var time = new Date().getTime();\r
16737                     var delta = time - this._time;\r
16738                     var clips = this._clips;\r
16739                     var len = clips.length;\r
16740 \r
16741                     var deferredEvents = [];\r
16742                     var deferredClips = [];\r
16743                     for (var i = 0; i < len; i++) {\r
16744                         var clip = clips[i];\r
16745                         var e = clip.step(time);\r
16746                         // Throw out the events need to be called after\r
16747                         // stage.update, like destroy\r
16748                         if (e) {\r
16749                             deferredEvents.push(e);\r
16750                             deferredClips.push(clip);\r
16751                         }\r
16752                     }\r
16753 \r
16754                     // Remove the finished clip\r
16755                     for (var i = 0; i < len;) {\r
16756                         if (clips[i]._needsRemove) {\r
16757                             clips[i] = clips[len - 1];\r
16758                             clips.pop();\r
16759                             len--;\r
16760                         }\r
16761                         else {\r
16762                             i++;\r
16763                         }\r
16764                     }\r
16765 \r
16766                     len = deferredEvents.length;\r
16767                     for (var i = 0; i < len; i++) {\r
16768                         deferredClips[i].fire(deferredEvents[i]);\r
16769                     }\r
16770 \r
16771                     this._time = time;\r
16772 \r
16773                     this.onframe(delta);\r
16774 \r
16775                     this.trigger('frame', delta);\r
16776 \r
16777                     if (this.stage.update) {\r
16778                         this.stage.update();\r
16779                     }\r
16780                 },\r
16781                 /**\r
16782                  * 开始运行动画\r
16783                  */\r
16784                 start: function () {\r
16785                     var self = this;\r
16786 \r
16787                     this._running = true;\r
16788 \r
16789                     function step() {\r
16790                         if (self._running) {\r
16791 \r
16792                             requestAnimationFrame(step);\r
16793 \r
16794                             self._update();\r
16795                         }\r
16796                     }\r
16797 \r
16798                     this._time = new Date().getTime();\r
16799                     requestAnimationFrame(step);\r
16800                 },\r
16801                 /**\r
16802                  * 停止运行动画\r
16803                  */\r
16804                 stop: function () {\r
16805                     this._running = false;\r
16806                 },\r
16807                 /**\r
16808                  * 清除所有动画片段\r
16809                  */\r
16810                 clear: function () {\r
16811                     this._clips = [];\r
16812                 },\r
16813                 /**\r
16814                  * 对一个目标创建一个animator对象,可以指定目标中的属性使用动画\r
16815                  * @param  {Object} target\r
16816                  * @param  {Object} options\r
16817                  * @param  {boolean} [options.loop=false] 是否循环播放动画\r
16818                  * @param  {Function} [options.getter=null]\r
16819                  *         如果指定getter函数,会通过getter函数取属性值\r
16820                  * @param  {Function} [options.setter=null]\r
16821                  *         如果指定setter函数,会通过setter函数设置属性值\r
16822                  * @return {module:zrender/animation/Animation~Animator}\r
16823                  */\r
16824                 animate: function (target, options) {\r
16825                     options = options || {};\r
16826                     var animator = new Animator(\r
16827                         target,\r
16828                         options.loop,\r
16829                         options.getter,\r
16830                         options.setter\r
16831                     );\r
16832 \r
16833                     return animator;\r
16834                 }\r
16835             };\r
16836 \r
16837             util.mixin(Animation, Dispatcher);\r
16838 \r
16839             module.exports = Animation;\r
16840 \r
16841 \r
16842 \r
16843 /***/ },\r
16844 /* 85 */\r
16845 /***/ function(module, exports, __webpack_require__) {\r
16846 \r
16847         'use strict';\r
16848         /**\r
16849          * Default canvas painter\r
16850          * @module zrender/Painter\r
16851          * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)\r
16852          *         errorrik (errorrik@gmail.com)\r
16853          *         pissang (https://www.github.com/pissang)\r
16854          */\r
16855          \r
16856 \r
16857             var config = __webpack_require__(40);\r
16858             var util = __webpack_require__(3);\r
16859             var log = __webpack_require__(39);\r
16860             var BoundingRect = __webpack_require__(15);\r
16861 \r
16862             var Layer = __webpack_require__(86);\r
16863 \r
16864             function parseInt10(val) {\r
16865                 return parseInt(val, 10);\r
16866             }\r
16867 \r
16868             function isLayerValid(layer) {\r
16869                 if (!layer) {\r
16870                     return false;\r
16871                 }\r
16872 \r
16873                 if (layer.isBuildin) {\r
16874                     return true;\r
16875                 }\r
16876 \r
16877                 if (typeof(layer.resize) !== 'function'\r
16878                     || typeof(layer.refresh) !== 'function'\r
16879                 ) {\r
16880                     return false;\r
16881                 }\r
16882 \r
16883                 return true;\r
16884             }\r
16885 \r
16886             function preProcessLayer(layer) {\r
16887                 layer.__unusedCount++;\r
16888             }\r
16889 \r
16890             function postProcessLayer(layer) {\r
16891                 layer.__dirty = false;\r
16892                 if (layer.__unusedCount == 1) {\r
16893                     layer.clear();\r
16894                 }\r
16895             }\r
16896 \r
16897             var tmpRect = new BoundingRect(0, 0, 0, 0);\r
16898             var viewRect = new BoundingRect(0, 0, 0, 0);\r
16899             function isDisplayableCulled(el, width, height) {\r
16900                 tmpRect.copy(el.getBoundingRect());\r
16901                 if (el.transform) {\r
16902                     tmpRect.applyTransform(el.transform);\r
16903                 }\r
16904                 viewRect.width = width;\r
16905                 viewRect.height = height;\r
16906                 return !tmpRect.intersect(viewRect);\r
16907             }\r
16908 \r
16909             function isClipPathChanged(clipPaths, prevClipPaths) {\r
16910                 if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {\r
16911                     return true;\r
16912                 }\r
16913                 for (var i = 0; i < clipPaths.length; i++) {\r
16914                     if (clipPaths[i] !== prevClipPaths[i]) {\r
16915                         return true;\r
16916                     }\r
16917                 }\r
16918             }\r
16919 \r
16920             function doClip(clipPaths, ctx) {\r
16921                 for (var i = 0; i < clipPaths.length; i++) {\r
16922                     var clipPath = clipPaths[i];\r
16923                     var m;\r
16924                     if (clipPath.transform) {\r
16925                         m = clipPath.transform;\r
16926                         ctx.transform(\r
16927                             m[0], m[1],\r
16928                             m[2], m[3],\r
16929                             m[4], m[5]\r
16930                         );\r
16931                     }\r
16932                     var path = clipPath.path;\r
16933                     path.beginPath(ctx);\r
16934                     clipPath.buildPath(path, clipPath.shape);\r
16935                     ctx.clip();\r
16936                     // Transform back\r
16937                     if (clipPath.transform) {\r
16938                         m = clipPath.invTransform;\r
16939                         ctx.transform(\r
16940                             m[0], m[1],\r
16941                             m[2], m[3],\r
16942                             m[4], m[5]\r
16943                         );\r
16944                     }\r
16945                 }\r
16946             }\r
16947 \r
16948             /**\r
16949              * @alias module:zrender/Painter\r
16950              * @constructor\r
16951              * @param {HTMLElement} root 绘图容器\r
16952              * @param {module:zrender/Storage} storage\r
16953              * @param {Ojbect} opts\r
16954              */\r
16955             var Painter = function (root, storage, opts) {\r
16956                 var singleCanvas = !root.nodeName // In node ?\r
16957                     || root.nodeName.toUpperCase() === 'CANVAS';\r
16958 \r
16959                 opts = opts || {};\r
16960 \r
16961                 /**\r
16962                  * @type {number}\r
16963                  */\r
16964                 this.dpr = opts.devicePixelRatio || config.devicePixelRatio;\r
16965                 /**\r
16966                  * @type {boolean}\r
16967                  * @private\r
16968                  */\r
16969                 this._singleCanvas = singleCanvas;\r
16970                 /**\r
16971                  * 绘图容器\r
16972                  * @type {HTMLElement}\r
16973                  */\r
16974                 this.root = root;\r
16975 \r
16976                 var rootStyle = root.style;\r
16977 \r
16978                 // In node environment using node-canvas\r
16979                 if (rootStyle) {\r
16980                     rootStyle['-webkit-tap-highlight-color'] = 'transparent';\r
16981                     rootStyle['-webkit-user-select'] = 'none';\r
16982                     rootStyle['user-select'] = 'none';\r
16983                     rootStyle['-webkit-touch-callout'] = 'none';\r
16984 \r
16985                     root.innerHTML = '';\r
16986                 }\r
16987 \r
16988                 /**\r
16989                  * @type {module:zrender/Storage}\r
16990                  */\r
16991                 this.storage = storage;\r
16992 \r
16993                 if (!singleCanvas) {\r
16994                     var width = this._getWidth();\r
16995                     var height = this._getHeight();\r
16996                     this._width = width;\r
16997                     this._height = height;\r
16998 \r
16999                     var domRoot = document.createElement('div');\r
17000                     this._domRoot = domRoot;\r
17001                     var domRootStyle = domRoot.style;\r
17002 \r
17003                     // domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬\r
17004                     domRootStyle.position = 'relative';\r
17005                     domRootStyle.overflow = 'hidden';\r
17006                     domRootStyle.width = this._width + 'px';\r
17007                     domRootStyle.height = this._height + 'px';\r
17008                     root.appendChild(domRoot);\r
17009 \r
17010                     /**\r
17011                      * @type {Object.<key, module:zrender/Layer>}\r
17012                      * @private\r
17013                      */\r
17014                     this._layers = {};\r
17015                     /**\r
17016                      * @type {Array.<number>}\r
17017                      * @private\r
17018                      */\r
17019                     this._zlevelList = [];\r
17020                 }\r
17021                 else {\r
17022                     // Use canvas width and height directly\r
17023                     var width = root.width;\r
17024                     var height = root.height;\r
17025                     this._width = width;\r
17026                     this._height = height;\r
17027 \r
17028                     // Create layer if only one given canvas\r
17029                     // Device pixel ratio is fixed to 1 because given canvas has its specified width and height\r
17030                     var mainLayer = new Layer(root, this, 1);\r
17031                     mainLayer.initContext();\r
17032                     // FIXME Use canvas width and height\r
17033                     // mainLayer.resize(width, height);\r
17034                     this._layers = {\r
17035                         0: mainLayer\r
17036                     };\r
17037                     this._zlevelList = [0];\r
17038                 }\r
17039 \r
17040                 this._layerConfig = {};\r
17041 \r
17042                 this.pathToImage = this._createPathToImage();\r
17043             };\r
17044 \r
17045             Painter.prototype = {\r
17046 \r
17047                 constructor: Painter,\r
17048 \r
17049                 /**\r
17050                  * If painter use a single canvas\r
17051                  * @return {boolean}\r
17052                  */\r
17053                 isSingleCanvas: function () {\r
17054                     return this._singleCanvas;\r
17055                 },\r
17056                 /**\r
17057                  * @return {HTMLDivElement}\r
17058                  */\r
17059                 getViewportRoot: function () {\r
17060                     return this._singleCanvas ? this._layers[0].dom : this._domRoot;\r
17061                 },\r
17062 \r
17063                 /**\r
17064                  * 刷新\r
17065                  * @param {boolean} [paintAll=false] 强制绘制所有displayable\r
17066                  */\r
17067                 refresh: function (paintAll) {\r
17068                     var list = this.storage.getDisplayList(true);\r
17069                     var zlevelList = this._zlevelList;\r
17070 \r
17071                     this._paintList(list, paintAll);\r
17072 \r
17073                     // Paint custum layers\r
17074                     for (var i = 0; i < zlevelList.length; i++) {\r
17075                         var z = zlevelList[i];\r
17076                         var layer = this._layers[z];\r
17077                         if (!layer.isBuildin && layer.refresh) {\r
17078                             layer.refresh();\r
17079                         }\r
17080                     }\r
17081 \r
17082                     return this;\r
17083                 },\r
17084 \r
17085                 _paintList: function (list, paintAll) {\r
17086 \r
17087                     if (paintAll == null) {\r
17088                         paintAll = false;\r
17089                     }\r
17090 \r
17091                     this._updateLayerStatus(list);\r
17092 \r
17093                     var currentLayer;\r
17094                     var currentZLevel;\r
17095                     var ctx;\r
17096 \r
17097                     var viewWidth = this._width;\r
17098                     var viewHeight = this._height;\r
17099 \r
17100                     this.eachBuildinLayer(preProcessLayer);\r
17101 \r
17102                     // var invTransform = [];\r
17103                     var prevElClipPaths = null;\r
17104 \r
17105                     for (var i = 0, l = list.length; i < l; i++) {\r
17106                         var el = list[i];\r
17107                         var elZLevel = this._singleCanvas ? 0 : el.zlevel;\r
17108                         // Change draw layer\r
17109                         if (currentZLevel !== elZLevel) {\r
17110                             // Only 0 zlevel if only has one canvas\r
17111                             currentZLevel = elZLevel;\r
17112                             currentLayer = this.getLayer(currentZLevel);\r
17113 \r
17114                             if (!currentLayer.isBuildin) {\r
17115                                 log(\r
17116                                     'ZLevel ' + currentZLevel\r
17117                                     + ' has been used by unkown layer ' + currentLayer.id\r
17118                                 );\r
17119                             }\r
17120 \r
17121                             ctx = currentLayer.ctx;\r
17122 \r
17123                             // Reset the count\r
17124                             currentLayer.__unusedCount = 0;\r
17125 \r
17126                             if (currentLayer.__dirty || paintAll) {\r
17127                                 currentLayer.clear();\r
17128                             }\r
17129                         }\r
17130 \r
17131                         if (\r
17132                             (currentLayer.__dirty || paintAll)\r
17133                             // Ignore invisible element\r
17134                             && !el.invisible\r
17135                             // Ignore transparent element\r
17136                             && el.style.opacity !== 0\r
17137                             // Ignore scale 0 element, in some environment like node-canvas\r
17138                             // Draw a scale 0 element can cause all following draw wrong\r
17139                             && el.scale[0] && el.scale[1]\r
17140                             // Ignore culled element\r
17141                             && !(el.culling && isDisplayableCulled(el, viewWidth, viewHeight))\r
17142                         ) {\r
17143                             var clipPaths = el.__clipPaths;\r
17144 \r
17145                             // Optimize when clipping on group with several elements\r
17146                             if (isClipPathChanged(clipPaths, prevElClipPaths)) {\r
17147                                 // If has previous clipping state, restore from it\r
17148                                 if (prevElClipPaths) {\r
17149                                     ctx.restore();\r
17150                                 }\r
17151                                 // New clipping state\r
17152                                 if (clipPaths) {\r
17153                                     ctx.save();\r
17154                                     doClip(clipPaths, ctx);\r
17155                                 }\r
17156                                 prevElClipPaths = clipPaths;\r
17157                             }\r
17158                             el.beforeBrush && el.beforeBrush(ctx);\r
17159                             el.brush(ctx, false);\r
17160                             el.afterBrush && el.afterBrush(ctx);\r
17161                         }\r
17162 \r
17163                         el.__dirty = false;\r
17164                     }\r
17165 \r
17166                     // If still has clipping state\r
17167                     if (prevElClipPaths) {\r
17168                         ctx.restore();\r
17169                     }\r
17170 \r
17171                     this.eachBuildinLayer(postProcessLayer);\r
17172                 },\r
17173 \r
17174                 /**\r
17175                  * 获取 zlevel 所在层,如果不存在则会创建一个新的层\r
17176                  * @param {number} zlevel\r
17177                  * @return {module:zrender/Layer}\r
17178                  */\r
17179                 getLayer: function (zlevel) {\r
17180                     if (this._singleCanvas) {\r
17181                         return this._layers[0];\r
17182                     }\r
17183 \r
17184                     var layer = this._layers[zlevel];\r
17185                     if (!layer) {\r
17186                         // Create a new layer\r
17187                         layer = new Layer('zr_' + zlevel, this, this.dpr);\r
17188                         layer.isBuildin = true;\r
17189 \r
17190                         if (this._layerConfig[zlevel]) {\r
17191                             util.merge(layer, this._layerConfig[zlevel], true);\r
17192                         }\r
17193 \r
17194                         this.insertLayer(zlevel, layer);\r
17195 \r
17196                         // Context is created after dom inserted to document\r
17197                         // Or excanvas will get 0px clientWidth and clientHeight\r
17198                         layer.initContext();\r
17199                     }\r
17200 \r
17201                     return layer;\r
17202                 },\r
17203 \r
17204                 insertLayer: function (zlevel, layer) {\r
17205 \r
17206                     var layersMap = this._layers;\r
17207                     var zlevelList = this._zlevelList;\r
17208                     var len = zlevelList.length;\r
17209                     var prevLayer = null;\r
17210                     var i = -1;\r
17211                     var domRoot = this._domRoot;\r
17212 \r
17213                     if (layersMap[zlevel]) {\r
17214                         log('ZLevel ' + zlevel + ' has been used already');\r
17215                         return;\r
17216                     }\r
17217                     // Check if is a valid layer\r
17218                     if (!isLayerValid(layer)) {\r
17219                         log('Layer of zlevel ' + zlevel + ' is not valid');\r
17220                         return;\r
17221                     }\r
17222 \r
17223                     if (len > 0 && zlevel > zlevelList[0]) {\r
17224                         for (i = 0; i < len - 1; i++) {\r
17225                             if (\r
17226                                 zlevelList[i] < zlevel\r
17227                                 && zlevelList[i + 1] > zlevel\r
17228                             ) {\r
17229                                 break;\r
17230                             }\r
17231                         }\r
17232                         prevLayer = layersMap[zlevelList[i]];\r
17233                     }\r
17234                     zlevelList.splice(i + 1, 0, zlevel);\r
17235 \r
17236                     if (prevLayer) {\r
17237                         var prevDom = prevLayer.dom;\r
17238                         if (prevDom.nextSibling) {\r
17239                             domRoot.insertBefore(\r
17240                                 layer.dom,\r
17241                                 prevDom.nextSibling\r
17242                             );\r
17243                         }\r
17244                         else {\r
17245                             domRoot.appendChild(layer.dom);\r
17246                         }\r
17247                     }\r
17248                     else {\r
17249                         if (domRoot.firstChild) {\r
17250                             domRoot.insertBefore(layer.dom, domRoot.firstChild);\r
17251                         }\r
17252                         else {\r
17253                             domRoot.appendChild(layer.dom);\r
17254                         }\r
17255                     }\r
17256 \r
17257                     layersMap[zlevel] = layer;\r
17258                 },\r
17259 \r
17260                 // Iterate each layer\r
17261                 eachLayer: function (cb, context) {\r
17262                     var zlevelList = this._zlevelList;\r
17263                     var z;\r
17264                     var i;\r
17265                     for (i = 0; i < zlevelList.length; i++) {\r
17266                         z = zlevelList[i];\r
17267                         cb.call(context, this._layers[z], z);\r
17268                     }\r
17269                 },\r
17270 \r
17271                 // Iterate each buildin layer\r
17272                 eachBuildinLayer: function (cb, context) {\r
17273                     var zlevelList = this._zlevelList;\r
17274                     var layer;\r
17275                     var z;\r
17276                     var i;\r
17277                     for (i = 0; i < zlevelList.length; i++) {\r
17278                         z = zlevelList[i];\r
17279                         layer = this._layers[z];\r
17280                         if (layer.isBuildin) {\r
17281                             cb.call(context, layer, z);\r
17282                         }\r
17283                     }\r
17284                 },\r
17285 \r
17286                 // Iterate each other layer except buildin layer\r
17287                 eachOtherLayer: function (cb, context) {\r
17288                     var zlevelList = this._zlevelList;\r
17289                     var layer;\r
17290                     var z;\r
17291                     var i;\r
17292                     for (i = 0; i < zlevelList.length; i++) {\r
17293                         z = zlevelList[i];\r
17294                         layer = this._layers[z];\r
17295                         if (! layer.isBuildin) {\r
17296                             cb.call(context, layer, z);\r
17297                         }\r
17298                     }\r
17299                 },\r
17300 \r
17301                 /**\r
17302                  * 获取所有已创建的层\r
17303                  * @param {Array.<module:zrender/Layer>} [prevLayer]\r
17304                  */\r
17305                 getLayers: function () {\r
17306                     return this._layers;\r
17307                 },\r
17308 \r
17309                 _updateLayerStatus: function (list) {\r
17310 \r
17311                     var layers = this._layers;\r
17312 \r
17313                     var elCounts = {};\r
17314 \r
17315                     this.eachBuildinLayer(function (layer, z) {\r
17316                         elCounts[z] = layer.elCount;\r
17317                         layer.elCount = 0;\r
17318                     });\r
17319 \r
17320                     for (var i = 0, l = list.length; i < l; i++) {\r
17321                         var el = list[i];\r
17322                         var zlevel = this._singleCanvas ? 0 : el.zlevel;\r
17323                         var layer = layers[zlevel];\r
17324                         if (layer) {\r
17325                             layer.elCount++;\r
17326                             // 已经被标记为需要刷新\r
17327                             if (layer.__dirty) {\r
17328                                 continue;\r
17329                             }\r
17330                             layer.__dirty = el.__dirty;\r
17331                         }\r
17332                     }\r
17333 \r
17334                     // 层中的元素数量有发生变化\r
17335                     this.eachBuildinLayer(function (layer, z) {\r
17336                         if (elCounts[z] !== layer.elCount) {\r
17337                             layer.__dirty = true;\r
17338                         }\r
17339                     });\r
17340                 },\r
17341 \r
17342                 /**\r
17343                  * 清除hover层外所有内容\r
17344                  */\r
17345                 clear: function () {\r
17346                     this.eachBuildinLayer(this._clearLayer);\r
17347                     return this;\r
17348                 },\r
17349 \r
17350                 _clearLayer: function (layer) {\r
17351                     layer.clear();\r
17352                 },\r
17353 \r
17354                 /**\r
17355                  * 修改指定zlevel的绘制参数\r
17356                  *\r
17357                  * @param {string} zlevel\r
17358                  * @param {Object} config 配置对象\r
17359                  * @param {string} [config.clearColor=0] 每次清空画布的颜色\r
17360                  * @param {string} [config.motionBlur=false] 是否开启动态模糊\r
17361                  * @param {number} [config.lastFrameAlpha=0.7]\r
17362                  *                 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显\r
17363                  */\r
17364                 configLayer: function (zlevel, config) {\r
17365                     if (config) {\r
17366                         var layerConfig = this._layerConfig;\r
17367                         if (!layerConfig[zlevel]) {\r
17368                             layerConfig[zlevel] = config;\r
17369                         }\r
17370                         else {\r
17371                             util.merge(layerConfig[zlevel], config, true);\r
17372                         }\r
17373 \r
17374                         var layer = this._layers[zlevel];\r
17375 \r
17376                         if (layer) {\r
17377                             util.merge(layer, layerConfig[zlevel], true);\r
17378                         }\r
17379                     }\r
17380                 },\r
17381 \r
17382                 /**\r
17383                  * 删除指定层\r
17384                  * @param {number} zlevel 层所在的zlevel\r
17385                  */\r
17386                 delLayer: function (zlevel) {\r
17387                     var layers = this._layers;\r
17388                     var zlevelList = this._zlevelList;\r
17389                     var layer = layers[zlevel];\r
17390                     if (!layer) {\r
17391                         return;\r
17392                     }\r
17393                     layer.dom.parentNode.removeChild(layer.dom);\r
17394                     delete layers[zlevel];\r
17395 \r
17396                     zlevelList.splice(util.indexOf(zlevelList, zlevel), 1);\r
17397                 },\r
17398 \r
17399                 /**\r
17400                  * 区域大小变化后重绘\r
17401                  */\r
17402                 resize: function (width, height) {\r
17403                     var domRoot = this._domRoot;\r
17404                     // FIXME Why ?\r
17405                     domRoot.style.display = 'none';\r
17406 \r
17407                     width = width || this._getWidth();\r
17408                     height = height || this._getHeight();\r
17409 \r
17410                     domRoot.style.display = '';\r
17411 \r
17412                     // 优化没有实际改变的resize\r
17413                     if (this._width != width || height != this._height) {\r
17414                         domRoot.style.width = width + 'px';\r
17415                         domRoot.style.height = height + 'px';\r
17416 \r
17417                         for (var id in this._layers) {\r
17418                             this._layers[id].resize(width, height);\r
17419                         }\r
17420 \r
17421                         this.refresh(true);\r
17422                     }\r
17423 \r
17424                     this._width = width;\r
17425                     this._height = height;\r
17426 \r
17427                     return this;\r
17428                 },\r
17429 \r
17430                 /**\r
17431                  * 清除单独的一个层\r
17432                  * @param {number} zlevel\r
17433                  */\r
17434                 clearLayer: function (zlevel) {\r
17435                     var layer = this._layers[zlevel];\r
17436                     if (layer) {\r
17437                         layer.clear();\r
17438                     }\r
17439                 },\r
17440 \r
17441                 /**\r
17442                  * 释放\r
17443                  */\r
17444                 dispose: function () {\r
17445                     this.root.innerHTML = '';\r
17446 \r
17447                     this.root =\r
17448                     this.storage =\r
17449 \r
17450                     this._domRoot =\r
17451                     this._layers = null;\r
17452                 },\r
17453 \r
17454                 /**\r
17455                  * Get canvas which has all thing rendered\r
17456                  * @param {Object} opts\r
17457                  * @param {string} [opts.backgroundColor]\r
17458                  */\r
17459                 getRenderedCanvas: function (opts) {\r
17460                     opts = opts || {};\r
17461                     if (this._singleCanvas) {\r
17462                         return this._layers[0].dom;\r
17463                     }\r
17464 \r
17465                     var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);\r
17466                     imageLayer.initContext();\r
17467 \r
17468                     var ctx = imageLayer.ctx;\r
17469                     imageLayer.clearColor = opts.backgroundColor;\r
17470                     imageLayer.clear();\r
17471 \r
17472                     var displayList = this.storage.getDisplayList(true);\r
17473 \r
17474                     for (var i = 0; i < displayList.length; i++) {\r
17475                         var el = displayList[i];\r
17476                         if (!el.invisible) {\r
17477                             el.beforeBrush && el.beforeBrush(ctx);\r
17478                             // TODO Check image cross origin\r
17479                             el.brush(ctx, false);\r
17480                             el.afterBrush && el.afterBrush(ctx);\r
17481                         }\r
17482                     }\r
17483 \r
17484                     return imageLayer.dom;\r
17485                 },\r
17486                 /**\r
17487                  * 获取绘图区域宽度\r
17488                  */\r
17489                 getWidth: function () {\r
17490                     return this._width;\r
17491                 },\r
17492 \r
17493                 /**\r
17494                  * 获取绘图区域高度\r
17495                  */\r
17496                 getHeight: function () {\r
17497                     return this._height;\r
17498                 },\r
17499 \r
17500                 _getWidth: function () {\r
17501                     var root = this.root;\r
17502                     var stl = document.defaultView.getComputedStyle(root);\r
17503 \r
17504                     // FIXME Better way to get the width and height when element has not been append to the document\r
17505                     return ((root.clientWidth || parseInt10(stl.width) || parseInt10(root.style.width))\r
17506                             - (parseInt10(stl.paddingLeft) || 0)\r
17507                             - (parseInt10(stl.paddingRight) || 0)) | 0;\r
17508                 },\r
17509 \r
17510                 _getHeight: function () {\r
17511                     var root = this.root;\r
17512                     var stl = document.defaultView.getComputedStyle(root);\r
17513 \r
17514                     return ((root.clientHeight || parseInt10(stl.height) || parseInt10(root.style.height))\r
17515                             - (parseInt10(stl.paddingTop) || 0)\r
17516                             - (parseInt10(stl.paddingBottom) || 0)) | 0;\r
17517                 },\r
17518 \r
17519                 _pathToImage: function (id, path, width, height, dpr) {\r
17520                     var canvas = document.createElement('canvas');\r
17521                     var ctx = canvas.getContext('2d');\r
17522 \r
17523                     canvas.width = width * dpr;\r
17524                     canvas.height = height * dpr;\r
17525 \r
17526                     ctx.clearRect(0, 0, width * dpr, height * dpr);\r
17527 \r
17528                     var pathTransform = {\r
17529                         position: path.position,\r
17530                         rotation: path.rotation,\r
17531                         scale: path.scale\r
17532                     };\r
17533                     path.position = [0, 0, 0];\r
17534                     path.rotation = 0;\r
17535                     path.scale = [1, 1];\r
17536                     if (path) {\r
17537                         path.brush(ctx);\r
17538                     }\r
17539 \r
17540                     var ImageShape = __webpack_require__(59);\r
17541                     var imgShape = new ImageShape({\r
17542                         id: id,\r
17543                         style: {\r
17544                             x: 0,\r
17545                             y: 0,\r
17546                             image: canvas\r
17547                         }\r
17548                     });\r
17549 \r
17550                     if (pathTransform.position != null) {\r
17551                         imgShape.position = path.position = pathTransform.position;\r
17552                     }\r
17553 \r
17554                     if (pathTransform.rotation != null) {\r
17555                         imgShape.rotation = path.rotation = pathTransform.rotation;\r
17556                     }\r
17557 \r
17558                     if (pathTransform.scale != null) {\r
17559                         imgShape.scale = path.scale = pathTransform.scale;\r
17560                     }\r
17561 \r
17562                     return imgShape;\r
17563                 },\r
17564 \r
17565                 _createPathToImage: function () {\r
17566                     var me = this;\r
17567 \r
17568                     return function (id, e, width, height) {\r
17569                         return me._pathToImage(\r
17570                             id, e, width, height, me.dpr\r
17571                         );\r
17572                     };\r
17573                 }\r
17574             };\r
17575 \r
17576             module.exports = Painter;\r
17577 \r
17578 \r
17579 \r
17580 /***/ },\r
17581 /* 86 */\r
17582 /***/ function(module, exports, __webpack_require__) {\r
17583 \r
17584         /**\r
17585          * @module zrender/Layer\r
17586          * @author pissang(https://www.github.com/pissang)\r
17587          */\r
17588 \r
17589 \r
17590             var util = __webpack_require__(3);\r
17591             var config = __webpack_require__(40);\r
17592 \r
17593             function returnFalse() {\r
17594                 return false;\r
17595             }\r
17596 \r
17597             /**\r
17598              * 创建dom\r
17599              *\r
17600              * @inner\r
17601              * @param {string} id dom id 待用\r
17602              * @param {string} type dom type,such as canvas, div etc.\r
17603              * @param {Painter} painter painter instance\r
17604              * @param {number} number\r
17605              */\r
17606             function createDom(id, type, painter, dpr) {\r
17607                 var newDom = document.createElement(type);\r
17608                 var width = painter.getWidth();\r
17609                 var height = painter.getHeight();\r
17610 \r
17611                 var newDomStyle = newDom.style;\r
17612                 // 没append呢,请原谅我这样写,清晰~\r
17613                 newDomStyle.position = 'absolute';\r
17614                 newDomStyle.left = 0;\r
17615                 newDomStyle.top = 0;\r
17616                 newDomStyle.width = width + 'px';\r
17617                 newDomStyle.height = height + 'px';\r
17618                 newDom.width = width * dpr;\r
17619                 newDom.height = height * dpr;\r
17620 \r
17621                 // id不作为索引用,避免可能造成的重名,定义为私有属性\r
17622                 newDom.setAttribute('data-zr-dom-id', id);\r
17623                 return newDom;\r
17624             }\r
17625 \r
17626             /**\r
17627              * @alias module:zrender/Layer\r
17628              * @constructor\r
17629              * @extends module:zrender/mixin/Transformable\r
17630              * @param {string} id\r
17631              * @param {module:zrender/Painter} painter\r
17632              * @param {number} [dpr]\r
17633              */\r
17634             var Layer = function(id, painter, dpr) {\r
17635                 var dom;\r
17636                 dpr = dpr || config.devicePixelRatio;\r
17637                 if (typeof id === 'string') {\r
17638                     dom = createDom(id, 'canvas', painter, dpr);\r
17639                 }\r
17640                 // Not using isDom because in node it will return false\r
17641                 else if (util.isObject(id)) {\r
17642                     dom = id;\r
17643                     id = dom.id;\r
17644                 }\r
17645                 this.id = id;\r
17646                 this.dom = dom;\r
17647 \r
17648                 var domStyle = dom.style;\r
17649                 if (domStyle) { // Not in node\r
17650                     dom.onselectstart = returnFalse; // 避免页面选中的尴尬\r
17651                     domStyle['-webkit-user-select'] = 'none';\r
17652                     domStyle['user-select'] = 'none';\r
17653                     domStyle['-webkit-touch-callout'] = 'none';\r
17654                     domStyle['-webkit-tap-highlight-color'] = 'rgba(0,0,0,0)';\r
17655                 }\r
17656 \r
17657                 this.domBack = null;\r
17658                 this.ctxBack = null;\r
17659 \r
17660                 this.painter = painter;\r
17661 \r
17662                 this.config = null;\r
17663 \r
17664                 // Configs\r
17665                 /**\r
17666                  * 每次清空画布的颜色\r
17667                  * @type {string}\r
17668                  * @default 0\r
17669                  */\r
17670                 this.clearColor = 0;\r
17671                 /**\r
17672                  * 是否开启动态模糊\r
17673                  * @type {boolean}\r
17674                  * @default false\r
17675                  */\r
17676                 this.motionBlur = false;\r
17677                 /**\r
17678                  * 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显\r
17679                  * @type {number}\r
17680                  * @default 0.7\r
17681                  */\r
17682                 this.lastFrameAlpha = 0.7;\r
17683 \r
17684                 /**\r
17685                  * Layer dpr\r
17686                  * @type {number}\r
17687                  */\r
17688                 this.dpr = dpr;\r
17689             };\r
17690 \r
17691             Layer.prototype = {\r
17692 \r
17693                 constructor: Layer,\r
17694 \r
17695                 elCount: 0,\r
17696 \r
17697                 __dirty: true,\r
17698 \r
17699                 initContext: function () {\r
17700                     this.ctx = this.dom.getContext('2d');\r
17701 \r
17702                     var dpr = this.dpr;\r
17703                     if (dpr != 1) {\r
17704                         this.ctx.scale(dpr, dpr);\r
17705                     }\r
17706                 },\r
17707 \r
17708                 createBackBuffer: function () {\r
17709                     var dpr = this.dpr;\r
17710 \r
17711                     this.domBack = createDom('back-' + this.id, 'canvas', this.painter, dpr);\r
17712                     this.ctxBack = this.domBack.getContext('2d');\r
17713 \r
17714                     if (dpr != 1) {\r
17715                         this.ctxBack.scale(dpr, dpr);\r
17716                     }\r
17717                 },\r
17718 \r
17719                 /**\r
17720                  * @param  {number} width\r
17721                  * @param  {number} height\r
17722                  */\r
17723                 resize: function (width, height) {\r
17724                     var dpr = this.dpr;\r
17725 \r
17726                     var dom = this.dom;\r
17727                     var domStyle = dom.style;\r
17728                     var domBack = this.domBack;\r
17729 \r
17730                     domStyle.width = width + 'px';\r
17731                     domStyle.height = height + 'px';\r
17732 \r
17733                     dom.width = width * dpr;\r
17734                     dom.height = height * dpr;\r
17735 \r
17736                     if (dpr != 1) {\r
17737                         this.ctx.scale(dpr, dpr);\r
17738                     }\r
17739 \r
17740                     if (domBack) {\r
17741                         domBack.width = width * dpr;\r
17742                         domBack.height = height * dpr;\r
17743 \r
17744                         if (dpr != 1) {\r
17745                             this.ctxBack.scale(dpr, dpr);\r
17746                         }\r
17747                     }\r
17748                 },\r
17749 \r
17750                 /**\r
17751                  * 清空该层画布\r
17752                  * @param {boolean} clearAll Clear all with out motion blur\r
17753                  */\r
17754                 clear: function (clearAll) {\r
17755                     var dom = this.dom;\r
17756                     var ctx = this.ctx;\r
17757                     var width = dom.width;\r
17758                     var height = dom.height;\r
17759 \r
17760                     var haveClearColor = this.clearColor;\r
17761                     var haveMotionBLur = this.motionBlur && !clearAll;\r
17762                     var lastFrameAlpha = this.lastFrameAlpha;\r
17763 \r
17764                     var dpr = this.dpr;\r
17765 \r
17766                     if (haveMotionBLur) {\r
17767                         if (!this.domBack) {\r
17768                             this.createBackBuffer();\r
17769                         }\r
17770 \r
17771                         this.ctxBack.globalCompositeOperation = 'copy';\r
17772                         this.ctxBack.drawImage(\r
17773                             dom, 0, 0,\r
17774                             width / dpr,\r
17775                             height / dpr\r
17776                         );\r
17777                     }\r
17778 \r
17779                     ctx.clearRect(0, 0, width / dpr, height / dpr);\r
17780                     if (haveClearColor) {\r
17781                         ctx.save();\r
17782                         ctx.fillStyle = this.clearColor;\r
17783                         ctx.fillRect(0, 0, width / dpr, height / dpr);\r
17784                         ctx.restore();\r
17785                     }\r
17786 \r
17787                     if (haveMotionBLur) {\r
17788                         var domBack = this.domBack;\r
17789                         ctx.save();\r
17790                         ctx.globalAlpha = lastFrameAlpha;\r
17791                         ctx.drawImage(domBack, 0, 0, width / dpr, height / dpr);\r
17792                         ctx.restore();\r
17793                     }\r
17794                 }\r
17795             };\r
17796 \r
17797             module.exports = Layer;\r
17798 \r
17799 \r
17800 /***/ },\r
17801 /* 87 */\r
17802 /***/ function(module, exports, __webpack_require__) {\r
17803 \r
17804         \r
17805 \r
17806             var graphic = __webpack_require__(42);\r
17807             var zrUtil = __webpack_require__(3);\r
17808             var PI = Math.PI;\r
17809             /**\r
17810              * @param {module:echarts/ExtensionAPI} api\r
17811              * @param {Object} [opts]\r
17812              * @param {string} [opts.text]\r
17813              * @param {string} [opts.color]\r
17814              * @param {string} [opts.textColor]\r
17815              * @return {module:zrender/Element}\r
17816              */\r
17817             module.exports = function (api, opts) {\r
17818                 opts = opts || {};\r
17819                 zrUtil.defaults(opts, {\r
17820                     text: 'loading',\r
17821                     color: '#c23531',\r
17822                     textColor: '#000',\r
17823                     maskColor: 'rgba(255, 255, 255, 0.8)',\r
17824                     zlevel: 0\r
17825                 });\r
17826                 var mask = new graphic.Rect({\r
17827                     style: {\r
17828                         fill: opts.maskColor\r
17829                     },\r
17830                     zlevel: opts.zlevel,\r
17831                     z: 10000\r
17832                 });\r
17833                 var arc = new graphic.Arc({\r
17834                     shape: {\r
17835                         startAngle: -PI / 2,\r
17836                         endAngle: -PI / 2 + 0.1,\r
17837                         r: 10\r
17838                     },\r
17839                     style: {\r
17840                         stroke: opts.color,\r
17841                         lineCap: 'round',\r
17842                         lineWidth: 5\r
17843                     },\r
17844                     zlevel: opts.zlevel,\r
17845                     z: 10001\r
17846                 });\r
17847                 var labelRect = new graphic.Rect({\r
17848                     style: {\r
17849                         fill: 'none',\r
17850                         text: opts.text,\r
17851                         textPosition: 'right',\r
17852                         textDistance: 10,\r
17853                         textFill: opts.textColor\r
17854                     },\r
17855                     zlevel: opts.zlevel,\r
17856                     z: 10001\r
17857                 });\r
17858 \r
17859                 arc.animateShape(true)\r
17860                     .when(1000, {\r
17861                         endAngle: PI * 3 / 2\r
17862                     })\r
17863                     .start('circularInOut');\r
17864                 arc.animateShape(true)\r
17865                     .when(1000, {\r
17866                         startAngle: PI * 3 / 2\r
17867                     })\r
17868                     .delay(300)\r
17869                     .start('circularInOut');\r
17870 \r
17871                 var group = new graphic.Group();\r
17872                 group.add(arc);\r
17873                 group.add(labelRect);\r
17874                 group.add(mask);\r
17875                 // Inject resize\r
17876                 group.resize = function () {\r
17877                     var cx = api.getWidth() / 2;\r
17878                     var cy = api.getHeight() / 2;\r
17879                     arc.setShape({\r
17880                         cx: cx,\r
17881                         cy: cy\r
17882                     });\r
17883                     var r = arc.shape.r;\r
17884                     labelRect.setShape({\r
17885                         x: cx - r,\r
17886                         y: cy - r,\r
17887                         width: r * 2,\r
17888                         height: r * 2\r
17889                     });\r
17890 \r
17891                     mask.setShape({\r
17892                         x: 0,\r
17893                         y: 0,\r
17894                         width: api.getWidth(),\r
17895                         height: api.getHeight()\r
17896                     });\r
17897                 };\r
17898                 group.resize();\r
17899                 return group;\r
17900             };\r
17901 \r
17902 \r
17903 /***/ },\r
17904 /* 88 */\r
17905 /***/ function(module, exports, __webpack_require__) {\r
17906 \r
17907         \r
17908             var Gradient = __webpack_require__(4);\r
17909             module.exports = function (seriesType, styleType, ecModel) {\r
17910                 function encodeColor(seriesModel) {\r
17911                     var colorAccessPath = [styleType, 'normal', 'color'];\r
17912                     var colorList = ecModel.get('color');\r
17913                     var data = seriesModel.getData();\r
17914                     var color = seriesModel.get(colorAccessPath) // Set in itemStyle\r
17915                         || colorList[seriesModel.seriesIndex % colorList.length];  // Default color\r
17916 \r
17917                     // FIXME Set color function or use the platte color\r
17918                     data.setVisual('color', color);\r
17919 \r
17920                     // Only visible series has each data be visual encoded\r
17921                     if (!ecModel.isSeriesFiltered(seriesModel)) {\r
17922                         if (typeof color === 'function' && !(color instanceof Gradient)) {\r
17923                             data.each(function (idx) {\r
17924                                 data.setItemVisual(\r
17925                                     idx, 'color', color(seriesModel.getDataParams(idx))\r
17926                                 );\r
17927                             });\r
17928                         }\r
17929 \r
17930                         data.each(function (idx) {\r
17931                             var itemModel = data.getItemModel(idx);\r
17932                             var color = itemModel.get(colorAccessPath, true);\r
17933                             if (color != null) {\r
17934                                 data.setItemVisual(idx, 'color', color);\r
17935                             }\r
17936                         });\r
17937                     }\r
17938                 }\r
17939                 seriesType ? ecModel.eachSeriesByType(seriesType, encodeColor)\r
17940                     : ecModel.eachSeries(encodeColor);\r
17941             };\r
17942 \r
17943 \r
17944 /***/ },\r
17945 /* 89 */\r
17946 /***/ function(module, exports, __webpack_require__) {\r
17947 \r
17948         // Compatitable with 2.0\r
17949 \r
17950 \r
17951             var zrUtil = __webpack_require__(3);\r
17952             var compatStyle = __webpack_require__(90);\r
17953 \r
17954             function get(opt, path) {\r
17955                 path = path.split(',');\r
17956                 var obj = opt;\r
17957                 for (var i = 0; i < path.length; i++) {\r
17958                     obj = obj && obj[path[i]];\r
17959                     if (obj == null) {\r
17960                         break;\r
17961                     }\r
17962                 }\r
17963                 return obj;\r
17964             }\r
17965 \r
17966             function set(opt, path, val, overwrite) {\r
17967                 path = path.split(',');\r
17968                 var obj = opt;\r
17969                 var key;\r
17970                 for (var i = 0; i < path.length - 1; i++) {\r
17971                     key = path[i];\r
17972                     if (obj[key] == null) {\r
17973                         obj[key] = {};\r
17974                     }\r
17975                     obj = obj[key];\r
17976                 }\r
17977                 if (overwrite || obj[path[i]] == null) {\r
17978                     obj[path[i]] = val;\r
17979                 }\r
17980             }\r
17981 \r
17982             function compatLayoutProperties(option) {\r
17983                 each(LAYOUT_PROPERTIES, function (prop) {\r
17984                     if (prop[0] in option && !(prop[1] in option)) {\r
17985                         option[prop[1]] = option[prop[0]];\r
17986                     }\r
17987                 });\r
17988             }\r
17989 \r
17990             var LAYOUT_PROPERTIES = [\r
17991                 ['x', 'left'], ['y', 'top'], ['x2', 'right'], ['y2', 'bottom']\r
17992             ];\r
17993 \r
17994             var COMPATITABLE_COMPONENTS = [\r
17995                 'grid', 'geo', 'parallel', 'legend', 'toolbox', 'title', 'visualMap', 'dataZoom', 'timeline'\r
17996             ];\r
17997 \r
17998             var COMPATITABLE_SERIES = [\r
17999                 'bar', 'boxplot', 'candlestick', 'chord', 'effectScatter',\r
18000                 'funnel', 'gauge', 'lines', 'graph', 'heatmap', 'line', 'map', 'parallel',\r
18001                 'pie', 'radar', 'sankey', 'scatter', 'treemap'\r
18002             ];\r
18003 \r
18004             var each = zrUtil.each;\r
18005 \r
18006             module.exports = function (option) {\r
18007                 each(option.series, function (seriesOpt) {\r
18008                     if (!zrUtil.isObject(seriesOpt)) {\r
18009                         return;\r
18010                     }\r
18011 \r
18012                     var seriesType = seriesOpt.type;\r
18013 \r
18014                     compatStyle(seriesOpt);\r
18015 \r
18016                     if (seriesType === 'pie' || seriesType === 'gauge') {\r
18017                         if (seriesOpt.clockWise != null) {\r
18018                             seriesOpt.clockwise = seriesOpt.clockWise;\r
18019                         }\r
18020                     }\r
18021                     if (seriesType === 'gauge') {\r
18022                         var pointerColor = get(seriesOpt, 'pointer.color');\r
18023                         pointerColor != null\r
18024                             && set(seriesOpt, 'itemStyle.normal.color', pointerColor);\r
18025                     }\r
18026 \r
18027                     for (var i = 0; i < COMPATITABLE_SERIES.length; i++) {\r
18028                         if (COMPATITABLE_SERIES[i] === seriesOpt.type) {\r
18029                             compatLayoutProperties(seriesOpt);\r
18030                             break;\r
18031                         }\r
18032                     }\r
18033                 });\r
18034 \r
18035                 // dataRange has changed to visualMap\r
18036                 if (option.dataRange) {\r
18037                     option.visualMap = option.dataRange;\r
18038                 }\r
18039 \r
18040                 each(COMPATITABLE_COMPONENTS, function (componentName) {\r
18041                     var options = option[componentName];\r
18042                     if (options) {\r
18043                         if (!zrUtil.isArray(options)) {\r
18044                             options = [options];\r
18045                         }\r
18046                         each(options, function (option) {\r
18047                             compatLayoutProperties(option);\r
18048                         });\r
18049                     }\r
18050                 });\r
18051             };\r
18052 \r
18053 \r
18054 /***/ },\r
18055 /* 90 */\r
18056 /***/ function(module, exports, __webpack_require__) {\r
18057 \r
18058         \r
18059 \r
18060             var zrUtil = __webpack_require__(3);\r
18061 \r
18062             var POSSIBLE_STYLES = [\r
18063                 'areaStyle', 'lineStyle', 'nodeStyle', 'linkStyle',\r
18064                 'chordStyle', 'label', 'labelLine'\r
18065             ];\r
18066 \r
18067             function compatItemStyle(opt) {\r
18068                 var itemStyleOpt = opt && opt.itemStyle;\r
18069                 if (itemStyleOpt) {\r
18070                     zrUtil.each(POSSIBLE_STYLES, function (styleName) {\r
18071                         var normalItemStyleOpt = itemStyleOpt.normal;\r
18072                         var emphasisItemStyleOpt = itemStyleOpt.emphasis;\r
18073                         if (normalItemStyleOpt && normalItemStyleOpt[styleName]) {\r
18074                             opt[styleName] = opt[styleName] || {};\r
18075                             if (!opt[styleName].normal) {\r
18076                                 opt[styleName].normal = normalItemStyleOpt[styleName];\r
18077                             }\r
18078                             else {\r
18079                                 zrUtil.merge(opt[styleName].normal, normalItemStyleOpt[styleName]);\r
18080                             }\r
18081                             normalItemStyleOpt[styleName] = null;\r
18082                         }\r
18083                         if (emphasisItemStyleOpt && emphasisItemStyleOpt[styleName]) {\r
18084                             opt[styleName] = opt[styleName] || {};\r
18085                             if (!opt[styleName].emphasis) {\r
18086                                 opt[styleName].emphasis = emphasisItemStyleOpt[styleName];\r
18087                             }\r
18088                             else {\r
18089                                 zrUtil.merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]);\r
18090                             }\r
18091                             emphasisItemStyleOpt[styleName] = null;\r
18092                         }\r
18093                     });\r
18094                 }\r
18095             }\r
18096 \r
18097             module.exports = function (seriesOpt) {\r
18098                 if (!seriesOpt) {\r
18099                     return;\r
18100                 }\r
18101                 compatItemStyle(seriesOpt);\r
18102                 compatItemStyle(seriesOpt.markPoint);\r
18103                 compatItemStyle(seriesOpt.markLine);\r
18104                 var data = seriesOpt.data;\r
18105                 if (data) {\r
18106                     for (var i = 0; i < data.length; i++) {\r
18107                         compatItemStyle(data[i]);\r
18108                     }\r
18109                     // mark point data\r
18110                     var markPoint = seriesOpt.markPoint;\r
18111                     if (markPoint && markPoint.data) {\r
18112                         var mpData = markPoint.data;\r
18113                         for (var i = 0; i < mpData.length; i++) {\r
18114                             compatItemStyle(mpData[i]);\r
18115                         }\r
18116                     }\r
18117                     // mark line data\r
18118                     var markLine = seriesOpt.markLine;\r
18119                     if (markLine && markLine.data) {\r
18120                         var mlData = markLine.data;\r
18121                         for (var i = 0; i < mlData.length; i++) {\r
18122                             if (zrUtil.isArray(mlData[i])) {\r
18123                                 compatItemStyle(mlData[i][0]);\r
18124                                 compatItemStyle(mlData[i][1]);\r
18125                             }\r
18126                             else {\r
18127                                 compatItemStyle(mlData[i]);\r
18128                             }\r
18129                         }\r
18130                     }\r
18131                 }\r
18132             };\r
18133 \r
18134 \r
18135 /***/ },\r
18136 /* 91 */\r
18137 /***/ function(module, exports, __webpack_require__) {\r
18138 \r
18139         \r
18140 \r
18141             var zrUtil = __webpack_require__(3);\r
18142             var echarts = __webpack_require__(1);\r
18143 \r
18144             __webpack_require__(92);\r
18145             __webpack_require__(97);\r
18146 \r
18147             echarts.registerVisualCoding('chart', zrUtil.curry(\r
18148                 __webpack_require__(103), 'line', 'circle', 'line'\r
18149             ));\r
18150             echarts.registerLayout(zrUtil.curry(\r
18151                 __webpack_require__(104), 'line'\r
18152             ));\r
18153 \r
18154             // Down sample after filter\r
18155             echarts.registerProcessor('statistic', zrUtil.curry(\r
18156                 __webpack_require__(105), 'line'\r
18157             ));\r
18158 \r
18159             // In case developer forget to include grid component\r
18160             __webpack_require__(106);\r
18161 \r
18162 \r
18163 /***/ },\r
18164 /* 92 */\r
18165 /***/ function(module, exports, __webpack_require__) {\r
18166 \r
18167         'use strict';\r
18168 \r
18169 \r
18170             var createListFromArray = __webpack_require__(93);\r
18171             var SeriesModel = __webpack_require__(27);\r
18172 \r
18173             module.exports = SeriesModel.extend({\r
18174 \r
18175                 type: 'series.line',\r
18176 \r
18177                 dependencies: ['grid', 'polar'],\r
18178 \r
18179                 getInitialData: function (option, ecModel) {\r
18180                     return createListFromArray(option.data, this, ecModel);\r
18181                 },\r
18182 \r
18183                 defaultOption: {\r
18184                     zlevel: 0,                  // 一级层叠\r
18185                     z: 2,                       // 二级层叠\r
18186                     coordinateSystem: 'cartesian2d',\r
18187                     legendHoverLink: true,\r
18188 \r
18189                     hoverAnimation: true,\r
18190                     // stack: null\r
18191                     xAxisIndex: 0,\r
18192                     yAxisIndex: 0,\r
18193 \r
18194                     polarIndex: 0,\r
18195 \r
18196                     // If clip the overflow value\r
18197                     clipOverflow: true,\r
18198 \r
18199                     label: {\r
18200                         normal: {\r
18201                             // show: false,\r
18202                             position: 'top'\r
18203                             // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
18204                             // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为\r
18205                             //           'inside'|'left'|'right'|'top'|'bottom'\r
18206                             // textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE\r
18207                         }\r
18208                         // emphasis: {\r
18209                             // show: false,\r
18210                             // position: 'top'\r
18211                             // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
18212                             // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为\r
18213                             //           'inside'|'left'|'right'|'top'|'bottom'\r
18214                             // textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE\r
18215                         // }\r
18216                     },\r
18217                     // itemStyle: {\r
18218                     //     normal: {\r
18219                     //         // color: 各异\r
18220                     //     },\r
18221                     //     emphasis: {\r
18222                     //         // color: 各异,\r
18223                     //     }\r
18224                     // },\r
18225                     lineStyle: {\r
18226                         normal: {\r
18227                             width: 2,\r
18228                             type: 'solid'\r
18229                         }\r
18230                     },\r
18231                     // areaStyle: {\r
18232                     // },\r
18233                     // smooth: false,\r
18234                     // smoothMonotone: null,\r
18235                     // 拐点图形类型\r
18236                     symbol: 'emptyCircle',\r
18237                     // 拐点图形大小\r
18238                     symbolSize: 4,\r
18239                     // 拐点图形旋转控制\r
18240                     // symbolRotate: null,\r
18241 \r
18242                     // 是否显示 symbol, 只有在 tooltip hover 的时候显示\r
18243                     showSymbol: true,\r
18244                     // 标志图形默认只有主轴显示(随主轴标签间隔隐藏策略)\r
18245                     // showAllSymbol: false\r
18246                     //\r
18247                     // 大数据过滤,'average', 'max', 'min', 'sum'\r
18248                     // sampling: 'none'\r
18249 \r
18250                     animationEasing: 'linear'\r
18251                 }\r
18252             });\r
18253 \r
18254 \r
18255 /***/ },\r
18256 /* 93 */\r
18257 /***/ function(module, exports, __webpack_require__) {\r
18258 \r
18259         'use strict';\r
18260 \r
18261 \r
18262             var List = __webpack_require__(94);\r
18263             var completeDimensions = __webpack_require__(96);\r
18264             var zrUtil = __webpack_require__(3);\r
18265             var modelUtil = __webpack_require__(5);\r
18266             var CoordinateSystem = __webpack_require__(25);\r
18267             var getDataItemValue = modelUtil.getDataItemValue;\r
18268             var converDataValue = modelUtil.converDataValue;\r
18269 \r
18270             function firstDataNotNull(data) {\r
18271                 var i = 0;\r
18272                 while (i < data.length && data[i] == null) {\r
18273                     i++;\r
18274                 }\r
18275                 return data[i];\r
18276             }\r
18277             function ifNeedCompleteOrdinalData(data) {\r
18278                 var sampleItem = firstDataNotNull(data);\r
18279                 return sampleItem != null\r
18280                     && !zrUtil.isArray(getDataItemValue(sampleItem));\r
18281             }\r
18282 \r
18283             /**\r
18284              * Helper function to create a list from option data\r
18285              */\r
18286             function createListFromArray(data, seriesModel, ecModel) {\r
18287                 // If data is undefined\r
18288                 data = data || [];\r
18289 \r
18290                 var coordSysName = seriesModel.get('coordinateSystem');\r
18291                 var creator = creators[coordSysName];\r
18292                 var registeredCoordSys = CoordinateSystem.get(coordSysName);\r
18293                 // FIXME\r
18294                 var result = creator && creator(data, seriesModel, ecModel);\r
18295                 var dimensions = result && result.dimensions;\r
18296                 if (!dimensions) {\r
18297                     // Get dimensions from registered coordinate system\r
18298                     dimensions = (registeredCoordSys && registeredCoordSys.dimensions) || ['x', 'y'];\r
18299                     dimensions = completeDimensions(dimensions, data, dimensions.concat(['value']));\r
18300                 }\r
18301                 var categoryAxisModel = result && result.categoryAxisModel;\r
18302 \r
18303                 var categoryDimIndex = dimensions[0].type === 'ordinal'\r
18304                     ? 0 : (dimensions[1].type === 'ordinal' ? 1 : -1);\r
18305 \r
18306                 var list = new List(dimensions, seriesModel);\r
18307 \r
18308                 var nameList = createNameList(result, data);\r
18309 \r
18310                 var dimValueGetter = (categoryAxisModel && ifNeedCompleteOrdinalData(data))\r
18311                     ? function (itemOpt, dimName, dataIndex, dimIndex) {\r
18312                         // Use dataIndex as ordinal value in categoryAxis\r
18313                         return dimIndex === categoryDimIndex\r
18314                             ? dataIndex\r
18315                             : converDataValue(getDataItemValue(itemOpt), dimensions[dimIndex]);\r
18316                     }\r
18317                     : function (itemOpt, dimName, dataIndex, dimIndex) {\r
18318                         var val = getDataItemValue(itemOpt);\r
18319                         return converDataValue(val && val[dimIndex], dimensions[dimIndex]);\r
18320                     };\r
18321 \r
18322                 list.initData(data, nameList, dimValueGetter);\r
18323 \r
18324                 return list;\r
18325             }\r
18326 \r
18327             function isStackable(axisType) {\r
18328                 return axisType !== 'category' && axisType !== 'time';\r
18329             }\r
18330 \r
18331             function getDimTypeByAxis(axisType) {\r
18332                 return axisType === 'category'\r
18333                     ? 'ordinal'\r
18334                     : axisType === 'time'\r
18335                     ? 'time'\r
18336                     : 'float';\r
18337             }\r
18338 \r
18339             /**\r
18340              * Creaters for each coord system.\r
18341              * @return {Object} {dimensions, categoryAxisModel};\r
18342              */\r
18343             var creators = {\r
18344 \r
18345                 cartesian2d: function (data, seriesModel, ecModel) {\r
18346                     var xAxisModel = ecModel.getComponent('xAxis', seriesModel.get('xAxisIndex'));\r
18347                     var yAxisModel = ecModel.getComponent('yAxis', seriesModel.get('yAxisIndex'));\r
18348                     var xAxisType = xAxisModel.get('type');\r
18349                     var yAxisType = yAxisModel.get('type');\r
18350 \r
18351                     var dimensions = [\r
18352                         {\r
18353                             name: 'x',\r
18354                             type: getDimTypeByAxis(xAxisType),\r
18355                             stackable: isStackable(xAxisType)\r
18356                         },\r
18357                         {\r
18358                             name: 'y',\r
18359                             // If two category axes\r
18360                             type: getDimTypeByAxis(yAxisType),\r
18361                             stackable: isStackable(yAxisType)\r
18362                         }\r
18363                     ];\r
18364 \r
18365                     var isXAxisCateogry = xAxisType === 'category';\r
18366 \r
18367                     completeDimensions(dimensions, data, ['x', 'y', 'z']);\r
18368 \r
18369                     return {\r
18370                         dimensions: dimensions,\r
18371                         categoryIndex: isXAxisCateogry ? 0 : 1,\r
18372                         categoryAxisModel: isXAxisCateogry\r
18373                             ? xAxisModel\r
18374                             : (yAxisType === 'category' ? yAxisModel : null)\r
18375                     };\r
18376                 },\r
18377 \r
18378                 polar: function (data, seriesModel, ecModel) {\r
18379                     var polarIndex = seriesModel.get('polarIndex') || 0;\r
18380 \r
18381                     var axisFinder = function (axisModel) {\r
18382                         return axisModel.get('polarIndex') === polarIndex;\r
18383                     };\r
18384 \r
18385                     var angleAxisModel = ecModel.findComponents({\r
18386                         mainType: 'angleAxis', filter: axisFinder\r
18387                     })[0];\r
18388                     var radiusAxisModel = ecModel.findComponents({\r
18389                         mainType: 'radiusAxis', filter: axisFinder\r
18390                     })[0];\r
18391 \r
18392                     var radiusAxisType = radiusAxisModel.get('type');\r
18393                     var angleAxisType = angleAxisModel.get('type');\r
18394 \r
18395                     var dimensions = [\r
18396                         {\r
18397                             name: 'radius',\r
18398                             type: getDimTypeByAxis(radiusAxisType),\r
18399                             stackable: isStackable(radiusAxisType)\r
18400                         },\r
18401                         {\r
18402                             name: 'angle',\r
18403                             type: getDimTypeByAxis(angleAxisType),\r
18404                             stackable: isStackable(angleAxisType)\r
18405                         }\r
18406                     ];\r
18407                     var isAngleAxisCateogry = angleAxisType === 'category';\r
18408 \r
18409                     completeDimensions(dimensions, data, ['radius', 'angle', 'value']);\r
18410 \r
18411                     return {\r
18412                         dimensions: dimensions,\r
18413                         categoryIndex: isAngleAxisCateogry ? 1 : 0,\r
18414                         categoryAxisModel: isAngleAxisCateogry\r
18415                             ? angleAxisModel\r
18416                             : (radiusAxisType === 'category' ? radiusAxisModel : null)\r
18417                     };\r
18418                 },\r
18419 \r
18420                 geo: function (data, seriesModel, ecModel) {\r
18421                     // TODO Region\r
18422                     // 多个散点图系列在同一个地区的时候\r
18423                     return {\r
18424                         dimensions: completeDimensions([\r
18425                             {name: 'lng'},\r
18426                             {name: 'lat'}\r
18427                         ], data, ['lng', 'lat', 'value'])\r
18428                     };\r
18429                 }\r
18430             };\r
18431 \r
18432             function createNameList(result, data) {\r
18433                 var nameList = [];\r
18434 \r
18435                 if (result && result.categoryAxisModel) {\r
18436                     // FIXME Two category axis\r
18437                     var categories = result.categoryAxisModel.getCategories();\r
18438                     if (categories) {\r
18439                         var dataLen = data.length;\r
18440                         // Ordered data is given explicitly like\r
18441                         // [[3, 0.2], [1, 0.3], [2, 0.15]]\r
18442                         // or given scatter data,\r
18443                         // pick the category\r
18444                         if (zrUtil.isArray(data[0]) && data[0].length > 1) {\r
18445                             nameList = [];\r
18446                             for (var i = 0; i < dataLen; i++) {\r
18447                                 nameList[i] = categories[data[i][result.categoryIndex || 0]];\r
18448                             }\r
18449                         }\r
18450                         else {\r
18451                             nameList = categories.slice(0);\r
18452                         }\r
18453                     }\r
18454                 }\r
18455 \r
18456                 return nameList;\r
18457             }\r
18458 \r
18459             module.exports = createListFromArray;\r
18460 \r
18461 \r
18462 \r
18463 /***/ },\r
18464 /* 94 */\r
18465 /***/ function(module, exports, __webpack_require__) {\r
18466 \r
18467         /* WEBPACK VAR INJECTION */(function(global) {/**\r
18468          * List for data storage\r
18469          * @module echarts/data/List\r
18470          */\r
18471 \r
18472 \r
18473             var UNDEFINED = 'undefined';\r
18474             var globalObj = typeof window === 'undefined' ? global : window;\r
18475             var Float64Array = typeof globalObj.Float64Array === UNDEFINED\r
18476                 ? Array : globalObj.Float64Array;\r
18477             var Int32Array = typeof globalObj.Int32Array === UNDEFINED\r
18478                 ? Array : globalObj.Int32Array;\r
18479 \r
18480             var dataCtors = {\r
18481                 'float': Float64Array,\r
18482                 'int': Int32Array,\r
18483                 // Ordinal data type can be string or int\r
18484                 'ordinal': Array,\r
18485                 'number': Array,\r
18486                 'time': Array\r
18487             };\r
18488 \r
18489             var Model = __webpack_require__(8);\r
18490             var DataDiffer = __webpack_require__(95);\r
18491 \r
18492             var zrUtil = __webpack_require__(3);\r
18493             var modelUtil = __webpack_require__(5);\r
18494             var isObject = zrUtil.isObject;\r
18495 \r
18496             var IMMUTABLE_PROPERTIES = [\r
18497                 'stackedOn', '_nameList', '_idList', '_rawData'\r
18498             ];\r
18499 \r
18500             var transferImmuProperties = function (a, b, wrappedMethod) {\r
18501                 zrUtil.each(IMMUTABLE_PROPERTIES.concat(wrappedMethod || []), function (propName) {\r
18502                     if (b.hasOwnProperty(propName)) {\r
18503                         a[propName] = b[propName];\r
18504                     }\r
18505                 });\r
18506             };\r
18507 \r
18508             /**\r
18509              * @constructor\r
18510              * @alias module:echarts/data/List\r
18511              *\r
18512              * @param {Array.<string>} dimensions\r
18513              *        Dimensions should be concrete names like x, y, z, lng, lat, angle, radius\r
18514              * @param {module:echarts/model/Model} hostModel\r
18515              */\r
18516             var List = function (dimensions, hostModel) {\r
18517 \r
18518                 dimensions = dimensions || ['x', 'y'];\r
18519 \r
18520                 var dimensionInfos = {};\r
18521                 var dimensionNames = [];\r
18522                 for (var i = 0; i < dimensions.length; i++) {\r
18523                     var dimensionName;\r
18524                     var dimensionInfo = {};\r
18525                     if (typeof dimensions[i] === 'string') {\r
18526                         dimensionName = dimensions[i];\r
18527                         dimensionInfo = {\r
18528                             name: dimensionName,\r
18529                             stackable: false,\r
18530                             // Type can be 'float', 'int', 'number'\r
18531                             // Default is number, Precision of float may not enough\r
18532                             type: 'number'\r
18533                         };\r
18534                     }\r
18535                     else {\r
18536                         dimensionInfo = dimensions[i];\r
18537                         dimensionName = dimensionInfo.name;\r
18538                         dimensionInfo.type = dimensionInfo.type || 'number';\r
18539                     }\r
18540                     dimensionNames.push(dimensionName);\r
18541                     dimensionInfos[dimensionName] = dimensionInfo;\r
18542                 }\r
18543                 /**\r
18544                  * @readOnly\r
18545                  * @type {Array.<string>}\r
18546                  */\r
18547                 this.dimensions = dimensionNames;\r
18548 \r
18549                 /**\r
18550                  * Infomation of each data dimension, like data type.\r
18551                  * @type {Object}\r
18552                  */\r
18553                 this._dimensionInfos = dimensionInfos;\r
18554 \r
18555                 /**\r
18556                  * @type {module:echarts/model/Model}\r
18557                  */\r
18558                 this.hostModel = hostModel;\r
18559 \r
18560                 /**\r
18561                  * Indices stores the indices of data subset after filtered.\r
18562                  * This data subset will be used in chart.\r
18563                  * @type {Array.<number>}\r
18564                  * @readOnly\r
18565                  */\r
18566                 this.indices = [];\r
18567 \r
18568                 /**\r
18569                  * Data storage\r
18570                  * @type {Object.<key, TypedArray|Array>}\r
18571                  * @private\r
18572                  */\r
18573                 this._storage = {};\r
18574 \r
18575                 /**\r
18576                  * @type {Array.<string>}\r
18577                  */\r
18578                 this._nameList = [];\r
18579                 /**\r
18580                  * @type {Array.<string>}\r
18581                  */\r
18582                 this._idList = [];\r
18583                 /**\r
18584                  * Models of data option is stored sparse for optimizing memory cost\r
18585                  * @type {Array.<module:echarts/model/Model>}\r
18586                  * @private\r
18587                  */\r
18588                 this._optionModels = [];\r
18589 \r
18590                 /**\r
18591                  * @param {module:echarts/data/List}\r
18592                  */\r
18593                 this.stackedOn = null;\r
18594 \r
18595                 /**\r
18596                  * Global visual properties after visual coding\r
18597                  * @type {Object}\r
18598                  * @private\r
18599                  */\r
18600                 this._visual = {};\r
18601 \r
18602                 /**\r
18603                  * Globel layout properties.\r
18604                  * @type {Object}\r
18605                  * @private\r
18606                  */\r
18607                 this._layout = {};\r
18608 \r
18609                 /**\r
18610                  * Item visual properties after visual coding\r
18611                  * @type {Array.<Object>}\r
18612                  * @private\r
18613                  */\r
18614                 this._itemVisuals = [];\r
18615 \r
18616                 /**\r
18617                  * Item layout properties after layout\r
18618                  * @type {Array.<Object>}\r
18619                  * @private\r
18620                  */\r
18621                 this._itemLayouts = [];\r
18622 \r
18623                 /**\r
18624                  * Graphic elemnents\r
18625                  * @type {Array.<module:zrender/Element>}\r
18626                  * @private\r
18627                  */\r
18628                 this._graphicEls = [];\r
18629 \r
18630                 /**\r
18631                  * @type {Array.<Array|Object>}\r
18632                  * @private\r
18633                  */\r
18634                 this._rawData;\r
18635 \r
18636                 /**\r
18637                  * @type {Object}\r
18638                  * @private\r
18639                  */\r
18640                 this._extent;\r
18641             };\r
18642 \r
18643             var listProto = List.prototype;\r
18644 \r
18645             listProto.type = 'list';\r
18646 \r
18647             /**\r
18648              * Get dimension name\r
18649              * @param {string|number} dim\r
18650              *        Dimension can be concrete names like x, y, z, lng, lat, angle, radius\r
18651              *        Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius'\r
18652              */\r
18653             listProto.getDimension = function (dim) {\r
18654                 if (!isNaN(dim)) {\r
18655                     dim = this.dimensions[dim] || dim;\r
18656                 }\r
18657                 return dim;\r
18658             };\r
18659             /**\r
18660              * Get type and stackable info of particular dimension\r
18661              * @param {string|number} dim\r
18662              *        Dimension can be concrete names like x, y, z, lng, lat, angle, radius\r
18663              *        Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius'\r
18664              */\r
18665             listProto.getDimensionInfo = function (dim) {\r
18666                 return zrUtil.clone(this._dimensionInfos[this.getDimension(dim)]);\r
18667             };\r
18668 \r
18669             /**\r
18670              * Initialize from data\r
18671              * @param {Array.<Object|number|Array>} data\r
18672              * @param {Array.<string>} [nameList]\r
18673              * @param {Function} [dimValueGetter] (dataItem, dimName, dataIndex, dimIndex) => number\r
18674              */\r
18675             listProto.initData = function (data, nameList, dimValueGetter) {\r
18676                 data = data || [];\r
18677 \r
18678                 this._rawData = data;\r
18679 \r
18680                 // Clear\r
18681                 var storage = this._storage = {};\r
18682                 var indices = this.indices = [];\r
18683 \r
18684                 var dimensions = this.dimensions;\r
18685                 var size = data.length;\r
18686                 var dimensionInfoMap = this._dimensionInfos;\r
18687 \r
18688                 var idList = [];\r
18689                 var nameRepeatCount = {};\r
18690 \r
18691                 nameList = nameList || [];\r
18692 \r
18693                 // Init storage\r
18694                 for (var i = 0; i < dimensions.length; i++) {\r
18695                     var dimInfo = dimensionInfoMap[dimensions[i]];\r
18696                     var DataCtor = dataCtors[dimInfo.type];\r
18697                     storage[dimensions[i]] = new DataCtor(size);\r
18698                 }\r
18699 \r
18700                 // Default dim value getter\r
18701                 dimValueGetter = dimValueGetter || function (dataItem, dimName, dataIndex, dimIndex) {\r
18702                     var value = modelUtil.getDataItemValue(dataItem);\r
18703                     return modelUtil.converDataValue(\r
18704                         zrUtil.isArray(value)\r
18705                             ? value[dimIndex]\r
18706                             // If value is a single number or something else not array.\r
18707                             : value,\r
18708                         dimensionInfoMap[dimName]\r
18709                     );\r
18710                 };\r
18711 \r
18712                 for (var idx = 0; idx < data.length; idx++) {\r
18713                     var dataItem = data[idx];\r
18714                     // Each data item is value\r
18715                     // [1, 2]\r
18716                     // 2\r
18717                     // Bar chart, line chart which uses category axis\r
18718                     // only gives the 'y' value. 'x' value is the indices of cateogry\r
18719                     // Use a tempValue to normalize the value to be a (x, y) value\r
18720 \r
18721                     // Store the data by dimensions\r
18722                     for (var k = 0; k < dimensions.length; k++) {\r
18723                         var dim = dimensions[k];\r
18724                         var dimStorage = storage[dim];\r
18725                         // PENDING NULL is empty or zero\r
18726                         dimStorage[idx] = dimValueGetter(dataItem, dim, idx, k);\r
18727                     }\r
18728 \r
18729                     indices.push(idx);\r
18730                 }\r
18731 \r
18732                 // Use the name in option and create id\r
18733                 for (var i = 0; i < data.length; i++) {\r
18734                     var id = '';\r
18735                     if (!nameList[i]) {\r
18736                         nameList[i] = data[i].name;\r
18737                         // Try using the id in option\r
18738                         id = data[i].id;\r
18739                     }\r
18740                     var name = nameList[i] || '';\r
18741                     if (!id && name) {\r
18742                         // Use name as id and add counter to avoid same name\r
18743                         nameRepeatCount[name] = nameRepeatCount[name] || 0;\r
18744                         id = name;\r
18745                         if (nameRepeatCount[name] > 0) {\r
18746                             id += '__ec__' + nameRepeatCount[name];\r
18747                         }\r
18748                         nameRepeatCount[name]++;\r
18749                     }\r
18750                     id && (idList[i] = id);\r
18751                 }\r
18752 \r
18753                 this._nameList = nameList;\r
18754                 this._idList = idList;\r
18755             };\r
18756 \r
18757             /**\r
18758              * @return {number}\r
18759              */\r
18760             listProto.count = function () {\r
18761                 return this.indices.length;\r
18762             };\r
18763 \r
18764             /**\r
18765              * Get value. Return NaN if idx is out of range.\r
18766              * @param {string} dim Dim must be concrete name.\r
18767              * @param {number} idx\r
18768              * @param {boolean} stack\r
18769              * @return {number}\r
18770              */\r
18771             listProto.get = function (dim, idx, stack) {\r
18772                 var storage = this._storage;\r
18773                 var dataIndex = this.indices[idx];\r
18774 \r
18775                 // If value not exists\r
18776                 if (dataIndex == null) {\r
18777                     return NaN;\r
18778                 }\r
18779 \r
18780                 var value = storage[dim] && storage[dim][dataIndex];\r
18781                 // FIXME ordinal data type is not stackable\r
18782                 if (stack) {\r
18783                     var dimensionInfo = this._dimensionInfos[dim];\r
18784                     if (dimensionInfo && dimensionInfo.stackable) {\r
18785                         var stackedOn = this.stackedOn;\r
18786                         while (stackedOn) {\r
18787                             // Get no stacked data of stacked on\r
18788                             var stackedValue = stackedOn.get(dim, idx);\r
18789                             // Considering positive stack, negative stack and empty data\r
18790                             if ((value >= 0 && stackedValue > 0)  // Positive stack\r
18791                                 || (value <= 0 && stackedValue < 0) // Negative stack\r
18792                             ) {\r
18793                                 value += stackedValue;\r
18794                             }\r
18795                             stackedOn = stackedOn.stackedOn;\r
18796                         }\r
18797                     }\r
18798                 }\r
18799                 return value;\r
18800             };\r
18801 \r
18802             /**\r
18803              * Get value for multi dimensions.\r
18804              * @param {Array.<string>} [dimensions] If ignored, using all dimensions.\r
18805              * @param {number} idx\r
18806              * @param {boolean} stack\r
18807              * @return {number}\r
18808              */\r
18809             listProto.getValues = function (dimensions, idx, stack) {\r
18810                 var values = [];\r
18811 \r
18812                 if (!zrUtil.isArray(dimensions)) {\r
18813                     stack = idx;\r
18814                     idx = dimensions;\r
18815                     dimensions = this.dimensions;\r
18816                 }\r
18817 \r
18818                 for (var i = 0, len = dimensions.length; i < len; i++) {\r
18819                     values.push(this.get(dimensions[i], idx, stack));\r
18820                 }\r
18821 \r
18822                 return values;\r
18823             };\r
18824 \r
18825             /**\r
18826              * If value is NaN. Inlcuding '-'\r
18827              * @param {string} dim\r
18828              * @param {number} idx\r
18829              * @return {number}\r
18830              */\r
18831             listProto.hasValue = function (idx) {\r
18832                 var dimensions = this.dimensions;\r
18833                 var dimensionInfos = this._dimensionInfos;\r
18834                 for (var i = 0, len = dimensions.length; i < len; i++) {\r
18835                     if (\r
18836                         // Ordinal type can be string or number\r
18837                         dimensionInfos[dimensions[i]].type !== 'ordinal'\r
18838                         && isNaN(this.get(dimensions[i], idx))\r
18839                     ) {\r
18840                         return false;\r
18841                     }\r
18842                 }\r
18843                 return true;\r
18844             };\r
18845 \r
18846             /**\r
18847              * Get extent of data in one dimension\r
18848              * @param {string} dim\r
18849              * @param {boolean} stack\r
18850              */\r
18851             listProto.getDataExtent = function (dim, stack) {\r
18852                 var dimData = this._storage[dim];\r
18853                 var dimInfo = this.getDimensionInfo(dim);\r
18854                 stack = (dimInfo && dimInfo.stackable) && stack;\r
18855                 var dimExtent = (this._extent || (this._extent = {}))[dim + (!!stack)];\r
18856                 var value;\r
18857                 if (dimExtent) {\r
18858                     return dimExtent;\r
18859                 }\r
18860                 // var dimInfo = this._dimensionInfos[dim];\r
18861                 if (dimData) {\r
18862                     var min = Infinity;\r
18863                     var max = -Infinity;\r
18864                     // var isOrdinal = dimInfo.type === 'ordinal';\r
18865                     for (var i = 0, len = this.count(); i < len; i++) {\r
18866                         value = this.get(dim, i, stack);\r
18867                         // FIXME\r
18868                         // if (isOrdinal && typeof value === 'string') {\r
18869                         //     value = zrUtil.indexOf(dimData, value);\r
18870                         //     console.log(value);\r
18871                         // }\r
18872                         value < min && (min = value);\r
18873                         value > max && (max = value);\r
18874                     }\r
18875                     return (this._extent[dim + stack] = [min, max]);\r
18876                 }\r
18877                 else {\r
18878                     return [Infinity, -Infinity];\r
18879                 }\r
18880             };\r
18881 \r
18882             /**\r
18883              * Get sum of data in one dimension\r
18884              * @param {string} dim\r
18885              * @param {boolean} stack\r
18886              */\r
18887             listProto.getSum = function (dim, stack) {\r
18888                 var dimData = this._storage[dim];\r
18889                 var sum = 0;\r
18890                 if (dimData) {\r
18891                     for (var i = 0, len = this.count(); i < len; i++) {\r
18892                         var value = this.get(dim, i, stack);\r
18893                         if (!isNaN(value)) {\r
18894                             sum += value;\r
18895                         }\r
18896                     }\r
18897                 }\r
18898                 return sum;\r
18899             };\r
18900 \r
18901             /**\r
18902              * Retreive the index with given value\r
18903              * @param {number} idx\r
18904              * @param {number} value\r
18905              * @return {number}\r
18906              */\r
18907             // FIXME Precision of float value\r
18908             listProto.indexOf = function (dim, value) {\r
18909                 var storage = this._storage;\r
18910                 var dimData = storage[dim];\r
18911                 var indices = this.indices;\r
18912 \r
18913                 if (dimData) {\r
18914                     for (var i = 0, len = indices.length; i < len; i++) {\r
18915                         var rawIndex = indices[i];\r
18916                         if (dimData[rawIndex] === value) {\r
18917                             return i;\r
18918                         }\r
18919                     }\r
18920                 }\r
18921                 return -1;\r
18922             };\r
18923 \r
18924             /**\r
18925              * Retreive the index with given name\r
18926              * @param {number} idx\r
18927              * @param {number} name\r
18928              * @return {number}\r
18929              */\r
18930             listProto.indexOfName = function (name) {\r
18931                 var indices = this.indices;\r
18932                 var nameList = this._nameList;\r
18933 \r
18934                 for (var i = 0, len = indices.length; i < len; i++) {\r
18935                     var rawIndex = indices[i];\r
18936                     if (nameList[rawIndex] === name) {\r
18937                         return i;\r
18938                     }\r
18939                 }\r
18940 \r
18941                 return -1;\r
18942             };\r
18943 \r
18944             /**\r
18945              * Retreive the index of nearest value\r
18946              * @param {string>} dim\r
18947              * @param {number} value\r
18948              * @param {boolean} stack If given value is after stacked\r
18949              * @return {number}\r
18950              */\r
18951             listProto.indexOfNearest = function (dim, value, stack) {\r
18952                 var storage = this._storage;\r
18953                 var dimData = storage[dim];\r
18954 \r
18955                 if (dimData) {\r
18956                     var minDist = Number.MAX_VALUE;\r
18957                     var nearestIdx = -1;\r
18958                     for (var i = 0, len = this.count(); i < len; i++) {\r
18959                         var diff = value - this.get(dim, i, stack);\r
18960                         var dist = Math.abs(diff);\r
18961                         if (dist < minDist\r
18962                             // For the case of two data are same on xAxis, which has sequence data.\r
18963                             // Show the nearest index\r
18964                             // https://github.com/ecomfe/echarts/issues/2869\r
18965                             || (dist === minDist && diff > 0)\r
18966                         ) {\r
18967                             minDist = dist;\r
18968                             nearestIdx = i;\r
18969                         }\r
18970                     }\r
18971                     return nearestIdx;\r
18972                 }\r
18973                 return -1;\r
18974             };\r
18975 \r
18976             /**\r
18977              * Get raw data index\r
18978              * @param {number} idx\r
18979              * @return {number}\r
18980              */\r
18981             listProto.getRawIndex = function (idx) {\r
18982                 var rawIdx = this.indices[idx];\r
18983                 return rawIdx == null ? -1 : rawIdx;\r
18984             };\r
18985 \r
18986             /**\r
18987              * @param {number} idx\r
18988              * @param {boolean} [notDefaultIdx=false]\r
18989              * @return {string}\r
18990              */\r
18991             listProto.getName = function (idx) {\r
18992                 return this._nameList[this.indices[idx]] || '';\r
18993             };\r
18994 \r
18995             /**\r
18996              * @param {number} idx\r
18997              * @param {boolean} [notDefaultIdx=false]\r
18998              * @return {string}\r
18999              */\r
19000             listProto.getId = function (idx) {\r
19001                 return this._idList[this.indices[idx]] || (this.getRawIndex(idx) + '');\r
19002             };\r
19003 \r
19004 \r
19005             function normalizeDimensions(dimensions) {\r
19006                 if (!zrUtil.isArray(dimensions)) {\r
19007                     dimensions = [dimensions];\r
19008                 }\r
19009                 return dimensions;\r
19010             }\r
19011 \r
19012             /**\r
19013              * Data iteration\r
19014              * @param {string|Array.<string>}\r
19015              * @param {Function} cb\r
19016              * @param {boolean} [stack=false]\r
19017              * @param {*} [context=this]\r
19018              *\r
19019              * @example\r
19020              *  list.each('x', function (x, idx) {});\r
19021              *  list.each(['x', 'y'], function (x, y, idx) {});\r
19022              *  list.each(function (idx) {})\r
19023              */\r
19024             listProto.each = function (dimensions, cb, stack, context) {\r
19025                 if (typeof dimensions === 'function') {\r
19026                     context = stack;\r
19027                     stack = cb;\r
19028                     cb = dimensions;\r
19029                     dimensions = [];\r
19030                 }\r
19031 \r
19032                 dimensions = zrUtil.map(\r
19033                     normalizeDimensions(dimensions), this.getDimension, this\r
19034                 );\r
19035 \r
19036                 var value = [];\r
19037                 var dimSize = dimensions.length;\r
19038                 var indices = this.indices;\r
19039 \r
19040                 context = context || this;\r
19041 \r
19042                 for (var i = 0; i < indices.length; i++) {\r
19043                     if (dimSize === 0) {\r
19044                         cb.call(context, i);\r
19045                     }\r
19046                     // Simple optimization\r
19047                     else if (dimSize === 1) {\r
19048                         cb.call(context, this.get(dimensions[0], i, stack), i);\r
19049                     }\r
19050                     else {\r
19051                         for (var k = 0; k < dimSize; k++) {\r
19052                             value[k] = this.get(dimensions[k], i, stack);\r
19053                         }\r
19054                         // Index\r
19055                         value[k] = i;\r
19056                         cb.apply(context, value);\r
19057                     }\r
19058                 }\r
19059             };\r
19060 \r
19061             /**\r
19062              * Data filter\r
19063              * @param {string|Array.<string>}\r
19064              * @param {Function} cb\r
19065              * @param {boolean} [stack=false]\r
19066              * @param {*} [context=this]\r
19067              */\r
19068             listProto.filterSelf = function (dimensions, cb, stack, context) {\r
19069                 if (typeof dimensions === 'function') {\r
19070                     context = stack;\r
19071                     stack = cb;\r
19072                     cb = dimensions;\r
19073                     dimensions = [];\r
19074                 }\r
19075 \r
19076                 dimensions = zrUtil.map(\r
19077                     normalizeDimensions(dimensions), this.getDimension, this\r
19078                 );\r
19079 \r
19080                 var newIndices = [];\r
19081                 var value = [];\r
19082                 var dimSize = dimensions.length;\r
19083                 var indices = this.indices;\r
19084 \r
19085                 context = context || this;\r
19086 \r
19087                 for (var i = 0; i < indices.length; i++) {\r
19088                     var keep;\r
19089                     // Simple optimization\r
19090                     if (dimSize === 1) {\r
19091                         keep = cb.call(\r
19092                             context, this.get(dimensions[0], i, stack), i\r
19093                         );\r
19094                     }\r
19095                     else {\r
19096                         for (var k = 0; k < dimSize; k++) {\r
19097                             value[k] = this.get(dimensions[k], i, stack);\r
19098                         }\r
19099                         value[k] = i;\r
19100                         keep = cb.apply(context, value);\r
19101                     }\r
19102                     if (keep) {\r
19103                         newIndices.push(indices[i]);\r
19104                     }\r
19105                 }\r
19106 \r
19107                 this.indices = newIndices;\r
19108 \r
19109                 // Reset data extent\r
19110                 this._extent = {};\r
19111 \r
19112                 return this;\r
19113             };\r
19114 \r
19115             /**\r
19116              * Data mapping to a plain array\r
19117              * @param {string|Array.<string>} [dimensions]\r
19118              * @param {Function} cb\r
19119              * @param {boolean} [stack=false]\r
19120              * @param {*} [context=this]\r
19121              * @return {Array}\r
19122              */\r
19123             listProto.mapArray = function (dimensions, cb, stack, context) {\r
19124                 if (typeof dimensions === 'function') {\r
19125                     context = stack;\r
19126                     stack = cb;\r
19127                     cb = dimensions;\r
19128                     dimensions = [];\r
19129                 }\r
19130 \r
19131                 var result = [];\r
19132                 this.each(dimensions, function () {\r
19133                     result.push(cb && cb.apply(this, arguments));\r
19134                 }, stack, context);\r
19135                 return result;\r
19136             };\r
19137 \r
19138             function cloneListForMapAndSample(original, excludeDimensions) {\r
19139                 var allDimensions = original.dimensions;\r
19140                 var list = new List(\r
19141                     zrUtil.map(allDimensions, original.getDimensionInfo, original),\r
19142                     original.hostModel\r
19143                 );\r
19144                 // FIXME If needs stackedOn, value may already been stacked\r
19145                 transferImmuProperties(list, original, original._wrappedMethods);\r
19146 \r
19147                 var storage = list._storage = {};\r
19148                 var originalStorage = original._storage;\r
19149                 // Init storage\r
19150                 for (var i = 0; i < allDimensions.length; i++) {\r
19151                     var dim = allDimensions[i];\r
19152                     var dimStore = originalStorage[dim];\r
19153                     if (zrUtil.indexOf(excludeDimensions, dim) >= 0) {\r
19154                         storage[dim] = new dimStore.constructor(\r
19155                             originalStorage[dim].length\r
19156                         );\r
19157                     }\r
19158                     else {\r
19159                         // Direct reference for other dimensions\r
19160                         storage[dim] = originalStorage[dim];\r
19161                     }\r
19162                 }\r
19163                 return list;\r
19164             }\r
19165 \r
19166             /**\r
19167              * Data mapping to a new List with given dimensions\r
19168              * @param {string|Array.<string>} dimensions\r
19169              * @param {Function} cb\r
19170              * @param {boolean} [stack=false]\r
19171              * @param {*} [context=this]\r
19172              * @return {Array}\r
19173              */\r
19174             listProto.map = function (dimensions, cb, stack, context) {\r
19175                 dimensions = zrUtil.map(\r
19176                     normalizeDimensions(dimensions), this.getDimension, this\r
19177                 );\r
19178 \r
19179                 var list = cloneListForMapAndSample(this, dimensions);\r
19180                 // Following properties are all immutable.\r
19181                 // So we can reference to the same value\r
19182                 var indices = list.indices = this.indices;\r
19183 \r
19184                 var storage = list._storage;\r
19185 \r
19186                 var tmpRetValue = [];\r
19187                 this.each(dimensions, function () {\r
19188                     var idx = arguments[arguments.length - 1];\r
19189                     var retValue = cb && cb.apply(this, arguments);\r
19190                     if (retValue != null) {\r
19191                         // a number\r
19192                         if (typeof retValue === 'number') {\r
19193                             tmpRetValue[0] = retValue;\r
19194                             retValue = tmpRetValue;\r
19195                         }\r
19196                         for (var i = 0; i < retValue.length; i++) {\r
19197                             var dim = dimensions[i];\r
19198                             var dimStore = storage[dim];\r
19199                             var rawIdx = indices[idx];\r
19200                             if (dimStore) {\r
19201                                 dimStore[rawIdx] = retValue[i];\r
19202                             }\r
19203                         }\r
19204                     }\r
19205                 }, stack, context);\r
19206 \r
19207                 return list;\r
19208             };\r
19209 \r
19210             /**\r
19211              * Large data down sampling on given dimension\r
19212              * @param {string} dimension\r
19213              * @param {number} rate\r
19214              * @param {Function} sampleValue\r
19215              * @param {Function} sampleIndex Sample index for name and id\r
19216              */\r
19217             listProto.downSample = function (dimension, rate, sampleValue, sampleIndex) {\r
19218                 var list = cloneListForMapAndSample(this, [dimension]);\r
19219                 var storage = this._storage;\r
19220                 var targetStorage = list._storage;\r
19221 \r
19222                 var originalIndices = this.indices;\r
19223                 var indices = list.indices = [];\r
19224 \r
19225                 var frameValues = [];\r
19226                 var frameIndices = [];\r
19227                 var frameSize = Math.floor(1 / rate);\r
19228 \r
19229                 var dimStore = targetStorage[dimension];\r
19230                 var len = this.count();\r
19231                 // Copy data from original data\r
19232                 for (var i = 0; i < storage[dimension].length; i++) {\r
19233                     targetStorage[dimension][i] = storage[dimension][i];\r
19234                 }\r
19235                 for (var i = 0; i < len; i += frameSize) {\r
19236                     // Last frame\r
19237                     if (frameSize > len - i) {\r
19238                         frameSize = len - i;\r
19239                         frameValues.length = frameSize;\r
19240                     }\r
19241                     for (var k = 0; k < frameSize; k++) {\r
19242                         var idx = originalIndices[i + k];\r
19243                         frameValues[k] = dimStore[idx];\r
19244                         frameIndices[k] = idx;\r
19245                     }\r
19246                     var value = sampleValue(frameValues);\r
19247                     var idx = frameIndices[sampleIndex(frameValues, value) || 0];\r
19248                     // Only write value on the filtered data\r
19249                     dimStore[idx] = value;\r
19250                     indices.push(idx);\r
19251                 }\r
19252                 return list;\r
19253             };\r
19254 \r
19255             /**\r
19256              * Get model of one data item.\r
19257              *\r
19258              * @param {number} idx\r
19259              */\r
19260             // FIXME Model proxy ?\r
19261             listProto.getItemModel = function (idx) {\r
19262                 var hostModel = this.hostModel;\r
19263                 idx = this.indices[idx];\r
19264                 return new Model(this._rawData[idx], hostModel, hostModel.ecModel);\r
19265             };\r
19266 \r
19267             /**\r
19268              * Create a data differ\r
19269              * @param {module:echarts/data/List} otherList\r
19270              * @return {module:echarts/data/DataDiffer}\r
19271              */\r
19272             listProto.diff = function (otherList) {\r
19273                 var idList = this._idList;\r
19274                 var otherIdList = otherList && otherList._idList;\r
19275                 return new DataDiffer(\r
19276                     otherList ? otherList.indices : [], this.indices, function (idx) {\r
19277                         return otherIdList[idx] || (idx + '');\r
19278                     }, function (idx) {\r
19279                         return idList[idx] || (idx + '');\r
19280                     }\r
19281                 );\r
19282             };\r
19283             /**\r
19284              * Get visual property.\r
19285              * @param {string} key\r
19286              */\r
19287             listProto.getVisual = function (key) {\r
19288                 var visual = this._visual;\r
19289                 return visual && visual[key];\r
19290             };\r
19291 \r
19292             /**\r
19293              * Set visual property\r
19294              * @param {string|Object} key\r
19295              * @param {*} [value]\r
19296              *\r
19297              * @example\r
19298              *  setVisual('color', color);\r
19299              *  setVisual({\r
19300              *      'color': color\r
19301              *  });\r
19302              */\r
19303             listProto.setVisual = function (key, val) {\r
19304                 if (isObject(key)) {\r
19305                     for (var name in key) {\r
19306                         if (key.hasOwnProperty(name)) {\r
19307                             this.setVisual(name, key[name]);\r
19308                         }\r
19309                     }\r
19310                     return;\r
19311                 }\r
19312                 this._visual = this._visual || {};\r
19313                 this._visual[key] = val;\r
19314             };\r
19315 \r
19316             /**\r
19317              * Set layout property.\r
19318              * @param {string} key\r
19319              * @param {*} [val]\r
19320              */\r
19321             listProto.setLayout = function (key, val) {\r
19322                 if (isObject(key)) {\r
19323                     for (var name in key) {\r
19324                         if (key.hasOwnProperty(name)) {\r
19325                             this.setLayout(name, key[name]);\r
19326                         }\r
19327                     }\r
19328                     return;\r
19329                 }\r
19330                 this._layout[key] = val;\r
19331             };\r
19332 \r
19333             /**\r
19334              * Get layout property.\r
19335              * @param  {string} key.\r
19336              * @return {*}\r
19337              */\r
19338             listProto.getLayout = function (key) {\r
19339                 return this._layout[key];\r
19340             };\r
19341 \r
19342             /**\r
19343              * Get layout of single data item\r
19344              * @param {number} idx\r
19345              */\r
19346             listProto.getItemLayout = function (idx) {\r
19347                 return this._itemLayouts[idx];\r
19348             },\r
19349 \r
19350             /**\r
19351              * Set layout of single data item\r
19352              * @param {number} idx\r
19353              * @param {Object} layout\r
19354              * @param {boolean=} [merge=false]\r
19355              */\r
19356             listProto.setItemLayout = function (idx, layout, merge) {\r
19357                 this._itemLayouts[idx] = merge\r
19358                     ? zrUtil.extend(this._itemLayouts[idx] || {}, layout)\r
19359                     : layout;\r
19360             },\r
19361 \r
19362             /**\r
19363              * Get visual property of single data item\r
19364              * @param {number} idx\r
19365              * @param {string} key\r
19366              * @param {boolean} ignoreParent\r
19367              */\r
19368             listProto.getItemVisual = function (idx, key, ignoreParent) {\r
19369                 var itemVisual = this._itemVisuals[idx];\r
19370                 var val = itemVisual && itemVisual[key];\r
19371                 if (val == null && !ignoreParent) {\r
19372                     // Use global visual property\r
19373                     return this.getVisual(key);\r
19374                 }\r
19375                 return val;\r
19376             },\r
19377 \r
19378             /**\r
19379              * Set visual property of single data item\r
19380              *\r
19381              * @param {number} idx\r
19382              * @param {string|Object} key\r
19383              * @param {*} [value]\r
19384              *\r
19385              * @example\r
19386              *  setItemVisual(0, 'color', color);\r
19387              *  setItemVisual(0, {\r
19388              *      'color': color\r
19389              *  });\r
19390              */\r
19391             listProto.setItemVisual = function (idx, key, value) {\r
19392                 var itemVisual = this._itemVisuals[idx] || {};\r
19393                 this._itemVisuals[idx] = itemVisual;\r
19394 \r
19395                 if (isObject(key)) {\r
19396                     for (var name in key) {\r
19397                         if (key.hasOwnProperty(name)) {\r
19398                             itemVisual[name] = key[name];\r
19399                         }\r
19400                     }\r
19401                     return;\r
19402                 }\r
19403                 itemVisual[key] = value;\r
19404             };\r
19405 \r
19406             var setItemDataAndSeriesIndex = function (child) {\r
19407                 child.seriesIndex = this.seriesIndex;\r
19408                 child.dataIndex = this.dataIndex;\r
19409             };\r
19410             /**\r
19411              * Set graphic element relative to data. It can be set as null\r
19412              * @param {number} idx\r
19413              * @param {module:zrender/Element} [el]\r
19414              */\r
19415             listProto.setItemGraphicEl = function (idx, el) {\r
19416                 var hostModel = this.hostModel;\r
19417 \r
19418                 if (el) {\r
19419                     // Add data index and series index for indexing the data by element\r
19420                     // Useful in tooltip\r
19421                     el.dataIndex = idx;\r
19422                     el.seriesIndex = hostModel && hostModel.seriesIndex;\r
19423                     if (el.type === 'group') {\r
19424                         el.traverse(setItemDataAndSeriesIndex, el);\r
19425                     }\r
19426                 }\r
19427 \r
19428                 this._graphicEls[idx] = el;\r
19429             };\r
19430 \r
19431             /**\r
19432              * @param {number} idx\r
19433              * @return {module:zrender/Element}\r
19434              */\r
19435             listProto.getItemGraphicEl = function (idx) {\r
19436                 return this._graphicEls[idx];\r
19437             };\r
19438 \r
19439             /**\r
19440              * @param {Function} cb\r
19441              * @param {*} context\r
19442              */\r
19443             listProto.eachItemGraphicEl = function (cb, context) {\r
19444                 zrUtil.each(this._graphicEls, function (el, idx) {\r
19445                     if (el) {\r
19446                         cb && cb.call(context, el, idx);\r
19447                     }\r
19448                 });\r
19449             };\r
19450 \r
19451             /**\r
19452              * Shallow clone a new list except visual and layout properties, and graph elements.\r
19453              * New list only change the indices.\r
19454              */\r
19455             listProto.cloneShallow = function () {\r
19456                 var dimensionInfoList = zrUtil.map(this.dimensions, this.getDimensionInfo, this);\r
19457                 var list = new List(dimensionInfoList, this.hostModel);\r
19458 \r
19459                 // FIXME\r
19460                 list._storage = this._storage;\r
19461 \r
19462                 transferImmuProperties(list, this, this._wrappedMethods);\r
19463 \r
19464                 list.indices = this.indices.slice();\r
19465 \r
19466                 return list;\r
19467             };\r
19468 \r
19469             /**\r
19470              * Wrap some method to add more feature\r
19471              * @param {string} methodName\r
19472              * @param {Function} injectFunction\r
19473              */\r
19474             listProto.wrapMethod = function (methodName, injectFunction) {\r
19475                 var originalMethod = this[methodName];\r
19476                 if (typeof originalMethod !== 'function') {\r
19477                     return;\r
19478                 }\r
19479                 this._wrappedMethods = this._wrappedMethods || [];\r
19480                 this._wrappedMethods.push(methodName);\r
19481                 this[methodName] = function () {\r
19482                     var res = originalMethod.apply(this, arguments);\r
19483                     return injectFunction.call(this, res);\r
19484                 };\r
19485             };\r
19486 \r
19487             module.exports = List;\r
19488 \r
19489         /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\r
19490 \r
19491 /***/ },\r
19492 /* 95 */\r
19493 /***/ function(module, exports) {\r
19494 \r
19495         'use strict';\r
19496 \r
19497 \r
19498             function defaultKeyGetter(item) {\r
19499                 return item;\r
19500             }\r
19501 \r
19502             function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter) {\r
19503                 this._old = oldArr;\r
19504                 this._new = newArr;\r
19505 \r
19506                 this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;\r
19507                 this._newKeyGetter = newKeyGetter || defaultKeyGetter;\r
19508             }\r
19509 \r
19510             DataDiffer.prototype = {\r
19511 \r
19512                 constructor: DataDiffer,\r
19513 \r
19514                 /**\r
19515                  * Callback function when add a data\r
19516                  */\r
19517                 add: function (func) {\r
19518                     this._add = func;\r
19519                     return this;\r
19520                 },\r
19521 \r
19522                 /**\r
19523                  * Callback function when update a data\r
19524                  */\r
19525                 update: function (func) {\r
19526                     this._update = func;\r
19527                     return this;\r
19528                 },\r
19529 \r
19530                 /**\r
19531                  * Callback function when remove a data\r
19532                  */\r
19533                 remove: function (func) {\r
19534                     this._remove = func;\r
19535                     return this;\r
19536                 },\r
19537 \r
19538                 execute: function () {\r
19539                     var oldArr = this._old;\r
19540                     var newArr = this._new;\r
19541                     var oldKeyGetter = this._oldKeyGetter;\r
19542                     var newKeyGetter = this._newKeyGetter;\r
19543 \r
19544                     var oldDataIndexMap = {};\r
19545                     var newDataIndexMap = {};\r
19546                     var i;\r
19547 \r
19548                     initIndexMap(oldArr, oldDataIndexMap, oldKeyGetter);\r
19549                     initIndexMap(newArr, newDataIndexMap, newKeyGetter);\r
19550 \r
19551                     // Travel by inverted order to make sure order consistency\r
19552                     // when duplicate keys exists (consider newDataIndex.pop() below).\r
19553                     // For performance consideration, these code below do not look neat.\r
19554                     for (i = 0; i < oldArr.length; i++) {\r
19555                         var key = oldKeyGetter(oldArr[i]);\r
19556                         var idx = newDataIndexMap[key];\r
19557 \r
19558                         // idx can never be empty array here. see 'set null' logic below.\r
19559                         if (idx != null) {\r
19560                             // Consider there is duplicate key (for example, use dataItem.name as key).\r
19561                             // We should make sure every item in newArr and oldArr can be visited.\r
19562                             var len = idx.length;\r
19563                             if (len) {\r
19564                                 len === 1 && (newDataIndexMap[key] = null);\r
19565                                 idx = idx.unshift();\r
19566                             }\r
19567                             else {\r
19568                                 newDataIndexMap[key] = null;\r
19569                             }\r
19570                             this._update && this._update(idx, i);\r
19571                         }\r
19572                         else {\r
19573                             this._remove && this._remove(i);\r
19574                         }\r
19575                     }\r
19576 \r
19577                     for (var key in newDataIndexMap) {\r
19578                         if (newDataIndexMap.hasOwnProperty(key)) {\r
19579                             var idx = newDataIndexMap[key];\r
19580                             if (idx == null) {\r
19581                                 continue;\r
19582                             }\r
19583                             // idx can never be empty array here. see 'set null' logic above.\r
19584                             if (!idx.length) {\r
19585                                 this._add && this._add(idx);\r
19586                             }\r
19587                             else {\r
19588                                 for (var i = 0, len = idx.length; i < len; i++) {\r
19589                                     this._add && this._add(idx[i]);\r
19590                                 }\r
19591                             }\r
19592                         }\r
19593                     }\r
19594                 }\r
19595             };\r
19596 \r
19597             function initIndexMap(arr, map, keyGetter) {\r
19598                 for (var i = 0; i < arr.length; i++) {\r
19599                     var key = keyGetter(arr[i]);\r
19600                     var existence = map[key];\r
19601                     if (existence == null) {\r
19602                         map[key] = i;\r
19603                     }\r
19604                     else {\r
19605                         if (!existence.length) {\r
19606                             map[key] = existence = [existence];\r
19607                         }\r
19608                         existence.push(i);\r
19609                     }\r
19610                 }\r
19611             }\r
19612 \r
19613             module.exports = DataDiffer;\r
19614 \r
19615 \r
19616 /***/ },\r
19617 /* 96 */\r
19618 /***/ function(module, exports, __webpack_require__) {\r
19619 \r
19620         /**\r
19621          * Complete dimensions by data (guess dimension).\r
19622          */\r
19623 \r
19624 \r
19625             var zrUtil = __webpack_require__(3);\r
19626 \r
19627             /**\r
19628              * Complete the dimensions array guessed from the data structure.\r
19629              * @param  {Array.<string>} dimensions      Necessary dimensions, like ['x', 'y']\r
19630              * @param  {Array} data                     Data list. [[1, 2, 3], [2, 3, 4]]\r
19631              * @param  {Array.<string>} defaultNames    Default names to fill not necessary dimensions, like ['value']\r
19632              * @param  {string} extraPrefix             Prefix of name when filling the left dimensions.\r
19633              * @return {Array.<string>}\r
19634              */\r
19635             function completeDimensions(dimensions, data, defaultNames, extraPrefix) {\r
19636                 if (!data) {\r
19637                     return dimensions;\r
19638                 }\r
19639 \r
19640                 var value0 = retrieveValue(data[0]);\r
19641                 var dimSize = zrUtil.isArray(value0) && value0.length || 1;\r
19642 \r
19643                 defaultNames = defaultNames || [];\r
19644                 extraPrefix = extraPrefix || 'extra';\r
19645                 for (var i = 0; i < dimSize; i++) {\r
19646                     if (!dimensions[i]) {\r
19647                         var name = defaultNames[i] || (extraPrefix + (i - defaultNames.length));\r
19648                         dimensions[i] = guessOrdinal(data, i)\r
19649                             ? {type: 'ordinal', name: name}\r
19650                             : name;\r
19651                     }\r
19652                 }\r
19653 \r
19654                 return dimensions;\r
19655             }\r
19656 \r
19657             // The rule should not be complex, otherwise user might not\r
19658             // be able to known where the data is wrong.\r
19659             function guessOrdinal(data, dimIndex) {\r
19660                 for (var i = 0, len = data.length; i < len; i++) {\r
19661                     var value = retrieveValue(data[i]);\r
19662 \r
19663                     if (!zrUtil.isArray(value)) {\r
19664                         return false;\r
19665                     }\r
19666 \r
19667                     var value = value[dimIndex];\r
19668                     if (value != null && isFinite(value)) {\r
19669                         return false;\r
19670                     }\r
19671                     else if (zrUtil.isString(value) && value !== '-') {\r
19672                         return true;\r
19673                     }\r
19674                 }\r
19675                 return false;\r
19676             }\r
19677 \r
19678             function retrieveValue(o) {\r
19679                 return zrUtil.isArray(o) ? o : zrUtil.isObject(o) ? o.value: o;\r
19680             }\r
19681 \r
19682             module.exports = completeDimensions;\r
19683 \r
19684 \r
19685 \r
19686 /***/ },\r
19687 /* 97 */\r
19688 /***/ function(module, exports, __webpack_require__) {\r
19689 \r
19690         'use strict';\r
19691 \r
19692 \r
19693             var zrUtil = __webpack_require__(3);\r
19694             var SymbolDraw = __webpack_require__(98);\r
19695             var Symbol = __webpack_require__(99);\r
19696             var lineAnimationDiff = __webpack_require__(101);\r
19697             var graphic = __webpack_require__(42);\r
19698 \r
19699             var polyHelper = __webpack_require__(102);\r
19700 \r
19701             var ChartView = __webpack_require__(41);\r
19702 \r
19703             function isPointsSame(points1, points2) {\r
19704                 if (points1.length !== points2.length) {\r
19705                     return;\r
19706                 }\r
19707                 for (var i = 0; i < points1.length; i++) {\r
19708                     var p1 = points1[i];\r
19709                     var p2 = points2[i];\r
19710                     if (p1[0] !== p2[0] || p1[1] !== p2[1]) {\r
19711                         return;\r
19712                     }\r
19713                 }\r
19714                 return true;\r
19715             }\r
19716 \r
19717             function getSmooth(smooth) {\r
19718                 return typeof (smooth) === 'number' ? smooth : (smooth ? 0.3 : 0);\r
19719             }\r
19720 \r
19721             function getAxisExtentWithGap(axis) {\r
19722                 var extent = axis.getGlobalExtent();\r
19723                 if (axis.onBand) {\r
19724                     // Remove extra 1px to avoid line miter in clipped edge\r
19725                     var halfBandWidth = axis.getBandWidth() / 2 - 1;\r
19726                     var dir = extent[1] > extent[0] ? 1 : -1;\r
19727                     extent[0] += dir * halfBandWidth;\r
19728                     extent[1] -= dir * halfBandWidth;\r
19729                 }\r
19730                 return extent;\r
19731             }\r
19732 \r
19733             function sign(val) {\r
19734                 return val >= 0 ? 1 : -1;\r
19735             }\r
19736             /**\r
19737              * @param {module:echarts/coord/cartesian/Cartesian2D|module:echarts/coord/polar/Polar} coordSys\r
19738              * @param {module:echarts/data/List} data\r
19739              * @param {Array.<Array.<number>>} points\r
19740              * @private\r
19741              */\r
19742             function getStackedOnPoints(coordSys, data) {\r
19743                 var baseAxis = coordSys.getBaseAxis();\r
19744                 var valueAxis = coordSys.getOtherAxis(baseAxis);\r
19745                 var valueStart = baseAxis.onZero\r
19746                     ? 0 : valueAxis.scale.getExtent()[0];\r
19747 \r
19748                 var valueDim = valueAxis.dim;\r
19749 \r
19750                 var baseDataOffset = valueDim === 'x' || valueDim === 'radius' ? 1 : 0;\r
19751 \r
19752                 return data.mapArray([valueDim], function (val, idx) {\r
19753                     var stackedOnSameSign;\r
19754                     var stackedOn = data.stackedOn;\r
19755                     // Find first stacked value with same sign\r
19756                     while (stackedOn &&\r
19757                         sign(stackedOn.get(valueDim, idx)) === sign(val)\r
19758                     ) {\r
19759                         stackedOnSameSign = stackedOn;\r
19760                         break;\r
19761                     }\r
19762                     var stackedData = [];\r
19763                     stackedData[baseDataOffset] = data.get(baseAxis.dim, idx);\r
19764                     stackedData[1 - baseDataOffset] = stackedOnSameSign\r
19765                         ? stackedOnSameSign.get(valueDim, idx, true) : valueStart;\r
19766 \r
19767                     return coordSys.dataToPoint(stackedData);\r
19768                 }, true);\r
19769             }\r
19770 \r
19771             function queryDataIndex(data, payload) {\r
19772                 if (payload.dataIndex != null) {\r
19773                     return payload.dataIndex;\r
19774                 }\r
19775                 else if (payload.name != null) {\r
19776                     return data.indexOfName(payload.name);\r
19777                 }\r
19778             }\r
19779 \r
19780             function createGridClipShape(cartesian, hasAnimation, seriesModel) {\r
19781                 var xExtent = getAxisExtentWithGap(cartesian.getAxis('x'));\r
19782                 var yExtent = getAxisExtentWithGap(cartesian.getAxis('y'));\r
19783                 var isHorizontal = cartesian.getBaseAxis().isHorizontal();\r
19784 \r
19785                 var x = xExtent[0];\r
19786                 var y = yExtent[0];\r
19787                 var width = xExtent[1] - x;\r
19788                 var height = yExtent[1] - y;\r
19789                 // Expand clip shape to avoid line value exceeds axis\r
19790                 if (!seriesModel.get('clipOverflow')) {\r
19791                     if (isHorizontal) {\r
19792                         y -= height;\r
19793                         height *= 3;\r
19794                     }\r
19795                     else {\r
19796                         x -= width;\r
19797                         width *= 3;\r
19798                     }\r
19799                 }\r
19800                 var clipPath = new graphic.Rect({\r
19801                     shape: {\r
19802                         x: x,\r
19803                         y: y,\r
19804                         width: width,\r
19805                         height: height\r
19806                     }\r
19807                 });\r
19808 \r
19809                 if (hasAnimation) {\r
19810                     clipPath.shape[isHorizontal ? 'width' : 'height'] = 0;\r
19811                     graphic.initProps(clipPath, {\r
19812                         shape: {\r
19813                             width: width,\r
19814                             height: height\r
19815                         }\r
19816                     }, seriesModel);\r
19817                 }\r
19818 \r
19819                 return clipPath;\r
19820             }\r
19821 \r
19822             function createPolarClipShape(polar, hasAnimation, seriesModel) {\r
19823                 var angleAxis = polar.getAngleAxis();\r
19824                 var radiusAxis = polar.getRadiusAxis();\r
19825 \r
19826                 var radiusExtent = radiusAxis.getExtent();\r
19827                 var angleExtent = angleAxis.getExtent();\r
19828 \r
19829                 var RADIAN = Math.PI / 180;\r
19830 \r
19831                 var clipPath = new graphic.Sector({\r
19832                     shape: {\r
19833                         cx: polar.cx,\r
19834                         cy: polar.cy,\r
19835                         r0: radiusExtent[0],\r
19836                         r: radiusExtent[1],\r
19837                         startAngle: -angleExtent[0] * RADIAN,\r
19838                         endAngle: -angleExtent[1] * RADIAN,\r
19839                         clockwise: angleAxis.inverse\r
19840                     }\r
19841                 });\r
19842 \r
19843                 if (hasAnimation) {\r
19844                     clipPath.shape.endAngle = -angleExtent[0] * RADIAN;\r
19845                     graphic.initProps(clipPath, {\r
19846                         shape: {\r
19847                             endAngle: -angleExtent[1] * RADIAN\r
19848                         }\r
19849                     }, seriesModel);\r
19850                 }\r
19851 \r
19852                 return clipPath;\r
19853             }\r
19854 \r
19855             function createClipShape(coordSys, hasAnimation, seriesModel) {\r
19856                 return coordSys.type === 'polar'\r
19857                     ? createPolarClipShape(coordSys, hasAnimation, seriesModel)\r
19858                     : createGridClipShape(coordSys, hasAnimation, seriesModel);\r
19859             }\r
19860 \r
19861             module.exports = ChartView.extend({\r
19862 \r
19863                 type: 'line',\r
19864 \r
19865                 init: function () {\r
19866                     var lineGroup = new graphic.Group();\r
19867 \r
19868                     var symbolDraw = new SymbolDraw();\r
19869                     this.group.add(symbolDraw.group);\r
19870 \r
19871                     this._symbolDraw = symbolDraw;\r
19872                     this._lineGroup = lineGroup;\r
19873                 },\r
19874 \r
19875                 render: function (seriesModel, ecModel, api) {\r
19876                     var coordSys = seriesModel.coordinateSystem;\r
19877                     var group = this.group;\r
19878                     var data = seriesModel.getData();\r
19879                     var lineStyleModel = seriesModel.getModel('lineStyle.normal');\r
19880                     var areaStyleModel = seriesModel.getModel('areaStyle.normal');\r
19881 \r
19882                     var points = data.mapArray(data.getItemLayout, true);\r
19883 \r
19884                     var isCoordSysPolar = coordSys.type === 'polar';\r
19885                     var prevCoordSys = this._coordSys;\r
19886 \r
19887                     var symbolDraw = this._symbolDraw;\r
19888                     var polyline = this._polyline;\r
19889                     var polygon = this._polygon;\r
19890 \r
19891                     var lineGroup = this._lineGroup;\r
19892 \r
19893                     var hasAnimation = seriesModel.get('animation');\r
19894 \r
19895                     var isAreaChart = !areaStyleModel.isEmpty();\r
19896                     var stackedOnPoints = getStackedOnPoints(coordSys, data);\r
19897 \r
19898                     var showSymbol = seriesModel.get('showSymbol');\r
19899 \r
19900                     var isSymbolIgnore = showSymbol && !isCoordSysPolar && !seriesModel.get('showAllSymbol')\r
19901                         && this._getSymbolIgnoreFunc(data, coordSys);\r
19902 \r
19903                     // Remove temporary symbols\r
19904                     var oldData = this._data;\r
19905                     oldData && oldData.eachItemGraphicEl(function (el, idx) {\r
19906                         if (el.__temp) {\r
19907                             group.remove(el);\r
19908                             oldData.setItemGraphicEl(idx, null);\r
19909                         }\r
19910                     });\r
19911 \r
19912                     // Remove previous created symbols if showSymbol changed to false\r
19913                     if (!showSymbol) {\r
19914                         symbolDraw.remove();\r
19915                     }\r
19916 \r
19917                     group.add(lineGroup);\r
19918 \r
19919                     // Initialization animation or coordinate system changed\r
19920                     if (\r
19921                         !(polyline && prevCoordSys.type === coordSys.type)\r
19922                     ) {\r
19923                         showSymbol && symbolDraw.updateData(data, isSymbolIgnore);\r
19924 \r
19925                         polyline = this._newPolyline(points, coordSys, hasAnimation);\r
19926                         if (isAreaChart) {\r
19927                             polygon = this._newPolygon(\r
19928                                 points, stackedOnPoints,\r
19929                                 coordSys, hasAnimation\r
19930                             );\r
19931                         }\r
19932                         lineGroup.setClipPath(createClipShape(coordSys, true, seriesModel));\r
19933                     }\r
19934                     else {\r
19935                         if (isAreaChart && !polygon) {\r
19936                             // If areaStyle is added\r
19937                             polygon = this._newPolygon(\r
19938                                 points, stackedOnPoints,\r
19939                                 coordSys, hasAnimation\r
19940                             );\r
19941                         }\r
19942                         else if (polygon && !isAreaChart) {\r
19943                             // If areaStyle is removed\r
19944                             lineGroup.remove(polygon);\r
19945                             polygon = this._polygon = null;\r
19946                         }\r
19947 \r
19948                         // Update clipPath\r
19949                         lineGroup.setClipPath(createClipShape(coordSys, false, seriesModel));\r
19950 \r
19951                         // Always update, or it is wrong in the case turning on legend\r
19952                         // because points are not changed\r
19953                         showSymbol && symbolDraw.updateData(data, isSymbolIgnore);\r
19954 \r
19955                         // Stop symbol animation and sync with line points\r
19956                         // FIXME performance?\r
19957                         data.eachItemGraphicEl(function (el) {\r
19958                             el.stopAnimation(true);\r
19959                         });\r
19960 \r
19961                         // In the case data zoom triggerred refreshing frequently\r
19962                         // Data may not change if line has a category axis. So it should animate nothing\r
19963                         if (!isPointsSame(this._stackedOnPoints, stackedOnPoints)\r
19964                             || !isPointsSame(this._points, points)\r
19965                         ) {\r
19966                             if (hasAnimation) {\r
19967                                 this._updateAnimation(\r
19968                                     data, stackedOnPoints, coordSys, api\r
19969                                 );\r
19970                             }\r
19971                             else {\r
19972                                 polyline.setShape({\r
19973                                     points: points\r
19974                                 });\r
19975                                 polygon && polygon.setShape({\r
19976                                     points: points,\r
19977                                     stackedOnPoints: stackedOnPoints\r
19978                                 });\r
19979                             }\r
19980                         }\r
19981                     }\r
19982 \r
19983                     polyline.setStyle(zrUtil.defaults(\r
19984                         // Use color in lineStyle first\r
19985                         lineStyleModel.getLineStyle(),\r
19986                         {\r
19987                             stroke: data.getVisual('color'),\r
19988                             lineJoin: 'bevel'\r
19989                         }\r
19990                     ));\r
19991 \r
19992                     var smooth = seriesModel.get('smooth');\r
19993                     smooth = getSmooth(seriesModel.get('smooth'));\r
19994                     polyline.setShape({\r
19995                         smooth: smooth,\r
19996                         smoothMonotone: seriesModel.get('smoothMonotone')\r
19997                     });\r
19998 \r
19999                     if (polygon) {\r
20000                         var stackedOn = data.stackedOn;\r
20001                         var stackedOnSmooth = 0;\r
20002 \r
20003                         polygon.style.opacity = 0.7;\r
20004                         polygon.setStyle(zrUtil.defaults(\r
20005                             areaStyleModel.getAreaStyle(),\r
20006                             {\r
20007                                 fill: data.getVisual('color'),\r
20008                                 lineJoin: 'bevel'\r
20009                             }\r
20010                         ));\r
20011 \r
20012                         if (stackedOn) {\r
20013                             var stackedOnSeries = stackedOn.hostModel;\r
20014                             stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));\r
20015                         }\r
20016 \r
20017                         polygon.setShape({\r
20018                             smooth: smooth,\r
20019                             stackedOnSmooth: stackedOnSmooth,\r
20020                             smoothMonotone: seriesModel.get('smoothMonotone')\r
20021                         });\r
20022                     }\r
20023 \r
20024                     this._data = data;\r
20025                     // Save the coordinate system for transition animation when data changed\r
20026                     this._coordSys = coordSys;\r
20027                     this._stackedOnPoints = stackedOnPoints;\r
20028                     this._points = points;\r
20029                 },\r
20030 \r
20031                 highlight: function (seriesModel, ecModel, api, payload) {\r
20032                     var data = seriesModel.getData();\r
20033                     var dataIndex = queryDataIndex(data, payload);\r
20034 \r
20035                     if (dataIndex != null && dataIndex >= 0) {\r
20036                         var symbol = data.getItemGraphicEl(dataIndex);\r
20037                         if (!symbol) {\r
20038                             // Create a temporary symbol if it is not exists\r
20039                             var pt = data.getItemLayout(dataIndex);\r
20040                             symbol = new Symbol(data, dataIndex, api);\r
20041                             symbol.position = pt;\r
20042                             symbol.setZ(\r
20043                                 seriesModel.get('zlevel'),\r
20044                                 seriesModel.get('z')\r
20045                             );\r
20046                             symbol.ignore = isNaN(pt[0]) || isNaN(pt[1]);\r
20047                             symbol.__temp = true;\r
20048                             data.setItemGraphicEl(dataIndex, symbol);\r
20049 \r
20050                             // Stop scale animation\r
20051                             symbol.stopSymbolAnimation(true);\r
20052 \r
20053                             this.group.add(symbol);\r
20054                         }\r
20055                         symbol.highlight();\r
20056                     }\r
20057                     else {\r
20058                         // Highlight whole series\r
20059                         ChartView.prototype.highlight.call(\r
20060                             this, seriesModel, ecModel, api, payload\r
20061                         );\r
20062                     }\r
20063                 },\r
20064 \r
20065                 downplay: function (seriesModel, ecModel, api, payload) {\r
20066                     var data = seriesModel.getData();\r
20067                     var dataIndex = queryDataIndex(data, payload);\r
20068                     if (dataIndex != null && dataIndex >= 0) {\r
20069                         var symbol = data.getItemGraphicEl(dataIndex);\r
20070                         if (symbol) {\r
20071                             if (symbol.__temp) {\r
20072                                 data.setItemGraphicEl(dataIndex, null);\r
20073                                 this.group.remove(symbol);\r
20074                             }\r
20075                             else {\r
20076                                 symbol.downplay();\r
20077                             }\r
20078                         }\r
20079                     }\r
20080                     else {\r
20081                         // Downplay whole series\r
20082                         ChartView.prototype.downplay.call(\r
20083                             this, seriesModel, ecModel, api, payload\r
20084                         );\r
20085                     }\r
20086                 },\r
20087 \r
20088                 /**\r
20089                  * @param {module:zrender/container/Group} group\r
20090                  * @param {Array.<Array.<number>>} points\r
20091                  * @private\r
20092                  */\r
20093                 _newPolyline: function (points) {\r
20094                     var polyline = this._polyline;\r
20095                     // Remove previous created polyline\r
20096                     if (polyline) {\r
20097                         this._lineGroup.remove(polyline);\r
20098                     }\r
20099 \r
20100                     polyline = new polyHelper.Polyline({\r
20101                         shape: {\r
20102                             points: points\r
20103                         },\r
20104                         silent: true,\r
20105                         z2: 10\r
20106                     });\r
20107 \r
20108                     this._lineGroup.add(polyline);\r
20109 \r
20110                     this._polyline = polyline;\r
20111 \r
20112                     return polyline;\r
20113                 },\r
20114 \r
20115                 /**\r
20116                  * @param {module:zrender/container/Group} group\r
20117                  * @param {Array.<Array.<number>>} stackedOnPoints\r
20118                  * @param {Array.<Array.<number>>} points\r
20119                  * @private\r
20120                  */\r
20121                 _newPolygon: function (points, stackedOnPoints) {\r
20122                     var polygon = this._polygon;\r
20123                     // Remove previous created polygon\r
20124                     if (polygon) {\r
20125                         this._lineGroup.remove(polygon);\r
20126                     }\r
20127 \r
20128                     polygon = new polyHelper.Polygon({\r
20129                         shape: {\r
20130                             points: points,\r
20131                             stackedOnPoints: stackedOnPoints\r
20132                         },\r
20133                         silent: true\r
20134                     });\r
20135 \r
20136                     this._lineGroup.add(polygon);\r
20137 \r
20138                     this._polygon = polygon;\r
20139                     return polygon;\r
20140                 },\r
20141                 /**\r
20142                  * @private\r
20143                  */\r
20144                 _getSymbolIgnoreFunc: function (data, coordSys) {\r
20145                     var categoryAxis = coordSys.getAxesByScale('ordinal')[0];\r
20146                     // `getLabelInterval` is provided by echarts/component/axis\r
20147                     if (categoryAxis && categoryAxis.isLabelIgnored) {\r
20148                         return zrUtil.bind(categoryAxis.isLabelIgnored, categoryAxis);\r
20149                     }\r
20150                 },\r
20151 \r
20152                 /**\r
20153                  * @private\r
20154                  */\r
20155                 // FIXME Two value axis\r
20156                 _updateAnimation: function (data, stackedOnPoints, coordSys, api) {\r
20157                     var polyline = this._polyline;\r
20158                     var polygon = this._polygon;\r
20159                     var seriesModel = data.hostModel;\r
20160 \r
20161                     var diff = lineAnimationDiff(\r
20162                         this._data, data,\r
20163                         this._stackedOnPoints, stackedOnPoints,\r
20164                         this._coordSys, coordSys\r
20165                     );\r
20166                     polyline.shape.points = diff.current;\r
20167 \r
20168                     graphic.updateProps(polyline, {\r
20169                         shape: {\r
20170                             points: diff.next\r
20171                         }\r
20172                     }, seriesModel);\r
20173 \r
20174                     if (polygon) {\r
20175                         polygon.setShape({\r
20176                             points: diff.current,\r
20177                             stackedOnPoints: diff.stackedOnCurrent\r
20178                         });\r
20179                         graphic.updateProps(polygon, {\r
20180                             shape: {\r
20181                                 points: diff.next,\r
20182                                 stackedOnPoints: diff.stackedOnNext\r
20183                             }\r
20184                         }, seriesModel);\r
20185                     }\r
20186 \r
20187                     var updatedDataInfo = [];\r
20188                     var diffStatus = diff.status;\r
20189 \r
20190                     for (var i = 0; i < diffStatus.length; i++) {\r
20191                         var cmd = diffStatus[i].cmd;\r
20192                         if (cmd === '=') {\r
20193                             var el = data.getItemGraphicEl(diffStatus[i].idx1);\r
20194                             if (el) {\r
20195                                 updatedDataInfo.push({\r
20196                                     el: el,\r
20197                                     ptIdx: i    // Index of points\r
20198                                 });\r
20199                             }\r
20200                         }\r
20201                     }\r
20202 \r
20203                     if (polyline.animators && polyline.animators.length) {\r
20204                         polyline.animators[0].during(function () {\r
20205                             for (var i = 0; i < updatedDataInfo.length; i++) {\r
20206                                 var el = updatedDataInfo[i].el;\r
20207                                 el.attr('position', polyline.shape.points[updatedDataInfo[i].ptIdx]);\r
20208                             }\r
20209                         });\r
20210                     }\r
20211                 },\r
20212 \r
20213                 remove: function (ecModel) {\r
20214                     var group = this.group;\r
20215                     var oldData = this._data;\r
20216                     this._lineGroup.removeAll();\r
20217                     this._symbolDraw.remove(true);\r
20218                     // Remove temporary created elements when highlighting\r
20219                     oldData && oldData.eachItemGraphicEl(function (el, idx) {\r
20220                         if (el.__temp) {\r
20221                             group.remove(el);\r
20222                             oldData.setItemGraphicEl(idx, null);\r
20223                         }\r
20224                     });\r
20225 \r
20226                     this._polyline =\r
20227                     this._polygon =\r
20228                     this._coordSys =\r
20229                     this._points =\r
20230                     this._stackedOnPoints =\r
20231                     this._data = null;\r
20232                 }\r
20233             });\r
20234 \r
20235 \r
20236 /***/ },\r
20237 /* 98 */\r
20238 /***/ function(module, exports, __webpack_require__) {\r
20239 \r
20240         /**\r
20241          * @module echarts/chart/helper/SymbolDraw\r
20242          */\r
20243 \r
20244 \r
20245             var graphic = __webpack_require__(42);\r
20246             var Symbol = __webpack_require__(99);\r
20247 \r
20248             /**\r
20249              * @constructor\r
20250              * @alias module:echarts/chart/helper/SymbolDraw\r
20251              * @param {module:zrender/graphic/Group} [symbolCtor]\r
20252              */\r
20253             function SymbolDraw(symbolCtor) {\r
20254                 this.group = new graphic.Group();\r
20255 \r
20256                 this._symbolCtor = symbolCtor || Symbol;\r
20257             }\r
20258 \r
20259             var symbolDrawProto = SymbolDraw.prototype;\r
20260 \r
20261             function symbolNeedsDraw(data, idx, isIgnore) {\r
20262                 var point = data.getItemLayout(idx);\r
20263                 return point && !isNaN(point[0]) && !isNaN(point[1]) && !(isIgnore && isIgnore(idx))\r
20264                             && data.getItemVisual(idx, 'symbol') !== 'none';\r
20265             }\r
20266             /**\r
20267              * Update symbols draw by new data\r
20268              * @param {module:echarts/data/List} data\r
20269              * @param {Array.<boolean>} [isIgnore]\r
20270              */\r
20271             symbolDrawProto.updateData = function (data, isIgnore) {\r
20272                 var group = this.group;\r
20273                 var seriesModel = data.hostModel;\r
20274                 var oldData = this._data;\r
20275 \r
20276                 var SymbolCtor = this._symbolCtor;\r
20277 \r
20278                 data.diff(oldData)\r
20279                     .add(function (newIdx) {\r
20280                         var point = data.getItemLayout(newIdx);\r
20281                         if (symbolNeedsDraw(data, newIdx, isIgnore)) {\r
20282                             var symbolEl = new SymbolCtor(data, newIdx);\r
20283                             symbolEl.attr('position', point);\r
20284                             data.setItemGraphicEl(newIdx, symbolEl);\r
20285                             group.add(symbolEl);\r
20286                         }\r
20287                     })\r
20288                     .update(function (newIdx, oldIdx) {\r
20289                         var symbolEl = oldData.getItemGraphicEl(oldIdx);\r
20290                         var point = data.getItemLayout(newIdx);\r
20291                         if (!symbolNeedsDraw(data, newIdx, isIgnore)) {\r
20292                             group.remove(symbolEl);\r
20293                             return;\r
20294                         }\r
20295                         if (!symbolEl) {\r
20296                             symbolEl = new SymbolCtor(data, newIdx);\r
20297                             symbolEl.attr('position', point);\r
20298                         }\r
20299                         else {\r
20300                             symbolEl.updateData(data, newIdx);\r
20301                             graphic.updateProps(symbolEl, {\r
20302                                 position: point\r
20303                             }, seriesModel);\r
20304                         }\r
20305 \r
20306                         // Add back\r
20307                         group.add(symbolEl);\r
20308 \r
20309                         data.setItemGraphicEl(newIdx, symbolEl);\r
20310                     })\r
20311                     .remove(function (oldIdx) {\r
20312                         var el = oldData.getItemGraphicEl(oldIdx);\r
20313                         el && el.fadeOut(function () {\r
20314                             group.remove(el);\r
20315                         });\r
20316                     })\r
20317                     .execute();\r
20318 \r
20319                 this._data = data;\r
20320             };\r
20321 \r
20322             symbolDrawProto.updateLayout = function () {\r
20323                 var data = this._data;\r
20324                 if (data) {\r
20325                     // Not use animation\r
20326                     data.eachItemGraphicEl(function (el, idx) {\r
20327                         el.attr('position', data.getItemLayout(idx));\r
20328                     });\r
20329                 }\r
20330             };\r
20331 \r
20332             symbolDrawProto.remove = function (enableAnimation) {\r
20333                 var group = this.group;\r
20334                 var data = this._data;\r
20335                 if (data) {\r
20336                     if (enableAnimation) {\r
20337                         data.eachItemGraphicEl(function (el) {\r
20338                             el.fadeOut(function () {\r
20339                                 group.remove(el);\r
20340                             });\r
20341                         });\r
20342                     }\r
20343                     else {\r
20344                         group.removeAll();\r
20345                     }\r
20346                 }\r
20347             };\r
20348 \r
20349             module.exports = SymbolDraw;\r
20350 \r
20351 \r
20352 /***/ },\r
20353 /* 99 */\r
20354 /***/ function(module, exports, __webpack_require__) {\r
20355 \r
20356         /**\r
20357          * @module echarts/chart/helper/Symbol\r
20358          */\r
20359 \r
20360 \r
20361             var zrUtil = __webpack_require__(3);\r
20362             var symbolUtil = __webpack_require__(100);\r
20363             var graphic = __webpack_require__(42);\r
20364             var numberUtil = __webpack_require__(7);\r
20365 \r
20366             function normalizeSymbolSize(symbolSize) {\r
20367                 if (!zrUtil.isArray(symbolSize)) {\r
20368                     symbolSize = [+symbolSize, +symbolSize];\r
20369                 }\r
20370                 return symbolSize;\r
20371             }\r
20372 \r
20373             /**\r
20374              * @constructor\r
20375              * @alias {module:echarts/chart/helper/Symbol}\r
20376              * @param {module:echarts/data/List} data\r
20377              * @param {number} idx\r
20378              * @extends {module:zrender/graphic/Group}\r
20379              */\r
20380             function Symbol(data, idx) {\r
20381                 graphic.Group.call(this);\r
20382 \r
20383                 this.updateData(data, idx);\r
20384             }\r
20385 \r
20386             var symbolProto = Symbol.prototype;\r
20387 \r
20388             function driftSymbol(dx, dy) {\r
20389                 this.parent.drift(dx, dy);\r
20390             }\r
20391 \r
20392             symbolProto._createSymbol = function (symbolType, data, idx) {\r
20393                 // Remove paths created before\r
20394                 this.removeAll();\r
20395 \r
20396                 var seriesModel = data.hostModel;\r
20397                 var color = data.getItemVisual(idx, 'color');\r
20398 \r
20399                 var symbolPath = symbolUtil.createSymbol(\r
20400                     symbolType, -0.5, -0.5, 1, 1, color\r
20401                 );\r
20402 \r
20403                 symbolPath.attr({\r
20404                     style: {\r
20405                         strokeNoScale: true\r
20406                     },\r
20407                     z2: 100,\r
20408                     culling: true,\r
20409                     scale: [0, 0]\r
20410                 });\r
20411                 // Rewrite drift method\r
20412                 symbolPath.drift = driftSymbol;\r
20413 \r
20414                 var size = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));\r
20415 \r
20416                 graphic.initProps(symbolPath, {\r
20417                     scale: size\r
20418                 }, seriesModel);\r
20419 \r
20420                 this._symbolType = symbolType;\r
20421 \r
20422                 this.add(symbolPath);\r
20423             };\r
20424 \r
20425             /**\r
20426              * Stop animation\r
20427              * @param {boolean} toLastFrame\r
20428              */\r
20429             symbolProto.stopSymbolAnimation = function (toLastFrame) {\r
20430                 this.childAt(0).stopAnimation(toLastFrame);\r
20431             };\r
20432 \r
20433             /**\r
20434              * Get scale(aka, current symbol size).\r
20435              * Including the change caused by animation\r
20436              * @param {Array.<number>} toLastFrame\r
20437              */\r
20438             symbolProto.getScale = function () {\r
20439                 return this.childAt(0).scale;\r
20440             };\r
20441 \r
20442             /**\r
20443              * Highlight symbol\r
20444              */\r
20445             symbolProto.highlight = function () {\r
20446                 this.childAt(0).trigger('emphasis');\r
20447             };\r
20448 \r
20449             /**\r
20450              * Downplay symbol\r
20451              */\r
20452             symbolProto.downplay = function () {\r
20453                 this.childAt(0).trigger('normal');\r
20454             };\r
20455 \r
20456             /**\r
20457              * @param {number} zlevel\r
20458              * @param {number} z\r
20459              */\r
20460             symbolProto.setZ = function (zlevel, z) {\r
20461                 var symbolPath = this.childAt(0);\r
20462                 symbolPath.zlevel = zlevel;\r
20463                 symbolPath.z = z;\r
20464             };\r
20465 \r
20466             symbolProto.setDraggable = function (draggable) {\r
20467                 var symbolPath = this.childAt(0);\r
20468                 symbolPath.draggable = draggable;\r
20469                 symbolPath.cursor = draggable ? 'move' : 'pointer';\r
20470             };\r
20471             /**\r
20472              * Update symbol properties\r
20473              * @param  {module:echarts/data/List} data\r
20474              * @param  {number} idx\r
20475              */\r
20476             symbolProto.updateData = function (data, idx) {\r
20477                 var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';\r
20478                 var seriesModel = data.hostModel;\r
20479                 var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));\r
20480                 if (symbolType !== this._symbolType) {\r
20481                     this._createSymbol(symbolType, data, idx);\r
20482                 }\r
20483                 else {\r
20484                     var symbolPath = this.childAt(0);\r
20485                     graphic.updateProps(symbolPath, {\r
20486                         scale: symbolSize\r
20487                     }, seriesModel);\r
20488                 }\r
20489                 this._updateCommon(data, idx, symbolSize);\r
20490 \r
20491                 this._seriesModel = seriesModel;\r
20492             };\r
20493 \r
20494             // Update common properties\r
20495             var normalStyleAccessPath = ['itemStyle', 'normal'];\r
20496             var emphasisStyleAccessPath = ['itemStyle', 'emphasis'];\r
20497             var normalLabelAccessPath = ['label', 'normal'];\r
20498             var emphasisLabelAccessPath = ['label', 'emphasis'];\r
20499 \r
20500             symbolProto._updateCommon = function (data, idx, symbolSize) {\r
20501                 var symbolPath = this.childAt(0);\r
20502                 var seriesModel = data.hostModel;\r
20503                 var itemModel = data.getItemModel(idx);\r
20504                 var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);\r
20505                 var color = data.getItemVisual(idx, 'color');\r
20506 \r
20507                 var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();\r
20508 \r
20509                 symbolPath.rotation = itemModel.getShallow('symbolRotate') * Math.PI / 180 || 0;\r
20510 \r
20511                 var symbolOffset = itemModel.getShallow('symbolOffset');\r
20512                 if (symbolOffset) {\r
20513                     var pos = symbolPath.position;\r
20514                     pos[0] = numberUtil.parsePercent(symbolOffset[0], symbolSize[0]);\r
20515                     pos[1] = numberUtil.parsePercent(symbolOffset[1], symbolSize[1]);\r
20516                 }\r
20517 \r
20518                 symbolPath.setColor(color);\r
20519 \r
20520                 zrUtil.extend(\r
20521                     symbolPath.style,\r
20522                     // Color must be excluded.\r
20523                     // Because symbol provide setColor individually to set fill and stroke\r
20524                     normalItemStyleModel.getItemStyle(['color'])\r
20525                 );\r
20526 \r
20527                 var labelModel = itemModel.getModel(normalLabelAccessPath);\r
20528                 var hoverLabelModel = itemModel.getModel(emphasisLabelAccessPath);\r
20529 \r
20530                 var elStyle = symbolPath.style;\r
20531 \r
20532                 // Get last value dim\r
20533                 var dimensions = data.dimensions.slice();\r
20534                 var valueDim = dimensions.pop();\r
20535                 var dataType;\r
20536                 while (\r
20537                     ((dataType = data.getDimensionInfo(valueDim).type) === 'ordinal')\r
20538                     || (dataType === 'time')\r
20539                 ) {\r
20540                     valueDim = dimensions.pop();\r
20541                 }\r
20542 \r
20543                 if (labelModel.get('show')) {\r
20544                     graphic.setText(elStyle, labelModel, color);\r
20545                     elStyle.text = zrUtil.retrieve(\r
20546                         seriesModel.getFormattedLabel(idx, 'normal'),\r
20547                         data.get(valueDim, idx)\r
20548                     );\r
20549                 }\r
20550                 else {\r
20551                     elStyle.text = '';\r
20552                 }\r
20553 \r
20554                 if (hoverLabelModel.getShallow('show')) {\r
20555                     graphic.setText(hoverStyle, hoverLabelModel, color);\r
20556                     hoverStyle.text = zrUtil.retrieve(\r
20557                         seriesModel.getFormattedLabel(idx, 'emphasis'),\r
20558                         data.get(valueDim, idx)\r
20559                     );\r
20560                 }\r
20561                 else {\r
20562                     hoverStyle.text = '';\r
20563                 }\r
20564 \r
20565                 var size = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));\r
20566 \r
20567                 symbolPath.off('mouseover')\r
20568                     .off('mouseout')\r
20569                     .off('emphasis')\r
20570                     .off('normal');\r
20571 \r
20572                 graphic.setHoverStyle(symbolPath, hoverStyle);\r
20573 \r
20574                 if (itemModel.getShallow('hoverAnimation')) {\r
20575                     var onEmphasis = function() {\r
20576                         var ratio = size[1] / size[0];\r
20577                         this.animateTo({\r
20578                             scale: [\r
20579                                 Math.max(size[0] * 1.1, size[0] + 3),\r
20580                                 Math.max(size[1] * 1.1, size[1] + 3 * ratio)\r
20581                             ]\r
20582                         }, 400, 'elasticOut');\r
20583                     };\r
20584                     var onNormal = function() {\r
20585                         this.animateTo({\r
20586                             scale: size\r
20587                         }, 400, 'elasticOut');\r
20588                     };\r
20589                     symbolPath.on('mouseover', onEmphasis)\r
20590                         .on('mouseout', onNormal)\r
20591                         .on('emphasis', onEmphasis)\r
20592                         .on('normal', onNormal);\r
20593                 }\r
20594             };\r
20595 \r
20596             symbolProto.fadeOut = function (cb) {\r
20597                 var symbolPath = this.childAt(0);\r
20598                 // Not show text when animating\r
20599                 symbolPath.style.text = '';\r
20600                 graphic.updateProps(symbolPath, {\r
20601                     scale: [0, 0]\r
20602                 }, this._seriesModel, cb);\r
20603             };\r
20604 \r
20605             zrUtil.inherits(Symbol, graphic.Group);\r
20606 \r
20607             module.exports = Symbol;\r
20608 \r
20609 \r
20610 /***/ },\r
20611 /* 100 */\r
20612 /***/ function(module, exports, __webpack_require__) {\r
20613 \r
20614         'use strict';\r
20615         // Symbol factory\r
20616 \r
20617 \r
20618             var graphic = __webpack_require__(42);\r
20619             var BoundingRect = __webpack_require__(15);\r
20620 \r
20621             /**\r
20622              * Triangle shape\r
20623              * @inner\r
20624              */\r
20625             var Triangle = graphic.extendShape({\r
20626                 type: 'triangle',\r
20627                 shape: {\r
20628                     cx: 0,\r
20629                     cy: 0,\r
20630                     width: 0,\r
20631                     height: 0\r
20632                 },\r
20633                 buildPath: function (path, shape) {\r
20634                     var cx = shape.cx;\r
20635                     var cy = shape.cy;\r
20636                     var width = shape.width / 2;\r
20637                     var height = shape.height / 2;\r
20638                     path.moveTo(cx, cy - height);\r
20639                     path.lineTo(cx + width, cy + height);\r
20640                     path.lineTo(cx - width, cy + height);\r
20641                     path.closePath();\r
20642                 }\r
20643             });\r
20644             /**\r
20645              * Diamond shape\r
20646              * @inner\r
20647              */\r
20648             var Diamond = graphic.extendShape({\r
20649                 type: 'diamond',\r
20650                 shape: {\r
20651                     cx: 0,\r
20652                     cy: 0,\r
20653                     width: 0,\r
20654                     height: 0\r
20655                 },\r
20656                 buildPath: function (path, shape) {\r
20657                     var cx = shape.cx;\r
20658                     var cy = shape.cy;\r
20659                     var width = shape.width / 2;\r
20660                     var height = shape.height / 2;\r
20661                     path.moveTo(cx, cy - height);\r
20662                     path.lineTo(cx + width, cy);\r
20663                     path.lineTo(cx, cy + height);\r
20664                     path.lineTo(cx - width, cy);\r
20665                     path.closePath();\r
20666                 }\r
20667             });\r
20668 \r
20669             /**\r
20670              * Pin shape\r
20671              * @inner\r
20672              */\r
20673             var Pin = graphic.extendShape({\r
20674                 type: 'pin',\r
20675                 shape: {\r
20676                     // x, y on the cusp\r
20677                     x: 0,\r
20678                     y: 0,\r
20679                     width: 0,\r
20680                     height: 0\r
20681                 },\r
20682 \r
20683                 buildPath: function (path, shape) {\r
20684                     var x = shape.x;\r
20685                     var y = shape.y;\r
20686                     var w = shape.width / 5 * 3;\r
20687                     // Height must be larger than width\r
20688                     var h = Math.max(w, shape.height);\r
20689                     var r = w / 2;\r
20690 \r
20691                     // Dist on y with tangent point and circle center\r
20692                     var dy = r * r / (h - r);\r
20693                     var cy = y - h + r + dy;\r
20694                     var angle = Math.asin(dy / r);\r
20695                     // Dist on x with tangent point and circle center\r
20696                     var dx = Math.cos(angle) * r;\r
20697 \r
20698                     var tanX = Math.sin(angle);\r
20699                     var tanY = Math.cos(angle);\r
20700 \r
20701                     path.arc(\r
20702                         x, cy, r,\r
20703                         Math.PI - angle,\r
20704                         Math.PI * 2 + angle\r
20705                     );\r
20706 \r
20707                     var cpLen = r * 0.6;\r
20708                     var cpLen2 = r * 0.7;\r
20709                     path.bezierCurveTo(\r
20710                         x + dx - tanX * cpLen, cy + dy + tanY * cpLen,\r
20711                         x, y - cpLen2,\r
20712                         x, y\r
20713                     );\r
20714                     path.bezierCurveTo(\r
20715                         x, y - cpLen2,\r
20716                         x - dx + tanX * cpLen, cy + dy + tanY * cpLen,\r
20717                         x - dx, cy + dy\r
20718                     );\r
20719                     path.closePath();\r
20720                 }\r
20721             });\r
20722 \r
20723             /**\r
20724              * Arrow shape\r
20725              * @inner\r
20726              */\r
20727             var Arrow = graphic.extendShape({\r
20728 \r
20729                 type: 'arrow',\r
20730 \r
20731                 shape: {\r
20732                     x: 0,\r
20733                     y: 0,\r
20734                     width: 0,\r
20735                     height: 0\r
20736                 },\r
20737 \r
20738                 buildPath: function (ctx, shape) {\r
20739                     var height = shape.height;\r
20740                     var width = shape.width;\r
20741                     var x = shape.x;\r
20742                     var y = shape.y;\r
20743                     var dx = width / 3 * 2;\r
20744                     ctx.moveTo(x, y);\r
20745                     ctx.lineTo(x + dx, y + height);\r
20746                     ctx.lineTo(x, y + height / 4 * 3);\r
20747                     ctx.lineTo(x - dx, y + height);\r
20748                     ctx.lineTo(x, y);\r
20749                     ctx.closePath();\r
20750                 }\r
20751             });\r
20752 \r
20753             /**\r
20754              * Map of path contructors\r
20755              * @type {Object.<string, module:zrender/graphic/Path>}\r
20756              */\r
20757             var symbolCtors = {\r
20758                 line: graphic.Line,\r
20759 \r
20760                 rect: graphic.Rect,\r
20761 \r
20762                 roundRect: graphic.Rect,\r
20763 \r
20764                 square: graphic.Rect,\r
20765 \r
20766                 circle: graphic.Circle,\r
20767 \r
20768                 diamond: Diamond,\r
20769 \r
20770                 pin: Pin,\r
20771 \r
20772                 arrow: Arrow,\r
20773 \r
20774                 triangle: Triangle\r
20775             };\r
20776 \r
20777             var symbolShapeMakers = {\r
20778 \r
20779                 line: function (x, y, w, h, shape) {\r
20780                     // FIXME\r
20781                     shape.x1 = x;\r
20782                     shape.y1 = y + h / 2;\r
20783                     shape.x2 = x + w;\r
20784                     shape.y2 = y + h / 2;\r
20785                 },\r
20786 \r
20787                 rect: function (x, y, w, h, shape) {\r
20788                     shape.x = x;\r
20789                     shape.y = y;\r
20790                     shape.width = w;\r
20791                     shape.height = h;\r
20792                 },\r
20793 \r
20794                 roundRect: function (x, y, w, h, shape) {\r
20795                     shape.x = x;\r
20796                     shape.y = y;\r
20797                     shape.width = w;\r
20798                     shape.height = h;\r
20799                     shape.r = Math.min(w, h) / 4;\r
20800                 },\r
20801 \r
20802                 square: function (x, y, w, h, shape) {\r
20803                     var size = Math.min(w, h);\r
20804                     shape.x = x;\r
20805                     shape.y = y;\r
20806                     shape.width = size;\r
20807                     shape.height = size;\r
20808                 },\r
20809 \r
20810                 circle: function (x, y, w, h, shape) {\r
20811                     // Put circle in the center of square\r
20812                     shape.cx = x + w / 2;\r
20813                     shape.cy = y + h / 2;\r
20814                     shape.r = Math.min(w, h) / 2;\r
20815                 },\r
20816 \r
20817                 diamond: function (x, y, w, h, shape) {\r
20818                     shape.cx = x + w / 2;\r
20819                     shape.cy = y + h / 2;\r
20820                     shape.width = w;\r
20821                     shape.height = h;\r
20822                 },\r
20823 \r
20824                 pin: function (x, y, w, h, shape) {\r
20825                     shape.x = x + w / 2;\r
20826                     shape.y = y + h / 2;\r
20827                     shape.width = w;\r
20828                     shape.height = h;\r
20829                 },\r
20830 \r
20831                 arrow: function (x, y, w, h, shape) {\r
20832                     shape.x = x + w / 2;\r
20833                     shape.y = y + h / 2;\r
20834                     shape.width = w;\r
20835                     shape.height = h;\r
20836                 },\r
20837 \r
20838                 triangle: function (x, y, w, h, shape) {\r
20839                     shape.cx = x + w / 2;\r
20840                     shape.cy = y + h / 2;\r
20841                     shape.width = w;\r
20842                     shape.height = h;\r
20843                 }\r
20844             };\r
20845 \r
20846             var symbolBuildProxies = {};\r
20847             for (var name in symbolCtors) {\r
20848                 symbolBuildProxies[name] = new symbolCtors[name]();\r
20849             }\r
20850 \r
20851             var Symbol = graphic.extendShape({\r
20852 \r
20853                 type: 'symbol',\r
20854 \r
20855                 shape: {\r
20856                     symbolType: '',\r
20857                     x: 0,\r
20858                     y: 0,\r
20859                     width: 0,\r
20860                     height: 0\r
20861                 },\r
20862 \r
20863                 beforeBrush: function () {\r
20864                     var style = this.style;\r
20865                     var shape = this.shape;\r
20866                     // FIXME\r
20867                     if (shape.symbolType === 'pin' && style.textPosition === 'inside') {\r
20868                         style.textPosition = ['50%', '40%'];\r
20869                         style.textAlign = 'center';\r
20870                         style.textVerticalAlign = 'middle';\r
20871                     }\r
20872                 },\r
20873 \r
20874                 buildPath: function (ctx, shape) {\r
20875                     var symbolType = shape.symbolType;\r
20876                     var proxySymbol = symbolBuildProxies[symbolType];\r
20877                     if (shape.symbolType !== 'none') {\r
20878                         if (!proxySymbol) {\r
20879                             // Default rect\r
20880                             symbolType = 'rect';\r
20881                             proxySymbol = symbolBuildProxies[symbolType];\r
20882                         }\r
20883                         symbolShapeMakers[symbolType](\r
20884                             shape.x, shape.y, shape.width, shape.height, proxySymbol.shape\r
20885                         );\r
20886                         proxySymbol.buildPath(ctx, proxySymbol.shape);\r
20887                     }\r
20888                 }\r
20889             });\r
20890 \r
20891             // Provide setColor helper method to avoid determine if set the fill or stroke outside\r
20892             var symbolPathSetColor = function (color) {\r
20893                 if (this.type !== 'image') {\r
20894                     var symbolStyle = this.style;\r
20895                     var symbolShape = this.shape;\r
20896                     if (symbolShape && symbolShape.symbolType === 'line') {\r
20897                         symbolStyle.stroke = color;\r
20898                     }\r
20899                     else if (this.__isEmptyBrush) {\r
20900                         symbolStyle.stroke = color;\r
20901                         symbolStyle.fill = '#fff';\r
20902                     }\r
20903                     else {\r
20904                         // FIXME 判断图形默认是填充还是描边,使用 onlyStroke ?\r
20905                         symbolStyle.fill && (symbolStyle.fill = color);\r
20906                         symbolStyle.stroke && (symbolStyle.stroke = color);\r
20907                     }\r
20908                     this.dirty();\r
20909                 }\r
20910             };\r
20911 \r
20912             var symbolUtil = {\r
20913                 /**\r
20914                  * Create a symbol element with given symbol configuration: shape, x, y, width, height, color\r
20915                  * @param {string} symbolType\r
20916                  * @param {number} x\r
20917                  * @param {number} y\r
20918                  * @param {number} w\r
20919                  * @param {number} h\r
20920                  * @param {string} color\r
20921                  */\r
20922                 createSymbol: function (symbolType, x, y, w, h, color) {\r
20923                     var isEmpty = symbolType.indexOf('empty') === 0;\r
20924                     if (isEmpty) {\r
20925                         symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);\r
20926                     }\r
20927                     var symbolPath;\r
20928 \r
20929                     if (symbolType.indexOf('image://') === 0) {\r
20930                         symbolPath = new graphic.Image({\r
20931                             style: {\r
20932                                 image: symbolType.slice(8),\r
20933                                 x: x,\r
20934                                 y: y,\r
20935                                 width: w,\r
20936                                 height: h\r
20937                             }\r
20938                         });\r
20939                     }\r
20940                     else if (symbolType.indexOf('path://') === 0) {\r
20941                         symbolPath = graphic.makePath(symbolType.slice(7), {}, new BoundingRect(x, y, w, h));\r
20942                     }\r
20943                     else {\r
20944                         symbolPath = new Symbol({\r
20945                             shape: {\r
20946                                 symbolType: symbolType,\r
20947                                 x: x,\r
20948                                 y: y,\r
20949                                 width: w,\r
20950                                 height: h\r
20951                             }\r
20952                         });\r
20953                     }\r
20954 \r
20955                     symbolPath.__isEmptyBrush = isEmpty;\r
20956 \r
20957                     symbolPath.setColor = symbolPathSetColor;\r
20958 \r
20959                     symbolPath.setColor(color);\r
20960 \r
20961                     return symbolPath;\r
20962                 }\r
20963             };\r
20964 \r
20965             module.exports = symbolUtil;\r
20966 \r
20967 \r
20968 /***/ },\r
20969 /* 101 */\r
20970 /***/ function(module, exports) {\r
20971 \r
20972         \r
20973 \r
20974             // var arrayDiff = require('zrender/lib/core/arrayDiff');\r
20975             // 'zrender/core/arrayDiff' has been used before, but it did\r
20976             // not do well in performance when roam with fixed dataZoom window.\r
20977 \r
20978             function sign(val) {\r
20979                 return val >= 0 ? 1 : -1;\r
20980             }\r
20981 \r
20982             function getStackedOnPoint(coordSys, data, idx) {\r
20983                 var baseAxis = coordSys.getBaseAxis();\r
20984                 var valueAxis = coordSys.getOtherAxis(baseAxis);\r
20985                 var valueStart = baseAxis.onZero\r
20986                     ? 0 : valueAxis.scale.getExtent()[0];\r
20987 \r
20988                 var valueDim = valueAxis.dim;\r
20989                 var baseDataOffset = valueDim === 'x' || valueDim === 'radius' ? 1 : 0;\r
20990 \r
20991                 var stackedOnSameSign;\r
20992                 var stackedOn = data.stackedOn;\r
20993                 var val = data.get(valueDim, idx);\r
20994                 // Find first stacked value with same sign\r
20995                 while (stackedOn &&\r
20996                     sign(stackedOn.get(valueDim, idx)) === sign(val)\r
20997                 ) {\r
20998                     stackedOnSameSign = stackedOn;\r
20999                     break;\r
21000                 }\r
21001                 var stackedData = [];\r
21002                 stackedData[baseDataOffset] = data.get(baseAxis.dim, idx);\r
21003                 stackedData[1 - baseDataOffset] = stackedOnSameSign\r
21004                     ? stackedOnSameSign.get(valueDim, idx, true) : valueStart;\r
21005 \r
21006                 return coordSys.dataToPoint(stackedData);\r
21007             }\r
21008 \r
21009             // function convertToIntId(newIdList, oldIdList) {\r
21010             //     // Generate int id instead of string id.\r
21011             //     // Compare string maybe slow in score function of arrDiff\r
21012 \r
21013             //     // Assume id in idList are all unique\r
21014             //     var idIndicesMap = {};\r
21015             //     var idx = 0;\r
21016             //     for (var i = 0; i < newIdList.length; i++) {\r
21017             //         idIndicesMap[newIdList[i]] = idx;\r
21018             //         newIdList[i] = idx++;\r
21019             //     }\r
21020             //     for (var i = 0; i < oldIdList.length; i++) {\r
21021             //         var oldId = oldIdList[i];\r
21022             //         // Same with newIdList\r
21023             //         if (idIndicesMap[oldId]) {\r
21024             //             oldIdList[i] = idIndicesMap[oldId];\r
21025             //         }\r
21026             //         else {\r
21027             //             oldIdList[i] = idx++;\r
21028             //         }\r
21029             //     }\r
21030             // }\r
21031 \r
21032             function diffData(oldData, newData) {\r
21033                 var diffResult = [];\r
21034 \r
21035                 newData.diff(oldData)\r
21036                     .add(function (idx) {\r
21037                         diffResult.push({cmd: '+', idx: idx});\r
21038                     })\r
21039                     .update(function (newIdx, oldIdx) {\r
21040                         diffResult.push({cmd: '=', idx: oldIdx, idx1: newIdx});\r
21041                     })\r
21042                     .remove(function (idx) {\r
21043                         diffResult.push({cmd: '-', idx: idx});\r
21044                     })\r
21045                     .execute();\r
21046 \r
21047                 return diffResult;\r
21048             }\r
21049 \r
21050             module.exports = function (\r
21051                 oldData, newData,\r
21052                 oldStackedOnPoints, newStackedOnPoints,\r
21053                 oldCoordSys, newCoordSys\r
21054             ) {\r
21055                 var diff = diffData(oldData, newData);\r
21056 \r
21057                 // var newIdList = newData.mapArray(newData.getId);\r
21058                 // var oldIdList = oldData.mapArray(oldData.getId);\r
21059 \r
21060                 // convertToIntId(newIdList, oldIdList);\r
21061 \r
21062                 // // FIXME One data ?\r
21063                 // diff = arrayDiff(oldIdList, newIdList);\r
21064 \r
21065                 var currPoints = [];\r
21066                 var nextPoints = [];\r
21067                 // Points for stacking base line\r
21068                 var currStackedPoints = [];\r
21069                 var nextStackedPoints = [];\r
21070 \r
21071                 var status = [];\r
21072                 var sortedIndices = [];\r
21073                 var rawIndices = [];\r
21074                 var dims = newCoordSys.dimensions;\r
21075                 for (var i = 0; i < diff.length; i++) {\r
21076                     var diffItem = diff[i];\r
21077                     var pointAdded = true;\r
21078 \r
21079                     // FIXME, animation is not so perfect when dataZoom window moves fast\r
21080                     // Which is in case remvoing or add more than one data in the tail or head\r
21081                     switch (diffItem.cmd) {\r
21082                         case '=':\r
21083                             var currentPt = oldData.getItemLayout(diffItem.idx);\r
21084                             var nextPt = newData.getItemLayout(diffItem.idx1);\r
21085                             // If previous data is NaN, use next point directly\r
21086                             if (isNaN(currentPt[0]) || isNaN(currentPt[1])) {\r
21087                                 currentPt = nextPt.slice();\r
21088                             }\r
21089                             currPoints.push(currentPt);\r
21090                             nextPoints.push(nextPt);\r
21091 \r
21092                             currStackedPoints.push(oldStackedOnPoints[diffItem.idx]);\r
21093                             nextStackedPoints.push(newStackedOnPoints[diffItem.idx1]);\r
21094 \r
21095                             rawIndices.push(newData.getRawIndex(diffItem.idx1));\r
21096                             break;\r
21097                         case '+':\r
21098                             var idx = diffItem.idx;\r
21099                             currPoints.push(\r
21100                                 oldCoordSys.dataToPoint([\r
21101                                     newData.get(dims[0], idx, true), newData.get(dims[1], idx, true)\r
21102                                 ])\r
21103                             );\r
21104 \r
21105                             nextPoints.push(newData.getItemLayout(idx).slice());\r
21106 \r
21107                             currStackedPoints.push(\r
21108                                 getStackedOnPoint(oldCoordSys, newData, idx)\r
21109                             );\r
21110                             nextStackedPoints.push(newStackedOnPoints[idx]);\r
21111 \r
21112                             rawIndices.push(newData.getRawIndex(idx));\r
21113                             break;\r
21114                         case '-':\r
21115                             var idx = diffItem.idx;\r
21116                             var rawIndex = oldData.getRawIndex(idx);\r
21117                             // Data is replaced. In the case of dynamic data queue\r
21118                             // FIXME FIXME FIXME\r
21119                             if (rawIndex !== idx) {\r
21120                                 currPoints.push(oldData.getItemLayout(idx));\r
21121                                 nextPoints.push(newCoordSys.dataToPoint([\r
21122                                     oldData.get(dims[0], idx, true), oldData.get(dims[1], idx, true)\r
21123                                 ]));\r
21124 \r
21125                                 currStackedPoints.push(oldStackedOnPoints[idx]);\r
21126                                 nextStackedPoints.push(\r
21127                                     getStackedOnPoint(\r
21128                                         newCoordSys, oldData, idx\r
21129                                     )\r
21130                                 );\r
21131 \r
21132                                 rawIndices.push(rawIndex);\r
21133                             }\r
21134                             else {\r
21135                                 pointAdded = false;\r
21136                             }\r
21137                     }\r
21138 \r
21139                     // Original indices\r
21140                     if (pointAdded) {\r
21141                         status.push(diffItem);\r
21142                         sortedIndices.push(sortedIndices.length);\r
21143                     }\r
21144                 }\r
21145 \r
21146                 // Diff result may be crossed if all items are changed\r
21147                 // Sort by data index\r
21148                 sortedIndices.sort(function (a, b) {\r
21149                     return rawIndices[a] - rawIndices[b];\r
21150                 });\r
21151 \r
21152                 var sortedCurrPoints = [];\r
21153                 var sortedNextPoints = [];\r
21154 \r
21155                 var sortedCurrStackedPoints = [];\r
21156                 var sortedNextStackedPoints = [];\r
21157 \r
21158                 var sortedStatus = [];\r
21159                 for (var i = 0; i < sortedIndices.length; i++) {\r
21160                     var idx = sortedIndices[i];\r
21161                     sortedCurrPoints[i] = currPoints[idx];\r
21162                     sortedNextPoints[i] = nextPoints[idx];\r
21163 \r
21164                     sortedCurrStackedPoints[i] = currStackedPoints[idx];\r
21165                     sortedNextStackedPoints[i] = nextStackedPoints[idx];\r
21166 \r
21167                     sortedStatus[i] = status[idx];\r
21168                 }\r
21169 \r
21170                 return {\r
21171                     current: sortedCurrPoints,\r
21172                     next: sortedNextPoints,\r
21173 \r
21174                     stackedOnCurrent: sortedCurrStackedPoints,\r
21175                     stackedOnNext: sortedNextStackedPoints,\r
21176 \r
21177                     status: sortedStatus\r
21178                 };\r
21179             };\r
21180 \r
21181 \r
21182 /***/ },\r
21183 /* 102 */\r
21184 /***/ function(module, exports, __webpack_require__) {\r
21185 \r
21186         // Poly path support NaN point\r
21187 \r
21188 \r
21189             var Path = __webpack_require__(44);\r
21190             var vec2 = __webpack_require__(16);\r
21191 \r
21192             var vec2Min = vec2.min;\r
21193             var vec2Max = vec2.max;\r
21194 \r
21195             var scaleAndAdd = vec2.scaleAndAdd;\r
21196             var v2Copy = vec2.copy;\r
21197 \r
21198             // Temporary variable\r
21199             var v = [];\r
21200             var cp0 = [];\r
21201             var cp1 = [];\r
21202 \r
21203             function drawSegment(\r
21204                 ctx, points, start, stop, len,\r
21205                 dir, smoothMin, smoothMax, smooth, smoothMonotone\r
21206             ) {\r
21207                 var idx = start;\r
21208                 for (var k = 0; k < len; k++) {\r
21209                     var p = points[idx];\r
21210                     if (idx >= stop || idx < 0 || isNaN(p[0]) || isNaN(p[1])) {\r
21211                         break;\r
21212                     }\r
21213 \r
21214                     if (idx === start) {\r
21215                         ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);\r
21216                         v2Copy(cp0, p);\r
21217                     }\r
21218                     else {\r
21219                         if (smooth > 0) {\r
21220                             var prevIdx = idx - dir;\r
21221                             var nextIdx = idx + dir;\r
21222 \r
21223                             var ratioNextSeg = 0.5;\r
21224                             var prevP = points[prevIdx];\r
21225                             var nextP = points[nextIdx];\r
21226                             // Last point\r
21227                             if ((dir > 0 && (idx === len - 1 || isNaN(nextP[0]) || isNaN(nextP[1])))\r
21228                                 || (dir <= 0 && (idx === 0 ||  isNaN(nextP[0]) || isNaN(nextP[1])))\r
21229                             ) {\r
21230                                 v2Copy(cp1, p);\r
21231                             }\r
21232                             else {\r
21233                                 // If next data is null\r
21234                                 if (isNaN(nextP[0]) || isNaN(nextP[1])) {\r
21235                                     nextP = p;\r
21236                                 }\r
21237 \r
21238                                 vec2.sub(v, nextP, prevP);\r
21239 \r
21240                                 var lenPrevSeg;\r
21241                                 var lenNextSeg;\r
21242                                 if (smoothMonotone === 'x' || smoothMonotone === 'y') {\r
21243                                     var dim = smoothMonotone === 'x' ? 0 : 1;\r
21244                                     lenPrevSeg = Math.abs(p[dim] - prevP[dim]);\r
21245                                     lenNextSeg = Math.abs(p[dim] - nextP[dim]);\r
21246                                 }\r
21247                                 else {\r
21248                                     lenPrevSeg = vec2.dist(p, prevP);\r
21249                                     lenNextSeg = vec2.dist(p, nextP);\r
21250                                 }\r
21251 \r
21252                                 // Use ratio of seg length\r
21253                                 ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);\r
21254 \r
21255                                 scaleAndAdd(cp1, p, v, -smooth * (1 - ratioNextSeg));\r
21256                             }\r
21257                             // Smooth constraint\r
21258                             vec2Min(cp0, cp0, smoothMax);\r
21259                             vec2Max(cp0, cp0, smoothMin);\r
21260                             vec2Min(cp1, cp1, smoothMax);\r
21261                             vec2Max(cp1, cp1, smoothMin);\r
21262 \r
21263                             ctx.bezierCurveTo(\r
21264                                 cp0[0], cp0[1],\r
21265                                 cp1[0], cp1[1],\r
21266                                 p[0], p[1]\r
21267                             );\r
21268                             // cp0 of next segment\r
21269                             scaleAndAdd(cp0, p, v, smooth * ratioNextSeg);\r
21270                         }\r
21271                         else {\r
21272                             ctx.lineTo(p[0], p[1]);\r
21273                         }\r
21274                     }\r
21275 \r
21276                     idx += dir;\r
21277                 }\r
21278 \r
21279                 return k;\r
21280             }\r
21281 \r
21282             function getBoundingBox(points, smoothConstraint) {\r
21283                 var ptMin = [Infinity, Infinity];\r
21284                 var ptMax = [-Infinity, -Infinity];\r
21285                 if (smoothConstraint) {\r
21286                     for (var i = 0; i < points.length; i++) {\r
21287                         var pt = points[i];\r
21288                         if (pt[0] < ptMin[0]) { ptMin[0] = pt[0]; }\r
21289                         if (pt[1] < ptMin[1]) { ptMin[1] = pt[1]; }\r
21290                         if (pt[0] > ptMax[0]) { ptMax[0] = pt[0]; }\r
21291                         if (pt[1] > ptMax[1]) { ptMax[1] = pt[1]; }\r
21292                     }\r
21293                 }\r
21294                 return {\r
21295                     min: smoothConstraint ? ptMin : ptMax,\r
21296                     max: smoothConstraint ? ptMax : ptMin\r
21297                 };\r
21298             }\r
21299 \r
21300             module.exports = {\r
21301 \r
21302                 Polyline: Path.extend({\r
21303 \r
21304                     type: 'ec-polyline',\r
21305 \r
21306                     shape: {\r
21307                         points: [],\r
21308 \r
21309                         smooth: 0,\r
21310 \r
21311                         smoothConstraint: true,\r
21312 \r
21313                         smoothMonotone: null\r
21314                     },\r
21315 \r
21316                     style: {\r
21317                         fill: null,\r
21318 \r
21319                         stroke: '#000'\r
21320                     },\r
21321 \r
21322                     buildPath: function (ctx, shape) {\r
21323                         var points = shape.points;\r
21324 \r
21325                         var i = 0;\r
21326                         var len = points.length;\r
21327 \r
21328                         var result = getBoundingBox(points, shape.smoothConstraint);\r
21329 \r
21330                         while (i < len) {\r
21331                             i += drawSegment(\r
21332                                 ctx, points, i, len, len,\r
21333                                 1, result.min, result.max, shape.smooth,\r
21334                                 shape.smoothMonotone\r
21335                             ) + 1;\r
21336                         }\r
21337                     }\r
21338                 }),\r
21339 \r
21340                 Polygon: Path.extend({\r
21341 \r
21342                     type: 'ec-polygon',\r
21343 \r
21344                     shape: {\r
21345                         points: [],\r
21346 \r
21347                         // Offset between stacked base points and points\r
21348                         stackedOnPoints: [],\r
21349 \r
21350                         smooth: 0,\r
21351 \r
21352                         stackedOnSmooth: 0,\r
21353 \r
21354                         smoothConstraint: true,\r
21355 \r
21356                         smoothMonotone: null\r
21357                     },\r
21358 \r
21359                     buildPath: function (ctx, shape) {\r
21360                         var points = shape.points;\r
21361                         var stackedOnPoints = shape.stackedOnPoints;\r
21362 \r
21363                         var i = 0;\r
21364                         var len = points.length;\r
21365                         var smoothMonotone = shape.smoothMonotone;\r
21366                         var bbox = getBoundingBox(points, shape.smoothConstraint);\r
21367                         var stackedOnBBox = getBoundingBox(stackedOnPoints, shape.smoothConstraint);\r
21368                         while (i < len) {\r
21369                             var k = drawSegment(\r
21370                                 ctx, points, i, len, len,\r
21371                                 1, bbox.min, bbox.max, shape.smooth,\r
21372                                 smoothMonotone\r
21373                             );\r
21374                             drawSegment(\r
21375                                 ctx, stackedOnPoints, i + k - 1, len, k,\r
21376                                 -1, stackedOnBBox.min, stackedOnBBox.max, shape.stackedOnSmooth,\r
21377                                 smoothMonotone\r
21378                             );\r
21379                             i += k + 1;\r
21380 \r
21381                             ctx.closePath();\r
21382                         }\r
21383                     }\r
21384                 })\r
21385             };\r
21386 \r
21387 \r
21388 /***/ },\r
21389 /* 103 */\r
21390 /***/ function(module, exports) {\r
21391 \r
21392         \r
21393 \r
21394             module.exports = function (seriesType, defaultSymbolType, legendSymbol, ecModel, api) {\r
21395 \r
21396                 // Encoding visual for all series include which is filtered for legend drawing\r
21397                 ecModel.eachRawSeriesByType(seriesType, function (seriesModel) {\r
21398                     var data = seriesModel.getData();\r
21399 \r
21400                     var symbolType = seriesModel.get('symbol') || defaultSymbolType;\r
21401                     var symbolSize = seriesModel.get('symbolSize');\r
21402 \r
21403                     data.setVisual({\r
21404                         legendSymbol: legendSymbol || symbolType,\r
21405                         symbol: symbolType,\r
21406                         symbolSize: symbolSize\r
21407                     });\r
21408 \r
21409                     // Only visible series has each data be visual encoded\r
21410                     if (!ecModel.isSeriesFiltered(seriesModel)) {\r
21411                         if (typeof symbolSize === 'function') {\r
21412                             data.each(function (idx) {\r
21413                                 var rawValue = seriesModel.getRawValue(idx);\r
21414                                 // FIXME\r
21415                                 var params = seriesModel.getDataParams(idx);\r
21416                                 data.setItemVisual(idx, 'symbolSize', symbolSize(rawValue, params));\r
21417                             });\r
21418                         }\r
21419                         data.each(function (idx) {\r
21420                             var itemModel = data.getItemModel(idx);\r
21421                             var itemSymbolType = itemModel.get('symbol', true);\r
21422                             var itemSymbolSize = itemModel.get('symbolSize', true);\r
21423                             // If has item symbol\r
21424                             if (itemSymbolType != null) {\r
21425                                 data.setItemVisual(idx, 'symbol', itemSymbolType);\r
21426                             }\r
21427                             if (itemSymbolSize != null) {\r
21428                                 // PENDING Transform symbolSize ?\r
21429                                 data.setItemVisual(idx, 'symbolSize', itemSymbolSize);\r
21430                             }\r
21431                         });\r
21432                     }\r
21433                 });\r
21434             };\r
21435 \r
21436 \r
21437 /***/ },\r
21438 /* 104 */\r
21439 /***/ function(module, exports) {\r
21440 \r
21441         \r
21442 \r
21443             module.exports = function (seriesType, ecModel, api) {\r
21444                 ecModel.eachSeriesByType(seriesType, function (seriesModel) {\r
21445                     var data = seriesModel.getData();\r
21446                     var coordSys = seriesModel.coordinateSystem;\r
21447 \r
21448                     var dims = coordSys.dimensions;\r
21449                     data.each(dims, function (x, y, idx) {\r
21450                         var point;\r
21451                         if (!isNaN(x) && !isNaN(y)) {\r
21452                             point = coordSys.dataToPoint([x, y]);\r
21453                         }\r
21454                         else {\r
21455                             // Also {Array.<number>}, not undefined to avoid if...else... statement\r
21456                             point = [NaN, NaN];\r
21457                         }\r
21458 \r
21459                         data.setItemLayout(idx, point);\r
21460                     }, true);\r
21461                 });\r
21462             };\r
21463 \r
21464 \r
21465 /***/ },\r
21466 /* 105 */\r
21467 /***/ function(module, exports) {\r
21468 \r
21469         \r
21470             var samplers = {\r
21471                 average: function (frame) {\r
21472                     var sum = 0;\r
21473                     var count = 0;\r
21474                     for (var i = 0; i < frame.length; i++) {\r
21475                         if (!isNaN(frame[i])) {\r
21476                             sum += frame[i];\r
21477                             count++;\r
21478                         }\r
21479                     }\r
21480                     // Return NaN if count is 0\r
21481                     return count === 0 ? NaN : sum / count;\r
21482                 },\r
21483                 sum: function (frame) {\r
21484                     var sum = 0;\r
21485                     for (var i = 0; i < frame.length; i++) {\r
21486                         // Ignore NaN\r
21487                         sum += frame[i] || 0;\r
21488                     }\r
21489                     return sum;\r
21490                 },\r
21491                 max: function (frame) {\r
21492                     var max = -Infinity;\r
21493                     for (var i = 0; i < frame.length; i++) {\r
21494                         frame[i] > max && (max = frame[i]);\r
21495                     }\r
21496                     return max;\r
21497                 },\r
21498                 min: function (frame) {\r
21499                     var min = Infinity;\r
21500                     for (var i = 0; i < frame.length; i++) {\r
21501                         frame[i] < min && (min = frame[i]);\r
21502                     }\r
21503                     return min;\r
21504                 }\r
21505             };\r
21506 \r
21507             var indexSampler = function (frame, value) {\r
21508                 return Math.round(frame.length / 2);\r
21509             };\r
21510             module.exports = function (seriesType, ecModel, api) {\r
21511                 ecModel.eachSeriesByType(seriesType, function (seriesModel) {\r
21512                     var data = seriesModel.getData();\r
21513                     var sampling = seriesModel.get('sampling');\r
21514                     var coordSys = seriesModel.coordinateSystem;\r
21515                     // Only cartesian2d support down sampling\r
21516                     if (coordSys.type === 'cartesian2d' && sampling) {\r
21517                         var baseAxis = coordSys.getBaseAxis();\r
21518                         var valueAxis = coordSys.getOtherAxis(baseAxis);\r
21519                         var extent = baseAxis.getExtent();\r
21520                         // Coordinste system has been resized\r
21521                         var size = extent[1] - extent[0];\r
21522                         var rate = Math.round(data.count() / size);\r
21523                         if (rate > 1) {\r
21524                             var sampler;\r
21525                             if (typeof sampling === 'string') {\r
21526                                 sampler = samplers[sampling];\r
21527                             }\r
21528                             else if (typeof sampling === 'function') {\r
21529                                 sampler = sampling;\r
21530                             }\r
21531                             if (sampler) {\r
21532                                 data = data.downSample(\r
21533                                     valueAxis.dim, 1 / rate, sampler, indexSampler\r
21534                                 );\r
21535                                 seriesModel.setData(data);\r
21536                             }\r
21537                         }\r
21538                     }\r
21539                 }, this);\r
21540             };\r
21541 \r
21542 \r
21543 /***/ },\r
21544 /* 106 */\r
21545 /***/ function(module, exports, __webpack_require__) {\r
21546 \r
21547         'use strict';\r
21548 \r
21549 \r
21550             var graphic = __webpack_require__(42);\r
21551             var zrUtil = __webpack_require__(3);\r
21552 \r
21553             __webpack_require__(107);\r
21554 \r
21555             __webpack_require__(124);\r
21556 \r
21557             // Grid view\r
21558             __webpack_require__(1).extendComponentView({\r
21559 \r
21560                 type: 'grid',\r
21561 \r
21562                 render: function (gridModel, ecModel) {\r
21563                     this.group.removeAll();\r
21564                     if (gridModel.get('show')) {\r
21565                         this.group.add(new graphic.Rect({\r
21566                             shape:gridModel.coordinateSystem.getRect(),\r
21567                             style: zrUtil.defaults({\r
21568                                 fill: gridModel.get('backgroundColor')\r
21569                             }, gridModel.getItemStyle()),\r
21570                             silent: true\r
21571                         }));\r
21572                     }\r
21573                 }\r
21574             });\r
21575 \r
21576 \r
21577 /***/ },\r
21578 /* 107 */\r
21579 /***/ function(module, exports, __webpack_require__) {\r
21580 \r
21581         /**\r
21582          * Grid is a region which contains at most 4 cartesian systems\r
21583          *\r
21584          * TODO Default cartesian\r
21585          */\r
21586         var factory = exports;\r
21587 \r
21588             var layout = __webpack_require__(21);\r
21589             var axisHelper = __webpack_require__(108);\r
21590 \r
21591             var zrUtil = __webpack_require__(3);\r
21592             var Cartesian2D = __webpack_require__(114);\r
21593             var Axis2D = __webpack_require__(116);\r
21594 \r
21595             var each = zrUtil.each;\r
21596 \r
21597             var ifAxisCrossZero = axisHelper.ifAxisCrossZero;\r
21598             var niceScaleExtent = axisHelper.niceScaleExtent;\r
21599 \r
21600             // 依赖 GridModel, AxisModel 做预处理\r
21601             __webpack_require__(119);\r
21602 \r
21603             /**\r
21604              * Check if the axis is used in the specified grid\r
21605              * @inner\r
21606              */\r
21607             function isAxisUsedInTheGrid(axisModel, gridModel, ecModel) {\r
21608                 return ecModel.getComponent('grid', axisModel.get('gridIndex')) === gridModel;\r
21609             }\r
21610 \r
21611             function getLabelUnionRect(axis) {\r
21612                 var axisModel = axis.model;\r
21613                 var labels = axisModel.getFormattedLabels();\r
21614                 var rect;\r
21615                 var step = 1;\r
21616                 var labelCount = labels.length;\r
21617                 if (labelCount > 40) {\r
21618                     // Simple optimization for large amount of labels\r
21619                     step = Math.ceil(labelCount / 40);\r
21620                 }\r
21621                 for (var i = 0; i < labelCount; i += step) {\r
21622                     if (!axis.isLabelIgnored(i)) {\r
21623                         var singleRect = axisModel.getTextRect(labels[i]);\r
21624                         // FIXME consider label rotate\r
21625                         rect ? rect.union(singleRect) : (rect = singleRect);\r
21626                     }\r
21627                 }\r
21628                 return rect;\r
21629             }\r
21630 \r
21631             function Grid(gridModel, ecModel, api) {\r
21632                 /**\r
21633                  * @type {Object.<string, module:echarts/coord/cartesian/Cartesian2D>}\r
21634                  * @private\r
21635                  */\r
21636                 this._coordsMap = {};\r
21637 \r
21638                 /**\r
21639                  * @type {Array.<module:echarts/coord/cartesian/Cartesian>}\r
21640                  * @private\r
21641                  */\r
21642                 this._coordsList = [];\r
21643 \r
21644                 /**\r
21645                  * @type {Object.<string, module:echarts/coord/cartesian/Axis2D>}\r
21646                  * @private\r
21647                  */\r
21648                 this._axesMap = {};\r
21649 \r
21650                 /**\r
21651                  * @type {Array.<module:echarts/coord/cartesian/Axis2D>}\r
21652                  * @private\r
21653                  */\r
21654                 this._axesList = [];\r
21655 \r
21656                 this._initCartesian(gridModel, ecModel, api);\r
21657 \r
21658                 this._model = gridModel;\r
21659             }\r
21660 \r
21661             var gridProto = Grid.prototype;\r
21662 \r
21663             gridProto.type = 'grid';\r
21664 \r
21665             gridProto.getRect = function () {\r
21666                 return this._rect;\r
21667             };\r
21668 \r
21669             gridProto.update = function (ecModel, api) {\r
21670 \r
21671                 var axesMap = this._axesMap;\r
21672 \r
21673                 this._updateScale(ecModel, this._model);\r
21674 \r
21675                 function ifAxisCanNotOnZero(otherAxisDim) {\r
21676                     var axes = axesMap[otherAxisDim];\r
21677                     for (var idx in axes) {\r
21678                         var axis = axes[idx];\r
21679                         if (axis && (axis.type === 'category' || !ifAxisCrossZero(axis))) {\r
21680                             return true;\r
21681                         }\r
21682                     }\r
21683                     return false;\r
21684                 }\r
21685 \r
21686                 each(axesMap.x, function (xAxis) {\r
21687                     niceScaleExtent(xAxis, xAxis.model);\r
21688                 });\r
21689                 each(axesMap.y, function (yAxis) {\r
21690                     niceScaleExtent(yAxis, yAxis.model);\r
21691                 });\r
21692                 // Fix configuration\r
21693                 each(axesMap.x, function (xAxis) {\r
21694                     // onZero can not be enabled in these two situations\r
21695                     // 1. When any other axis is a category axis\r
21696                     // 2. When any other axis not across 0 point\r
21697                     if (ifAxisCanNotOnZero('y')) {\r
21698                         xAxis.onZero = false;\r
21699                     }\r
21700                 });\r
21701                 each(axesMap.y, function (yAxis) {\r
21702                     if (ifAxisCanNotOnZero('x')) {\r
21703                         yAxis.onZero = false;\r
21704                     }\r
21705                 });\r
21706 \r
21707                 // Resize again if containLabel is enabled\r
21708                 // FIXME It may cause getting wrong grid size in data processing stage\r
21709                 this.resize(this._model, api);\r
21710             };\r
21711 \r
21712             /**\r
21713              * Resize the grid\r
21714              * @param {module:echarts/coord/cartesian/GridModel} gridModel\r
21715              * @param {module:echarts/ExtensionAPI} api\r
21716              */\r
21717             gridProto.resize = function (gridModel, api) {\r
21718 \r
21719                 var gridRect = layout.getLayoutRect(\r
21720                     gridModel.getBoxLayoutParams(), {\r
21721                         width: api.getWidth(),\r
21722                         height: api.getHeight()\r
21723                     });\r
21724 \r
21725                 this._rect = gridRect;\r
21726 \r
21727                 var axesList = this._axesList;\r
21728 \r
21729                 adjustAxes();\r
21730 \r
21731                 // Minus label size\r
21732                 if (gridModel.get('containLabel')) {\r
21733                     each(axesList, function (axis) {\r
21734                         if (!axis.model.get('axisLabel.inside')) {\r
21735                             var labelUnionRect = getLabelUnionRect(axis);\r
21736                             if (labelUnionRect) {\r
21737                                 var dim = axis.isHorizontal() ? 'height' : 'width';\r
21738                                 var margin = axis.model.get('axisLabel.margin');\r
21739                                 gridRect[dim] -= labelUnionRect[dim] + margin;\r
21740                                 if (axis.position === 'top') {\r
21741                                     gridRect.y += labelUnionRect.height + margin;\r
21742                                 }\r
21743                                 else if (axis.position === 'left')  {\r
21744                                     gridRect.x += labelUnionRect.width + margin;\r
21745                                 }\r
21746                             }\r
21747                         }\r
21748                     });\r
21749 \r
21750                     adjustAxes();\r
21751                 }\r
21752 \r
21753                 function adjustAxes() {\r
21754                     each(axesList, function (axis) {\r
21755                         var isHorizontal = axis.isHorizontal();\r
21756                         var extent = isHorizontal ? [0, gridRect.width] : [0, gridRect.height];\r
21757                         var idx = axis.inverse ? 1 : 0;\r
21758                         axis.setExtent(extent[idx], extent[1 - idx]);\r
21759                         updateAxisTransfrom(axis, isHorizontal ? gridRect.x : gridRect.y);\r
21760                     });\r
21761                 }\r
21762             };\r
21763 \r
21764             /**\r
21765              * @param {string} axisType\r
21766              * @param {ndumber} [axisIndex]\r
21767              */\r
21768             gridProto.getAxis = function (axisType, axisIndex) {\r
21769                 var axesMapOnDim = this._axesMap[axisType];\r
21770                 if (axesMapOnDim != null) {\r
21771                     if (axisIndex == null) {\r
21772                         // Find first axis\r
21773                         for (var name in axesMapOnDim) {\r
21774                             return axesMapOnDim[name];\r
21775                         }\r
21776                     }\r
21777                     return axesMapOnDim[axisIndex];\r
21778                 }\r
21779             };\r
21780 \r
21781             gridProto.getCartesian = function (xAxisIndex, yAxisIndex) {\r
21782                 var key = 'x' + xAxisIndex + 'y' + yAxisIndex;\r
21783                 return this._coordsMap[key];\r
21784             };\r
21785 \r
21786             /**\r
21787              * Initialize cartesian coordinate systems\r
21788              * @private\r
21789              */\r
21790             gridProto._initCartesian = function (gridModel, ecModel, api) {\r
21791                 var axisPositionUsed = {\r
21792                     left: false,\r
21793                     right: false,\r
21794                     top: false,\r
21795                     bottom: false\r
21796                 };\r
21797 \r
21798                 var axesMap = {\r
21799                     x: {},\r
21800                     y: {}\r
21801                 };\r
21802                 var axesCount = {\r
21803                     x: 0,\r
21804                     y: 0\r
21805                 };\r
21806 \r
21807                 /// Create axis\r
21808                 ecModel.eachComponent('xAxis', createAxisCreator('x'), this);\r
21809                 ecModel.eachComponent('yAxis', createAxisCreator('y'), this);\r
21810 \r
21811                 if (!axesCount.x || !axesCount.y) {\r
21812                     // Roll back when there no either x or y axis\r
21813                     this._axesMap = {};\r
21814                     this._axesList = [];\r
21815                     return;\r
21816                 }\r
21817 \r
21818                 this._axesMap = axesMap;\r
21819 \r
21820                 /// Create cartesian2d\r
21821                 each(axesMap.x, function (xAxis, xAxisIndex) {\r
21822                     each(axesMap.y, function (yAxis, yAxisIndex) {\r
21823                         var key = 'x' + xAxisIndex + 'y' + yAxisIndex;\r
21824                         var cartesian = new Cartesian2D(key);\r
21825 \r
21826                         cartesian.grid = this;\r
21827 \r
21828                         this._coordsMap[key] = cartesian;\r
21829                         this._coordsList.push(cartesian);\r
21830 \r
21831                         cartesian.addAxis(xAxis);\r
21832                         cartesian.addAxis(yAxis);\r
21833                     }, this);\r
21834                 }, this);\r
21835 \r
21836                 function createAxisCreator(axisType) {\r
21837                     return function (axisModel, idx) {\r
21838                         if (!isAxisUsedInTheGrid(axisModel, gridModel, ecModel)) {\r
21839                             return;\r
21840                         }\r
21841 \r
21842                         var axisPosition = axisModel.get('position');\r
21843                         if (axisType === 'x') {\r
21844                             // Fix position\r
21845                             if (axisPosition !== 'top' && axisPosition !== 'bottom') {\r
21846                                 // Default bottom of X\r
21847                                 axisPosition = 'bottom';\r
21848                             }\r
21849                             if (axisPositionUsed[axisPosition]) {\r
21850                                 axisPosition = axisPosition === 'top' ? 'bottom' : 'top';\r
21851                             }\r
21852                         }\r
21853                         else {\r
21854                             // Fix position\r
21855                             if (axisPosition !== 'left' && axisPosition !== 'right') {\r
21856                                 // Default left of Y\r
21857                                 axisPosition = 'left';\r
21858                             }\r
21859                             if (axisPositionUsed[axisPosition]) {\r
21860                                 axisPosition = axisPosition === 'left' ? 'right' : 'left';\r
21861                             }\r
21862                         }\r
21863                         axisPositionUsed[axisPosition] = true;\r
21864 \r
21865                         var axis = new Axis2D(\r
21866                             axisType, axisHelper.createScaleByModel(axisModel),\r
21867                             [0, 0],\r
21868                             axisModel.get('type'),\r
21869                             axisPosition\r
21870                         );\r
21871 \r
21872                         var isCategory = axis.type === 'category';\r
21873                         axis.onBand = isCategory && axisModel.get('boundaryGap');\r
21874                         axis.inverse = axisModel.get('inverse');\r
21875 \r
21876                         axis.onZero = axisModel.get('axisLine.onZero');\r
21877 \r
21878                         // Inject axis into axisModel\r
21879                         axisModel.axis = axis;\r
21880 \r
21881                         // Inject axisModel into axis\r
21882                         axis.model = axisModel;\r
21883 \r
21884                         // Index of axis, can be used as key\r
21885                         axis.index = idx;\r
21886 \r
21887                         this._axesList.push(axis);\r
21888 \r
21889                         axesMap[axisType][idx] = axis;\r
21890                         axesCount[axisType]++;\r
21891                     };\r
21892                 }\r
21893             };\r
21894 \r
21895             /**\r
21896              * Update cartesian properties from series\r
21897              * @param  {module:echarts/model/Option} option\r
21898              * @private\r
21899              */\r
21900             gridProto._updateScale = function (ecModel, gridModel) {\r
21901                 // Reset scale\r
21902                 zrUtil.each(this._axesList, function (axis) {\r
21903                     axis.scale.setExtent(Infinity, -Infinity);\r
21904                 });\r
21905                 ecModel.eachSeries(function (seriesModel) {\r
21906                     if (seriesModel.get('coordinateSystem') === 'cartesian2d') {\r
21907                         var xAxisIndex = seriesModel.get('xAxisIndex');\r
21908                         var yAxisIndex = seriesModel.get('yAxisIndex');\r
21909 \r
21910                         var xAxisModel = ecModel.getComponent('xAxis', xAxisIndex);\r
21911                         var yAxisModel = ecModel.getComponent('yAxis', yAxisIndex);\r
21912 \r
21913                         if (!isAxisUsedInTheGrid(xAxisModel, gridModel, ecModel)\r
21914                             || !isAxisUsedInTheGrid(yAxisModel, gridModel, ecModel)\r
21915                          ) {\r
21916                             return;\r
21917                         }\r
21918 \r
21919                         var cartesian = this.getCartesian(xAxisIndex, yAxisIndex);\r
21920                         var data = seriesModel.getData();\r
21921                         var xAxis = cartesian.getAxis('x');\r
21922                         var yAxis = cartesian.getAxis('y');\r
21923 \r
21924                         if (data.type === 'list') {\r
21925                             unionExtent(data, xAxis, seriesModel);\r
21926                             unionExtent(data, yAxis, seriesModel);\r
21927                         }\r
21928                     }\r
21929                 }, this);\r
21930 \r
21931                 function unionExtent(data, axis, seriesModel) {\r
21932                     each(seriesModel.coordDimToDataDim(axis.dim), function (dim) {\r
21933                         axis.scale.unionExtent(data.getDataExtent(\r
21934                             dim, axis.scale.type !== 'ordinal'\r
21935                         ));\r
21936                     });\r
21937                 }\r
21938             };\r
21939 \r
21940             /**\r
21941              * @inner\r
21942              */\r
21943             function updateAxisTransfrom(axis, coordBase) {\r
21944                 var axisExtent = axis.getExtent();\r
21945                 var axisExtentSum = axisExtent[0] + axisExtent[1];\r
21946 \r
21947                 // Fast transform\r
21948                 axis.toGlobalCoord = axis.dim === 'x'\r
21949                     ? function (coord) {\r
21950                         return coord + coordBase;\r
21951                     }\r
21952                     : function (coord) {\r
21953                         return axisExtentSum - coord + coordBase;\r
21954                     };\r
21955                 axis.toLocalCoord = axis.dim === 'x'\r
21956                     ? function (coord) {\r
21957                         return coord - coordBase;\r
21958                     }\r
21959                     : function (coord) {\r
21960                         return axisExtentSum - coord + coordBase;\r
21961                     };\r
21962             }\r
21963 \r
21964             Grid.create = function (ecModel, api) {\r
21965                 var grids = [];\r
21966                 ecModel.eachComponent('grid', function (gridModel, idx) {\r
21967                     var grid = new Grid(gridModel, ecModel, api);\r
21968                     grid.name = 'grid_' + idx;\r
21969                     grid.resize(gridModel, api);\r
21970 \r
21971                     gridModel.coordinateSystem = grid;\r
21972 \r
21973                     grids.push(grid);\r
21974                 });\r
21975 \r
21976                 // Inject the coordinateSystems into seriesModel\r
21977                 ecModel.eachSeries(function (seriesModel) {\r
21978                     if (seriesModel.get('coordinateSystem') !== 'cartesian2d') {\r
21979                         return;\r
21980                     }\r
21981                     var xAxisIndex = seriesModel.get('xAxisIndex');\r
21982                     // TODO Validate\r
21983                     var xAxisModel = ecModel.getComponent('xAxis', xAxisIndex);\r
21984                     var grid = grids[xAxisModel.get('gridIndex')];\r
21985                     seriesModel.coordinateSystem = grid.getCartesian(\r
21986                         xAxisIndex, seriesModel.get('yAxisIndex')\r
21987                     );\r
21988                 });\r
21989 \r
21990                 return grids;\r
21991             };\r
21992 \r
21993             // For deciding which dimensions to use when creating list data\r
21994             Grid.dimensions = Cartesian2D.prototype.dimensions;\r
21995 \r
21996             __webpack_require__(25).register('cartesian2d', Grid);\r
21997 \r
21998             module.exports = Grid;\r
21999 \r
22000 \r
22001 /***/ },\r
22002 /* 108 */\r
22003 /***/ function(module, exports, __webpack_require__) {\r
22004 \r
22005         \r
22006 \r
22007             var OrdinalScale = __webpack_require__(109);\r
22008             var IntervalScale = __webpack_require__(111);\r
22009             __webpack_require__(112);\r
22010             __webpack_require__(113);\r
22011             var Scale = __webpack_require__(110);\r
22012 \r
22013             var numberUtil = __webpack_require__(7);\r
22014             var zrUtil = __webpack_require__(3);\r
22015             var textContain = __webpack_require__(14);\r
22016             var axisHelper = {};\r
22017 \r
22018             /**\r
22019              * Get axis scale extent before niced.\r
22020              */\r
22021             axisHelper.getScaleExtent = function (axis, model) {\r
22022                 var scale = axis.scale;\r
22023                 var originalExtent = scale.getExtent();\r
22024                 var span = originalExtent[1] - originalExtent[0];\r
22025                 if (scale.type === 'ordinal') {\r
22026                     // If series has no data, scale extent may be wrong\r
22027                     if (!isFinite(span)) {\r
22028                         return [0, 0];\r
22029                     }\r
22030                     else {\r
22031                         return originalExtent;\r
22032                     }\r
22033                 }\r
22034                 var min = model.getMin ? model.getMin() : model.get('min');\r
22035                 var max = model.getMax ? model.getMax() : model.get('max');\r
22036                 var crossZero = model.getNeedCrossZero\r
22037                     ? model.getNeedCrossZero() : !model.get('scale');\r
22038                 var boundaryGap = model.get('boundaryGap');\r
22039                 if (!zrUtil.isArray(boundaryGap)) {\r
22040                     boundaryGap = [boundaryGap || 0, boundaryGap || 0];\r
22041                 }\r
22042                 boundaryGap[0] = numberUtil.parsePercent(boundaryGap[0], 1);\r
22043                 boundaryGap[1] = numberUtil.parsePercent(boundaryGap[1], 1);\r
22044                 var fixMin = true;\r
22045                 var fixMax = true;\r
22046                 // Add boundary gap\r
22047                 if (min == null) {\r
22048                     min = originalExtent[0] - boundaryGap[0] * span;\r
22049                     fixMin = false;\r
22050                 }\r
22051                 if (max == null) {\r
22052                     max = originalExtent[1] + boundaryGap[1] * span;\r
22053                     fixMax = false;\r
22054                 }\r
22055                 // TODO Only one data\r
22056                 if (min === 'dataMin') {\r
22057                     min = originalExtent[0];\r
22058                 }\r
22059                 if (max === 'dataMax') {\r
22060                     max = originalExtent[1];\r
22061                 }\r
22062                 // Evaluate if axis needs cross zero\r
22063                 if (crossZero) {\r
22064                     // Axis is over zero and min is not set\r
22065                     if (min > 0 && max > 0 && !fixMin) {\r
22066                         min = 0;\r
22067                     }\r
22068                     // Axis is under zero and max is not set\r
22069                     if (min < 0 && max < 0 && !fixMax) {\r
22070                         max = 0;\r
22071                     }\r
22072                 }\r
22073                 return [min, max];\r
22074             };\r
22075 \r
22076             axisHelper.niceScaleExtent = function (axis, model) {\r
22077                 var scale = axis.scale;\r
22078                 var extent = axisHelper.getScaleExtent(axis, model);\r
22079                 var fixMin = (model.getMin ? model.getMin() : model.get('min')) != null;\r
22080                 var fixMax = (model.getMax ? model.getMax() : model.get('max')) != null;\r
22081                 scale.setExtent(extent[0], extent[1]);\r
22082                 scale.niceExtent(model.get('splitNumber'), fixMin, fixMax);\r
22083 \r
22084                 // If some one specified the min, max. And the default calculated interval\r
22085                 // is not good enough. He can specify the interval. It is often appeared\r
22086                 // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard\r
22087                 // to be 60.\r
22088                 // FIXME\r
22089                 var interval = model.get('interval');\r
22090                 if (interval != null) {\r
22091                     scale.setInterval && scale.setInterval(interval);\r
22092                 }\r
22093             };\r
22094 \r
22095             /**\r
22096              * @param {module:echarts/model/Model} model\r
22097              * @param {string} [axisType] Default retrieve from model.type\r
22098              * @return {module:echarts/scale/*}\r
22099              */\r
22100             axisHelper.createScaleByModel = function(model, axisType) {\r
22101                 axisType = axisType || model.get('type');\r
22102                 if (axisType) {\r
22103                     switch (axisType) {\r
22104                         // Buildin scale\r
22105                         case 'category':\r
22106                             return new OrdinalScale(\r
22107                                 model.getCategories(), [Infinity, -Infinity]\r
22108                             );\r
22109                         case 'value':\r
22110                             return new IntervalScale();\r
22111                         // Extended scale, like time and log\r
22112                         default:\r
22113                             return (Scale.getClass(axisType) || IntervalScale).create(model);\r
22114                     }\r
22115                 }\r
22116             };\r
22117 \r
22118             /**\r
22119              * Check if the axis corss 0\r
22120              */\r
22121             axisHelper.ifAxisCrossZero = function (axis) {\r
22122                 var dataExtent = axis.scale.getExtent();\r
22123                 var min = dataExtent[0];\r
22124                 var max = dataExtent[1];\r
22125                 return !((min > 0 && max > 0) || (min < 0 && max < 0));\r
22126             };\r
22127 \r
22128             /**\r
22129              * @param {Array.<number>} tickCoords In axis self coordinate.\r
22130              * @param {Array.<string>} labels\r
22131              * @param {string} font\r
22132              * @param {boolean} isAxisHorizontal\r
22133              * @return {number}\r
22134              */\r
22135             axisHelper.getAxisLabelInterval = function (tickCoords, labels, font, isAxisHorizontal) {\r
22136                 // FIXME\r
22137                 // 不同角的axis和label,不只是horizontal和vertical.\r
22138 \r
22139                 var textSpaceTakenRect;\r
22140                 var autoLabelInterval = 0;\r
22141                 var accumulatedLabelInterval = 0;\r
22142 \r
22143                 var step = 1;\r
22144                 if (labels.length > 40) {\r
22145                     // Simple optimization for large amount of labels\r
22146                     step = Math.round(labels.length / 40);\r
22147                 }\r
22148                 for (var i = 0; i < tickCoords.length; i += step) {\r
22149                     var tickCoord = tickCoords[i];\r
22150                     var rect = textContain.getBoundingRect(\r
22151                         labels[i], font, 'center', 'top'\r
22152                     );\r
22153                     rect[isAxisHorizontal ? 'x' : 'y'] += tickCoord;\r
22154                     rect[isAxisHorizontal ? 'width' : 'height'] *= 1.5;\r
22155                     if (!textSpaceTakenRect) {\r
22156                         textSpaceTakenRect = rect.clone();\r
22157                     }\r
22158                     // There is no space for current label;\r
22159                     else if (textSpaceTakenRect.intersect(rect)) {\r
22160                         accumulatedLabelInterval++;\r
22161                         autoLabelInterval = Math.max(autoLabelInterval, accumulatedLabelInterval);\r
22162                     }\r
22163                     else {\r
22164                         textSpaceTakenRect.union(rect);\r
22165                         // Reset\r
22166                         accumulatedLabelInterval = 0;\r
22167                     }\r
22168                 }\r
22169                 if (autoLabelInterval === 0 && step > 1) {\r
22170                     return step;\r
22171                 }\r
22172                 return autoLabelInterval * step;\r
22173             };\r
22174 \r
22175             /**\r
22176              * @param {Object} axis\r
22177              * @param {Function} labelFormatter\r
22178              * @return {Array.<string>}\r
22179              */\r
22180             axisHelper.getFormattedLabels = function (axis, labelFormatter) {\r
22181                 var scale = axis.scale;\r
22182                 var labels = scale.getTicksLabels();\r
22183                 var ticks = scale.getTicks();\r
22184                 if (typeof labelFormatter === 'string') {\r
22185                     labelFormatter = (function (tpl) {\r
22186                         return function (val) {\r
22187                             return tpl.replace('{value}', val);\r
22188                         };\r
22189                     })(labelFormatter);\r
22190                     return zrUtil.map(labels, labelFormatter);\r
22191                 }\r
22192                 else if (typeof labelFormatter === 'function') {\r
22193                     return zrUtil.map(ticks, function (tick, idx) {\r
22194                         return labelFormatter(\r
22195                             axis.type === 'category' ? scale.getLabel(tick) : tick,\r
22196                             idx\r
22197                         );\r
22198                     }, this);\r
22199                 }\r
22200                 else {\r
22201                     return labels;\r
22202                 }\r
22203             };\r
22204 \r
22205             module.exports = axisHelper;\r
22206 \r
22207 \r
22208 /***/ },\r
22209 /* 109 */\r
22210 /***/ function(module, exports, __webpack_require__) {\r
22211 \r
22212         /**\r
22213          * Linear continuous scale\r
22214          * @module echarts/coord/scale/Ordinal\r
22215          *\r
22216          * http://en.wikipedia.org/wiki/Level_of_measurement\r
22217          */\r
22218 \r
22219         // FIXME only one data\r
22220 \r
22221 \r
22222             var zrUtil = __webpack_require__(3);\r
22223             var Scale = __webpack_require__(110);\r
22224 \r
22225             var scaleProto = Scale.prototype;\r
22226 \r
22227             var OrdinalScale = Scale.extend({\r
22228 \r
22229                 type: 'ordinal',\r
22230 \r
22231                 init: function (data, extent) {\r
22232                     this._data = data;\r
22233                     this._extent = extent || [0, data.length - 1];\r
22234                 },\r
22235 \r
22236                 parse: function (val) {\r
22237                     return typeof val === 'string'\r
22238                         ? zrUtil.indexOf(this._data, val)\r
22239                         // val might be float.\r
22240                         : Math.round(val);\r
22241                 },\r
22242 \r
22243                 contain: function (rank) {\r
22244                     rank = this.parse(rank);\r
22245                     return scaleProto.contain.call(this, rank)\r
22246                         && this._data[rank] != null;\r
22247                 },\r
22248 \r
22249                 /**\r
22250                  * Normalize given rank or name to linear [0, 1]\r
22251                  * @param {number|string} [val]\r
22252                  * @return {number}\r
22253                  */\r
22254                 normalize: function (val) {\r
22255                     return scaleProto.normalize.call(this, this.parse(val));\r
22256                 },\r
22257 \r
22258                 scale: function (val) {\r
22259                     return Math.round(scaleProto.scale.call(this, val));\r
22260                 },\r
22261 \r
22262                 /**\r
22263                  * @return {Array}\r
22264                  */\r
22265                 getTicks: function () {\r
22266                     var ticks = [];\r
22267                     var extent = this._extent;\r
22268                     var rank = extent[0];\r
22269 \r
22270                     while (rank <= extent[1]) {\r
22271                         ticks.push(rank);\r
22272                         rank++;\r
22273                     }\r
22274 \r
22275                     return ticks;\r
22276                 },\r
22277 \r
22278                 /**\r
22279                  * Get item on rank n\r
22280                  * @param {number} n\r
22281                  * @return {string}\r
22282                  */\r
22283                 getLabel: function (n) {\r
22284                     return this._data[n];\r
22285                 },\r
22286 \r
22287                 /**\r
22288                  * @return {number}\r
22289                  */\r
22290                 count: function () {\r
22291                     return this._extent[1] - this._extent[0] + 1;\r
22292                 },\r
22293 \r
22294                 niceTicks: zrUtil.noop,\r
22295                 niceExtent: zrUtil.noop\r
22296             });\r
22297 \r
22298             /**\r
22299              * @return {module:echarts/scale/Time}\r
22300              */\r
22301             OrdinalScale.create = function () {\r
22302                 return new OrdinalScale();\r
22303             };\r
22304 \r
22305             module.exports = OrdinalScale;\r
22306 \r
22307 \r
22308 /***/ },\r
22309 /* 110 */\r
22310 /***/ function(module, exports, __webpack_require__) {\r
22311 \r
22312         /**\r
22313          * // Scale class management\r
22314          * @module echarts/scale/Scale\r
22315          */\r
22316 \r
22317 \r
22318             var clazzUtil = __webpack_require__(9);\r
22319 \r
22320             function Scale() {\r
22321                 /**\r
22322                  * Extent\r
22323                  * @type {Array.<number>}\r
22324                  * @protected\r
22325                  */\r
22326                 this._extent = [Infinity, -Infinity];\r
22327 \r
22328                 /**\r
22329                  * Step is calculated in adjustExtent\r
22330                  * @type {Array.<number>}\r
22331                  * @protected\r
22332                  */\r
22333                 this._interval = 0;\r
22334 \r
22335                 this.init && this.init.apply(this, arguments);\r
22336             }\r
22337 \r
22338             var scaleProto = Scale.prototype;\r
22339 \r
22340             /**\r
22341              * Parse input val to valid inner number.\r
22342              * @param {*} val\r
22343              * @return {number}\r
22344              */\r
22345             scaleProto.parse = function (val) {\r
22346                 // Notice: This would be a trap here, If the implementation\r
22347                 // of this method depends on extent, and this method is used\r
22348                 // before extent set (like in dataZoom), it would be wrong.\r
22349                 // Nevertheless, parse does not depend on extent generally.\r
22350                 return val;\r
22351             };\r
22352 \r
22353             scaleProto.contain = function (val) {\r
22354                 var extent = this._extent;\r
22355                 return val >= extent[0] && val <= extent[1];\r
22356             };\r
22357 \r
22358             /**\r
22359              * Normalize value to linear [0, 1], return 0.5 if extent span is 0\r
22360              * @param {number} val\r
22361              * @return {number}\r
22362              */\r
22363             scaleProto.normalize = function (val) {\r
22364                 var extent = this._extent;\r
22365                 if (extent[1] === extent[0]) {\r
22366                     return 0.5;\r
22367                 }\r
22368                 return (val - extent[0]) / (extent[1] - extent[0]);\r
22369             };\r
22370 \r
22371             /**\r
22372              * Scale normalized value\r
22373              * @param {number} val\r
22374              * @return {number}\r
22375              */\r
22376             scaleProto.scale = function (val) {\r
22377                 var extent = this._extent;\r
22378                 return val * (extent[1] - extent[0]) + extent[0];\r
22379             };\r
22380 \r
22381             /**\r
22382              * Set extent from data\r
22383              * @param {Array.<number>} other\r
22384              */\r
22385             scaleProto.unionExtent = function (other) {\r
22386                 var extent = this._extent;\r
22387                 other[0] < extent[0] && (extent[0] = other[0]);\r
22388                 other[1] > extent[1] && (extent[1] = other[1]);\r
22389                 // not setExtent because in log axis it may transformed to power\r
22390                 // this.setExtent(extent[0], extent[1]);\r
22391             };\r
22392 \r
22393             /**\r
22394              * Get extent\r
22395              * @return {Array.<number>}\r
22396              */\r
22397             scaleProto.getExtent = function () {\r
22398                 return this._extent.slice();\r
22399             };\r
22400 \r
22401             /**\r
22402              * Set extent\r
22403              * @param {number} start\r
22404              * @param {number} end\r
22405              */\r
22406             scaleProto.setExtent = function (start, end) {\r
22407                 var thisExtent = this._extent;\r
22408                 if (!isNaN(start)) {\r
22409                     thisExtent[0] = start;\r
22410                 }\r
22411                 if (!isNaN(end)) {\r
22412                     thisExtent[1] = end;\r
22413                 }\r
22414             };\r
22415 \r
22416             /**\r
22417              * @return {Array.<string>}\r
22418              */\r
22419             scaleProto.getTicksLabels = function () {\r
22420                 var labels = [];\r
22421                 var ticks = this.getTicks();\r
22422                 for (var i = 0; i < ticks.length; i++) {\r
22423                     labels.push(this.getLabel(ticks[i]));\r
22424                 }\r
22425                 return labels;\r
22426             };\r
22427 \r
22428             clazzUtil.enableClassExtend(Scale);\r
22429             clazzUtil.enableClassManagement(Scale, {\r
22430                 registerWhenExtend: true\r
22431             });\r
22432 \r
22433             module.exports = Scale;\r
22434 \r
22435 \r
22436 /***/ },\r
22437 /* 111 */\r
22438 /***/ function(module, exports, __webpack_require__) {\r
22439 \r
22440         /**\r
22441          * Interval scale\r
22442          * @module echarts/scale/Interval\r
22443          */\r
22444 \r
22445 \r
22446 \r
22447             var numberUtil = __webpack_require__(7);\r
22448             var formatUtil = __webpack_require__(6);\r
22449             var Scale = __webpack_require__(110);\r
22450 \r
22451             var mathFloor = Math.floor;\r
22452             var mathCeil = Math.ceil;\r
22453             /**\r
22454              * @alias module:echarts/coord/scale/Interval\r
22455              * @constructor\r
22456              */\r
22457             var IntervalScale = Scale.extend({\r
22458 \r
22459                 type: 'interval',\r
22460 \r
22461                 _interval: 0,\r
22462 \r
22463                 setExtent: function (start, end) {\r
22464                     var thisExtent = this._extent;\r
22465                     //start,end may be a Number like '25',so...\r
22466                     if (!isNaN(start)) {\r
22467                         thisExtent[0] = parseFloat(start);\r
22468                     }\r
22469                     if (!isNaN(end)) {\r
22470                         thisExtent[1] = parseFloat(end);\r
22471                     }\r
22472                 },\r
22473 \r
22474                 unionExtent: function (other) {\r
22475                     var extent = this._extent;\r
22476                     other[0] < extent[0] && (extent[0] = other[0]);\r
22477                     other[1] > extent[1] && (extent[1] = other[1]);\r
22478 \r
22479                     // unionExtent may called by it's sub classes\r
22480                     IntervalScale.prototype.setExtent.call(this, extent[0], extent[1]);\r
22481                 },\r
22482                 /**\r
22483                  * Get interval\r
22484                  */\r
22485                 getInterval: function () {\r
22486                     if (!this._interval) {\r
22487                         this.niceTicks();\r
22488                     }\r
22489                     return this._interval;\r
22490                 },\r
22491 \r
22492                 /**\r
22493                  * Set interval\r
22494                  */\r
22495                 setInterval: function (interval) {\r
22496                     this._interval = interval;\r
22497                     // Dropped auto calculated niceExtent and use user setted extent\r
22498                     // We assume user wan't to set both interval, min, max to get a better result\r
22499                     this._niceExtent = this._extent.slice();\r
22500                 },\r
22501 \r
22502                 /**\r
22503                  * @return {Array.<number>}\r
22504                  */\r
22505                 getTicks: function () {\r
22506                     if (!this._interval) {\r
22507                         this.niceTicks();\r
22508                     }\r
22509                     var interval = this._interval;\r
22510                     var extent = this._extent;\r
22511                     var ticks = [];\r
22512 \r
22513                     // Consider this case: using dataZoom toolbox, zoom and zoom.\r
22514                     var safeLimit = 10000;\r
22515 \r
22516                     if (interval) {\r
22517                         var niceExtent = this._niceExtent;\r
22518                         if (extent[0] < niceExtent[0]) {\r
22519                             ticks.push(extent[0]);\r
22520                         }\r
22521                         var tick = niceExtent[0];\r
22522                         while (tick <= niceExtent[1]) {\r
22523                             ticks.push(tick);\r
22524                             // Avoid rounding error\r
22525                             tick = numberUtil.round(tick + interval);\r
22526                             if (ticks.length > safeLimit) {\r
22527                                 return [];\r
22528                             }\r
22529                         }\r
22530                         if (extent[1] > niceExtent[1]) {\r
22531                             ticks.push(extent[1]);\r
22532                         }\r
22533                     }\r
22534 \r
22535                     return ticks;\r
22536                 },\r
22537 \r
22538                 /**\r
22539                  * @return {Array.<string>}\r
22540                  */\r
22541                 getTicksLabels: function () {\r
22542                     var labels = [];\r
22543                     var ticks = this.getTicks();\r
22544                     for (var i = 0; i < ticks.length; i++) {\r
22545                         labels.push(this.getLabel(ticks[i]));\r
22546                     }\r
22547                     return labels;\r
22548                 },\r
22549 \r
22550                 /**\r
22551                  * @param {number} n\r
22552                  * @return {number}\r
22553                  */\r
22554                 getLabel: function (data) {\r
22555                     return formatUtil.addCommas(data);\r
22556                 },\r
22557 \r
22558                 /**\r
22559                  * Update interval and extent of intervals for nice ticks\r
22560                  *\r
22561                  * @param {number} [splitNumber = 5] Desired number of ticks\r
22562                  */\r
22563                 niceTicks: function (splitNumber) {\r
22564                     splitNumber = splitNumber || 5;\r
22565                     var extent = this._extent;\r
22566                     var span = extent[1] - extent[0];\r
22567                     if (!isFinite(span)) {\r
22568                         return;\r
22569                     }\r
22570                     // User may set axis min 0 and data are all negative\r
22571                     // FIXME If it needs to reverse ?\r
22572                     if (span < 0) {\r
22573                         span = -span;\r
22574                         extent.reverse();\r
22575                     }\r
22576 \r
22577                     // From "Nice Numbers for Graph Labels" of Graphic Gems\r
22578                     // var niceSpan = numberUtil.nice(span, false);\r
22579                     var step = numberUtil.nice(span / splitNumber, true);\r
22580 \r
22581                     // Niced extent inside original extent\r
22582                     var niceExtent = [\r
22583                         numberUtil.round(mathCeil(extent[0] / step) * step),\r
22584                         numberUtil.round(mathFloor(extent[1] / step) * step)\r
22585                     ];\r
22586 \r
22587                     this._interval = step;\r
22588                     this._niceExtent = niceExtent;\r
22589                 },\r
22590 \r
22591                 /**\r
22592                  * Nice extent.\r
22593                  * @param {number} [splitNumber = 5] Given approx tick number\r
22594                  * @param {boolean} [fixMin=false]\r
22595                  * @param {boolean} [fixMax=false]\r
22596                  */\r
22597                 niceExtent: function (splitNumber, fixMin, fixMax) {\r
22598                     var extent = this._extent;\r
22599                     // If extent start and end are same, expand them\r
22600                     if (extent[0] === extent[1]) {\r
22601                         if (extent[0] !== 0) {\r
22602                             // Expand extent\r
22603                             var expandSize = extent[0] / 2;\r
22604                             extent[0] -= expandSize;\r
22605                             extent[1] += expandSize;\r
22606                         }\r
22607                         else {\r
22608                             extent[1] = 1;\r
22609                         }\r
22610                     }\r
22611                     var span = extent[1] - extent[0];\r
22612                     // If there are no data and extent are [Infinity, -Infinity]\r
22613                     if (!isFinite(span)) {\r
22614                         extent[0] = 0;\r
22615                         extent[1] = 1;\r
22616                     }\r
22617 \r
22618                     this.niceTicks(splitNumber);\r
22619 \r
22620                     // var extent = this._extent;\r
22621                     var interval = this._interval;\r
22622 \r
22623                     if (!fixMin) {\r
22624                         extent[0] = numberUtil.round(mathFloor(extent[0] / interval) * interval);\r
22625                     }\r
22626                     if (!fixMax) {\r
22627                         extent[1] = numberUtil.round(mathCeil(extent[1] / interval) * interval);\r
22628                     }\r
22629                 }\r
22630             });\r
22631 \r
22632             /**\r
22633              * @return {module:echarts/scale/Time}\r
22634              */\r
22635             IntervalScale.create = function () {\r
22636                 return new IntervalScale();\r
22637             };\r
22638 \r
22639             module.exports = IntervalScale;\r
22640 \r
22641 \r
22642 \r
22643 /***/ },\r
22644 /* 112 */\r
22645 /***/ function(module, exports, __webpack_require__) {\r
22646 \r
22647         /**\r
22648          * Interval scale\r
22649          * @module echarts/coord/scale/Time\r
22650          */\r
22651 \r
22652 \r
22653 \r
22654             var zrUtil = __webpack_require__(3);\r
22655             var numberUtil = __webpack_require__(7);\r
22656             var formatUtil = __webpack_require__(6);\r
22657 \r
22658             var IntervalScale = __webpack_require__(111);\r
22659 \r
22660             var intervalScaleProto = IntervalScale.prototype;\r
22661 \r
22662             var mathCeil = Math.ceil;\r
22663             var mathFloor = Math.floor;\r
22664             var ONE_DAY = 3600000 * 24;\r
22665 \r
22666             // FIXME 公用?\r
22667             var bisect = function (a, x, lo, hi) {\r
22668                 while (lo < hi) {\r
22669                     var mid = lo + hi >>> 1;\r
22670                     if (a[mid][2] < x) {\r
22671                         lo = mid + 1;\r
22672                     }\r
22673                     else {\r
22674                         hi  = mid;\r
22675                     }\r
22676                 }\r
22677                 return lo;\r
22678             };\r
22679 \r
22680             /**\r
22681              * @alias module:echarts/coord/scale/Time\r
22682              * @constructor\r
22683              */\r
22684             var TimeScale = IntervalScale.extend({\r
22685                 type: 'time',\r
22686 \r
22687                 // Overwrite\r
22688                 getLabel: function (val) {\r
22689                     var stepLvl = this._stepLvl;\r
22690 \r
22691                     var date = new Date(val);\r
22692 \r
22693                     return formatUtil.formatTime(stepLvl[0], date);\r
22694                 },\r
22695 \r
22696                 // Overwrite\r
22697                 niceExtent: function (approxTickNum, fixMin, fixMax) {\r
22698                     var extent = this._extent;\r
22699                     // If extent start and end are same, expand them\r
22700                     if (extent[0] === extent[1]) {\r
22701                         // Expand extent\r
22702                         extent[0] -= ONE_DAY;\r
22703                         extent[1] += ONE_DAY;\r
22704                     }\r
22705                     // If there are no data and extent are [Infinity, -Infinity]\r
22706                     if (extent[1] === -Infinity && extent[0] === Infinity) {\r
22707                         var d = new Date();\r
22708                         extent[1] = new Date(d.getFullYear(), d.getMonth(), d.getDate());\r
22709                         extent[0] = extent[1] - ONE_DAY;\r
22710                     }\r
22711 \r
22712                     this.niceTicks(approxTickNum, fixMin, fixMax);\r
22713 \r
22714                     // var extent = this._extent;\r
22715                     var interval = this._interval;\r
22716 \r
22717                     if (!fixMin) {\r
22718                         extent[0] = numberUtil.round(mathFloor(extent[0] / interval) * interval);\r
22719                     }\r
22720                     if (!fixMax) {\r
22721                         extent[1] = numberUtil.round(mathCeil(extent[1] / interval) * interval);\r
22722                     }\r
22723                 },\r
22724 \r
22725                 // Overwrite\r
22726                 niceTicks: function (approxTickNum) {\r
22727                     approxTickNum = approxTickNum || 10;\r
22728 \r
22729                     var extent = this._extent;\r
22730                     var span = extent[1] - extent[0];\r
22731                     var approxInterval = span / approxTickNum;\r
22732                     var scaleLevelsLen = scaleLevels.length;\r
22733                     var idx = bisect(scaleLevels, approxInterval, 0, scaleLevelsLen);\r
22734 \r
22735                     var level = scaleLevels[Math.min(idx, scaleLevelsLen - 1)];\r
22736                     var interval = level[2];\r
22737                     // Same with interval scale if span is much larger than 1 year\r
22738                     if (level[0] === 'year') {\r
22739                         var yearSpan = span / interval;\r
22740 \r
22741                         // From "Nice Numbers for Graph Labels" of Graphic Gems\r
22742                         // var niceYearSpan = numberUtil.nice(yearSpan, false);\r
22743                         var yearStep = numberUtil.nice(yearSpan / approxTickNum, true);\r
22744 \r
22745                         interval *= yearStep;\r
22746                     }\r
22747 \r
22748                     var niceExtent = [\r
22749                         mathCeil(extent[0] / interval) * interval,\r
22750                         mathFloor(extent[1] / interval) * interval\r
22751                     ];\r
22752 \r
22753                     this._stepLvl = level;\r
22754                     // Interval will be used in getTicks\r
22755                     this._interval = interval;\r
22756                     this._niceExtent = niceExtent;\r
22757                 },\r
22758 \r
22759                 parse: function (val) {\r
22760                     // val might be float.\r
22761                     return +numberUtil.parseDate(val);\r
22762                 }\r
22763             });\r
22764 \r
22765             zrUtil.each(['contain', 'normalize'], function (methodName) {\r
22766                 TimeScale.prototype[methodName] = function (val) {\r
22767                     return intervalScaleProto[methodName].call(this, this.parse(val));\r
22768                 };\r
22769             });\r
22770 \r
22771             // Steps from d3\r
22772             var scaleLevels = [\r
22773                 // Format       step    interval\r
22774                 ['hh:mm:ss',    1,      1000],           // 1s\r
22775                 ['hh:mm:ss',    5,      1000 * 5],       // 5s\r
22776                 ['hh:mm:ss',    10,     1000 * 10],      // 10s\r
22777                 ['hh:mm:ss',    15,     1000 * 15],      // 15s\r
22778                 ['hh:mm:ss',    30,     1000 * 30],      // 30s\r
22779                 ['hh:mm\nMM-dd',1,      60000],          // 1m\r
22780                 ['hh:mm\nMM-dd',5,      60000 * 5],      // 5m\r
22781                 ['hh:mm\nMM-dd',10,     60000 * 10],     // 10m\r
22782                 ['hh:mm\nMM-dd',15,     60000 * 15],     // 15m\r
22783                 ['hh:mm\nMM-dd',30,     60000 * 30],     // 30m\r
22784                 ['hh:mm\nMM-dd',1,      3600000],        // 1h\r
22785                 ['hh:mm\nMM-dd',2,      3600000 * 2],    // 2h\r
22786                 ['hh:mm\nMM-dd',6,      3600000 * 6],    // 6h\r
22787                 ['hh:mm\nMM-dd',12,     3600000 * 12],   // 12h\r
22788                 ['MM-dd\nyyyy', 1,      ONE_DAY],   // 1d\r
22789                 ['week',        7,      ONE_DAY * 7],        // 7d\r
22790                 ['month',       1,      ONE_DAY * 31],       // 1M\r
22791                 ['quarter',     3,      ONE_DAY * 380 / 4],  // 3M\r
22792                 ['half-year',   6,      ONE_DAY * 380 / 2],  // 6M\r
22793                 ['year',        1,      ONE_DAY * 380]       // 1Y\r
22794             ];\r
22795 \r
22796             /**\r
22797              * @return {module:echarts/scale/Time}\r
22798              */\r
22799             TimeScale.create = function () {\r
22800                 return new TimeScale();\r
22801             };\r
22802 \r
22803             module.exports = TimeScale;\r
22804 \r
22805 \r
22806 /***/ },\r
22807 /* 113 */\r
22808 /***/ function(module, exports, __webpack_require__) {\r
22809 \r
22810         /**\r
22811          * Log scale\r
22812          * @module echarts/scale/Log\r
22813          */\r
22814 \r
22815 \r
22816             var zrUtil = __webpack_require__(3);\r
22817             var Scale = __webpack_require__(110);\r
22818             var numberUtil = __webpack_require__(7);\r
22819 \r
22820             // Use some method of IntervalScale\r
22821             var IntervalScale = __webpack_require__(111);\r
22822 \r
22823             var scaleProto = Scale.prototype;\r
22824             var intervalScaleProto = IntervalScale.prototype;\r
22825 \r
22826             var mathFloor = Math.floor;\r
22827             var mathCeil = Math.ceil;\r
22828             var mathPow = Math.pow;\r
22829 \r
22830             var LOG_BASE = 10;\r
22831             var mathLog = Math.log;\r
22832 \r
22833             var LogScale = Scale.extend({\r
22834 \r
22835                 type: 'log',\r
22836 \r
22837                 /**\r
22838                  * @return {Array.<number>}\r
22839                  */\r
22840                 getTicks: function () {\r
22841                     return zrUtil.map(intervalScaleProto.getTicks.call(this), function (val) {\r
22842                         return numberUtil.round(mathPow(LOG_BASE, val));\r
22843                     });\r
22844                 },\r
22845 \r
22846                 /**\r
22847                  * @param {number} val\r
22848                  * @return {string}\r
22849                  */\r
22850                 getLabel: intervalScaleProto.getLabel,\r
22851 \r
22852                 /**\r
22853                  * @param  {number} val\r
22854                  * @return {number}\r
22855                  */\r
22856                 scale: function (val) {\r
22857                     val = scaleProto.scale.call(this, val);\r
22858                     return mathPow(LOG_BASE, val);\r
22859                 },\r
22860 \r
22861                 /**\r
22862                  * @param {number} start\r
22863                  * @param {number} end\r
22864                  */\r
22865                 setExtent: function (start, end) {\r
22866                     start = mathLog(start) / mathLog(LOG_BASE);\r
22867                     end = mathLog(end) / mathLog(LOG_BASE);\r
22868                     intervalScaleProto.setExtent.call(this, start, end);\r
22869                 },\r
22870 \r
22871                 /**\r
22872                  * @return {number} end\r
22873                  */\r
22874                 getExtent: function () {\r
22875                     var extent = scaleProto.getExtent.call(this);\r
22876                     extent[0] = mathPow(LOG_BASE, extent[0]);\r
22877                     extent[1] = mathPow(LOG_BASE, extent[1]);\r
22878                     return extent;\r
22879                 },\r
22880 \r
22881                 /**\r
22882                  * @param  {Array.<number>} extent\r
22883                  */\r
22884                 unionExtent: function (extent) {\r
22885                     extent[0] = mathLog(extent[0]) / mathLog(LOG_BASE);\r
22886                     extent[1] = mathLog(extent[1]) / mathLog(LOG_BASE);\r
22887                     scaleProto.unionExtent.call(this, extent);\r
22888                 },\r
22889 \r
22890                 /**\r
22891                  * Update interval and extent of intervals for nice ticks\r
22892                  * @param  {number} [approxTickNum = 10] Given approx tick number\r
22893                  */\r
22894                 niceTicks: function (approxTickNum) {\r
22895                     approxTickNum = approxTickNum || 10;\r
22896                     var extent = this._extent;\r
22897                     var span = extent[1] - extent[0];\r
22898                     if (span === Infinity || span <= 0) {\r
22899                         return;\r
22900                     }\r
22901 \r
22902                     var interval = mathPow(10, mathFloor(mathLog(span / approxTickNum) / Math.LN10));\r
22903                     var err = approxTickNum / span * interval;\r
22904 \r
22905                     // Filter ticks to get closer to the desired count.\r
22906                     if (err <= 0.5) {\r
22907                         interval *= 10;\r
22908                     }\r
22909                     var niceExtent = [\r
22910                         numberUtil.round(mathCeil(extent[0] / interval) * interval),\r
22911                         numberUtil.round(mathFloor(extent[1] / interval) * interval)\r
22912                     ];\r
22913 \r
22914                     this._interval = interval;\r
22915                     this._niceExtent = niceExtent;\r
22916                 },\r
22917 \r
22918                 /**\r
22919                  * Nice extent.\r
22920                  * @param {number} [approxTickNum = 10] Given approx tick number\r
22921                  * @param {boolean} [fixMin=false]\r
22922                  * @param {boolean} [fixMax=false]\r
22923                  */\r
22924                 niceExtent: intervalScaleProto.niceExtent\r
22925             });\r
22926 \r
22927             zrUtil.each(['contain', 'normalize'], function (methodName) {\r
22928                 LogScale.prototype[methodName] = function (val) {\r
22929                     val = mathLog(val) / mathLog(LOG_BASE);\r
22930                     return scaleProto[methodName].call(this, val);\r
22931                 };\r
22932             });\r
22933 \r
22934             LogScale.create = function () {\r
22935                 return new LogScale();\r
22936             };\r
22937 \r
22938             module.exports = LogScale;\r
22939 \r
22940 \r
22941 /***/ },\r
22942 /* 114 */\r
22943 /***/ function(module, exports, __webpack_require__) {\r
22944 \r
22945         'use strict';\r
22946 \r
22947 \r
22948             var zrUtil = __webpack_require__(3);\r
22949             var Cartesian = __webpack_require__(115);\r
22950 \r
22951             function Cartesian2D(name) {\r
22952 \r
22953                 Cartesian.call(this, name);\r
22954             }\r
22955 \r
22956             Cartesian2D.prototype = {\r
22957 \r
22958                 constructor: Cartesian2D,\r
22959 \r
22960                 type: 'cartesian2d',\r
22961 \r
22962                 /**\r
22963                  * @type {Array.<string>}\r
22964                  * @readOnly\r
22965                  */\r
22966                 dimensions: ['x', 'y'],\r
22967 \r
22968                 /**\r
22969                  * Base axis will be used on stacking.\r
22970                  *\r
22971                  * @return {module:echarts/coord/cartesian/Axis2D}\r
22972                  */\r
22973                 getBaseAxis: function () {\r
22974                     return this.getAxesByScale('ordinal')[0]\r
22975                         || this.getAxesByScale('time')[0]\r
22976                         || this.getAxis('x');\r
22977                 },\r
22978 \r
22979                 /**\r
22980                  * If contain point\r
22981                  * @param {Array.<number>} point\r
22982                  * @return {boolean}\r
22983                  */\r
22984                 containPoint: function (point) {\r
22985                     var axisX = this.getAxis('x');\r
22986                     var axisY = this.getAxis('y');\r
22987                     return axisX.contain(axisX.toLocalCoord(point[0]))\r
22988                         && axisY.contain(axisY.toLocalCoord(point[1]));\r
22989                 },\r
22990 \r
22991                 /**\r
22992                  * If contain data\r
22993                  * @param {Array.<number>} data\r
22994                  * @return {boolean}\r
22995                  */\r
22996                 containData: function (data) {\r
22997                     return this.getAxis('x').containData(data[0])\r
22998                         && this.getAxis('y').containData(data[1]);\r
22999                 },\r
23000 \r
23001                 /**\r
23002                  * Convert series data to an array of points\r
23003                  * @param {module:echarts/data/List} data\r
23004                  * @param {boolean} stack\r
23005                  * @return {Array}\r
23006                  *  Return array of points. For example:\r
23007                  *  `[[10, 10], [20, 20], [30, 30]]`\r
23008                  */\r
23009                 dataToPoints: function (data, stack) {\r
23010                     return data.mapArray(['x', 'y'], function (x, y) {\r
23011                         return this.dataToPoint([x, y]);\r
23012                     }, stack, this);\r
23013                 },\r
23014 \r
23015                 /**\r
23016                  * @param {Array.<number>} data\r
23017                  * @param {boolean} [clamp=false]\r
23018                  * @return {Array.<number>}\r
23019                  */\r
23020                 dataToPoint: function (data, clamp) {\r
23021                     var xAxis = this.getAxis('x');\r
23022                     var yAxis = this.getAxis('y');\r
23023                     return [\r
23024                         xAxis.toGlobalCoord(xAxis.dataToCoord(data[0], clamp)),\r
23025                         yAxis.toGlobalCoord(yAxis.dataToCoord(data[1], clamp))\r
23026                     ];\r
23027                 },\r
23028 \r
23029                 /**\r
23030                  * @param {Array.<number>} point\r
23031                  * @param {boolean} [clamp=false]\r
23032                  * @return {Array.<number>}\r
23033                  */\r
23034                 pointToData: function (point, clamp) {\r
23035                     var xAxis = this.getAxis('x');\r
23036                     var yAxis = this.getAxis('y');\r
23037                     return [\r
23038                         xAxis.coordToData(xAxis.toLocalCoord(point[0]), clamp),\r
23039                         yAxis.coordToData(yAxis.toLocalCoord(point[1]), clamp)\r
23040                     ];\r
23041                 },\r
23042 \r
23043                 /**\r
23044                  * Get other axis\r
23045                  * @param {module:echarts/coord/cartesian/Axis2D} axis\r
23046                  */\r
23047                 getOtherAxis: function (axis) {\r
23048                     return this.getAxis(axis.dim === 'x' ? 'y' : 'x');\r
23049                 }\r
23050             };\r
23051 \r
23052             zrUtil.inherits(Cartesian2D, Cartesian);\r
23053 \r
23054             module.exports = Cartesian2D;\r
23055 \r
23056 \r
23057 /***/ },\r
23058 /* 115 */\r
23059 /***/ function(module, exports, __webpack_require__) {\r
23060 \r
23061         'use strict';\r
23062         /**\r
23063          * Cartesian coordinate system\r
23064          * @module  echarts/coord/Cartesian\r
23065          *\r
23066          */\r
23067 \r
23068 \r
23069             var zrUtil = __webpack_require__(3);\r
23070 \r
23071             function dimAxisMapper(dim) {\r
23072                 return this._axes[dim];\r
23073             }\r
23074 \r
23075             /**\r
23076              * @alias module:echarts/coord/Cartesian\r
23077              * @constructor\r
23078              */\r
23079             var Cartesian = function (name) {\r
23080                 this._axes = {};\r
23081 \r
23082                 this._dimList = [];\r
23083 \r
23084                 /**\r
23085                  * @type {string}\r
23086                  */\r
23087                 this.name = name || '';\r
23088             };\r
23089 \r
23090             Cartesian.prototype = {\r
23091 \r
23092                 constructor: Cartesian,\r
23093 \r
23094                 type: 'cartesian',\r
23095 \r
23096                 /**\r
23097                  * Get axis\r
23098                  * @param  {number|string} dim\r
23099                  * @return {module:echarts/coord/Cartesian~Axis}\r
23100                  */\r
23101                 getAxis: function (dim) {\r
23102                     return this._axes[dim];\r
23103                 },\r
23104 \r
23105                 /**\r
23106                  * Get axes list\r
23107                  * @return {Array.<module:echarts/coord/Cartesian~Axis>}\r
23108                  */\r
23109                 getAxes: function () {\r
23110                     return zrUtil.map(this._dimList, dimAxisMapper, this);\r
23111                 },\r
23112 \r
23113                 /**\r
23114                  * Get axes list by given scale type\r
23115                  */\r
23116                 getAxesByScale: function (scaleType) {\r
23117                     scaleType = scaleType.toLowerCase();\r
23118                     return zrUtil.filter(\r
23119                         this.getAxes(),\r
23120                         function (axis) {\r
23121                             return axis.scale.type === scaleType;\r
23122                         }\r
23123                     );\r
23124                 },\r
23125 \r
23126                 /**\r
23127                  * Add axis\r
23128                  * @param {module:echarts/coord/Cartesian.Axis}\r
23129                  */\r
23130                 addAxis: function (axis) {\r
23131                     var dim = axis.dim;\r
23132 \r
23133                     this._axes[dim] = axis;\r
23134 \r
23135                     this._dimList.push(dim);\r
23136                 },\r
23137 \r
23138                 /**\r
23139                  * Convert data to coord in nd space\r
23140                  * @param {Array.<number>|Object.<string, number>} val\r
23141                  * @return {Array.<number>|Object.<string, number>}\r
23142                  */\r
23143                 dataToCoord: function (val) {\r
23144                     return this._dataCoordConvert(val, 'dataToCoord');\r
23145                 },\r
23146 \r
23147                 /**\r
23148                  * Convert coord in nd space to data\r
23149                  * @param  {Array.<number>|Object.<string, number>} val\r
23150                  * @return {Array.<number>|Object.<string, number>}\r
23151                  */\r
23152                 coordToData: function (val) {\r
23153                     return this._dataCoordConvert(val, 'coordToData');\r
23154                 },\r
23155 \r
23156                 _dataCoordConvert: function (input, method) {\r
23157                     var dimList = this._dimList;\r
23158 \r
23159                     var output = input instanceof Array ? [] : {};\r
23160 \r
23161                     for (var i = 0; i < dimList.length; i++) {\r
23162                         var dim = dimList[i];\r
23163                         var axis = this._axes[dim];\r
23164 \r
23165                         output[dim] = axis[method](input[dim]);\r
23166                     }\r
23167 \r
23168                     return output;\r
23169                 }\r
23170             };\r
23171 \r
23172             module.exports = Cartesian;\r
23173 \r
23174 \r
23175 /***/ },\r
23176 /* 116 */\r
23177 /***/ function(module, exports, __webpack_require__) {\r
23178 \r
23179         \r
23180 \r
23181             var zrUtil = __webpack_require__(3);\r
23182             var Axis = __webpack_require__(117);\r
23183             var axisLabelInterval = __webpack_require__(118);\r
23184 \r
23185             /**\r
23186              * Extend axis 2d\r
23187              * @constructor module:echarts/coord/cartesian/Axis2D\r
23188              * @extends {module:echarts/coord/cartesian/Axis}\r
23189              * @param {string} dim\r
23190              * @param {*} scale\r
23191              * @param {Array.<number>} coordExtent\r
23192              * @param {string} axisType\r
23193              * @param {string} position\r
23194              */\r
23195             var Axis2D = function (dim, scale, coordExtent, axisType, position) {\r
23196                 Axis.call(this, dim, scale, coordExtent);\r
23197                 /**\r
23198                  * Axis type\r
23199                  *  - 'category'\r
23200                  *  - 'value'\r
23201                  *  - 'time'\r
23202                  *  - 'log'\r
23203                  * @type {string}\r
23204                  */\r
23205                 this.type = axisType || 'value';\r
23206 \r
23207                 /**\r
23208                  * Axis position\r
23209                  *  - 'top'\r
23210                  *  - 'bottom'\r
23211                  *  - 'left'\r
23212                  *  - 'right'\r
23213                  */\r
23214                 this.position = position || 'bottom';\r
23215             };\r
23216 \r
23217             Axis2D.prototype = {\r
23218 \r
23219                 constructor: Axis2D,\r
23220 \r
23221                 /**\r
23222                  * Index of axis, can be used as key\r
23223                  */\r
23224                 index: 0,\r
23225                 /**\r
23226                  * If axis is on the zero position of the other axis\r
23227                  * @type {boolean}\r
23228                  */\r
23229                 onZero: false,\r
23230 \r
23231                 /**\r
23232                  * Axis model\r
23233                  * @param {module:echarts/coord/cartesian/AxisModel}\r
23234                  */\r
23235                 model: null,\r
23236 \r
23237                 isHorizontal: function () {\r
23238                     var position = this.position;\r
23239                     return position === 'top' || position === 'bottom';\r
23240                 },\r
23241 \r
23242                 getGlobalExtent: function () {\r
23243                     var ret = this.getExtent();\r
23244                     ret[0] = this.toGlobalCoord(ret[0]);\r
23245                     ret[1] = this.toGlobalCoord(ret[1]);\r
23246                     return ret;\r
23247                 },\r
23248 \r
23249                 /**\r
23250                  * @return {number}\r
23251                  */\r
23252                 getLabelInterval: function () {\r
23253                     var labelInterval = this._labelInterval;\r
23254                     if (!labelInterval) {\r
23255                         labelInterval = this._labelInterval = axisLabelInterval(this);\r
23256                     }\r
23257                     return labelInterval;\r
23258                 },\r
23259 \r
23260                 /**\r
23261                  * If label is ignored.\r
23262                  * Automatically used when axis is category and label can not be all shown\r
23263                  * @param  {number}  idx\r
23264                  * @return {boolean}\r
23265                  */\r
23266                 isLabelIgnored: function (idx) {\r
23267                     if (this.type === 'category') {\r
23268                         var labelInterval = this.getLabelInterval();\r
23269                         return ((typeof labelInterval === 'function')\r
23270                             && !labelInterval(idx, this.scale.getLabel(idx)))\r
23271                             || idx % (labelInterval + 1);\r
23272                     }\r
23273                 },\r
23274 \r
23275                 /**\r
23276                  * Transform global coord to local coord,\r
23277                  * i.e. var localCoord = axis.toLocalCoord(80);\r
23278                  * designate by module:echarts/coord/cartesian/Grid.\r
23279                  * @type {Function}\r
23280                  */\r
23281                 toLocalCoord: null,\r
23282 \r
23283                 /**\r
23284                  * Transform global coord to local coord,\r
23285                  * i.e. var globalCoord = axis.toLocalCoord(40);\r
23286                  * designate by module:echarts/coord/cartesian/Grid.\r
23287                  * @type {Function}\r
23288                  */\r
23289                 toGlobalCoord: null\r
23290 \r
23291             };\r
23292             zrUtil.inherits(Axis2D, Axis);\r
23293 \r
23294             module.exports = Axis2D;\r
23295 \r
23296 \r
23297 /***/ },\r
23298 /* 117 */\r
23299 /***/ function(module, exports, __webpack_require__) {\r
23300 \r
23301         \r
23302 \r
23303             var numberUtil = __webpack_require__(7);\r
23304             var linearMap = numberUtil.linearMap;\r
23305             var zrUtil = __webpack_require__(3);\r
23306 \r
23307             function fixExtentWithBands(extent, nTick) {\r
23308                 var size = extent[1] - extent[0];\r
23309                 var len = nTick;\r
23310                 var margin = size / len / 2;\r
23311                 extent[0] += margin;\r
23312                 extent[1] -= margin;\r
23313             }\r
23314 \r
23315             var normalizedExtent = [0, 1];\r
23316             /**\r
23317              * @name module:echarts/coord/CartesianAxis\r
23318              * @constructor\r
23319              */\r
23320             var Axis = function (dim, scale, extent) {\r
23321 \r
23322                 /**\r
23323                  * Axis dimension. Such as 'x', 'y', 'z', 'angle', 'radius'\r
23324                  * @type {string}\r
23325                  */\r
23326                 this.dim = dim;\r
23327 \r
23328                 /**\r
23329                  * Axis scale\r
23330                  * @type {module:echarts/coord/scale/*}\r
23331                  */\r
23332                 this.scale = scale;\r
23333 \r
23334                 /**\r
23335                  * @type {Array.<number>}\r
23336                  * @private\r
23337                  */\r
23338                 this._extent = extent || [0, 0];\r
23339 \r
23340                 /**\r
23341                  * @type {boolean}\r
23342                  */\r
23343                 this.inverse = false;\r
23344 \r
23345                 /**\r
23346                  * Usually true when axis has a ordinal scale\r
23347                  * @type {boolean}\r
23348                  */\r
23349                 this.onBand = false;\r
23350             };\r
23351 \r
23352             Axis.prototype = {\r
23353 \r
23354                 constructor: Axis,\r
23355 \r
23356                 /**\r
23357                  * If axis extent contain given coord\r
23358                  * @param {number} coord\r
23359                  * @return {boolean}\r
23360                  */\r
23361                 contain: function (coord) {\r
23362                     var extent = this._extent;\r
23363                     var min = Math.min(extent[0], extent[1]);\r
23364                     var max = Math.max(extent[0], extent[1]);\r
23365                     return coord >= min && coord <= max;\r
23366                 },\r
23367 \r
23368                 /**\r
23369                  * If axis extent contain given data\r
23370                  * @param {number} data\r
23371                  * @return {boolean}\r
23372                  */\r
23373                 containData: function (data) {\r
23374                     return this.contain(this.dataToCoord(data));\r
23375                 },\r
23376 \r
23377                 /**\r
23378                  * Get coord extent.\r
23379                  * @return {Array.<number>}\r
23380                  */\r
23381                 getExtent: function () {\r
23382                     var ret = this._extent.slice();\r
23383                     return ret;\r
23384                 },\r
23385 \r
23386                 /**\r
23387                  * Get precision used for formatting\r
23388                  * @param {Array.<number>} [dataExtent]\r
23389                  * @return {number}\r
23390                  */\r
23391                 getPixelPrecision: function (dataExtent) {\r
23392                     return numberUtil.getPixelPrecision(\r
23393                         dataExtent || this.scale.getExtent(),\r
23394                         this._extent\r
23395                     );\r
23396                 },\r
23397 \r
23398                 /**\r
23399                  * Set coord extent\r
23400                  * @param {number} start\r
23401                  * @param {number} end\r
23402                  */\r
23403                 setExtent: function (start, end) {\r
23404                     var extent = this._extent;\r
23405                     extent[0] = start;\r
23406                     extent[1] = end;\r
23407                 },\r
23408 \r
23409                 /**\r
23410                  * Convert data to coord. Data is the rank if it has a ordinal scale\r
23411                  * @param {number} data\r
23412                  * @param  {boolean} clamp\r
23413                  * @return {number}\r
23414                  */\r
23415                 dataToCoord: function (data, clamp) {\r
23416                     var extent = this._extent;\r
23417                     var scale = this.scale;\r
23418                     data = scale.normalize(data);\r
23419 \r
23420                     if (this.onBand && scale.type === 'ordinal') {\r
23421                         extent = extent.slice();\r
23422                         fixExtentWithBands(extent, scale.count());\r
23423                     }\r
23424 \r
23425                     return linearMap(data, normalizedExtent, extent, clamp);\r
23426                 },\r
23427 \r
23428                 /**\r
23429                  * Convert coord to data. Data is the rank if it has a ordinal scale\r
23430                  * @param {number} coord\r
23431                  * @param  {boolean} clamp\r
23432                  * @return {number}\r
23433                  */\r
23434                 coordToData: function (coord, clamp) {\r
23435                     var extent = this._extent;\r
23436                     var scale = this.scale;\r
23437 \r
23438                     if (this.onBand && scale.type === 'ordinal') {\r
23439                         extent = extent.slice();\r
23440                         fixExtentWithBands(extent, scale.count());\r
23441                     }\r
23442 \r
23443                     var t = linearMap(coord, extent, normalizedExtent, clamp);\r
23444 \r
23445                     return this.scale.scale(t);\r
23446                 },\r
23447                 /**\r
23448                  * @return {Array.<number>}\r
23449                  */\r
23450                 getTicksCoords: function () {\r
23451                     if (this.onBand) {\r
23452                         var bands = this.getBands();\r
23453                         var coords = [];\r
23454                         for (var i = 0; i < bands.length; i++) {\r
23455                             coords.push(bands[i][0]);\r
23456                         }\r
23457                         if (bands[i - 1]) {\r
23458                             coords.push(bands[i - 1][1]);\r
23459                         }\r
23460                         return coords;\r
23461                     }\r
23462                     else {\r
23463                         return zrUtil.map(this.scale.getTicks(), this.dataToCoord, this);\r
23464                     }\r
23465                 },\r
23466 \r
23467                 /**\r
23468                  * Coords of labels are on the ticks or on the middle of bands\r
23469                  * @return {Array.<number>}\r
23470                  */\r
23471                 getLabelsCoords: function () {\r
23472                     if (this.onBand) {\r
23473                         var bands = this.getBands();\r
23474                         var coords = [];\r
23475                         var band;\r
23476                         for (var i = 0; i < bands.length; i++) {\r
23477                             band = bands[i];\r
23478                             coords.push((band[0] + band[1]) / 2);\r
23479                         }\r
23480                         return coords;\r
23481                     }\r
23482                     else {\r
23483                         return zrUtil.map(this.scale.getTicks(), this.dataToCoord, this);\r
23484                     }\r
23485                 },\r
23486 \r
23487                 /**\r
23488                  * Get bands.\r
23489                  *\r
23490                  * If axis has labels [1, 2, 3, 4]. Bands on the axis are\r
23491                  * |---1---|---2---|---3---|---4---|.\r
23492                  *\r
23493                  * @return {Array}\r
23494                  */\r
23495                  // FIXME Situation when labels is on ticks\r
23496                 getBands: function () {\r
23497                     var extent = this.getExtent();\r
23498                     var bands = [];\r
23499                     var len = this.scale.count();\r
23500                     var start = extent[0];\r
23501                     var end = extent[1];\r
23502                     var span = end - start;\r
23503 \r
23504                     for (var i = 0; i < len; i++) {\r
23505                         bands.push([\r
23506                             span * i / len + start,\r
23507                             span * (i + 1) / len + start\r
23508                         ]);\r
23509                     }\r
23510                     return bands;\r
23511                 },\r
23512 \r
23513                 /**\r
23514                  * Get width of band\r
23515                  * @return {number}\r
23516                  */\r
23517                 getBandWidth: function () {\r
23518                     var axisExtent = this._extent;\r
23519                     var dataExtent = this.scale.getExtent();\r
23520 \r
23521                     var len = dataExtent[1] - dataExtent[0] + (this.onBand ? 1 : 0);\r
23522                     // Fix #2728, avoid NaN when only one data.\r
23523                     len === 0 && (len = 1);\r
23524 \r
23525                     var size = Math.abs(axisExtent[1] - axisExtent[0]);\r
23526 \r
23527                     return Math.abs(size) / len;\r
23528                 }\r
23529             };\r
23530 \r
23531             module.exports = Axis;\r
23532 \r
23533 \r
23534 /***/ },\r
23535 /* 118 */\r
23536 /***/ function(module, exports, __webpack_require__) {\r
23537 \r
23538         'use strict';\r
23539         /**\r
23540          * Helper function for axisLabelInterval calculation\r
23541          */\r
23542 \r
23543 \r
23544 \r
23545             var zrUtil = __webpack_require__(3);\r
23546             var axisHelper = __webpack_require__(108);\r
23547 \r
23548             module.exports = function (axis) {\r
23549                 var axisModel = axis.model;\r
23550                 var labelModel = axisModel.getModel('axisLabel');\r
23551                 var labelInterval = labelModel.get('interval');\r
23552                 if (!(axis.type === 'category' && labelInterval === 'auto')) {\r
23553                     return labelInterval === 'auto' ? 0 : labelInterval;\r
23554                 }\r
23555 \r
23556                 return axisHelper.getAxisLabelInterval(\r
23557                     zrUtil.map(axis.scale.getTicks(), axis.dataToCoord, axis),\r
23558                     axisModel.getFormattedLabels(),\r
23559                     labelModel.getModel('textStyle').getFont(),\r
23560                     axis.isHorizontal()\r
23561                 );\r
23562             };\r
23563 \r
23564 \r
23565 /***/ },\r
23566 /* 119 */\r
23567 /***/ function(module, exports, __webpack_require__) {\r
23568 \r
23569         'use strict';\r
23570         // Grid 是在有直角坐标系的时候必须要存在的\r
23571         // 所以这里也要被 Cartesian2D 依赖\r
23572 \r
23573 \r
23574             __webpack_require__(120);\r
23575             var ComponentModel = __webpack_require__(19);\r
23576 \r
23577             module.exports = ComponentModel.extend({\r
23578 \r
23579                 type: 'grid',\r
23580 \r
23581                 dependencies: ['xAxis', 'yAxis'],\r
23582 \r
23583                 layoutMode: 'box',\r
23584 \r
23585                 /**\r
23586                  * @type {module:echarts/coord/cartesian/Grid}\r
23587                  */\r
23588                 coordinateSystem: null,\r
23589 \r
23590                 defaultOption: {\r
23591                     show: false,\r
23592                     zlevel: 0,\r
23593                     z: 0,\r
23594                     left: '10%',\r
23595                     top: 60,\r
23596                     right: '10%',\r
23597                     bottom: 60,\r
23598                     // If grid size contain label\r
23599                     containLabel: false,\r
23600                     // width: {totalWidth} - left - right,\r
23601                     // height: {totalHeight} - top - bottom,\r
23602                     backgroundColor: 'rgba(0,0,0,0)',\r
23603                     borderWidth: 1,\r
23604                     borderColor: '#ccc'\r
23605                 }\r
23606             });\r
23607 \r
23608 \r
23609 /***/ },\r
23610 /* 120 */\r
23611 /***/ function(module, exports, __webpack_require__) {\r
23612 \r
23613         'use strict';\r
23614 \r
23615 \r
23616             var ComponentModel = __webpack_require__(19);\r
23617             var zrUtil = __webpack_require__(3);\r
23618             var axisModelCreator = __webpack_require__(121);\r
23619 \r
23620             var AxisModel = ComponentModel.extend({\r
23621 \r
23622                 type: 'cartesian2dAxis',\r
23623 \r
23624                 /**\r
23625                  * @type {module:echarts/coord/cartesian/Axis2D}\r
23626                  */\r
23627                 axis: null,\r
23628 \r
23629                 /**\r
23630                  * @override\r
23631                  */\r
23632                 init: function () {\r
23633                     AxisModel.superApply(this, 'init', arguments);\r
23634                     this._resetRange();\r
23635                 },\r
23636 \r
23637                 /**\r
23638                  * @override\r
23639                  */\r
23640                 mergeOption: function () {\r
23641                     AxisModel.superApply(this, 'mergeOption', arguments);\r
23642                     this._resetRange();\r
23643                 },\r
23644 \r
23645                 /**\r
23646                  * @override\r
23647                  */\r
23648                 restoreData: function () {\r
23649                     AxisModel.superApply(this, 'restoreData', arguments);\r
23650                     this._resetRange();\r
23651                 },\r
23652 \r
23653                 /**\r
23654                  * @public\r
23655                  * @param {number} rangeStart\r
23656                  * @param {number} rangeEnd\r
23657                  */\r
23658                 setRange: function (rangeStart, rangeEnd) {\r
23659                     this.option.rangeStart = rangeStart;\r
23660                     this.option.rangeEnd = rangeEnd;\r
23661                 },\r
23662 \r
23663                 /**\r
23664                  * @public\r
23665                  * @return {Array.<number|string|Date>}\r
23666                  */\r
23667                 getMin: function () {\r
23668                     var option = this.option;\r
23669                     return option.rangeStart != null ? option.rangeStart : option.min;\r
23670                 },\r
23671 \r
23672                 /**\r
23673                  * @public\r
23674                  * @return {Array.<number|string|Date>}\r
23675                  */\r
23676                 getMax: function () {\r
23677                     var option = this.option;\r
23678                     return option.rangeEnd != null ? option.rangeEnd : option.max;\r
23679                 },\r
23680 \r
23681                 /**\r
23682                  * @public\r
23683                  * @return {boolean}\r
23684                  */\r
23685                 getNeedCrossZero: function () {\r
23686                     var option = this.option;\r
23687                     return (option.rangeStart != null || option.rangeEnd != null)\r
23688                         ? false : !option.scale;\r
23689                 },\r
23690 \r
23691                 /**\r
23692                  * @private\r
23693                  */\r
23694                 _resetRange: function () {\r
23695                     // rangeStart and rangeEnd is readonly.\r
23696                     this.option.rangeStart = this.option.rangeEnd = null;\r
23697                 }\r
23698 \r
23699             });\r
23700 \r
23701             function getAxisType(axisDim, option) {\r
23702                 // Default axis with data is category axis\r
23703                 return option.type || (option.data ? 'category' : 'value');\r
23704             }\r
23705 \r
23706             zrUtil.merge(AxisModel.prototype, __webpack_require__(123));\r
23707 \r
23708             var extraOption = {\r
23709                 gridIndex: 0\r
23710             };\r
23711 \r
23712             axisModelCreator('x', AxisModel, getAxisType, extraOption);\r
23713             axisModelCreator('y', AxisModel, getAxisType, extraOption);\r
23714 \r
23715             module.exports = AxisModel;\r
23716 \r
23717 \r
23718 /***/ },\r
23719 /* 121 */\r
23720 /***/ function(module, exports, __webpack_require__) {\r
23721 \r
23722         \r
23723 \r
23724             var axisDefault = __webpack_require__(122);\r
23725             var zrUtil = __webpack_require__(3);\r
23726             var ComponentModel = __webpack_require__(19);\r
23727             var layout = __webpack_require__(21);\r
23728 \r
23729             // FIXME axisType is fixed ?\r
23730             var AXIS_TYPES = ['value', 'category', 'time', 'log'];\r
23731 \r
23732             /**\r
23733              * Generate sub axis model class\r
23734              * @param {string} axisName 'x' 'y' 'radius' 'angle' 'parallel'\r
23735              * @param {module:echarts/model/Component} BaseAxisModelClass\r
23736              * @param {Function} axisTypeDefaulter\r
23737              * @param {Object} [extraDefaultOption]\r
23738              */\r
23739             module.exports = function (axisName, BaseAxisModelClass, axisTypeDefaulter, extraDefaultOption) {\r
23740 \r
23741                 zrUtil.each(AXIS_TYPES, function (axisType) {\r
23742 \r
23743                     BaseAxisModelClass.extend({\r
23744 \r
23745                         type: axisName + 'Axis.' + axisType,\r
23746 \r
23747                         mergeDefaultAndTheme: function (option, ecModel) {\r
23748                             var layoutMode = this.layoutMode;\r
23749                             var inputPositionParams = layoutMode\r
23750                                 ? layout.getLayoutParams(option) : {};\r
23751 \r
23752                             var themeModel = ecModel.getTheme();\r
23753                             zrUtil.merge(option, themeModel.get(axisType + 'Axis'));\r
23754                             zrUtil.merge(option, this.getDefaultOption());\r
23755 \r
23756                             option.type = axisTypeDefaulter(axisName, option);\r
23757 \r
23758                             if (layoutMode) {\r
23759                                 layout.mergeLayoutParam(option, inputPositionParams, layoutMode);\r
23760                             }\r
23761                         },\r
23762 \r
23763                         defaultOption: zrUtil.mergeAll(\r
23764                             [\r
23765                                 {},\r
23766                                 axisDefault[axisType + 'Axis'],\r
23767                                 extraDefaultOption\r
23768                             ],\r
23769                             true\r
23770                         )\r
23771                     });\r
23772                 });\r
23773 \r
23774                 ComponentModel.registerSubTypeDefaulter(\r
23775                     axisName + 'Axis',\r
23776                     zrUtil.curry(axisTypeDefaulter, axisName)\r
23777                 );\r
23778             };\r
23779 \r
23780 \r
23781 /***/ },\r
23782 /* 122 */\r
23783 /***/ function(module, exports, __webpack_require__) {\r
23784 \r
23785         \r
23786 \r
23787             var zrUtil = __webpack_require__(3);\r
23788 \r
23789             var defaultOption = {\r
23790                 show: true,\r
23791                 zlevel: 0,                  // 一级层叠\r
23792                 z: 0,                       // 二级层叠\r
23793                 // 反向坐标轴\r
23794                 inverse: false,\r
23795                 // 坐标轴名字,默认为空\r
23796                 name: '',\r
23797                 // 坐标轴名字位置,支持'start' | 'middle' | 'end'\r
23798                 nameLocation: 'end',\r
23799                 // 坐标轴文字样式,默认取全局样式\r
23800                 nameTextStyle: {},\r
23801                 // 文字与轴线距离\r
23802                 nameGap: 15,\r
23803                 // 坐标轴线\r
23804                 axisLine: {\r
23805                     // 默认显示,属性show控制显示与否\r
23806                     show: true,\r
23807                     onZero: true,\r
23808                     // 属性lineStyle控制线条样式\r
23809                     lineStyle: {\r
23810                         color: '#333',\r
23811                         width: 1,\r
23812                         type: 'solid'\r
23813                     }\r
23814                 },\r
23815                 // 坐标轴小标记\r
23816                 axisTick: {\r
23817                     // 属性show控制显示与否,默认显示\r
23818                     show: true,\r
23819                     // 控制小标记是否在grid里\r
23820                     inside: false,\r
23821                     // 属性length控制线长\r
23822                     length: 5,\r
23823                     // 属性lineStyle控制线条样式\r
23824                     lineStyle: {\r
23825                         color: '#333',\r
23826                         width: 1\r
23827                     }\r
23828                 },\r
23829                 // 坐标轴文本标签,详见axis.axisLabel\r
23830                 axisLabel: {\r
23831                     show: true,\r
23832                     // 控制文本标签是否在grid里\r
23833                     inside: false,\r
23834                     rotate: 0,\r
23835                     margin: 8,\r
23836                     // formatter: null,\r
23837                     // 其余属性默认使用全局文本样式,详见TEXTSTYLE\r
23838                     textStyle: {\r
23839                         color: '#333',\r
23840                         fontSize: 12\r
23841                     }\r
23842                 },\r
23843                 // 分隔线\r
23844                 splitLine: {\r
23845                     // 默认显示,属性show控制显示与否\r
23846                     show: true,\r
23847                     // 属性lineStyle(详见lineStyle)控制线条样式\r
23848                     lineStyle: {\r
23849                         color: ['#ccc'],\r
23850                         width: 1,\r
23851                         type: 'solid'\r
23852                     }\r
23853                 },\r
23854                 // 分隔区域\r
23855                 splitArea: {\r
23856                     // 默认不显示,属性show控制显示与否\r
23857                     show: false,\r
23858                     // 属性areaStyle(详见areaStyle)控制区域样式\r
23859                     areaStyle: {\r
23860                         color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)']\r
23861                     }\r
23862                 }\r
23863             };\r
23864 \r
23865             var categoryAxis = zrUtil.merge({\r
23866                 // 类目起始和结束两端空白策略\r
23867                 boundaryGap: true,\r
23868                 // 坐标轴小标记\r
23869                 axisTick: {\r
23870                     interval: 'auto'\r
23871                 },\r
23872                 // 坐标轴文本标签,详见axis.axisLabel\r
23873                 axisLabel: {\r
23874                     interval: 'auto'\r
23875                 }\r
23876             }, defaultOption);\r
23877 \r
23878             var valueAxis = zrUtil.defaults({\r
23879                 // 数值起始和结束两端空白策略\r
23880                 boundaryGap: [0, 0],\r
23881                 // 最小值, 设置成 'dataMin' 则从数据中计算最小值\r
23882                 // min: null,\r
23883                 // 最大值,设置成 'dataMax' 则从数据中计算最大值\r
23884                 // max: null,\r
23885                 // Readonly prop, specifies start value of the range when using data zoom.\r
23886                 // rangeStart: null\r
23887                 // Readonly prop, specifies end value of the range when using data zoom.\r
23888                 // rangeEnd: null\r
23889                 // 脱离0值比例,放大聚焦到最终_min,_max区间\r
23890                 // scale: false,\r
23891                 // 分割段数,默认为5\r
23892                 splitNumber: 5\r
23893             }, defaultOption);\r
23894 \r
23895             // FIXME\r
23896             var timeAxis = zrUtil.defaults({\r
23897                 scale: true,\r
23898                 min: 'dataMin',\r
23899                 max: 'dataMax'\r
23900             }, valueAxis);\r
23901             var logAxis = zrUtil.defaults({}, valueAxis);\r
23902             logAxis.scale = true;\r
23903 \r
23904             module.exports = {\r
23905                 categoryAxis: categoryAxis,\r
23906                 valueAxis: valueAxis,\r
23907                 timeAxis: timeAxis,\r
23908                 logAxis: logAxis\r
23909             };\r
23910 \r
23911 \r
23912 /***/ },\r
23913 /* 123 */\r
23914 /***/ function(module, exports, __webpack_require__) {\r
23915 \r
23916         \r
23917 \r
23918             var zrUtil = __webpack_require__(3);\r
23919             var axisHelper = __webpack_require__(108);\r
23920 \r
23921             function getName(obj) {\r
23922                 if (zrUtil.isObject(obj) && obj.value != null) {\r
23923                     return obj.value;\r
23924                 }\r
23925                 else {\r
23926                     return obj;\r
23927                 }\r
23928             }\r
23929             /**\r
23930              * Get categories\r
23931              */\r
23932             function getCategories() {\r
23933                 return this.get('type') === 'category'\r
23934                     && zrUtil.map(this.get('data'), getName);\r
23935             }\r
23936 \r
23937             /**\r
23938              * Format labels\r
23939              * @return {Array.<string>}\r
23940              */\r
23941             function getFormattedLabels() {\r
23942                 return axisHelper.getFormattedLabels(\r
23943                     this.axis,\r
23944                     this.get('axisLabel.formatter')\r
23945                 );\r
23946             }\r
23947 \r
23948             module.exports = {\r
23949 \r
23950                 getFormattedLabels: getFormattedLabels,\r
23951 \r
23952                 getCategories: getCategories\r
23953             };\r
23954 \r
23955 \r
23956 /***/ },\r
23957 /* 124 */\r
23958 /***/ function(module, exports, __webpack_require__) {\r
23959 \r
23960         'use strict';\r
23961         // TODO boundaryGap\r
23962 \r
23963 \r
23964             __webpack_require__(120);\r
23965 \r
23966             __webpack_require__(125);\r
23967 \r
23968 \r
23969 /***/ },\r
23970 /* 125 */\r
23971 /***/ function(module, exports, __webpack_require__) {\r
23972 \r
23973         \r
23974 \r
23975             var zrUtil = __webpack_require__(3);\r
23976             var graphic = __webpack_require__(42);\r
23977             var AxisBuilder = __webpack_require__(126);\r
23978             var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick;\r
23979             var getInterval = AxisBuilder.getInterval;\r
23980 \r
23981             var axisBuilderAttrs = [\r
23982                 'axisLine', 'axisLabel', 'axisTick', 'axisName'\r
23983             ];\r
23984             var selfBuilderAttrs = [\r
23985                 'splitLine', 'splitArea'\r
23986             ];\r
23987 \r
23988             var AxisView = __webpack_require__(1).extendComponentView({\r
23989 \r
23990                 type: 'axis',\r
23991 \r
23992                 render: function (axisModel, ecModel) {\r
23993 \r
23994                     this.group.removeAll();\r
23995 \r
23996                     if (!axisModel.get('show')) {\r
23997                         return;\r
23998                     }\r
23999 \r
24000                     var gridModel = ecModel.getComponent('grid', axisModel.get('gridIndex'));\r
24001 \r
24002                     var layout = layoutAxis(gridModel, axisModel);\r
24003 \r
24004                     var axisBuilder = new AxisBuilder(axisModel, layout);\r
24005 \r
24006                     zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);\r
24007 \r
24008                     this.group.add(axisBuilder.getGroup());\r
24009 \r
24010                     zrUtil.each(selfBuilderAttrs, function (name) {\r
24011                         if (axisModel.get(name +'.show')) {\r
24012                             this['_' + name](axisModel, gridModel, layout.labelInterval);\r
24013                         }\r
24014                     }, this);\r
24015                 },\r
24016 \r
24017                 /**\r
24018                  * @param {module:echarts/coord/cartesian/AxisModel} axisModel\r
24019                  * @param {module:echarts/coord/cartesian/GridModel} gridModel\r
24020                  * @param {number|Function} labelInterval\r
24021                  * @private\r
24022                  */\r
24023                 _splitLine: function (axisModel, gridModel, labelInterval) {\r
24024                     var axis = axisModel.axis;\r
24025 \r
24026                     var splitLineModel = axisModel.getModel('splitLine');\r
24027                     var lineStyleModel = splitLineModel.getModel('lineStyle');\r
24028                     var lineWidth = lineStyleModel.get('width');\r
24029                     var lineColors = lineStyleModel.get('color');\r
24030 \r
24031                     var lineInterval = getInterval(splitLineModel, labelInterval);\r
24032 \r
24033                     lineColors = zrUtil.isArray(lineColors) ? lineColors : [lineColors];\r
24034 \r
24035                     var gridRect = gridModel.coordinateSystem.getRect();\r
24036                     var isHorizontal = axis.isHorizontal();\r
24037 \r
24038                     var splitLines = [];\r
24039                     var lineCount = 0;\r
24040 \r
24041                     var ticksCoords = axis.getTicksCoords();\r
24042 \r
24043                     var p1 = [];\r
24044                     var p2 = [];\r
24045                     for (var i = 0; i < ticksCoords.length; i++) {\r
24046                         if (ifIgnoreOnTick(axis, i, lineInterval)) {\r
24047                             continue;\r
24048                         }\r
24049 \r
24050                         var tickCoord = axis.toGlobalCoord(ticksCoords[i]);\r
24051 \r
24052                         if (isHorizontal) {\r
24053                             p1[0] = tickCoord;\r
24054                             p1[1] = gridRect.y;\r
24055                             p2[0] = tickCoord;\r
24056                             p2[1] = gridRect.y + gridRect.height;\r
24057                         }\r
24058                         else {\r
24059                             p1[0] = gridRect.x;\r
24060                             p1[1] = tickCoord;\r
24061                             p2[0] = gridRect.x + gridRect.width;\r
24062                             p2[1] = tickCoord;\r
24063                         }\r
24064 \r
24065                         var colorIndex = (lineCount++) % lineColors.length;\r
24066                         splitLines[colorIndex] = splitLines[colorIndex] || [];\r
24067                         splitLines[colorIndex].push(new graphic.Line(graphic.subPixelOptimizeLine({\r
24068                             shape: {\r
24069                                 x1: p1[0],\r
24070                                 y1: p1[1],\r
24071                                 x2: p2[0],\r
24072                                 y2: p2[1]\r
24073                             },\r
24074                             style: {\r
24075                                 lineWidth: lineWidth\r
24076                             },\r
24077                             silent: true\r
24078                         })));\r
24079                     }\r
24080 \r
24081                     // Simple optimization\r
24082                     // Batching the lines if color are the same\r
24083                     var lineStyle = lineStyleModel.getLineStyle();\r
24084                     for (var i = 0; i < splitLines.length; i++) {\r
24085                         this.group.add(graphic.mergePath(splitLines[i], {\r
24086                             style: zrUtil.defaults({\r
24087                                 stroke: lineColors[i % lineColors.length]\r
24088                             }, lineStyle),\r
24089                             silent: true\r
24090                         }));\r
24091                     }\r
24092                 },\r
24093 \r
24094                 /**\r
24095                  * @param {module:echarts/coord/cartesian/AxisModel} axisModel\r
24096                  * @param {module:echarts/coord/cartesian/GridModel} gridModel\r
24097                  * @param {number|Function} labelInterval\r
24098                  * @private\r
24099                  */\r
24100                 _splitArea: function (axisModel, gridModel, labelInterval) {\r
24101                     var axis = axisModel.axis;\r
24102 \r
24103                     var splitAreaModel = axisModel.getModel('splitArea');\r
24104                     var areaStyleModel = splitAreaModel.getModel('areaStyle');\r
24105                     var areaColors = areaStyleModel.get('color');\r
24106 \r
24107                     var gridRect = gridModel.coordinateSystem.getRect();\r
24108                     var ticksCoords = axis.getTicksCoords();\r
24109 \r
24110                     var prevX = axis.toGlobalCoord(ticksCoords[0]);\r
24111                     var prevY = axis.toGlobalCoord(ticksCoords[0]);\r
24112 \r
24113                     var splitAreaRects = [];\r
24114                     var count = 0;\r
24115 \r
24116                     var areaInterval = getInterval(splitAreaModel, labelInterval);\r
24117 \r
24118                     areaColors = zrUtil.isArray(areaColors) ? areaColors : [areaColors];\r
24119 \r
24120                     for (var i = 1; i < ticksCoords.length; i++) {\r
24121                         if (ifIgnoreOnTick(axis, i, areaInterval)) {\r
24122                             continue;\r
24123                         }\r
24124 \r
24125                         var tickCoord = axis.toGlobalCoord(ticksCoords[i]);\r
24126 \r
24127                         var x;\r
24128                         var y;\r
24129                         var width;\r
24130                         var height;\r
24131                         if (axis.isHorizontal()) {\r
24132                             x = prevX;\r
24133                             y = gridRect.y;\r
24134                             width = tickCoord - x;\r
24135                             height = gridRect.height;\r
24136                         }\r
24137                         else {\r
24138                             x = gridRect.x;\r
24139                             y = prevY;\r
24140                             width = gridRect.width;\r
24141                             height = tickCoord - y;\r
24142                         }\r
24143 \r
24144                         var colorIndex = (count++) % areaColors.length;\r
24145                         splitAreaRects[colorIndex] = splitAreaRects[colorIndex] || [];\r
24146                         splitAreaRects[colorIndex].push(new graphic.Rect({\r
24147                             shape: {\r
24148                                 x: x,\r
24149                                 y: y,\r
24150                                 width: width,\r
24151                                 height: height\r
24152                             },\r
24153                             silent: true\r
24154                         }));\r
24155 \r
24156                         prevX = x + width;\r
24157                         prevY = y + height;\r
24158                     }\r
24159 \r
24160                     // Simple optimization\r
24161                     // Batching the rects if color are the same\r
24162                     var areaStyle = areaStyleModel.getAreaStyle();\r
24163                     for (var i = 0; i < splitAreaRects.length; i++) {\r
24164                         this.group.add(graphic.mergePath(splitAreaRects[i], {\r
24165                             style: zrUtil.defaults({\r
24166                                 fill: areaColors[i % areaColors.length]\r
24167                             }, areaStyle),\r
24168                             silent: true\r
24169                         }));\r
24170                     }\r
24171                 }\r
24172             });\r
24173 \r
24174             AxisView.extend({\r
24175                 type: 'xAxis'\r
24176             });\r
24177             AxisView.extend({\r
24178                 type: 'yAxis'\r
24179             });\r
24180 \r
24181             /**\r
24182              * @inner\r
24183              */\r
24184             function layoutAxis(gridModel, axisModel) {\r
24185                 var grid = gridModel.coordinateSystem;\r
24186                 var axis = axisModel.axis;\r
24187                 var layout = {};\r
24188 \r
24189                 var rawAxisPosition = axis.position;\r
24190                 var axisPosition = axis.onZero ? 'onZero' : rawAxisPosition;\r
24191                 var axisDim = axis.dim;\r
24192 \r
24193                 // [left, right, top, bottom]\r
24194                 var rect = grid.getRect();\r
24195                 var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height];\r
24196 \r
24197                 var posMap = {\r
24198                     x: {top: rectBound[2], bottom: rectBound[3]},\r
24199                     y: {left: rectBound[0], right: rectBound[1]}\r
24200                 };\r
24201                 posMap.x.onZero = Math.max(Math.min(getZero('y'), posMap.x.bottom), posMap.x.top);\r
24202                 posMap.y.onZero = Math.max(Math.min(getZero('x'), posMap.y.right), posMap.y.left);\r
24203 \r
24204                 function getZero(dim, val) {\r
24205                     var theAxis = grid.getAxis(dim);\r
24206                     return theAxis.toGlobalCoord(theAxis.dataToCoord(0));\r
24207                 }\r
24208 \r
24209                 // Axis position\r
24210                 layout.position = [\r
24211                     axisDim === 'y' ? posMap.y[axisPosition] : rectBound[0],\r
24212                     axisDim === 'x' ? posMap.x[axisPosition] : rectBound[3]\r
24213                 ];\r
24214 \r
24215                 // Axis rotation\r
24216                 var r = {x: 0, y: 1};\r
24217                 layout.rotation = Math.PI / 2 * r[axisDim];\r
24218 \r
24219                 // Tick and label direction, x y is axisDim\r
24220                 var dirMap = {top: -1, bottom: 1, left: -1, right: 1};\r
24221 \r
24222                 layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition];\r
24223                 if (axis.onZero) {\r
24224                     layout.labelOffset = posMap[axisDim][rawAxisPosition] - posMap[axisDim].onZero;\r
24225                 }\r
24226 \r
24227                 if (axisModel.getModel('axisTick').get('inside')) {\r
24228                     layout.tickDirection = -layout.tickDirection;\r
24229                 }\r
24230                 if (axisModel.getModel('axisLabel').get('inside')) {\r
24231                     layout.labelDirection = -layout.labelDirection;\r
24232                 }\r
24233 \r
24234                 // Special label rotation\r
24235                 var labelRotation = axisModel.getModel('axisLabel').get('rotate');\r
24236                 layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation;\r
24237 \r
24238                 // label interval when auto mode.\r
24239                 layout.labelInterval = axis.getLabelInterval();\r
24240 \r
24241                 // Over splitLine and splitArea\r
24242                 layout.z2 = 1;\r
24243 \r
24244                 return layout;\r
24245             }\r
24246 \r
24247 \r
24248 /***/ },\r
24249 /* 126 */\r
24250 /***/ function(module, exports, __webpack_require__) {\r
24251 \r
24252         \r
24253 \r
24254             var zrUtil = __webpack_require__(3);\r
24255             var graphic = __webpack_require__(42);\r
24256             var Model = __webpack_require__(8);\r
24257             var numberUtil = __webpack_require__(7);\r
24258             var remRadian = numberUtil.remRadian;\r
24259             var isRadianAroundZero = numberUtil.isRadianAroundZero;\r
24260 \r
24261             var PI = Math.PI;\r
24262 \r
24263             /**\r
24264              * A final axis is translated and rotated from a "standard axis".\r
24265              * So opt.position and opt.rotation is required.\r
24266              *\r
24267              * A standard axis is and axis from [0, 0] to [0, axisExtent[1]],\r
24268              * for example: (0, 0) ------------> (0, 50)\r
24269              *\r
24270              * nameDirection or tickDirection or labelDirection is 1 means tick\r
24271              * or label is below the standard axis, whereas is -1 means above\r
24272              * the standard axis. labelOffset means offset between label and axis,\r
24273              * which is useful when 'onZero', where axisLabel is in the grid and\r
24274              * label in outside grid.\r
24275              *\r
24276              * Tips: like always,\r
24277              * positive rotation represents anticlockwise, and negative rotation\r
24278              * represents clockwise.\r
24279              * The direction of position coordinate is the same as the direction\r
24280              * of screen coordinate.\r
24281              *\r
24282              * Do not need to consider axis 'inverse', which is auto processed by\r
24283              * axis extent.\r
24284              *\r
24285              * @param {module:zrender/container/Group} group\r
24286              * @param {Object} axisModel\r
24287              * @param {Object} opt Standard axis parameters.\r
24288              * @param {Array.<number>} opt.position [x, y]\r
24289              * @param {number} opt.rotation by radian\r
24290              * @param {number} [opt.nameDirection=1] 1 or -1 Used when nameLocation is 'middle'.\r
24291              * @param {number} [opt.tickDirection=1] 1 or -1\r
24292              * @param {number} [opt.labelDirection=1] 1 or -1\r
24293              * @param {number} [opt.labelOffset=0] Usefull when onZero.\r
24294              * @param {string} [opt.axisName] default get from axisModel.\r
24295              * @param {number} [opt.labelRotation] by degree, default get from axisModel.\r
24296              * @param {number} [opt.labelInterval] Default label interval when label\r
24297              *                                     interval from model is null or 'auto'.\r
24298              * @param {number} [opt.strokeContainThreshold] Default label interval when label\r
24299              * @param {number} [opt.silent=true]\r
24300              */\r
24301             var AxisBuilder = function (axisModel, opt) {\r
24302 \r
24303                 /**\r
24304                  * @readOnly\r
24305                  */\r
24306                 this.opt = opt;\r
24307 \r
24308                 /**\r
24309                  * @readOnly\r
24310                  */\r
24311                 this.axisModel = axisModel;\r
24312 \r
24313                 // Default value\r
24314                 zrUtil.defaults(\r
24315                     opt,\r
24316                     {\r
24317                         labelOffset: 0,\r
24318                         nameDirection: 1,\r
24319                         tickDirection: 1,\r
24320                         labelDirection: 1,\r
24321                         silent: true\r
24322                     }\r
24323                 );\r
24324 \r
24325                 /**\r
24326                  * @readOnly\r
24327                  */\r
24328                 this.group = new graphic.Group({\r
24329                     position: opt.position.slice(),\r
24330                     rotation: opt.rotation\r
24331                 });\r
24332             };\r
24333 \r
24334             AxisBuilder.prototype = {\r
24335 \r
24336                 constructor: AxisBuilder,\r
24337 \r
24338                 hasBuilder: function (name) {\r
24339                     return !!builders[name];\r
24340                 },\r
24341 \r
24342                 add: function (name) {\r
24343                     builders[name].call(this);\r
24344                 },\r
24345 \r
24346                 getGroup: function () {\r
24347                     return this.group;\r
24348                 }\r
24349 \r
24350             };\r
24351 \r
24352             var builders = {\r
24353 \r
24354                 /**\r
24355                  * @private\r
24356                  */\r
24357                 axisLine: function () {\r
24358                     var opt = this.opt;\r
24359                     var axisModel = this.axisModel;\r
24360 \r
24361                     if (!axisModel.get('axisLine.show')) {\r
24362                         return;\r
24363                     }\r
24364 \r
24365                     var extent = this.axisModel.axis.getExtent();\r
24366 \r
24367                     this.group.add(new graphic.Line({\r
24368                         shape: {\r
24369                             x1: extent[0],\r
24370                             y1: 0,\r
24371                             x2: extent[1],\r
24372                             y2: 0\r
24373                         },\r
24374                         style: zrUtil.extend(\r
24375                             {lineCap: 'round'},\r
24376                             axisModel.getModel('axisLine.lineStyle').getLineStyle()\r
24377                         ),\r
24378                         strokeContainThreshold: opt.strokeContainThreshold,\r
24379                         silent: !!opt.silent,\r
24380                         z2: 1\r
24381                     }));\r
24382                 },\r
24383 \r
24384                 /**\r
24385                  * @private\r
24386                  */\r
24387                 axisTick: function () {\r
24388                     var axisModel = this.axisModel;\r
24389 \r
24390                     if (!axisModel.get('axisTick.show')) {\r
24391                         return;\r
24392                     }\r
24393 \r
24394                     var axis = axisModel.axis;\r
24395                     var tickModel = axisModel.getModel('axisTick');\r
24396                     var opt = this.opt;\r
24397 \r
24398                     var lineStyleModel = tickModel.getModel('lineStyle');\r
24399                     var tickLen = tickModel.get('length');\r
24400                     var tickInterval = getInterval(tickModel, opt.labelInterval);\r
24401                     var ticksCoords = axis.getTicksCoords();\r
24402                     var tickLines = [];\r
24403 \r
24404                     for (var i = 0; i < ticksCoords.length; i++) {\r
24405                         // Only ordinal scale support tick interval\r
24406                         if (ifIgnoreOnTick(axis, i, tickInterval)) {\r
24407                              continue;\r
24408                         }\r
24409 \r
24410                         var tickCoord = ticksCoords[i];\r
24411 \r
24412                         // Tick line\r
24413                         tickLines.push(new graphic.Line(graphic.subPixelOptimizeLine({\r
24414                             shape: {\r
24415                                 x1: tickCoord,\r
24416                                 y1: 0,\r
24417                                 x2: tickCoord,\r
24418                                 y2: opt.tickDirection * tickLen\r
24419                             },\r
24420                             style: {\r
24421                                 lineWidth: lineStyleModel.get('width')\r
24422                             },\r
24423                             silent: true\r
24424                         })));\r
24425                     }\r
24426 \r
24427                     this.group.add(graphic.mergePath(tickLines, {\r
24428                         style: lineStyleModel.getLineStyle(),\r
24429                         z2: 2,\r
24430                         silent: true\r
24431                     }));\r
24432                 },\r
24433 \r
24434                 /**\r
24435                  * @param {module:echarts/coord/cartesian/AxisModel} axisModel\r
24436                  * @param {module:echarts/coord/cartesian/GridModel} gridModel\r
24437                  * @private\r
24438                  */\r
24439                 axisLabel: function () {\r
24440                     var axisModel = this.axisModel;\r
24441 \r
24442                     if (!axisModel.get('axisLabel.show')) {\r
24443                         return;\r
24444                     }\r
24445 \r
24446                     var opt = this.opt;\r
24447                     var axis = axisModel.axis;\r
24448                     var labelModel = axisModel.getModel('axisLabel');\r
24449                     var textStyleModel = labelModel.getModel('textStyle');\r
24450                     var labelMargin = labelModel.get('margin');\r
24451                     var ticks = axis.scale.getTicks();\r
24452                     var labels = axisModel.getFormattedLabels();\r
24453 \r
24454                     // Special label rotate.\r
24455                     var labelRotation = opt.labelRotation;\r
24456                     if (labelRotation == null) {\r
24457                         labelRotation = labelModel.get('rotate') || 0;\r
24458                     }\r
24459                     // To radian.\r
24460                     labelRotation = labelRotation * PI / 180;\r
24461 \r
24462                     var labelLayout = innerTextLayout(opt, labelRotation, opt.labelDirection);\r
24463                     var categoryData = axisModel.get('data');\r
24464 \r
24465                     var textEls = [];\r
24466                     for (var i = 0; i < ticks.length; i++) {\r
24467                         if (ifIgnoreOnTick(axis, i, opt.labelInterval)) {\r
24468                              continue;\r
24469                         }\r
24470 \r
24471                         var itemTextStyleModel = textStyleModel;\r
24472                         if (categoryData && categoryData[i] && categoryData[i].textStyle) {\r
24473                             itemTextStyleModel = new Model(\r
24474                                 categoryData[i].textStyle, textStyleModel, axisModel.ecModel\r
24475                             );\r
24476                         }\r
24477 \r
24478                         var tickCoord = axis.dataToCoord(ticks[i]);\r
24479                         var pos = [\r
24480                             tickCoord,\r
24481                             opt.labelOffset + opt.labelDirection * labelMargin\r
24482                         ];\r
24483 \r
24484                         var textEl = new graphic.Text({\r
24485                             style: {\r
24486                                 text: labels[i],\r
24487                                 textAlign: itemTextStyleModel.get('align', true) || labelLayout.textAlign,\r
24488                                 textVerticalAlign: itemTextStyleModel.get('baseline', true) || labelLayout.verticalAlign,\r
24489                                 textFont: itemTextStyleModel.getFont(),\r
24490                                 fill: itemTextStyleModel.getTextColor()\r
24491                             },\r
24492                             position: pos,\r
24493                             rotation: labelLayout.rotation,\r
24494                             silent: true,\r
24495                             z2: 10\r
24496                         });\r
24497                         textEls.push(textEl);\r
24498                         this.group.add(textEl);\r
24499                     }\r
24500 \r
24501                     function isTwoLabelOverlapped(current, next) {\r
24502                         var firstRect = current && current.getBoundingRect().clone();\r
24503                         var nextRect = next && next.getBoundingRect().clone();\r
24504                         if (firstRect && nextRect) {\r
24505                             firstRect.applyTransform(current.getLocalTransform());\r
24506                             nextRect.applyTransform(next.getLocalTransform());\r
24507                             return firstRect.intersect(nextRect);\r
24508                         }\r
24509                     }\r
24510                     if (axis.type !== 'category') {\r
24511                         // If min or max are user set, we need to check\r
24512                         // If the tick on min(max) are overlap on their neighbour tick\r
24513                         // If they are overlapped, we need to hide the min(max) tick label\r
24514                         if (axisModel.getMin ? axisModel.getMin() : axisModel.get('min')) {\r
24515                             var firstLabel = textEls[0];\r
24516                             var nextLabel = textEls[1];\r
24517                             if (isTwoLabelOverlapped(firstLabel, nextLabel)) {\r
24518                                 firstLabel.ignore = true;\r
24519                             }\r
24520                         }\r
24521                         if (axisModel.getMax ? axisModel.getMax() : axisModel.get('max')) {\r
24522                             var lastLabel = textEls[textEls.length - 1];\r
24523                             var prevLabel = textEls[textEls.length - 2];\r
24524                             if (isTwoLabelOverlapped(prevLabel, lastLabel)) {\r
24525                                 lastLabel.ignore = true;\r
24526                             }\r
24527                         }\r
24528                     }\r
24529                 },\r
24530 \r
24531                 /**\r
24532                  * @private\r
24533                  */\r
24534                 axisName: function () {\r
24535                     var opt = this.opt;\r
24536                     var axisModel = this.axisModel;\r
24537 \r
24538                     var name = this.opt.axisName;\r
24539                     // If name is '', do not get name from axisMode.\r
24540                     if (name == null) {\r
24541                         name = axisModel.get('name');\r
24542                     }\r
24543 \r
24544                     if (!name) {\r
24545                         return;\r
24546                     }\r
24547 \r
24548                     var nameLocation = axisModel.get('nameLocation');\r
24549                     var nameDirection = opt.nameDirection;\r
24550                     var textStyleModel = axisModel.getModel('nameTextStyle');\r
24551                     var gap = axisModel.get('nameGap') || 0;\r
24552 \r
24553                     var extent = this.axisModel.axis.getExtent();\r
24554                     var gapSignal = extent[0] > extent[1] ? -1 : 1;\r
24555                     var pos = [\r
24556                         nameLocation === 'start'\r
24557                             ? extent[0] - gapSignal * gap\r
24558                             : nameLocation === 'end'\r
24559                             ? extent[1] + gapSignal * gap\r
24560                             : (extent[0] + extent[1]) / 2, // 'middle'\r
24561                         // Reuse labelOffset.\r
24562                         nameLocation === 'middle' ? opt.labelOffset + nameDirection * gap : 0\r
24563                     ];\r
24564 \r
24565                     var labelLayout;\r
24566 \r
24567                     if (nameLocation === 'middle') {\r
24568                         labelLayout = innerTextLayout(opt, opt.rotation, nameDirection);\r
24569                     }\r
24570                     else {\r
24571                         labelLayout = endTextLayout(opt, nameLocation, extent);\r
24572                     }\r
24573 \r
24574                     this.group.add(new graphic.Text({\r
24575                         style: {\r
24576                             text: name,\r
24577                             textFont: textStyleModel.getFont(),\r
24578                             fill: textStyleModel.getTextColor()\r
24579                                 || axisModel.get('axisLine.lineStyle.color'),\r
24580                             textAlign: labelLayout.textAlign,\r
24581                             textVerticalAlign: labelLayout.verticalAlign\r
24582                         },\r
24583                         position: pos,\r
24584                         rotation: labelLayout.rotation,\r
24585                         silent: true,\r
24586                         z2: 1\r
24587                     }));\r
24588                 }\r
24589 \r
24590             };\r
24591 \r
24592             /**\r
24593              * @inner\r
24594              */\r
24595             function innerTextLayout(opt, textRotation, direction) {\r
24596                 var rotationDiff = remRadian(textRotation - opt.rotation);\r
24597                 var textAlign;\r
24598                 var verticalAlign;\r
24599 \r
24600                 if (isRadianAroundZero(rotationDiff)) { // Label is parallel with axis line.\r
24601                     verticalAlign = direction > 0 ? 'top' : 'bottom';\r
24602                     textAlign = 'center';\r
24603                 }\r
24604                 else if (isRadianAroundZero(rotationDiff - PI)) { // Label is inverse parallel with axis line.\r
24605                     verticalAlign = direction > 0 ? 'bottom' : 'top';\r
24606                     textAlign = 'center';\r
24607                 }\r
24608                 else {\r
24609                     verticalAlign = 'middle';\r
24610 \r
24611                     if (rotationDiff > 0 && rotationDiff < PI) {\r
24612                         textAlign = direction > 0 ? 'right' : 'left';\r
24613                     }\r
24614                     else {\r
24615                         textAlign = direction > 0 ? 'left' : 'right';\r
24616                     }\r
24617                 }\r
24618 \r
24619                 return {\r
24620                     rotation: rotationDiff,\r
24621                     textAlign: textAlign,\r
24622                     verticalAlign: verticalAlign\r
24623                 };\r
24624             }\r
24625 \r
24626             /**\r
24627              * @inner\r
24628              */\r
24629             function endTextLayout(opt, textPosition, extent) {\r
24630                 var rotationDiff = remRadian(-opt.rotation);\r
24631                 var textAlign;\r
24632                 var verticalAlign;\r
24633                 var inverse = extent[0] > extent[1];\r
24634                 var onLeft = (textPosition === 'start' && !inverse)\r
24635                     || (textPosition !== 'start' && inverse);\r
24636 \r
24637                 if (isRadianAroundZero(rotationDiff - PI / 2)) {\r
24638                     verticalAlign = onLeft ? 'bottom' : 'top';\r
24639                     textAlign = 'center';\r
24640                 }\r
24641                 else if (isRadianAroundZero(rotationDiff - PI * 1.5)) {\r
24642                     verticalAlign = onLeft ? 'top' : 'bottom';\r
24643                     textAlign = 'center';\r
24644                 }\r
24645                 else {\r
24646                     verticalAlign = 'middle';\r
24647                     if (rotationDiff < PI * 1.5 && rotationDiff > PI / 2) {\r
24648                         textAlign = onLeft ? 'left' : 'right';\r
24649                     }\r
24650                     else {\r
24651                         textAlign = onLeft ? 'right' : 'left';\r
24652                     }\r
24653                 }\r
24654 \r
24655                 return {\r
24656                     rotation: rotationDiff,\r
24657                     textAlign: textAlign,\r
24658                     verticalAlign: verticalAlign\r
24659                 };\r
24660             }\r
24661 \r
24662             /**\r
24663              * @static\r
24664              */\r
24665             var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick = function (axis, i, interval) {\r
24666                 var rawTick;\r
24667                 var scale = axis.scale;\r
24668                 return scale.type === 'ordinal'\r
24669                     && (\r
24670                         typeof interval === 'function'\r
24671                             ? (\r
24672                                 rawTick = scale.getTicks()[i],\r
24673                                 !interval(rawTick, scale.getLabel(rawTick))\r
24674                             )\r
24675                             : i % (interval + 1)\r
24676                     );\r
24677             };\r
24678 \r
24679             /**\r
24680              * @static\r
24681              */\r
24682             var getInterval = AxisBuilder.getInterval = function (model, labelInterval) {\r
24683                 var interval = model.get('interval');\r
24684                 if (interval == null || interval == 'auto') {\r
24685                     interval = labelInterval;\r
24686                 }\r
24687                 return interval;\r
24688             };\r
24689 \r
24690             module.exports = AxisBuilder;\r
24691 \r
24692 \r
24693 \r
24694 /***/ },\r
24695 /* 127 */\r
24696 /***/ function(module, exports, __webpack_require__) {\r
24697 \r
24698         \r
24699 \r
24700             var zrUtil = __webpack_require__(3);\r
24701 \r
24702             __webpack_require__(107);\r
24703 \r
24704             __webpack_require__(128);\r
24705             __webpack_require__(129);\r
24706 \r
24707             var barLayoutGrid = __webpack_require__(131);\r
24708             var echarts = __webpack_require__(1);\r
24709 \r
24710             echarts.registerLayout(zrUtil.curry(barLayoutGrid, 'bar'));\r
24711             // Visual coding for legend\r
24712             echarts.registerVisualCoding('chart', function (ecModel) {\r
24713                 ecModel.eachSeriesByType('bar', function (seriesModel) {\r
24714                     var data = seriesModel.getData();\r
24715                     data.setVisual('legendSymbol', 'roundRect');\r
24716                 });\r
24717             });\r
24718 \r
24719             // In case developer forget to include grid component\r
24720             __webpack_require__(106);\r
24721 \r
24722 \r
24723 /***/ },\r
24724 /* 128 */\r
24725 /***/ function(module, exports, __webpack_require__) {\r
24726 \r
24727         'use strict';\r
24728 \r
24729 \r
24730             var SeriesModel = __webpack_require__(27);\r
24731             var createListFromArray = __webpack_require__(93);\r
24732 \r
24733             module.exports = SeriesModel.extend({\r
24734 \r
24735                 type: 'series.bar',\r
24736 \r
24737                 dependencies: ['grid', 'polar'],\r
24738 \r
24739                 getInitialData: function (option, ecModel) {\r
24740                     return createListFromArray(option.data, this, ecModel);\r
24741                 },\r
24742 \r
24743                 getMarkerPosition: function (value) {\r
24744                     var coordSys = this.coordinateSystem;\r
24745                     if (coordSys) {\r
24746                         var pt = coordSys.dataToPoint(value);\r
24747                         var data = this.getData();\r
24748                         var offset = data.getLayout('offset');\r
24749                         var size = data.getLayout('size');\r
24750                         var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1;\r
24751                         pt[offsetIndex] += offset + size / 2;\r
24752                         return pt;\r
24753                     }\r
24754                     return [NaN, NaN];\r
24755                 },\r
24756 \r
24757                 defaultOption: {\r
24758                     zlevel: 0,                  // 一级层叠\r
24759                     z: 2,                       // 二级层叠\r
24760                     coordinateSystem: 'cartesian2d',\r
24761                     legendHoverLink: true,\r
24762                     // stack: null\r
24763 \r
24764                     // Cartesian coordinate system\r
24765                     xAxisIndex: 0,\r
24766                     yAxisIndex: 0,\r
24767 \r
24768                     // 最小高度改为0\r
24769                     barMinHeight: 0,\r
24770 \r
24771                     // barMaxWidth: null,\r
24772                     // 默认自适应\r
24773                     // barWidth: null,\r
24774                     // 柱间距离,默认为柱形宽度的30%,可设固定值\r
24775                     // barGap: '30%',\r
24776                     // 类目间柱形距离,默认为类目间距的20%,可设固定值\r
24777                     // barCategoryGap: '20%',\r
24778                     // label: {\r
24779                     //     normal: {\r
24780                     //         show: false\r
24781                     //         formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
24782 \r
24783                     //         // 默认自适应,水平布局为'top',垂直布局为'right',可选为\r
24784                     //         //           'inside' | 'insideleft' | 'insideTop' | 'insideRight' | 'insideBottom' |\r
24785                     //         //           'outside' |'left' | 'right'|'top'|'bottom'\r
24786                     //         position:\r
24787 \r
24788                     //         textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE\r
24789                     //     }\r
24790                     // },\r
24791                     itemStyle: {\r
24792                         normal: {\r
24793                             // color: '各异',\r
24794                             // 柱条边线\r
24795                             barBorderColor: '#fff',\r
24796                             // 柱条边线线宽,单位px,默认为1\r
24797                             barBorderWidth: 0\r
24798                         },\r
24799                         emphasis: {\r
24800                             // color: '各异',\r
24801                             // 柱条边线\r
24802                             barBorderColor: '#fff',\r
24803                             // 柱条边线线宽,单位px,默认为1\r
24804                             barBorderWidth: 0\r
24805                         }\r
24806                     }\r
24807                 }\r
24808             });\r
24809 \r
24810 \r
24811 /***/ },\r
24812 /* 129 */\r
24813 /***/ function(module, exports, __webpack_require__) {\r
24814 \r
24815         'use strict';\r
24816 \r
24817 \r
24818             var zrUtil = __webpack_require__(3);\r
24819             var graphic = __webpack_require__(42);\r
24820 \r
24821             zrUtil.extend(__webpack_require__(8).prototype, __webpack_require__(130));\r
24822 \r
24823             function fixLayoutWithLineWidth(layout, lineWidth) {\r
24824                 var signX = layout.width > 0 ? 1 : -1;\r
24825                 var signY = layout.height > 0 ? 1 : -1;\r
24826                 // In case width or height are too small.\r
24827                 lineWidth = Math.min(lineWidth, Math.abs(layout.width), Math.abs(layout.height));\r
24828                 layout.x += signX * lineWidth / 2;\r
24829                 layout.y += signY * lineWidth / 2;\r
24830                 layout.width -= signX * lineWidth;\r
24831                 layout.height -= signY * lineWidth;\r
24832             }\r
24833 \r
24834             module.exports = __webpack_require__(1).extendChartView({\r
24835 \r
24836                 type: 'bar',\r
24837 \r
24838                 render: function (seriesModel, ecModel, api) {\r
24839                     var coordinateSystemType = seriesModel.get('coordinateSystem');\r
24840 \r
24841                     if (coordinateSystemType === 'cartesian2d') {\r
24842                         this._renderOnCartesian(seriesModel, ecModel, api);\r
24843                     }\r
24844 \r
24845                     return this.group;\r
24846                 },\r
24847 \r
24848                 _renderOnCartesian: function (seriesModel, ecModel, api) {\r
24849                     var group = this.group;\r
24850                     var data = seriesModel.getData();\r
24851                     var oldData = this._data;\r
24852 \r
24853                     var cartesian = seriesModel.coordinateSystem;\r
24854                     var baseAxis = cartesian.getBaseAxis();\r
24855                     var isHorizontal = baseAxis.isHorizontal();\r
24856 \r
24857                     var enableAnimation = seriesModel.get('animation');\r
24858 \r
24859                     var barBorderWidthQuery = ['itemStyle', 'normal', 'barBorderWidth'];\r
24860 \r
24861                     function createRect(dataIndex, isUpdate) {\r
24862                         var layout = data.getItemLayout(dataIndex);\r
24863                         var lineWidth = data.getItemModel(dataIndex).get(barBorderWidthQuery) || 0;\r
24864                         fixLayoutWithLineWidth(layout, lineWidth);\r
24865 \r
24866                         var rect = new graphic.Rect({\r
24867                             shape: zrUtil.extend({}, layout)\r
24868                         });\r
24869                         // Animation\r
24870                         if (enableAnimation) {\r
24871                             var rectShape = rect.shape;\r
24872                             var animateProperty = isHorizontal ? 'height' : 'width';\r
24873                             var animateTarget = {};\r
24874                             rectShape[animateProperty] = 0;\r
24875                             animateTarget[animateProperty] = layout[animateProperty];\r
24876                             graphic[isUpdate? 'updateProps' : 'initProps'](rect, {\r
24877                                 shape: animateTarget\r
24878                             }, seriesModel);\r
24879                         }\r
24880                         return rect;\r
24881                     }\r
24882                     data.diff(oldData)\r
24883                         .add(function (dataIndex) {\r
24884                             // 空数据\r
24885                             if (!data.hasValue(dataIndex)) {\r
24886                                 return;\r
24887                             }\r
24888 \r
24889                             var rect = createRect(dataIndex);\r
24890 \r
24891                             data.setItemGraphicEl(dataIndex, rect);\r
24892 \r
24893                             group.add(rect);\r
24894 \r
24895                         })\r
24896                         .update(function (newIndex, oldIndex) {\r
24897                             var rect = oldData.getItemGraphicEl(oldIndex);\r
24898                             // 空数据\r
24899                             if (!data.hasValue(newIndex)) {\r
24900                                 group.remove(rect);\r
24901                                 return;\r
24902                             }\r
24903                             if (!rect) {\r
24904                                 rect = createRect(newIndex, true);\r
24905                             }\r
24906 \r
24907                             var layout = data.getItemLayout(newIndex);\r
24908                             var lineWidth = data.getItemModel(newIndex).get(barBorderWidthQuery) || 0;\r
24909                             fixLayoutWithLineWidth(layout, lineWidth);\r
24910 \r
24911                             graphic.updateProps(rect, {\r
24912                                 shape: layout\r
24913                             }, seriesModel);\r
24914 \r
24915                             data.setItemGraphicEl(newIndex, rect);\r
24916 \r
24917                             // Add back\r
24918                             group.add(rect);\r
24919                         })\r
24920                         .remove(function (idx) {\r
24921                             var rect = oldData.getItemGraphicEl(idx);\r
24922                             if (rect) {\r
24923                                 // Not show text when animating\r
24924                                 rect.style.text = '';\r
24925                                 graphic.updateProps(rect, {\r
24926                                     shape: {\r
24927                                         width: 0\r
24928                                     }\r
24929                                 }, seriesModel, function () {\r
24930                                     group.remove(rect);\r
24931                                 });\r
24932                             }\r
24933                         })\r
24934                         .execute();\r
24935 \r
24936                     this._updateStyle(seriesModel, data, isHorizontal);\r
24937 \r
24938                     this._data = data;\r
24939                 },\r
24940 \r
24941                 _updateStyle: function (seriesModel, data, isHorizontal) {\r
24942                     function setLabel(style, model, color, labelText, labelPositionOutside) {\r
24943                         graphic.setText(style, model, color);\r
24944                         style.text = labelText;\r
24945                         if (style.textPosition === 'outside') {\r
24946                             style.textPosition = labelPositionOutside;\r
24947                         }\r
24948                     }\r
24949 \r
24950                     data.eachItemGraphicEl(function (rect, idx) {\r
24951                         var itemModel = data.getItemModel(idx);\r
24952                         var color = data.getItemVisual(idx, 'color');\r
24953                         var layout = data.getItemLayout(idx);\r
24954                         var itemStyleModel = itemModel.getModel('itemStyle.normal');\r
24955 \r
24956                         var hoverStyle = itemModel.getModel('itemStyle.emphasis').getItemStyle();\r
24957 \r
24958                         rect.setShape('r', itemStyleModel.get('barBorderRadius') || 0);\r
24959 \r
24960                         rect.setStyle(zrUtil.defaults(\r
24961                             {\r
24962                                 fill: color\r
24963                             },\r
24964                             itemStyleModel.getBarItemStyle()\r
24965                         ));\r
24966 \r
24967                         var labelPositionOutside = isHorizontal\r
24968                             ? (layout.height > 0 ? 'bottom' : 'top')\r
24969                             : (layout.width > 0 ? 'left' : 'right');\r
24970 \r
24971                         var labelModel = itemModel.getModel('label.normal');\r
24972                         var hoverLabelModel = itemModel.getModel('label.emphasis');\r
24973                         var rectStyle = rect.style;\r
24974                         if (labelModel.get('show')) {\r
24975                             setLabel(\r
24976                                 rectStyle, labelModel, color,\r
24977                                 zrUtil.retrieve(\r
24978                                     seriesModel.getFormattedLabel(idx, 'normal'),\r
24979                                     seriesModel.getRawValue(idx)\r
24980                                 ),\r
24981                                 labelPositionOutside\r
24982                             );\r
24983                         }\r
24984                         else {\r
24985                             rectStyle.text = '';\r
24986                         }\r
24987                         if (hoverLabelModel.get('show')) {\r
24988                             setLabel(\r
24989                                 hoverStyle, hoverLabelModel, color,\r
24990                                 zrUtil.retrieve(\r
24991                                     seriesModel.getFormattedLabel(idx, 'emphasis'),\r
24992                                     seriesModel.getRawValue(idx)\r
24993                                 ),\r
24994                                 labelPositionOutside\r
24995                             );\r
24996                         }\r
24997                         else {\r
24998                             hoverStyle.text = '';\r
24999                         }\r
25000                         graphic.setHoverStyle(rect, hoverStyle);\r
25001                     });\r
25002                 },\r
25003 \r
25004                 remove: function (ecModel, api) {\r
25005                     var group = this.group;\r
25006                     if (ecModel.get('animation')) {\r
25007                         if (this._data) {\r
25008                             this._data.eachItemGraphicEl(function (el) {\r
25009                                 // Not show text when animating\r
25010                                 el.style.text = '';\r
25011                                 graphic.updateProps(el, {\r
25012                                     shape: {\r
25013                                         width: 0\r
25014                                     }\r
25015                                 }, ecModel, function () {\r
25016                                     group.remove(el);\r
25017                                 });\r
25018                             });\r
25019                         }\r
25020                     }\r
25021                     else {\r
25022                         group.removeAll();\r
25023                     }\r
25024                 }\r
25025             });\r
25026 \r
25027 \r
25028 /***/ },\r
25029 /* 130 */\r
25030 /***/ function(module, exports, __webpack_require__) {\r
25031 \r
25032         \r
25033             module.exports = {\r
25034                 getBarItemStyle: __webpack_require__(11)(\r
25035                     [\r
25036                         ['fill', 'color'],\r
25037                         ['stroke', 'barBorderColor'],\r
25038                         ['lineWidth', 'barBorderWidth'],\r
25039                         ['opacity'],\r
25040                         ['shadowBlur'],\r
25041                         ['shadowOffsetX'],\r
25042                         ['shadowOffsetY'],\r
25043                         ['shadowColor']\r
25044                     ]\r
25045                 )\r
25046             };\r
25047 \r
25048 \r
25049 /***/ },\r
25050 /* 131 */\r
25051 /***/ function(module, exports, __webpack_require__) {\r
25052 \r
25053         'use strict';\r
25054 \r
25055 \r
25056             var zrUtil = __webpack_require__(3);\r
25057             var numberUtil = __webpack_require__(7);\r
25058             var parsePercent = numberUtil.parsePercent;\r
25059 \r
25060             function getSeriesStackId(seriesModel) {\r
25061                 return seriesModel.get('stack') || '__ec_stack_' + seriesModel.seriesIndex;\r
25062             }\r
25063 \r
25064             function calBarWidthAndOffset(barSeries, api) {\r
25065                 // Columns info on each category axis. Key is cartesian name\r
25066                 var columnsMap = {};\r
25067 \r
25068                 zrUtil.each(barSeries, function (seriesModel, idx) {\r
25069                     var cartesian = seriesModel.coordinateSystem;\r
25070 \r
25071                     var baseAxis = cartesian.getBaseAxis();\r
25072 \r
25073                     var columnsOnAxis = columnsMap[baseAxis.index] || {\r
25074                         remainedWidth: baseAxis.getBandWidth(),\r
25075                         autoWidthCount: 0,\r
25076                         categoryGap: '20%',\r
25077                         gap: '30%',\r
25078                         axis: baseAxis,\r
25079                         stacks: {}\r
25080                     };\r
25081                     var stacks = columnsOnAxis.stacks;\r
25082                     columnsMap[baseAxis.index] = columnsOnAxis;\r
25083 \r
25084                     var stackId = getSeriesStackId(seriesModel);\r
25085 \r
25086                     if (!stacks[stackId]) {\r
25087                         columnsOnAxis.autoWidthCount++;\r
25088                     }\r
25089                     stacks[stackId] = stacks[stackId] || {\r
25090                         width: 0,\r
25091                         maxWidth: 0\r
25092                     };\r
25093 \r
25094                     var barWidth = seriesModel.get('barWidth');\r
25095                     var barMaxWidth = seriesModel.get('barMaxWidth');\r
25096                     var barGap = seriesModel.get('barGap');\r
25097                     var barCategoryGap = seriesModel.get('barCategoryGap');\r
25098                     // TODO\r
25099                     if (barWidth && ! stacks[stackId].width) {\r
25100                         barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);\r
25101                         stacks[stackId].width = barWidth;\r
25102                         columnsOnAxis.remainedWidth -= barWidth;\r
25103                     }\r
25104 \r
25105                     barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);\r
25106                     (barGap != null) && (columnsOnAxis.gap = barGap);\r
25107                     (barCategoryGap != null) && (columnsOnAxis.categoryGap = barCategoryGap);\r
25108                 });\r
25109 \r
25110                 var result = {};\r
25111 \r
25112                 zrUtil.each(columnsMap, function (columnsOnAxis, coordSysName) {\r
25113 \r
25114                     result[coordSysName] = {};\r
25115 \r
25116                     var stacks = columnsOnAxis.stacks;\r
25117                     var baseAxis = columnsOnAxis.axis;\r
25118                     var bandWidth = baseAxis.getBandWidth();\r
25119                     var categoryGap = parsePercent(columnsOnAxis.categoryGap, bandWidth);\r
25120                     var barGapPercent = parsePercent(columnsOnAxis.gap, 1);\r
25121 \r
25122                     var remainedWidth = columnsOnAxis.remainedWidth;\r
25123                     var autoWidthCount = columnsOnAxis.autoWidthCount;\r
25124                     var autoWidth = (remainedWidth - categoryGap)\r
25125                         / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);\r
25126                     autoWidth = Math.max(autoWidth, 0);\r
25127 \r
25128                     // Find if any auto calculated bar exceeded maxBarWidth\r
25129                     zrUtil.each(stacks, function (column, stack) {\r
25130                         var maxWidth = column.maxWidth;\r
25131                         if (!column.width && maxWidth && maxWidth < autoWidth) {\r
25132                             maxWidth = Math.min(maxWidth, remainedWidth);\r
25133                             remainedWidth -= maxWidth;\r
25134                             column.width = maxWidth;\r
25135                             autoWidthCount--;\r
25136                         }\r
25137                     });\r
25138 \r
25139                     // Recalculate width again\r
25140                     autoWidth = (remainedWidth - categoryGap)\r
25141                         / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);\r
25142                     autoWidth = Math.max(autoWidth, 0);\r
25143 \r
25144                     var widthSum = 0;\r
25145                     var lastColumn;\r
25146                     zrUtil.each(stacks, function (column, idx) {\r
25147                         if (!column.width) {\r
25148                             column.width = autoWidth;\r
25149                         }\r
25150                         lastColumn = column;\r
25151                         widthSum += column.width * (1 + barGapPercent);\r
25152                     });\r
25153                     if (lastColumn) {\r
25154                         widthSum -= lastColumn.width * barGapPercent;\r
25155                     }\r
25156 \r
25157                     var offset = -widthSum / 2;\r
25158                     zrUtil.each(stacks, function (column, stackId) {\r
25159                         result[coordSysName][stackId] = result[coordSysName][stackId] || {\r
25160                             offset: offset,\r
25161                             width: column.width\r
25162                         };\r
25163 \r
25164                         offset += column.width * (1 + barGapPercent);\r
25165                     });\r
25166                 });\r
25167 \r
25168                 return result;\r
25169             }\r
25170 \r
25171             /**\r
25172              * @param {string} seriesType\r
25173              * @param {module:echarts/model/Global} ecModel\r
25174              * @param {module:echarts/ExtensionAPI} api\r
25175              */\r
25176             function barLayoutGrid(seriesType, ecModel, api) {\r
25177 \r
25178                 var barWidthAndOffset = calBarWidthAndOffset(\r
25179                     zrUtil.filter(\r
25180                         ecModel.getSeriesByType(seriesType),\r
25181                         function (seriesModel) {\r
25182                             return !ecModel.isSeriesFiltered(seriesModel)\r
25183                                 && seriesModel.coordinateSystem\r
25184                                 && seriesModel.coordinateSystem.type === 'cartesian2d';\r
25185                         }\r
25186                     )\r
25187                 );\r
25188 \r
25189                 var lastStackCoords = {};\r
25190 \r
25191                 ecModel.eachSeriesByType(seriesType, function (seriesModel) {\r
25192 \r
25193                     var data = seriesModel.getData();\r
25194                     var cartesian = seriesModel.coordinateSystem;\r
25195                     var baseAxis = cartesian.getBaseAxis();\r
25196 \r
25197                     var stackId = getSeriesStackId(seriesModel);\r
25198                     var columnLayoutInfo = barWidthAndOffset[baseAxis.index][stackId];\r
25199                     var columnOffset = columnLayoutInfo.offset;\r
25200                     var columnWidth = columnLayoutInfo.width;\r
25201                     var valueAxis = cartesian.getOtherAxis(baseAxis);\r
25202 \r
25203                     var barMinHeight = seriesModel.get('barMinHeight') || 0;\r
25204 \r
25205                     var valueAxisStart = baseAxis.onZero\r
25206                         ? valueAxis.toGlobalCoord(valueAxis.dataToCoord(0))\r
25207                         : valueAxis.getGlobalExtent()[0];\r
25208 \r
25209                     var coords = cartesian.dataToPoints(data, true);\r
25210                     lastStackCoords[stackId] = lastStackCoords[stackId] || [];\r
25211 \r
25212                     data.setLayout({\r
25213                         offset: columnOffset,\r
25214                         size: columnWidth\r
25215                     });\r
25216                     data.each(valueAxis.dim, function (value, idx) {\r
25217                         // 空数据\r
25218                         if (isNaN(value)) {\r
25219                             return;\r
25220                         }\r
25221                         if (!lastStackCoords[stackId][idx]) {\r
25222                             lastStackCoords[stackId][idx] = {\r
25223                                 // Positive stack\r
25224                                 p: valueAxisStart,\r
25225                                 // Negative stack\r
25226                                 n: valueAxisStart\r
25227                             };\r
25228                         }\r
25229                         var sign = value >= 0 ? 'p' : 'n';\r
25230                         var coord = coords[idx];\r
25231                         var lastCoord = lastStackCoords[stackId][idx][sign];\r
25232                         var x, y, width, height;\r
25233                         if (valueAxis.isHorizontal()) {\r
25234                             x = lastCoord;\r
25235                             y = coord[1] + columnOffset;\r
25236                             width = coord[0] - lastCoord;\r
25237                             height = columnWidth;\r
25238 \r
25239                             if (Math.abs(width) < barMinHeight) {\r
25240                                 width = (width < 0 ? -1 : 1) * barMinHeight;\r
25241                             }\r
25242                             lastStackCoords[stackId][idx][sign] += width;\r
25243                         }\r
25244                         else {\r
25245                             x = coord[0] + columnOffset;\r
25246                             y = lastCoord;\r
25247                             width = columnWidth;\r
25248                             height = coord[1] - lastCoord;\r
25249                             if (Math.abs(height) < barMinHeight) {\r
25250                                 // Include zero to has a positive bar\r
25251                                 height = (height <= 0 ? -1 : 1) * barMinHeight;\r
25252                             }\r
25253                             lastStackCoords[stackId][idx][sign] += height;\r
25254                         }\r
25255 \r
25256                         data.setItemLayout(idx, {\r
25257                             x: x,\r
25258                             y: y,\r
25259                             width: width,\r
25260                             height: height\r
25261                         });\r
25262                     }, true);\r
25263 \r
25264                 }, this);\r
25265             }\r
25266 \r
25267             module.exports = barLayoutGrid;\r
25268 \r
25269 \r
25270 /***/ },\r
25271 /* 132 */\r
25272 /***/ function(module, exports, __webpack_require__) {\r
25273 \r
25274         \r
25275 \r
25276             var zrUtil = __webpack_require__(3);\r
25277             var echarts = __webpack_require__(1);\r
25278 \r
25279             __webpack_require__(133);\r
25280             __webpack_require__(135);\r
25281 \r
25282             __webpack_require__(136)('pie', [{\r
25283                 type: 'pieToggleSelect',\r
25284                 event: 'pieselectchanged',\r
25285                 method: 'toggleSelected'\r
25286             }, {\r
25287                 type: 'pieSelect',\r
25288                 event: 'pieselected',\r
25289                 method: 'select'\r
25290             }, {\r
25291                 type: 'pieUnSelect',\r
25292                 event: 'pieunselected',\r
25293                 method: 'unSelect'\r
25294             }]);\r
25295 \r
25296             echarts.registerVisualCoding(\r
25297                 'chart',  zrUtil.curry(__webpack_require__(137), 'pie')\r
25298             );\r
25299 \r
25300             echarts.registerLayout(zrUtil.curry(\r
25301                 __webpack_require__(138), 'pie'\r
25302             ));\r
25303 \r
25304             echarts.registerProcessor(\r
25305                 'filter', zrUtil.curry(__webpack_require__(140), 'pie')\r
25306             );\r
25307 \r
25308 \r
25309 /***/ },\r
25310 /* 133 */\r
25311 /***/ function(module, exports, __webpack_require__) {\r
25312 \r
25313         'use strict';\r
25314 \r
25315 \r
25316             var List = __webpack_require__(94);\r
25317             var zrUtil = __webpack_require__(3);\r
25318             var modelUtil = __webpack_require__(5);\r
25319             var completeDimensions = __webpack_require__(96);\r
25320 \r
25321             var dataSelectableMixin = __webpack_require__(134);\r
25322 \r
25323             var PieSeries = __webpack_require__(1).extendSeriesModel({\r
25324 \r
25325                 type: 'series.pie',\r
25326 \r
25327                 // Overwrite\r
25328                 init: function (option) {\r
25329                     PieSeries.superApply(this, 'init', arguments);\r
25330 \r
25331                     // Enable legend selection for each data item\r
25332                     // Use a function instead of direct access because data reference may changed\r
25333                     this.legendDataProvider = function () {\r
25334                         return this._dataBeforeProcessed;\r
25335                     };\r
25336 \r
25337                     this.updateSelectedMap();\r
25338 \r
25339                     this._defaultLabelLine(option);\r
25340                 },\r
25341 \r
25342                 // Overwrite\r
25343                 mergeOption: function (newOption) {\r
25344                     PieSeries.superCall(this, 'mergeOption', newOption);\r
25345                     this.updateSelectedMap();\r
25346                 },\r
25347 \r
25348                 getInitialData: function (option, ecModel) {\r
25349                     var dimensions = completeDimensions(['value'], option.data);\r
25350                     var list = new List(dimensions, this);\r
25351                     list.initData(option.data);\r
25352                     return list;\r
25353                 },\r
25354 \r
25355                 // Overwrite\r
25356                 getDataParams: function (dataIndex) {\r
25357                     var data = this._data;\r
25358                     var params = PieSeries.superCall(this, 'getDataParams', dataIndex);\r
25359                     var sum = data.getSum('value');\r
25360                     // FIXME toFixed?\r
25361                     //\r
25362                     // Percent is 0 if sum is 0\r
25363                     params.percent = !sum ? 0 : +(data.get('value', dataIndex) / sum * 100).toFixed(2);\r
25364 \r
25365                     params.$vars.push('percent');\r
25366                     return params;\r
25367                 },\r
25368 \r
25369                 _defaultLabelLine: function (option) {\r
25370                     // Extend labelLine emphasis\r
25371                     modelUtil.defaultEmphasis(option.labelLine, ['show']);\r
25372 \r
25373                     var labelLineNormalOpt = option.labelLine.normal;\r
25374                     var labelLineEmphasisOpt = option.labelLine.emphasis;\r
25375                     // Not show label line if `label.normal.show = false`\r
25376                     labelLineNormalOpt.show = labelLineNormalOpt.show\r
25377                         && option.label.normal.show;\r
25378                     labelLineEmphasisOpt.show = labelLineEmphasisOpt.show\r
25379                         && option.label.emphasis.show;\r
25380                 },\r
25381 \r
25382                 defaultOption: {\r
25383                     zlevel: 0,\r
25384                     z: 2,\r
25385                     legendHoverLink: true,\r
25386 \r
25387                     hoverAnimation: true,\r
25388                     // 默认全局居中\r
25389                     center: ['50%', '50%'],\r
25390                     radius: [0, '75%'],\r
25391                     // 默认顺时针\r
25392                     clockwise: true,\r
25393                     startAngle: 90,\r
25394                     // 最小角度改为0\r
25395                     minAngle: 0,\r
25396                     // 选中是扇区偏移量\r
25397                     selectedOffset: 10,\r
25398 \r
25399                     // If use strategy to avoid label overlapping\r
25400                     avoidLabelOverlap: true,\r
25401                     // 选择模式,默认关闭,可选single,multiple\r
25402                     // selectedMode: false,\r
25403                     // 南丁格尔玫瑰图模式,'radius'(半径) | 'area'(面积)\r
25404                     // roseType: null,\r
25405 \r
25406                     label: {\r
25407                         normal: {\r
25408                             // If rotate around circle\r
25409                             rotate: false,\r
25410                             show: true,\r
25411                             // 'outer', 'inside', 'center'\r
25412                             position: 'outer'\r
25413                             // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
25414                             // textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE\r
25415                             // distance: 当position为inner时有效,为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数\r
25416                         },\r
25417                         emphasis: {}\r
25418                     },\r
25419                     // Enabled when label.normal.position is 'outer'\r
25420                     labelLine: {\r
25421                         normal: {\r
25422                             show: true,\r
25423                             // 引导线两段中的第一段长度\r
25424                             length: 15,\r
25425                             // 引导线两段中的第二段长度\r
25426                             length2: 15,\r
25427                             smooth: false,\r
25428                             lineStyle: {\r
25429                                 // color: 各异,\r
25430                                 width: 1,\r
25431                                 type: 'solid'\r
25432                             }\r
25433                         }\r
25434                     },\r
25435                     itemStyle: {\r
25436                         normal: {\r
25437                             // color: 各异,\r
25438                             borderColor: 'rgba(0,0,0,0)',\r
25439                             borderWidth: 1\r
25440                         },\r
25441                         emphasis: {\r
25442                             // color: 各异,\r
25443                             borderColor: 'rgba(0,0,0,0)',\r
25444                             borderWidth: 1\r
25445                         }\r
25446                     },\r
25447 \r
25448                     animationEasing: 'cubicOut',\r
25449 \r
25450                     data: []\r
25451                 }\r
25452             });\r
25453 \r
25454             zrUtil.mixin(PieSeries, dataSelectableMixin);\r
25455 \r
25456             module.exports = PieSeries;\r
25457 \r
25458 \r
25459 /***/ },\r
25460 /* 134 */\r
25461 /***/ function(module, exports, __webpack_require__) {\r
25462 \r
25463         /**\r
25464          * Data selectable mixin for chart series.\r
25465          * To eanble data select, option of series must have `selectedMode`.\r
25466          * And each data item will use `selected` to toggle itself selected status\r
25467          *\r
25468          * @module echarts/chart/helper/DataSelectable\r
25469          */\r
25470 \r
25471 \r
25472             var zrUtil = __webpack_require__(3);\r
25473 \r
25474             module.exports = {\r
25475 \r
25476                 updateSelectedMap: function () {\r
25477                     var option = this.option;\r
25478                     this._dataOptMap = zrUtil.reduce(option.data, function (dataOptMap, dataOpt) {\r
25479                         dataOptMap[dataOpt.name] = dataOpt;\r
25480                         return dataOptMap;\r
25481                     }, {});\r
25482                 },\r
25483                 /**\r
25484                  * @param {string} name\r
25485                  */\r
25486                 // PENGING If selectedMode is null ?\r
25487                 select: function (name) {\r
25488                     var dataOptMap = this._dataOptMap;\r
25489                     var dataOpt = dataOptMap[name];\r
25490                     var selectedMode = this.get('selectedMode');\r
25491                     if (selectedMode === 'single') {\r
25492                         zrUtil.each(dataOptMap, function (dataOpt) {\r
25493                             dataOpt.selected = false;\r
25494                         });\r
25495                     }\r
25496                     dataOpt && (dataOpt.selected = true);\r
25497                 },\r
25498 \r
25499                 /**\r
25500                  * @param {string} name\r
25501                  */\r
25502                 unSelect: function (name) {\r
25503                     var dataOpt = this._dataOptMap[name];\r
25504                     // var selectedMode = this.get('selectedMode');\r
25505                     // selectedMode !== 'single' && dataOpt && (dataOpt.selected = false);\r
25506                     dataOpt && (dataOpt.selected = false);\r
25507                 },\r
25508 \r
25509                 /**\r
25510                  * @param {string} name\r
25511                  */\r
25512                 toggleSelected: function (name) {\r
25513                     var dataOpt = this._dataOptMap[name];\r
25514                     if (dataOpt != null) {\r
25515                         this[dataOpt.selected ? 'unSelect' : 'select'](name);\r
25516                         return dataOpt.selected;\r
25517                     }\r
25518                 },\r
25519 \r
25520                 /**\r
25521                  * @param {string} name\r
25522                  */\r
25523                 isSelected: function (name) {\r
25524                     var dataOpt = this._dataOptMap[name];\r
25525                     return dataOpt && dataOpt.selected;\r
25526                 }\r
25527             };\r
25528 \r
25529 \r
25530 /***/ },\r
25531 /* 135 */\r
25532 /***/ function(module, exports, __webpack_require__) {\r
25533 \r
25534         \r
25535 \r
25536             var graphic = __webpack_require__(42);\r
25537             var zrUtil = __webpack_require__(3);\r
25538 \r
25539             /**\r
25540              * @param {module:echarts/model/Series} seriesModel\r
25541              * @param {boolean} hasAnimation\r
25542              * @inner\r
25543              */\r
25544             function updateDataSelected(uid, seriesModel, hasAnimation, api) {\r
25545                 var data = seriesModel.getData();\r
25546                 var dataIndex = this.dataIndex;\r
25547                 var name = data.getName(dataIndex);\r
25548                 var selectedOffset = seriesModel.get('selectedOffset');\r
25549 \r
25550                 api.dispatchAction({\r
25551                     type: 'pieToggleSelect',\r
25552                     from: uid,\r
25553                     name: name,\r
25554                     seriesId: seriesModel.id\r
25555                 });\r
25556 \r
25557                 data.each(function (idx) {\r
25558                     toggleItemSelected(\r
25559                         data.getItemGraphicEl(idx),\r
25560                         data.getItemLayout(idx),\r
25561                         seriesModel.isSelected(data.getName(idx)),\r
25562                         selectedOffset,\r
25563                         hasAnimation\r
25564                     );\r
25565                 });\r
25566             }\r
25567 \r
25568             /**\r
25569              * @param {module:zrender/graphic/Sector} el\r
25570              * @param {Object} layout\r
25571              * @param {boolean} isSelected\r
25572              * @param {number} selectedOffset\r
25573              * @param {boolean} hasAnimation\r
25574              * @inner\r
25575              */\r
25576             function toggleItemSelected(el, layout, isSelected, selectedOffset, hasAnimation) {\r
25577                 var midAngle = (layout.startAngle + layout.endAngle) / 2;\r
25578 \r
25579                 var dx = Math.cos(midAngle);\r
25580                 var dy = Math.sin(midAngle);\r
25581 \r
25582                 var offset = isSelected ? selectedOffset : 0;\r
25583                 var position = [dx * offset, dy * offset];\r
25584 \r
25585                 hasAnimation\r
25586                     // animateTo will stop revious animation like update transition\r
25587                     ? el.animate()\r
25588                         .when(200, {\r
25589                             position: position\r
25590                         })\r
25591                         .start('bounceOut')\r
25592                     : el.attr('position', position);\r
25593             }\r
25594 \r
25595             /**\r
25596              * Piece of pie including Sector, Label, LabelLine\r
25597              * @constructor\r
25598              * @extends {module:zrender/graphic/Group}\r
25599              */\r
25600             function PiePiece(data, idx) {\r
25601 \r
25602                 graphic.Group.call(this);\r
25603 \r
25604                 var sector = new graphic.Sector({\r
25605                     z2: 2\r
25606                 });\r
25607                 var polyline = new graphic.Polyline();\r
25608                 var text = new graphic.Text();\r
25609                 this.add(sector);\r
25610                 this.add(polyline);\r
25611                 this.add(text);\r
25612 \r
25613                 this.updateData(data, idx, true);\r
25614 \r
25615                 // Hover to change label and labelLine\r
25616                 function onEmphasis() {\r
25617                     polyline.ignore = polyline.hoverIgnore;\r
25618                     text.ignore = text.hoverIgnore;\r
25619                 }\r
25620                 function onNormal() {\r
25621                     polyline.ignore = polyline.normalIgnore;\r
25622                     text.ignore = text.normalIgnore;\r
25623                 }\r
25624                 this.on('emphasis', onEmphasis)\r
25625                     .on('normal', onNormal)\r
25626                     .on('mouseover', onEmphasis)\r
25627                     .on('mouseout', onNormal);\r
25628             }\r
25629 \r
25630             var piePieceProto = PiePiece.prototype;\r
25631 \r
25632             function getLabelStyle(data, idx, state, labelModel, labelPosition) {\r
25633                 var textStyleModel = labelModel.getModel('textStyle');\r
25634                 var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';\r
25635                 return {\r
25636                     fill: textStyleModel.getTextColor()\r
25637                         || (isLabelInside ? '#fff' : data.getItemVisual(idx, 'color')),\r
25638                     textFont: textStyleModel.getFont(),\r
25639                     text: zrUtil.retrieve(\r
25640                         data.hostModel.getFormattedLabel(idx, state), data.getName(idx)\r
25641                     )\r
25642                 };\r
25643             }\r
25644 \r
25645             piePieceProto.updateData = function (data, idx, firstCreate) {\r
25646 \r
25647                 var sector = this.childAt(0);\r
25648 \r
25649                 var seriesModel = data.hostModel;\r
25650                 var itemModel = data.getItemModel(idx);\r
25651                 var layout = data.getItemLayout(idx);\r
25652                 var sectorShape = zrUtil.extend({}, layout);\r
25653                 sectorShape.label = null;\r
25654                 if (firstCreate) {\r
25655                     sector.setShape(sectorShape);\r
25656                     sector.shape.endAngle = layout.startAngle;\r
25657                     graphic.updateProps(sector, {\r
25658                         shape: {\r
25659                             endAngle: layout.endAngle\r
25660                         }\r
25661                     }, seriesModel);\r
25662                 }\r
25663                 else {\r
25664                     graphic.updateProps(sector, {\r
25665                         shape: sectorShape\r
25666                     }, seriesModel);\r
25667                 }\r
25668 \r
25669                 // Update common style\r
25670                 var itemStyleModel = itemModel.getModel('itemStyle');\r
25671                 var visualColor = data.getItemVisual(idx, 'color');\r
25672 \r
25673                 sector.setStyle(\r
25674                     zrUtil.defaults(\r
25675                         {\r
25676                             fill: visualColor\r
25677                         },\r
25678                         itemStyleModel.getModel('normal').getItemStyle()\r
25679                     )\r
25680                 );\r
25681                 sector.hoverStyle = itemStyleModel.getModel('emphasis').getItemStyle();\r
25682 \r
25683                 // Toggle selected\r
25684                 toggleItemSelected(\r
25685                     this,\r
25686                     data.getItemLayout(idx),\r
25687                     itemModel.get('selected'),\r
25688                     seriesModel.get('selectedOffset'),\r
25689                     seriesModel.get('animation')\r
25690                 );\r
25691 \r
25692                 function onEmphasis() {\r
25693                     // Sector may has animation of updating data. Force to move to the last frame\r
25694                     // Or it may stopped on the wrong shape\r
25695                     sector.stopAnimation(true);\r
25696                     sector.animateTo({\r
25697                         shape: {\r
25698                             r: layout.r + 10\r
25699                         }\r
25700                     }, 300, 'elasticOut');\r
25701                 }\r
25702                 function onNormal() {\r
25703                     sector.stopAnimation(true);\r
25704                     sector.animateTo({\r
25705                         shape: {\r
25706                             r: layout.r\r
25707                         }\r
25708                     }, 300, 'elasticOut');\r
25709                 }\r
25710                 sector.off('mouseover').off('mouseout').off('emphasis').off('normal');\r
25711                 if (itemModel.get('hoverAnimation')) {\r
25712                     sector\r
25713                         .on('mouseover', onEmphasis)\r
25714                         .on('mouseout', onNormal)\r
25715                         .on('emphasis', onEmphasis)\r
25716                         .on('normal', onNormal);\r
25717                 }\r
25718 \r
25719                 this._updateLabel(data, idx);\r
25720 \r
25721                 graphic.setHoverStyle(this);\r
25722             };\r
25723 \r
25724             piePieceProto._updateLabel = function (data, idx) {\r
25725 \r
25726                 var labelLine = this.childAt(1);\r
25727                 var labelText = this.childAt(2);\r
25728 \r
25729                 var seriesModel = data.hostModel;\r
25730                 var itemModel = data.getItemModel(idx);\r
25731                 var layout = data.getItemLayout(idx);\r
25732                 var labelLayout = layout.label;\r
25733                 var visualColor = data.getItemVisual(idx, 'color');\r
25734 \r
25735                 graphic.updateProps(labelLine, {\r
25736                     shape: {\r
25737                         points: labelLayout.linePoints || [\r
25738                             [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y]\r
25739                         ]\r
25740                     }\r
25741                 }, seriesModel);\r
25742 \r
25743                 graphic.updateProps(labelText, {\r
25744                     style: {\r
25745                         x: labelLayout.x,\r
25746                         y: labelLayout.y\r
25747                     }\r
25748                 }, seriesModel);\r
25749                 labelText.attr({\r
25750                     style: {\r
25751                         textVerticalAlign: labelLayout.verticalAlign,\r
25752                         textAlign: labelLayout.textAlign,\r
25753                         textFont: labelLayout.font\r
25754                     },\r
25755                     rotation: labelLayout.rotation,\r
25756                     origin: [labelLayout.x, labelLayout.y],\r
25757                     z2: 10\r
25758                 });\r
25759 \r
25760                 var labelModel = itemModel.getModel('label.normal');\r
25761                 var labelHoverModel = itemModel.getModel('label.emphasis');\r
25762                 var labelLineModel = itemModel.getModel('labelLine.normal');\r
25763                 var labelLineHoverModel = itemModel.getModel('labelLine.emphasis');\r
25764                 var labelPosition = labelModel.get('position') || labelHoverModel.get('position');\r
25765 \r
25766                 labelText.setStyle(getLabelStyle(data, idx, 'normal', labelModel, labelPosition));\r
25767 \r
25768                 labelText.ignore = labelText.normalIgnore = !labelModel.get('show');\r
25769                 labelText.hoverIgnore = !labelHoverModel.get('show');\r
25770 \r
25771                 labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show');\r
25772                 labelLine.hoverIgnore = !labelLineHoverModel.get('show');\r
25773 \r
25774                 // Default use item visual color\r
25775                 labelLine.setStyle({\r
25776                     stroke: visualColor\r
25777                 });\r
25778                 labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());\r
25779 \r
25780                 labelText.hoverStyle = getLabelStyle(data, idx, 'emphasis', labelHoverModel, labelPosition);\r
25781                 labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();\r
25782 \r
25783                 var smooth = labelLineModel.get('smooth');\r
25784                 if (smooth && smooth === true) {\r
25785                     smooth = 0.4;\r
25786                 }\r
25787                 labelLine.setShape({\r
25788                     smooth: smooth\r
25789                 });\r
25790             };\r
25791 \r
25792             zrUtil.inherits(PiePiece, graphic.Group);\r
25793 \r
25794 \r
25795             // Pie view\r
25796             var Pie = __webpack_require__(41).extend({\r
25797 \r
25798                 type: 'pie',\r
25799 \r
25800                 init: function () {\r
25801                     var sectorGroup = new graphic.Group();\r
25802                     this._sectorGroup = sectorGroup;\r
25803                 },\r
25804 \r
25805                 render: function (seriesModel, ecModel, api, payload) {\r
25806                     if (payload && (payload.from === this.uid)) {\r
25807                         return;\r
25808                     }\r
25809 \r
25810                     var data = seriesModel.getData();\r
25811                     var oldData = this._data;\r
25812                     var group = this.group;\r
25813 \r
25814                     var hasAnimation = ecModel.get('animation');\r
25815                     var isFirstRender = !oldData;\r
25816 \r
25817                     var onSectorClick = zrUtil.curry(\r
25818                         updateDataSelected, this.uid, seriesModel, hasAnimation, api\r
25819                     );\r
25820 \r
25821                     var selectedMode = seriesModel.get('selectedMode');\r
25822 \r
25823                     data.diff(oldData)\r
25824                         .add(function (idx) {\r
25825                             var piePiece = new PiePiece(data, idx);\r
25826                             if (isFirstRender) {\r
25827                                 piePiece.eachChild(function (child) {\r
25828                                     child.stopAnimation(true);\r
25829                                 });\r
25830                             }\r
25831 \r
25832                             selectedMode && piePiece.on('click', onSectorClick);\r
25833 \r
25834                             data.setItemGraphicEl(idx, piePiece);\r
25835 \r
25836                             group.add(piePiece);\r
25837                         })\r
25838                         .update(function (newIdx, oldIdx) {\r
25839                             var piePiece = oldData.getItemGraphicEl(oldIdx);\r
25840 \r
25841                             piePiece.updateData(data, newIdx);\r
25842 \r
25843                             piePiece.off('click');\r
25844                             selectedMode && piePiece.on('click', onSectorClick);\r
25845                             group.add(piePiece);\r
25846                             data.setItemGraphicEl(newIdx, piePiece);\r
25847                         })\r
25848                         .remove(function (idx) {\r
25849                             var piePiece = oldData.getItemGraphicEl(idx);\r
25850                             group.remove(piePiece);\r
25851                         })\r
25852                         .execute();\r
25853 \r
25854                     if (hasAnimation && isFirstRender && data.count() > 0) {\r
25855                         var shape = data.getItemLayout(0);\r
25856                         var r = Math.max(api.getWidth(), api.getHeight()) / 2;\r
25857 \r
25858                         var removeClipPath = zrUtil.bind(group.removeClipPath, group);\r
25859                         group.setClipPath(this._createClipPath(\r
25860                             shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath, seriesModel\r
25861                         ));\r
25862                     }\r
25863 \r
25864                     this._data = data;\r
25865                 },\r
25866 \r
25867                 _createClipPath: function (\r
25868                     cx, cy, r, startAngle, clockwise, cb, seriesModel\r
25869                 ) {\r
25870                     var clipPath = new graphic.Sector({\r
25871                         shape: {\r
25872                             cx: cx,\r
25873                             cy: cy,\r
25874                             r0: 0,\r
25875                             r: r,\r
25876                             startAngle: startAngle,\r
25877                             endAngle: startAngle,\r
25878                             clockwise: clockwise\r
25879                         }\r
25880                     });\r
25881 \r
25882                     graphic.initProps(clipPath, {\r
25883                         shape: {\r
25884                             endAngle: startAngle + (clockwise ? 1 : -1) * Math.PI * 2\r
25885                         }\r
25886                     }, seriesModel, cb);\r
25887 \r
25888                     return clipPath;\r
25889                 }\r
25890             });\r
25891 \r
25892             module.exports = Pie;\r
25893 \r
25894 \r
25895 /***/ },\r
25896 /* 136 */\r
25897 /***/ function(module, exports, __webpack_require__) {\r
25898 \r
25899         \r
25900             var echarts = __webpack_require__(1);\r
25901             var zrUtil = __webpack_require__(3);\r
25902             module.exports = function (seriesType, actionInfos) {\r
25903                 zrUtil.each(actionInfos, function (actionInfo) {\r
25904                     actionInfo.update = 'updateView';\r
25905                     /**\r
25906                      * @payload\r
25907                      * @property {string} seriesName\r
25908                      * @property {string} name\r
25909                      */\r
25910                     echarts.registerAction(actionInfo, function (payload, ecModel) {\r
25911                         var selected = {};\r
25912                         ecModel.eachComponent(\r
25913                             {mainType: 'series', subType: seriesType, query: payload},\r
25914                             function (seriesModel) {\r
25915                                 if (seriesModel[actionInfo.method]) {\r
25916                                     seriesModel[actionInfo.method](payload.name);\r
25917                                 }\r
25918                                 var data = seriesModel.getData();\r
25919                                 // Create selected map\r
25920                                 data.each(function (idx) {\r
25921                                     var name = data.getName(idx);\r
25922                                     selected[name] = seriesModel.isSelected(name) || false;\r
25923                                 });\r
25924                             }\r
25925                         );\r
25926                         return {\r
25927                             name: payload.name,\r
25928                             selected: selected\r
25929                         };\r
25930                     });\r
25931                 });\r
25932             };\r
25933 \r
25934 \r
25935 /***/ },\r
25936 /* 137 */\r
25937 /***/ function(module, exports) {\r
25938 \r
25939         // Pick color from palette for each data item\r
25940 \r
25941 \r
25942             module.exports = function (seriesType, ecModel) {\r
25943                 var globalColorList = ecModel.get('color');\r
25944                 var offset = 0;\r
25945                 ecModel.eachRawSeriesByType(seriesType, function (seriesModel) {\r
25946                     var colorList = seriesModel.get('color', true);\r
25947                     var dataAll = seriesModel.getRawData();\r
25948                     if (!ecModel.isSeriesFiltered(seriesModel)) {\r
25949                         var data = seriesModel.getData();\r
25950                         data.each(function (idx) {\r
25951                             var itemModel = data.getItemModel(idx);\r
25952                             var rawIdx = data.getRawIndex(idx);\r
25953                             // If series.itemStyle.normal.color is a function. itemVisual may be encoded\r
25954                             var singleDataColor = data.getItemVisual(idx, 'color', true);\r
25955                             if (!singleDataColor) {\r
25956                                 var paletteColor = colorList ? colorList[rawIdx % colorList.length]\r
25957                                     : globalColorList[(rawIdx + offset) % globalColorList.length];\r
25958                                 var color = itemModel.get('itemStyle.normal.color') || paletteColor;\r
25959                                 // Legend may use the visual info in data before processed\r
25960                                 dataAll.setItemVisual(rawIdx, 'color', color);\r
25961                                 data.setItemVisual(idx, 'color', color);\r
25962                             }\r
25963                             else {\r
25964                                 // Set data all color for legend\r
25965                                 dataAll.setItemVisual(rawIdx, 'color', singleDataColor);\r
25966                             }\r
25967                         });\r
25968                     }\r
25969                     offset += dataAll.count();\r
25970                 });\r
25971             };\r
25972 \r
25973 \r
25974 /***/ },\r
25975 /* 138 */\r
25976 /***/ function(module, exports, __webpack_require__) {\r
25977 \r
25978         // TODO minAngle\r
25979 \r
25980 \r
25981 \r
25982             var numberUtil = __webpack_require__(7);\r
25983             var parsePercent = numberUtil.parsePercent;\r
25984             var labelLayout = __webpack_require__(139);\r
25985             var zrUtil = __webpack_require__(3);\r
25986 \r
25987             var PI2 = Math.PI * 2;\r
25988             var RADIAN = Math.PI / 180;\r
25989 \r
25990             module.exports = function (seriesType, ecModel, api) {\r
25991                 ecModel.eachSeriesByType(seriesType, function (seriesModel) {\r
25992                     var center = seriesModel.get('center');\r
25993                     var radius = seriesModel.get('radius');\r
25994 \r
25995                     if (!zrUtil.isArray(radius)) {\r
25996                         radius = [0, radius];\r
25997                     }\r
25998                     if (!zrUtil.isArray(center)) {\r
25999                         center = [center, center];\r
26000                     }\r
26001 \r
26002                     var width = api.getWidth();\r
26003                     var height = api.getHeight();\r
26004                     var size = Math.min(width, height);\r
26005                     var cx = parsePercent(center[0], width);\r
26006                     var cy = parsePercent(center[1], height);\r
26007                     var r0 = parsePercent(radius[0], size / 2);\r
26008                     var r = parsePercent(radius[1], size / 2);\r
26009 \r
26010                     var data = seriesModel.getData();\r
26011 \r
26012                     var startAngle = -seriesModel.get('startAngle') * RADIAN;\r
26013 \r
26014                     var minAngle = seriesModel.get('minAngle') * RADIAN;\r
26015 \r
26016                     var sum = data.getSum('value');\r
26017                     // Sum may be 0\r
26018                     var unitRadian = Math.PI / (sum || data.count()) * 2;\r
26019 \r
26020                     var clockwise = seriesModel.get('clockwise');\r
26021 \r
26022                     var roseType = seriesModel.get('roseType');\r
26023 \r
26024                     // [0...max]\r
26025                     var extent = data.getDataExtent('value');\r
26026                     extent[0] = 0;\r
26027 \r
26028                     // In the case some sector angle is smaller than minAngle\r
26029                     var restAngle = PI2;\r
26030                     var valueSumLargerThanMinAngle = 0;\r
26031 \r
26032                     var currentAngle = startAngle;\r
26033 \r
26034                     var dir = clockwise ? 1 : -1;\r
26035                     data.each('value', function (value, idx) {\r
26036                         var angle;\r
26037                         // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样?\r
26038                         if (roseType !== 'area') {\r
26039                             angle = sum === 0 ? unitRadian : (value * unitRadian);\r
26040                         }\r
26041                         else {\r
26042                             angle = PI2 / (data.count() || 1);\r
26043                         }\r
26044 \r
26045                         if (angle < minAngle) {\r
26046                             angle = minAngle;\r
26047                             restAngle -= minAngle;\r
26048                         }\r
26049                         else {\r
26050                             valueSumLargerThanMinAngle += value;\r
26051                         }\r
26052 \r
26053                         var endAngle = currentAngle + dir * angle;\r
26054                         data.setItemLayout(idx, {\r
26055                             angle: angle,\r
26056                             startAngle: currentAngle,\r
26057                             endAngle: endAngle,\r
26058                             clockwise: clockwise,\r
26059                             cx: cx,\r
26060                             cy: cy,\r
26061                             r0: r0,\r
26062                             r: roseType\r
26063                                 ? numberUtil.linearMap(value, extent, [r0, r])\r
26064                                 : r\r
26065                         });\r
26066 \r
26067                         currentAngle = endAngle;\r
26068                     }, true);\r
26069 \r
26070                     // Some sector is constrained by minAngle\r
26071                     // Rest sectors needs recalculate angle\r
26072                     if (restAngle < PI2) {\r
26073                         // Average the angle if rest angle is not enough after all angles is\r
26074                         // Constrained by minAngle\r
26075                         if (restAngle <= 1e-3) {\r
26076                             var angle = PI2 / data.count();\r
26077                             data.each(function (idx) {\r
26078                                 var layout = data.getItemLayout(idx);\r
26079                                 layout.startAngle = startAngle + dir * idx * angle;\r
26080                                 layout.endAngle = startAngle + dir * (idx + 1) * angle;\r
26081                             });\r
26082                         }\r
26083                         else {\r
26084                             unitRadian = restAngle / valueSumLargerThanMinAngle;\r
26085                             currentAngle = startAngle;\r
26086                             data.each('value', function (value, idx) {\r
26087                                 var layout = data.getItemLayout(idx);\r
26088                                 var angle = layout.angle === minAngle\r
26089                                     ? minAngle : value * unitRadian;\r
26090                                 layout.startAngle = currentAngle;\r
26091                                 layout.endAngle = currentAngle + dir * angle;\r
26092                                 currentAngle += angle;\r
26093                             });\r
26094                         }\r
26095                     }\r
26096 \r
26097                     labelLayout(seriesModel, r, width, height);\r
26098                 });\r
26099             };\r
26100 \r
26101 \r
26102 /***/ },\r
26103 /* 139 */\r
26104 /***/ function(module, exports, __webpack_require__) {\r
26105 \r
26106         'use strict';\r
26107         // FIXME emphasis label position is not same with normal label position\r
26108 \r
26109 \r
26110             var textContain = __webpack_require__(14);\r
26111 \r
26112             function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {\r
26113                 list.sort(function (a, b) {\r
26114                     return a.y - b.y;\r
26115                 });\r
26116 \r
26117                 // 压\r
26118                 function shiftDown(start, end, delta, dir) {\r
26119                     for (var j = start; j < end; j++) {\r
26120                         list[j].y += delta;\r
26121                         if (j > start\r
26122                             && j + 1 < end\r
26123                             && list[j + 1].y > list[j].y + list[j].height\r
26124                         ) {\r
26125                             shiftUp(j, delta / 2);\r
26126                             return;\r
26127                         }\r
26128                     }\r
26129 \r
26130                     shiftUp(end - 1, delta / 2);\r
26131                 }\r
26132 \r
26133                 // 弹\r
26134                 function shiftUp(end, delta) {\r
26135                     for (var j = end; j >= 0; j--) {\r
26136                         list[j].y -= delta;\r
26137                         if (j > 0\r
26138                             && list[j].y > list[j - 1].y + list[j - 1].height\r
26139                         ) {\r
26140                             break;\r
26141                         }\r
26142                     }\r
26143                 }\r
26144 \r
26145                 function changeX(list, isDownList, cx, cy, r, dir) {\r
26146                     var lastDeltaX = dir > 0\r
26147                         ? isDownList                // 右侧\r
26148                             ? Number.MAX_VALUE      // 下\r
26149                             : 0                     // 上\r
26150                         : isDownList                // 左侧\r
26151                             ? Number.MAX_VALUE      // 下\r
26152                             : 0;                    // 上\r
26153 \r
26154                     for (var i = 0, l = list.length; i < l; i++) {\r
26155                         // Not change x for center label\r
26156                         if (list[i].position === 'center') {\r
26157                             continue;\r
26158                         }\r
26159                         var deltaY = Math.abs(list[i].y - cy);\r
26160                         var length = list[i].len;\r
26161                         var length2 = list[i].len2;\r
26162                         var deltaX = (deltaY < r + length)\r
26163                             ? Math.sqrt(\r
26164                                   (r + length + length2) * (r + length + length2)\r
26165                                   - deltaY * deltaY\r
26166                               )\r
26167                             : Math.abs(list[i].x - cx);\r
26168                         if (isDownList && deltaX >= lastDeltaX) {\r
26169                             // 右下,左下\r
26170                             deltaX = lastDeltaX - 10;\r
26171                         }\r
26172                         if (!isDownList && deltaX <= lastDeltaX) {\r
26173                             // 右上,左上\r
26174                             deltaX = lastDeltaX + 10;\r
26175                         }\r
26176 \r
26177                         list[i].x = cx + deltaX * dir;\r
26178                         lastDeltaX = deltaX;\r
26179                     }\r
26180                 }\r
26181 \r
26182                 var lastY = 0;\r
26183                 var delta;\r
26184                 var len = list.length;\r
26185                 var upList = [];\r
26186                 var downList = [];\r
26187                 for (var i = 0; i < len; i++) {\r
26188                     delta = list[i].y - lastY;\r
26189                     if (delta < 0) {\r
26190                         shiftDown(i, len, -delta, dir);\r
26191                     }\r
26192                     lastY = list[i].y + list[i].height;\r
26193                 }\r
26194                 if (viewHeight - lastY < 0) {\r
26195                     shiftUp(len - 1, lastY - viewHeight);\r
26196                 }\r
26197                 for (var i = 0; i < len; i++) {\r
26198                     if (list[i].y >= cy) {\r
26199                         downList.push(list[i]);\r
26200                     }\r
26201                     else {\r
26202                         upList.push(list[i]);\r
26203                     }\r
26204                 }\r
26205                 changeX(upList, false, cx, cy, r, dir);\r
26206                 changeX(downList, true, cx, cy, r, dir);\r
26207             }\r
26208 \r
26209             function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {\r
26210                 var leftList = [];\r
26211                 var rightList = [];\r
26212                 for (var i = 0; i < labelLayoutList.length; i++) {\r
26213                     if (labelLayoutList[i].x < cx) {\r
26214                         leftList.push(labelLayoutList[i]);\r
26215                     }\r
26216                     else {\r
26217                         rightList.push(labelLayoutList[i]);\r
26218                     }\r
26219                 }\r
26220 \r
26221                 adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight);\r
26222                 adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight);\r
26223 \r
26224                 for (var i = 0; i < labelLayoutList.length; i++) {\r
26225                     var linePoints = labelLayoutList[i].linePoints;\r
26226                     if (linePoints) {\r
26227                         var dist = linePoints[1][0] - linePoints[2][0];\r
26228                         if (labelLayoutList[i].x < cx) {\r
26229                             linePoints[2][0] = labelLayoutList[i].x + 3;\r
26230                         }\r
26231                         else {\r
26232                             linePoints[2][0] = labelLayoutList[i].x - 3;\r
26233                         }\r
26234                         linePoints[1][1] = linePoints[2][1] = labelLayoutList[i].y;\r
26235                         linePoints[1][0] = linePoints[2][0] + dist;\r
26236                     }\r
26237                 }\r
26238             }\r
26239 \r
26240             module.exports = function (seriesModel, r, viewWidth, viewHeight) {\r
26241                 var data = seriesModel.getData();\r
26242                 var labelLayoutList = [];\r
26243                 var cx;\r
26244                 var cy;\r
26245                 var hasLabelRotate = false;\r
26246 \r
26247                 data.each(function (idx) {\r
26248                     var layout = data.getItemLayout(idx);\r
26249 \r
26250                     var itemModel = data.getItemModel(idx);\r
26251                     var labelModel = itemModel.getModel('label.normal');\r
26252                     // Use position in normal or emphasis\r
26253                     var labelPosition = labelModel.get('position') || itemModel.get('label.emphasis.position');\r
26254 \r
26255                     var labelLineModel = itemModel.getModel('labelLine.normal');\r
26256                     var labelLineLen = labelLineModel.get('length');\r
26257                     var labelLineLen2 = labelLineModel.get('length2');\r
26258 \r
26259                     var midAngle = (layout.startAngle + layout.endAngle) / 2;\r
26260                     var dx = Math.cos(midAngle);\r
26261                     var dy = Math.sin(midAngle);\r
26262 \r
26263                     var textX;\r
26264                     var textY;\r
26265                     var linePoints;\r
26266                     var textAlign;\r
26267 \r
26268                     cx = layout.cx;\r
26269                     cy = layout.cy;\r
26270 \r
26271                     var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';\r
26272                     if (labelPosition === 'center') {\r
26273                         textX = layout.cx;\r
26274                         textY = layout.cy;\r
26275                         textAlign = 'center';\r
26276                     }\r
26277                     else {\r
26278                         var x1 = (isLabelInside ? layout.r / 2 * dx : layout.r * dx) + cx;\r
26279                         var y1 = (isLabelInside ? layout.r / 2 * dy : layout.r * dy) + cy;\r
26280 \r
26281                         textX = x1 + dx * 3;\r
26282                         textY = y1 + dy * 3;\r
26283 \r
26284                         if (!isLabelInside) {\r
26285                             // For roseType\r
26286                             var x2 = x1 + dx * (labelLineLen + r - layout.r);\r
26287                             var y2 = y1 + dy * (labelLineLen + r - layout.r);\r
26288                             var x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2);\r
26289                             var y3 = y2;\r
26290 \r
26291                             textX = x3 + (dx < 0 ? -5 : 5);\r
26292                             textY = y3;\r
26293                             linePoints = [[x1, y1], [x2, y2], [x3, y3]];\r
26294                         }\r
26295 \r
26296                         textAlign = isLabelInside ? 'center' : (dx > 0 ? 'left' : 'right');\r
26297                     }\r
26298                     var font = labelModel.getModel('textStyle').getFont();\r
26299 \r
26300                     var labelRotate = labelModel.get('rotate')\r
26301                         ? (dx < 0 ? -midAngle + Math.PI : -midAngle) : 0;\r
26302                     var text = seriesModel.getFormattedLabel(idx, 'normal')\r
26303                                 || data.getName(idx);\r
26304                     var textRect = textContain.getBoundingRect(\r
26305                         text, font, textAlign, 'top'\r
26306                     );\r
26307                     hasLabelRotate = !!labelRotate;\r
26308                     layout.label = {\r
26309                         x: textX,\r
26310                         y: textY,\r
26311                         position: labelPosition,\r
26312                         height: textRect.height,\r
26313                         len: labelLineLen,\r
26314                         len2: labelLineLen2,\r
26315                         linePoints: linePoints,\r
26316                         textAlign: textAlign,\r
26317                         verticalAlign: 'middle',\r
26318                         font: font,\r
26319                         rotation: labelRotate\r
26320                     };\r
26321 \r
26322                     // Not layout the inside label\r
26323                     if (!isLabelInside) {\r
26324                         labelLayoutList.push(layout.label);\r
26325                     }\r
26326                 });\r
26327                 if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {\r
26328                     avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight);\r
26329                 }\r
26330             };\r
26331 \r
26332 \r
26333 /***/ },\r
26334 /* 140 */\r
26335 /***/ function(module, exports) {\r
26336 \r
26337         \r
26338             module.exports = function (seriesType, ecModel) {\r
26339                 var legendModels = ecModel.findComponents({\r
26340                     mainType: 'legend'\r
26341                 });\r
26342                 if (!legendModels || !legendModels.length) {\r
26343                     return;\r
26344                 }\r
26345                 ecModel.eachSeriesByType(seriesType, function (series) {\r
26346                     var data = series.getData();\r
26347                     data.filterSelf(function (idx) {\r
26348                         var name = data.getName(idx);\r
26349                         // If in any legend component the status is not selected.\r
26350                         for (var i = 0; i < legendModels.length; i++) {\r
26351                             if (!legendModels[i].isSelected(name)) {\r
26352                                 return false;\r
26353                             }\r
26354                         }\r
26355                         return true;\r
26356                     }, this);\r
26357                 }, this);\r
26358             };\r
26359 \r
26360 \r
26361 /***/ },\r
26362 /* 141 */\r
26363 /***/ function(module, exports, __webpack_require__) {\r
26364 \r
26365         \r
26366 \r
26367             var zrUtil = __webpack_require__(3);\r
26368             var echarts = __webpack_require__(1);\r
26369 \r
26370             __webpack_require__(142);\r
26371             __webpack_require__(143);\r
26372 \r
26373             echarts.registerVisualCoding('chart', zrUtil.curry(\r
26374                 __webpack_require__(103), 'scatter', 'circle', null\r
26375             ));\r
26376             echarts.registerLayout(zrUtil.curry(\r
26377                 __webpack_require__(104), 'scatter'\r
26378             ));\r
26379 \r
26380             // In case developer forget to include grid component\r
26381             __webpack_require__(106);\r
26382 \r
26383 \r
26384 /***/ },\r
26385 /* 142 */\r
26386 /***/ function(module, exports, __webpack_require__) {\r
26387 \r
26388         'use strict';\r
26389 \r
26390 \r
26391             var createListFromArray = __webpack_require__(93);\r
26392             var SeriesModel = __webpack_require__(27);\r
26393 \r
26394             module.exports = SeriesModel.extend({\r
26395 \r
26396                 type: 'series.scatter',\r
26397 \r
26398                 dependencies: ['grid', 'polar'],\r
26399 \r
26400                 getInitialData: function (option, ecModel) {\r
26401                     var list = createListFromArray(option.data, this, ecModel);\r
26402                     return list;\r
26403                 },\r
26404 \r
26405                 defaultOption: {\r
26406                     coordinateSystem: 'cartesian2d',\r
26407                     zlevel: 0,\r
26408                     z: 2,\r
26409                     legendHoverLink: true,\r
26410 \r
26411                     hoverAnimation: true,\r
26412                     // Cartesian coordinate system\r
26413                     xAxisIndex: 0,\r
26414                     yAxisIndex: 0,\r
26415 \r
26416                     // Polar coordinate system\r
26417                     polarIndex: 0,\r
26418 \r
26419                     // Geo coordinate system\r
26420                     geoIndex: 0,\r
26421 \r
26422                     // symbol: null,        // 图形类型\r
26423                     symbolSize: 10,          // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2\r
26424                     // symbolRotate: null,  // 图形旋转控制\r
26425 \r
26426                     large: false,\r
26427                     // Available when large is true\r
26428                     largeThreshold: 2000,\r
26429 \r
26430                     // label: {\r
26431                         // normal: {\r
26432                             // show: false\r
26433                             // distance: 5,\r
26434                             // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
26435                             // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为\r
26436                             //           'inside'|'left'|'right'|'top'|'bottom'\r
26437                             // textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE\r
26438                     //     }\r
26439                     // },\r
26440                     itemStyle: {\r
26441                         normal: {\r
26442                             opacity: 0.8\r
26443                             // color: 各异\r
26444                         }\r
26445                     }\r
26446                 }\r
26447             });\r
26448 \r
26449 \r
26450 /***/ },\r
26451 /* 143 */\r
26452 /***/ function(module, exports, __webpack_require__) {\r
26453 \r
26454         \r
26455 \r
26456             var SymbolDraw = __webpack_require__(98);\r
26457             var LargeSymbolDraw = __webpack_require__(144);\r
26458 \r
26459             __webpack_require__(1).extendChartView({\r
26460 \r
26461                 type: 'scatter',\r
26462 \r
26463                 init: function () {\r
26464                     this._normalSymbolDraw = new SymbolDraw();\r
26465                     this._largeSymbolDraw = new LargeSymbolDraw();\r
26466                 },\r
26467 \r
26468                 render: function (seriesModel, ecModel, api) {\r
26469                     var data = seriesModel.getData();\r
26470                     var largeSymbolDraw = this._largeSymbolDraw;\r
26471                     var normalSymbolDraw = this._normalSymbolDraw;\r
26472                     var group = this.group;\r
26473 \r
26474                     var symbolDraw = seriesModel.get('large') && data.count() > seriesModel.get('largeThreshold')\r
26475                         ? largeSymbolDraw : normalSymbolDraw;\r
26476 \r
26477                     this._symbolDraw = symbolDraw;\r
26478                     symbolDraw.updateData(data);\r
26479                     group.add(symbolDraw.group);\r
26480 \r
26481                     group.remove(\r
26482                         symbolDraw === largeSymbolDraw\r
26483                         ? normalSymbolDraw.group : largeSymbolDraw.group\r
26484                     );\r
26485                 },\r
26486 \r
26487                 updateLayout: function (seriesModel) {\r
26488                     this._symbolDraw.updateLayout(seriesModel);\r
26489                 },\r
26490 \r
26491                 remove: function (ecModel, api) {\r
26492                     this._symbolDraw && this._symbolDraw.remove(api, true);\r
26493                 }\r
26494             });\r
26495 \r
26496 \r
26497 /***/ },\r
26498 /* 144 */\r
26499 /***/ function(module, exports, __webpack_require__) {\r
26500 \r
26501         \r
26502 \r
26503             var graphic = __webpack_require__(42);\r
26504             var symbolUtil = __webpack_require__(100);\r
26505             var zrUtil = __webpack_require__(3);\r
26506 \r
26507             var LargeSymbolPath = graphic.extendShape({\r
26508                 shape: {\r
26509                     points: null,\r
26510                     sizes: null\r
26511                 },\r
26512 \r
26513                 symbolProxy: null,\r
26514 \r
26515                 buildPath: function (path, shape) {\r
26516                     var points = shape.points;\r
26517                     var sizes = shape.sizes;\r
26518 \r
26519                     var symbolProxy = this.symbolProxy;\r
26520                     var symbolProxyShape = symbolProxy.shape;\r
26521                     for (var i = 0; i < points.length; i++) {\r
26522                         var pt = points[i];\r
26523                         var size = sizes[i];\r
26524                         if (size[0] < 4) {\r
26525                             // Optimize for small symbol\r
26526                             path.rect(\r
26527                                 pt[0] - size[0] / 2, pt[1] - size[1] / 2,\r
26528                                 size[0], size[1]\r
26529                             );\r
26530                         }\r
26531                         else {\r
26532                             symbolProxyShape.x = pt[0] - size[0] / 2;\r
26533                             symbolProxyShape.y = pt[1] - size[1] / 2;\r
26534                             symbolProxyShape.width = size[0];\r
26535                             symbolProxyShape.height = size[1];\r
26536 \r
26537                             symbolProxy.buildPath(path, symbolProxyShape);\r
26538                         }\r
26539                     }\r
26540                 }\r
26541             });\r
26542 \r
26543             function LargeSymbolDraw() {\r
26544                 this.group = new graphic.Group();\r
26545 \r
26546                 this._symbolEl = new LargeSymbolPath({\r
26547                     silent: true\r
26548                 });\r
26549             }\r
26550 \r
26551             var largeSymbolProto = LargeSymbolDraw.prototype;\r
26552 \r
26553             /**\r
26554              * Update symbols draw by new data\r
26555              * @param {module:echarts/data/List} data\r
26556              */\r
26557             largeSymbolProto.updateData = function (data) {\r
26558                 this.group.removeAll();\r
26559 \r
26560                 var symbolEl = this._symbolEl;\r
26561 \r
26562                 var seriesModel = data.hostModel;\r
26563 \r
26564                 symbolEl.setShape({\r
26565                     points: data.mapArray(data.getItemLayout),\r
26566                     sizes: data.mapArray(\r
26567                         function (idx) {\r
26568                             var size = data.getItemVisual(idx, 'symbolSize');\r
26569                             if (!zrUtil.isArray(size)) {\r
26570                                 size = [size, size];\r
26571                             }\r
26572                             return size;\r
26573                         }\r
26574                     )\r
26575                 });\r
26576 \r
26577                 // Create symbolProxy to build path for each data\r
26578                 symbolEl.symbolProxy = symbolUtil.createSymbol(\r
26579                     data.getVisual('symbol'), 0, 0, 0, 0\r
26580                 );\r
26581                 // Use symbolProxy setColor method\r
26582                 symbolEl.setColor = symbolEl.symbolProxy.setColor;\r
26583 \r
26584                 symbolEl.setStyle(\r
26585                     seriesModel.getModel('itemStyle.normal').getItemStyle(['color'])\r
26586                 );\r
26587 \r
26588                 var visualColor = data.getVisual('color');\r
26589                 if (visualColor) {\r
26590                     symbolEl.setColor(visualColor);\r
26591                 }\r
26592 \r
26593                 // Add back\r
26594                 this.group.add(this._symbolEl);\r
26595             };\r
26596 \r
26597             largeSymbolProto.updateLayout = function (seriesModel) {\r
26598                 var data = seriesModel.getData();\r
26599                 this._symbolEl.setShape({\r
26600                     points: data.mapArray(data.getItemLayout)\r
26601                 });\r
26602             };\r
26603 \r
26604             largeSymbolProto.remove = function () {\r
26605                 this.group.removeAll();\r
26606             };\r
26607 \r
26608             module.exports = LargeSymbolDraw;\r
26609 \r
26610 \r
26611 /***/ },\r
26612 /* 145 */\r
26613 /***/ function(module, exports, __webpack_require__) {\r
26614 \r
26615         \r
26616 \r
26617             var zrUtil = __webpack_require__(3);\r
26618             var echarts = __webpack_require__(1);\r
26619 \r
26620             // Must use radar component\r
26621             __webpack_require__(146);\r
26622 \r
26623             __webpack_require__(151);\r
26624             __webpack_require__(152);\r
26625 \r
26626             echarts.registerVisualCoding(\r
26627                 'chart',  zrUtil.curry(__webpack_require__(137), 'radar')\r
26628             );\r
26629             echarts.registerVisualCoding('chart', zrUtil.curry(\r
26630                 __webpack_require__(103), 'radar', 'circle', null\r
26631             ));\r
26632             echarts.registerLayout(__webpack_require__(153));\r
26633 \r
26634             echarts.registerProcessor(\r
26635                 'filter', zrUtil.curry(__webpack_require__(140), 'radar')\r
26636             );\r
26637 \r
26638             echarts.registerPreprocessor(__webpack_require__(154));\r
26639 \r
26640 \r
26641 /***/ },\r
26642 /* 146 */\r
26643 /***/ function(module, exports, __webpack_require__) {\r
26644 \r
26645         \r
26646 \r
26647             __webpack_require__(147);\r
26648             __webpack_require__(149);\r
26649 \r
26650             __webpack_require__(150);\r
26651 \r
26652 \r
26653 /***/ },\r
26654 /* 147 */\r
26655 /***/ function(module, exports, __webpack_require__) {\r
26656 \r
26657         // TODO clockwise\r
26658 \r
26659 \r
26660             var zrUtil = __webpack_require__(3);\r
26661             var IndicatorAxis = __webpack_require__(148);\r
26662             var IntervalScale = __webpack_require__(111);\r
26663             var numberUtil = __webpack_require__(7);\r
26664             var axisHelper = __webpack_require__(108);\r
26665 \r
26666             function Radar(radarModel, ecModel, api) {\r
26667 \r
26668                 this._model = radarModel;\r
26669                 /**\r
26670                  * Radar dimensions\r
26671                  * @type {Array.<string>}\r
26672                  */\r
26673                 this.dimensions = [];\r
26674 \r
26675                 this._indicatorAxes = zrUtil.map(radarModel.getIndicatorModels(), function (indicatorModel, idx) {\r
26676                     var dim = 'indicator_' + idx;\r
26677                     var indicatorAxis = new IndicatorAxis(dim, new IntervalScale());\r
26678                     indicatorAxis.name = indicatorModel.get('name');\r
26679                     // Inject model and axis\r
26680                     indicatorAxis.model = indicatorModel;\r
26681                     indicatorModel.axis = indicatorAxis;\r
26682                     this.dimensions.push(dim);\r
26683                     return indicatorAxis;\r
26684                 }, this);\r
26685 \r
26686                 this.resize(radarModel, api);\r
26687 \r
26688                 /**\r
26689                  * @type {number}\r
26690                  * @readOnly\r
26691                  */\r
26692                 this.cx;\r
26693                 /**\r
26694                  * @type {number}\r
26695                  * @readOnly\r
26696                  */\r
26697                 this.cy;\r
26698                 /**\r
26699                  * @type {number}\r
26700                  * @readOnly\r
26701                  */\r
26702                 this.r;\r
26703                 /**\r
26704                  * @type {number}\r
26705                  * @readOnly\r
26706                  */\r
26707                 this.startAngle;\r
26708             }\r
26709 \r
26710             Radar.prototype.getIndicatorAxes = function () {\r
26711                 return this._indicatorAxes;\r
26712             };\r
26713 \r
26714             Radar.prototype.dataToPoint = function (value, indicatorIndex) {\r
26715                 var indicatorAxis = this._indicatorAxes[indicatorIndex];\r
26716 \r
26717                 return this.coordToPoint(indicatorAxis.dataToCoord(value), indicatorIndex);\r
26718             };\r
26719 \r
26720             Radar.prototype.coordToPoint = function (coord, indicatorIndex) {\r
26721                 var indicatorAxis = this._indicatorAxes[indicatorIndex];\r
26722                 var angle = indicatorAxis.angle;\r
26723                 var x = this.cx + coord * Math.cos(angle);\r
26724                 var y = this.cy - coord * Math.sin(angle);\r
26725                 return [x, y];\r
26726             };\r
26727 \r
26728             Radar.prototype.pointToData = function (pt) {\r
26729                 var dx = pt[0] - this.cx;\r
26730                 var dy = pt[1] - this.cy;\r
26731                 var radius = Math.sqrt(dx * dx + dy * dy);\r
26732                 dx /= radius;\r
26733                 dy /= radius;\r
26734 \r
26735                 var radian = Math.atan2(-dy, dx);\r
26736 \r
26737                 // Find the closest angle\r
26738                 // FIXME index can calculated directly\r
26739                 var minRadianDiff = Infinity;\r
26740                 var closestAxis;\r
26741                 var closestAxisIdx = -1;\r
26742                 for (var i = 0; i < this._indicatorAxes.length; i++) {\r
26743                     var indicatorAxis = this._indicatorAxes[i];\r
26744                     var diff = Math.abs(radian - indicatorAxis.angle);\r
26745                     if (diff < minRadianDiff) {\r
26746                         closestAxis = indicatorAxis;\r
26747                         closestAxisIdx = i;\r
26748                         minRadianDiff = diff;\r
26749                     }\r
26750                 }\r
26751 \r
26752                 return [closestAxisIdx, +(closestAxis && closestAxis.coodToData(radius))];\r
26753             };\r
26754 \r
26755             Radar.prototype.resize = function (radarModel, api) {\r
26756                 var center = radarModel.get('center');\r
26757                 var viewWidth = api.getWidth();\r
26758                 var viewHeight = api.getHeight();\r
26759                 var viewSize = Math.min(viewWidth, viewHeight) / 2;\r
26760                 this.cx = numberUtil.parsePercent(center[0], viewWidth);\r
26761                 this.cy = numberUtil.parsePercent(center[1], viewHeight);\r
26762 \r
26763                 this.startAngle = radarModel.get('startAngle') * Math.PI / 180;\r
26764 \r
26765                 this.r = numberUtil.parsePercent(radarModel.get('radius'), viewSize);\r
26766 \r
26767                 zrUtil.each(this._indicatorAxes, function (indicatorAxis, idx) {\r
26768                     indicatorAxis.setExtent(0, this.r);\r
26769                     var angle = (this.startAngle + idx * Math.PI * 2 / this._indicatorAxes.length);\r
26770                     // Normalize to [-PI, PI]\r
26771                     angle = Math.atan2(Math.sin(angle), Math.cos(angle));\r
26772                     indicatorAxis.angle = angle;\r
26773                 }, this);\r
26774             };\r
26775 \r
26776             Radar.prototype.update = function (ecModel, api) {\r
26777                 var indicatorAxes = this._indicatorAxes;\r
26778                 var radarModel = this._model;\r
26779                 zrUtil.each(indicatorAxes, function (indicatorAxis) {\r
26780                     indicatorAxis.scale.setExtent(Infinity, -Infinity);\r
26781                 });\r
26782                 ecModel.eachSeriesByType('radar', function (radarSeries, idx) {\r
26783                     if (radarSeries.get('coordinateSystem') !== 'radar'\r
26784                         || ecModel.getComponent('radar', radarSeries.get('radarIndex')) !== radarModel\r
26785                     ) {\r
26786                         return;\r
26787                     }\r
26788                     var data = radarSeries.getData();\r
26789                     zrUtil.each(indicatorAxes, function (indicatorAxis) {\r
26790                         indicatorAxis.scale.unionExtent(data.getDataExtent(indicatorAxis.dim));\r
26791                     });\r
26792                 }, this);\r
26793 \r
26794                 var splitNumber = radarModel.get('splitNumber');\r
26795 \r
26796                 function increaseInterval(interval) {\r
26797                     var exp10 = Math.pow(10, Math.floor(Math.log(interval) / Math.LN10));\r
26798                     // Increase interval\r
26799                     var f = interval / exp10;\r
26800                     if (f === 2) {\r
26801                         f = 5;\r
26802                     }\r
26803                     else { // f is 2 or 5\r
26804                         f *= 2;\r
26805                     }\r
26806                     return f * exp10;\r
26807                 }\r
26808                 // Force all the axis fixing the maxSplitNumber.\r
26809                 zrUtil.each(indicatorAxes, function (indicatorAxis, idx) {\r
26810                     var rawExtent = axisHelper.getScaleExtent(indicatorAxis, indicatorAxis.model);\r
26811                     axisHelper.niceScaleExtent(indicatorAxis, indicatorAxis.model);\r
26812 \r
26813                     var axisModel = indicatorAxis.model;\r
26814                     var scale = indicatorAxis.scale;\r
26815                     var fixedMin = axisModel.get('min');\r
26816                     var fixedMax = axisModel.get('max');\r
26817                     var interval = scale.getInterval();\r
26818 \r
26819                     if (fixedMin != null && fixedMax != null) {\r
26820                         // User set min, max, divide to get new interval\r
26821                         // FIXME precision\r
26822                         scale.setInterval(\r
26823                             (fixedMax - fixedMin) / splitNumber\r
26824                         );\r
26825                     }\r
26826                     else if (fixedMin != null) {\r
26827                         var max;\r
26828                         // User set min, expand extent on the other side\r
26829                         do {\r
26830                             max = fixedMin + interval * splitNumber;\r
26831                             scale.setExtent(+fixedMin, max);\r
26832                             // Interval must been set after extent\r
26833                             // FIXME\r
26834                             scale.setInterval(interval);\r
26835 \r
26836                             interval = increaseInterval(interval);\r
26837                         } while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1]));\r
26838                     }\r
26839                     else if (fixedMax != null) {\r
26840                         var min;\r
26841                         // User set min, expand extent on the other side\r
26842                         do {\r
26843                             min = fixedMax - interval * splitNumber;\r
26844                             scale.setExtent(min, +fixedMax);\r
26845                             scale.setInterval(interval);\r
26846                             interval = increaseInterval(interval);\r
26847                         } while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0]));\r
26848                     }\r
26849                     else {\r
26850                         var nicedSplitNumber = scale.getTicks().length - 1;\r
26851                         if (nicedSplitNumber > splitNumber) {\r
26852                             interval = increaseInterval(interval);\r
26853                         }\r
26854                         // PENDING\r
26855                         var center = Math.round((rawExtent[0] + rawExtent[1]) / 2 / interval) * interval;\r
26856                         var halfSplitNumber = Math.round(splitNumber / 2);\r
26857                         scale.setExtent(\r
26858                             numberUtil.round(center - halfSplitNumber * interval),\r
26859                             numberUtil.round(center + (splitNumber - halfSplitNumber) * interval)\r
26860                         );\r
26861                         scale.setInterval(interval);\r
26862                     }\r
26863                 });\r
26864             };\r
26865 \r
26866             /**\r
26867              * Radar dimensions is based on the data\r
26868              * @type {Array}\r
26869              */\r
26870             Radar.dimensions = [];\r
26871 \r
26872             Radar.create = function (ecModel, api) {\r
26873                 var radarList = [];\r
26874                 ecModel.eachComponent('radar', function (radarModel) {\r
26875                     var radar = new Radar(radarModel, ecModel, api);\r
26876                     radarList.push(radar);\r
26877                     radarModel.coordinateSystem = radar;\r
26878                 });\r
26879                 ecModel.eachSeriesByType('radar', function (radarSeries) {\r
26880                     if (radarSeries.get('coordinateSystem') === 'radar') {\r
26881                         // Inject coordinate system\r
26882                         radarSeries.coordinateSystem = radarList[radarSeries.get('radarIndex') || 0];\r
26883                     }\r
26884                 });\r
26885                 return radarList;\r
26886             };\r
26887 \r
26888             __webpack_require__(25).register('radar', Radar);\r
26889             module.exports = Radar;\r
26890 \r
26891 \r
26892 /***/ },\r
26893 /* 148 */\r
26894 /***/ function(module, exports, __webpack_require__) {\r
26895 \r
26896         \r
26897 \r
26898             var zrUtil = __webpack_require__(3);\r
26899             var Axis = __webpack_require__(117);\r
26900 \r
26901             function IndicatorAxis(dim, scale, radiusExtent) {\r
26902                 Axis.call(this, dim, scale, radiusExtent);\r
26903 \r
26904                 /**\r
26905                  * Axis type\r
26906                  *  - 'category'\r
26907                  *  - 'value'\r
26908                  *  - 'time'\r
26909                  *  - 'log'\r
26910                  * @type {string}\r
26911                  */\r
26912                 this.type = 'value';\r
26913 \r
26914                 this.angle = 0;\r
26915 \r
26916                 /**\r
26917                  * Indicator name\r
26918                  * @type {string}\r
26919                  */\r
26920                 this.name = '';\r
26921                 /**\r
26922                  * @type {module:echarts/model/Model}\r
26923                  */\r
26924                 this.model;\r
26925             }\r
26926 \r
26927             zrUtil.inherits(IndicatorAxis, Axis);\r
26928 \r
26929             module.exports = IndicatorAxis;\r
26930 \r
26931 \r
26932 /***/ },\r
26933 /* 149 */\r
26934 /***/ function(module, exports, __webpack_require__) {\r
26935 \r
26936         \r
26937 \r
26938 \r
26939             var axisDefault = __webpack_require__(122);\r
26940             var valueAxisDefault = axisDefault.valueAxis;\r
26941             var Model = __webpack_require__(8);\r
26942             var zrUtil = __webpack_require__(3);\r
26943 \r
26944             var axisModelCommonMixin = __webpack_require__(123);\r
26945 \r
26946             function defaultsShow(opt, show) {\r
26947                 return zrUtil.defaults({\r
26948                     show: show\r
26949                 }, opt);\r
26950             }\r
26951 \r
26952             var RadarModel = __webpack_require__(1).extendComponentModel({\r
26953 \r
26954                 type: 'radar',\r
26955 \r
26956                 optionUpdated: function () {\r
26957                     var boundaryGap = this.get('boundaryGap');\r
26958                     var splitNumber = this.get('splitNumber');\r
26959                     var scale = this.get('scale');\r
26960                     var axisLine = this.get('axisLine');\r
26961                     var axisTick = this.get('axisTick');\r
26962                     var axisLabel = this.get('axisLabel');\r
26963                     var nameTextStyle = this.get('name.textStyle');\r
26964                     var showName = this.get('name.show');\r
26965                     var nameFormatter = this.get('name.formatter');\r
26966                     var nameGap = this.get('nameGap');\r
26967                     var indicatorModels = zrUtil.map(this.get('indicator') || [], function (indicatorOpt) {\r
26968                         // PENDING\r
26969                         if (indicatorOpt.max != null && indicatorOpt.max > 0) {\r
26970                             indicatorOpt.min = 0;\r
26971                         }\r
26972                         else if (indicatorOpt.min != null && indicatorOpt.min < 0) {\r
26973                             indicatorOpt.max = 0;\r
26974                         }\r
26975                         // Use same configuration\r
26976                         indicatorOpt = zrUtil.merge(zrUtil.clone(indicatorOpt), {\r
26977                             boundaryGap: boundaryGap,\r
26978                             splitNumber: splitNumber,\r
26979                             scale: scale,\r
26980                             axisLine: axisLine,\r
26981                             axisTick: axisTick,\r
26982                             axisLabel: axisLabel,\r
26983                             // Competitable with 2 and use text\r
26984                             name: indicatorOpt.text,\r
26985                             nameLocation: 'end',\r
26986                             nameGap: nameGap,\r
26987                             // min: 0,\r
26988                             nameTextStyle: nameTextStyle\r
26989                         }, false);\r
26990                         if (!showName) {\r
26991                             indicatorOpt.name = '';\r
26992                         }\r
26993                         if (typeof nameFormatter === 'string') {\r
26994                             indicatorOpt.name = nameFormatter.replace('{value}', indicatorOpt.name);\r
26995                         }\r
26996                         else if (typeof nameFormatter === 'function') {\r
26997                             indicatorOpt.name = nameFormatter(\r
26998                                 indicatorOpt.name, indicatorOpt\r
26999                             );\r
27000                         }\r
27001                         return zrUtil.extend(\r
27002                             new Model(indicatorOpt, null, this.ecModel),\r
27003                             axisModelCommonMixin\r
27004                         );\r
27005                     }, this);\r
27006                     this.getIndicatorModels = function () {\r
27007                         return indicatorModels;\r
27008                     };\r
27009                 },\r
27010 \r
27011                 defaultOption: {\r
27012 \r
27013                     zlevel: 0,\r
27014 \r
27015                     z: 0,\r
27016 \r
27017                     center: ['50%', '50%'],\r
27018 \r
27019                     radius: '75%',\r
27020 \r
27021                     startAngle: 90,\r
27022 \r
27023                     name: {\r
27024                         show: true\r
27025                         // formatter: null\r
27026                         // textStyle: {}\r
27027                     },\r
27028 \r
27029                     boundaryGap: [0, 0],\r
27030 \r
27031                     splitNumber: 5,\r
27032 \r
27033                     nameGap: 15,\r
27034 \r
27035                     scale: false,\r
27036 \r
27037                     // Polygon or circle\r
27038                     shape: 'polygon',\r
27039 \r
27040                     axisLine: zrUtil.merge(\r
27041                         {\r
27042                             lineStyle: {\r
27043                                 color: '#bbb'\r
27044                             }\r
27045                         },\r
27046                         valueAxisDefault.axisLine\r
27047                     ),\r
27048                     axisLabel: defaultsShow(valueAxisDefault.axisLabel, false),\r
27049                     axisTick: defaultsShow(valueAxisDefault.axisTick, false),\r
27050                     splitLine: defaultsShow(valueAxisDefault.splitLine, true),\r
27051                     splitArea: defaultsShow(valueAxisDefault.splitArea, true),\r
27052 \r
27053                     // {text, min, max}\r
27054                     indicator: []\r
27055                 }\r
27056             });\r
27057 \r
27058             module.exports = RadarModel;\r
27059 \r
27060 \r
27061 /***/ },\r
27062 /* 150 */\r
27063 /***/ function(module, exports, __webpack_require__) {\r
27064 \r
27065         \r
27066 \r
27067             var AxisBuilder = __webpack_require__(126);\r
27068             var zrUtil = __webpack_require__(3);\r
27069             var graphic = __webpack_require__(42);\r
27070 \r
27071             var axisBuilderAttrs = [\r
27072                 'axisLine', 'axisLabel', 'axisTick', 'axisName'\r
27073             ];\r
27074 \r
27075             module.exports = __webpack_require__(1).extendComponentView({\r
27076 \r
27077                 type: 'radar',\r
27078 \r
27079                 render: function (radarModel, ecModel, api) {\r
27080                     var group = this.group;\r
27081                     group.removeAll();\r
27082 \r
27083                     this._buildAxes(radarModel);\r
27084                     this._buildSplitLineAndArea(radarModel);\r
27085                 },\r
27086 \r
27087                 _buildAxes: function (radarModel) {\r
27088                     var radar = radarModel.coordinateSystem;\r
27089                     var indicatorAxes = radar.getIndicatorAxes();\r
27090                     var axisBuilders = zrUtil.map(indicatorAxes, function (indicatorAxis) {\r
27091                         var axisBuilder = new AxisBuilder(indicatorAxis.model, {\r
27092                             position: [radar.cx, radar.cy],\r
27093                             rotation: indicatorAxis.angle,\r
27094                             labelDirection: -1,\r
27095                             tickDirection: -1,\r
27096                             nameDirection: 1\r
27097                         });\r
27098                         return axisBuilder;\r
27099                     });\r
27100 \r
27101                     zrUtil.each(axisBuilders, function (axisBuilder) {\r
27102                         zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);\r
27103                         this.group.add(axisBuilder.getGroup());\r
27104                     }, this);\r
27105                 },\r
27106 \r
27107                 _buildSplitLineAndArea: function (radarModel) {\r
27108                     var radar = radarModel.coordinateSystem;\r
27109                     var splitNumber = radarModel.get('splitNumber');\r
27110                     var indicatorAxes = radar.getIndicatorAxes();\r
27111                     if (!indicatorAxes.length) {\r
27112                         return;\r
27113                     }\r
27114                     var shape = radarModel.get('shape');\r
27115                     var splitLineModel = radarModel.getModel('splitLine');\r
27116                     var splitAreaModel = radarModel.getModel('splitArea');\r
27117                     var lineStyleModel = splitLineModel.getModel('lineStyle');\r
27118                     var areaStyleModel = splitAreaModel.getModel('areaStyle');\r
27119 \r
27120                     var showSplitLine = splitLineModel.get('show');\r
27121                     var showSplitArea = splitAreaModel.get('show');\r
27122                     var splitLineColors = lineStyleModel.get('color');\r
27123                     var splitAreaColors = areaStyleModel.get('color');\r
27124 \r
27125                     splitLineColors = zrUtil.isArray(splitLineColors) ? splitLineColors : [splitLineColors];\r
27126                     splitAreaColors = zrUtil.isArray(splitAreaColors) ? splitAreaColors : [splitAreaColors];\r
27127 \r
27128                     var splitLines = [];\r
27129                     var splitAreas = [];\r
27130 \r
27131                     function getColorIndex(areaOrLine, areaOrLineColorList, idx) {\r
27132                         var colorIndex = idx % areaOrLineColorList.length;\r
27133                         areaOrLine[colorIndex] = areaOrLine[colorIndex] || [];\r
27134                         return colorIndex;\r
27135                     }\r
27136 \r
27137                     if (shape === 'circle') {\r
27138                         var ticksRadius = indicatorAxes[0].getTicksCoords();\r
27139                         var cx = radar.cx;\r
27140                         var cy = radar.cy;\r
27141                         for (var i = 0; i < ticksRadius.length; i++) {\r
27142                             if (showSplitLine) {\r
27143                                 var colorIndex = getColorIndex(splitLines, splitLineColors, i);\r
27144                                 splitLines[colorIndex].push(new graphic.Circle({\r
27145                                     shape: {\r
27146                                         cx: cx,\r
27147                                         cy: cy,\r
27148                                         r: ticksRadius[i]\r
27149                                     }\r
27150                                 }));\r
27151                             }\r
27152                             if (showSplitArea && i < ticksRadius.length - 1) {\r
27153                                 var colorIndex = getColorIndex(splitAreas, splitAreaColors, i);\r
27154                                 splitAreas[colorIndex].push(new graphic.Ring({\r
27155                                     shape: {\r
27156                                         cx: cx,\r
27157                                         cy: cy,\r
27158                                         r0: ticksRadius[i],\r
27159                                         r: ticksRadius[i + 1]\r
27160                                     }\r
27161                                 }));\r
27162                             }\r
27163                         }\r
27164                     }\r
27165                     // Polyyon\r
27166                     else {\r
27167                         var axesTicksPoints = zrUtil.map(indicatorAxes, function (indicatorAxis, idx) {\r
27168                             var ticksCoords = indicatorAxis.getTicksCoords();\r
27169                             return zrUtil.map(ticksCoords, function (tickCoord) {\r
27170                                 return radar.coordToPoint(tickCoord, idx);\r
27171                             });\r
27172                         });\r
27173 \r
27174                         var prevPoints = [];\r
27175                         for (var i = 0; i <= splitNumber; i++) {\r
27176                             var points = [];\r
27177                             for (var j = 0; j < indicatorAxes.length; j++) {\r
27178                                 points.push(axesTicksPoints[j][i]);\r
27179                             }\r
27180                             // Close\r
27181                             points.push(points[0].slice());\r
27182                             if (showSplitLine) {\r
27183                                 var colorIndex = getColorIndex(splitLines, splitLineColors, i);\r
27184                                 splitLines[colorIndex].push(new graphic.Polyline({\r
27185                                     shape: {\r
27186                                         points: points\r
27187                                     }\r
27188                                 }));\r
27189                             }\r
27190                             if (showSplitArea && prevPoints) {\r
27191                                 var colorIndex = getColorIndex(splitAreas, splitAreaColors, i - 1);\r
27192                                 splitAreas[colorIndex].push(new graphic.Polygon({\r
27193                                     shape: {\r
27194                                         points: points.concat(prevPoints)\r
27195                                     }\r
27196                                 }));\r
27197                             }\r
27198                             prevPoints = points.slice().reverse();\r
27199                         }\r
27200                     }\r
27201 \r
27202                     var lineStyle = lineStyleModel.getLineStyle();\r
27203                     var areaStyle = areaStyleModel.getAreaStyle();\r
27204                     // Add splitArea before splitLine\r
27205                     zrUtil.each(splitAreas, function (splitAreas, idx) {\r
27206                         this.group.add(graphic.mergePath(\r
27207                             splitAreas, {\r
27208                                 style: zrUtil.defaults({\r
27209                                     stroke: 'none',\r
27210                                     fill: splitAreaColors[idx % splitAreaColors.length]\r
27211                                 }, areaStyle),\r
27212                                 silent: true\r
27213                             }\r
27214                         ));\r
27215                     }, this);\r
27216 \r
27217                     zrUtil.each(splitLines, function (splitLines, idx) {\r
27218                         this.group.add(graphic.mergePath(\r
27219                             splitLines, {\r
27220                                 style: zrUtil.defaults({\r
27221                                     fill: 'none',\r
27222                                     stroke: splitLineColors[idx % splitLineColors.length]\r
27223                                 }, lineStyle),\r
27224                                 silent: true\r
27225                             }\r
27226                         ));\r
27227                     }, this);\r
27228 \r
27229                 }\r
27230             });\r
27231 \r
27232 \r
27233 /***/ },\r
27234 /* 151 */\r
27235 /***/ function(module, exports, __webpack_require__) {\r
27236 \r
27237         'use strict';\r
27238 \r
27239 \r
27240             var SeriesModel = __webpack_require__(27);\r
27241             var List = __webpack_require__(94);\r
27242             var completeDimensions = __webpack_require__(96);\r
27243             var zrUtil = __webpack_require__(3);\r
27244             var formatUtil = __webpack_require__(6);\r
27245 \r
27246             var RadarSeries = SeriesModel.extend({\r
27247 \r
27248                 type: 'series.radar',\r
27249 \r
27250                 dependencies: ['radar'],\r
27251 \r
27252 \r
27253                 // Overwrite\r
27254                 init: function (option) {\r
27255                     RadarSeries.superApply(this, 'init', arguments);\r
27256 \r
27257                     // Enable legend selection for each data item\r
27258                     // Use a function instead of direct access because data reference may changed\r
27259                     this.legendDataProvider = function () {\r
27260                         return this._dataBeforeProcessed;\r
27261                     };\r
27262                 },\r
27263 \r
27264                 getInitialData: function (option, ecModel) {\r
27265                     var data = option.data || [];\r
27266                     var dimensions = completeDimensions(\r
27267                         [], data, [], 'indicator_'\r
27268                     );\r
27269                     var list = new List(dimensions, this);\r
27270                     list.initData(data);\r
27271                     return list;\r
27272                 },\r
27273 \r
27274                 formatTooltip: function (dataIndex) {\r
27275                     var value = this.getRawValue(dataIndex);\r
27276                     var coordSys = this.coordinateSystem;\r
27277                     var indicatorAxes = coordSys.getIndicatorAxes();\r
27278                     return this._data.getName(dataIndex) + '<br />'\r
27279                         + zrUtil.map(indicatorAxes, function (axis, idx) {\r
27280                             return axis.name + ' : ' + value[idx];\r
27281                         }).join('<br />');\r
27282                 },\r
27283 \r
27284                 getFormattedLabel: function (dataIndex, status, formatter, indicatorIndex) {\r
27285                     status = status || 'normal';\r
27286                     var data = this.getData();\r
27287                     var itemModel = data.getItemModel(dataIndex);\r
27288 \r
27289                     var params = this.getDataParams(dataIndex);\r
27290                     if (formatter == null) {\r
27291                         formatter = itemModel.get(['label', status, 'formatter']);\r
27292                     }\r
27293                     // Get value of specified indicator\r
27294                     params.value = params.value[indicatorIndex || 0];\r
27295                     if (typeof formatter === 'function') {\r
27296                         params.status = status;\r
27297                         return formatter(params);\r
27298                     }\r
27299                     else if (typeof formatter === 'string') {\r
27300                         return formatUtil.formatTpl(formatter, params);\r
27301                     }\r
27302                 },\r
27303 \r
27304                 defaultOption: {\r
27305                     zlevel: 0,\r
27306                     z: 2,\r
27307                     coordinateSystem: 'radar',\r
27308                     legendHoverLink: true,\r
27309                     radarIndex: 0,\r
27310                     lineStyle: {\r
27311                         normal: {\r
27312                             width: 2,\r
27313                             type: 'solid'\r
27314                         }\r
27315                     },\r
27316                     label: {\r
27317                         normal: {\r
27318                             position: 'top'\r
27319                         }\r
27320                     },\r
27321                     // areaStyle: {\r
27322                     // },\r
27323                     // itemStyle: {}\r
27324                     symbol: 'emptyCircle',\r
27325                     symbolSize: 4\r
27326                     // symbolRotate: null\r
27327                 }\r
27328             });\r
27329 \r
27330             module.exports = RadarSeries;\r
27331 \r
27332 \r
27333 /***/ },\r
27334 /* 152 */\r
27335 /***/ function(module, exports, __webpack_require__) {\r
27336 \r
27337         \r
27338 \r
27339             var graphic = __webpack_require__(42);\r
27340             var zrUtil = __webpack_require__(3);\r
27341             var symbolUtil = __webpack_require__(100);\r
27342 \r
27343             function normalizeSymbolSize(symbolSize) {\r
27344                 if (!zrUtil.isArray(symbolSize)) {\r
27345                     symbolSize = [+symbolSize, +symbolSize];\r
27346                 }\r
27347                 return symbolSize;\r
27348             }\r
27349             module.exports = __webpack_require__(1).extendChartView({\r
27350                 type: 'radar',\r
27351 \r
27352                 render: function (seriesModel, ecModel, api) {\r
27353                     var polar = seriesModel.coordinateSystem;\r
27354                     var group = this.group;\r
27355 \r
27356                     var data = seriesModel.getData();\r
27357                     var oldData = this._data;\r
27358 \r
27359                     function createSymbol(data, idx) {\r
27360                         var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';\r
27361                         var color = data.getItemVisual(idx, 'color');\r
27362                         if (symbolType === 'none') {\r
27363                             return;\r
27364                         }\r
27365                         var symbolPath = symbolUtil.createSymbol(\r
27366                             symbolType, -0.5, -0.5, 1, 1, color\r
27367                         );\r
27368                         symbolPath.attr({\r
27369                             style: {\r
27370                                 strokeNoScale: true\r
27371                             },\r
27372                             z2: 100,\r
27373                             scale: normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'))\r
27374                         });\r
27375                         return symbolPath;\r
27376                     }\r
27377 \r
27378                     function updateSymbols(oldPoints, newPoints, symbolGroup, data, idx, isInit) {\r
27379                         // Simply rerender all\r
27380                         symbolGroup.removeAll();\r
27381                         for (var i = 0; i < newPoints.length - 1; i++) {\r
27382                             var symbolPath = createSymbol(data, idx);\r
27383                             if (symbolPath) {\r
27384                                 symbolPath.__dimIdx = i;\r
27385                                 if (oldPoints[i]) {\r
27386                                     symbolPath.attr('position', oldPoints[i]);\r
27387                                     graphic[isInit ? 'initProps' : 'updateProps'](\r
27388                                         symbolPath, {\r
27389                                             position: newPoints[i]\r
27390                                         }, seriesModel\r
27391                                     );\r
27392                                 }\r
27393                                 else {\r
27394                                     symbolPath.attr('position', newPoints[i]);\r
27395                                 }\r
27396                                 symbolGroup.add(symbolPath);\r
27397                             }\r
27398                         }\r
27399                     }\r
27400 \r
27401                     function getInitialPoints(points) {\r
27402                         return zrUtil.map(points, function (pt) {\r
27403                             return [polar.cx, polar.cy];\r
27404                         });\r
27405                     }\r
27406                     data.diff(oldData)\r
27407                         .add(function (idx) {\r
27408                             var points = data.getItemLayout(idx);\r
27409                             if (!points) {\r
27410                                 return;\r
27411                             }\r
27412                             var polygon = new graphic.Polygon();\r
27413                             var polyline = new graphic.Polyline();\r
27414                             var target = {\r
27415                                 shape: {\r
27416                                     points: points\r
27417                                 }\r
27418                             };\r
27419                             polygon.shape.points = getInitialPoints(points);\r
27420                             polyline.shape.points = getInitialPoints(points);\r
27421                             graphic.initProps(polygon, target, seriesModel);\r
27422                             graphic.initProps(polyline, target, seriesModel);\r
27423 \r
27424                             var itemGroup = new graphic.Group();\r
27425                             var symbolGroup = new graphic.Group();\r
27426                             itemGroup.add(polyline);\r
27427                             itemGroup.add(polygon);\r
27428                             itemGroup.add(symbolGroup);\r
27429 \r
27430                             updateSymbols(\r
27431                                 polyline.shape.points, points, symbolGroup, data, idx, true\r
27432                             );\r
27433 \r
27434                             data.setItemGraphicEl(idx, itemGroup);\r
27435                         })\r
27436                         .update(function (newIdx, oldIdx) {\r
27437                             var itemGroup = oldData.getItemGraphicEl(oldIdx);\r
27438                             var polyline = itemGroup.childAt(0);\r
27439                             var polygon = itemGroup.childAt(1);\r
27440                             var symbolGroup = itemGroup.childAt(2);\r
27441                             var target = {\r
27442                                 shape: {\r
27443                                     points: data.getItemLayout(newIdx)\r
27444                                 }\r
27445                             };\r
27446                             if (!target.shape.points) {\r
27447                                 return;\r
27448                             }\r
27449                             updateSymbols(\r
27450                                 polyline.shape.points, target.shape.points, symbolGroup, data, newIdx, false\r
27451                             );\r
27452 \r
27453                             graphic.updateProps(polyline, target, seriesModel);\r
27454                             graphic.updateProps(polygon, target, seriesModel);\r
27455 \r
27456                             data.setItemGraphicEl(newIdx, itemGroup);\r
27457                         })\r
27458                         .remove(function (idx) {\r
27459                             group.remove(oldData.getItemGraphicEl(idx));\r
27460                         })\r
27461                         .execute();\r
27462 \r
27463                     data.eachItemGraphicEl(function (itemGroup, idx) {\r
27464                         var itemModel = data.getItemModel(idx);\r
27465                         var polyline = itemGroup.childAt(0);\r
27466                         var polygon = itemGroup.childAt(1);\r
27467                         var symbolGroup = itemGroup.childAt(2);\r
27468                         var color = data.getItemVisual(idx, 'color');\r
27469 \r
27470                         group.add(itemGroup);\r
27471 \r
27472                         polyline.setStyle(\r
27473                             zrUtil.extend(\r
27474                                 itemModel.getModel('lineStyle.normal').getLineStyle(),\r
27475                                 {\r
27476                                     stroke: color\r
27477                                 }\r
27478                             )\r
27479                         );\r
27480                         polyline.hoverStyle = itemModel.getModel('lineStyle.emphasis').getLineStyle();\r
27481 \r
27482                         var areaStyleModel = itemModel.getModel('areaStyle.normal');\r
27483                         var hoverAreaStyleModel = itemModel.getModel('areaStyle.emphasis');\r
27484                         var polygonIgnore = areaStyleModel.isEmpty() && areaStyleModel.parentModel.isEmpty();\r
27485                         var hoverPolygonIgnore = hoverAreaStyleModel.isEmpty() && hoverAreaStyleModel.parentModel.isEmpty();\r
27486 \r
27487                         hoverPolygonIgnore = hoverPolygonIgnore && polygonIgnore;\r
27488                         polygon.ignore = polygonIgnore;\r
27489 \r
27490                         polygon.setStyle(\r
27491                             zrUtil.defaults(\r
27492                                 areaStyleModel.getAreaStyle(),\r
27493                                 {\r
27494                                     fill: color,\r
27495                                     opacity: 0.7\r
27496                                 }\r
27497                             )\r
27498                         );\r
27499                         polygon.hoverStyle = hoverAreaStyleModel.getAreaStyle();\r
27500 \r
27501                         var itemStyle = itemModel.getModel('itemStyle.normal').getItemStyle(['color']);\r
27502                         var itemHoverStyle = itemModel.getModel('itemStyle.emphasis').getItemStyle();\r
27503                         var labelModel = itemModel.getModel('label.normal');\r
27504                         var labelHoverModel = itemModel.getModel('label.emphasis');\r
27505                         symbolGroup.eachChild(function (symbolPath) {\r
27506                             symbolPath.setStyle(itemStyle);\r
27507                             symbolPath.hoverStyle = zrUtil.clone(itemHoverStyle);\r
27508 \r
27509                             var defaultText = data.get(data.dimensions[symbolPath.__dimIdx], idx);\r
27510                             graphic.setText(symbolPath.style, labelModel, color);\r
27511                             symbolPath.setStyle({\r
27512                                 text: labelModel.get('show') ? zrUtil.retrieve(\r
27513                                     seriesModel.getFormattedLabel(\r
27514                                         idx, 'normal', null, symbolPath.__dimIdx\r
27515                                     ),\r
27516                                     defaultText\r
27517                                 ) : ''\r
27518                             });\r
27519 \r
27520                             graphic.setText(symbolPath.hoverStyle, labelHoverModel, color);\r
27521                             symbolPath.hoverStyle.text = labelHoverModel.get('show') ? zrUtil.retrieve(\r
27522                                 seriesModel.getFormattedLabel(\r
27523                                     idx, 'emphasis', null, symbolPath.__dimIdx\r
27524                                 ),\r
27525                                 defaultText\r
27526                             ) : '';\r
27527                         });\r
27528 \r
27529                         function onEmphasis() {\r
27530                             polygon.attr('ignore', hoverPolygonIgnore);\r
27531                         }\r
27532 \r
27533                         function onNormal() {\r
27534                             polygon.attr('ignore', polygonIgnore);\r
27535                         }\r
27536 \r
27537                         itemGroup.off('mouseover').off('mouseout').off('normal').off('emphasis');\r
27538                         itemGroup.on('emphasis', onEmphasis)\r
27539                             .on('mouseover', onEmphasis)\r
27540                             .on('normal', onNormal)\r
27541                             .on('mouseout', onNormal);\r
27542 \r
27543                         graphic.setHoverStyle(itemGroup);\r
27544                     });\r
27545 \r
27546                     this._data = data;\r
27547                 },\r
27548 \r
27549                 remove: function () {\r
27550                     this.group.removeAll();\r
27551                     this._data = null;\r
27552                 }\r
27553             });\r
27554 \r
27555 \r
27556 /***/ },\r
27557 /* 153 */\r
27558 /***/ function(module, exports) {\r
27559 \r
27560         \r
27561 \r
27562             module.exports = function (ecModel, api) {\r
27563                 ecModel.eachSeriesByType('radar', function (seriesModel) {\r
27564                     var data = seriesModel.getData();\r
27565                     var points = [];\r
27566                     var coordSys = seriesModel.coordinateSystem;\r
27567                     if (!coordSys) {\r
27568                         return;\r
27569                     }\r
27570 \r
27571                     function pointsConverter(val, idx) {\r
27572                         points[idx] = points[idx] || [];\r
27573                         points[idx][i] = coordSys.dataToPoint(val, i);\r
27574                     }\r
27575                     for (var i = 0; i < coordSys.getIndicatorAxes().length; i++) {\r
27576                         var dim = data.dimensions[i];\r
27577                         data.each(dim, pointsConverter);\r
27578                     }\r
27579 \r
27580                     data.each(function (idx) {\r
27581                         // Close polygon\r
27582                         points[idx][0] && points[idx].push(points[idx][0].slice());\r
27583                         data.setItemLayout(idx, points[idx]);\r
27584                     });\r
27585                 });\r
27586             };\r
27587 \r
27588 \r
27589 /***/ },\r
27590 /* 154 */\r
27591 /***/ function(module, exports, __webpack_require__) {\r
27592 \r
27593         // Backward compat for radar chart in 2\r
27594 \r
27595 \r
27596             var zrUtil = __webpack_require__(3);\r
27597 \r
27598             module.exports = function (option) {\r
27599                 var polarOptArr = option.polar;\r
27600                 if (polarOptArr) {\r
27601                     if (!zrUtil.isArray(polarOptArr)) {\r
27602                         polarOptArr = [polarOptArr];\r
27603                     }\r
27604                     var polarNotRadar = [];\r
27605                     zrUtil.each(polarOptArr, function (polarOpt, idx) {\r
27606                         if (polarOpt.indicator) {\r
27607                             if (polarOpt.type && !polarOpt.shape) {\r
27608                                 polarOpt.shape = polarOpt.type;\r
27609                             }\r
27610                             option.radar = option.radar || [];\r
27611                             if (!zrUtil.isArray(option.radar)) {\r
27612                                 option.radar = [option.radar];\r
27613                             }\r
27614                             option.radar.push(polarOpt);\r
27615                         }\r
27616                         else {\r
27617                             polarNotRadar.push(polarOpt);\r
27618                         }\r
27619                     });\r
27620                     option.polar = polarNotRadar;\r
27621                 }\r
27622                 zrUtil.each(option.series, function (seriesOpt) {\r
27623                     if (seriesOpt.type === 'radar' && seriesOpt.polarIndex) {\r
27624                         seriesOpt.radarIndex = seriesOpt.polarIndex;\r
27625                     }\r
27626                 });\r
27627             };\r
27628 \r
27629 \r
27630 /***/ },\r
27631 /* 155 */\r
27632 /***/ function(module, exports, __webpack_require__) {\r
27633 \r
27634         \r
27635 \r
27636             var echarts = __webpack_require__(1);\r
27637 \r
27638             __webpack_require__(156);\r
27639 \r
27640             __webpack_require__(157);\r
27641 \r
27642             __webpack_require__(161);\r
27643 \r
27644             __webpack_require__(163);\r
27645 \r
27646             echarts.registerLayout(__webpack_require__(173));\r
27647 \r
27648             echarts.registerVisualCoding('chart', __webpack_require__(174));\r
27649 \r
27650             echarts.registerProcessor('statistic', __webpack_require__(175));\r
27651 \r
27652             echarts.registerPreprocessor(__webpack_require__(176));\r
27653 \r
27654             __webpack_require__(136)('map', [{\r
27655                 type: 'mapToggleSelect',\r
27656                 event: 'mapselectchanged',\r
27657                 method: 'toggleSelected'\r
27658             }, {\r
27659                 type: 'mapSelect',\r
27660                 event: 'mapselected',\r
27661                 method: 'select'\r
27662             }, {\r
27663                 type: 'mapUnSelect',\r
27664                 event: 'mapunselected',\r
27665                 method: 'unSelect'\r
27666             }]);\r
27667 \r
27668 \r
27669 /***/ },\r
27670 /* 156 */\r
27671 /***/ function(module, exports, __webpack_require__) {\r
27672 \r
27673         \r
27674 \r
27675             var List = __webpack_require__(94);\r
27676             var echarts = __webpack_require__(1);\r
27677             var SeriesModel = __webpack_require__(27);\r
27678             var zrUtil = __webpack_require__(3);\r
27679             var completeDimensions = __webpack_require__(96);\r
27680 \r
27681             var formatUtil = __webpack_require__(6);\r
27682             var encodeHTML = formatUtil.encodeHTML;\r
27683             var addCommas = formatUtil.addCommas;\r
27684 \r
27685             var dataSelectableMixin = __webpack_require__(134);\r
27686 \r
27687             function fillData(dataOpt, geoJson) {\r
27688                 var dataNameMap = {};\r
27689                 var features = geoJson.features;\r
27690                 for (var i = 0; i < dataOpt.length; i++) {\r
27691                     dataNameMap[dataOpt[i].name] = dataOpt[i];\r
27692                 }\r
27693 \r
27694                 for (var i = 0; i < features.length; i++) {\r
27695                     var name = features[i].properties.name;\r
27696                     if (!dataNameMap[name]) {\r
27697                         dataOpt.push({\r
27698                             value: NaN,\r
27699                             name: name\r
27700                         });\r
27701                     }\r
27702                 }\r
27703                 return dataOpt;\r
27704             }\r
27705 \r
27706             var MapSeries = SeriesModel.extend({\r
27707 \r
27708                 type: 'series.map',\r
27709 \r
27710                 /**\r
27711                  * Only first map series of same mapType will drawMap\r
27712                  * @type {boolean}\r
27713                  */\r
27714                 needsDrawMap: false,\r
27715 \r
27716                 /**\r
27717                  * Group of all map series with same mapType\r
27718                  * @type {boolean}\r
27719                  */\r
27720                 seriesGroup: [],\r
27721 \r
27722                 init: function (option) {\r
27723 \r
27724                     option = this._fillOption(option);\r
27725                     this.option = option;\r
27726 \r
27727                     MapSeries.superApply(this, 'init', arguments);\r
27728 \r
27729                     this.updateSelectedMap();\r
27730                 },\r
27731 \r
27732                 getInitialData: function (option) {\r
27733                     var dimensions = completeDimensions(['value'], option.data || []);\r
27734 \r
27735                     var list = new List(dimensions, this);\r
27736 \r
27737                     list.initData(option.data);\r
27738 \r
27739                     return list;\r
27740                 },\r
27741 \r
27742                 mergeOption: function (newOption) {\r
27743                     newOption = this._fillOption(newOption);\r
27744 \r
27745                     MapSeries.superCall(this, 'mergeOption', newOption);\r
27746 \r
27747                     this.updateSelectedMap();\r
27748                 },\r
27749 \r
27750                 _fillOption: function (option) {\r
27751                     // Shallow clone\r
27752                     option = zrUtil.extend({}, option);\r
27753 \r
27754                     var map = echarts.getMap(option.mapType);\r
27755                     var geoJson = map && map.geoJson;\r
27756                     geoJson && option.data\r
27757                         && (option.data = fillData(option.data, geoJson));\r
27758 \r
27759                     return option;\r
27760                 },\r
27761 \r
27762                 /**\r
27763                  * @param {number} zoom\r
27764                  */\r
27765                 setRoamZoom: function (zoom) {\r
27766                     var roamDetail = this.option.roamDetail;\r
27767                     roamDetail && (roamDetail.zoom = zoom);\r
27768                 },\r
27769 \r
27770                 /**\r
27771                  * @param {number} x\r
27772                  * @param {number} y\r
27773                  */\r
27774                 setRoamPan: function (x, y) {\r
27775                     var roamDetail = this.option.roamDetail;\r
27776                     if (roamDetail) {\r
27777                         roamDetail.x = x;\r
27778                         roamDetail.y = y;\r
27779                     }\r
27780                 },\r
27781 \r
27782                 getRawValue: function (dataIndex) {\r
27783                     // Use value stored in data instead because it is calculated from multiple series\r
27784                     // FIXME Provide all value of multiple series ?\r
27785                     return this._data.get('value', dataIndex);\r
27786                 },\r
27787 \r
27788                 /**\r
27789                  * Map tooltip formatter\r
27790                  *\r
27791                  * @param {number} dataIndex\r
27792                  */\r
27793                 formatTooltip: function (dataIndex) {\r
27794                     var data = this._data;\r
27795                     var formattedValue = addCommas(this.getRawValue(dataIndex));\r
27796                     var name = data.getName(dataIndex);\r
27797 \r
27798                     var seriesGroup = this.seriesGroup;\r
27799                     var seriesNames = [];\r
27800                     for (var i = 0; i < seriesGroup.length; i++) {\r
27801                         if (!isNaN(seriesGroup[i].getRawValue(dataIndex))) {\r
27802                             seriesNames.push(\r
27803                                 encodeHTML(seriesGroup[i].name)\r
27804                             );\r
27805                         }\r
27806                     }\r
27807 \r
27808                     return seriesNames.join(', ') + '<br />'\r
27809                         + name + ' : ' + formattedValue;\r
27810                 },\r
27811 \r
27812                 defaultOption: {\r
27813                     // 一级层叠\r
27814                     zlevel: 0,\r
27815                     // 二级层叠\r
27816                     z: 2,\r
27817                     coordinateSystem: 'geo',\r
27818                     // 各省的 map 暂时都用中文\r
27819                     map: 'china',\r
27820 \r
27821                     // 'center' | 'left' | 'right' | 'x%' | {number}\r
27822                     left: 'center',\r
27823                     // 'center' | 'top' | 'bottom' | 'x%' | {number}\r
27824                     top: 'center',\r
27825                     // right\r
27826                     // bottom\r
27827                     // width:\r
27828                     // height   // 自适应\r
27829 \r
27830                     // 数值合并方式,默认加和,可选为:\r
27831                     // 'sum' | 'average' | 'max' | 'min'\r
27832                     // mapValueCalculation: 'sum',\r
27833                     // 地图数值计算结果小数精度\r
27834                     // mapValuePrecision: 0,\r
27835                     // 显示图例颜色标识(系列标识的小圆点),图例开启时有效\r
27836                     showLegendSymbol: true,\r
27837                     // 选择模式,默认关闭,可选single,multiple\r
27838                     // selectedMode: false,\r
27839                     dataRangeHoverLink: true,\r
27840                     // 是否开启缩放及漫游模式\r
27841                     // roam: false,\r
27842 \r
27843                     // 在 roam 开启的时候使用\r
27844                     roamDetail: {\r
27845                         x: 0,\r
27846                         y: 0,\r
27847                         zoom: 1\r
27848                     },\r
27849 \r
27850                     scaleLimit: null,\r
27851 \r
27852                     label: {\r
27853                         normal: {\r
27854                             show: false,\r
27855                             textStyle: {\r
27856                                 color: '#000'\r
27857                             }\r
27858                         },\r
27859                         emphasis: {\r
27860                             show: false,\r
27861                             textStyle: {\r
27862                                 color: '#000'\r
27863                             }\r
27864                         }\r
27865                     },\r
27866                     // scaleLimit: null,\r
27867                     itemStyle: {\r
27868                         normal: {\r
27869                             // color: 各异,\r
27870                             borderWidth: 0.5,\r
27871                             borderColor: '#444',\r
27872                             areaColor: '#eee'\r
27873                         },\r
27874                         // 也是选中样式\r
27875                         emphasis: {\r
27876                             areaColor: 'rgba(255,215, 0, 0.8)'\r
27877                         }\r
27878                     }\r
27879                 }\r
27880             });\r
27881 \r
27882             zrUtil.mixin(MapSeries, dataSelectableMixin);\r
27883 \r
27884             module.exports = MapSeries;\r
27885 \r
27886 \r
27887 /***/ },\r
27888 /* 157 */\r
27889 /***/ function(module, exports, __webpack_require__) {\r
27890 \r
27891         \r
27892 \r
27893             // var zrUtil = require('zrender/lib/core/util');\r
27894             var graphic = __webpack_require__(42);\r
27895 \r
27896             var MapDraw = __webpack_require__(158);\r
27897 \r
27898             __webpack_require__(1).extendChartView({\r
27899 \r
27900                 type: 'map',\r
27901 \r
27902                 render: function (mapModel, ecModel, api, payload) {\r
27903                     // Not render if it is an toggleSelect action from self\r
27904                     if (payload && payload.type === 'mapToggleSelect'\r
27905                         && payload.from === this.uid\r
27906                     ) {\r
27907                         return;\r
27908                     }\r
27909 \r
27910                     var group = this.group;\r
27911                     group.removeAll();\r
27912                     // Not update map if it is an roam action from self\r
27913                     if (!(payload && payload.type === 'geoRoam'\r
27914                         && payload.component === 'series'\r
27915                         && payload.name === mapModel.name)) {\r
27916 \r
27917                         if (mapModel.needsDrawMap) {\r
27918                             var mapDraw = this._mapDraw || new MapDraw(api, true);\r
27919                             group.add(mapDraw.group);\r
27920 \r
27921                             mapDraw.draw(mapModel, ecModel, api, this);\r
27922 \r
27923                             this._mapDraw = mapDraw;\r
27924                         }\r
27925                         else {\r
27926                             // Remove drawed map\r
27927                             this._mapDraw && this._mapDraw.remove();\r
27928                             this._mapDraw = null;\r
27929                         }\r
27930                     }\r
27931                     else {\r
27932                         var mapDraw = this._mapDraw;\r
27933                         mapDraw && group.add(mapDraw.group);\r
27934                     }\r
27935 \r
27936                     mapModel.get('showLegendSymbol') && ecModel.getComponent('legend')\r
27937                         && this._renderSymbols(mapModel, ecModel, api);\r
27938                 },\r
27939 \r
27940                 remove: function () {\r
27941                     this._mapDraw && this._mapDraw.remove();\r
27942                     this._mapDraw = null;\r
27943                     this.group.removeAll();\r
27944                 },\r
27945 \r
27946                 _renderSymbols: function (mapModel, ecModel, api) {\r
27947                     var data = mapModel.getData();\r
27948                     var group = this.group;\r
27949 \r
27950                     data.each('value', function (value, idx) {\r
27951                         if (isNaN(value)) {\r
27952                             return;\r
27953                         }\r
27954 \r
27955                         var layout = data.getItemLayout(idx);\r
27956 \r
27957                         if (!layout || !layout.point) {\r
27958                             // Not exists in map\r
27959                             return;\r
27960                         }\r
27961 \r
27962                         var point = layout.point;\r
27963                         var offset = layout.offset;\r
27964 \r
27965                         var circle = new graphic.Circle({\r
27966                             style: {\r
27967                                 fill: data.getVisual('color')\r
27968                             },\r
27969                             shape: {\r
27970                                 cx: point[0] + offset * 9,\r
27971                                 cy: point[1],\r
27972                                 r: 3\r
27973                             },\r
27974                             silent: true,\r
27975                             z2: 10\r
27976                         });\r
27977 \r
27978                         // First data on the same region\r
27979                         if (!offset) {\r
27980                             var labelText = data.getName(idx);\r
27981 \r
27982                             var itemModel = data.getItemModel(idx);\r
27983                             var labelModel = itemModel.getModel('label.normal');\r
27984                             var hoverLabelModel = itemModel.getModel('label.emphasis');\r
27985 \r
27986                             var textStyleModel = labelModel.getModel('textStyle');\r
27987                             var hoverTextStyleModel = hoverLabelModel.getModel('textStyle');\r
27988 \r
27989                             var polygonGroups = data.getItemGraphicEl(idx);\r
27990                             circle.setStyle({\r
27991                                 textPosition: 'bottom'\r
27992                             });\r
27993 \r
27994                             var onEmphasis = function () {\r
27995                                 circle.setStyle({\r
27996                                     text: hoverLabelModel.get('show') ? labelText : '',\r
27997                                     textFill: hoverTextStyleModel.getTextColor(),\r
27998                                     textFont: hoverTextStyleModel.getFont()\r
27999                                 });\r
28000                             };\r
28001 \r
28002                             var onNormal = function () {\r
28003                                 circle.setStyle({\r
28004                                     text: labelModel.get('show') ? labelText : '',\r
28005                                     textFill: textStyleModel.getTextColor(),\r
28006                                     textFont: textStyleModel.getFont()\r
28007                                 });\r
28008                             };\r
28009 \r
28010                             polygonGroups.on('mouseover', onEmphasis)\r
28011                                 .on('mouseout', onNormal)\r
28012                                 .on('emphasis', onEmphasis)\r
28013                                 .on('normal', onNormal);\r
28014 \r
28015                             onNormal();\r
28016                         }\r
28017 \r
28018                         group.add(circle);\r
28019                     });\r
28020                 }\r
28021             });\r
28022 \r
28023 \r
28024 /***/ },\r
28025 /* 158 */\r
28026 /***/ function(module, exports, __webpack_require__) {\r
28027 \r
28028         /**\r
28029          * @module echarts/component/helper/MapDraw\r
28030          */\r
28031 \r
28032 \r
28033             var RoamController = __webpack_require__(159);\r
28034             var graphic = __webpack_require__(42);\r
28035             var zrUtil = __webpack_require__(3);\r
28036 \r
28037             function getFixedItemStyle(model, scale) {\r
28038                 var itemStyle = model.getItemStyle();\r
28039                 var areaColor = model.get('areaColor');\r
28040                 if (areaColor) {\r
28041                     itemStyle.fill = areaColor;\r
28042                 }\r
28043 \r
28044                 return itemStyle;\r
28045             }\r
28046 \r
28047             function updateMapSelectHandler(mapOrGeoModel, data, group, api, fromView) {\r
28048                 group.off('click');\r
28049                 mapOrGeoModel.get('selectedMode')\r
28050                     && group.on('click', function (e) {\r
28051                         var dataIndex = e.target.dataIndex;\r
28052                         if (dataIndex != null) {\r
28053                             var name = data.getName(dataIndex);\r
28054 \r
28055                             api.dispatchAction({\r
28056                                 type: 'mapToggleSelect',\r
28057                                 seriesIndex: mapOrGeoModel.seriesIndex,\r
28058                                 name: name,\r
28059                                 from: fromView.uid\r
28060                             });\r
28061 \r
28062                             updateMapSelected(mapOrGeoModel, data, api);\r
28063                         }\r
28064                     });\r
28065             }\r
28066 \r
28067             function updateMapSelected(mapOrGeoModel, data) {\r
28068                 data.eachItemGraphicEl(function (el, idx) {\r
28069                     var name = data.getName(idx);\r
28070                     el.trigger(mapOrGeoModel.isSelected(name) ? 'emphasis' : 'normal');\r
28071                 });\r
28072             }\r
28073 \r
28074             /**\r
28075              * @alias module:echarts/component/helper/MapDraw\r
28076              * @param {module:echarts/ExtensionAPI} api\r
28077              * @param {boolean} updateGroup\r
28078              */\r
28079             function MapDraw(api, updateGroup) {\r
28080 \r
28081                 var group = new graphic.Group();\r
28082 \r
28083                 /**\r
28084                  * @type {module:echarts/component/helper/RoamController}\r
28085                  * @private\r
28086                  */\r
28087                 this._controller = new RoamController(\r
28088                     api.getZr(), updateGroup ? group : null, null\r
28089                 );\r
28090 \r
28091                 /**\r
28092                  * @type {module:zrender/container/Group}\r
28093                  * @readOnly\r
28094                  */\r
28095                 this.group = group;\r
28096 \r
28097                 /**\r
28098                  * @type {boolean}\r
28099                  * @private\r
28100                  */\r
28101                 this._updateGroup = updateGroup;\r
28102             }\r
28103 \r
28104             MapDraw.prototype = {\r
28105 \r
28106                 constructor: MapDraw,\r
28107 \r
28108                 draw: function (mapOrGeoModel, ecModel, api, fromView) {\r
28109 \r
28110                     // geoModel has no data\r
28111                     var data = mapOrGeoModel.getData && mapOrGeoModel.getData();\r
28112 \r
28113                     var geo = mapOrGeoModel.coordinateSystem;\r
28114 \r
28115                     var group = this.group;\r
28116                     group.removeAll();\r
28117 \r
28118                     var scale = geo.scale;\r
28119                     group.position = geo.position.slice();\r
28120                     group.scale = scale.slice();\r
28121 \r
28122                     var itemStyleModel;\r
28123                     var hoverItemStyleModel;\r
28124                     var itemStyle;\r
28125                     var hoverItemStyle;\r
28126 \r
28127                     var labelModel;\r
28128                     var hoverLabelModel;\r
28129 \r
28130                     var itemStyleAccessPath = ['itemStyle', 'normal'];\r
28131                     var hoverItemStyleAccessPath = ['itemStyle', 'emphasis'];\r
28132                     var labelAccessPath = ['label', 'normal'];\r
28133                     var hoverLabelAccessPath = ['label', 'emphasis'];\r
28134                     if (!data) {\r
28135                         itemStyleModel = mapOrGeoModel.getModel(itemStyleAccessPath);\r
28136                         hoverItemStyleModel = mapOrGeoModel.getModel(hoverItemStyleAccessPath);\r
28137 \r
28138                         itemStyle = getFixedItemStyle(itemStyleModel, scale);\r
28139                         hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale);\r
28140 \r
28141                         labelModel = mapOrGeoModel.getModel(labelAccessPath);\r
28142                         hoverLabelModel = mapOrGeoModel.getModel(hoverLabelAccessPath);\r
28143                     }\r
28144 \r
28145                     zrUtil.each(geo.regions, function (region) {\r
28146 \r
28147                         var regionGroup = new graphic.Group();\r
28148                         var dataIdx;\r
28149                         // Use the itemStyle in data if has data\r
28150                         if (data) {\r
28151                             // FIXME If dataIdx < 0\r
28152                             dataIdx = data.indexOfName(region.name);\r
28153                             var itemModel = data.getItemModel(dataIdx);\r
28154 \r
28155                             // Only visual color of each item will be used. It can be encoded by dataRange\r
28156                             // But visual color of series is used in symbol drawing\r
28157                             //\r
28158                             // Visual color for each series is for the symbol draw\r
28159                             var visualColor = data.getItemVisual(dataIdx, 'color', true);\r
28160 \r
28161                             itemStyleModel = itemModel.getModel(itemStyleAccessPath);\r
28162                             hoverItemStyleModel = itemModel.getModel(hoverItemStyleAccessPath);\r
28163 \r
28164                             itemStyle = getFixedItemStyle(itemStyleModel, scale);\r
28165                             hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale);\r
28166 \r
28167                             labelModel = itemModel.getModel(labelAccessPath);\r
28168                             hoverLabelModel = itemModel.getModel(hoverLabelAccessPath);\r
28169 \r
28170                             if (visualColor) {\r
28171                                 itemStyle.fill = visualColor;\r
28172                             }\r
28173                         }\r
28174                         var textStyleModel = labelModel.getModel('textStyle');\r
28175                         var hoverTextStyleModel = hoverLabelModel.getModel('textStyle');\r
28176 \r
28177                         zrUtil.each(region.contours, function (contour) {\r
28178 \r
28179                             var polygon = new graphic.Polygon({\r
28180                                 shape: {\r
28181                                     points: contour\r
28182                                 },\r
28183                                 style: {\r
28184                                     strokeNoScale: true\r
28185                                 },\r
28186                                 culling: true\r
28187                             });\r
28188 \r
28189                             polygon.setStyle(itemStyle);\r
28190 \r
28191                             regionGroup.add(polygon);\r
28192                         });\r
28193 \r
28194                         // Label\r
28195                         var showLabel = labelModel.get('show');\r
28196                         var hoverShowLabel = hoverLabelModel.get('show');\r
28197 \r
28198                         var isDataNaN = data && isNaN(data.get('value', dataIdx));\r
28199                         var itemLayout = data && data.getItemLayout(dataIdx);\r
28200                         // In the following cases label will be drawn\r
28201                         // 1. In map series and data value is NaN\r
28202                         // 2. In geo component\r
28203                         // 4. Region has no series legendSymbol, which will be add a showLabel flag in mapSymbolLayout\r
28204                         if (\r
28205                             (!data || isDataNaN && (showLabel || hoverShowLabel))\r
28206                          || (itemLayout && itemLayout.showLabel)\r
28207                          ) {\r
28208                             var query = data ? dataIdx : region.name;\r
28209                             var formattedStr = mapOrGeoModel.getFormattedLabel(query, 'normal');\r
28210                             var hoverFormattedStr = mapOrGeoModel.getFormattedLabel(query, 'emphasis');\r
28211                             var text = new graphic.Text({\r
28212                                 style: {\r
28213                                     text: showLabel ? (formattedStr || region.name) : '',\r
28214                                     fill: textStyleModel.getTextColor(),\r
28215                                     textFont: textStyleModel.getFont(),\r
28216                                     textAlign: 'center',\r
28217                                     textVerticalAlign: 'middle'\r
28218                                 },\r
28219                                 hoverStyle: {\r
28220                                     text: hoverShowLabel ? (hoverFormattedStr || region.name) : '',\r
28221                                     fill: hoverTextStyleModel.getTextColor(),\r
28222                                     textFont: hoverTextStyleModel.getFont()\r
28223                                 },\r
28224                                 position: region.center.slice(),\r
28225                                 scale: [1 / scale[0], 1 / scale[1]],\r
28226                                 z2: 10,\r
28227                                 silent: true\r
28228                             });\r
28229 \r
28230                             regionGroup.add(text);\r
28231                         }\r
28232 \r
28233                         // setItemGraphicEl, setHoverStyle after all polygons and labels\r
28234                         // are added to the rigionGroup\r
28235                         data && data.setItemGraphicEl(dataIdx, regionGroup);\r
28236 \r
28237                         graphic.setHoverStyle(regionGroup, hoverItemStyle);\r
28238 \r
28239                         group.add(regionGroup);\r
28240                     });\r
28241 \r
28242                     this._updateController(mapOrGeoModel, ecModel, api);\r
28243 \r
28244                     data && updateMapSelectHandler(mapOrGeoModel, data, group, api, fromView);\r
28245 \r
28246                     data && updateMapSelected(mapOrGeoModel, data);\r
28247                 },\r
28248 \r
28249                 remove: function () {\r
28250                     this.group.removeAll();\r
28251                     this._controller.dispose();\r
28252                 },\r
28253 \r
28254                 _updateController: function (mapOrGeoModel, ecModel, api) {\r
28255                     var geo = mapOrGeoModel.coordinateSystem;\r
28256                     var controller = this._controller;\r
28257                     controller.zoomLimit = mapOrGeoModel.get('scaleLimit');\r
28258                     // Update zoom from model\r
28259                     controller.zoom = mapOrGeoModel.get('roamDetail.zoom');\r
28260                     // roamType is will be set default true if it is null\r
28261                     controller.enable(mapOrGeoModel.get('roam') || false);\r
28262                     // FIXME mainType, subType 作为 component 的属性?\r
28263                     var mainType = mapOrGeoModel.type.split('.')[0];\r
28264                     controller.off('pan')\r
28265                         .on('pan', function (dx, dy) {\r
28266                             api.dispatchAction({\r
28267                                 type: 'geoRoam',\r
28268                                 component: mainType,\r
28269                                 name: mapOrGeoModel.name,\r
28270                                 dx: dx,\r
28271                                 dy: dy\r
28272                             });\r
28273                         });\r
28274                     controller.off('zoom')\r
28275                         .on('zoom', function (zoom, mouseX, mouseY) {\r
28276                             api.dispatchAction({\r
28277                                 type: 'geoRoam',\r
28278                                 component: mainType,\r
28279                                 name: mapOrGeoModel.name,\r
28280                                 zoom: zoom,\r
28281                                 originX: mouseX,\r
28282                                 originY: mouseY\r
28283                             });\r
28284 \r
28285                             if (this._updateGroup) {\r
28286                                 var group = this.group;\r
28287                                 var scale = group.scale;\r
28288                                 group.traverse(function (el) {\r
28289                                     if (el.type === 'text') {\r
28290                                         el.attr('scale', [1 / scale[0], 1 / scale[1]]);\r
28291                                     }\r
28292                                 });\r
28293                             }\r
28294                         }, this);\r
28295 \r
28296                     controller.rect = geo.getViewRect();\r
28297                 }\r
28298             };\r
28299 \r
28300             module.exports = MapDraw;\r
28301 \r
28302 \r
28303 /***/ },\r
28304 /* 159 */\r
28305 /***/ function(module, exports, __webpack_require__) {\r
28306 \r
28307         /**\r
28308          * @module echarts/component/helper/RoamController\r
28309          */\r
28310 \r
28311 \r
28312 \r
28313             var Eventful = __webpack_require__(32);\r
28314             var zrUtil = __webpack_require__(3);\r
28315             var eventTool = __webpack_require__(80);\r
28316             var interactionMutex = __webpack_require__(160);\r
28317 \r
28318             function mousedown(e) {\r
28319                 if (e.target && e.target.draggable) {\r
28320                     return;\r
28321                 }\r
28322 \r
28323                 var x = e.offsetX;\r
28324                 var y = e.offsetY;\r
28325                 var rect = this.rect;\r
28326                 if (rect && rect.contain(x, y)) {\r
28327                     this._x = x;\r
28328                     this._y = y;\r
28329                     this._dragging = true;\r
28330                 }\r
28331             }\r
28332 \r
28333             function mousemove(e) {\r
28334                 if (!this._dragging) {\r
28335                     return;\r
28336                 }\r
28337 \r
28338                 eventTool.stop(e.event);\r
28339 \r
28340                 if (e.gestureEvent !== 'pinch') {\r
28341 \r
28342                     if (interactionMutex.isTaken('globalPan', this._zr)) {\r
28343                         return;\r
28344                     }\r
28345 \r
28346                     var x = e.offsetX;\r
28347                     var y = e.offsetY;\r
28348 \r
28349                     var dx = x - this._x;\r
28350                     var dy = y - this._y;\r
28351 \r
28352                     this._x = x;\r
28353                     this._y = y;\r
28354 \r
28355                     var target = this.target;\r
28356 \r
28357                     if (target) {\r
28358                         var pos = target.position;\r
28359                         pos[0] += dx;\r
28360                         pos[1] += dy;\r
28361                         target.dirty();\r
28362                     }\r
28363 \r
28364                     eventTool.stop(e.event);\r
28365                     this.trigger('pan', dx, dy);\r
28366                 }\r
28367             }\r
28368 \r
28369             function mouseup(e) {\r
28370                 this._dragging = false;\r
28371             }\r
28372 \r
28373             function mousewheel(e) {\r
28374                 eventTool.stop(e.event);\r
28375                 // Convenience:\r
28376                 // Mac and VM Windows on Mac: scroll up: zoom out.\r
28377                 // Windows: scroll up: zoom in.\r
28378                 var zoomDelta = e.wheelDelta > 0 ? 1.1 : 1 / 1.1;\r
28379                 zoom.call(this, e, zoomDelta, e.offsetX, e.offsetY);\r
28380             }\r
28381 \r
28382             function pinch(e) {\r
28383                 if (interactionMutex.isTaken('globalPan', this._zr)) {\r
28384                     return;\r
28385                 }\r
28386 \r
28387                 eventTool.stop(e.event);\r
28388                 var zoomDelta = e.pinchScale > 1 ? 1.1 : 1 / 1.1;\r
28389                 zoom.call(this, e, zoomDelta, e.pinchX, e.pinchY);\r
28390             }\r
28391 \r
28392             function zoom(e, zoomDelta, zoomX, zoomY) {\r
28393                 var rect = this.rect;\r
28394 \r
28395                 if (rect && rect.contain(zoomX, zoomY)) {\r
28396 \r
28397                     var target = this.target;\r
28398                     var zoomLimit = this.zoomLimit;\r
28399 \r
28400                     if (target) {\r
28401                         var pos = target.position;\r
28402                         var scale = target.scale;\r
28403 \r
28404                         var newZoom = this.zoom = this.zoom || 1;\r
28405                         newZoom *= zoomDelta;\r
28406                         if (zoomLimit) {\r
28407                             newZoom = Math.max(\r
28408                                 Math.min(zoomLimit.max, newZoom),\r
28409                                 zoomLimit.min\r
28410                             );\r
28411                         }\r
28412                         var zoomScale = newZoom / this.zoom;\r
28413                         this.zoom = newZoom;\r
28414                         // Keep the mouse center when scaling\r
28415                         pos[0] -= (zoomX - pos[0]) * (zoomScale - 1);\r
28416                         pos[1] -= (zoomY - pos[1]) * (zoomScale - 1);\r
28417                         scale[0] *= zoomScale;\r
28418                         scale[1] *= zoomScale;\r
28419 \r
28420                         target.dirty();\r
28421                     }\r
28422 \r
28423                     this.trigger('zoom', zoomDelta, zoomX, zoomY);\r
28424                 }\r
28425             }\r
28426 \r
28427             /**\r
28428              * @alias module:echarts/component/helper/RoamController\r
28429              * @constructor\r
28430              * @mixin {module:zrender/mixin/Eventful}\r
28431              *\r
28432              * @param {module:zrender/zrender~ZRender} zr\r
28433              * @param {module:zrender/Element} target\r
28434              * @param {module:zrender/core/BoundingRect} rect\r
28435              */\r
28436             function RoamController(zr, target, rect) {\r
28437 \r
28438                 /**\r
28439                  * @type {module:zrender/Element}\r
28440                  */\r
28441                 this.target = target;\r
28442 \r
28443                 /**\r
28444                  * @type {module:zrender/core/BoundingRect}\r
28445                  */\r
28446                 this.rect = rect;\r
28447 \r
28448                 /**\r
28449                  * { min: 1, max: 2 }\r
28450                  * @type {Object}\r
28451                  */\r
28452                 this.zoomLimit;\r
28453 \r
28454                 /**\r
28455                  * @type {number}\r
28456                  */\r
28457                 this.zoom;\r
28458                 /**\r
28459                  * @type {module:zrender}\r
28460                  */\r
28461                 this._zr = zr;\r
28462 \r
28463                 // Avoid two roamController bind the same handler\r
28464                 var bind = zrUtil.bind;\r
28465                 var mousedownHandler = bind(mousedown, this);\r
28466                 var mousemoveHandler = bind(mousemove, this);\r
28467                 var mouseupHandler = bind(mouseup, this);\r
28468                 var mousewheelHandler = bind(mousewheel, this);\r
28469                 var pinchHandler = bind(pinch, this);\r
28470 \r
28471                 Eventful.call(this);\r
28472 \r
28473                 /**\r
28474                  * Notice: only enable needed types. For example, if 'zoom'\r
28475                  * is not needed, 'zoom' should not be enabled, otherwise\r
28476                  * default mousewheel behaviour (scroll page) will be disabled.\r
28477                  *\r
28478                  * @param  {boolean|string} [controlType=true] Specify the control type,\r
28479                  *                          which can be null/undefined or true/false\r
28480                  *                          or 'pan/move' or 'zoom'/'scale'\r
28481                  */\r
28482                 this.enable = function (controlType) {\r
28483                     // Disable previous first\r
28484                     this.disable();\r
28485 \r
28486                     if (controlType == null) {\r
28487                         controlType = true;\r
28488                     }\r
28489 \r
28490                     if (controlType === true || (controlType === 'move' || controlType === 'pan')) {\r
28491                         zr.on('mousedown', mousedownHandler);\r
28492                         zr.on('mousemove', mousemoveHandler);\r
28493                         zr.on('mouseup', mouseupHandler);\r
28494                     }\r
28495                     if (controlType === true || (controlType === 'scale' || controlType === 'zoom')) {\r
28496                         zr.on('mousewheel', mousewheelHandler);\r
28497                         zr.on('pinch', pinchHandler);\r
28498                     }\r
28499                 };\r
28500 \r
28501                 this.disable = function () {\r
28502                     zr.off('mousedown', mousedownHandler);\r
28503                     zr.off('mousemove', mousemoveHandler);\r
28504                     zr.off('mouseup', mouseupHandler);\r
28505                     zr.off('mousewheel', mousewheelHandler);\r
28506                     zr.off('pinch', pinchHandler);\r
28507                 };\r
28508 \r
28509                 this.dispose = this.disable;\r
28510 \r
28511                 this.isDragging = function () {\r
28512                     return this._dragging;\r
28513                 };\r
28514 \r
28515                 this.isPinching = function () {\r
28516                     return this._pinching;\r
28517                 };\r
28518             }\r
28519 \r
28520             zrUtil.mixin(RoamController, Eventful);\r
28521 \r
28522             module.exports = RoamController;\r
28523 \r
28524 \r
28525 /***/ },\r
28526 /* 160 */\r
28527 /***/ function(module, exports) {\r
28528 \r
28529         \r
28530 \r
28531             var ATTR = '\0_ec_interaction_mutex';\r
28532 \r
28533             var interactionMutex = {\r
28534 \r
28535                 take: function (key, zr) {\r
28536                     getStore(zr)[key] = true;\r
28537                 },\r
28538 \r
28539                 release: function (key, zr) {\r
28540                     getStore(zr)[key] = false;\r
28541                 },\r
28542 \r
28543                 isTaken: function (key, zr) {\r
28544                     return !!getStore(zr)[key];\r
28545                 }\r
28546             };\r
28547 \r
28548             function getStore(zr) {\r
28549                 return zr[ATTR] || (zr[ATTR] = {});\r
28550             }\r
28551 \r
28552             module.exports = interactionMutex;\r
28553 \r
28554 \r
28555 /***/ },\r
28556 /* 161 */\r
28557 /***/ function(module, exports, __webpack_require__) {\r
28558 \r
28559         \r
28560 \r
28561             var zrUtil = __webpack_require__(3);\r
28562             var roamHelper = __webpack_require__(162);\r
28563 \r
28564             var echarts = __webpack_require__(1);\r
28565             var actionInfo = {\r
28566                 type: 'geoRoam',\r
28567                 event: 'geoRoam',\r
28568                 update: 'updateLayout'\r
28569             };\r
28570 \r
28571             /**\r
28572              * @payload\r
28573              * @property {string} [component=series]\r
28574              * @property {string} name Component name\r
28575              * @property {number} [dx]\r
28576              * @property {number} [dy]\r
28577              * @property {number} [zoom]\r
28578              * @property {number} [originX]\r
28579              * @property {number} [originY]\r
28580              */\r
28581             echarts.registerAction(actionInfo, function (payload, ecModel) {\r
28582                 var componentType = payload.component || 'series';\r
28583 \r
28584                 ecModel.eachComponent(componentType, function (componentModel) {\r
28585                     if (componentModel.name === payload.name) {\r
28586                         var geo = componentModel.coordinateSystem;\r
28587                         if (geo.type !== 'geo') {\r
28588                             return;\r
28589                         }\r
28590 \r
28591                         var roamDetailModel = componentModel.getModel('roamDetail');\r
28592                         var res = roamHelper.calcPanAndZoom(\r
28593                             roamDetailModel, payload, componentModel.get('scaleLimit')\r
28594                         );\r
28595 \r
28596                         componentModel.setRoamPan\r
28597                             && componentModel.setRoamPan(res.x, res.y);\r
28598 \r
28599                         componentModel.setRoamZoom\r
28600                             && componentModel.setRoamZoom(res.zoom);\r
28601 \r
28602                         geo && geo.setPan(res.x, res.y);\r
28603                         geo && geo.setZoom(res.zoom);\r
28604 \r
28605                         // All map series with same `map` use the same geo coordinate system\r
28606                         // So the roamDetail must be in sync. Include the series not selected by legend\r
28607                         if (componentType === 'series') {\r
28608                             zrUtil.each(componentModel.seriesGroup, function (seriesModel) {\r
28609                                 seriesModel.setRoamPan(res.x, res.y);\r
28610                                 seriesModel.setRoamZoom(res.zoom);\r
28611                             });\r
28612                         }\r
28613                     }\r
28614                 });\r
28615             });\r
28616 \r
28617 \r
28618 /***/ },\r
28619 /* 162 */\r
28620 /***/ function(module, exports) {\r
28621 \r
28622         \r
28623 \r
28624             var roamHelper = {};\r
28625 \r
28626             /**\r
28627              * Calculate pan and zoom which from roamDetail model\r
28628              * @param {module:echarts/model/Model} roamDetailModel\r
28629              * @param {Object} payload\r
28630              * @param {Object} [zoomLimit]\r
28631              */\r
28632             roamHelper.calcPanAndZoom = function (\r
28633                 roamDetailModel, payload, zoomLimit\r
28634             ) {\r
28635                 var dx = payload.dx;\r
28636                 var dy = payload.dy;\r
28637                 var zoom = payload.zoom;\r
28638 \r
28639                 var panX = roamDetailModel.get('x') || 0;\r
28640                 var panY = roamDetailModel.get('y') || 0;\r
28641 \r
28642                 var previousZoom = roamDetailModel.get('zoom') || 1;\r
28643 \r
28644                 if (dx != null && dy != null) {\r
28645                     panX += dx;\r
28646                     panY += dy;\r
28647                 }\r
28648                 if (zoom != null) {\r
28649                     if (zoomLimit) {\r
28650                         zoom = Math.max(\r
28651                             Math.min(previousZoom * zoom, zoomLimit.max),\r
28652                             zoomLimit.min\r
28653                         ) / previousZoom;\r
28654                     }\r
28655                     var fixX = (payload.originX - panX) * (zoom - 1);\r
28656                     var fixY = (payload.originY - panY) * (zoom - 1);\r
28657 \r
28658                     panX -= fixX;\r
28659                     panY -= fixY;\r
28660                 }\r
28661 \r
28662                 return {\r
28663                     x: panX,\r
28664                     y: panY,\r
28665                     zoom: (zoom || 1) * previousZoom\r
28666                 };\r
28667             };\r
28668 \r
28669             module.exports = roamHelper;\r
28670 \r
28671 \r
28672 /***/ },\r
28673 /* 163 */\r
28674 /***/ function(module, exports, __webpack_require__) {\r
28675 \r
28676         \r
28677 \r
28678             __webpack_require__(164);\r
28679 \r
28680             var Geo = __webpack_require__(165);\r
28681 \r
28682             var layout = __webpack_require__(21);\r
28683             var zrUtil = __webpack_require__(3);\r
28684 \r
28685             var mapDataStores = {};\r
28686 \r
28687             /**\r
28688              * Resize method bound to the geo\r
28689              * @param {module:echarts/coord/geo/GeoModel|module:echarts/chart/map/MapModel} geoModel\r
28690              * @param {module:echarts/ExtensionAPI} api\r
28691              */\r
28692             function resizeGeo (geoModel, api) {\r
28693                 var rect = this.getBoundingRect();\r
28694 \r
28695                 var boxLayoutOption = geoModel.getBoxLayoutParams();\r
28696                 // 0.75 rate\r
28697                 boxLayoutOption.aspect = rect.width / rect.height * 0.75;\r
28698 \r
28699                 var viewRect = layout.getLayoutRect(boxLayoutOption, {\r
28700                     width: api.getWidth(),\r
28701                     height: api.getHeight()\r
28702                 });\r
28703 \r
28704                 this.setViewRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height);\r
28705 \r
28706                 var roamDetailModel = geoModel.getModel('roamDetail');\r
28707 \r
28708                 var panX = roamDetailModel.get('x') || 0;\r
28709                 var panY = roamDetailModel.get('y') || 0;\r
28710                 var zoom = roamDetailModel.get('zoom') || 1;\r
28711 \r
28712                 this.setPan(panX, panY);\r
28713                 this.setZoom(zoom);\r
28714             }\r
28715 \r
28716             /**\r
28717              * @param {module:echarts/coord/Geo} geo\r
28718              * @param {module:echarts/model/Model} model\r
28719              * @inner\r
28720              */\r
28721             function setGeoCoords(geo, model) {\r
28722                 zrUtil.each(model.get('geoCoord'), function (geoCoord, name) {\r
28723                     geo.addGeoCoord(name, geoCoord);\r
28724                 });\r
28725             }\r
28726 \r
28727             function mapNotExistsError(name) {\r
28728                 console.error('Map ' + name + ' not exists');\r
28729             }\r
28730 \r
28731             var geoCreator = {\r
28732 \r
28733                 // For deciding which dimensions to use when creating list data\r
28734                 dimensions: Geo.prototype.dimensions,\r
28735 \r
28736                 create: function (ecModel, api) {\r
28737                     var geoList = [];\r
28738 \r
28739                     // FIXME Create each time may be slow\r
28740                     ecModel.eachComponent('geo', function (geoModel, idx) {\r
28741                         var name = geoModel.get('map');\r
28742                         var mapData = mapDataStores[name];\r
28743                         if (!mapData) {\r
28744                             mapNotExistsError(name);\r
28745                         }\r
28746                         var geo = new Geo(\r
28747                             name + idx, name,\r
28748                             mapData && mapData.geoJson, mapData && mapData.specialAreas,\r
28749                             geoModel.get('nameMap')\r
28750                         );\r
28751                         geo.zoomLimit = geoModel.get('scaleLimit');\r
28752                         geoList.push(geo);\r
28753 \r
28754                         setGeoCoords(geo, geoModel);\r
28755 \r
28756                         geoModel.coordinateSystem = geo;\r
28757                         geo.model = geoModel;\r
28758 \r
28759                         // Inject resize method\r
28760                         geo.resize = resizeGeo;\r
28761 \r
28762                         geo.resize(geoModel, api);\r
28763                     });\r
28764 \r
28765                     ecModel.eachSeries(function (seriesModel) {\r
28766                         var coordSys = seriesModel.get('coordinateSystem');\r
28767                         if (coordSys === 'geo') {\r
28768                             var geoIndex = seriesModel.get('geoIndex') || 0;\r
28769                             seriesModel.coordinateSystem = geoList[geoIndex];\r
28770                         }\r
28771                     });\r
28772 \r
28773                     // If has map series\r
28774                     var mapModelGroupBySeries = {};\r
28775 \r
28776                     ecModel.eachSeriesByType('map', function (seriesModel) {\r
28777                         var mapType = seriesModel.get('map');\r
28778 \r
28779                         mapModelGroupBySeries[mapType] = mapModelGroupBySeries[mapType] || [];\r
28780 \r
28781                         mapModelGroupBySeries[mapType].push(seriesModel);\r
28782                     });\r
28783 \r
28784                     zrUtil.each(mapModelGroupBySeries, function (mapSeries, mapType) {\r
28785                         var mapData = mapDataStores[mapType];\r
28786                         if (!mapData) {\r
28787                             mapNotExistsError(name);\r
28788                         }\r
28789 \r
28790                         var nameMapList = zrUtil.map(mapSeries, function (singleMapSeries) {\r
28791                             return singleMapSeries.get('nameMap');\r
28792                         });\r
28793                         var geo = new Geo(\r
28794                             mapType, mapType,\r
28795                             mapData && mapData.geoJson, mapData && mapData.specialAreas,\r
28796                             zrUtil.mergeAll(nameMapList)\r
28797                         );\r
28798                         geo.zoomLimit = zrUtil.retrieve.apply(null, zrUtil.map(mapSeries, function (singleMapSeries) {\r
28799                             return singleMapSeries.get('scaleLimit');\r
28800                         }));\r
28801                         geoList.push(geo);\r
28802 \r
28803                         // Inject resize method\r
28804                         geo.resize = resizeGeo;\r
28805 \r
28806                         geo.resize(mapSeries[0], api);\r
28807 \r
28808                         zrUtil.each(mapSeries, function (singleMapSeries) {\r
28809                             singleMapSeries.coordinateSystem = geo;\r
28810 \r
28811                             setGeoCoords(geo, singleMapSeries);\r
28812                         });\r
28813                     });\r
28814 \r
28815                     return geoList;\r
28816                 },\r
28817 \r
28818                 /**\r
28819                  * @param {string} mapName\r
28820                  * @param {Object|string} geoJson\r
28821                  * @param {Object} [specialAreas]\r
28822                  *\r
28823                  * @example\r
28824                  *     $.get('USA.json', function (geoJson) {\r
28825                  *         echarts.registerMap('USA', geoJson);\r
28826                  *         // Or\r
28827                  *         echarts.registerMap('USA', {\r
28828                  *             geoJson: geoJson,\r
28829                  *             specialAreas: {}\r
28830                  *         })\r
28831                  *     });\r
28832                  */\r
28833                 registerMap: function (mapName, geoJson, specialAreas) {\r
28834                     if (geoJson.geoJson && !geoJson.features) {\r
28835                         specialAreas = geoJson.specialAreas;\r
28836                         geoJson = geoJson.geoJson;\r
28837                     }\r
28838                     if (typeof geoJson === 'string') {\r
28839                         geoJson = (typeof JSON !== 'undefined' && JSON.parse)\r
28840                             ? JSON.parse(geoJson) : (new Function('return (' + geoJson + ');'))();\r
28841                     }\r
28842                     mapDataStores[mapName] = {\r
28843                         geoJson: geoJson,\r
28844                         specialAreas: specialAreas\r
28845                     };\r
28846                 },\r
28847 \r
28848                 /**\r
28849                  * @param {string} mapName\r
28850                  * @return {Object}\r
28851                  */\r
28852                 getMap: function (mapName) {\r
28853                     return mapDataStores[mapName];\r
28854                 }\r
28855             };\r
28856 \r
28857             // Inject methods into echarts\r
28858             var echarts = __webpack_require__(1);\r
28859 \r
28860             echarts.registerMap = geoCreator.registerMap;\r
28861 \r
28862             echarts.getMap = geoCreator.getMap;\r
28863 \r
28864             // TODO\r
28865             echarts.loadMap = function () {};\r
28866 \r
28867             echarts.registerCoordinateSystem('geo', geoCreator);\r
28868 \r
28869 \r
28870 /***/ },\r
28871 /* 164 */\r
28872 /***/ function(module, exports, __webpack_require__) {\r
28873 \r
28874         'use strict';\r
28875 \r
28876             var modelUtil = __webpack_require__(5);\r
28877             var ComponentModel = __webpack_require__(19);\r
28878 \r
28879             ComponentModel.extend({\r
28880 \r
28881                 type: 'geo',\r
28882 \r
28883                 /**\r
28884                  * @type {module:echarts/coord/geo/Geo}\r
28885                  */\r
28886                 coordinateSystem: null,\r
28887 \r
28888                 init: function (option) {\r
28889                     ComponentModel.prototype.init.apply(this, arguments);\r
28890 \r
28891                     // Default label emphasis `position` and `show`\r
28892                     modelUtil.defaultEmphasis(\r
28893                         option.label, ['position', 'show', 'textStyle', 'distance', 'formatter']\r
28894                     );\r
28895                 },\r
28896 \r
28897                 defaultOption: {\r
28898 \r
28899                     zlevel: 0,\r
28900 \r
28901                     z: 0,\r
28902 \r
28903                     show: true,\r
28904 \r
28905                     left: 'center',\r
28906 \r
28907                     top: 'center',\r
28908 \r
28909                     // 自适应\r
28910                     // width:,\r
28911                     // height:,\r
28912                     // right\r
28913                     // bottom\r
28914 \r
28915                     // Map type\r
28916                     map: '',\r
28917 \r
28918                     // 在 roam 开启的时候使用\r
28919                     roamDetail: {\r
28920                         x: 0,\r
28921                         y: 0,\r
28922                         zoom: 1\r
28923                     },\r
28924 \r
28925                     scaleLimit: null,\r
28926 \r
28927                     label: {\r
28928                         normal: {\r
28929                             show: false,\r
28930                             textStyle: {\r
28931                                 color: '#000'\r
28932                             }\r
28933                         },\r
28934                         emphasis: {\r
28935                             show: true,\r
28936                             textStyle: {\r
28937                                 color: 'rgb(100,0,0)'\r
28938                             }\r
28939                         }\r
28940                     },\r
28941 \r
28942                     itemStyle: {\r
28943                         normal: {\r
28944                             // color: 各异,\r
28945                             borderWidth: 0.5,\r
28946                             borderColor: '#444',\r
28947                             color: '#eee'\r
28948                         },\r
28949                         emphasis: {                 // 也是选中样式\r
28950                             color: 'rgba(255,215,0,0.8)'\r
28951                         }\r
28952                     }\r
28953                 },\r
28954 \r
28955                 /**\r
28956                  * Format label\r
28957                  * @param {string} name Region name\r
28958                  * @param {string} [status='normal'] 'normal' or 'emphasis'\r
28959                  * @return {string}\r
28960                  */\r
28961                 getFormattedLabel: function (name, status) {\r
28962                     var formatter = this.get('label.' + status + '.formatter');\r
28963                     var params = {\r
28964                         name: name\r
28965                     };\r
28966                     if (typeof formatter === 'function') {\r
28967                         params.status = status;\r
28968                         return formatter(params);\r
28969                     }\r
28970                     else if (typeof formatter === 'string') {\r
28971                         return formatter.replace('{a}', params.seriesName);\r
28972                     }\r
28973                 },\r
28974 \r
28975                 setRoamZoom: function (zoom) {\r
28976                     var roamDetail = this.option.roamDetail;\r
28977                     roamDetail && (roamDetail.zoom = zoom);\r
28978                 },\r
28979 \r
28980                 setRoamPan: function (x, y) {\r
28981                     var roamDetail = this.option.roamDetail;\r
28982                     if (roamDetail) {\r
28983                         roamDetail.x = x;\r
28984                         roamDetail.y = y;\r
28985                     }\r
28986                 }\r
28987             });\r
28988 \r
28989 \r
28990 /***/ },\r
28991 /* 165 */\r
28992 /***/ function(module, exports, __webpack_require__) {\r
28993 \r
28994         \r
28995 \r
28996             var parseGeoJson = __webpack_require__(166);\r
28997 \r
28998             var zrUtil = __webpack_require__(3);\r
28999 \r
29000             var BoundingRect = __webpack_require__(15);\r
29001 \r
29002             var View = __webpack_require__(169);\r
29003 \r
29004 \r
29005             // Geo fix functions\r
29006             var geoFixFuncs = [\r
29007                 __webpack_require__(170),\r
29008                 __webpack_require__(171),\r
29009                 __webpack_require__(172)\r
29010             ];\r
29011 \r
29012             /**\r
29013              * [Geo description]\r
29014              * @param {string} name Geo name\r
29015              * @param {string} map Map type\r
29016              * @param {Object} geoJson\r
29017              * @param {Object} [specialAreas]\r
29018              *        Specify the positioned areas by left, top, width, height\r
29019              * @param {Object.<string, string>} [nameMap]\r
29020              *        Specify name alias\r
29021              */\r
29022             function Geo(name, map, geoJson, specialAreas, nameMap) {\r
29023 \r
29024                 View.call(this, name);\r
29025 \r
29026                 /**\r
29027                  * Map type\r
29028                  * @type {string}\r
29029                  */\r
29030                 this.map = map;\r
29031 \r
29032                 this._nameCoordMap = {};\r
29033 \r
29034                 this.loadGeoJson(geoJson, specialAreas, nameMap);\r
29035             }\r
29036 \r
29037             Geo.prototype = {\r
29038 \r
29039                 constructor: Geo,\r
29040 \r
29041                 type: 'geo',\r
29042 \r
29043                 /**\r
29044                  * @param {Array.<string>}\r
29045                  * @readOnly\r
29046                  */\r
29047                 dimensions: ['lng', 'lat'],\r
29048 \r
29049                 /**\r
29050                  * @param {Object} geoJson\r
29051                  * @param {Object} [specialAreas]\r
29052                  *        Specify the positioned areas by left, top, width, height\r
29053                  * @param {Object.<string, string>} [nameMap]\r
29054                  *        Specify name alias\r
29055                  */\r
29056                 loadGeoJson: function (geoJson, specialAreas, nameMap) {\r
29057                     // https://jsperf.com/try-catch-performance-overhead\r
29058                     try {\r
29059                         this.regions = geoJson ? parseGeoJson(geoJson) : [];\r
29060                     }\r
29061                     catch (e) {\r
29062                         throw 'Invalid geoJson format\n' + e;\r
29063                     }\r
29064                     specialAreas = specialAreas || {};\r
29065                     nameMap = nameMap || {};\r
29066                     var regions = this.regions;\r
29067                     var regionsMap = {};\r
29068                     for (var i = 0; i < regions.length; i++) {\r
29069                         var regionName = regions[i].name;\r
29070                         // Try use the alias in nameMap\r
29071                         regionName = nameMap[regionName] || regionName;\r
29072                         regions[i].name = regionName;\r
29073 \r
29074                         regionsMap[regionName] = regions[i];\r
29075                         // Add geoJson\r
29076                         this.addGeoCoord(regionName, regions[i].center);\r
29077 \r
29078                         // Some area like Alaska in USA map needs to be tansformed\r
29079                         // to look better\r
29080                         var specialArea = specialAreas[regionName];\r
29081                         if (specialArea) {\r
29082                             regions[i].transformTo(\r
29083                                 specialArea.left, specialArea.top, specialArea.width, specialArea.height\r
29084                             );\r
29085                         }\r
29086                     }\r
29087 \r
29088                     this._regionsMap = regionsMap;\r
29089 \r
29090                     this._rect = null;\r
29091 \r
29092                     zrUtil.each(geoFixFuncs, function (fixFunc) {\r
29093                         fixFunc(this);\r
29094                     }, this);\r
29095                 },\r
29096 \r
29097                 // Overwrite\r
29098                 transformTo: function (x, y, width, height) {\r
29099                     var rect = this.getBoundingRect();\r
29100 \r
29101                     rect = rect.clone();\r
29102                     // Longitute is inverted\r
29103                     rect.y = -rect.y - rect.height;\r
29104 \r
29105                     var viewTransform = this._viewTransform;\r
29106 \r
29107                     viewTransform.transform = rect.calculateTransform(\r
29108                         new BoundingRect(x, y, width, height)\r
29109                     );\r
29110 \r
29111                     viewTransform.decomposeTransform();\r
29112 \r
29113                     var scale = viewTransform.scale;\r
29114                     scale[1] = -scale[1];\r
29115 \r
29116                     viewTransform.updateTransform();\r
29117 \r
29118                     this._updateTransform();\r
29119                 },\r
29120 \r
29121                 /**\r
29122                  * @param {string} name\r
29123                  * @return {module:echarts/coord/geo/Region}\r
29124                  */\r
29125                 getRegion: function (name) {\r
29126                     return this._regionsMap[name];\r
29127                 },\r
29128 \r
29129                 /**\r
29130                  * Add geoCoord for indexing by name\r
29131                  * @param {string} name\r
29132                  * @param {Array.<number>} geoCoord\r
29133                  */\r
29134                 addGeoCoord: function (name, geoCoord) {\r
29135                     this._nameCoordMap[name] = geoCoord;\r
29136                 },\r
29137 \r
29138                 /**\r
29139                  * Get geoCoord by name\r
29140                  * @param {string} name\r
29141                  * @return {Array.<number>}\r
29142                  */\r
29143                 getGeoCoord: function (name) {\r
29144                     return this._nameCoordMap[name];\r
29145                 },\r
29146 \r
29147                 // Overwrite\r
29148                 getBoundingRect: function () {\r
29149                     if (this._rect) {\r
29150                         return this._rect;\r
29151                     }\r
29152                     var rect;\r
29153 \r
29154                     var regions = this.regions;\r
29155                     for (var i = 0; i < regions.length; i++) {\r
29156                         var regionRect = regions[i].getBoundingRect();\r
29157                         rect = rect || regionRect.clone();\r
29158                         rect.union(regionRect);\r
29159                     }\r
29160                     // FIXME Always return new ?\r
29161                     return (this._rect = rect || new BoundingRect(0, 0, 0, 0));\r
29162                 },\r
29163 \r
29164                 /**\r
29165                  * Convert series data to a list of points\r
29166                  * @param {module:echarts/data/List} data\r
29167                  * @param {boolean} stack\r
29168                  * @return {Array}\r
29169                  *  Return list of points. For example:\r
29170                  *  `[[10, 10], [20, 20], [30, 30]]`\r
29171                  */\r
29172                 dataToPoints: function (data) {\r
29173                     var item = [];\r
29174                     return data.mapArray(['lng', 'lat'], function (lon, lat) {\r
29175                         item[0] = lon;\r
29176                         item[1] = lat;\r
29177                         return this.dataToPoint(item);\r
29178                     }, this);\r
29179                 },\r
29180 \r
29181                 // Overwrite\r
29182                 /**\r
29183                  * @param {string|Array.<number>} data\r
29184                  * @return {Array.<number>}\r
29185                  */\r
29186                 dataToPoint: function (data) {\r
29187                     if (typeof data === 'string') {\r
29188                         // Map area name to geoCoord\r
29189                         data = this.getGeoCoord(data);\r
29190                     }\r
29191                     if (data) {\r
29192                         return View.prototype.dataToPoint.call(this, data);\r
29193                     }\r
29194                 }\r
29195             };\r
29196 \r
29197             zrUtil.mixin(Geo, View);\r
29198 \r
29199             module.exports = Geo;\r
29200 \r
29201 \r
29202 /***/ },\r
29203 /* 166 */\r
29204 /***/ function(module, exports, __webpack_require__) {\r
29205 \r
29206         /**\r
29207          * Parse and decode geo json\r
29208          * @module echarts/coord/geo/parseGeoJson\r
29209          */\r
29210 \r
29211 \r
29212             var zrUtil = __webpack_require__(3);\r
29213 \r
29214             var Region = __webpack_require__(167);\r
29215 \r
29216             function decode(json) {\r
29217                 if (!json.UTF8Encoding) {\r
29218                     return json;\r
29219                 }\r
29220                 var features = json.features;\r
29221 \r
29222                 for (var f = 0; f < features.length; f++) {\r
29223                     var feature = features[f];\r
29224                     var geometry = feature.geometry;\r
29225                     var coordinates = geometry.coordinates;\r
29226                     var encodeOffsets = geometry.encodeOffsets;\r
29227 \r
29228                     for (var c = 0; c < coordinates.length; c++) {\r
29229                         var coordinate = coordinates[c];\r
29230 \r
29231                         if (geometry.type === 'Polygon') {\r
29232                             coordinates[c] = decodePolygon(\r
29233                                 coordinate,\r
29234                                 encodeOffsets[c]\r
29235                             );\r
29236                         }\r
29237                         else if (geometry.type === 'MultiPolygon') {\r
29238                             for (var c2 = 0; c2 < coordinate.length; c2++) {\r
29239                                 var polygon = coordinate[c2];\r
29240                                 coordinate[c2] = decodePolygon(\r
29241                                     polygon,\r
29242                                     encodeOffsets[c][c2]\r
29243                                 );\r
29244                             }\r
29245                         }\r
29246                     }\r
29247                 }\r
29248                 // Has been decoded\r
29249                 json.UTF8Encoding = false;\r
29250                 return json;\r
29251             }\r
29252 \r
29253             function decodePolygon(coordinate, encodeOffsets) {\r
29254                 var result = [];\r
29255                 var prevX = encodeOffsets[0];\r
29256                 var prevY = encodeOffsets[1];\r
29257 \r
29258                 for (var i = 0; i < coordinate.length; i += 2) {\r
29259                     var x = coordinate.charCodeAt(i) - 64;\r
29260                     var y = coordinate.charCodeAt(i + 1) - 64;\r
29261                     // ZigZag decoding\r
29262                     x = (x >> 1) ^ (-(x & 1));\r
29263                     y = (y >> 1) ^ (-(y & 1));\r
29264                     // Delta deocding\r
29265                     x += prevX;\r
29266                     y += prevY;\r
29267 \r
29268                     prevX = x;\r
29269                     prevY = y;\r
29270                     // Dequantize\r
29271                     result.push([x / 1024, y / 1024]);\r
29272                 }\r
29273 \r
29274                 return result;\r
29275             }\r
29276 \r
29277             /**\r
29278              * @inner\r
29279              */\r
29280             function flattern2D(array) {\r
29281                 var ret = [];\r
29282                 for (var i = 0; i < array.length; i++) {\r
29283                     for (var k = 0; k < array[i].length; k++) {\r
29284                         ret.push(array[i][k]);\r
29285                     }\r
29286                 }\r
29287                 return ret;\r
29288             }\r
29289 \r
29290             /**\r
29291              * @alias module:echarts/coord/geo/parseGeoJson\r
29292              * @param {Object} geoJson\r
29293              * @return {module:zrender/container/Group}\r
29294              */\r
29295             module.exports = function (geoJson) {\r
29296 \r
29297                 decode(geoJson);\r
29298 \r
29299                 return zrUtil.map(zrUtil.filter(geoJson.features, function (featureObj) {\r
29300                     // Output of mapshaper may have geometry null\r
29301                     return featureObj.geometry && featureObj.properties;\r
29302                 }), function (featureObj) {\r
29303                     var properties = featureObj.properties;\r
29304                     var geometry = featureObj.geometry;\r
29305 \r
29306                     var coordinates = geometry.coordinates;\r
29307 \r
29308                     if (geometry.type === 'MultiPolygon') {\r
29309                         coordinates = flattern2D(coordinates);\r
29310                     }\r
29311 \r
29312                     return new Region(\r
29313                         properties.name,\r
29314                         coordinates,\r
29315                         properties.cp\r
29316                     );\r
29317                 });\r
29318             };\r
29319 \r
29320 \r
29321 /***/ },\r
29322 /* 167 */\r
29323 /***/ function(module, exports, __webpack_require__) {\r
29324 \r
29325         /**\r
29326          * @module echarts/coord/geo/Region\r
29327          */\r
29328 \r
29329 \r
29330             var polygonContain = __webpack_require__(168);\r
29331 \r
29332             var BoundingRect = __webpack_require__(15);\r
29333 \r
29334             var bbox = __webpack_require__(50);\r
29335             var vec2 = __webpack_require__(16);\r
29336 \r
29337             /**\r
29338              * @param {string} name\r
29339              * @param {Array} contours\r
29340              * @param {Array.<number>} cp\r
29341              */\r
29342             function Region(name, contours, cp) {\r
29343 \r
29344                 /**\r
29345                  * @type {string}\r
29346                  * @readOnly\r
29347                  */\r
29348                 this.name = name;\r
29349 \r
29350                 /**\r
29351                  * @type {Array.<Array>}\r
29352                  * @readOnly\r
29353                  */\r
29354                 this.contours = contours;\r
29355 \r
29356                 if (!cp) {\r
29357                     var rect = this.getBoundingRect();\r
29358                     cp = [\r
29359                         rect.x + rect.width / 2,\r
29360                         rect.y + rect.height / 2\r
29361                     ];\r
29362                 }\r
29363                 else {\r
29364                     cp = [cp[0], cp[1]];\r
29365                 }\r
29366                 /**\r
29367                  * @type {Array.<number>}\r
29368                  */\r
29369                 this.center = cp;\r
29370             }\r
29371 \r
29372             Region.prototype = {\r
29373 \r
29374                 constructor: Region,\r
29375 \r
29376                 /**\r
29377                  * @return {module:zrender/core/BoundingRect}\r
29378                  */\r
29379                 getBoundingRect: function () {\r
29380                     var rect = this._rect;\r
29381                     if (rect) {\r
29382                         return rect;\r
29383                     }\r
29384 \r
29385                     var MAX_NUMBER = Number.MAX_VALUE;\r
29386                     var min = [MAX_NUMBER, MAX_NUMBER];\r
29387                     var max = [-MAX_NUMBER, -MAX_NUMBER];\r
29388                     var min2 = [];\r
29389                     var max2 = [];\r
29390                     var contours = this.contours;\r
29391                     for (var i = 0; i < contours.length; i++) {\r
29392                         bbox.fromPoints(contours[i], min2, max2);\r
29393                         vec2.min(min, min, min2);\r
29394                         vec2.max(max, max, max2);\r
29395                     }\r
29396                     // No data\r
29397                     if (i === 0) {\r
29398                         min[0] = min[1] = max[0] = max[1] = 0;\r
29399                     }\r
29400 \r
29401                     return (this._rect = new BoundingRect(\r
29402                         min[0], min[1], max[0] - min[0], max[1] - min[1]\r
29403                     ));\r
29404                 },\r
29405 \r
29406                 /**\r
29407                  * @param {<Array.<number>} coord\r
29408                  * @return {boolean}\r
29409                  */\r
29410                 contain: function (coord) {\r
29411                     var rect = this.getBoundingRect();\r
29412                     var contours = this.contours;\r
29413                     if (rect.contain(coord[0], coord[1])) {\r
29414                         for (var i = 0, len = contours.length; i < len; i++) {\r
29415                             if (polygonContain.contain(contours[i], coord[0], coord[1])) {\r
29416                                 return true;\r
29417                             }\r
29418                         }\r
29419                     }\r
29420                     return false;\r
29421                 },\r
29422 \r
29423                 transformTo: function (x, y, width, height) {\r
29424                     var rect = this.getBoundingRect();\r
29425                     var aspect = rect.width / rect.height;\r
29426                     if (!width) {\r
29427                         width = aspect * height;\r
29428                     }\r
29429                     else if (!height) {\r
29430                         height = width / aspect ;\r
29431                     }\r
29432                     var target = new BoundingRect(x, y, width, height);\r
29433                     var transform = rect.calculateTransform(target);\r
29434                     var contours = this.contours;\r
29435                     for (var i = 0; i < contours.length; i++) {\r
29436                         for (var p = 0; p < contours[i].length; p++) {\r
29437                             vec2.applyTransform(contours[i][p], contours[i][p], transform);\r
29438                         }\r
29439                     }\r
29440                     rect = this._rect;\r
29441                     rect.copy(target);\r
29442                     // Update center\r
29443                     this.center = [\r
29444                         rect.x + rect.width / 2,\r
29445                         rect.y + rect.height / 2\r
29446                     ];\r
29447                 }\r
29448             };\r
29449 \r
29450             module.exports = Region;\r
29451 \r
29452 \r
29453 /***/ },\r
29454 /* 168 */\r
29455 /***/ function(module, exports, __webpack_require__) {\r
29456 \r
29457         \r
29458 \r
29459             var windingLine = __webpack_require__(57);\r
29460 \r
29461             var EPSILON = 1e-8;\r
29462 \r
29463             function isAroundEqual(a, b) {\r
29464                 return Math.abs(a - b) < EPSILON;\r
29465             }\r
29466 \r
29467             function contain(points, x, y) {\r
29468                 var w = 0;\r
29469                 var p = points[0];\r
29470 \r
29471                 if (!p) {\r
29472                     return false;\r
29473                 }\r
29474 \r
29475                 for (var i = 1; i < points.length; i++) {\r
29476                     var p2 = points[i];\r
29477                     w += windingLine(p[0], p[1], p2[0], p2[1], x, y);\r
29478                     p = p2;\r
29479                 }\r
29480 \r
29481                 // Close polygon\r
29482                 var p0 = points[0];\r
29483                 if (!isAroundEqual(p[0], p0[0]) || !isAroundEqual(p[1], p0[1])) {\r
29484                     w += windingLine(p[0], p[1], p0[0], p0[1], x, y);\r
29485                 }\r
29486 \r
29487                 return w !== 0;\r
29488             }\r
29489 \r
29490 \r
29491             module.exports = {\r
29492                 contain: contain\r
29493             };\r
29494 \r
29495 \r
29496 /***/ },\r
29497 /* 169 */\r
29498 /***/ function(module, exports, __webpack_require__) {\r
29499 \r
29500         /**\r
29501          * Simple view coordinate system\r
29502          * Mapping given x, y to transformd view x, y\r
29503          */\r
29504 \r
29505 \r
29506             var vector = __webpack_require__(16);\r
29507             var matrix = __webpack_require__(17);\r
29508 \r
29509             var Transformable = __webpack_require__(33);\r
29510             var zrUtil = __webpack_require__(3);\r
29511 \r
29512             var BoundingRect = __webpack_require__(15);\r
29513 \r
29514             var v2ApplyTransform = vector.applyTransform;\r
29515 \r
29516             // Dummy transform node\r
29517             function TransformDummy() {\r
29518                 Transformable.call(this);\r
29519             }\r
29520             zrUtil.mixin(TransformDummy, Transformable);\r
29521 \r
29522             function View(name) {\r
29523                 /**\r
29524                  * @type {string}\r
29525                  */\r
29526                 this.name = name;\r
29527 \r
29528                 /**\r
29529                  * @type {Array.<number>}\r
29530                  */\r
29531                 this.zoomLimit;\r
29532 \r
29533                 Transformable.call(this);\r
29534 \r
29535                 this._roamTransform = new TransformDummy();\r
29536 \r
29537                 this._viewTransform = new TransformDummy();\r
29538             }\r
29539 \r
29540             View.prototype = {\r
29541 \r
29542                 constructor: View,\r
29543 \r
29544                 type: 'view',\r
29545 \r
29546                 /**\r
29547                  * @param {Array.<string>}\r
29548                  * @readOnly\r
29549                  */\r
29550                 dimensions: ['x', 'y'],\r
29551 \r
29552                 /**\r
29553                  * Set bounding rect\r
29554                  * @param {number} x\r
29555                  * @param {number} y\r
29556                  * @param {number} width\r
29557                  * @param {number} height\r
29558                  */\r
29559 \r
29560                 // PENDING to getRect\r
29561                 setBoundingRect: function (x, y, width, height) {\r
29562                     this._rect = new BoundingRect(x, y, width, height);\r
29563                     return this._rect;\r
29564                 },\r
29565 \r
29566                 /**\r
29567                  * @return {module:zrender/core/BoundingRect}\r
29568                  */\r
29569                 // PENDING to getRect\r
29570                 getBoundingRect: function () {\r
29571                     return this._rect;\r
29572                 },\r
29573 \r
29574                 /**\r
29575                  * @param {number} x\r
29576                  * @param {number} y\r
29577                  * @param {number} width\r
29578                  * @param {number} height\r
29579                  */\r
29580                 setViewRect: function (x, y, width, height) {\r
29581                     this.transformTo(x, y, width, height);\r
29582                     this._viewRect = new BoundingRect(x, y, width, height);\r
29583                 },\r
29584 \r
29585                 /**\r
29586                  * Transformed to particular position and size\r
29587                  * @param {number} x\r
29588                  * @param {number} y\r
29589                  * @param {number} width\r
29590                  * @param {number} height\r
29591                  */\r
29592                 transformTo: function (x, y, width, height) {\r
29593                     var rect = this.getBoundingRect();\r
29594                     var viewTransform = this._viewTransform;\r
29595 \r
29596                     viewTransform.transform = rect.calculateTransform(\r
29597                         new BoundingRect(x, y, width, height)\r
29598                     );\r
29599 \r
29600                     viewTransform.decomposeTransform();\r
29601 \r
29602                     this._updateTransform();\r
29603                 },\r
29604 \r
29605                 /**\r
29606                  * @param {number} x\r
29607                  * @param {number} y\r
29608                  */\r
29609                 setPan: function (x, y) {\r
29610 \r
29611                     this._roamTransform.position = [x, y];\r
29612 \r
29613                     this._updateTransform();\r
29614                 },\r
29615 \r
29616                 /**\r
29617                  * @param {number} zoom\r
29618                  */\r
29619                 setZoom: function (zoom) {\r
29620                     var zoomLimit = this.zoomLimit;\r
29621                     if (zoomLimit) {\r
29622                         zoom = Math.max(\r
29623                             Math.min(zoom, zoomLimit.max), zoomLimit.min\r
29624                         );\r
29625                     }\r
29626 \r
29627                     this._roamTransform.scale = [zoom, zoom];\r
29628 \r
29629                     this._updateTransform();\r
29630                 },\r
29631 \r
29632                 /**\r
29633                  * @return {Array.<number}\r
29634                  */\r
29635                 getRoamTransform: function () {\r
29636                     return this._roamTransform.transform;\r
29637                 },\r
29638 \r
29639                 /**\r
29640                  * Update transform from roam and mapLocation\r
29641                  * @private\r
29642                  */\r
29643                 _updateTransform: function () {\r
29644                     var roamTransform = this._roamTransform;\r
29645                     var viewTransform = this._viewTransform;\r
29646                     // var scale = this.scale;\r
29647 \r
29648                     viewTransform.parent = roamTransform;\r
29649                     roamTransform.updateTransform();\r
29650                     viewTransform.updateTransform();\r
29651 \r
29652                     viewTransform.transform\r
29653                         && matrix.copy(this.transform || (this.transform = []), viewTransform.transform);\r
29654 \r
29655                     this.decomposeTransform();\r
29656                 },\r
29657 \r
29658                 /**\r
29659                  * @return {module:zrender/core/BoundingRect}\r
29660                  */\r
29661                 getViewRect: function () {\r
29662                     return this._viewRect;\r
29663                 },\r
29664 \r
29665                 /**\r
29666                  * Convert a single (lon, lat) data item to (x, y) point.\r
29667                  * @param {Array.<number>} data\r
29668                  * @return {Array.<number>}\r
29669                  */\r
29670                 dataToPoint: function (data) {\r
29671                     var transform = this.transform;\r
29672                     return transform\r
29673                         ? v2ApplyTransform([], data, transform)\r
29674                         : [data[0], data[1]];\r
29675                 },\r
29676 \r
29677                 /**\r
29678                  * Convert a (x, y) point to (lon, lat) data\r
29679                  * @param {Array.<number>} point\r
29680                  * @return {Array.<number>}\r
29681                  */\r
29682                 pointToData: function (point) {\r
29683                     var invTransform = this.invTransform;\r
29684                     return invTransform\r
29685                         ? v2ApplyTransform([], point, invTransform)\r
29686                         : [point[0], point[1]];\r
29687                 }\r
29688 \r
29689                 /**\r
29690                  * @return {number}\r
29691                  */\r
29692                 // getScalarScale: function () {\r
29693                 //     // Use determinant square root of transform to mutiply scalar\r
29694                 //     var m = this.transform;\r
29695                 //     var det = Math.sqrt(Math.abs(m[0] * m[3] - m[2] * m[1]));\r
29696                 //     return det;\r
29697                 // }\r
29698             };\r
29699 \r
29700             zrUtil.mixin(View, Transformable);\r
29701 \r
29702             module.exports = View;\r
29703 \r
29704 \r
29705 /***/ },\r
29706 /* 170 */\r
29707 /***/ function(module, exports, __webpack_require__) {\r
29708 \r
29709         // Fix for 南海诸岛\r
29710 \r
29711 \r
29712             var Region = __webpack_require__(167);\r
29713 \r
29714             var geoCoord = [126, 25];\r
29715 \r
29716             var points = [\r
29717                 [[0,3.5],[7,11.2],[15,11.9],[30,7],[42,0.7],[52,0.7],\r
29718                  [56,7.7],[59,0.7],[64,0.7],[64,0],[5,0],[0,3.5]],\r
29719                 [[13,16.1],[19,14.7],[16,21.7],[11,23.1],[13,16.1]],\r
29720                 [[12,32.2],[14,38.5],[15,38.5],[13,32.2],[12,32.2]],\r
29721                 [[16,47.6],[12,53.2],[13,53.2],[18,47.6],[16,47.6]],\r
29722                 [[6,64.4],[8,70],[9,70],[8,64.4],[6,64.4]],\r
29723                 [[23,82.6],[29,79.8],[30,79.8],[25,82.6],[23,82.6]],\r
29724                 [[37,70.7],[43,62.3],[44,62.3],[39,70.7],[37,70.7]],\r
29725                 [[48,51.1],[51,45.5],[53,45.5],[50,51.1],[48,51.1]],\r
29726                 [[51,35],[51,28.7],[53,28.7],[53,35],[51,35]],\r
29727                 [[52,22.4],[55,17.5],[56,17.5],[53,22.4],[52,22.4]],\r
29728                 [[58,12.6],[62,7],[63,7],[60,12.6],[58,12.6]],\r
29729                 [[0,3.5],[0,93.1],[64,93.1],[64,0],[63,0],[63,92.4],\r
29730                  [1,92.4],[1,3.5],[0,3.5]]\r
29731             ];\r
29732             for (var i = 0; i < points.length; i++) {\r
29733                 for (var k = 0; k < points[i].length; k++) {\r
29734                     points[i][k][0] /= 10.5;\r
29735                     points[i][k][1] /= -10.5 / 0.75;\r
29736 \r
29737                     points[i][k][0] += geoCoord[0];\r
29738                     points[i][k][1] += geoCoord[1];\r
29739                 }\r
29740             }\r
29741             module.exports = function (geo) {\r
29742                 if (geo.map === 'china') {\r
29743                     geo.regions.push(new Region(\r
29744                         '南海诸岛', points, geoCoord\r
29745                     ));\r
29746                 }\r
29747             };\r
29748 \r
29749 \r
29750 /***/ },\r
29751 /* 171 */\r
29752 /***/ function(module, exports, __webpack_require__) {\r
29753 \r
29754         \r
29755 \r
29756             var zrUtil = __webpack_require__(3);\r
29757 \r
29758             var coordsOffsetMap = {\r
29759                 '南海诸岛' : [32, 80],\r
29760                 // 全国\r
29761                 '广东': [0, -10],\r
29762                 '香港': [10, 5],\r
29763                 '澳门': [-10, 10],\r
29764                 //'北京': [-10, 0],\r
29765                 '天津': [5, 5]\r
29766             };\r
29767 \r
29768             module.exports = function (geo) {\r
29769                 zrUtil.each(geo.regions, function (region) {\r
29770                     var coordFix = coordsOffsetMap[region.name];\r
29771                     if (coordFix) {\r
29772                         var cp = region.center;\r
29773                         cp[0] += coordFix[0] / 10.5;\r
29774                         cp[1] += -coordFix[1] / (10.5 / 0.75);\r
29775                     }\r
29776                 });\r
29777             };\r
29778 \r
29779 \r
29780 /***/ },\r
29781 /* 172 */\r
29782 /***/ function(module, exports, __webpack_require__) {\r
29783 \r
29784         \r
29785 \r
29786             var zrUtil = __webpack_require__(3);\r
29787 \r
29788             var geoCoordMap = {\r
29789                 'Russia': [100, 60],\r
29790                 'United States of America': [-99, 38]\r
29791             };\r
29792 \r
29793             module.exports = function (geo) {\r
29794                 zrUtil.each(geo.regions, function (region) {\r
29795                     var geoCoord = geoCoordMap[region.name];\r
29796                     if (geoCoord) {\r
29797                         var cp = region.center;\r
29798                         cp[0] = geoCoord[0];\r
29799                         cp[1] = geoCoord[1];\r
29800                     }\r
29801                 });\r
29802             };\r
29803 \r
29804 \r
29805 /***/ },\r
29806 /* 173 */\r
29807 /***/ function(module, exports, __webpack_require__) {\r
29808 \r
29809         \r
29810 \r
29811             var zrUtil = __webpack_require__(3);\r
29812 \r
29813             module.exports = function (ecModel) {\r
29814 \r
29815                 var processedMapType = {};\r
29816 \r
29817                 ecModel.eachSeriesByType('map', function (mapSeries) {\r
29818                     var mapType = mapSeries.get('mapType');\r
29819                     if (processedMapType[mapType]) {\r
29820                         return;\r
29821                     }\r
29822 \r
29823                     var mapSymbolOffsets = {};\r
29824 \r
29825                     zrUtil.each(mapSeries.seriesGroup, function (subMapSeries) {\r
29826                         var geo = subMapSeries.coordinateSystem;\r
29827                         var data = subMapSeries.getData();\r
29828                         if (subMapSeries.get('showLegendSymbol') && ecModel.getComponent('legend')) {\r
29829                             data.each('value', function (value, idx) {\r
29830                                 var name = data.getName(idx);\r
29831                                 var region = geo.getRegion(name);\r
29832 \r
29833                                 // No region or no value\r
29834                                 // In MapSeries data regions will be filled with NaN\r
29835                                 // If they are not in the series.data array.\r
29836                                 // So here must validate if value is NaN\r
29837                                 if (!region || isNaN(value)) {\r
29838                                     return;\r
29839                                 }\r
29840 \r
29841                                 var offset = mapSymbolOffsets[name] || 0;\r
29842 \r
29843                                 var point = geo.dataToPoint(region.center);\r
29844 \r
29845                                 mapSymbolOffsets[name] = offset + 1;\r
29846 \r
29847                                 data.setItemLayout(idx, {\r
29848                                     point: point,\r
29849                                     offset: offset\r
29850                                 });\r
29851                             });\r
29852                         }\r
29853                     });\r
29854 \r
29855                     // Show label of those region not has legendSymbol(which is offset 0)\r
29856                     var data = mapSeries.getData();\r
29857                     data.each(function (idx) {\r
29858                         var name = data.getName(idx);\r
29859                         var layout = data.getItemLayout(idx) || {};\r
29860                         layout.showLabel = !mapSymbolOffsets[name];\r
29861                         data.setItemLayout(idx, layout);\r
29862                     });\r
29863 \r
29864                     processedMapType[mapType] = true;\r
29865                 });\r
29866             };\r
29867 \r
29868 \r
29869 /***/ },\r
29870 /* 174 */\r
29871 /***/ function(module, exports) {\r
29872 \r
29873         \r
29874             module.exports = function (ecModel) {\r
29875                 ecModel.eachSeriesByType('map', function (seriesModel) {\r
29876                     var colorList = seriesModel.get('color');\r
29877                     var itemStyleModel = seriesModel.getModel('itemStyle.normal');\r
29878 \r
29879                     var areaColor = itemStyleModel.get('areaColor');\r
29880                     var color = itemStyleModel.get('color')\r
29881                         || colorList[seriesModel.seriesIndex % colorList.length];\r
29882 \r
29883                     seriesModel.getData().setVisual({\r
29884                         'areaColor': areaColor,\r
29885                         'color': color\r
29886                     });\r
29887                 });\r
29888             };\r
29889 \r
29890 \r
29891 /***/ },\r
29892 /* 175 */\r
29893 /***/ function(module, exports, __webpack_require__) {\r
29894 \r
29895         \r
29896 \r
29897             var zrUtil = __webpack_require__(3);\r
29898 \r
29899             // FIXME 公用?\r
29900             /**\r
29901              * @param {Array.<module:echarts/data/List>} datas\r
29902              * @param {string} statisticsType 'average' 'sum'\r
29903              * @inner\r
29904              */\r
29905             function dataStatistics(datas, statisticsType) {\r
29906                 var dataNameMap = {};\r
29907                 var dims = ['value'];\r
29908 \r
29909                 for (var i = 0; i < datas.length; i++) {\r
29910                     datas[i].each(dims, function (value, idx) {\r
29911                         var name = datas[i].getName(idx);\r
29912                         dataNameMap[name] = dataNameMap[name] || [];\r
29913                         if (!isNaN(value)) {\r
29914                             dataNameMap[name].push(value);\r
29915                         }\r
29916                     });\r
29917                 }\r
29918 \r
29919                 return datas[0].map(dims, function (value, idx) {\r
29920                     var name = datas[0].getName(idx);\r
29921                     var sum = 0;\r
29922                     var min = Infinity;\r
29923                     var max = -Infinity;\r
29924                     var len = dataNameMap[name].length;\r
29925                     for (var i = 0; i < len; i++) {\r
29926                         min = Math.min(min, dataNameMap[name][i]);\r
29927                         max = Math.max(max, dataNameMap[name][i]);\r
29928                         sum += dataNameMap[name][i];\r
29929                     }\r
29930                     var result;\r
29931                     if (statisticsType === 'min') {\r
29932                         result = min;\r
29933                     }\r
29934                     else if (statisticsType === 'max') {\r
29935                         result = max;\r
29936                     }\r
29937                     else if (statisticsType === 'average') {\r
29938                         result = sum / len;\r
29939                     }\r
29940                     else {\r
29941                         result = sum;\r
29942                     }\r
29943                     return len === 0 ? NaN : result;\r
29944                 });\r
29945             }\r
29946 \r
29947             module.exports = function (ecModel) {\r
29948                 var seriesGroupByMapType = {};\r
29949                 ecModel.eachSeriesByType('map', function (seriesModel) {\r
29950                     var mapType = seriesModel.get('map');\r
29951                     seriesGroupByMapType[mapType] = seriesGroupByMapType[mapType] || [];\r
29952                     seriesGroupByMapType[mapType].push(seriesModel);\r
29953                 });\r
29954 \r
29955                 zrUtil.each(seriesGroupByMapType, function (seriesList, mapType) {\r
29956                     var data = dataStatistics(\r
29957                         zrUtil.map(seriesList, function (seriesModel) {\r
29958                             return seriesModel.getData();\r
29959                         }),\r
29960                         seriesList[0].get('mapValueCalculation')\r
29961                     );\r
29962 \r
29963                     seriesList[0].seriesGroup = [];\r
29964 \r
29965                     seriesList[0].setData(data);\r
29966 \r
29967                     // FIXME Put where?\r
29968                     for (var i = 0; i < seriesList.length; i++) {\r
29969                         seriesList[i].seriesGroup = seriesList;\r
29970                         seriesList[i].needsDrawMap = i === 0;\r
29971                     }\r
29972                 });\r
29973             };\r
29974 \r
29975 \r
29976 /***/ },\r
29977 /* 176 */\r
29978 /***/ function(module, exports, __webpack_require__) {\r
29979 \r
29980         \r
29981 \r
29982             var zrUtil = __webpack_require__(3);\r
29983             var geoProps = [\r
29984                 'x', 'y', 'x2', 'y2', 'width', 'height', 'map', 'roam', 'roamDetail', 'label', 'itemStyle'\r
29985             ];\r
29986 \r
29987             var geoCoordsMap = {};\r
29988 \r
29989             function createGeoFromMap(mapSeriesOpt) {\r
29990                 var geoOpt = {};\r
29991                 zrUtil.each(geoProps, function (propName) {\r
29992                     if (mapSeriesOpt[propName] != null) {\r
29993                         geoOpt[propName] = mapSeriesOpt[propName];\r
29994                     }\r
29995                 });\r
29996                 return geoOpt;\r
29997             }\r
29998             module.exports = function (option) {\r
29999                 // Save geoCoord\r
30000                 var mapSeries = [];\r
30001                 zrUtil.each(option.series, function (seriesOpt) {\r
30002                     if (seriesOpt.type === 'map') {\r
30003                         mapSeries.push(seriesOpt);\r
30004                     }\r
30005                     zrUtil.extend(geoCoordsMap, seriesOpt.geoCoord);\r
30006                 });\r
30007 \r
30008                 var newCreatedGeoOptMap = {};\r
30009                 zrUtil.each(mapSeries, function (seriesOpt) {\r
30010                     seriesOpt.map = seriesOpt.map || seriesOpt.mapType;\r
30011                     // Put x, y, width, height, x2, y2 in the top level\r
30012                     zrUtil.defaults(seriesOpt, seriesOpt.mapLocation);\r
30013                     if (seriesOpt.markPoint) {\r
30014                         var markPoint = seriesOpt.markPoint;\r
30015                         // Convert name or geoCoord in markPoint to lng and lat\r
30016                         // For example\r
30017                         // { name: 'xxx', value: 10} Or\r
30018                         // { geoCoord: [lng, lat], value: 10} to\r
30019                         // { name: 'xxx', value: [lng, lat, 10]}\r
30020                         markPoint.data = zrUtil.map(markPoint.data, function (dataOpt) {\r
30021                             if (!zrUtil.isArray(dataOpt.value)) {\r
30022                                 var geoCoord;\r
30023                                 if (dataOpt.geoCoord) {\r
30024                                     geoCoord = dataOpt.geoCoord;\r
30025                                 }\r
30026                                 else if (dataOpt.name) {\r
30027                                     geoCoord = geoCoordsMap[dataOpt.name];\r
30028                                 }\r
30029                                 var newValue = geoCoord ? [geoCoord[0], geoCoord[1]] : [NaN, NaN];\r
30030                                 if (dataOpt.value != null) {\r
30031                                     newValue.push(dataOpt.value);\r
30032                                 }\r
30033                                 dataOpt.value = newValue;\r
30034                             }\r
30035                             return dataOpt;\r
30036                         });\r
30037                         // Convert map series which only has markPoint without data to scatter series\r
30038                         // FIXME\r
30039                         if (!(seriesOpt.data && seriesOpt.data.length)) {\r
30040                             if (!option.geo) {\r
30041                                 option.geo = [];\r
30042                             }\r
30043 \r
30044                             // Use same geo if multiple map series has same map type\r
30045                             var geoOpt = newCreatedGeoOptMap[seriesOpt.map];\r
30046                             if (!geoOpt) {\r
30047                                 geoOpt = newCreatedGeoOptMap[seriesOpt.map] = createGeoFromMap(seriesOpt);\r
30048                                 option.geo.push(geoOpt);\r
30049                             }\r
30050 \r
30051                             var scatterSeries = seriesOpt.markPoint;\r
30052                             scatterSeries.type = option.effect && option.effect.show ? 'effectScatter' : 'scatter';\r
30053                             scatterSeries.coordinateSystem = 'geo';\r
30054                             scatterSeries.geoIndex = zrUtil.indexOf(option.geo, geoOpt);\r
30055                             scatterSeries.name = seriesOpt.name;\r
30056 \r
30057                             option.series.splice(zrUtil.indexOf(option.series, seriesOpt), 1, scatterSeries);\r
30058                         }\r
30059                     }\r
30060                 });\r
30061             };\r
30062 \r
30063 \r
30064 /***/ },\r
30065 /* 177 */\r
30066 /***/ function(module, exports, __webpack_require__) {\r
30067 \r
30068         \r
30069 \r
30070             var echarts = __webpack_require__(1);\r
30071 \r
30072             __webpack_require__(178);\r
30073             __webpack_require__(182);\r
30074             __webpack_require__(185);\r
30075 \r
30076             echarts.registerVisualCoding('chart', __webpack_require__(186));\r
30077 \r
30078             echarts.registerLayout(__webpack_require__(188));\r
30079 \r
30080 \r
30081 /***/ },\r
30082 /* 178 */\r
30083 /***/ function(module, exports, __webpack_require__) {\r
30084 \r
30085         \r
30086 \r
30087             var SeriesModel = __webpack_require__(27);\r
30088             var Tree = __webpack_require__(179);\r
30089             var zrUtil = __webpack_require__(3);\r
30090             var Model = __webpack_require__(8);\r
30091             var formatUtil = __webpack_require__(6);\r
30092             var helper = __webpack_require__(181);\r
30093             var encodeHTML = formatUtil.encodeHTML;\r
30094             var addCommas = formatUtil.addCommas;\r
30095 \r
30096 \r
30097             module.exports = SeriesModel.extend({\r
30098 \r
30099                 type: 'series.treemap',\r
30100 \r
30101                 dependencies: ['grid', 'polar'],\r
30102 \r
30103                 /**\r
30104                  * @type {module:echarts/data/Tree~Node}\r
30105                  */\r
30106                 _viewRoot: null,\r
30107 \r
30108                 defaultOption: {\r
30109                     // center: ['50%', '50%'],          // not supported in ec3.\r
30110                     // size: ['80%', '80%'],            // deprecated, compatible with ec2.\r
30111                     left: 'center',\r
30112                     top: 'middle',\r
30113                     right: null,\r
30114                     bottom: null,\r
30115                     width: '80%',\r
30116                     height: '80%',\r
30117                     sort: true,                         // Can be null or false or true\r
30118                                                         // (order by desc default, asc not supported yet (strange effect))\r
30119                     clipWindow: 'origin',               // Size of clipped window when zooming. 'origin' or 'fullscreen'\r
30120                     squareRatio: 0.5 * (1 + Math.sqrt(5)), // golden ratio\r
30121                     leafDepth: null,                    // Nodes on depth from root are regarded as leaves.\r
30122                                                         // Count from zero (zero represents only view root).\r
30123                     visualDimension: 0,                 // Can be 0, 1, 2, 3.\r
30124                     zoomToNodeRatio: 0.32 * 0.32,       // Be effective when using zoomToNode. Specify the proportion of the\r
30125                                                         // target node area in the view area.\r
30126                     roam: true,                         // true, false, 'scale' or 'zoom', 'move'.\r
30127                     nodeClick: 'zoomToNode',            // Leaf node click behaviour: 'zoomToNode', 'link', false.\r
30128                                                         // If leafDepth is set and clicking a node which has children but\r
30129                                                         // be on left depth, the behaviour would be changing root. Otherwise\r
30130                                                         // use behavious defined above.\r
30131                     animation: true,\r
30132                     animationDurationUpdate: 900,\r
30133                     animationEasing: 'quinticInOut',\r
30134                     breadcrumb: {\r
30135                         show: true,\r
30136                         height: 22,\r
30137                         left: 'center',\r
30138                         top: 'bottom',\r
30139                         // right\r
30140                         // bottom\r
30141                         emptyItemWidth: 25,             // Width of empty node.\r
30142                         itemStyle: {\r
30143                             normal: {\r
30144                                 color: 'rgba(0,0,0,0.7)', //'#5793f3',\r
30145                                 borderColor: 'rgba(255,255,255,0.7)',\r
30146                                 borderWidth: 1,\r
30147                                 shadowColor: 'rgba(150,150,150,1)',\r
30148                                 shadowBlur: 3,\r
30149                                 shadowOffsetX: 0,\r
30150                                 shadowOffsetY: 0,\r
30151                                 textStyle: {\r
30152                                     color: '#fff'\r
30153                                 }\r
30154                             },\r
30155                             emphasis: {\r
30156                                 textStyle: {}\r
30157                             }\r
30158                         }\r
30159                     },\r
30160                     label: {\r
30161                         normal: {\r
30162                             show: true,\r
30163                             position: ['50%', '50%'], // Can be 5, '5%' or position stirng like 'insideTopLeft', ...\r
30164                             textStyle: {\r
30165                                 align: 'center',\r
30166                                 baseline: 'middle',\r
30167                                 color: '#fff',\r
30168                                 ellipsis: true\r
30169                             }\r
30170                         }\r
30171                     },\r
30172                     itemStyle: {\r
30173                         normal: {\r
30174                             color: null,            // Can be 'none' if not necessary.\r
30175                             colorAlpha: null,       // Can be 'none' if not necessary.\r
30176                             colorSaturation: null,  // Can be 'none' if not necessary.\r
30177                             borderWidth: 0,\r
30178                             gapWidth: 0,\r
30179                             borderColor: '#fff',\r
30180                             borderColorSaturation: null // If specified, borderColor will be ineffective, and the\r
30181                                                         // border color is evaluated by color of current node and\r
30182                                                         // borderColorSaturation.\r
30183                         },\r
30184                         emphasis: {\r
30185 \r
30186                         }\r
30187                     },\r
30188                     color: 'none',              // Array. Specify color list of each level.\r
30189                                                 // level[0].color would be global color list.\r
30190                     colorAlpha: null,           // Array. Specify color alpha range of each level, like [0.2, 0.8]\r
30191                     colorSaturation: null,      // Array. Specify color saturation of each level, like [0.2, 0.5]\r
30192                     colorMappingBy: 'index',    // 'value' or 'index' or 'id'.\r
30193                     visibleMin: 10,             // If area less than this threshold (unit: pixel^2), node will not\r
30194                                                 // be rendered. Only works when sort is 'asc' or 'desc'.\r
30195                     childrenVisibleMin: null,   // If area of a node less than this threshold (unit: pixel^2),\r
30196                                                 // grandchildren will not show.\r
30197                                                 // Why grandchildren? If not grandchildren but children,\r
30198                                                 // some siblings show children and some not,\r
30199                                                 // the appearance may be mess and not consistent,\r
30200                     levels: []                  // Each item: {\r
30201                                                 //     visibleMin, itemStyle, visualDimension, label\r
30202                                                 // }\r
30203                     // data: {\r
30204                     //      value: [],\r
30205                     //      children: [],\r
30206                     //      link: 'http://xxx.xxx.xxx',\r
30207                     //      target: 'blank' or 'self'\r
30208                     // }\r
30209                 },\r
30210 \r
30211                 /**\r
30212                  * @override\r
30213                  */\r
30214                 getInitialData: function (option, ecModel) {\r
30215                     var data = option.data || [];\r
30216                     var rootName = option.name;\r
30217                     rootName == null && (rootName = option.name);\r
30218 \r
30219                     // Create a virtual root.\r
30220                     var root = {name: rootName, children: option.data};\r
30221                     var value0 = (data[0] || {}).value;\r
30222 \r
30223                     completeTreeValue(root, zrUtil.isArray(value0) ? value0.length : -1);\r
30224 \r
30225                     // FIXME\r
30226                     // sereis.mergeOption 的 getInitData是否放在merge后,从而能直接获取merege后的结果而非手动判断。\r
30227                     var levels = option.levels || [];\r
30228 \r
30229                     levels = option.levels = setDefault(levels, ecModel);\r
30230 \r
30231                     // Make sure always a new tree is created when setOption,\r
30232                     // in TreemapView, we check whether oldTree === newTree\r
30233                     // to choose mappings approach among old shapes and new shapes.\r
30234                     return Tree.createTree(root, this, levels).data;\r
30235                 },\r
30236 \r
30237                 optionUpdated: function () {\r
30238                     this.resetViewRoot();\r
30239                 },\r
30240 \r
30241                 /**\r
30242                  * @override\r
30243                  * @param {number} dataIndex\r
30244                  * @param {boolean} [mutipleSeries=false]\r
30245                  */\r
30246                 formatTooltip: function (dataIndex) {\r
30247                     var data = this.getData();\r
30248                     var value = this.getRawValue(dataIndex);\r
30249                     var formattedValue = zrUtil.isArray(value)\r
30250                         ? addCommas(value[0]) : addCommas(value);\r
30251                     var name = data.getName(dataIndex);\r
30252 \r
30253                     return encodeHTML(name) + ': ' + formattedValue;\r
30254                 },\r
30255 \r
30256                 /**\r
30257                  * Add tree path to tooltip param\r
30258                  *\r
30259                  * @override\r
30260                  * @param {number} dataIndex\r
30261                  * @return {Object}\r
30262                  */\r
30263                 getDataParams: function (dataIndex) {\r
30264                     var params = SeriesModel.prototype.getDataParams.apply(this, arguments);\r
30265 \r
30266                     var data = this.getData();\r
30267                     var node = data.tree.getNodeByDataIndex(dataIndex);\r
30268                     var treePathInfo = params.treePathInfo = [];\r
30269 \r
30270                     while (node) {\r
30271                         var nodeDataIndex = node.dataIndex;\r
30272                         treePathInfo.push({\r
30273                             name: node.name,\r
30274                             dataIndex: nodeDataIndex,\r
30275                             value: this.getRawValue(nodeDataIndex)\r
30276                         });\r
30277                         node = node.parentNode;\r
30278                     }\r
30279 \r
30280                     treePathInfo.reverse();\r
30281 \r
30282                     return params;\r
30283                 },\r
30284 \r
30285                 /**\r
30286                  * @public\r
30287                  * @param {Object} layoutInfo {\r
30288                  *                                x: containerGroup x\r
30289                  *                                y: containerGroup y\r
30290                  *                                width: containerGroup width\r
30291                  *                                height: containerGroup height\r
30292                  *                            }\r
30293                  */\r
30294                 setLayoutInfo: function (layoutInfo) {\r
30295                     /**\r
30296                      * @readOnly\r
30297                      * @type {Object}\r
30298                      */\r
30299                     this.layoutInfo = this.layoutInfo || {};\r
30300                     zrUtil.extend(this.layoutInfo, layoutInfo);\r
30301                 },\r
30302 \r
30303                 /**\r
30304                  * @param  {string} id\r
30305                  * @return {number} index\r
30306                  */\r
30307                 mapIdToIndex: function (id) {\r
30308                     // A feature is implemented:\r
30309                     // index is monotone increasing with the sequence of\r
30310                     // input id at the first time.\r
30311                     // This feature can make sure that each data item and its\r
30312                     // mapped color have the same index between data list and\r
30313                     // color list at the beginning, which is useful for user\r
30314                     // to adjust data-color mapping.\r
30315 \r
30316                     /**\r
30317                      * @private\r
30318                      * @type {Object}\r
30319                      */\r
30320                     var idIndexMap = this._idIndexMap;\r
30321 \r
30322                     if (!idIndexMap) {\r
30323                         idIndexMap = this._idIndexMap = {};\r
30324                         /**\r
30325                          * @private\r
30326                          * @type {number}\r
30327                          */\r
30328                         this._idIndexMapCount = 0;\r
30329                     }\r
30330 \r
30331                     var index = idIndexMap[id];\r
30332                     if (index == null) {\r
30333                         idIndexMap[id] = index = this._idIndexMapCount++;\r
30334                     }\r
30335 \r
30336                     return index;\r
30337                 },\r
30338 \r
30339                 getViewRoot: function () {\r
30340                     return this._viewRoot;\r
30341                 },\r
30342 \r
30343                 /**\r
30344                  * @param {module:echarts/data/Tree~Node} [viewRoot]\r
30345                  * @return {string} direction 'drilldown' or 'rollup'\r
30346                  */\r
30347                 resetViewRoot: function (viewRoot) {\r
30348                     viewRoot\r
30349                         ? (this._viewRoot = viewRoot)\r
30350                         : (viewRoot = this._viewRoot);\r
30351 \r
30352                     var root = this.getData().tree.root;\r
30353 \r
30354                     if (!viewRoot\r
30355                         || (viewRoot !== root && !root.contains(viewRoot))\r
30356                     ) {\r
30357                         this._viewRoot = root;\r
30358                     }\r
30359                 }\r
30360             });\r
30361 \r
30362             /**\r
30363              * @param {Object} dataNode\r
30364              */\r
30365             function completeTreeValue(dataNode, arrValueLength) {\r
30366                 // Postorder travel tree.\r
30367                 // If value of none-leaf node is not set,\r
30368                 // calculate it by suming up the value of all children.\r
30369                 var sum = 0;\r
30370 \r
30371                 zrUtil.each(dataNode.children, function (child) {\r
30372 \r
30373                     completeTreeValue(child, arrValueLength);\r
30374 \r
30375                     var childValue = child.value;\r
30376                     zrUtil.isArray(childValue) && (childValue = childValue[0]);\r
30377 \r
30378                     sum += childValue;\r
30379                 });\r
30380 \r
30381                 var thisValue = dataNode.value;\r
30382 \r
30383                 if (arrValueLength >= 0) {\r
30384                     if (!zrUtil.isArray(thisValue)) {\r
30385                         dataNode.value = new Array(arrValueLength);\r
30386                     }\r
30387                     else {\r
30388                         thisValue = thisValue[0];\r
30389                     }\r
30390                 }\r
30391 \r
30392                 if (thisValue == null || isNaN(thisValue)) {\r
30393                     thisValue = sum;\r
30394                 }\r
30395                 // Value should not less than 0.\r
30396                 if (thisValue < 0) {\r
30397                     thisValue = 0;\r
30398                 }\r
30399 \r
30400                 arrValueLength >= 0\r
30401                     ? (dataNode.value[0] = thisValue)\r
30402                     : (dataNode.value = thisValue);\r
30403             }\r
30404 \r
30405             /**\r
30406              * set default to level configuration\r
30407              */\r
30408             function setDefault(levels, ecModel) {\r
30409                 var globalColorList = ecModel.get('color');\r
30410 \r
30411                 if (!globalColorList) {\r
30412                     return;\r
30413                 }\r
30414 \r
30415                 levels = levels || [];\r
30416                 var hasColorDefine;\r
30417                 zrUtil.each(levels, function (levelDefine) {\r
30418                     var model = new Model(levelDefine);\r
30419                     var modelColor = model.get('color');\r
30420                     if (model.get('itemStyle.normal.color')\r
30421                         || (modelColor && modelColor !== 'none')\r
30422                     ) {\r
30423                         hasColorDefine = true;\r
30424                     }\r
30425                 });\r
30426 \r
30427                 if (!hasColorDefine) {\r
30428                     var level0 = levels[0] || (levels[0] = {});\r
30429                     level0.color = globalColorList.slice();\r
30430                 }\r
30431 \r
30432                 return levels;\r
30433             }\r
30434 \r
30435 \r
30436 \r
30437 /***/ },\r
30438 /* 179 */\r
30439 /***/ function(module, exports, __webpack_require__) {\r
30440 \r
30441         /**\r
30442          * Tree data structure\r
30443          *\r
30444          * @module echarts/data/Tree\r
30445          */\r
30446 \r
30447 \r
30448             var zrUtil = __webpack_require__(3);\r
30449             var Model = __webpack_require__(8);\r
30450             var List = __webpack_require__(94);\r
30451             var linkListHelper = __webpack_require__(180);\r
30452             var completeDimensions = __webpack_require__(96);\r
30453 \r
30454             /**\r
30455              * @constructor module:echarts/data/Tree~TreeNode\r
30456              * @param {string} name\r
30457              * @param {number} [dataIndex=-1]\r
30458              * @param {module:echarts/data/Tree} hostTree\r
30459              */\r
30460             var TreeNode = function (name, dataIndex, hostTree) {\r
30461                 /**\r
30462                  * @type {string}\r
30463                  */\r
30464                 this.name = name || '';\r
30465 \r
30466                 /**\r
30467                  * Depth of node\r
30468                  *\r
30469                  * @type {number}\r
30470                  * @readOnly\r
30471                  */\r
30472                 this.depth = 0;\r
30473 \r
30474                 /**\r
30475                  * Height of the subtree rooted at this node.\r
30476                  * @type {number}\r
30477                  * @readOnly\r
30478                  */\r
30479                 this.height = 0;\r
30480 \r
30481                 /**\r
30482                  * @type {module:echarts/data/Tree~TreeNode}\r
30483                  * @readOnly\r
30484                  */\r
30485                 this.parentNode = null;\r
30486 \r
30487                 /**\r
30488                  * Reference to list item.\r
30489                  * Do not persistent dataIndex outside,\r
30490                  * besause it may be changed by list.\r
30491                  * If dataIndex -1,\r
30492                  * this node is logical deleted (filtered) in list.\r
30493                  *\r
30494                  * @type {Object}\r
30495                  * @readOnly\r
30496                  */\r
30497                 this.dataIndex = dataIndex == null ? -1 : dataIndex;\r
30498 \r
30499                 /**\r
30500                  * @type {Array.<module:echarts/data/Tree~TreeNode>}\r
30501                  * @readOnly\r
30502                  */\r
30503                 this.children = [];\r
30504 \r
30505                 /**\r
30506                  * @type {Array.<module:echarts/data/Tree~TreeNode>}\r
30507                  * @pubilc\r
30508                  */\r
30509                 this.viewChildren = [];\r
30510 \r
30511                 /**\r
30512                  * @type {moduel:echarts/data/Tree}\r
30513                  * @readOnly\r
30514                  */\r
30515                 this.hostTree = hostTree;\r
30516             };\r
30517 \r
30518             TreeNode.prototype = {\r
30519 \r
30520                 constructor: TreeNode,\r
30521 \r
30522                 /**\r
30523                  * The node is removed.\r
30524                  * @return {boolean} is removed.\r
30525                  */\r
30526                 isRemoved: function () {\r
30527                     return this.dataIndex < 0;\r
30528                 },\r
30529 \r
30530                 /**\r
30531                  * Travel this subtree (include this node).\r
30532                  * Usage:\r
30533                  *    node.eachNode(function () { ... }); // preorder\r
30534                  *    node.eachNode('preorder', function () { ... }); // preorder\r
30535                  *    node.eachNode('postorder', function () { ... }); // postorder\r
30536                  *    node.eachNode(\r
30537                  *        {order: 'postorder', attr: 'viewChildren'},\r
30538                  *        function () { ... }\r
30539                  *    ); // postorder\r
30540                  *\r
30541                  * @param {(Object|string)} options If string, means order.\r
30542                  * @param {string=} options.order 'preorder' or 'postorder'\r
30543                  * @param {string=} options.attr 'children' or 'viewChildren'\r
30544                  * @param {Function} cb If in preorder and return false,\r
30545                  *                      its subtree will not be visited.\r
30546                  * @param {Object} [context]\r
30547                  */\r
30548                 eachNode: function (options, cb, context) {\r
30549                     if (typeof options === 'function') {\r
30550                         context = cb;\r
30551                         cb = options;\r
30552                         options = null;\r
30553                     }\r
30554 \r
30555                     options = options || {};\r
30556                     if (zrUtil.isString(options)) {\r
30557                         options = {order: options};\r
30558                     }\r
30559 \r
30560                     var order = options.order || 'preorder';\r
30561                     var children = this[options.attr || 'children'];\r
30562 \r
30563                     var suppressVisitSub;\r
30564                     order === 'preorder' && (suppressVisitSub = cb.call(context, this));\r
30565 \r
30566                     for (var i = 0; !suppressVisitSub && i < children.length; i++) {\r
30567                         children[i].eachNode(options, cb, context);\r
30568                     }\r
30569 \r
30570                     order === 'postorder' && cb.call(context, this);\r
30571                 },\r
30572 \r
30573                 /**\r
30574                  * Update depth and height of this subtree.\r
30575                  *\r
30576                  * @param  {number} depth\r
30577                  */\r
30578                 updateDepthAndHeight: function (depth) {\r
30579                     var height = 0;\r
30580                     this.depth = depth;\r
30581                     for (var i = 0; i < this.children.length; i++) {\r
30582                         var child = this.children[i];\r
30583                         child.updateDepthAndHeight(depth + 1);\r
30584                         if (child.height > height) {\r
30585                             height = child.height;\r
30586                         }\r
30587                     }\r
30588                     this.height = height + 1;\r
30589                 },\r
30590 \r
30591                 /**\r
30592                  * @param  {string} id\r
30593                  * @return {module:echarts/data/Tree~TreeNode}\r
30594                  */\r
30595                 getNodeById: function (id) {\r
30596                     if (this.getId() === id) {\r
30597                         return this;\r
30598                     }\r
30599                     for (var i = 0, children = this.children, len = children.length; i < len; i++) {\r
30600                         var res = children[i].getNodeById(id);\r
30601                         if (res) {\r
30602                             return res;\r
30603                         }\r
30604                     }\r
30605                 },\r
30606 \r
30607                 /**\r
30608                  * @param {module:echarts/data/Tree~TreeNode} node\r
30609                  * @return {boolean}\r
30610                  */\r
30611                 contains: function (node) {\r
30612                     if (node === this) {\r
30613                         return true;\r
30614                     }\r
30615                     for (var i = 0, children = this.children, len = children.length; i < len; i++) {\r
30616                         var res = children[i].contains(node);\r
30617                         if (res) {\r
30618                             return res;\r
30619                         }\r
30620                     }\r
30621                 },\r
30622 \r
30623                 /**\r
30624                  * @param {boolean} includeSelf Default false.\r
30625                  * @return {Array.<module:echarts/data/Tree~TreeNode>} order: [root, child, grandchild, ...]\r
30626                  */\r
30627                 getAncestors: function (includeSelf) {\r
30628                     var ancestors = [];\r
30629                     var node = includeSelf ? this : this.parentNode;\r
30630                     while (node) {\r
30631                         ancestors.push(node);\r
30632                         node = node.parentNode;\r
30633                     }\r
30634                     ancestors.reverse();\r
30635                     return ancestors;\r
30636                 },\r
30637 \r
30638                 /**\r
30639                  * @param {string|Array=} [dimension='value'] Default 'value'. can be 0, 1, 2, 3\r
30640                  * @return {number} Value.\r
30641                  */\r
30642                 getValue: function (dimension) {\r
30643                     var data = this.hostTree.data;\r
30644                     return data.get(data.getDimension(dimension || 'value'), this.dataIndex);\r
30645                 },\r
30646 \r
30647                 /**\r
30648                  * @param {Object} layout\r
30649                  * @param {boolean=} [merge=false]\r
30650                  */\r
30651                 setLayout: function (layout, merge) {\r
30652                     this.dataIndex >= 0\r
30653                         && this.hostTree.data.setItemLayout(this.dataIndex, layout, merge);\r
30654                 },\r
30655 \r
30656                 /**\r
30657                  * @return {Object} layout\r
30658                  */\r
30659                 getLayout: function () {\r
30660                     return this.hostTree.data.getItemLayout(this.dataIndex);\r
30661                 },\r
30662 \r
30663                 /**\r
30664                  * @param {string} path\r
30665                  * @return {module:echarts/model/Model}\r
30666                  */\r
30667                 getModel: function (path) {\r
30668                     if (this.dataIndex < 0) {\r
30669                         return;\r
30670                     }\r
30671                     var hostTree = this.hostTree;\r
30672                     var itemModel = hostTree.data.getItemModel(this.dataIndex);\r
30673                     var levelModel = this.getLevelModel();\r
30674 \r
30675                     return itemModel.getModel(path, (levelModel || hostTree.hostModel).getModel(path));\r
30676                 },\r
30677 \r
30678                 /**\r
30679                  * @return {module:echarts/model/Model}\r
30680                  */\r
30681                 getLevelModel: function () {\r
30682                     return (this.hostTree.levelModels || [])[this.depth];\r
30683                 },\r
30684 \r
30685                 /**\r
30686                  * @example\r
30687                  *  setItemVisual('color', color);\r
30688                  *  setItemVisual({\r
30689                  *      'color': color\r
30690                  *  });\r
30691                  */\r
30692                 setVisual: function (key, value) {\r
30693                     this.dataIndex >= 0\r
30694                         && this.hostTree.data.setItemVisual(this.dataIndex, key, value);\r
30695                 },\r
30696 \r
30697                 /**\r
30698                  * @public\r
30699                  */\r
30700                 getVisual: function (key, ignoreParent) {\r
30701                     return this.hostTree.data.getItemVisual(this.dataIndex, key, ignoreParent);\r
30702                 },\r
30703 \r
30704                 /**\r
30705                  * @public\r
30706                  * @return {number}\r
30707                  */\r
30708                 getRawIndex: function () {\r
30709                     return this.hostTree.data.getRawIndex(this.dataIndex);\r
30710                 },\r
30711 \r
30712                 /**\r
30713                  * @public\r
30714                  * @return {string}\r
30715                  */\r
30716                 getId: function () {\r
30717                     return this.hostTree.data.getId(this.dataIndex);\r
30718                 }\r
30719             };\r
30720 \r
30721             /**\r
30722              * @constructor\r
30723              * @alias module:echarts/data/Tree\r
30724              * @param {module:echarts/model/Model} hostModel\r
30725              * @param {Array.<Object>} levelOptions\r
30726              */\r
30727             function Tree(hostModel, levelOptions) {\r
30728                 /**\r
30729                  * @type {module:echarts/data/Tree~TreeNode}\r
30730                  * @readOnly\r
30731                  */\r
30732                 this.root;\r
30733 \r
30734                 /**\r
30735                  * @type {module:echarts/data/List}\r
30736                  * @readOnly\r
30737                  */\r
30738                 this.data;\r
30739 \r
30740                 /**\r
30741                  * Index of each item is the same as the raw index of coresponding list item.\r
30742                  * @private\r
30743                  * @type {Array.<module:echarts/data/Tree~TreeNode}\r
30744                  */\r
30745                 this._nodes = [];\r
30746 \r
30747                 /**\r
30748                  * @private\r
30749                  * @readOnly\r
30750                  * @type {module:echarts/model/Model}\r
30751                  */\r
30752                 this.hostModel = hostModel;\r
30753 \r
30754                 /**\r
30755                  * @private\r
30756                  * @readOnly\r
30757                  * @type {Array.<module:echarts/model/Model}\r
30758                  */\r
30759                 this.levelModels = zrUtil.map(levelOptions || [], function (levelDefine) {\r
30760                     return new Model(levelDefine, hostModel, hostModel.ecModel);\r
30761                 });\r
30762             }\r
30763 \r
30764             Tree.prototype = {\r
30765 \r
30766                 constructor: Tree,\r
30767 \r
30768                 type: 'tree',\r
30769 \r
30770                 /**\r
30771                  * Travel this subtree (include this node).\r
30772                  * Usage:\r
30773                  *    node.eachNode(function () { ... }); // preorder\r
30774                  *    node.eachNode('preorder', function () { ... }); // preorder\r
30775                  *    node.eachNode('postorder', function () { ... }); // postorder\r
30776                  *    node.eachNode(\r
30777                  *        {order: 'postorder', attr: 'viewChildren'},\r
30778                  *        function () { ... }\r
30779                  *    ); // postorder\r
30780                  *\r
30781                  * @param {(Object|string)} options If string, means order.\r
30782                  * @param {string=} options.order 'preorder' or 'postorder'\r
30783                  * @param {string=} options.attr 'children' or 'viewChildren'\r
30784                  * @param {Function} cb\r
30785                  * @param {Object}   [context]\r
30786                  */\r
30787                 eachNode: function(options, cb, context) {\r
30788                     this.root.eachNode(options, cb, context);\r
30789                 },\r
30790 \r
30791                 /**\r
30792                  * @param {number} dataIndex\r
30793                  * @return {module:echarts/data/Tree~TreeNode}\r
30794                  */\r
30795                 getNodeByDataIndex: function (dataIndex) {\r
30796                     var rawIndex = this.data.getRawIndex(dataIndex);\r
30797                     return this._nodes[rawIndex];\r
30798                 },\r
30799 \r
30800                 /**\r
30801                  * @param {string} name\r
30802                  * @return {module:echarts/data/Tree~TreeNode}\r
30803                  */\r
30804                 getNodeByName: function (name) {\r
30805                     return this.root.getNodeByName(name);\r
30806                 },\r
30807 \r
30808                 /**\r
30809                  * Update item available by list,\r
30810                  * when list has been performed options like 'filterSelf' or 'map'.\r
30811                  */\r
30812                 update: function () {\r
30813                     var data = this.data;\r
30814                     var nodes = this._nodes;\r
30815 \r
30816                     for (var i = 0, len = nodes.length; i < len; i++) {\r
30817                         nodes[i].dataIndex = -1;\r
30818                     }\r
30819 \r
30820                     for (var i = 0, len = data.count(); i < len; i++) {\r
30821                         nodes[data.getRawIndex(i)].dataIndex = i;\r
30822                     }\r
30823                 }\r
30824             };\r
30825 \r
30826             /**\r
30827              * data node format:\r
30828              * {\r
30829              *     name: ...\r
30830              *     value: ...\r
30831              *     children: [\r
30832              *         {\r
30833              *             name: ...\r
30834              *             value: ...\r
30835              *             children: ...\r
30836              *         },\r
30837              *         ...\r
30838              *     ]\r
30839              * }\r
30840              *\r
30841              * @static\r
30842              * @param {Objec} dataRoot Root node.\r
30843              * @param {module:echarts/model/Model} hostModel\r
30844              * @param {Array.<Object>} levelOptions\r
30845              * @return module:echarts/data/Tree\r
30846              */\r
30847             Tree.createTree = function (dataRoot, hostModel, levelOptions) {\r
30848 \r
30849                 var tree = new Tree(hostModel, levelOptions);\r
30850                 var listData = [];\r
30851 \r
30852                 buildHierarchy(dataRoot);\r
30853 \r
30854                 function buildHierarchy(dataNode, parentNode) {\r
30855                     listData.push(dataNode);\r
30856 \r
30857                     var node = new TreeNode(dataNode.name, listData.length - 1, tree);\r
30858                     parentNode\r
30859                         ? addChild(node, parentNode)\r
30860                         : (tree.root = node);\r
30861 \r
30862                     var children = dataNode.children;\r
30863                     if (children) {\r
30864                         for (var i = 0; i < children.length; i++) {\r
30865                             buildHierarchy(children[i], node);\r
30866                         }\r
30867                     }\r
30868                 }\r
30869 \r
30870                 tree.root.updateDepthAndHeight(0);\r
30871 \r
30872                 var dimensions = completeDimensions([{name: 'value'}], listData);\r
30873                 var list = new List(dimensions, hostModel);\r
30874                 list.initData(listData);\r
30875 \r
30876                 linkListHelper.linkToTree(list, tree);\r
30877 \r
30878                 return tree;\r
30879             };\r
30880 \r
30881             /**\r
30882              * It is needed to consider the mess of 'list', 'hostModel' when creating a TreeNote,\r
30883              * so this function is not ready and not necessary to be public.\r
30884              *\r
30885              * @param {(module:echarts/data/Tree~TreeNode|Object)} child\r
30886              */\r
30887             function addChild(child, node) {\r
30888                 var children = node.children;\r
30889                 if (child.parentNode === node) {\r
30890                     return;\r
30891                 }\r
30892 \r
30893                 children.push(child);\r
30894                 child.parentNode = node;\r
30895 \r
30896                 node.hostTree._nodes.push(child);\r
30897             }\r
30898 \r
30899             module.exports = Tree;\r
30900 \r
30901 \r
30902 /***/ },\r
30903 /* 180 */\r
30904 /***/ function(module, exports, __webpack_require__) {\r
30905 \r
30906         /**\r
30907          * Link list to graph or tree\r
30908          */\r
30909 \r
30910 \r
30911             var zrUtil = __webpack_require__(3);\r
30912             var arraySlice = Array.prototype.slice;\r
30913 \r
30914             // Caution:\r
30915             // In most case, only one of the list and its shallow clones (see list.cloneShallow)\r
30916             // can be active in echarts process. Considering heap memory consumption,\r
30917             // we do not clone tree or graph, but share them among list and its shallow clones.\r
30918             // But in some rare case, we have to keep old list (like do animation in chart). So\r
30919             // please take care that both the old list and the new list share the same tree/graph.\r
30920 \r
30921             function linkList(list, target, targetType) {\r
30922                 zrUtil.each(listProxyMethods, function (method, methodName) {\r
30923                     var originMethod = list[methodName];\r
30924                     list[methodName] = zrUtil.curry(method, originMethod, target, targetType);\r
30925                 });\r
30926 \r
30927                 list[targetType] = target;\r
30928                 target.data = list;\r
30929 \r
30930                 return list;\r
30931             }\r
30932 \r
30933             var listProxyMethods = {\r
30934                 cloneShallow: function (originMethod, target, targetType) {\r
30935                     var newList = originMethod.apply(this, arraySlice.call(arguments, 3));\r
30936                     return linkList(newList, target, targetType);\r
30937                 },\r
30938                 map: function (originMethod, target, targetType) {\r
30939                     var newList = originMethod.apply(this, arraySlice.call(arguments, 3));\r
30940                     return linkList(newList, target, targetType);\r
30941                 },\r
30942                 filterSelf: function (originMethod, target, targetType) {\r
30943                     var result = originMethod.apply(this, arraySlice.call(arguments, 3));\r
30944                     target.update();\r
30945                     return result;\r
30946                 }\r
30947             };\r
30948 \r
30949             module.exports = {\r
30950                 linkToGraph: function (list, graph) {\r
30951                     linkList(list, graph, 'graph');\r
30952                 },\r
30953 \r
30954                 linkToTree: function (list, tree) {\r
30955                     linkList(list, tree, 'tree');\r
30956                 }\r
30957             };\r
30958 \r
30959 \r
30960 /***/ },\r
30961 /* 181 */\r
30962 /***/ function(module, exports, __webpack_require__) {\r
30963 \r
30964         \r
30965 \r
30966             var zrUtil = __webpack_require__(3);\r
30967 \r
30968             var helper = {\r
30969 \r
30970                 retrieveTargetInfo: function (payload, seriesModel) {\r
30971                     if (payload\r
30972                         && (\r
30973                             payload.type === 'treemapZoomToNode'\r
30974                             || payload.type === 'treemapRootToNode'\r
30975                         )\r
30976                     ) {\r
30977                         var root = seriesModel.getData().tree.root;\r
30978                         var targetNode = payload.targetNode;\r
30979                         if (targetNode && root.contains(targetNode)) {\r
30980                             return {node: targetNode};\r
30981                         }\r
30982 \r
30983                         var targetNodeId = payload.targetNodeId;\r
30984                         if (targetNodeId != null && (targetNode = root.getNodeById(targetNodeId))) {\r
30985                             return {node: targetNode};\r
30986                         }\r
30987                     }\r
30988                 },\r
30989 \r
30990                 getPathToRoot: function (node) {\r
30991                     var path = [];\r
30992                     while (node) {\r
30993                         path.push(node);\r
30994                         node = node.parentNode;\r
30995                     }\r
30996                     return path.reverse();\r
30997                 },\r
30998 \r
30999                 aboveViewRoot: function (viewRoot, node) {\r
31000                     var viewPath = helper.getPathToRoot(viewRoot);\r
31001                     return helper.aboveViewRootByViewPath(viewPath, node);\r
31002                 },\r
31003 \r
31004                 // viewPath should obtained from getPathToRoot(viewRoot)\r
31005                 aboveViewRootByViewPath: function (viewPath, node) {\r
31006                     var index = zrUtil.indexOf(viewPath, node);\r
31007                     // The last one is viewRoot\r
31008                     return index >= 0 && index !== viewPath.length - 1;\r
31009                 }\r
31010 \r
31011             };\r
31012 \r
31013             module.exports = helper;\r
31014 \r
31015 \r
31016 /***/ },\r
31017 /* 182 */\r
31018 /***/ function(module, exports, __webpack_require__) {\r
31019 \r
31020          \r
31021 \r
31022             var zrUtil = __webpack_require__(3);\r
31023             var graphic = __webpack_require__(42);\r
31024             var DataDiffer = __webpack_require__(95);\r
31025             var helper = __webpack_require__(181);\r
31026             var Breadcrumb = __webpack_require__(183);\r
31027             var RoamController = __webpack_require__(159);\r
31028             var BoundingRect = __webpack_require__(15);\r
31029             var matrix = __webpack_require__(17);\r
31030             var animationUtil = __webpack_require__(184);\r
31031             var bind = zrUtil.bind;\r
31032             var Group = graphic.Group;\r
31033             var Rect = graphic.Rect;\r
31034             var each = zrUtil.each;\r
31035 \r
31036             var DRAG_THRESHOLD = 3;\r
31037 \r
31038             module.exports = __webpack_require__(1).extendChartView({\r
31039 \r
31040                 type: 'treemap',\r
31041 \r
31042                 /**\r
31043                  * @override\r
31044                  */\r
31045                 init: function (o, api) {\r
31046 \r
31047                     /**\r
31048                      * @private\r
31049                      * @type {module:zrender/container/Group}\r
31050                      */\r
31051                     this._containerGroup;\r
31052 \r
31053                     /**\r
31054                      * @private\r
31055                      * @type {Object.<string, Array.<module:zrender/container/Group>>}\r
31056                      */\r
31057                     this._storage = createStorage();\r
31058 \r
31059                     /**\r
31060                      * @private\r
31061                      * @type {module:echarts/data/Tree}\r
31062                      */\r
31063                     this._oldTree;\r
31064 \r
31065                     /**\r
31066                      * @private\r
31067                      * @type {module:echarts/chart/treemap/Breadcrumb}\r
31068                      */\r
31069                     this._breadcrumb;\r
31070 \r
31071                     /**\r
31072                      * @private\r
31073                      * @type {module:echarts/component/helper/RoamController}\r
31074                      */\r
31075                     this._controller;\r
31076 \r
31077                     /**\r
31078                      * 'ready', 'animating'\r
31079                      * @private\r
31080                      */\r
31081                     this._state = 'ready';\r
31082 \r
31083                     /**\r
31084                      * @private\r
31085                      * @type {boolean}\r
31086                      */\r
31087                     this._mayClick;\r
31088                 },\r
31089 \r
31090                 /**\r
31091                  * @override\r
31092                  */\r
31093                 render: function (seriesModel, ecModel, api, payload) {\r
31094 \r
31095                     var models = ecModel.findComponents({\r
31096                         mainType: 'series', subType: 'treemap', query: payload\r
31097                     });\r
31098                     if (zrUtil.indexOf(models, seriesModel) < 0) {\r
31099                         return;\r
31100                     }\r
31101 \r
31102                     this.seriesModel = seriesModel;\r
31103                     this.api = api;\r
31104                     this.ecModel = ecModel;\r
31105 \r
31106                     var targetInfo = helper.retrieveTargetInfo(payload, seriesModel);\r
31107                     var payloadType = payload && payload.type;\r
31108                     var layoutInfo = seriesModel.layoutInfo;\r
31109                     var isInit = !this._oldTree;\r
31110                     var thisStorage = this._storage;\r
31111 \r
31112                     // Mark new root when action is treemapRootToNode.\r
31113                     var reRoot = (payloadType === 'treemapRootToNode' && targetInfo && thisStorage)\r
31114                         ? {\r
31115                             rootNodeGroup: thisStorage.nodeGroup[targetInfo.node.getRawIndex()],\r
31116                             direction: payload.direction\r
31117                         }\r
31118                         : null;\r
31119 \r
31120                     var containerGroup = this._giveContainerGroup(layoutInfo);\r
31121 \r
31122                     var renderResult = this._doRender(containerGroup, seriesModel, reRoot);\r
31123 \r
31124                     (\r
31125                         !isInit && (\r
31126                             !payloadType\r
31127                             || payloadType === 'treemapZoomToNode'\r
31128                             || payloadType === 'treemapRootToNode'\r
31129                         )\r
31130                     )\r
31131                         ? this._doAnimation(containerGroup, renderResult, seriesModel, reRoot)\r
31132                         : renderResult.renderFinally();\r
31133 \r
31134                     this._resetController(api);\r
31135 \r
31136                     this._renderBreadcrumb(seriesModel, api, targetInfo);\r
31137                 },\r
31138 \r
31139                 /**\r
31140                  * @private\r
31141                  */\r
31142                 _giveContainerGroup: function (layoutInfo) {\r
31143                     var containerGroup = this._containerGroup;\r
31144                     if (!containerGroup) {\r
31145                         // FIXME\r
31146                         // 加一层containerGroup是为了clip,但是现在clip功能并没有实现。\r
31147                         containerGroup = this._containerGroup = new Group();\r
31148                         this._initEvents(containerGroup);\r
31149                         this.group.add(containerGroup);\r
31150                     }\r
31151                     containerGroup.position = [layoutInfo.x, layoutInfo.y];\r
31152 \r
31153                     return containerGroup;\r
31154                 },\r
31155 \r
31156                 /**\r
31157                  * @private\r
31158                  */\r
31159                 _doRender: function (containerGroup, seriesModel, reRoot) {\r
31160                     var thisTree = seriesModel.getData().tree;\r
31161                     var oldTree = this._oldTree;\r
31162 \r
31163                     // Clear last shape records.\r
31164                     var lastsForAnimation = createStorage();\r
31165                     var thisStorage = createStorage();\r
31166                     var oldStorage = this._storage;\r
31167                     var willInvisibleEls = [];\r
31168                     var willVisibleEls = [];\r
31169                     var willDeleteEls = [];\r
31170                     var renderNode = bind(\r
31171                         this._renderNode, this,\r
31172                         thisStorage, oldStorage, reRoot,\r
31173                         lastsForAnimation, willInvisibleEls, willVisibleEls\r
31174                     );\r
31175                     var viewRoot = seriesModel.getViewRoot();\r
31176                     var viewPath = helper.getPathToRoot(viewRoot);\r
31177 \r
31178                     // Notice: when thisTree and oldTree are the same tree (see list.cloneShadow),\r
31179                     // the oldTree is actually losted, so we can not find all of the old graphic\r
31180                     // elements from tree. So we use this stragegy: make element storage, move\r
31181                     // from old storage to new storage, clear old storage.\r
31182 \r
31183                     dualTravel(\r
31184                         thisTree.root ? [thisTree.root] : [],\r
31185                         (oldTree && oldTree.root) ? [oldTree.root] : [],\r
31186                         containerGroup,\r
31187                         thisTree === oldTree || !oldTree,\r
31188                         0\r
31189                     );\r
31190 \r
31191                     // Process all removing.\r
31192                     var willDeleteEls = clearStorage(oldStorage);\r
31193 \r
31194                     this._oldTree = thisTree;\r
31195                     this._storage = thisStorage;\r
31196 \r
31197                     return {\r
31198                         lastsForAnimation: lastsForAnimation,\r
31199                         willDeleteEls: willDeleteEls,\r
31200                         renderFinally: renderFinally\r
31201                     };\r
31202 \r
31203                     function dualTravel(thisViewChildren, oldViewChildren, parentGroup, sameTree, viewPathIndex) {\r
31204                         // When 'render' is triggered by action,\r
31205                         // 'this' and 'old' may be the same tree,\r
31206                         // we use rawIndex in that case.\r
31207                         if (sameTree) {\r
31208                             oldViewChildren = thisViewChildren;\r
31209                             each(thisViewChildren, function (child, index) {\r
31210                                 !child.isRemoved() && processNode(index, index);\r
31211                             });\r
31212                         }\r
31213                         // Diff hierarchically (diff only in each subtree, but not whole).\r
31214                         // because, consistency of view is important.\r
31215                         else {\r
31216                             (new DataDiffer(oldViewChildren, thisViewChildren, getKey, getKey))\r
31217                                 .add(processNode)\r
31218                                 .update(processNode)\r
31219                                 .remove(zrUtil.curry(processNode, null))\r
31220                                 .execute();\r
31221                         }\r
31222 \r
31223                         function getKey(node) {\r
31224                             // Identify by name or raw index.\r
31225                             return node.getId();\r
31226                         }\r
31227 \r
31228                         function processNode(newIndex, oldIndex) {\r
31229                             var thisNode = newIndex != null ? thisViewChildren[newIndex] : null;\r
31230                             var oldNode = oldIndex != null ? oldViewChildren[oldIndex] : null;\r
31231 \r
31232                             // Whether under viewRoot.\r
31233                             if (!thisNode\r
31234                                 || isNaN(viewPathIndex)\r
31235                                 || (viewPathIndex < viewPath.length && viewPath[viewPathIndex] !== thisNode)\r
31236                             ) {\r
31237                                 // Deleting nodes will be performed finally. This method just find\r
31238                                 // element from old storage, or create new element, set them to new\r
31239                                 // storage, and set styles.\r
31240                                 return;\r
31241                             }\r
31242 \r
31243                             var group = renderNode(thisNode, oldNode, parentGroup);\r
31244 \r
31245                             group && dualTravel(\r
31246                                 thisNode && thisNode.viewChildren || [],\r
31247                                 oldNode && oldNode.viewChildren || [],\r
31248                                 group,\r
31249                                 sameTree,\r
31250                                 viewPathIndex + 1\r
31251                             );\r
31252                         }\r
31253                     }\r
31254 \r
31255                     function clearStorage(storage) {\r
31256                         var willDeleteEls = createStorage();\r
31257                         storage && each(storage, function (store, storageName) {\r
31258                             var delEls = willDeleteEls[storageName];\r
31259                             each(store, function (el) {\r
31260                                 el && (delEls.push(el), el.__tmWillDelete = storageName);\r
31261                             });\r
31262                         });\r
31263                         return willDeleteEls;\r
31264                     }\r
31265 \r
31266                     function renderFinally() {\r
31267                         each(willDeleteEls, function (els) {\r
31268                             each(els, function (el) {\r
31269                                 el.parent && el.parent.remove(el);\r
31270                             });\r
31271                         });\r
31272                         // Theoritically there is no intersection between willInvisibleEls\r
31273                         // and willVisibleEls have, but we set visible after for robustness.\r
31274                         each(willInvisibleEls, function (el) {\r
31275                             el.invisible = true;\r
31276                             // Setting invisible is for optimizing, so no need to set dirty,\r
31277                             // just mark as invisible.\r
31278                             el.dirty();\r
31279                         });\r
31280                         each(willVisibleEls, function (el) {\r
31281                             el.invisible = false;\r
31282                             el.__tmWillVisible = false;\r
31283                             el.dirty();\r
31284                         });\r
31285                     }\r
31286                 },\r
31287 \r
31288                 /**\r
31289                  * @private\r
31290                  */\r
31291                 _renderNode: function (\r
31292                     thisStorage, oldStorage, reRoot,\r
31293                     lastsForAnimation, willInvisibleEls, willVisibleEls,\r
31294                     thisNode, oldNode, parentGroup\r
31295                 ) {\r
31296                     var thisRawIndex = thisNode && thisNode.getRawIndex();\r
31297                     var oldRawIndex = oldNode && oldNode.getRawIndex();\r
31298 \r
31299                     var layout = thisNode.getLayout();\r
31300                     var thisWidth = layout.width;\r
31301                     var thisHeight = layout.height;\r
31302                     var invisible = layout.invisible;\r
31303 \r
31304                     // Node group\r
31305                     var group = giveGraphic('nodeGroup', Group);\r
31306                     if (!group) {\r
31307                         return;\r
31308                     }\r
31309                     parentGroup.add(group);\r
31310                     group.position = [layout.x, layout.y];\r
31311                     group.__tmNodeWidth = thisWidth;\r
31312                     group.__tmNodeHeight = thisHeight;\r
31313 \r
31314                     // Background\r
31315                     var bg = giveGraphic('background', Rect, 0);\r
31316                     if (bg) {\r
31317                         bg.setShape({x: 0, y: 0, width: thisWidth, height: thisHeight});\r
31318                         updateStyle(bg, {fill: thisNode.getVisual('borderColor', true)});\r
31319                         group.add(bg);\r
31320                     }\r
31321 \r
31322                     var thisViewChildren = thisNode.viewChildren;\r
31323 \r
31324                     // No children, render content.\r
31325                     if (!thisViewChildren || !thisViewChildren.length) {\r
31326                         var borderWidth = layout.borderWidth;\r
31327                         var content = giveGraphic('content', Rect, 3);\r
31328                         if (content) {\r
31329                             var contentWidth = Math.max(thisWidth - 2 * borderWidth, 0);\r
31330                             var contentHeight = Math.max(thisHeight - 2 * borderWidth, 0);\r
31331                             var labelModel = thisNode.getModel('label.normal');\r
31332                             var textStyleModel = thisNode.getModel('label.normal.textStyle');\r
31333                             var hoverStyle = thisNode.getModel('itemStyle.emphasis').getItemStyle();\r
31334                             var text = thisNode.getModel().get('name');\r
31335                             var textRect = textStyleModel.getTextRect(text);\r
31336                             var showLabel = labelModel.get('show');\r
31337 \r
31338                             if (!showLabel || textRect.height > contentHeight) {\r
31339                                 text = '';\r
31340                             }\r
31341                             else if (textRect.width > contentWidth) {\r
31342                                 text = textStyleModel.get('ellipsis')\r
31343                                     ? textStyleModel.ellipsis(text, contentWidth) : '';\r
31344                             }\r
31345 \r
31346                             graphic.setHoverStyle(content, hoverStyle);\r
31347 \r
31348                             // For tooltip.\r
31349                             content.dataIndex = thisNode.dataIndex;\r
31350                             content.seriesIndex = this.seriesModel.seriesIndex;\r
31351 \r
31352                             content.culling = true;\r
31353                             content.setShape({\r
31354                                 x: borderWidth,\r
31355                                 y: borderWidth,\r
31356                                 width: contentWidth,\r
31357                                 height: contentHeight\r
31358                             });\r
31359 \r
31360                             updateStyle(content, {\r
31361                                 fill: thisNode.getVisual('color', true),\r
31362                                 text: text,\r
31363                                 textPosition: labelModel.get('position'),\r
31364                                 textFill: textStyleModel.getTextColor(),\r
31365                                 textAlign: textStyleModel.get('align'),\r
31366                                 textVerticalAlign: textStyleModel.get('baseline'),\r
31367                                 textFont: textStyleModel.getFont()\r
31368                             });\r
31369                             group.add(content);\r
31370                         }\r
31371                     }\r
31372 \r
31373                     return group;\r
31374 \r
31375                     function giveGraphic(storageName, Ctor, z) {\r
31376                         var element = oldRawIndex != null && oldStorage[storageName][oldRawIndex];\r
31377                         var lasts = lastsForAnimation[storageName];\r
31378 \r
31379                         if (element) {\r
31380                             // Remove from oldStorage\r
31381                             oldStorage[storageName][oldRawIndex] = null;\r
31382                             prepareAnimationWhenHasOld(lasts, element, storageName);\r
31383                         }\r
31384                         // If invisible and no old element, do not create new element (for optimizing).\r
31385                         else if (!invisible) {\r
31386                             element = new Ctor({z: z});\r
31387                             prepareAnimationWhenNoOld(lasts, element, storageName);\r
31388                         }\r
31389 \r
31390                         // Set to thisStorage\r
31391                         return (thisStorage[storageName][thisRawIndex] = element);\r
31392                     }\r
31393 \r
31394                     function prepareAnimationWhenHasOld(lasts, element, storageName) {\r
31395                         var lastCfg = lasts[thisRawIndex] = {};\r
31396                         lastCfg.old = storageName === 'nodeGroup'\r
31397                             ? element.position.slice()\r
31398                             : zrUtil.extend({}, element.shape);\r
31399                     }\r
31400 \r
31401                     // If a element is new, we need to find the animation start point carefully,\r
31402                     // otherwise it will looks strange when 'zoomToNode'.\r
31403                     function prepareAnimationWhenNoOld(lasts, element, storageName) {\r
31404                         // New background do not animate but delay show.\r
31405                         if (storageName === 'background') {\r
31406                             element.invisible = true;\r
31407                             element.__tmWillVisible = true;\r
31408                             willVisibleEls.push(element);\r
31409                         }\r
31410                         else {\r
31411                             var lastCfg = lasts[thisRawIndex] = {};\r
31412                             var parentNode = thisNode.parentNode;\r
31413 \r
31414                             if (parentNode && (!reRoot || reRoot.direction === 'drilldown')) {\r
31415                                 var parentOldX = 0;\r
31416                                 var parentOldY = 0;\r
31417                                 // For convenience, get old bounding rect from background.\r
31418                                 var parentOldBg = lastsForAnimation.background[parentNode.getRawIndex()];\r
31419 \r
31420                                 if (parentOldBg && parentOldBg.old) {\r
31421                                     parentOldX = parentOldBg.old.width / 2; // Devided by 2 for reRoot effect.\r
31422                                     parentOldY = parentOldBg.old.height / 2;\r
31423                                 }\r
31424                                 // When no parent old shape found, its parent is new too,\r
31425                                 // so we can just use {x:0, y:0}.\r
31426                                 lastCfg.old = storageName === 'nodeGroup'\r
31427                                     ? [parentOldX, parentOldY]\r
31428                                     : {x: parentOldX, y: parentOldY, width: 0, height: 0};\r
31429                             }\r
31430 \r
31431                             // Fade in, user can be aware that these nodes are new.\r
31432                             lastCfg.fadein = storageName !== 'nodeGroup';\r
31433                         }\r
31434                     }\r
31435 \r
31436                     function updateStyle(element, style) {\r
31437                         if (!invisible) {\r
31438                             // If invisible, do not set visual, otherwise the element will\r
31439                             // change immediately before animation. We think it is OK to\r
31440                             // remain its origin color when moving out of the view window.\r
31441                             element.setStyle(style);\r
31442                             if (!element.__tmWillVisible) {\r
31443                                 element.invisible = false;\r
31444                             }\r
31445                         }\r
31446                         else {\r
31447                             // Delay invisible setting utill animation finished,\r
31448                             // avoid element vanish suddenly before animation.\r
31449                             !element.invisible && willInvisibleEls.push(element);\r
31450                         }\r
31451                     }\r
31452                 },\r
31453 \r
31454                 /**\r
31455                  * @private\r
31456                  */\r
31457                 _doAnimation: function (containerGroup, renderResult, seriesModel, reRoot) {\r
31458                     if (!seriesModel.get('animation')) {\r
31459                         return;\r
31460                     }\r
31461 \r
31462                     var duration = seriesModel.get('animationDurationUpdate');\r
31463                     var easing = seriesModel.get('animationEasing');\r
31464                     var animationWrap = animationUtil.createWrap();\r
31465 \r
31466                     // Make delete animations.\r
31467                     each(renderResult.willDeleteEls, function (store, storageName) {\r
31468                         each(store, function (el, rawIndex) {\r
31469                             var storageName;\r
31470 \r
31471                             if (el.invisible || !(storageName = el.__tmWillDelete)) {\r
31472                                 return;\r
31473                             }\r
31474 \r
31475                             var parent = el.parent; // Always has parent, and parent is nodeGroup.\r
31476                             var target;\r
31477 \r
31478                             if (reRoot && reRoot.direction === 'drilldown') {\r
31479                                 if (parent === reRoot.rootNodeGroup) {\r
31480                                     // Only 'content' will enter this branch, but not nodeGroup.\r
31481                                     target = {\r
31482                                         shape: {\r
31483                                             x: 0, y: 0,\r
31484                                             width: parent.__tmNodeWidth, height: parent.__tmNodeHeight\r
31485                                         }\r
31486                                     };\r
31487                                     el.z = 2;\r
31488                                 }\r
31489                                 else {\r
31490                                     target = {style: {opacity: 0}};\r
31491                                     el.z = 1;\r
31492                                 }\r
31493                             }\r
31494                             else {\r
31495                                 var targetX = 0;\r
31496                                 var targetY = 0;\r
31497 \r
31498                                 if (!parent.__tmWillDelete) {\r
31499                                     // Let node animate to right-bottom corner, cooperating with fadeout,\r
31500                                     // which is appropriate for user understanding.\r
31501                                     // Divided by 2 for reRoot rollup effect.\r
31502                                     targetX = parent.__tmNodeWidth / 2;\r
31503                                     targetY = parent.__tmNodeHeight / 2;\r
31504                                 }\r
31505                                 target = storageName === 'nodeGroup'\r
31506                                     ? {position: [targetX, targetY], style: {opacity: 0}}\r
31507                                     : {\r
31508                                         shape: {x: targetX, y: targetY, width: 0, height: 0},\r
31509                                         style: {opacity: 0}\r
31510                                     };\r
31511                             }\r
31512 \r
31513                             target && animationWrap.add(el, target, duration, easing);\r
31514                         });\r
31515                     });\r
31516 \r
31517                     // Make other animations\r
31518                     each(this._storage, function (store, storageName) {\r
31519                         each(store, function (el, rawIndex) {\r
31520                             var last = renderResult.lastsForAnimation[storageName][rawIndex];\r
31521                             var target = {};\r
31522 \r
31523                             if (!last) {\r
31524                                 return;\r
31525                             }\r
31526 \r
31527                             if (storageName === 'nodeGroup') {\r
31528                                 if (last.old) {\r
31529                                     target.position = el.position.slice();\r
31530                                     el.position = last.old;\r
31531                                 }\r
31532                             }\r
31533                             else {\r
31534                                 if (last.old) {\r
31535                                     target.shape = zrUtil.extend({}, el.shape);\r
31536                                     el.setShape(last.old);\r
31537                                 }\r
31538 \r
31539                                 if (last.fadein) {\r
31540                                     el.setStyle('opacity', 0);\r
31541                                     target.style = {opacity: 1};\r
31542                                 }\r
31543                                 // When animation is stopped for succedent animation starting,\r
31544                                 // el.style.opacity might not be 1\r
31545                                 else if (el.style.opacity !== 1) {\r
31546                                     target.style = {opacity: 1};\r
31547                                 }\r
31548                             }\r
31549                             animationWrap.add(el, target, duration, easing);\r
31550                         });\r
31551                     }, this);\r
31552 \r
31553                     this._state = 'animating';\r
31554 \r
31555                     animationWrap\r
31556                         .done(bind(function () {\r
31557                             this._state = 'ready';\r
31558                             renderResult.renderFinally();\r
31559                         }, this))\r
31560                         .start();\r
31561                 },\r
31562 \r
31563                 /**\r
31564                  * @private\r
31565                  */\r
31566                 _resetController: function (api) {\r
31567                     var controller = this._controller;\r
31568 \r
31569                     // Init controller.\r
31570                     if (!controller) {\r
31571                         controller = this._controller = new RoamController(api.getZr());\r
31572                         controller.enable(this.seriesModel.get('roam'));\r
31573                         controller.on('pan', bind(this._onPan, this));\r
31574                         controller.on('zoom', bind(this._onZoom, this));\r
31575                     }\r
31576 \r
31577                     controller.rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight());\r
31578                 },\r
31579 \r
31580                 /**\r
31581                  * @private\r
31582                  */\r
31583                 _clearController: function () {\r
31584                     var controller = this._controller;\r
31585                     if (controller) {\r
31586                         controller.off('pan').off('zoom');\r
31587                         controller = null;\r
31588                     }\r
31589                 },\r
31590 \r
31591                 /**\r
31592                  * @private\r
31593                  */\r
31594                 _onPan: function (dx, dy) {\r
31595                     this._mayClick = false;\r
31596 \r
31597                     if (this._state !== 'animating'\r
31598                         && (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD)\r
31599                     ) {\r
31600                         // These param must not be cached.\r
31601                         var viewRoot = this.seriesModel.getViewRoot();\r
31602 \r
31603                         if (!viewRoot) {\r
31604                             return;\r
31605                         }\r
31606 \r
31607                         var rootLayout = viewRoot.getLayout();\r
31608 \r
31609                         if (!rootLayout) {\r
31610                             return;\r
31611                         }\r
31612 \r
31613                         this.api.dispatchAction({\r
31614                             type: 'treemapMove',\r
31615                             from: this.uid,\r
31616                             seriesId: this.seriesModel.id,\r
31617                             rootRect: {\r
31618                                 x: rootLayout.x + dx, y: rootLayout.y + dy,\r
31619                                 width: rootLayout.width, height: rootLayout.height\r
31620                             }\r
31621                         });\r
31622                     }\r
31623                 },\r
31624 \r
31625                 /**\r
31626                  * @private\r
31627                  */\r
31628                 _onZoom: function (scale, mouseX, mouseY) {\r
31629                     this._mayClick = false;\r
31630 \r
31631                     if (this._state !== 'animating') {\r
31632                         // These param must not be cached.\r
31633                         var viewRoot = this.seriesModel.getViewRoot();\r
31634 \r
31635                         if (!viewRoot) {\r
31636                             return;\r
31637                         }\r
31638 \r
31639                         var rootLayout = viewRoot.getLayout();\r
31640 \r
31641                         if (!rootLayout) {\r
31642                             return;\r
31643                         }\r
31644 \r
31645                         var rect = new BoundingRect(\r
31646                             rootLayout.x, rootLayout.y, rootLayout.width, rootLayout.height\r
31647                         );\r
31648                         var layoutInfo = this.seriesModel.layoutInfo;\r
31649 \r
31650                         // Transform mouse coord from global to containerGroup.\r
31651                         mouseX -= layoutInfo.x;\r
31652                         mouseY -= layoutInfo.y;\r
31653 \r
31654                         // Scale root bounding rect.\r
31655                         var m = matrix.create();\r
31656                         matrix.translate(m, m, [-mouseX, -mouseY]);\r
31657                         matrix.scale(m, m, [scale, scale]);\r
31658                         matrix.translate(m, m, [mouseX, mouseY]);\r
31659 \r
31660                         rect.applyTransform(m);\r
31661 \r
31662                         this.api.dispatchAction({\r
31663                             type: 'treemapRender',\r
31664                             from: this.uid,\r
31665                             seriesId: this.seriesModel.id,\r
31666                             rootRect: {\r
31667                                 x: rect.x, y: rect.y,\r
31668                                 width: rect.width, height: rect.height\r
31669                             }\r
31670                         });\r
31671                     }\r
31672                 },\r
31673 \r
31674                 /**\r
31675                  * @private\r
31676                  */\r
31677                 _initEvents: function (containerGroup) {\r
31678                     // FIXME\r
31679                     // 不用click以及silent的原因是,animate时视图设置silent true来避免click生效,\r
31680                     // 但是animate中,按下鼠标,animate结束后(silent设回为false)松开鼠标,\r
31681                     // 还是会触发click,期望是不触发。\r
31682 \r
31683                     // Mousedown occurs when drag start, and mouseup occurs when drag end,\r
31684                     // click event should not be triggered in that case.\r
31685 \r
31686                     containerGroup.on('mousedown', function (e) {\r
31687                         this._state === 'ready' && (this._mayClick = true);\r
31688                     }, this);\r
31689                     containerGroup.on('mouseup', function (e) {\r
31690                         if (this._mayClick) {\r
31691                             this._mayClick = false;\r
31692                             this._state === 'ready' && onClick.call(this, e);\r
31693                         }\r
31694                     }, this);\r
31695 \r
31696                     function onClick(e) {\r
31697                         var nodeClick = this.seriesModel.get('nodeClick', true);\r
31698 \r
31699                         if (!nodeClick) {\r
31700                             return;\r
31701                         }\r
31702 \r
31703                         var targetInfo = this.findTarget(e.offsetX, e.offsetY);\r
31704 \r
31705                         if (!targetInfo) {\r
31706                             return;\r
31707                         }\r
31708 \r
31709                         var node = targetInfo.node;\r
31710                         if (node.getLayout().isLeafRoot) {\r
31711                             this._rootToNode(targetInfo);\r
31712                         }\r
31713                         else {\r
31714                             if (nodeClick === 'zoomToNode') {\r
31715                                 this._zoomToNode(targetInfo);\r
31716                             }\r
31717                             else if (nodeClick === 'link') {\r
31718                                 var itemModel = node.hostTree.data.getItemModel(node.dataIndex);\r
31719                                 var link = itemModel.get('link', true);\r
31720                                 var linkTarget = itemModel.get('target', true) || 'blank';\r
31721                                 link && window.open(link, linkTarget);\r
31722                             }\r
31723                         }\r
31724                     }\r
31725                 },\r
31726 \r
31727                 /**\r
31728                  * @private\r
31729                  */\r
31730                 _renderBreadcrumb: function (seriesModel, api, targetInfo) {\r
31731                     if (!targetInfo) {\r
31732                         // Find breadcrumb tail on center of containerGroup.\r
31733                         targetInfo = this.findTarget(api.getWidth() / 2, api.getHeight() / 2);\r
31734 \r
31735                         if (!targetInfo) {\r
31736                             targetInfo = {node: seriesModel.getData().tree.root};\r
31737                         }\r
31738                     }\r
31739 \r
31740                     (this._breadcrumb || (this._breadcrumb = new Breadcrumb(this.group, bind(onSelect, this))))\r
31741                         .render(seriesModel, api, targetInfo.node);\r
31742 \r
31743                     function onSelect(node) {\r
31744                         if (this._state !== 'animating') {\r
31745                             helper.aboveViewRoot(seriesModel.getViewRoot(), node)\r
31746                                 ? this._rootToNode({node: node})\r
31747                                 : this._zoomToNode({node: node});\r
31748                         }\r
31749                     }\r
31750                 },\r
31751 \r
31752                 /**\r
31753                  * @override\r
31754                  */\r
31755                 remove: function () {\r
31756                     this._clearController();\r
31757                     this._containerGroup && this._containerGroup.removeAll();\r
31758                     this._storage = createStorage();\r
31759                     this._state = 'ready';\r
31760                     this._breadcrumb && this._breadcrumb.remove();\r
31761                 },\r
31762 \r
31763                 dispose: function () {\r
31764                     this._clearController();\r
31765                 },\r
31766 \r
31767                 /**\r
31768                  * @private\r
31769                  */\r
31770                 _zoomToNode: function (targetInfo) {\r
31771                     this.api.dispatchAction({\r
31772                         type: 'treemapZoomToNode',\r
31773                         from: this.uid,\r
31774                         seriesId: this.seriesModel.id,\r
31775                         targetNode: targetInfo.node\r
31776                     });\r
31777                 },\r
31778 \r
31779                 /**\r
31780                  * @private\r
31781                  */\r
31782                 _rootToNode: function (targetInfo) {\r
31783                     this.api.dispatchAction({\r
31784                         type: 'treemapRootToNode',\r
31785                         from: this.uid,\r
31786                         seriesId: this.seriesModel.id,\r
31787                         targetNode: targetInfo.node\r
31788                     });\r
31789                 },\r
31790 \r
31791                 /**\r
31792                  * @public\r
31793                  * @param {number} x Global coord x.\r
31794                  * @param {number} y Global coord y.\r
31795                  * @return {Object} info If not found, return undefined;\r
31796                  * @return {number} info.node Target node.\r
31797                  * @return {number} info.offsetX x refer to target node.\r
31798                  * @return {number} info.offsetY y refer to target node.\r
31799                  */\r
31800                 findTarget: function (x, y) {\r
31801                     var targetInfo;\r
31802                     var viewRoot = this.seriesModel.getViewRoot();\r
31803 \r
31804                     viewRoot.eachNode({attr: 'viewChildren', order: 'preorder'}, function (node) {\r
31805                         var bgEl = this._storage.background[node.getRawIndex()];\r
31806                         // If invisible, there might be no element.\r
31807                         if (bgEl) {\r
31808                             var point = bgEl.transformCoordToLocal(x, y);\r
31809                             var shape = bgEl.shape;\r
31810 \r
31811                             // For performance consideration, dont use 'getBoundingRect'.\r
31812                             if (shape.x <= point[0]\r
31813                                 && point[0] <= shape.x + shape.width\r
31814                                 && shape.y <= point[1]\r
31815                                 && point[1] <= shape.y + shape.height\r
31816                             ) {\r
31817                                 targetInfo = {node: node, offsetX: point[0], offsetY: point[1]};\r
31818                             }\r
31819                             else {\r
31820                                 return false; // Suppress visit subtree.\r
31821                             }\r
31822                         }\r
31823                     }, this);\r
31824 \r
31825                     return targetInfo;\r
31826                 }\r
31827 \r
31828             });\r
31829 \r
31830             function createStorage() {\r
31831                 return {nodeGroup: [], background: [], content: []};\r
31832             }\r
31833 \r
31834 \r
31835 \r
31836 /***/ },\r
31837 /* 183 */\r
31838 /***/ function(module, exports, __webpack_require__) {\r
31839 \r
31840          \r
31841 \r
31842             var graphic = __webpack_require__(42);\r
31843             var layout = __webpack_require__(21);\r
31844             var zrUtil = __webpack_require__(3);\r
31845 \r
31846             var TEXT_PADDING = 8;\r
31847             var ITEM_GAP = 8;\r
31848             var ARRAY_LENGTH = 5;\r
31849 \r
31850             function Breadcrumb(containerGroup, onSelect) {\r
31851                 /**\r
31852                  * @private\r
31853                  * @type {module:zrender/container/Group}\r
31854                  */\r
31855                 this.group = new graphic.Group();\r
31856 \r
31857                 containerGroup.add(this.group);\r
31858 \r
31859                 /**\r
31860                  * @private\r
31861                  * @type {Function}\r
31862                  */\r
31863                 this._onSelect = onSelect || zrUtil.noop;\r
31864             }\r
31865 \r
31866             Breadcrumb.prototype = {\r
31867 \r
31868                 constructor: Breadcrumb,\r
31869 \r
31870                 render: function (seriesModel, api, targetNode) {\r
31871                     var model = seriesModel.getModel('breadcrumb');\r
31872                     var thisGroup = this.group;\r
31873 \r
31874                     thisGroup.removeAll();\r
31875 \r
31876                     if (!model.get('show') || !targetNode) {\r
31877                         return;\r
31878                     }\r
31879 \r
31880                     var normalStyleModel = model.getModel('itemStyle.normal');\r
31881                     // var emphasisStyleModel = model.getModel('itemStyle.emphasis');\r
31882                     var textStyleModel = normalStyleModel.getModel('textStyle');\r
31883 \r
31884                     var layoutParam = {\r
31885                         pos: {\r
31886                             left: model.get('left'),\r
31887                             right: model.get('right'),\r
31888                             top: model.get('top'),\r
31889                             bottom: model.get('bottom')\r
31890                         },\r
31891                         box: {\r
31892                             width: api.getWidth(),\r
31893                             height: api.getHeight()\r
31894                         },\r
31895                         emptyItemWidth: model.get('emptyItemWidth'),\r
31896                         totalWidth: 0,\r
31897                         renderList: []\r
31898                     };\r
31899 \r
31900                     this._prepare(\r
31901                         model, targetNode, layoutParam, textStyleModel\r
31902                     );\r
31903                     this._renderContent(\r
31904                         model, targetNode, layoutParam, normalStyleModel, textStyleModel\r
31905                     );\r
31906 \r
31907                     layout.positionGroup(thisGroup, layoutParam.pos, layoutParam.box);\r
31908                 },\r
31909 \r
31910                 /**\r
31911                  * Prepare render list and total width\r
31912                  * @private\r
31913                  */\r
31914                 _prepare: function (model, targetNode, layoutParam, textStyleModel) {\r
31915                     for (var node = targetNode; node; node = node.parentNode) {\r
31916                         var text = node.getModel().get('name');\r
31917                         var textRect = textStyleModel.getTextRect(text);\r
31918                         var itemWidth = Math.max(\r
31919                             textRect.width + TEXT_PADDING * 2,\r
31920                             layoutParam.emptyItemWidth\r
31921                         );\r
31922                         layoutParam.totalWidth += itemWidth + ITEM_GAP;\r
31923                         layoutParam.renderList.push({node: node, text: text, width: itemWidth});\r
31924                     }\r
31925                 },\r
31926 \r
31927                 /**\r
31928                  * @private\r
31929                  */\r
31930                 _renderContent: function (\r
31931                     model, targetNode, layoutParam, normalStyleModel, textStyleModel\r
31932                 ) {\r
31933                     // Start rendering.\r
31934                     var lastX = 0;\r
31935                     var emptyItemWidth = layoutParam.emptyItemWidth;\r
31936                     var height = model.get('height');\r
31937                     var availableSize = layout.getAvailableSize(layoutParam.pos, layoutParam.box);\r
31938                     var totalWidth = layoutParam.totalWidth;\r
31939                     var renderList = layoutParam.renderList;\r
31940 \r
31941                     for (var i = renderList.length - 1; i >= 0; i--) {\r
31942                         var item = renderList[i];\r
31943                         var itemWidth = item.width;\r
31944                         var text = item.text;\r
31945 \r
31946                         // Hdie text and shorten width if necessary.\r
31947                         if (totalWidth > availableSize.width) {\r
31948                             totalWidth -= itemWidth - emptyItemWidth;\r
31949                             itemWidth = emptyItemWidth;\r
31950                             text = '';\r
31951                         }\r
31952 \r
31953                         this.group.add(new graphic.Polygon({\r
31954                             shape: {\r
31955                                 points: makeItemPoints(\r
31956                                     lastX, 0, itemWidth, height,\r
31957                                     i === renderList.length - 1, i === 0\r
31958                                 )\r
31959                             },\r
31960                             style: zrUtil.defaults(\r
31961                                 normalStyleModel.getItemStyle(),\r
31962                                 {\r
31963                                     lineJoin: 'bevel',\r
31964                                     text: text,\r
31965                                     textFill: textStyleModel.getTextColor(),\r
31966                                     textFont: textStyleModel.getFont()\r
31967                                 }\r
31968                             ),\r
31969                             z: 10,\r
31970                             onclick: zrUtil.bind(this._onSelect, this, item.node)\r
31971                         }));\r
31972 \r
31973                         lastX += itemWidth + ITEM_GAP;\r
31974                     }\r
31975                 },\r
31976 \r
31977                 /**\r
31978                  * @override\r
31979                  */\r
31980                 remove: function () {\r
31981                     this.group.removeAll();\r
31982                 }\r
31983             };\r
31984 \r
31985             function makeItemPoints(x, y, itemWidth, itemHeight, head, tail) {\r
31986                 var points = [\r
31987                     [head ? x : x - ARRAY_LENGTH, y],\r
31988                     [x + itemWidth, y],\r
31989                     [x + itemWidth, y + itemHeight],\r
31990                     [head ? x : x - ARRAY_LENGTH, y + itemHeight]\r
31991                 ];\r
31992                 !tail && points.splice(2, 0, [x + itemWidth + ARRAY_LENGTH, y + itemHeight / 2]);\r
31993                 !head && points.push([x, y + itemHeight / 2]);\r
31994                 return points;\r
31995             }\r
31996 \r
31997             module.exports = Breadcrumb;\r
31998 \r
31999 \r
32000 /***/ },\r
32001 /* 184 */\r
32002 /***/ function(module, exports, __webpack_require__) {\r
32003 \r
32004          \r
32005 \r
32006             var zrUtil = __webpack_require__(3);\r
32007 \r
32008             /**\r
32009              * @param {number} [time=500] Time in ms\r
32010              * @param {string} [easing='linear']\r
32011              * @param {number} [delay=0]\r
32012              * @param {Function} [callback]\r
32013              *\r
32014              * @example\r
32015              *  // Animate position\r
32016              *  animation\r
32017              *      .createWrap()\r
32018              *      .add(el1, {position: [10, 10]})\r
32019              *      .add(el2, {shape: {width: 500}, style: {fill: 'red'}}, 400)\r
32020              *      .done(function () { // done })\r
32021              *      .start('cubicOut');\r
32022              */\r
32023             function createWrap() {\r
32024 \r
32025                 var storage = [];\r
32026                 var elExistsMap = {};\r
32027                 var doneCallback;\r
32028 \r
32029                 return {\r
32030 \r
32031                     /**\r
32032                      * Caution: a el can only be added once, otherwise 'done'\r
32033                      * might not be called. This method checks this (by el.id),\r
32034                      * suppresses adding and returns false when existing el found.\r
32035                      *\r
32036                      * @param {modele:zrender/Element} el\r
32037                      * @param {Object} target\r
32038                      * @param {number} [time=500]\r
32039                      * @param {number} [delay=0]\r
32040                      * @param {string} [easing='linear']\r
32041                      * @return {boolean} Whether adding succeeded.\r
32042                      *\r
32043                      * @example\r
32044                      *     add(el, target, time, delay, easing);\r
32045                      *     add(el, target, time, easing);\r
32046                      *     add(el, target, time);\r
32047                      *     add(el, target);\r
32048                      */\r
32049                     add: function (el, target, time, delay, easing) {\r
32050                         if (zrUtil.isString(delay)) {\r
32051                             easing = delay;\r
32052                             delay = 0;\r
32053                         }\r
32054 \r
32055                         if (elExistsMap[el.id]) {\r
32056                             return false;\r
32057                         }\r
32058                         elExistsMap[el.id] = 1;\r
32059 \r
32060                         storage.push(\r
32061                             {el: el, target: target, time: time, delay: delay, easing: easing}\r
32062                         );\r
32063 \r
32064                         return true;\r
32065                     },\r
32066 \r
32067                     /**\r
32068                      * Only execute when animation finished. Will not execute when any\r
32069                      * of 'stop' or 'stopAnimation' called.\r
32070                      *\r
32071                      * @param {Function} callback\r
32072                      */\r
32073                     done: function (callback) {\r
32074                         doneCallback = callback;\r
32075                         return this;\r
32076                     },\r
32077 \r
32078                     /**\r
32079                      * Will stop exist animation firstly.\r
32080                      */\r
32081                     start: function () {\r
32082                         var count = storage.length;\r
32083 \r
32084                         for (var i = 0, len = storage.length; i < len; i++) {\r
32085                             var item = storage[i];\r
32086                             item.el.animateTo(item.target, item.time, item.delay, item.easing, done);\r
32087                         }\r
32088 \r
32089                         return this;\r
32090 \r
32091                         function done() {\r
32092                             count--;\r
32093                             if (!count) {\r
32094                                 storage.length = 0;\r
32095                                 elExistsMap = {};\r
32096                                 doneCallback && doneCallback();\r
32097                             }\r
32098                         }\r
32099                     }\r
32100                 };\r
32101             }\r
32102 \r
32103             module.exports = {createWrap: createWrap};\r
32104 \r
32105 \r
32106 /***/ },\r
32107 /* 185 */\r
32108 /***/ function(module, exports, __webpack_require__) {\r
32109 \r
32110         /**\r
32111          * @file Treemap action\r
32112          */\r
32113 \r
32114 \r
32115             var echarts = __webpack_require__(1);\r
32116             var helper = __webpack_require__(181);\r
32117 \r
32118             var noop = function () {};\r
32119 \r
32120             var actionTypes = [\r
32121                 'treemapZoomToNode',\r
32122                 'treemapRender',\r
32123                 'treemapMove'\r
32124             ];\r
32125 \r
32126             for (var i = 0; i < actionTypes.length; i++) {\r
32127                 echarts.registerAction({type: actionTypes[i], update: 'updateView'}, noop);\r
32128             }\r
32129 \r
32130             echarts.registerAction(\r
32131                 {type: 'treemapRootToNode', update: 'updateView'},\r
32132                 function (payload, ecModel) {\r
32133                     ecModel.eachComponent(\r
32134                         {mainType: 'series', subType: 'treemap', query: payload},\r
32135                         function (model, index) {\r
32136                             var targetInfo = helper.retrieveTargetInfo(payload, model);\r
32137 \r
32138                             if (targetInfo) {\r
32139                                 var originViewRoot = model.getViewRoot();\r
32140                                 if (originViewRoot) {\r
32141                                     payload.direction = helper.aboveViewRoot(originViewRoot, targetInfo.node)\r
32142                                         ? 'rollup' : 'drilldown';\r
32143                                 }\r
32144                                 model.resetViewRoot(targetInfo.node);\r
32145                             }\r
32146                         }\r
32147                     );\r
32148                 }\r
32149             );\r
32150 \r
32151 \r
32152 \r
32153 /***/ },\r
32154 /* 186 */\r
32155 /***/ function(module, exports, __webpack_require__) {\r
32156 \r
32157         \r
32158 \r
32159             var VisualMapping = __webpack_require__(187);\r
32160             var zrColor = __webpack_require__(38);\r
32161             var zrUtil = __webpack_require__(3);\r
32162             var isArray = zrUtil.isArray;\r
32163 \r
32164             var ITEM_STYLE_NORMAL = 'itemStyle.normal';\r
32165 \r
32166             module.exports = function (ecModel, payload) {\r
32167 \r
32168                 var condition = {mainType: 'series', subType: 'treemap', query: payload};\r
32169                 ecModel.eachComponent(condition, function (seriesModel) {\r
32170 \r
32171                     var tree = seriesModel.getData().tree;\r
32172                     var root = tree.root;\r
32173                     var seriesItemStyleModel = seriesModel.getModel(ITEM_STYLE_NORMAL);\r
32174 \r
32175                     if (root.isRemoved()) {\r
32176                         return;\r
32177                     }\r
32178 \r
32179                     var levelItemStyles = zrUtil.map(tree.levelModels, function (levelModel) {\r
32180                         return levelModel ? levelModel.get(ITEM_STYLE_NORMAL) : null;\r
32181                     });\r
32182 \r
32183                     travelTree(\r
32184                         root,\r
32185                         {},\r
32186                         levelItemStyles,\r
32187                         seriesItemStyleModel,\r
32188                         seriesModel.getViewRoot().getAncestors(),\r
32189                         seriesModel\r
32190                     );\r
32191                 });\r
32192             };\r
32193 \r
32194             function travelTree(\r
32195                 node, designatedVisual, levelItemStyles, seriesItemStyleModel,\r
32196                 viewRootAncestors, seriesModel\r
32197             ) {\r
32198                 var nodeModel = node.getModel();\r
32199                 var nodeLayout = node.getLayout();\r
32200 \r
32201                 // Optimize\r
32202                 if (nodeLayout.invisible) {\r
32203                     return;\r
32204                 }\r
32205 \r
32206                 var nodeItemStyleModel = node.getModel(ITEM_STYLE_NORMAL);\r
32207                 var levelItemStyle = levelItemStyles[node.depth];\r
32208                 var visuals = buildVisuals(\r
32209                     nodeItemStyleModel, designatedVisual, levelItemStyle, seriesItemStyleModel\r
32210                 );\r
32211 \r
32212                 // calculate border color\r
32213                 var borderColor = nodeItemStyleModel.get('borderColor');\r
32214                 var borderColorSaturation = nodeItemStyleModel.get('borderColorSaturation');\r
32215                 var thisNodeColor;\r
32216                 if (borderColorSaturation != null) {\r
32217                     // For performance, do not always execute 'calculateColor'.\r
32218                     thisNodeColor = calculateColor(visuals, node);\r
32219                     borderColor = calculateBorderColor(borderColorSaturation, thisNodeColor);\r
32220                 }\r
32221                 node.setVisual('borderColor', borderColor);\r
32222 \r
32223                 var viewChildren = node.viewChildren;\r
32224                 if (!viewChildren || !viewChildren.length) {\r
32225                     thisNodeColor = calculateColor(visuals, node);\r
32226                     // Apply visual to this node.\r
32227                     node.setVisual('color', thisNodeColor);\r
32228                 }\r
32229                 else {\r
32230                     var mapping = buildVisualMapping(\r
32231                         node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren\r
32232                     );\r
32233                     // Designate visual to children.\r
32234                     zrUtil.each(viewChildren, function (child, index) {\r
32235                         // If higher than viewRoot, only ancestors of viewRoot is needed to visit.\r
32236                         if (child.depth >= viewRootAncestors.length\r
32237                             || child === viewRootAncestors[child.depth]\r
32238                         ) {\r
32239                             var childVisual = mapVisual(\r
32240                                 nodeModel, visuals, child, index, mapping, seriesModel\r
32241                             );\r
32242                             travelTree(\r
32243                                 child, childVisual, levelItemStyles, seriesItemStyleModel,\r
32244                                 viewRootAncestors, seriesModel\r
32245                             );\r
32246                         }\r
32247                     });\r
32248                 }\r
32249             }\r
32250 \r
32251             function buildVisuals(\r
32252                 nodeItemStyleModel, designatedVisual, levelItemStyle, seriesItemStyleModel\r
32253             ) {\r
32254                 var visuals = zrUtil.extend({}, designatedVisual);\r
32255 \r
32256                 zrUtil.each(['color', 'colorAlpha', 'colorSaturation'], function (visualName) {\r
32257                     // Priority: thisNode > thisLevel > parentNodeDesignated > seriesModel\r
32258                     var val = nodeItemStyleModel.get(visualName, true); // Ignore parent\r
32259                     val == null && levelItemStyle && (val = levelItemStyle[visualName]);\r
32260                     val == null && (val = designatedVisual[visualName]);\r
32261                     val == null && (val = seriesItemStyleModel.get(visualName));\r
32262 \r
32263                     val != null && (visuals[visualName] = val);\r
32264                 });\r
32265 \r
32266                 return visuals;\r
32267             }\r
32268 \r
32269             function calculateColor(visuals) {\r
32270                 var color = getValueVisualDefine(visuals, 'color');\r
32271 \r
32272                 if (color) {\r
32273                     var colorAlpha = getValueVisualDefine(visuals, 'colorAlpha');\r
32274                     var colorSaturation = getValueVisualDefine(visuals, 'colorSaturation');\r
32275                     if (colorSaturation) {\r
32276                         color = zrColor.modifyHSL(color, null, null, colorSaturation);\r
32277                     }\r
32278                     if (colorAlpha) {\r
32279                         color = zrColor.modifyAlpha(color, colorAlpha);\r
32280                     }\r
32281 \r
32282                     return color;\r
32283                 }\r
32284             }\r
32285 \r
32286             function calculateBorderColor(borderColorSaturation, thisNodeColor) {\r
32287                 return thisNodeColor != null\r
32288                      ? zrColor.modifyHSL(thisNodeColor, null, null, borderColorSaturation)\r
32289                      : null;\r
32290             }\r
32291 \r
32292             function getValueVisualDefine(visuals, name) {\r
32293                 var value = visuals[name];\r
32294                 if (value != null && value !== 'none') {\r
32295                     return value;\r
32296                 }\r
32297             }\r
32298 \r
32299             function buildVisualMapping(\r
32300                 node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren\r
32301             ) {\r
32302                 if (!viewChildren || !viewChildren.length) {\r
32303                     return;\r
32304                 }\r
32305 \r
32306                 var rangeVisual = getRangeVisual(nodeModel, 'color')\r
32307                     || (\r
32308                         visuals.color != null\r
32309                         && visuals.color !== 'none'\r
32310                         && (\r
32311                             getRangeVisual(nodeModel, 'colorAlpha')\r
32312                             || getRangeVisual(nodeModel, 'colorSaturation')\r
32313                         )\r
32314                     );\r
32315 \r
32316                 if (!rangeVisual) {\r
32317                     return;\r
32318                 }\r
32319 \r
32320                 var colorMappingBy = nodeModel.get('colorMappingBy');\r
32321                 var opt = {\r
32322                     type: rangeVisual.name,\r
32323                     dataExtent: nodeLayout.dataExtent,\r
32324                     visual: rangeVisual.range\r
32325                 };\r
32326                 if (opt.type === 'color'\r
32327                     && (colorMappingBy === 'index' || colorMappingBy === 'id')\r
32328                 ) {\r
32329                     opt.mappingMethod = 'category';\r
32330                     opt.loop = true;\r
32331                     // categories is ordinal, so do not set opt.categories.\r
32332                 }\r
32333                 else {\r
32334                     opt.mappingMethod = 'linear';\r
32335                 }\r
32336 \r
32337                 var mapping = new VisualMapping(opt);\r
32338                 mapping.__drColorMappingBy = colorMappingBy;\r
32339 \r
32340                 return mapping;\r
32341             }\r
32342 \r
32343             // Notice: If we dont have the attribute 'colorRange', but only use\r
32344             // attribute 'color' to represent both concepts of 'colorRange' and 'color',\r
32345             // (It means 'colorRange' when 'color' is Array, means 'color' when not array),\r
32346             // this problem will be encountered:\r
32347             // If a level-1 node dont have children, and its siblings has children,\r
32348             // and colorRange is set on level-1, then the node can not be colored.\r
32349             // So we separate 'colorRange' and 'color' to different attributes.\r
32350             function getRangeVisual(nodeModel, name) {\r
32351                 // 'colorRange', 'colorARange', 'colorSRange'.\r
32352                 // If not exsits on this node, fetch from levels and series.\r
32353                 var range = nodeModel.get(name);\r
32354                 return (isArray(range) && range.length) ? {name: name, range: range} : null;\r
32355             }\r
32356 \r
32357             function mapVisual(nodeModel, visuals, child, index, mapping, seriesModel) {\r
32358                 var childVisuals = zrUtil.extend({}, visuals);\r
32359 \r
32360                 if (mapping) {\r
32361                     var mappingType = mapping.type;\r
32362                     var colorMappingBy = mappingType === 'color' && mapping.__drColorMappingBy;\r
32363                     var value =\r
32364                         colorMappingBy === 'index'\r
32365                         ? index\r
32366                         : colorMappingBy === 'id'\r
32367                         ? seriesModel.mapIdToIndex(child.getId())\r
32368                         : child.getValue(nodeModel.get('visualDimension'));\r
32369 \r
32370                     childVisuals[mappingType] = mapping.mapValueToVisual(value);\r
32371                 }\r
32372 \r
32373                 return childVisuals;\r
32374             }\r
32375 \r
32376 \r
32377 \r
32378 /***/ },\r
32379 /* 187 */\r
32380 /***/ function(module, exports, __webpack_require__) {\r
32381 \r
32382         /**\r
32383          * @file Visual mapping.\r
32384          */\r
32385 \r
32386 \r
32387             var zrUtil = __webpack_require__(3);\r
32388             var zrColor = __webpack_require__(38);\r
32389             var linearMap = __webpack_require__(7).linearMap;\r
32390             var each = zrUtil.each;\r
32391             var isObject = zrUtil.isObject;\r
32392 \r
32393             var CATEGORY_DEFAULT_VISUAL_INDEX = -1;\r
32394 \r
32395             function linearMapArray(val, domain, range, clamp) {\r
32396                 if (zrUtil.isArray(val)) {\r
32397                     return zrUtil.map(val, function (v) {\r
32398                         return linearMap(v, domain, range, clamp);\r
32399                     });\r
32400                 }\r
32401                 return linearMap(val, domain, range, clamp);\r
32402             }\r
32403             /**\r
32404              * @param {Object} option\r
32405              * @param {string} [option.type] See visualHandlers.\r
32406              * @param {string} [option.mappingMethod] 'linear' or 'piecewise' or 'category'\r
32407              * @param {Array.<number>=} [option.dataExtent] [minExtent, maxExtent],\r
32408              *                                              required when mappingMethod is 'linear'\r
32409              * @param {Array.<Object>=} [option.pieceList] [\r
32410              *                                             {value: someValue},\r
32411              *                                             {interval: [min1, max1], visual: {...}},\r
32412              *                                             {interval: [min2, max2]}\r
32413              *                                             ],\r
32414              *                                            required when mappingMethod is 'piecewise'.\r
32415              *                                            Visual for only each piece can be specified.\r
32416              * @param {Array.<string|Object>=} [option.categories] ['cate1', 'cate2']\r
32417              *                                            required when mappingMethod is 'category'.\r
32418              *                                            If no option.categories, it represents\r
32419              *                                            categories is [0, 1, 2, ...].\r
32420              * @param {boolean} [option.loop=false] Whether loop mapping when mappingMethod is 'category'.\r
32421              * @param {(Array|Object|*)} [option.visual]  Visual data.\r
32422              *                                            when mappingMethod is 'category',\r
32423              *                                            visual data can be array or object\r
32424              *                                            (like: {cate1: '#222', none: '#fff'})\r
32425              *                                            or primary types (which represents\r
32426              *                                            defualt category visual), otherwise visual\r
32427              *                                            can only be array.\r
32428              *\r
32429              */\r
32430             var VisualMapping = function (option) {\r
32431                 var mappingMethod = option.mappingMethod;\r
32432                 var visualType = option.type;\r
32433 \r
32434                 /**\r
32435                  * @readOnly\r
32436                  * @type {string}\r
32437                  */\r
32438                 this.type = visualType;\r
32439 \r
32440                 /**\r
32441                  * @readOnly\r
32442                  * @type {string}\r
32443                  */\r
32444                 this.mappingMethod = mappingMethod;\r
32445 \r
32446                 /**\r
32447                  * @readOnly\r
32448                  * @type {Object}\r
32449                  */\r
32450                 var thisOption = this.option = zrUtil.clone(option);\r
32451 \r
32452                 /**\r
32453                  * @private\r
32454                  * @type {Function}\r
32455                  */\r
32456                 this._normalizeData = normalizers[mappingMethod];\r
32457 \r
32458                 /**\r
32459                  * @private\r
32460                  * @type {Function}\r
32461                  */\r
32462                 this._getSpecifiedVisual = zrUtil.bind(\r
32463                     specifiedVisualGetters[mappingMethod], this, visualType\r
32464                 );\r
32465 \r
32466                 zrUtil.extend(this, visualHandlers[visualType]);\r
32467 \r
32468                 if (mappingMethod === 'piecewise') {\r
32469                     preprocessForPiecewise(thisOption);\r
32470                 }\r
32471                 if (mappingMethod === 'category') {\r
32472                     preprocessForCategory(thisOption);\r
32473                 }\r
32474             };\r
32475 \r
32476             VisualMapping.prototype = {\r
32477 \r
32478                 constructor: VisualMapping,\r
32479 \r
32480                 applyVisual: null,\r
32481 \r
32482                 isValueActive: null,\r
32483 \r
32484                 mapValueToVisual: null,\r
32485 \r
32486                 getNormalizer: function () {\r
32487                     return zrUtil.bind(this._normalizeData, this);\r
32488                 }\r
32489             };\r
32490 \r
32491             var visualHandlers = VisualMapping.visualHandlers = {\r
32492 \r
32493                 color: {\r
32494 \r
32495                     applyVisual: defaultApplyColor,\r
32496 \r
32497                     /**\r
32498                      * Create a mapper function\r
32499                      * @return {Function}\r
32500                      */\r
32501                     getColorMapper: function () {\r
32502                         var visual = isCategory(this)\r
32503                             ? this.option.visual\r
32504                             : zrUtil.map(this.option.visual, zrColor.parse);\r
32505                         return zrUtil.bind(\r
32506                             isCategory(this)\r
32507                             ? function (value, isNormalized) {\r
32508                                 !isNormalized && (value = this._normalizeData(value));\r
32509                                 return getVisualForCategory(this, visual, value);\r
32510                             }\r
32511                             : function (value, isNormalized, out) {\r
32512                                 // If output rgb array\r
32513                                 // which will be much faster and useful in pixel manipulation\r
32514                                 var returnRGBArray = !!out;\r
32515                                 !isNormalized && (value = this._normalizeData(value));\r
32516                                 out = zrColor.fastMapToColor(value, visual, out);\r
32517                                 return returnRGBArray ? out : zrUtil.stringify(out, 'rgba');\r
32518                             }, this);\r
32519                     },\r
32520 \r
32521                     // value:\r
32522                     // (1) {number}\r
32523                     // (2) {Array.<number>} Represents a interval, for colorStops.\r
32524                     // Return type:\r
32525                     // (1) {string} color value like '#444'\r
32526                     // (2) {Array.<Object>} colorStops,\r
32527                     // like [{color: '#fff', offset: 0}, {color: '#444', offset: 1}]\r
32528                     // where offset is between 0 and 1.\r
32529                     mapValueToVisual: function (value) {\r
32530                         var visual = this.option.visual;\r
32531 \r
32532                         if (zrUtil.isArray(value)) {\r
32533                             value = [\r
32534                                 this._normalizeData(value[0]),\r
32535                                 this._normalizeData(value[1])\r
32536                             ];\r
32537 \r
32538                             // For creating gradient color list.\r
32539                             return zrColor.mapIntervalToColor(value, visual);\r
32540                         }\r
32541                         else {\r
32542                             var normalized = this._normalizeData(value);\r
32543                             var result = this._getSpecifiedVisual(value);\r
32544 \r
32545                             if (result == null) {\r
32546                                 result = isCategory(this)\r
32547                                     ? getVisualForCategory(this, visual, normalized)\r
32548                                     : zrColor.mapToColor(normalized, visual);\r
32549                             }\r
32550 \r
32551                             return result;\r
32552                         }\r
32553                     }\r
32554                 },\r
32555 \r
32556                 colorHue: makePartialColorVisualHandler(function (color, value) {\r
32557                     return zrColor.modifyHSL(color, value);\r
32558                 }),\r
32559 \r
32560                 colorSaturation: makePartialColorVisualHandler(function (color, value) {\r
32561                     return zrColor.modifyHSL(color, null, value);\r
32562                 }),\r
32563 \r
32564                 colorLightness: makePartialColorVisualHandler(function (color, value) {\r
32565                     return zrColor.modifyHSL(color, null, null, value);\r
32566                 }),\r
32567 \r
32568                 colorAlpha: makePartialColorVisualHandler(function (color, value) {\r
32569                     return zrColor.modifyAlpha(color, value);\r
32570                 }),\r
32571 \r
32572                 symbol: {\r
32573                     applyVisual: function (value, getter, setter) {\r
32574                         var symbolCfg = this.mapValueToVisual(value);\r
32575                         if (zrUtil.isString(symbolCfg)) {\r
32576                             setter('symbol', symbolCfg);\r
32577                         }\r
32578                         else if (isObject(symbolCfg)) {\r
32579                             for (var name in symbolCfg) {\r
32580                                 if (symbolCfg.hasOwnProperty(name)) {\r
32581                                     setter(name, symbolCfg[name]);\r
32582                                 }\r
32583                             }\r
32584                         }\r
32585                     },\r
32586 \r
32587                     mapValueToVisual: function (value) {\r
32588                         var normalized = this._normalizeData(value);\r
32589                         var result = this._getSpecifiedVisual(value);\r
32590                         var visual = this.option.visual;\r
32591 \r
32592                         if (result == null) {\r
32593                             result = isCategory(this)\r
32594                                 ? getVisualForCategory(this, visual, normalized)\r
32595                                 : (arrayGetByNormalizedValue(visual, normalized) || {});\r
32596                         }\r
32597 \r
32598                         return result;\r
32599                     }\r
32600                 },\r
32601 \r
32602                 symbolSize: {\r
32603                     applyVisual: function (value, getter, setter) {\r
32604                         setter('symbolSize', this.mapValueToVisual(value));\r
32605                     },\r
32606 \r
32607                     mapValueToVisual: function (value) {\r
32608                         var normalized = this._normalizeData(value);\r
32609                         var result = this._getSpecifiedVisual(value);\r
32610                         var visual = this.option.visual;\r
32611 \r
32612                         if (result == null) {\r
32613                             result = isCategory(this)\r
32614                                 ? getVisualForCategory(this, visual, normalized)\r
32615                                 : linearMapArray(normalized, [0, 1], visual, true);\r
32616                         }\r
32617                         return result;\r
32618                     }\r
32619                 }\r
32620             };\r
32621 \r
32622             function preprocessForPiecewise(thisOption) {\r
32623                 var pieceList = thisOption.pieceList;\r
32624                 thisOption.hasSpecialVisual = false;\r
32625 \r
32626                 zrUtil.each(pieceList, function (piece, index) {\r
32627                     piece.originIndex = index;\r
32628                     if (piece.visual) {\r
32629                         thisOption.hasSpecialVisual = true;\r
32630                     }\r
32631                 });\r
32632             }\r
32633 \r
32634             function preprocessForCategory(thisOption) {\r
32635                 // Hash categories.\r
32636                 var categories = thisOption.categories;\r
32637                 var visual = thisOption.visual;\r
32638                 var isVisualArray = zrUtil.isArray(visual);\r
32639 \r
32640                 if (!categories) {\r
32641                     if (!isVisualArray) {\r
32642                         // visual should be array when no categories.\r
32643                         throw new Error();\r
32644                     }\r
32645                     else {\r
32646                         return;\r
32647                     }\r
32648                 }\r
32649 \r
32650                 var categoryMap = thisOption.categoryMap = {};\r
32651                 each(categories, function (cate, index) {\r
32652                     categoryMap[cate] = index;\r
32653                 });\r
32654 \r
32655                 // Process visual map input.\r
32656                 if (!isVisualArray) {\r
32657                     var visualArr = [];\r
32658 \r
32659                     if (zrUtil.isObject(visual)) {\r
32660                         each(visual, function (v, cate) {\r
32661                             var index = categoryMap[cate];\r
32662                             visualArr[index != null ? index : CATEGORY_DEFAULT_VISUAL_INDEX] = v;\r
32663                         });\r
32664                     }\r
32665                     else { // Is primary type, represents default visual.\r
32666                         visualArr[CATEGORY_DEFAULT_VISUAL_INDEX] = visual;\r
32667                     }\r
32668 \r
32669                     visual = thisOption.visual = visualArr;\r
32670                 }\r
32671 \r
32672                 // Remove categories that has no visual,\r
32673                 // then we can mapping them to CATEGORY_DEFAULT_VISUAL_INDEX.\r
32674                 for (var i = categories.length - 1; i >= 0; i--) {\r
32675                     if (visual[i] == null) {\r
32676                         delete categoryMap[categories[i]];\r
32677                         categories.pop();\r
32678                     }\r
32679                 }\r
32680             }\r
32681 \r
32682             function makePartialColorVisualHandler(applyValue) {\r
32683                 return {\r
32684 \r
32685                     applyVisual: function (value, getter, setter) {\r
32686                         // color can be {string} or {Array.<Object>} (for gradient color stops)\r
32687                         var color = getter('color');\r
32688                         var isArrayValue = zrUtil.isArray(value);\r
32689                         value = isArrayValue\r
32690                             ? [this.mapValueToVisual(value[0]), this.mapValueToVisual(value[1])]\r
32691                             : this.mapValueToVisual(value);\r
32692 \r
32693                         if (zrUtil.isArray(color)) {\r
32694                             for (var i = 0, len = color.length; i < len; i++) {\r
32695                                 color[i].color = applyValue(\r
32696                                     color[i].color, isArrayValue ? value[i] : value\r
32697                                 );\r
32698                             }\r
32699                         }\r
32700                         else {\r
32701                             // Must not be array value\r
32702                             setter('color', applyValue(color, value));\r
32703                         }\r
32704                     },\r
32705 \r
32706                     mapValueToVisual: function (value) {\r
32707                         var normalized = this._normalizeData(value);\r
32708                         var result = this._getSpecifiedVisual(value);\r
32709                         var visual = this.option.visual;\r
32710 \r
32711                         if (result == null) {\r
32712                             result = isCategory(this)\r
32713                                 ? getVisualForCategory(this, visual, normalized)\r
32714                                 : linearMapArray(normalized, [0, 1], visual, true);\r
32715                         }\r
32716                         return result;\r
32717                     }\r
32718                 };\r
32719             }\r
32720 \r
32721             function arrayGetByNormalizedValue(arr, normalized) {\r
32722                 return arr[\r
32723                     Math.round(linearMapArray(normalized, [0, 1], [0, arr.length - 1], true))\r
32724                 ];\r
32725             }\r
32726 \r
32727             function defaultApplyColor(value, getter, setter) {\r
32728                 setter('color', this.mapValueToVisual(value));\r
32729             }\r
32730 \r
32731             function getVisualForCategory(me, visual, normalized) {\r
32732                 return visual[\r
32733                     (me.option.loop && normalized !== CATEGORY_DEFAULT_VISUAL_INDEX)\r
32734                         ? normalized % visual.length\r
32735                         : normalized\r
32736                 ];\r
32737             }\r
32738 \r
32739             function isCategory(me) {\r
32740                 return me.option.mappingMethod === 'category';\r
32741             }\r
32742 \r
32743 \r
32744             var normalizers = {\r
32745 \r
32746                 linear: function (value) {\r
32747                     return linearMapArray(value, this.option.dataExtent, [0, 1], true);\r
32748                 },\r
32749 \r
32750                 piecewise: function (value) {\r
32751                     var pieceList = this.option.pieceList;\r
32752                     var pieceIndex = VisualMapping.findPieceIndex(value, pieceList);\r
32753                     if (pieceIndex != null) {\r
32754                         return linearMapArray(pieceIndex, [0, pieceList.length - 1], [0, 1], true);\r
32755                     }\r
32756                 },\r
32757 \r
32758                 category: function (value) {\r
32759                     var index = this.option.categories\r
32760                         ? this.option.categoryMap[value]\r
32761                         : value; // ordinal\r
32762                     return index == null ? CATEGORY_DEFAULT_VISUAL_INDEX : index;\r
32763                 }\r
32764             };\r
32765 \r
32766 \r
32767             // FIXME\r
32768             // refactor\r
32769             var specifiedVisualGetters = {\r
32770 \r
32771                 // Linear do not support this feature.\r
32772                 linear: zrUtil.noop,\r
32773 \r
32774                 piecewise: function (visualType, value) {\r
32775                     var thisOption = this.option;\r
32776                     var pieceList = thisOption.pieceList;\r
32777                     if (thisOption.hasSpecialVisual) {\r
32778                         var pieceIndex = VisualMapping.findPieceIndex(value, pieceList);\r
32779                         var piece = pieceList[pieceIndex];\r
32780                         if (piece && piece.visual) {\r
32781                             return piece.visual[visualType];\r
32782                         }\r
32783                     }\r
32784                 },\r
32785 \r
32786                 // Category do not need to support this feature.\r
32787                 // Visual can be set in visualMap.inRange or\r
32788                 // visualMap.outOfRange directly.\r
32789                 category: zrUtil.noop\r
32790             };\r
32791 \r
32792             /**\r
32793              * @public\r
32794              */\r
32795             VisualMapping.addVisualHandler = function (name, handler) {\r
32796                 visualHandlers[name] = handler;\r
32797             };\r
32798 \r
32799             /**\r
32800              * @public\r
32801              */\r
32802             VisualMapping.isValidType = function (visualType) {\r
32803                 return visualHandlers.hasOwnProperty(visualType);\r
32804             };\r
32805 \r
32806             /**\r
32807              * Convinent method.\r
32808              * Visual can be Object or Array or primary type.\r
32809              *\r
32810              * @public\r
32811              */\r
32812             VisualMapping.eachVisual = function (visual, callback, context) {\r
32813                 if (zrUtil.isObject(visual)) {\r
32814                     zrUtil.each(visual, callback, context);\r
32815                 }\r
32816                 else {\r
32817                     callback.call(context, visual);\r
32818                 }\r
32819             };\r
32820 \r
32821             VisualMapping.mapVisual = function (visual, callback, context) {\r
32822                 var isPrimary;\r
32823                 var newVisual = zrUtil.isArray(visual)\r
32824                     ? []\r
32825                     : zrUtil.isObject(visual)\r
32826                     ? {}\r
32827                     : (isPrimary = true, null);\r
32828 \r
32829                 VisualMapping.eachVisual(visual, function (v, key) {\r
32830                     var newVal = callback.call(context, v, key);\r
32831                     isPrimary ? (newVisual = newVal) : (newVisual[key] = newVal);\r
32832                 });\r
32833                 return newVisual;\r
32834             };\r
32835 \r
32836             /**\r
32837              * 'color', 'colorSaturation', 'colorAlpha', ... are in the same visualCluster named 'color'.\r
32838              * Other visuals are in the cluster named as the same as theirselves.\r
32839              *\r
32840              * @public\r
32841              * @param {string} visualType\r
32842              * @param {string} visualCluster\r
32843              * @return {boolean}\r
32844              */\r
32845             VisualMapping.isInVisualCluster = function (visualType, visualCluster) {\r
32846                 return visualCluster === 'color'\r
32847                     ? !!(visualType && visualType.indexOf(visualCluster) === 0)\r
32848                     : visualType === visualCluster;\r
32849             };\r
32850 \r
32851             /**\r
32852              * @public\r
32853              * @param {Object} obj\r
32854              * @return {Oject} new object containers visual values.\r
32855              *                 If no visuals, return null.\r
32856              */\r
32857             VisualMapping.retrieveVisuals = function (obj) {\r
32858                 var ret = {};\r
32859                 var hasVisual;\r
32860 \r
32861                 obj && each(visualHandlers, function (h, visualType) {\r
32862                     if (obj.hasOwnProperty(visualType)) {\r
32863                         ret[visualType] = obj[visualType];\r
32864                         hasVisual = true;\r
32865                     }\r
32866                 });\r
32867 \r
32868                 return hasVisual ? ret : null;\r
32869             };\r
32870 \r
32871             /**\r
32872              * Give order to visual types, considering colorSaturation, colorAlpha depends on color.\r
32873              *\r
32874              * @public\r
32875              * @param {(Object|Array)} visualTypes If Object, like: {color: ..., colorSaturation: ...}\r
32876              *                                     IF Array, like: ['color', 'symbol', 'colorSaturation']\r
32877              * @return {Array.<string>} Sorted visual types.\r
32878              */\r
32879             VisualMapping.prepareVisualTypes = function (visualTypes) {\r
32880                 if (isObject(visualTypes)) {\r
32881                     var types = [];\r
32882                     each(visualTypes, function (item, type) {\r
32883                         types.push(type);\r
32884                     });\r
32885                     visualTypes = types;\r
32886                 }\r
32887                 else if (zrUtil.isArray(visualTypes)) {\r
32888                     visualTypes = visualTypes.slice();\r
32889                 }\r
32890                 else {\r
32891                     return [];\r
32892                 }\r
32893 \r
32894                 visualTypes.sort(function (type1, type2) {\r
32895                     // color should be front of colorSaturation, colorAlpha, ...\r
32896                     // symbol and symbolSize do not matter.\r
32897                     return (type2 === 'color' && type1 !== 'color' && type1.indexOf('color') === 0)\r
32898                         ? 1 : -1;\r
32899                 });\r
32900 \r
32901                 return visualTypes;\r
32902             };\r
32903 \r
32904             /**\r
32905              * @public {Array.<Object>} [{value: ..., interval: [min, max]}, ...]\r
32906              * @return {number} index\r
32907              */\r
32908             VisualMapping.findPieceIndex = function (value, pieceList) {\r
32909                 // value has high priority.\r
32910                 for (var i = 0, len = pieceList.length; i < len; i++) {\r
32911                     var piece = pieceList[i];\r
32912                     if (piece.value != null && piece.value === value) {\r
32913                         return i;\r
32914                     }\r
32915                 }\r
32916 \r
32917                 for (var i = 0, len = pieceList.length; i < len; i++) {\r
32918                     var piece = pieceList[i];\r
32919                     var interval = piece.interval;\r
32920                     if (interval) {\r
32921                         if (interval[0] === -Infinity) {\r
32922                             if (value < interval[1]) {\r
32923                                 return i;\r
32924                             }\r
32925                         }\r
32926                         else if (interval[1] === Infinity) {\r
32927                             if (interval[0] < value) {\r
32928                                 return i;\r
32929                             }\r
32930                         }\r
32931                         else if (\r
32932                             piece.interval[0] <= value\r
32933                             && value <= piece.interval[1]\r
32934                         ) {\r
32935                             return i;\r
32936                         }\r
32937                     }\r
32938                 }\r
32939             };\r
32940 \r
32941             module.exports = VisualMapping;\r
32942 \r
32943 \r
32944 \r
32945 \r
32946 /***/ },\r
32947 /* 188 */\r
32948 /***/ function(module, exports, __webpack_require__) {\r
32949 \r
32950         \r
32951 \r
32952             var mathMax = Math.max;\r
32953             var mathMin = Math.min;\r
32954             var zrUtil = __webpack_require__(3);\r
32955             var numberUtil = __webpack_require__(7);\r
32956             var layout = __webpack_require__(21);\r
32957             var helper = __webpack_require__(181);\r
32958             var parsePercent = numberUtil.parsePercent;\r
32959             var retrieveValue = zrUtil.retrieve;\r
32960             var BoundingRect = __webpack_require__(15);\r
32961             var helper = __webpack_require__(181);\r
32962 \r
32963             /**\r
32964              * @public\r
32965              */\r
32966             function update(ecModel, api, payload) {\r
32967                 // Layout result in each node:\r
32968                 // {x, y, width, height, area, borderWidth}\r
32969                 var condition = {mainType: 'series', subType: 'treemap', query: payload};\r
32970                 ecModel.eachComponent(condition, function (seriesModel) {\r
32971 \r
32972                     var ecWidth = api.getWidth();\r
32973                     var ecHeight = api.getHeight();\r
32974                     var seriesOption = seriesModel.option;\r
32975 \r
32976                     var size = seriesOption.size || []; // Compatible with ec2.\r
32977                     var containerWidth = parsePercent(\r
32978                         retrieveValue(seriesOption.width, size[0]),\r
32979                         ecWidth\r
32980                     );\r
32981                     var containerHeight = parsePercent(\r
32982                         retrieveValue(seriesOption.height, size[1]),\r
32983                         ecHeight\r
32984                     );\r
32985 \r
32986                     var layoutInfo = layout.getLayoutRect(\r
32987                         seriesModel.getBoxLayoutParams(),\r
32988                         {\r
32989                             width: api.getWidth(),\r
32990                             height: api.getHeight()\r
32991                         }\r
32992                     );\r
32993 \r
32994                     // Fetch payload info.\r
32995                     var payloadType = payload && payload.type;\r
32996                     var targetInfo = helper.retrieveTargetInfo(payload, seriesModel);\r
32997                     var rootRect = (payloadType === 'treemapRender' || payloadType === 'treemapMove')\r
32998                         ? payload.rootRect : null;\r
32999                     var viewRoot = seriesModel.getViewRoot();\r
33000 \r
33001                     if (payloadType !== 'treemapMove') {\r
33002                         var rootSize = payloadType === 'treemapZoomToNode'\r
33003                             ? estimateRootSize(\r
33004                                 seriesModel, targetInfo, viewRoot, containerWidth, containerHeight\r
33005                             )\r
33006                             : rootRect\r
33007                             ? [rootRect.width, rootRect.height]\r
33008                             : [containerWidth, containerHeight];\r
33009 \r
33010                         var sort = seriesOption.sort;\r
33011                         if (sort && sort !== 'asc' && sort !== 'desc') {\r
33012                             sort = 'desc';\r
33013                         }\r
33014                         var options = {\r
33015                             squareRatio: seriesOption.squareRatio,\r
33016                             sort: sort,\r
33017                             leafDepth: seriesOption.leafDepth\r
33018                         };\r
33019 \r
33020                         viewRoot.setLayout({\r
33021                             x: 0, y: 0,\r
33022                             width: rootSize[0], height: rootSize[1],\r
33023                             area: rootSize[0] * rootSize[1]\r
33024                         });\r
33025 \r
33026                         squarify(viewRoot, options, false, 0);\r
33027                     }\r
33028 \r
33029                     // Set root position\r
33030                     viewRoot.setLayout(\r
33031                         calculateRootPosition(layoutInfo, rootRect, targetInfo),\r
33032                         true\r
33033                     );\r
33034 \r
33035                     seriesModel.setLayoutInfo(layoutInfo);\r
33036 \r
33037                     // Optimize\r
33038                     // FIXME\r
33039                     // 现在没有clip功能,暂时取ec高宽。\r
33040                     prunning(\r
33041                         seriesModel.getData().tree.root,\r
33042                         // Transform to base element coordinate system.\r
33043                         new BoundingRect(-layoutInfo.x, -layoutInfo.y, ecWidth, ecHeight),\r
33044                         helper.getPathToRoot(viewRoot)\r
33045                     );\r
33046 \r
33047                 });\r
33048             }\r
33049 \r
33050             /**\r
33051              * Layout treemap with squarify algorithm.\r
33052              * @see https://graphics.ethz.ch/teaching/scivis_common/Literature/squarifiedTreeMaps.pdf\r
33053              * @see https://github.com/mbostock/d3/blob/master/src/layout/treemap.js\r
33054              *\r
33055              * @protected\r
33056              * @param {module:echarts/data/Tree~TreeNode} node\r
33057              * @param {Object} options\r
33058              * @param {string} options.sort 'asc' or 'desc'\r
33059              * @param {number} options.squareRatio\r
33060              * @param {boolean} hideChildren\r
33061              * @param {number} depth\r
33062              */\r
33063             function squarify(node, options, hideChildren, depth) {\r
33064                 var width;\r
33065                 var height;\r
33066 \r
33067                 if (node.isRemoved()) {\r
33068                     return;\r
33069                 }\r
33070 \r
33071                 var thisLayout = node.getLayout();\r
33072                 width = thisLayout.width;\r
33073                 height = thisLayout.height;\r
33074 \r
33075                 // Considering border and gap\r
33076                 var itemStyleModel = node.getModel('itemStyle.normal');\r
33077                 var borderWidth = itemStyleModel.get('borderWidth');\r
33078                 var halfGapWidth = itemStyleModel.get('gapWidth') / 2;\r
33079                 var layoutOffset = borderWidth - halfGapWidth;\r
33080                 var nodeModel = node.getModel();\r
33081 \r
33082                 node.setLayout({borderWidth: borderWidth}, true);\r
33083 \r
33084                 width = mathMax(width - 2 * layoutOffset, 0);\r
33085                 height = mathMax(height - 2 * layoutOffset, 0);\r
33086 \r
33087                 var totalArea = width * height;\r
33088                 var viewChildren = initChildren(\r
33089                     node, nodeModel, totalArea, options, hideChildren, depth\r
33090                 );\r
33091 \r
33092                 if (!viewChildren.length) {\r
33093                     return;\r
33094                 }\r
33095 \r
33096                 var rect = {x: layoutOffset, y: layoutOffset, width: width, height: height};\r
33097                 var rowFixedLength = mathMin(width, height);\r
33098                 var best = Infinity; // the best row score so far\r
33099                 var row = [];\r
33100                 row.area = 0;\r
33101 \r
33102                 for (var i = 0, len = viewChildren.length; i < len;) {\r
33103                     var child = viewChildren[i];\r
33104 \r
33105                     row.push(child);\r
33106                     row.area += child.getLayout().area;\r
33107                     var score = worst(row, rowFixedLength, options.squareRatio);\r
33108 \r
33109                     // continue with this orientation\r
33110                     if (score <= best) {\r
33111                         i++;\r
33112                         best = score;\r
33113                     }\r
33114                     // abort, and try a different orientation\r
33115                     else {\r
33116                         row.area -= row.pop().getLayout().area;\r
33117                         position(row, rowFixedLength, rect, halfGapWidth, false);\r
33118                         rowFixedLength = mathMin(rect.width, rect.height);\r
33119                         row.length = row.area = 0;\r
33120                         best = Infinity;\r
33121                     }\r
33122                 }\r
33123 \r
33124                 if (row.length) {\r
33125                     position(row, rowFixedLength, rect, halfGapWidth, true);\r
33126                 }\r
33127 \r
33128                 if (!hideChildren) {\r
33129                     var childrenVisibleMin = nodeModel.get('childrenVisibleMin');\r
33130                     if (childrenVisibleMin != null && totalArea < childrenVisibleMin) {\r
33131                         hideChildren = true;\r
33132                     }\r
33133                 }\r
33134 \r
33135                 for (var i = 0, len = viewChildren.length; i < len; i++) {\r
33136                     squarify(viewChildren[i], options, hideChildren, depth + 1);\r
33137                 }\r
33138             }\r
33139 \r
33140             /**\r
33141              * Set area to each child, and calculate data extent for visual coding.\r
33142              */\r
33143             function initChildren(node, nodeModel, totalArea, options, hideChildren, depth) {\r
33144                 var viewChildren = node.children || [];\r
33145                 var orderBy = options.sort;\r
33146                 orderBy !== 'asc' && orderBy !== 'desc' && (orderBy = null);\r
33147 \r
33148                 var overLeafDepth = options.leafDepth != null && options.leafDepth <= depth;\r
33149 \r
33150                 // leafDepth has higher priority.\r
33151                 if (hideChildren && !overLeafDepth) {\r
33152                     return (node.viewChildren = []);\r
33153                 }\r
33154 \r
33155                 // Sort children, order by desc.\r
33156                 viewChildren = zrUtil.filter(viewChildren, function (child) {\r
33157                     return !child.isRemoved();\r
33158                 });\r
33159 \r
33160                 sort(viewChildren, orderBy);\r
33161 \r
33162                 var info = statistic(nodeModel, viewChildren, orderBy);\r
33163 \r
33164                 if (info.sum === 0) {\r
33165                     return (node.viewChildren = []);\r
33166                 }\r
33167 \r
33168                 info.sum = filterByThreshold(nodeModel, totalArea, info.sum, orderBy, viewChildren);\r
33169 \r
33170                 if (info.sum === 0) {\r
33171                     return (node.viewChildren = []);\r
33172                 }\r
33173 \r
33174                 // Set area to each child.\r
33175                 for (var i = 0, len = viewChildren.length; i < len; i++) {\r
33176                     var area = viewChildren[i].getValue() / info.sum * totalArea;\r
33177                     // Do not use setLayout({...}, true), because it is needed to clear last layout.\r
33178                     viewChildren[i].setLayout({area: area});\r
33179                 }\r
33180 \r
33181                 if (overLeafDepth) {\r
33182                     viewChildren.length && node.setLayout({isLeafRoot: true}, true);\r
33183                     viewChildren.length = 0;\r
33184                 }\r
33185 \r
33186                 node.viewChildren = viewChildren;\r
33187                 node.setLayout({dataExtent: info.dataExtent}, true);\r
33188 \r
33189                 return viewChildren;\r
33190             }\r
33191 \r
33192             /**\r
33193              * Consider 'visibleMin'. Modify viewChildren and get new sum.\r
33194              */\r
33195             function filterByThreshold(nodeModel, totalArea, sum, orderBy, orderedChildren) {\r
33196 \r
33197                 // visibleMin is not supported yet when no option.sort.\r
33198                 if (!orderBy) {\r
33199                     return sum;\r
33200                 }\r
33201 \r
33202                 var visibleMin = nodeModel.get('visibleMin');\r
33203                 var len = orderedChildren.length;\r
33204                 var deletePoint = len;\r
33205 \r
33206                 // Always travel from little value to big value.\r
33207                 for (var i = len - 1; i >= 0; i--) {\r
33208                     var value = orderedChildren[\r
33209                         orderBy === 'asc' ? len - i - 1 : i\r
33210                     ].getValue();\r
33211 \r
33212                     if (value / sum * totalArea < visibleMin) {\r
33213                         deletePoint = i;\r
33214                         sum -= value;\r
33215                     }\r
33216                 }\r
33217 \r
33218                 orderBy === 'asc'\r
33219                     ? orderedChildren.splice(0, len - deletePoint)\r
33220                     : orderedChildren.splice(deletePoint, len - deletePoint);\r
33221 \r
33222                 return sum;\r
33223             }\r
33224 \r
33225             /**\r
33226              * Sort\r
33227              */\r
33228             function sort(viewChildren, orderBy) {\r
33229                 if (orderBy) {\r
33230                     viewChildren.sort(function (a, b) {\r
33231                         return orderBy === 'asc'\r
33232                             ?  a.getValue() - b.getValue() : b.getValue() - a.getValue();\r
33233                     });\r
33234                 }\r
33235                 return viewChildren;\r
33236             }\r
33237 \r
33238             /**\r
33239              * Statistic\r
33240              */\r
33241             function statistic(nodeModel, children, orderBy) {\r
33242                 // Calculate sum.\r
33243                 var sum = 0;\r
33244                 for (var i = 0, len = children.length; i < len; i++) {\r
33245                     sum += children[i].getValue();\r
33246                 }\r
33247 \r
33248                 // Statistic data extent for latter visual coding.\r
33249                 // Notice: data extent should be calculate based on raw children\r
33250                 // but not filtered view children, otherwise visual mapping will not\r
33251                 // be stable when zoom (where children is filtered by visibleMin).\r
33252 \r
33253                 var dimension = nodeModel.get('visualDimension');\r
33254                 var dataExtent;\r
33255 \r
33256                 // The same as area dimension.\r
33257                 if (!children || !children.length) {\r
33258                     dataExtent = [NaN, NaN];\r
33259                 }\r
33260                 else if (dimension === 'value' && orderBy) {\r
33261                     dataExtent = [\r
33262                         children[children.length - 1].getValue(),\r
33263                         children[0].getValue()\r
33264                     ];\r
33265                     orderBy === 'asc' && dataExtent.reverse();\r
33266                 }\r
33267                 // Other dimension.\r
33268                 else {\r
33269                     var dataExtent = [Infinity, -Infinity];\r
33270                     zrUtil.each(children, function (child) {\r
33271                         var value = child.getValue(dimension);\r
33272                         value < dataExtent[0] && (dataExtent[0] = value);\r
33273                         value > dataExtent[1] && (dataExtent[1] = value);\r
33274                     });\r
33275                 }\r
33276 \r
33277                 return {sum: sum, dataExtent: dataExtent};\r
33278             }\r
33279 \r
33280             /**\r
33281              * Computes the score for the specified row,\r
33282              * as the worst aspect ratio.\r
33283              */\r
33284             function worst(row, rowFixedLength, ratio) {\r
33285                 var areaMax = 0;\r
33286                 var areaMin = Infinity;\r
33287 \r
33288                 for (var i = 0, area, len = row.length; i < len; i++) {\r
33289                     area = row[i].getLayout().area;\r
33290                     if (area) {\r
33291                         area < areaMin && (areaMin = area);\r
33292                         area > areaMax && (areaMax = area);\r
33293                     }\r
33294                 }\r
33295 \r
33296                 var squareArea = row.area * row.area;\r
33297                 var f = rowFixedLength * rowFixedLength * ratio;\r
33298 \r
33299                 return squareArea\r
33300                     ? mathMax(\r
33301                         (f * areaMax) / squareArea,\r
33302                         squareArea / (f * areaMin)\r
33303                     )\r
33304                     : Infinity;\r
33305             }\r
33306 \r
33307             /**\r
33308              * Positions the specified row of nodes. Modifies `rect`.\r
33309              */\r
33310             function position(row, rowFixedLength, rect, halfGapWidth, flush) {\r
33311                 // When rowFixedLength === rect.width,\r
33312                 // it is horizontal subdivision,\r
33313                 // rowFixedLength is the width of the subdivision,\r
33314                 // rowOtherLength is the height of the subdivision,\r
33315                 // and nodes will be positioned from left to right.\r
33316 \r
33317                 // wh[idx0WhenH] means: when horizontal,\r
33318                 //      wh[idx0WhenH] => wh[0] => 'width'.\r
33319                 //      xy[idx1WhenH] => xy[1] => 'y'.\r
33320                 var idx0WhenH = rowFixedLength === rect.width ? 0 : 1;\r
33321                 var idx1WhenH = 1 - idx0WhenH;\r
33322                 var xy = ['x', 'y'];\r
33323                 var wh = ['width', 'height'];\r
33324 \r
33325                 var last = rect[xy[idx0WhenH]];\r
33326                 var rowOtherLength = rowFixedLength\r
33327                     ? row.area / rowFixedLength : 0;\r
33328 \r
33329                 if (flush || rowOtherLength > rect[wh[idx1WhenH]]) {\r
33330                     rowOtherLength = rect[wh[idx1WhenH]]; // over+underflow\r
33331                 }\r
33332                 for (var i = 0, rowLen = row.length; i < rowLen; i++) {\r
33333                     var node = row[i];\r
33334                     var nodeLayout = {};\r
33335                     var step = rowOtherLength\r
33336                         ? node.getLayout().area / rowOtherLength : 0;\r
33337 \r
33338                     var wh1 = nodeLayout[wh[idx1WhenH]] = mathMax(rowOtherLength - 2 * halfGapWidth, 0);\r
33339 \r
33340                     // We use Math.max/min to avoid negative width/height when considering gap width.\r
33341                     var remain = rect[xy[idx0WhenH]] + rect[wh[idx0WhenH]] - last;\r
33342                     var modWH = (i === rowLen - 1 || remain < step) ? remain : step;\r
33343                     var wh0 = nodeLayout[wh[idx0WhenH]] = mathMax(modWH - 2 * halfGapWidth, 0);\r
33344 \r
33345                     nodeLayout[xy[idx1WhenH]] = rect[xy[idx1WhenH]] + mathMin(halfGapWidth, wh1 / 2);\r
33346                     nodeLayout[xy[idx0WhenH]] = last + mathMin(halfGapWidth, wh0 / 2);\r
33347 \r
33348                     last += modWH;\r
33349                     node.setLayout(nodeLayout, true);\r
33350                 }\r
33351 \r
33352                 rect[xy[idx1WhenH]] += rowOtherLength;\r
33353                 rect[wh[idx1WhenH]] -= rowOtherLength;\r
33354             }\r
33355 \r
33356             // Return [containerWidth, containerHeight] as defualt.\r
33357             function estimateRootSize(seriesModel, targetInfo, viewRoot, containerWidth, containerHeight) {\r
33358                 // If targetInfo.node exists, we zoom to the node,\r
33359                 // so estimate whold width and heigth by target node.\r
33360                 var currNode = (targetInfo || {}).node;\r
33361                 var defaultSize = [containerWidth, containerHeight];\r
33362 \r
33363                 if (!currNode || currNode === viewRoot) {\r
33364                     return defaultSize;\r
33365                 }\r
33366 \r
33367                 var parent;\r
33368                 var viewArea = containerWidth * containerHeight;\r
33369                 var area = viewArea * seriesModel.option.zoomToNodeRatio;\r
33370 \r
33371                 while (parent = currNode.parentNode) { // jshint ignore:line\r
33372                     var sum = 0;\r
33373                     var siblings = parent.children;\r
33374 \r
33375                     for (var i = 0, len = siblings.length; i < len; i++) {\r
33376                         sum += siblings[i].getValue();\r
33377                     }\r
33378                     var currNodeValue = currNode.getValue();\r
33379                     if (currNodeValue === 0) {\r
33380                         return defaultSize;\r
33381                     }\r
33382                     area *= sum / currNodeValue;\r
33383 \r
33384                     var borderWidth = parent.getModel('itemStyle.normal').get('borderWidth');\r
33385 \r
33386                     if (isFinite(borderWidth)) {\r
33387                         // Considering border, suppose aspect ratio is 1.\r
33388                         area += 4 * borderWidth * borderWidth + 4 * borderWidth * Math.pow(area, 0.5);\r
33389                     }\r
33390 \r
33391                     area > numberUtil.MAX_SAFE_INTEGER && (area = numberUtil.MAX_SAFE_INTEGER);\r
33392 \r
33393                     currNode = parent;\r
33394                 }\r
33395 \r
33396                 area < viewArea && (area = viewArea);\r
33397                 var scale = Math.pow(area / viewArea, 0.5);\r
33398 \r
33399                 return [containerWidth * scale, containerHeight * scale];\r
33400             }\r
33401 \r
33402             // Root postion base on coord of containerGroup\r
33403             function calculateRootPosition(layoutInfo, rootRect, targetInfo) {\r
33404                 if (rootRect) {\r
33405                     return {x: rootRect.x, y: rootRect.y};\r
33406                 }\r
33407 \r
33408                 var defaultPosition = {x: 0, y: 0};\r
33409                 if (!targetInfo) {\r
33410                     return defaultPosition;\r
33411                 }\r
33412 \r
33413                 // If targetInfo is fetched by 'retrieveTargetInfo',\r
33414                 // old tree and new tree are the same tree,\r
33415                 // so the node still exists and we can visit it.\r
33416 \r
33417                 var targetNode = targetInfo.node;\r
33418                 var layout = targetNode.getLayout();\r
33419 \r
33420                 if (!layout) {\r
33421                     return defaultPosition;\r
33422                 }\r
33423 \r
33424                 // Transform coord from local to container.\r
33425                 var targetCenter = [layout.width / 2, layout.height / 2];\r
33426                 var node = targetNode;\r
33427                 while (node) {\r
33428                     var nodeLayout = node.getLayout();\r
33429                     targetCenter[0] += nodeLayout.x;\r
33430                     targetCenter[1] += nodeLayout.y;\r
33431                     node = node.parentNode;\r
33432                 }\r
33433 \r
33434                 return {\r
33435                     x: layoutInfo.width / 2 - targetCenter[0],\r
33436                     y: layoutInfo.height / 2 - targetCenter[1]\r
33437                 };\r
33438             }\r
33439 \r
33440             // Mark invisible nodes for prunning when visual coding and rendering.\r
33441             // Prunning depends on layout and root position, so we have to do it after them.\r
33442             function prunning(node, clipRect, viewPath) {\r
33443                 var nodeLayout = node.getLayout();\r
33444 \r
33445                 node.setLayout({\r
33446                     invisible: nodeLayout\r
33447                         ? !clipRect.intersect(nodeLayout)\r
33448                         : !helper.aboveViewRootByViewPath(viewPath, node)\r
33449                 }, true);\r
33450 \r
33451                 var viewChildren = node.viewChildren || [];\r
33452                 for (var i = 0, len = viewChildren.length; i < len; i++) {\r
33453                     // Transform to child coordinate.\r
33454                     var childClipRect = new BoundingRect(\r
33455                         clipRect.x - nodeLayout.x,\r
33456                         clipRect.y - nodeLayout.y,\r
33457                         clipRect.width,\r
33458                         clipRect.height\r
33459                     );\r
33460                     prunning(viewChildren[i], childClipRect, viewPath);\r
33461                 }\r
33462             }\r
33463 \r
33464             module.exports = update;\r
33465 \r
33466 \r
33467 /***/ },\r
33468 /* 189 */\r
33469 /***/ function(module, exports, __webpack_require__) {\r
33470 \r
33471         \r
33472 \r
33473             var echarts = __webpack_require__(1);\r
33474             var zrUtil = __webpack_require__(3);\r
33475 \r
33476             __webpack_require__(190);\r
33477             __webpack_require__(193);\r
33478 \r
33479             __webpack_require__(197);\r
33480 \r
33481             echarts.registerProcessor('filter', __webpack_require__(198));\r
33482 \r
33483             echarts.registerVisualCoding('chart', zrUtil.curry(\r
33484                 __webpack_require__(103), 'graph', 'circle', null\r
33485             ));\r
33486             echarts.registerVisualCoding('chart', __webpack_require__(199));\r
33487 \r
33488             echarts.registerLayout(__webpack_require__(200));\r
33489             echarts.registerLayout(__webpack_require__(202));\r
33490             echarts.registerLayout(__webpack_require__(204));\r
33491 \r
33492             // Graph view coordinate system\r
33493             echarts.registerCoordinateSystem('graphView', {\r
33494                 create: __webpack_require__(206)\r
33495             });\r
33496 \r
33497 \r
33498 /***/ },\r
33499 /* 190 */\r
33500 /***/ function(module, exports, __webpack_require__) {\r
33501 \r
33502         'use strict';\r
33503 \r
33504 \r
33505             var List = __webpack_require__(94);\r
33506             var zrUtil = __webpack_require__(3);\r
33507 \r
33508             var createGraphFromNodeEdge = __webpack_require__(191);\r
33509 \r
33510             var GraphSeries = __webpack_require__(1).extendSeriesModel({\r
33511 \r
33512                 type: 'series.graph',\r
33513 \r
33514                 init: function (option) {\r
33515                     GraphSeries.superApply(this, 'init', arguments);\r
33516 \r
33517                     // Provide data for legend select\r
33518                     this.legendDataProvider = function () {\r
33519                         return this._categoriesData;\r
33520                     };\r
33521 \r
33522                     this._updateCategoriesData();\r
33523                 },\r
33524 \r
33525                 mergeOption: function (option) {\r
33526                     GraphSeries.superApply(this, 'mergeOption', arguments);\r
33527 \r
33528                     this._updateCategoriesData();\r
33529                 },\r
33530 \r
33531                 getInitialData: function (option, ecModel) {\r
33532                     var edges = option.edges || option.links;\r
33533                     var nodes = option.data || option.nodes;\r
33534                     if (nodes && edges) {\r
33535                         var graph = createGraphFromNodeEdge(nodes, edges, this, true);\r
33536                         var list = graph.data;\r
33537                         var self = this;\r
33538                         // Overwrite list.getItemModel to\r
33539                         list.wrapMethod('getItemModel', function (model) {\r
33540                             var categoriesModels = self._categoriesModels;\r
33541                             var categoryIdx = model.getShallow('category');\r
33542                             var categoryModel = categoriesModels[categoryIdx];\r
33543                             if (categoryModel) {\r
33544                                 categoryModel.parentModel = model.parentModel;\r
33545                                 model.parentModel = categoryModel;\r
33546                             }\r
33547                             return model;\r
33548                         });\r
33549                         return list;\r
33550                     }\r
33551                 },\r
33552 \r
33553                 restoreData: function () {\r
33554                     GraphSeries.superApply(this, 'restoreData', arguments);\r
33555                     this.getGraph().restoreData();\r
33556                 },\r
33557 \r
33558                 /**\r
33559                  * @return {module:echarts/data/Graph}\r
33560                  */\r
33561                 getGraph: function () {\r
33562                     return this.getData().graph;\r
33563                 },\r
33564 \r
33565                 /**\r
33566                  * @return {module:echarts/data/List}\r
33567                  */\r
33568                 getEdgeData: function () {\r
33569                     return this.getGraph().edgeData;\r
33570                 },\r
33571 \r
33572                 /**\r
33573                  * @return {module:echarts/data/List}\r
33574                  */\r
33575                 getCategoriesData: function () {\r
33576                     return this._categoriesData;\r
33577                 },\r
33578 \r
33579                 _updateCategoriesData: function () {\r
33580                     var categories = zrUtil.map(this.option.categories || [], function (category) {\r
33581                         // Data must has value\r
33582                         return category.value != null ? category : zrUtil.extend({\r
33583                             value: 0\r
33584                         }, category);\r
33585                     });\r
33586                     var categoriesData = new List(['value'], this);\r
33587                     categoriesData.initData(categories);\r
33588 \r
33589                     this._categoriesData = categoriesData;\r
33590 \r
33591                     this._categoriesModels = categoriesData.mapArray(function (idx) {\r
33592                         return categoriesData.getItemModel(idx, true);\r
33593                     });\r
33594                 },\r
33595 \r
33596                 /**\r
33597                  * @param {number} zoom\r
33598                  */\r
33599                 setRoamZoom: function (zoom) {\r
33600                     var roamDetail = this.option.roamDetail;\r
33601                     roamDetail && (roamDetail.zoom = zoom);\r
33602                 },\r
33603 \r
33604                 /**\r
33605                  * @param {number} x\r
33606                  * @param {number} y\r
33607                  */\r
33608                 setRoamPan: function (x, y) {\r
33609                     var roamDetail = this.option.roamDetail;\r
33610                     if (roamDetail) {\r
33611                         roamDetail.x = x;\r
33612                         roamDetail.y = y;\r
33613                     }\r
33614                 },\r
33615 \r
33616                 defaultOption: {\r
33617                     zlevel: 0,\r
33618                     z: 2,\r
33619 \r
33620                     color: ['#61a0a8', '#d14a61', '#fd9c35', '#675bba', '#fec42c',\r
33621                             '#dd4444', '#fd9c35', '#cd4870'],\r
33622 \r
33623                     coordinateSystem: 'view',\r
33624 \r
33625                     legendHoverLink: true,\r
33626 \r
33627                     hoverAnimation: true,\r
33628 \r
33629                     layout: null,\r
33630 \r
33631                     // Configuration of force\r
33632                     force: {\r
33633                         initLayout: null,\r
33634                         repulsion: 50,\r
33635                         gravity: 0.1,\r
33636                         edgeLength: 30,\r
33637 \r
33638                         layoutAnimation: true\r
33639                     },\r
33640 \r
33641                     left: 'center',\r
33642                     top: 'center',\r
33643                     // right: null,\r
33644                     // bottom: null,\r
33645                     // width: '80%',\r
33646                     // height: '80%',\r
33647 \r
33648                     symbol: 'circle',\r
33649                     symbolSize: 10,\r
33650 \r
33651                     draggable: false,\r
33652 \r
33653                     roam: false,\r
33654                     roamDetail: {\r
33655                         x: 0,\r
33656                         y: 0,\r
33657                         zoom: 1\r
33658                     },\r
33659 \r
33660                     // Symbol size scale ratio in roam\r
33661                     nodeScaleRatio: 0.6,\r
33662 \r
33663                     // Line width scale ratio in roam\r
33664                     // edgeScaleRatio: 0.1,\r
33665 \r
33666                     // categories: [],\r
33667 \r
33668                     // data: []\r
33669                     // Or\r
33670                     // nodes: []\r
33671                     //\r
33672                     // links: []\r
33673                     // Or\r
33674                     // edges: []\r
33675 \r
33676                     label: {\r
33677                         normal: {\r
33678                             show: false\r
33679                         },\r
33680                         emphasis: {\r
33681                             show: true\r
33682                         }\r
33683                     },\r
33684 \r
33685                     itemStyle: {\r
33686                         normal: {},\r
33687                         emphasis: {}\r
33688                     },\r
33689 \r
33690                     lineStyle: {\r
33691                         normal: {\r
33692                             color: '#aaa',\r
33693                             width: 1,\r
33694                             curveness: 0,\r
33695                             opacity: 0.5\r
33696                         },\r
33697                         emphasis: {}\r
33698                     }\r
33699                 }\r
33700             });\r
33701 \r
33702             module.exports = GraphSeries;\r
33703 \r
33704 \r
33705 /***/ },\r
33706 /* 191 */\r
33707 /***/ function(module, exports, __webpack_require__) {\r
33708 \r
33709         \r
33710 \r
33711             var List = __webpack_require__(94);\r
33712             var Graph = __webpack_require__(192);\r
33713             var linkList = __webpack_require__(180);\r
33714             var completeDimensions = __webpack_require__(96);\r
33715             var zrUtil = __webpack_require__(3);\r
33716 \r
33717             module.exports = function (nodes, edges, hostModel, directed) {\r
33718                 var graph = new Graph(directed);\r
33719                 for (var i = 0; i < nodes.length; i++) {\r
33720                     graph.addNode(zrUtil.retrieve(\r
33721                         // Id, name, dataIndex\r
33722                         nodes[i].id, nodes[i].name, i\r
33723                     ), i);\r
33724                 }\r
33725 \r
33726                 var linkNameList = [];\r
33727                 var validEdges = [];\r
33728                 for (var i = 0; i < edges.length; i++) {\r
33729                     var link = edges[i];\r
33730                     // addEdge may fail when source or target not exists\r
33731                     if (graph.addEdge(link.source, link.target, i)) {\r
33732                         validEdges.push(link);\r
33733                         linkNameList.push(zrUtil.retrieve(link.id, link.source + ' - ' + link.target));\r
33734                     }\r
33735                 }\r
33736 \r
33737                 // FIXME\r
33738                 var dimensionNames = completeDimensions(['value'], nodes);\r
33739 \r
33740                 var nodeData = new List(dimensionNames, hostModel);\r
33741                 var edgeData = new List(['value'], hostModel);\r
33742 \r
33743                 nodeData.initData(nodes);\r
33744                 edgeData.initData(validEdges, linkNameList);\r
33745 \r
33746                 graph.setEdgeData(edgeData);\r
33747 \r
33748                 linkList.linkToGraph(nodeData, graph);\r
33749                 // Update dataIndex of nodes and edges because invalid edge may be removed\r
33750                 graph.update();\r
33751 \r
33752                 return graph;\r
33753             };\r
33754 \r
33755 \r
33756 /***/ },\r
33757 /* 192 */\r
33758 /***/ function(module, exports, __webpack_require__) {\r
33759 \r
33760         'use strict';\r
33761         /**\r
33762          * Graph data structure\r
33763          *\r
33764          * @module echarts/data/Graph\r
33765          * @author Yi Shen(https://www.github.com/pissang)\r
33766          */\r
33767 \r
33768 \r
33769             var zrUtil = __webpack_require__(3);\r
33770 \r
33771             /**\r
33772              * @alias module:echarts/data/Graph\r
33773              * @constructor\r
33774              * @param {boolean} directed\r
33775              */\r
33776             var Graph = function(directed) {\r
33777                 /**\r
33778                  * 是否是有向图\r
33779                  * @type {boolean}\r
33780                  * @private\r
33781                  */\r
33782                 this._directed = directed || false;\r
33783 \r
33784                 /**\r
33785                  * @type {Array.<module:echarts/data/Graph.Node>}\r
33786                  * @readOnly\r
33787                  */\r
33788                 this.nodes = [];\r
33789 \r
33790                 /**\r
33791                  * @type {Array.<module:echarts/data/Graph.Edge>}\r
33792                  * @readOnly\r
33793                  */\r
33794                 this.edges = [];\r
33795 \r
33796                 /**\r
33797                  * @type {Object.<string, module:echarts/data/Graph.Node>}\r
33798                  * @private\r
33799                  */\r
33800                 this._nodesMap = {};\r
33801                 /**\r
33802                  * @type {Object.<string, module:echarts/data/Graph.Edge>}\r
33803                  * @private\r
33804                  */\r
33805                 this._edgesMap = {};\r
33806 \r
33807                 /**\r
33808                  * @type {module:echarts/data/List}\r
33809                  * @readOnly\r
33810                  */\r
33811                 this.data;\r
33812 \r
33813                 /**\r
33814                  * @type {module:echarts/data/List}\r
33815                  * @readOnly\r
33816                  */\r
33817                 this.edgeData;\r
33818             };\r
33819 \r
33820             var graphProto = Graph.prototype;\r
33821             /**\r
33822              * @type {string}\r
33823              */\r
33824             graphProto.type = 'graph';\r
33825 \r
33826             /**\r
33827              * If is directed graph\r
33828              * @return {boolean}\r
33829              */\r
33830             graphProto.isDirected = function () {\r
33831                 return this._directed;\r
33832             };\r
33833 \r
33834             /**\r
33835              * Add a new node\r
33836              * @param {string} id\r
33837              * @param {number} [dataIndex]\r
33838              */\r
33839             graphProto.addNode = function (id, dataIndex) {\r
33840                 var nodesMap = this._nodesMap;\r
33841 \r
33842                 if (nodesMap[id]) {\r
33843                     return;\r
33844                 }\r
33845 \r
33846                 var node = new Node(id, dataIndex);\r
33847                 node.hostGraph = this;\r
33848 \r
33849                 this.nodes.push(node);\r
33850 \r
33851                 nodesMap[id] = node;\r
33852                 return node;\r
33853             };\r
33854 \r
33855             /**\r
33856              * Get node by data index\r
33857              * @param  {number} dataIndex\r
33858              * @return {module:echarts/data/Graph~Node}\r
33859              */\r
33860             graphProto.getNodeByIndex = function (dataIndex) {\r
33861                 var rawIdx = this.data.getRawIndex(dataIndex);\r
33862                 return this.nodes[rawIdx];\r
33863             };\r
33864             /**\r
33865              * Get node by id\r
33866              * @param  {string} id\r
33867              * @return {module:echarts/data/Graph.Node}\r
33868              */\r
33869             graphProto.getNodeById = function (id) {\r
33870                 return this._nodesMap[id];\r
33871             };\r
33872 \r
33873             /**\r
33874              * Add a new edge\r
33875              * @param {string|module:echarts/data/Graph.Node} n1\r
33876              * @param {string|module:echarts/data/Graph.Node} n2\r
33877              * @param {number} [dataIndex=-1]\r
33878              * @return {module:echarts/data/Graph.Edge}\r
33879              */\r
33880             graphProto.addEdge = function (n1, n2, dataIndex) {\r
33881                 var nodesMap = this._nodesMap;\r
33882                 var edgesMap = this._edgesMap;\r
33883 \r
33884                 if (!(n1 instanceof Node)) {\r
33885                     n1 = nodesMap[n1];\r
33886                 }\r
33887                 if (!(n2 instanceof Node)) {\r
33888                     n2 = nodesMap[n2];\r
33889                 }\r
33890                 if (!n1 || !n2) {\r
33891                     return;\r
33892                 }\r
33893 \r
33894                 var key = n1.id + '-' + n2.id;\r
33895                 // PENDING\r
33896                 if (edgesMap[key]) {\r
33897                     return;\r
33898                 }\r
33899 \r
33900                 var edge = new Edge(n1, n2, dataIndex);\r
33901                 edge.hostGraph = this;\r
33902 \r
33903                 if (this._directed) {\r
33904                     n1.outEdges.push(edge);\r
33905                     n2.inEdges.push(edge);\r
33906                 }\r
33907                 n1.edges.push(edge);\r
33908                 if (n1 !== n2) {\r
33909                     n2.edges.push(edge);\r
33910                 }\r
33911 \r
33912                 this.edges.push(edge);\r
33913                 edgesMap[key] = edge;\r
33914 \r
33915                 return edge;\r
33916             };\r
33917 \r
33918             /**\r
33919              * Get edge by data index\r
33920              * @param  {number} dataIndex\r
33921              * @return {module:echarts/data/Graph~Node}\r
33922              */\r
33923             graphProto.getEdgeByIndex = function (dataIndex) {\r
33924                 var rawIdx = this.edgeData.getRawIndex(dataIndex);\r
33925                 return this.edges[rawIdx];\r
33926             };\r
33927             /**\r
33928              * Get edge by two linked nodes\r
33929              * @param  {module:echarts/data/Graph.Node|string} n1\r
33930              * @param  {module:echarts/data/Graph.Node|string} n2\r
33931              * @return {module:echarts/data/Graph.Edge}\r
33932              */\r
33933             graphProto.getEdge = function (n1, n2) {\r
33934                 if (n1 instanceof Node) {\r
33935                     n1 = n1.id;\r
33936                 }\r
33937                 if (n2 instanceof Node) {\r
33938                     n2 = n2.id;\r
33939                 }\r
33940 \r
33941                 var edgesMap = this._edgesMap;\r
33942 \r
33943                 if (this._directed) {\r
33944                     return edgesMap[n1 + '-' + n2];\r
33945                 } else {\r
33946                     return edgesMap[n1 + '-' + n2]\r
33947                         || edgesMap[n2 + '-' + n1];\r
33948                 }\r
33949             };\r
33950 \r
33951             /**\r
33952              * Iterate all nodes\r
33953              * @param  {Function} cb\r
33954              * @param  {*} [context]\r
33955              */\r
33956             graphProto.eachNode = function (cb, context) {\r
33957                 var nodes = this.nodes;\r
33958                 var len = nodes.length;\r
33959                 for (var i = 0; i < len; i++) {\r
33960                     if (nodes[i].dataIndex >= 0) {\r
33961                         cb.call(context, nodes[i], i);\r
33962                     }\r
33963                 }\r
33964             };\r
33965 \r
33966             /**\r
33967              * Iterate all edges\r
33968              * @param  {Function} cb\r
33969              * @param  {*} [context]\r
33970              */\r
33971             graphProto.eachEdge = function (cb, context) {\r
33972                 var edges = this.edges;\r
33973                 var len = edges.length;\r
33974                 for (var i = 0; i < len; i++) {\r
33975                     if (edges[i].dataIndex >= 0\r
33976                         && edges[i].node1.dataIndex >= 0\r
33977                         && edges[i].node2.dataIndex >= 0\r
33978                     ) {\r
33979                         cb.call(context, edges[i], i);\r
33980                     }\r
33981                 }\r
33982             };\r
33983 \r
33984             /**\r
33985              * Breadth first traverse\r
33986              * @param {Function} cb\r
33987              * @param {module:echarts/data/Graph.Node} startNode\r
33988              * @param {string} [direction='none'] 'none'|'in'|'out'\r
33989              * @param {*} [context]\r
33990              */\r
33991             graphProto.breadthFirstTraverse = function (\r
33992                 cb, startNode, direction, context\r
33993             ) {\r
33994                 if (!(startNode instanceof Node)) {\r
33995                     startNode = this._nodesMap[startNode];\r
33996                 }\r
33997                 if (!startNode) {\r
33998                     return;\r
33999                 }\r
34000 \r
34001                 var edgeType = direction === 'out'\r
34002                     ? 'outEdges' : (direction === 'in' ? 'inEdges' : 'edges');\r
34003 \r
34004                 for (var i = 0; i < this.nodes.length; i++) {\r
34005                     this.nodes[i].__visited = false;\r
34006                 }\r
34007 \r
34008                 if (cb.call(context, startNode, null)) {\r
34009                     return;\r
34010                 }\r
34011 \r
34012                 var queue = [startNode];\r
34013                 while (queue.length) {\r
34014                     var currentNode = queue.shift();\r
34015                     var edges = currentNode[edgeType];\r
34016 \r
34017                     for (var i = 0; i < edges.length; i++) {\r
34018                         var e = edges[i];\r
34019                         var otherNode = e.node1 === currentNode\r
34020                             ? e.node2 : e.node1;\r
34021                         if (!otherNode.__visited) {\r
34022                             if (cb.call(otherNode, otherNode, currentNode)) {\r
34023                                 // Stop traversing\r
34024                                 return;\r
34025                             }\r
34026                             queue.push(otherNode);\r
34027                             otherNode.__visited = true;\r
34028                         }\r
34029                     }\r
34030                 }\r
34031             };\r
34032 \r
34033             // TODO\r
34034             // graphProto.depthFirstTraverse = function (\r
34035             //     cb, startNode, direction, context\r
34036             // ) {\r
34037 \r
34038             // };\r
34039 \r
34040             // Filter update\r
34041             graphProto.update = function () {\r
34042                 var data = this.data;\r
34043                 var edgeData = this.edgeData;\r
34044                 var nodes = this.nodes;\r
34045                 var edges = this.edges;\r
34046 \r
34047                 for (var i = 0, len = nodes.length; i < len; i++) {\r
34048                     nodes[i].dataIndex = -1;\r
34049                 }\r
34050                 for (var i = 0, len = data.count(); i < len; i++) {\r
34051                     nodes[data.getRawIndex(i)].dataIndex = i;\r
34052                 }\r
34053 \r
34054                 edgeData.filterSelf(function (idx) {\r
34055                     var edge = edges[edgeData.getRawIndex(idx)];\r
34056                     return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0;\r
34057                 });\r
34058 \r
34059                 // Update edge\r
34060                 for (var i = 0, len = edges.length; i < len; i++) {\r
34061                     edges[i].dataIndex = -1;\r
34062                 }\r
34063                 for (var i = 0, len = edgeData.count(); i < len; i++) {\r
34064                     edges[edgeData.getRawIndex(i)].dataIndex = i;\r
34065                 }\r
34066             };\r
34067 \r
34068             /**\r
34069              * Set edge data\r
34070              * @param {module:echarts/data/List} edgeData\r
34071              */\r
34072             graphProto.setEdgeData = function (edgeData) {\r
34073                 this.edgeData = edgeData;\r
34074                 this._edgeDataSaved = edgeData.cloneShallow();\r
34075             };\r
34076 \r
34077             graphProto.restoreData = function () {\r
34078                 this.edgeData = this._edgeDataSaved.cloneShallow();\r
34079             };\r
34080 \r
34081             /**\r
34082              * @return {module:echarts/data/Graph}\r
34083              */\r
34084             graphProto.clone = function () {\r
34085                 var graph = new Graph(this._directed);\r
34086                 var nodes = this.nodes;\r
34087                 var edges = this.edges;\r
34088                 for (var i = 0; i < nodes.length; i++) {\r
34089                     graph.addNode(nodes[i].id, nodes[i].dataIndex);\r
34090                 }\r
34091                 for (var i = 0; i < edges.length; i++) {\r
34092                     var e = edges[i];\r
34093                     graph.addEdge(e.node1.id, e.node2.id, e.dataIndex);\r
34094                 }\r
34095                 return graph;\r
34096             };\r
34097 \r
34098 \r
34099             /**\r
34100              * @alias module:echarts/data/Graph.Node\r
34101              */\r
34102             function Node(id, dataIndex) {\r
34103                 /**\r
34104                 * @type {string}\r
34105                 */\r
34106                 this.id = id == null ? '' : id;\r
34107 \r
34108                 /**\r
34109                 * @type {Array.<module:echarts/data/Graph.Edge>}\r
34110                 */\r
34111                 this.inEdges = [];\r
34112                 /**\r
34113                 * @type {Array.<module:echarts/data/Graph.Edge>}\r
34114                 */\r
34115                 this.outEdges = [];\r
34116                 /**\r
34117                 * @type {Array.<module:echarts/data/Graph.Edge>}\r
34118                 */\r
34119                 this.edges = [];\r
34120                 /**\r
34121                  * @type {module:echarts/data/Graph}\r
34122                  */\r
34123                 this.hostGraph;\r
34124 \r
34125                 /**\r
34126                  * @type {number}\r
34127                  */\r
34128                 this.dataIndex = dataIndex == null ? -1 : dataIndex;\r
34129             }\r
34130 \r
34131             Node.prototype = {\r
34132 \r
34133                 constructor: Node,\r
34134 \r
34135                 /**\r
34136                  * @return {number}\r
34137                  */\r
34138                 degree: function () {\r
34139                     return this.edges.length;\r
34140                 },\r
34141 \r
34142                 /**\r
34143                  * @return {number}\r
34144                  */\r
34145                 inDegree: function () {\r
34146                     return this.inEdges.length;\r
34147                 },\r
34148 \r
34149                 /**\r
34150                 * @return {number}\r
34151                 */\r
34152                 outDegree: function () {\r
34153                     return this.outEdges.length;\r
34154                 },\r
34155 \r
34156                 /**\r
34157                  * @param {string} [path]\r
34158                  * @return {module:echarts/model/Model}\r
34159                  */\r
34160                 getModel: function (path) {\r
34161                     if (this.dataIndex < 0) {\r
34162                         return;\r
34163                     }\r
34164                     var graph = this.hostGraph;\r
34165                     var itemModel = graph.data.getItemModel(this.dataIndex);\r
34166 \r
34167                     return itemModel.getModel(path);\r
34168                 }\r
34169             };\r
34170 \r
34171             /**\r
34172              * 图边\r
34173              * @alias module:echarts/data/Graph.Edge\r
34174              * @param {module:echarts/data/Graph.Node} n1\r
34175              * @param {module:echarts/data/Graph.Node} n2\r
34176              * @param {number} [dataIndex=-1]\r
34177              */\r
34178             function Edge(n1, n2, dataIndex) {\r
34179 \r
34180                 /**\r
34181                  * 节点1,如果是有向图则为源节点\r
34182                  * @type {module:echarts/data/Graph.Node}\r
34183                  */\r
34184                 this.node1 = n1;\r
34185 \r
34186                 /**\r
34187                  * 节点2,如果是有向图则为目标节点\r
34188                  * @type {module:echarts/data/Graph.Node}\r
34189                  */\r
34190                 this.node2 = n2;\r
34191 \r
34192                 this.dataIndex = dataIndex == null ? -1 : dataIndex;\r
34193             }\r
34194 \r
34195             /**\r
34196              * @param {string} [path]\r
34197              * @return {module:echarts/model/Model}\r
34198              */\r
34199              Edge.prototype.getModel = function (path) {\r
34200                 if (this.dataIndex < 0) {\r
34201                     return;\r
34202                 }\r
34203                 var graph = this.hostGraph;\r
34204                 var itemModel = graph.edgeData.getItemModel(this.dataIndex);\r
34205 \r
34206                 return itemModel.getModel(path);\r
34207             };\r
34208 \r
34209             var createGraphDataProxyMixin = function (hostName, dataName) {\r
34210                 return {\r
34211                     /**\r
34212                      * @param {string=} [dimension='value'] Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.\r
34213                      * @return {number}\r
34214                      */\r
34215                     getValue: function (dimension) {\r
34216                         var data = this[hostName][dataName];\r
34217                         return data.get(data.getDimension(dimension || 'value'), this.dataIndex);\r
34218                     },\r
34219 \r
34220                     /**\r
34221                      * @param {Object|string} key\r
34222                      * @param {*} [value]\r
34223                      */\r
34224                     setVisual: function (key, value) {\r
34225                         this.dataIndex >= 0\r
34226                             && this[hostName][dataName].setItemVisual(this.dataIndex, key, value);\r
34227                     },\r
34228 \r
34229                     /**\r
34230                      * @param {string} key\r
34231                      * @return {boolean}\r
34232                      */\r
34233                     getVisual: function (key, ignoreParent) {\r
34234                         return this[hostName][dataName].getItemVisual(this.dataIndex, key, ignoreParent);\r
34235                     },\r
34236 \r
34237                     /**\r
34238                      * @param {Object} layout\r
34239                      * @return {boolean} [merge=false]\r
34240                      */\r
34241                     setLayout: function (layout, merge) {\r
34242                         this.dataIndex >= 0\r
34243                             && this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge);\r
34244                     },\r
34245 \r
34246                     /**\r
34247                      * @return {Object}\r
34248                      */\r
34249                     getLayout: function () {\r
34250                         return this[hostName][dataName].getItemLayout(this.dataIndex);\r
34251                     },\r
34252 \r
34253                     /**\r
34254                      * @return {module:zrender/Element}\r
34255                      */\r
34256                     getGraphicEl: function () {\r
34257                         return this[hostName][dataName].getItemGraphicEl(this.dataIndex);\r
34258                     },\r
34259 \r
34260                     /**\r
34261                      * @return {number}\r
34262                      */\r
34263                     getRawIndex: function () {\r
34264                         return this[hostName][dataName].getRawIndex(this.dataIndex);\r
34265                     }\r
34266                 };\r
34267             };\r
34268 \r
34269             zrUtil.mixin(Node, createGraphDataProxyMixin('hostGraph', 'data'));\r
34270             zrUtil.mixin(Edge, createGraphDataProxyMixin('hostGraph', 'edgeData'));\r
34271 \r
34272             Graph.Node = Node;\r
34273             Graph.Edge = Edge;\r
34274 \r
34275             module.exports = Graph;\r
34276 \r
34277 \r
34278 /***/ },\r
34279 /* 193 */\r
34280 /***/ function(module, exports, __webpack_require__) {\r
34281 \r
34282         \r
34283 \r
34284 \r
34285             var SymbolDraw = __webpack_require__(98);\r
34286             var LineDraw = __webpack_require__(194);\r
34287             var RoamController = __webpack_require__(159);\r
34288 \r
34289             var modelUtil = __webpack_require__(5);\r
34290             var graphic = __webpack_require__(42);\r
34291 \r
34292             __webpack_require__(1).extendChartView({\r
34293 \r
34294                 type: 'graph',\r
34295 \r
34296                 init: function (ecModel, api) {\r
34297                     var symbolDraw = new SymbolDraw();\r
34298                     var lineDraw = new LineDraw();\r
34299                     var group = this.group;\r
34300 \r
34301                     var controller = new RoamController(api.getZr(), group);\r
34302 \r
34303                     group.add(symbolDraw.group);\r
34304                     group.add(lineDraw.group);\r
34305 \r
34306                     this._symbolDraw = symbolDraw;\r
34307                     this._lineDraw = lineDraw;\r
34308                     this._controller = controller;\r
34309 \r
34310                     this._firstRender = true;\r
34311                 },\r
34312 \r
34313                 render: function (seriesModel, ecModel, api) {\r
34314                     var coordSys = seriesModel.coordinateSystem;\r
34315                     // Only support view and geo coordinate system\r
34316                     if (coordSys.type !== 'geo' && coordSys.type !== 'view') {\r
34317                         return;\r
34318                     }\r
34319 \r
34320                     var data = seriesModel.getData();\r
34321                     this._model = seriesModel;\r
34322 \r
34323                     var symbolDraw = this._symbolDraw;\r
34324                     var lineDraw = this._lineDraw;\r
34325 \r
34326                     symbolDraw.updateData(data);\r
34327 \r
34328                     var edgeData = data.graph.edgeData;\r
34329                     var rawOption = seriesModel.option;\r
34330                     var formatModel = modelUtil.createDataFormatModel(\r
34331                         seriesModel, edgeData, rawOption.edges || rawOption.links\r
34332                     );\r
34333                     formatModel.formatTooltip = function (dataIndex) {\r
34334                         var params = this.getDataParams(dataIndex);\r
34335                         var edge = data.graph.getEdgeByIndex(dataIndex);\r
34336                         var sourceName = data.getName(edge.node1.dataIndex);\r
34337                         var targetName = data.getName(edge.node2.dataIndex);\r
34338                         var html = sourceName + ' > ' + targetName;\r
34339                         if (params.value) {\r
34340                             html += ' : ' + params.value;\r
34341                         }\r
34342                         return html;\r
34343                     };\r
34344 \r
34345                     lineDraw.updateData(edgeData, null, null);\r
34346                     edgeData.eachItemGraphicEl(function (el) {\r
34347                         el.traverse(function (child) {\r
34348                             child.dataModel = formatModel;\r
34349                         });\r
34350                     });\r
34351 \r
34352                     // Save the original lineWidth\r
34353                     // data.graph.eachEdge(function (edge) {\r
34354                     //     edge.__lineWidth = edge.getModel('lineStyle.normal').get('width');\r
34355                     // });\r
34356 \r
34357                     var group = this.group;\r
34358                     var groupNewProp = {\r
34359                         position: coordSys.position,\r
34360                         scale: coordSys.scale\r
34361                     };\r
34362                     if (this._firstRender) {\r
34363                         group.attr(groupNewProp);\r
34364                     }\r
34365                     else {\r
34366                         graphic.updateProps(group, groupNewProp, seriesModel);\r
34367                     }\r
34368 \r
34369                     this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');\r
34370                     // this._edgeScaleRatio = seriesModel.get('edgeScaleRatio');\r
34371 \r
34372                     this._updateNodeAndLinkScale();\r
34373 \r
34374                     this._updateController(seriesModel, coordSys, api);\r
34375 \r
34376                     clearTimeout(this._layoutTimeout);\r
34377                     var forceLayout = seriesModel.forceLayout;\r
34378                     var layoutAnimation = seriesModel.get('force.layoutAnimation');\r
34379                     if (forceLayout) {\r
34380                         this._startForceLayoutIteration(forceLayout, layoutAnimation);\r
34381                     }\r
34382                     // Update draggable\r
34383                     data.eachItemGraphicEl(function (el, idx) {\r
34384                         var draggable = data.getItemModel(idx).get('draggable');\r
34385                         if (draggable && forceLayout) {\r
34386                             el.on('drag', function () {\r
34387                                 forceLayout.warmUp();\r
34388                                 !this._layouting\r
34389                                     && this._startForceLayoutIteration(forceLayout, layoutAnimation);\r
34390                                 forceLayout.setFixed(idx);\r
34391                                 // Write position back to layout\r
34392                                 data.setItemLayout(idx, el.position);\r
34393                             }, this).on('dragend', function () {\r
34394                                 forceLayout.setUnfixed(idx);\r
34395                             }, this);\r
34396                         }\r
34397                         else {\r
34398                             el.off('drag');\r
34399                         }\r
34400                         el.setDraggable(draggable);\r
34401                     }, this);\r
34402 \r
34403                     this._firstRender = false;\r
34404                 },\r
34405 \r
34406                 _startForceLayoutIteration: function (forceLayout, layoutAnimation) {\r
34407                     var self = this;\r
34408                     (function step() {\r
34409                         forceLayout.step(function (stopped) {\r
34410                             self.updateLayout();\r
34411                             (self._layouting = !stopped) && (\r
34412                                 layoutAnimation\r
34413                                     ? (self._layoutTimeout = setTimeout(step, 16))\r
34414                                     : step()\r
34415                             );\r
34416                         });\r
34417                     })();\r
34418                 },\r
34419 \r
34420                 _updateController: function (seriesModel, coordSys, api) {\r
34421                     var controller = this._controller;\r
34422                     controller.rect = coordSys.getViewRect();\r
34423 \r
34424                     controller.enable(seriesModel.get('roam'));\r
34425 \r
34426                     controller\r
34427                         .off('pan')\r
34428                         .off('zoom')\r
34429                         .on('pan', function (dx, dy) {\r
34430                             api.dispatchAction({\r
34431                                 seriesId: seriesModel.id,\r
34432                                 type: 'graphRoam',\r
34433                                 dx: dx,\r
34434                                 dy: dy\r
34435                             });\r
34436                         })\r
34437                         .on('zoom', function (zoom, mouseX, mouseY) {\r
34438                             api.dispatchAction({\r
34439                                 seriesId: seriesModel.id,\r
34440                                 type: 'graphRoam',\r
34441                                 zoom:  zoom,\r
34442                                 originX: mouseX,\r
34443                                 originY: mouseY\r
34444                             });\r
34445                         })\r
34446                         .on('zoom', this._updateNodeAndLinkScale, this);\r
34447                 },\r
34448 \r
34449                 _updateNodeAndLinkScale: function () {\r
34450                     var seriesModel = this._model;\r
34451                     var data = seriesModel.getData();\r
34452 \r
34453                     var group = this.group;\r
34454                     var nodeScaleRatio = this._nodeScaleRatio;\r
34455                     // var edgeScaleRatio = this._edgeScaleRatio;\r
34456 \r
34457                     // Assume scale aspect is 1\r
34458                     var groupScale = group.scale[0];\r
34459 \r
34460                     var nodeScale = (groupScale - 1) * nodeScaleRatio + 1;\r
34461                     // var edgeScale = (groupScale - 1) * edgeScaleRatio + 1;\r
34462                     var invScale = [\r
34463                         nodeScale / groupScale,\r
34464                         nodeScale / groupScale\r
34465                     ];\r
34466 \r
34467                     data.eachItemGraphicEl(function (el, idx) {\r
34468                         el.attr('scale', invScale);\r
34469                     });\r
34470                     // data.graph.eachEdge(function (edge) {\r
34471                     //     var lineGroup = edge.getGraphicEl();\r
34472                     //     // FIXME\r
34473                     //     lineGroup.childOfName('line').setStyle(\r
34474                     //         'lineWidth',\r
34475                     //         edge.__lineWidth * edgeScale / groupScale\r
34476                     //     );\r
34477                     // });\r
34478                 },\r
34479 \r
34480                 updateLayout: function (seriesModel, ecModel) {\r
34481                     this._symbolDraw.updateLayout();\r
34482                     this._lineDraw.updateLayout();\r
34483                 },\r
34484 \r
34485                 remove: function (ecModel, api) {\r
34486                     this._symbolDraw && this._symbolDraw.remove();\r
34487                     this._lineDraw && this._lineDraw.remove();\r
34488                 }\r
34489             });\r
34490 \r
34491 \r
34492 /***/ },\r
34493 /* 194 */\r
34494 /***/ function(module, exports, __webpack_require__) {\r
34495 \r
34496         /**\r
34497          * @module echarts/chart/helper/LineDraw\r
34498          */\r
34499 \r
34500 \r
34501             var graphic = __webpack_require__(42);\r
34502             var LineGroup = __webpack_require__(195);\r
34503 \r
34504             /**\r
34505              * @alias module:echarts/component/marker/LineDraw\r
34506              * @constructor\r
34507              */\r
34508             function LineDraw(ctor) {\r
34509                 this._ctor = ctor || LineGroup;\r
34510                 this.group = new graphic.Group();\r
34511             }\r
34512 \r
34513             var lineDrawProto = LineDraw.prototype;\r
34514 \r
34515             /**\r
34516              * @param {module:echarts/data/List} lineData\r
34517              * @param {module:echarts/data/List} [fromData]\r
34518              * @param {module:echarts/data/List} [toData]\r
34519              */\r
34520             lineDrawProto.updateData = function (lineData, fromData, toData) {\r
34521 \r
34522                 var oldLineData = this._lineData;\r
34523                 var group = this.group;\r
34524                 var LineCtor = this._ctor;\r
34525 \r
34526                 lineData.diff(oldLineData)\r
34527                     .add(function (idx) {\r
34528                         var lineGroup = new LineCtor(lineData, fromData, toData, idx);\r
34529 \r
34530                         lineData.setItemGraphicEl(idx, lineGroup);\r
34531 \r
34532                         group.add(lineGroup);\r
34533                     })\r
34534                     .update(function (newIdx, oldIdx) {\r
34535                         var lineGroup = oldLineData.getItemGraphicEl(oldIdx);\r
34536                         lineGroup.updateData(lineData, fromData, toData, newIdx);\r
34537 \r
34538                         lineData.setItemGraphicEl(newIdx, lineGroup);\r
34539 \r
34540                         group.add(lineGroup);\r
34541                     })\r
34542                     .remove(function (idx) {\r
34543                         group.remove(oldLineData.getItemGraphicEl(idx));\r
34544                     })\r
34545                     .execute();\r
34546 \r
34547                 this._lineData = lineData;\r
34548                 this._fromData = fromData;\r
34549                 this._toData = toData;\r
34550             };\r
34551 \r
34552             lineDrawProto.updateLayout = function () {\r
34553                 var lineData = this._lineData;\r
34554                 lineData.eachItemGraphicEl(function (el, idx) {\r
34555                     el.updateLayout(lineData, this._fromData, this._toData, idx);\r
34556                 }, this);\r
34557             };\r
34558 \r
34559             lineDrawProto.remove = function () {\r
34560                 this.group.removeAll();\r
34561             };\r
34562 \r
34563             module.exports = LineDraw;\r
34564 \r
34565 \r
34566 /***/ },\r
34567 /* 195 */\r
34568 /***/ function(module, exports, __webpack_require__) {\r
34569 \r
34570         /**\r
34571          * @module echarts/chart/helper/Line\r
34572          */\r
34573 \r
34574 \r
34575             var symbolUtil = __webpack_require__(100);\r
34576             var vector = __webpack_require__(16);\r
34577             var LinePath = __webpack_require__(196);\r
34578             var graphic = __webpack_require__(42);\r
34579             var zrUtil = __webpack_require__(3);\r
34580             var numberUtil = __webpack_require__(7);\r
34581 \r
34582             /**\r
34583              * @inner\r
34584              */\r
34585             function createSymbol(name, data, idx) {\r
34586                 var color = data.getItemVisual(idx, 'color');\r
34587                 var symbolType = data.getItemVisual(idx, 'symbol');\r
34588                 var symbolSize = data.getItemVisual(idx, 'symbolSize');\r
34589 \r
34590                 if (symbolType === 'none') {\r
34591                     return;\r
34592                 }\r
34593 \r
34594                 if (!zrUtil.isArray(symbolSize)) {\r
34595                     symbolSize = [symbolSize, symbolSize];\r
34596                 }\r
34597                 var symbolPath = symbolUtil.createSymbol(\r
34598                     symbolType, -symbolSize[0] / 2, -symbolSize[1] / 2,\r
34599                     symbolSize[0], symbolSize[1], color\r
34600                 );\r
34601                 symbolPath.name = name;\r
34602 \r
34603                 return symbolPath;\r
34604             }\r
34605 \r
34606             function createLine(points) {\r
34607                 var line = new LinePath({\r
34608                     name: 'line',\r
34609                     style: {\r
34610                         strokeNoScale: true\r
34611                     }\r
34612                 });\r
34613                 setLinePoints(line.shape, points);\r
34614                 return line;\r
34615             }\r
34616 \r
34617             function setLinePoints(targetShape, points) {\r
34618                 var p1 = points[0];\r
34619                 var p2 = points[1];\r
34620                 var cp1 = points[2];\r
34621                 targetShape.x1 = p1[0];\r
34622                 targetShape.y1 = p1[1];\r
34623                 targetShape.x2 = p2[0];\r
34624                 targetShape.y2 = p2[1];\r
34625                 targetShape.percent = 1;\r
34626 \r
34627                 if (cp1) {\r
34628                     targetShape.cpx1 = cp1[0];\r
34629                     targetShape.cpy1 = cp1[1];\r
34630                 }\r
34631             }\r
34632 \r
34633             function isSymbolArrow(symbol) {\r
34634                 return symbol.type === 'symbol' && symbol.shape.symbolType === 'arrow';\r
34635             }\r
34636 \r
34637             function updateSymbolBeforeLineUpdate () {\r
34638                 var lineGroup = this;\r
34639                 var line = lineGroup.childOfName('line');\r
34640                 // If line not changed\r
34641                 if (!this.__dirty && !line.__dirty) {\r
34642                     return;\r
34643                 }\r
34644                 var symbolFrom = lineGroup.childOfName('fromSymbol');\r
34645                 var symbolTo = lineGroup.childOfName('toSymbol');\r
34646                 var label = lineGroup.childOfName('label');\r
34647                 var fromPos = line.pointAt(0);\r
34648                 var toPos = line.pointAt(line.shape.percent);\r
34649 \r
34650                 var d = vector.sub([], toPos, fromPos);\r
34651                 vector.normalize(d, d);\r
34652 \r
34653                 if (symbolFrom) {\r
34654                     symbolFrom.attr('position', fromPos);\r
34655                     // Rotate the arrow\r
34656                     // FIXME Hard coded ?\r
34657                     if (isSymbolArrow(symbolFrom)) {\r
34658                         symbolFrom.attr('rotation', tangentRotation(toPos, fromPos));\r
34659                     }\r
34660                 }\r
34661                 if (symbolTo) {\r
34662                     symbolTo.attr('position', toPos);\r
34663                     if (isSymbolArrow(symbolTo)) {\r
34664                         symbolTo.attr('rotation', tangentRotation(fromPos, toPos));\r
34665                     }\r
34666                 }\r
34667 \r
34668                 label.attr('position', toPos);\r
34669 \r
34670                 var textPosition;\r
34671                 var textAlign;\r
34672                 var textVerticalAlign;\r
34673                 // End\r
34674                 if (label.__position === 'end') {\r
34675                     textPosition = [d[0] * 5 + toPos[0], d[1] * 5 + toPos[1]];\r
34676                     textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center');\r
34677                     textVerticalAlign = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle');\r
34678                 }\r
34679                 // Start\r
34680                 else {\r
34681                     textPosition = [-d[0] * 5 + fromPos[0], -d[1] * 5 + fromPos[1]];\r
34682                     textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center');\r
34683                     textVerticalAlign = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle');\r
34684                 }\r
34685                 label.attr({\r
34686                     style: {\r
34687                         // Use the user specified text align and baseline first\r
34688                         textVerticalAlign: label.__verticalAlign || textVerticalAlign,\r
34689                         textAlign: label.__textAlign || textAlign\r
34690                     },\r
34691                     position: textPosition\r
34692                 });\r
34693             }\r
34694 \r
34695             function tangentRotation(p1, p2) {\r
34696                 return -Math.PI / 2 - Math.atan2(\r
34697                     p2[1] - p1[1], p2[0] - p1[0]\r
34698                 );\r
34699             }\r
34700 \r
34701             /**\r
34702              * @constructor\r
34703              * @extends {module:zrender/graphic/Group}\r
34704              * @alias {module:echarts/chart/helper/Line}\r
34705              */\r
34706             function Line(lineData, fromData, toData, idx) {\r
34707                 graphic.Group.call(this);\r
34708 \r
34709                 this._createLine(lineData, fromData, toData, idx);\r
34710             }\r
34711 \r
34712             var lineProto = Line.prototype;\r
34713 \r
34714             // Update symbol position and rotation\r
34715             lineProto.beforeUpdate = updateSymbolBeforeLineUpdate;\r
34716 \r
34717             lineProto._createLine = function (lineData, fromData, toData, idx) {\r
34718                 var seriesModel = lineData.hostModel;\r
34719                 var linePoints = lineData.getItemLayout(idx);\r
34720 \r
34721                 var line = createLine(linePoints);\r
34722                 line.shape.percent = 0;\r
34723                 graphic.initProps(line, {\r
34724                     shape: {\r
34725                         percent: 1\r
34726                     }\r
34727                 }, seriesModel);\r
34728 \r
34729                 this.add(line);\r
34730 \r
34731                 var label = new graphic.Text({\r
34732                     name: 'label'\r
34733                 });\r
34734                 this.add(label);\r
34735 \r
34736                 if (fromData) {\r
34737                     var symbolFrom = createSymbol('fromSymbol', fromData, idx);\r
34738                     // symbols must added after line to make sure\r
34739                     // it will be updated after line#update.\r
34740                     // Or symbol position and rotation update in line#beforeUpdate will be one frame slow\r
34741                     this.add(symbolFrom);\r
34742 \r
34743                     this._fromSymbolType = fromData.getItemVisual(idx, 'symbol');\r
34744                 }\r
34745                 if (toData) {\r
34746                     var symbolTo = createSymbol('toSymbol', toData, idx);\r
34747                     this.add(symbolTo);\r
34748 \r
34749                     this._toSymbolType = toData.getItemVisual(idx, 'symbol');\r
34750                 }\r
34751 \r
34752                 this._updateCommonStl(lineData, fromData, toData, idx);\r
34753             };\r
34754 \r
34755             lineProto.updateData = function (lineData, fromData, toData, idx) {\r
34756                 var seriesModel = lineData.hostModel;\r
34757 \r
34758                 var line = this.childOfName('line');\r
34759                 var linePoints = lineData.getItemLayout(idx);\r
34760                 var target = {\r
34761                     shape: {}\r
34762                 };\r
34763                 setLinePoints(target.shape, linePoints);\r
34764                 graphic.updateProps(line, target, seriesModel);\r
34765 \r
34766                 // Symbol changed\r
34767                 if (fromData) {\r
34768                     var fromSymbolType = fromData.getItemVisual(idx, 'symbol');\r
34769                     if (this._fromSymbolType !== fromSymbolType) {\r
34770                         var symbolFrom = createSymbol('fromSymbol', fromData, idx);\r
34771                         this.remove(this.childOfName('fromSymbol'));\r
34772                         this.add(symbolFrom);\r
34773                     }\r
34774                     this._fromSymbolType = fromSymbolType;\r
34775                 }\r
34776                 if (toData) {\r
34777                     var toSymbolType = toData.getItemVisual(idx, 'symbol');\r
34778                     // Symbol changed\r
34779                     if (toSymbolType !== this._toSymbolType) {\r
34780                         var symbolTo = createSymbol('toSymbol', toData, idx);\r
34781                         this.remove(this.childOfName('toSymbol'));\r
34782                         this.add(symbolTo);\r
34783                     }\r
34784                     this._toSymbolType = toSymbolType;\r
34785                 }\r
34786 \r
34787                 this._updateCommonStl(lineData, fromData, toData, idx);\r
34788             };\r
34789 \r
34790             lineProto._updateCommonStl = function (lineData, fromData, toData, idx) {\r
34791                 var seriesModel = lineData.hostModel;\r
34792 \r
34793                 var line = this.childOfName('line');\r
34794                 var itemModel = lineData.getItemModel(idx);\r
34795 \r
34796                 var labelModel = itemModel.getModel('label.normal');\r
34797                 var textStyleModel = labelModel.getModel('textStyle');\r
34798                 var labelHoverModel = itemModel.getModel('label.emphasis');\r
34799                 var textStyleHoverModel = labelHoverModel.getModel('textStyle');\r
34800 \r
34801                 var defaultText = numberUtil.round(seriesModel.getRawValue(idx));\r
34802                 if (isNaN(defaultText)) {\r
34803                     // Use name\r
34804                     defaultText = lineData.getName(idx);\r
34805                 }\r
34806                 line.setStyle(zrUtil.extend(\r
34807                     {\r
34808                         stroke: lineData.getItemVisual(idx, 'color')\r
34809                     },\r
34810                     itemModel.getModel('lineStyle.normal').getLineStyle()\r
34811                 ));\r
34812 \r
34813                 var label = this.childOfName('label');\r
34814                 label.setStyle({\r
34815                     text: labelModel.get('show')\r
34816                         ? zrUtil.retrieve(\r
34817                             seriesModel.getFormattedLabel(idx, 'normal'),\r
34818                             defaultText\r
34819                         )\r
34820                         : '',\r
34821                     textFont: textStyleModel.getFont(),\r
34822                     fill: textStyleModel.getTextColor() || lineData.getItemVisual(idx, 'color')\r
34823                 });\r
34824                 label.hoverStyle = {\r
34825                     text: labelHoverModel.get('show')\r
34826                         ? zrUtil.retrieve(\r
34827                             seriesModel.getFormattedLabel(idx, 'emphasis'),\r
34828                             defaultText\r
34829                         )\r
34830                         : '',\r
34831                     textFont: textStyleHoverModel.getFont(),\r
34832                     fill: textStyleHoverModel.getTextColor()\r
34833                 };\r
34834                 label.__textAlign = textStyleModel.get('align');\r
34835                 label.__verticalAlign = textStyleModel.get('baseline');\r
34836                 label.__position = labelModel.get('position');\r
34837 \r
34838                 graphic.setHoverStyle(\r
34839                     this, itemModel.getModel('lineStyle.emphasis').getLineStyle()\r
34840                 );\r
34841             };\r
34842 \r
34843             lineProto.updateLayout = function (lineData, fromData, toData, idx) {\r
34844                 var points = lineData.getItemLayout(idx);\r
34845                 var linePath = this.childOfName('line');\r
34846                 setLinePoints(linePath.shape, points);\r
34847                 linePath.dirty(true);\r
34848                 // var fromEl = fromData && fromData.getItemGraphicEl(idx);\r
34849                 // var toEl = toData && toData.getItemGraphicEl(idx);\r
34850                 // fromEl && fromEl.attr('position', points[0]);\r
34851                 // toEl && toEl.attr('position', points[1]);\r
34852             };\r
34853 \r
34854             zrUtil.inherits(Line, graphic.Group);\r
34855 \r
34856             module.exports = Line;\r
34857 \r
34858 \r
34859 /***/ },\r
34860 /* 196 */\r
34861 /***/ function(module, exports, __webpack_require__) {\r
34862 \r
34863         /**\r
34864          * Line path for bezier and straight line draw\r
34865          */\r
34866 \r
34867             var graphic = __webpack_require__(42);\r
34868 \r
34869             var straightLineProto = graphic.Line.prototype;\r
34870             var bezierCurveProto = graphic.BezierCurve.prototype;\r
34871 \r
34872             module.exports = graphic.extendShape({\r
34873 \r
34874                 type: 'ec-line',\r
34875 \r
34876                 style: {\r
34877                     stroke: '#000',\r
34878                     fill: null\r
34879                 },\r
34880 \r
34881                 shape: {\r
34882                     x1: 0,\r
34883                     y1: 0,\r
34884                     x2: 0,\r
34885                     y2: 0,\r
34886                     percent: 1,\r
34887                     cpx1: null,\r
34888                     cpy1: null\r
34889                 },\r
34890 \r
34891                 buildPath: function (ctx, shape) {\r
34892                     (shape.cpx1 == null || shape.cpy1 == null\r
34893                         ? straightLineProto : bezierCurveProto).buildPath(ctx, shape);\r
34894                 },\r
34895 \r
34896                 pointAt: function (t) {\r
34897                     var shape = this.shape;\r
34898                     return shape.cpx1 == null || shape.cpy1 == null\r
34899                         ? straightLineProto.pointAt.call(this, t)\r
34900                         : bezierCurveProto.pointAt.call(this, t);\r
34901                 }\r
34902             });\r
34903 \r
34904 \r
34905 /***/ },\r
34906 /* 197 */\r
34907 /***/ function(module, exports, __webpack_require__) {\r
34908 \r
34909         \r
34910 \r
34911             var echarts = __webpack_require__(1);\r
34912             var roamHelper = __webpack_require__(162);\r
34913 \r
34914             var actionInfo = {\r
34915                 type: 'graphRoam',\r
34916                 event: 'graphRoam',\r
34917                 update: 'none'\r
34918             };\r
34919 \r
34920             /**\r
34921              * @payload\r
34922              * @property {string} name Series name\r
34923              * @property {number} [dx]\r
34924              * @property {number} [dy]\r
34925              * @property {number} [zoom]\r
34926              * @property {number} [originX]\r
34927              * @property {number} [originY]\r
34928              */\r
34929 \r
34930             echarts.registerAction(actionInfo, function (payload, ecModel) {\r
34931                 ecModel.eachComponent({mainType: 'series', query: payload}, function (seriesModel) {\r
34932                     var coordSys = seriesModel.coordinateSystem;\r
34933 \r
34934                     var roamDetailModel = seriesModel.getModel('roamDetail');\r
34935                     var res = roamHelper.calcPanAndZoom(roamDetailModel, payload);\r
34936 \r
34937                     seriesModel.setRoamPan\r
34938                         && seriesModel.setRoamPan(res.x, res.y);\r
34939 \r
34940                     seriesModel.setRoamZoom\r
34941                         && seriesModel.setRoamZoom(res.zoom);\r
34942 \r
34943                     coordSys && coordSys.setPan(res.x, res.y);\r
34944                     coordSys && coordSys.setZoom(res.zoom);\r
34945                 });\r
34946             });\r
34947 \r
34948 \r
34949 /***/ },\r
34950 /* 198 */\r
34951 /***/ function(module, exports) {\r
34952 \r
34953         \r
34954 \r
34955             module.exports = function (ecModel) {\r
34956                 var legendModels = ecModel.findComponents({\r
34957                     mainType: 'legend'\r
34958                 });\r
34959                 if (!legendModels || !legendModels.length) {\r
34960                     return;\r
34961                 }\r
34962                 ecModel.eachSeriesByType('graph', function (graphSeries) {\r
34963                     var categoriesData = graphSeries.getCategoriesData();\r
34964                     var graph = graphSeries.getGraph();\r
34965                     var data = graph.data;\r
34966 \r
34967                     var categoryNames = categoriesData.mapArray(categoriesData.getName);\r
34968 \r
34969                     data.filterSelf(function (idx) {\r
34970                         var model = data.getItemModel(idx);\r
34971                         var category = model.getShallow('category');\r
34972                         if (category != null) {\r
34973                             if (typeof category === 'number') {\r
34974                                 category = categoryNames[category];\r
34975                             }\r
34976                             // If in any legend component the status is not selected.\r
34977                             for (var i = 0; i < legendModels.length; i++) {\r
34978                                 if (!legendModels[i].isSelected(category)) {\r
34979                                     return false;\r
34980                                 }\r
34981                             }\r
34982                         }\r
34983                         return true;\r
34984                     });\r
34985                 }, this);\r
34986             };\r
34987 \r
34988 \r
34989 /***/ },\r
34990 /* 199 */\r
34991 /***/ function(module, exports) {\r
34992 \r
34993         \r
34994 \r
34995             module.exports = function (ecModel) {\r
34996                 ecModel.eachSeriesByType('graph', function (seriesModel) {\r
34997                     var colorList = seriesModel.get('color');\r
34998                     var categoriesData = seriesModel.getCategoriesData();\r
34999                     var data = seriesModel.getData();\r
35000 \r
35001                     var categoryNameIdxMap = {};\r
35002 \r
35003                     categoriesData.each(function (idx) {\r
35004                         categoryNameIdxMap[categoriesData.getName(idx)] = idx;\r
35005 \r
35006                         var itemModel = categoriesData.getItemModel(idx);\r
35007                         var rawIdx = categoriesData.getRawIndex(idx);\r
35008                         var color = itemModel.get('itemStyle.normal.color')\r
35009                             || colorList[rawIdx % colorList.length];\r
35010                         categoriesData.setItemVisual(idx, 'color', color);\r
35011                     });\r
35012 \r
35013                     // Assign category color to visual\r
35014                     if (categoriesData.count()) {\r
35015                         data.each(function (idx) {\r
35016                             var model = data.getItemModel(idx);\r
35017                             var category = model.getShallow('category');\r
35018                             if (category != null) {\r
35019                                 if (typeof category === 'string') {\r
35020                                     category = categoryNameIdxMap[category];\r
35021                                 }\r
35022                                 data.setItemVisual(\r
35023                                     idx, 'color',\r
35024                                     categoriesData.getItemVisual(category, 'color')\r
35025                                 );\r
35026                             }\r
35027                         });\r
35028                     }\r
35029                 });\r
35030             };\r
35031 \r
35032 \r
35033 /***/ },\r
35034 /* 200 */\r
35035 /***/ function(module, exports, __webpack_require__) {\r
35036 \r
35037         \r
35038 \r
35039             var simpleLayoutHelper = __webpack_require__(201);\r
35040             module.exports = function (ecModel, api) {\r
35041                 ecModel.eachSeriesByType('graph', function (seriesModel) {\r
35042                     var layout = seriesModel.get('layout');\r
35043                     if (!layout || layout === 'none') {\r
35044                         simpleLayoutHelper(seriesModel);\r
35045                     }\r
35046                 });\r
35047             };\r
35048 \r
35049 \r
35050 /***/ },\r
35051 /* 201 */\r
35052 /***/ function(module, exports) {\r
35053 \r
35054         \r
35055             module.exports = function (seriesModel) {\r
35056                 var coordSys = seriesModel.coordinateSystem;\r
35057                 if (coordSys && coordSys.type !== 'view') {\r
35058                     return;\r
35059                 }\r
35060                 var graph = seriesModel.getGraph();\r
35061 \r
35062                 graph.eachNode(function (node) {\r
35063                     var model = node.getModel();\r
35064                     node.setLayout([+model.get('x'), +model.get('y')]);\r
35065                 });\r
35066 \r
35067                 graph.eachEdge(function (edge) {\r
35068                     var curveness = edge.getModel().get('lineStyle.normal.curveness') || 0;\r
35069                     var p1 = edge.node1.getLayout();\r
35070                     var p2 = edge.node2.getLayout();\r
35071                     var cp1;\r
35072                     if (curveness > 0) {\r
35073                         cp1 = [\r
35074                             (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * curveness,\r
35075                             (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * curveness\r
35076                         ];\r
35077                     }\r
35078                     edge.setLayout([p1, p2, cp1]);\r
35079                 });\r
35080             };\r
35081 \r
35082 \r
35083 /***/ },\r
35084 /* 202 */\r
35085 /***/ function(module, exports, __webpack_require__) {\r
35086 \r
35087         \r
35088             var circularLayoutHelper = __webpack_require__(203);\r
35089             module.exports = function (ecModel, api) {\r
35090                 ecModel.eachSeriesByType('graph', function (seriesModel) {\r
35091                     if (seriesModel.get('layout') === 'circular') {\r
35092                         circularLayoutHelper(seriesModel);\r
35093                     }\r
35094                 });\r
35095             };\r
35096 \r
35097 \r
35098 /***/ },\r
35099 /* 203 */\r
35100 /***/ function(module, exports) {\r
35101 \r
35102         \r
35103             module.exports = function (seriesModel) {\r
35104                 var coordSys = seriesModel.coordinateSystem;\r
35105                 if (coordSys && coordSys.type !== 'view') {\r
35106                     return;\r
35107                 }\r
35108 \r
35109                 var rect = coordSys.getBoundingRect();\r
35110 \r
35111                 var nodeData = seriesModel.getData();\r
35112                 var graph = nodeData.graph;\r
35113 \r
35114                 var angle = 0;\r
35115                 var sum = nodeData.getSum('value');\r
35116                 var unitAngle = Math.PI * 2 / (sum || nodeData.count());\r
35117 \r
35118                 var cx = rect.width / 2 + rect.x;\r
35119                 var cy = rect.height / 2 + rect.y;\r
35120 \r
35121                 var r = Math.min(rect.width, rect.height) / 2;\r
35122 \r
35123                 graph.eachNode(function (node) {\r
35124                     var value = node.getValue('value');\r
35125 \r
35126                     angle += unitAngle * (sum ? value : 2) / 2;\r
35127 \r
35128                     node.setLayout([\r
35129                         r * Math.cos(angle) + cx,\r
35130                         r * Math.sin(angle) + cy\r
35131                     ]);\r
35132 \r
35133                     angle += unitAngle * (sum ? value : 2) / 2;\r
35134                 });\r
35135 \r
35136                 graph.eachEdge(function (edge) {\r
35137                     var curveness = edge.getModel().get('lineStyle.normal.curveness') || 0;\r
35138                     var p1 = edge.node1.getLayout();\r
35139                     var p2 = edge.node2.getLayout();\r
35140                     var cp1;\r
35141                     if (curveness > 0) {\r
35142                         cp1 = [cx, cy];\r
35143                     }\r
35144                     edge.setLayout([p1, p2, cp1]);\r
35145                 });\r
35146             };\r
35147 \r
35148 \r
35149 /***/ },\r
35150 /* 204 */\r
35151 /***/ function(module, exports, __webpack_require__) {\r
35152 \r
35153         \r
35154 \r
35155             var forceHelper = __webpack_require__(205);\r
35156             var numberUtil = __webpack_require__(7);\r
35157             var simpleLayoutHelper = __webpack_require__(201);\r
35158             var circularLayoutHelper = __webpack_require__(203);\r
35159             var vec2 = __webpack_require__(16);\r
35160 \r
35161             module.exports = function (ecModel, api) {\r
35162                 ecModel.eachSeriesByType('graph', function (graphSeries) {\r
35163                     if (graphSeries.get('layout') === 'force') {\r
35164                         var preservedPoints = graphSeries.preservedPoints || {};\r
35165                         var graph = graphSeries.getGraph();\r
35166                         var nodeData = graph.data;\r
35167                         var edgeData = graph.edgeData;\r
35168                         var forceModel = graphSeries.getModel('force');\r
35169                         var initLayout = forceModel.get('initLayout');\r
35170                         if (graphSeries.preservedPoints) {\r
35171                             nodeData.each(function (idx) {\r
35172                                 var id = nodeData.getId(idx);\r
35173                                 nodeData.setItemLayout(idx, preservedPoints[id] || [NaN, NaN]);\r
35174                             });\r
35175                         }\r
35176                         else if (!initLayout || initLayout === 'none') {\r
35177                             simpleLayoutHelper(graphSeries);\r
35178                         }\r
35179                         else if (initLayout === 'circular') {\r
35180                             circularLayoutHelper(graphSeries);\r
35181                         }\r
35182 \r
35183                         var nodeDataExtent = nodeData.getDataExtent('value');\r
35184                         // var edgeDataExtent = edgeData.getDataExtent('value');\r
35185                         var repulsion = forceModel.get('repulsion');\r
35186                         var edgeLength = forceModel.get('edgeLength');\r
35187                         var nodes = nodeData.mapArray('value', function (value, idx) {\r
35188                             var point = nodeData.getItemLayout(idx);\r
35189                             // var w = numberUtil.linearMap(value, nodeDataExtent, [0, 50]);\r
35190                             var rep = numberUtil.linearMap(value, nodeDataExtent, [0, repulsion]) || (repulsion / 2);\r
35191                             return {\r
35192                                 w: rep,\r
35193                                 rep: rep,\r
35194                                 p: (!point || isNaN(point[0]) || isNaN(point[1])) ? null : point\r
35195                             };\r
35196                         });\r
35197                         var edges = edgeData.mapArray('value', function (value, idx) {\r
35198                             var edge = graph.getEdgeByIndex(idx);\r
35199                             // var w = numberUtil.linearMap(value, edgeDataExtent, [0, 100]);\r
35200                             return {\r
35201                                 n1: nodes[edge.node1.dataIndex],\r
35202                                 n2: nodes[edge.node2.dataIndex],\r
35203                                 d: edgeLength,\r
35204                                 curveness: edge.getModel().get('lineStyle.normal.curveness') || 0\r
35205                             };\r
35206                         });\r
35207 \r
35208                         var coordSys = graphSeries.coordinateSystem;\r
35209                         var rect = coordSys.getBoundingRect();\r
35210                         var forceInstance = forceHelper(nodes, edges, {\r
35211                             rect: rect,\r
35212                             gravity: forceModel.get('gravity')\r
35213                         });\r
35214                         var oldStep = forceInstance.step;\r
35215                         forceInstance.step = function (cb) {\r
35216                             for (var i = 0, l = nodes.length; i < l; i++) {\r
35217                                 if (nodes[i].fixed) {\r
35218                                     // Write back to layout instance\r
35219                                     vec2.copy(nodes[i].p, graph.getNodeByIndex(i).getLayout());\r
35220                                 }\r
35221                             }\r
35222                             oldStep(function (nodes, edges, stopped) {\r
35223                                 for (var i = 0, l = nodes.length; i < l; i++) {\r
35224                                     if (!nodes[i].fixed) {\r
35225                                         graph.getNodeByIndex(i).setLayout(nodes[i].p);\r
35226                                     }\r
35227                                     preservedPoints[nodeData.getId(i)] = nodes[i].p;\r
35228                                 }\r
35229                                 for (var i = 0, l = edges.length; i < l; i++) {\r
35230                                     var e = edges[i];\r
35231                                     var p1 = e.n1.p;\r
35232                                     var p2 = e.n2.p;\r
35233                                     var points = [p1, p2];\r
35234                                     if (e.curveness > 0) {\r
35235                                         points.push([\r
35236                                             (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * e.curveness,\r
35237                                             (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * e.curveness\r
35238                                         ]);\r
35239                                     }\r
35240                                     graph.getEdgeByIndex(i).setLayout(points);\r
35241                                 }\r
35242                                 // Update layout\r
35243 \r
35244                                 cb && cb(stopped);\r
35245                             });\r
35246                         };\r
35247                         graphSeries.forceLayout = forceInstance;\r
35248                         graphSeries.preservedPoints = preservedPoints;\r
35249 \r
35250                         // Step to get the layout\r
35251                         forceInstance.step();\r
35252                     }\r
35253                     else {\r
35254                         // Remove prev injected forceLayout instance\r
35255                         graphSeries.forceLayout = null;\r
35256                     }\r
35257                 });\r
35258             };\r
35259 \r
35260 \r
35261 /***/ },\r
35262 /* 205 */\r
35263 /***/ function(module, exports, __webpack_require__) {\r
35264 \r
35265         \r
35266 \r
35267             var vec2 = __webpack_require__(16);\r
35268             var scaleAndAdd = vec2.scaleAndAdd;\r
35269 \r
35270             // function adjacentNode(n, e) {\r
35271             //     return e.n1 === n ? e.n2 : e.n1;\r
35272             // }\r
35273 \r
35274             module.exports = function (nodes, edges, opts) {\r
35275                 var rect = opts.rect;\r
35276                 var width = rect.width;\r
35277                 var height = rect.height;\r
35278                 var center = [rect.x + width / 2, rect.y + height / 2];\r
35279                 // var scale = opts.scale || 1;\r
35280                 var gravity = opts.gravity == null ? 0.1 : opts.gravity;\r
35281 \r
35282                 // for (var i = 0; i < edges.length; i++) {\r
35283                 //     var e = edges[i];\r
35284                 //     var n1 = e.n1;\r
35285                 //     var n2 = e.n2;\r
35286                 //     n1.edges = n1.edges || [];\r
35287                 //     n2.edges = n2.edges || [];\r
35288                 //     n1.edges.push(e);\r
35289                 //     n2.edges.push(e);\r
35290                 // }\r
35291                 // Init position\r
35292                 for (var i = 0; i < nodes.length; i++) {\r
35293                     var n = nodes[i];\r
35294                     if (!n.p) {\r
35295                         // Use the position from first adjecent node with defined position\r
35296                         // Or use a random position\r
35297                         // From d3\r
35298                         // if (n.edges) {\r
35299                         //     var j = -1;\r
35300                         //     while (++j < n.edges.length) {\r
35301                         //         var e = n.edges[j];\r
35302                         //         var other = adjacentNode(n, e);\r
35303                         //         if (other.p) {\r
35304                         //             n.p = vec2.clone(other.p);\r
35305                         //             break;\r
35306                         //         }\r
35307                         //     }\r
35308                         // }\r
35309                         // if (!n.p) {\r
35310                             n.p = vec2.create(\r
35311                                 width * (Math.random() - 0.5) + center[0],\r
35312                                 height * (Math.random() - 0.5) + center[1]\r
35313                             );\r
35314                         // }\r
35315                     }\r
35316                     n.pp = vec2.clone(n.p);\r
35317                     n.edges = null;\r
35318                 }\r
35319 \r
35320                 // Formula in 'Graph Drawing by Force-directed Placement'\r
35321                 // var k = scale * Math.sqrt(width * height / nodes.length);\r
35322                 // var k2 = k * k;\r
35323 \r
35324                 var friction = 0.6;\r
35325 \r
35326                 return {\r
35327                     warmUp: function () {\r
35328                         friction = 0.5;\r
35329                     },\r
35330 \r
35331                     setFixed: function (idx) {\r
35332                         nodes[idx].fixed = true;\r
35333                     },\r
35334 \r
35335                     setUnfixed: function (idx) {\r
35336                         nodes[idx].fixed = false;\r
35337                     },\r
35338 \r
35339                     step: function (cb) {\r
35340                         var v12 = [];\r
35341                         var nLen = nodes.length;\r
35342                         for (var i = 0; i < edges.length; i++) {\r
35343                             var e = edges[i];\r
35344                             var n1 = e.n1;\r
35345                             var n2 = e.n2;\r
35346 \r
35347                             vec2.sub(v12, n2.p, n1.p);\r
35348                             var d = vec2.len(v12) - e.d;\r
35349                             var w = n2.w / (n1.w + n2.w);\r
35350                             vec2.normalize(v12, v12);\r
35351 \r
35352                             !n1.fixed && scaleAndAdd(n1.p, n1.p, v12, w * d * friction);\r
35353                             !n2.fixed && scaleAndAdd(n2.p, n2.p, v12, -(1 - w) * d * friction);\r
35354                         }\r
35355                         // Gravity\r
35356                         for (var i = 0; i < nLen; i++) {\r
35357                             var n = nodes[i];\r
35358                             if (!n.fixed) {\r
35359                                 vec2.sub(v12, center, n.p);\r
35360                                 // var d = vec2.len(v12);\r
35361                                 // vec2.scale(v12, v12, 1 / d);\r
35362                                 // var gravityFactor = gravity;\r
35363                                 vec2.scaleAndAdd(n.p, n.p, v12, gravity * friction);\r
35364                             }\r
35365                         }\r
35366 \r
35367                         // Repulsive\r
35368                         // PENDING\r
35369                         for (var i = 0; i < nLen; i++) {\r
35370                             var n1 = nodes[i];\r
35371                             for (var j = i + 1; j < nLen; j++) {\r
35372                                 var n2 = nodes[j];\r
35373                                 vec2.sub(v12, n2.p, n1.p);\r
35374                                 var d = vec2.len(v12);\r
35375                                 if (d === 0) {\r
35376                                     // Random repulse\r
35377                                     vec2.set(v12, Math.random() - 0.5, Math.random() - 0.5);\r
35378                                     d = 1;\r
35379                                 }\r
35380                                 var repFact = (n1.rep + n2.rep) / d / d;\r
35381                                 !n1.fixed && scaleAndAdd(n1.pp, n1.pp, v12, repFact);\r
35382                                 !n2.fixed && scaleAndAdd(n2.pp, n2.pp, v12, -repFact);\r
35383                             }\r
35384                         }\r
35385                         var v = [];\r
35386                         for (var i = 0; i < nLen; i++) {\r
35387                             var n = nodes[i];\r
35388                             if (!n.fixed) {\r
35389                                 vec2.sub(v, n.p, n.pp);\r
35390                                 vec2.scaleAndAdd(n.p, n.p, v, friction);\r
35391                                 vec2.copy(n.pp, n.p);\r
35392                             }\r
35393                         }\r
35394 \r
35395                         friction = friction * 0.992;\r
35396 \r
35397                         cb && cb(nodes, edges, friction < 0.01);\r
35398                     }\r
35399                 };\r
35400             };\r
35401 \r
35402 \r
35403 /***/ },\r
35404 /* 206 */\r
35405 /***/ function(module, exports, __webpack_require__) {\r
35406 \r
35407         \r
35408             // FIXME Where to create the simple view coordinate system\r
35409             var View = __webpack_require__(169);\r
35410             var layout = __webpack_require__(21);\r
35411             var bbox = __webpack_require__(50);\r
35412 \r
35413             function getViewRect(seriesModel, api, aspect) {\r
35414                 var option = seriesModel.getBoxLayoutParams();\r
35415                 option.aspect = aspect;\r
35416                 return layout.getLayoutRect(option, {\r
35417                     width: api.getWidth(),\r
35418                     height: api.getHeight()\r
35419                 });\r
35420             }\r
35421 \r
35422             module.exports = function (ecModel, api) {\r
35423                 var viewList = [];\r
35424                 ecModel.eachSeriesByType('graph', function (seriesModel) {\r
35425                     var coordSysType = seriesModel.get('coordinateSystem');\r
35426                     if (!coordSysType || coordSysType === 'view') {\r
35427                         var viewCoordSys = new View();\r
35428                         viewList.push(viewCoordSys);\r
35429 \r
35430                         var data = seriesModel.getData();\r
35431                         var positions = data.mapArray(function (idx) {\r
35432                             var itemModel = data.getItemModel(idx);\r
35433                             return [+itemModel.get('x'), +itemModel.get('y')];\r
35434                         });\r
35435 \r
35436                         var min = [];\r
35437                         var max = [];\r
35438 \r
35439                         bbox.fromPoints(positions, min, max);\r
35440 \r
35441                         // FIXME If get view rect after data processed?\r
35442                         var viewRect = getViewRect(\r
35443                             seriesModel, api, (max[0] - min[0]) / (max[1] - min[1]) || 1\r
35444                         );\r
35445                         // Position may be NaN, use view rect instead\r
35446                         if (isNaN(min[0]) || isNaN(min[1])) {\r
35447                             min = [viewRect.x, viewRect.y];\r
35448                             max = [viewRect.x + viewRect.width, viewRect.y + viewRect.height];\r
35449                         }\r
35450 \r
35451                         var bbWidth = max[0] - min[0];\r
35452                         var bbHeight = max[1] - min[1];\r
35453 \r
35454                         var viewWidth = viewRect.width;\r
35455                         var viewHeight = viewRect.height;\r
35456 \r
35457                         viewCoordSys = seriesModel.coordinateSystem = new View();\r
35458 \r
35459                         viewCoordSys.setBoundingRect(\r
35460                             min[0], min[1], bbWidth, bbHeight\r
35461                         );\r
35462                         viewCoordSys.setViewRect(\r
35463                             viewRect.x, viewRect.y, viewWidth, viewHeight\r
35464                         );\r
35465 \r
35466                         // Update roam info\r
35467                         var roamDetailModel = seriesModel.getModel('roamDetail');\r
35468                         viewCoordSys.setPan(roamDetailModel.get('x') || 0, roamDetailModel.get('y') || 0);\r
35469                         viewCoordSys.setZoom(roamDetailModel.get('zoom') || 1);\r
35470                     }\r
35471                 });\r
35472                 return viewList;\r
35473             };\r
35474 \r
35475 \r
35476 /***/ },\r
35477 /* 207 */\r
35478 /***/ function(module, exports, __webpack_require__) {\r
35479 \r
35480         \r
35481             __webpack_require__(208);\r
35482             __webpack_require__(209);\r
35483 \r
35484 \r
35485 /***/ },\r
35486 /* 208 */\r
35487 /***/ function(module, exports, __webpack_require__) {\r
35488 \r
35489         \r
35490 \r
35491             var List = __webpack_require__(94);\r
35492             var SeriesModel = __webpack_require__(27);\r
35493             var zrUtil = __webpack_require__(3);\r
35494 \r
35495             var GaugeSeries = SeriesModel.extend({\r
35496 \r
35497                 type: 'series.gauge',\r
35498 \r
35499                 getInitialData: function (option, ecModel) {\r
35500                     var list = new List(['value'], this);\r
35501                     var dataOpt = option.data || [];\r
35502                     if (!zrUtil.isArray(dataOpt)) {\r
35503                         dataOpt = [dataOpt];\r
35504                     }\r
35505                     // Only use the first data item\r
35506                     list.initData(dataOpt);\r
35507                     return list;\r
35508                 },\r
35509 \r
35510                 defaultOption: {\r
35511                     zlevel: 0,\r
35512                     z: 2,\r
35513                     // 默认全局居中\r
35514                     center: ['50%', '50%'],\r
35515                     legendHoverLink: true,\r
35516                     radius: '75%',\r
35517                     startAngle: 225,\r
35518                     endAngle: -45,\r
35519                     clockwise: true,\r
35520                     // 最小值\r
35521                     min: 0,\r
35522                     // 最大值\r
35523                     max: 100,\r
35524                     // 分割段数,默认为10\r
35525                     splitNumber: 10,\r
35526                     // 坐标轴线\r
35527                     axisLine: {\r
35528                         // 默认显示,属性show控制显示与否\r
35529                         show: true,\r
35530                         lineStyle: {       // 属性lineStyle控制线条样式\r
35531                             color: [[0.2, '#91c7ae'], [0.8, '#63869e'], [1, '#c23531']],\r
35532                             width: 30\r
35533                         }\r
35534                     },\r
35535                     // 分隔线\r
35536                     splitLine: {\r
35537                         // 默认显示,属性show控制显示与否\r
35538                         show: true,\r
35539                         // 属性length控制线长\r
35540                         length: 30,\r
35541                         // 属性lineStyle(详见lineStyle)控制线条样式\r
35542                         lineStyle: {\r
35543                             color: '#eee',\r
35544                             width: 2,\r
35545                             type: 'solid'\r
35546                         }\r
35547                     },\r
35548                     // 坐标轴小标记\r
35549                     axisTick: {\r
35550                         // 属性show控制显示与否,默认不显示\r
35551                         show: true,\r
35552                         // 每份split细分多少段\r
35553                         splitNumber: 5,\r
35554                         // 属性length控制线长\r
35555                         length: 8,\r
35556                         // 属性lineStyle控制线条样式\r
35557                         lineStyle: {\r
35558                             color: '#eee',\r
35559                             width: 1,\r
35560                             type: 'solid'\r
35561                         }\r
35562                     },\r
35563                     axisLabel: {\r
35564                         show: true,\r
35565                         // formatter: null,\r
35566                         textStyle: {       // 其余属性默认使用全局文本样式,详见TEXTSTYLE\r
35567                             color: 'auto'\r
35568                         }\r
35569                     },\r
35570                     pointer: {\r
35571                         show: true,\r
35572                         length: '80%',\r
35573                         width: 8\r
35574                     },\r
35575                     itemStyle: {\r
35576                         normal: {\r
35577                             color: 'auto'\r
35578                         }\r
35579                     },\r
35580                     title: {\r
35581                         show: true,\r
35582                         // x, y,单位px\r
35583                         offsetCenter: [0, '-40%'],\r
35584                         // 其余属性默认使用全局文本样式,详见TEXTSTYLE\r
35585                         textStyle: {\r
35586                             color: '#333',\r
35587                             fontSize: 15\r
35588                         }\r
35589                     },\r
35590                     detail: {\r
35591                         show: true,\r
35592                         backgroundColor: 'rgba(0,0,0,0)',\r
35593                         borderWidth: 0,\r
35594                         borderColor: '#ccc',\r
35595                         width: 100,\r
35596                         height: 40,\r
35597                         // x, y,单位px\r
35598                         offsetCenter: [0, '40%'],\r
35599                         // formatter: null,\r
35600                         // 其余属性默认使用全局文本样式,详见TEXTSTYLE\r
35601                         textStyle: {\r
35602                             color: 'auto',\r
35603                             fontSize: 30\r
35604                         }\r
35605                     }\r
35606                 }\r
35607             });\r
35608 \r
35609             module.exports = GaugeSeries;\r
35610 \r
35611 \r
35612 /***/ },\r
35613 /* 209 */\r
35614 /***/ function(module, exports, __webpack_require__) {\r
35615 \r
35616         \r
35617 \r
35618             var PointerPath = __webpack_require__(210);\r
35619 \r
35620             var graphic = __webpack_require__(42);\r
35621             var numberUtil = __webpack_require__(7);\r
35622             var parsePercent = numberUtil.parsePercent;\r
35623 \r
35624             function parsePosition(seriesModel, api) {\r
35625                 var center = seriesModel.get('center');\r
35626                 var width = api.getWidth();\r
35627                 var height = api.getHeight();\r
35628                 var size = Math.min(width, height);\r
35629                 var cx = parsePercent(center[0], api.getWidth());\r
35630                 var cy = parsePercent(center[1], api.getHeight());\r
35631                 var r = parsePercent(seriesModel.get('radius'), size / 2);\r
35632 \r
35633                 return {\r
35634                     cx: cx,\r
35635                     cy: cy,\r
35636                     r: r\r
35637                 };\r
35638             }\r
35639 \r
35640             function formatLabel(label, labelFormatter) {\r
35641                 if (labelFormatter) {\r
35642                     if (typeof labelFormatter === 'string') {\r
35643                         label = labelFormatter.replace('{value}', label);\r
35644                     }\r
35645                     else if (typeof labelFormatter === 'function') {\r
35646                         label = labelFormatter(label);\r
35647                     }\r
35648                 }\r
35649 \r
35650                 return label;\r
35651             }\r
35652 \r
35653             var PI2 = Math.PI * 2;\r
35654 \r
35655             var GaugeView = __webpack_require__(41).extend({\r
35656 \r
35657                 type: 'gauge',\r
35658 \r
35659                 render: function (seriesModel, ecModel, api) {\r
35660 \r
35661                     this.group.removeAll();\r
35662 \r
35663                     var colorList = seriesModel.get('axisLine.lineStyle.color');\r
35664                     var posInfo = parsePosition(seriesModel, api);\r
35665 \r
35666                     this._renderMain(\r
35667                         seriesModel, ecModel, api, colorList, posInfo\r
35668                     );\r
35669                 },\r
35670 \r
35671                 _renderMain: function (seriesModel, ecModel, api, colorList, posInfo) {\r
35672                     var group = this.group;\r
35673 \r
35674                     var axisLineModel = seriesModel.getModel('axisLine');\r
35675                     var lineStyleModel = axisLineModel.getModel('lineStyle');\r
35676 \r
35677                     var clockwise = seriesModel.get('clockwise');\r
35678                     var startAngle = -seriesModel.get('startAngle') / 180 * Math.PI;\r
35679                     var endAngle = -seriesModel.get('endAngle') / 180 * Math.PI;\r
35680 \r
35681                     var angleRangeSpan = (endAngle - startAngle) % PI2;\r
35682 \r
35683                     var prevEndAngle = startAngle;\r
35684                     var axisLineWidth = lineStyleModel.get('width');\r
35685 \r
35686                     for (var i = 0; i < colorList.length; i++) {\r
35687                         var endAngle = startAngle + angleRangeSpan * colorList[i][0];\r
35688                         var sector = new graphic.Sector({\r
35689                             shape: {\r
35690                                 startAngle: prevEndAngle,\r
35691                                 endAngle: endAngle,\r
35692                                 cx: posInfo.cx,\r
35693                                 cy: posInfo.cy,\r
35694                                 clockwise: clockwise,\r
35695                                 r0: posInfo.r - axisLineWidth,\r
35696                                 r: posInfo.r\r
35697                             },\r
35698                             silent: true\r
35699                         });\r
35700 \r
35701                         sector.setStyle({\r
35702                             fill: colorList[i][1]\r
35703                         });\r
35704 \r
35705                         sector.setStyle(lineStyleModel.getLineStyle(\r
35706                             // Because we use sector to simulate arc\r
35707                             // so the properties for stroking are useless\r
35708                             ['color', 'borderWidth', 'borderColor']\r
35709                         ));\r
35710 \r
35711                         group.add(sector);\r
35712 \r
35713                         prevEndAngle = endAngle;\r
35714                     }\r
35715 \r
35716                     var getColor = function (percent) {\r
35717                         // Less than 0\r
35718                         if (percent <= 0) {\r
35719                             return colorList[0][1];\r
35720                         }\r
35721                         for (var i = 0; i < colorList.length; i++) {\r
35722                             if (colorList[i][0] >= percent\r
35723                                 && (i === 0 ? 0 : colorList[i - 1][0]) < percent\r
35724                             ) {\r
35725                                 return colorList[i][1];\r
35726                             }\r
35727                         }\r
35728                         // More than 1\r
35729                         return colorList[i - 1][1];\r
35730                     };\r
35731 \r
35732                     if (!clockwise) {\r
35733                         var tmp = startAngle;\r
35734                         startAngle = endAngle;\r
35735                         endAngle = tmp;\r
35736                     }\r
35737 \r
35738                     this._renderTicks(\r
35739                         seriesModel, ecModel, api, getColor, posInfo,\r
35740                         startAngle, endAngle, clockwise\r
35741                     );\r
35742 \r
35743                     this._renderPointer(\r
35744                         seriesModel, ecModel, api, getColor, posInfo,\r
35745                         startAngle, endAngle, clockwise\r
35746                     );\r
35747 \r
35748                     this._renderTitle(\r
35749                         seriesModel, ecModel, api, getColor, posInfo\r
35750                     );\r
35751                     this._renderDetail(\r
35752                         seriesModel, ecModel, api, getColor, posInfo\r
35753                     );\r
35754                 },\r
35755 \r
35756                 _renderTicks: function (\r
35757                     seriesModel, ecModel, api, getColor, posInfo,\r
35758                     startAngle, endAngle, clockwise\r
35759                 ) {\r
35760                     var group = this.group;\r
35761                     var cx = posInfo.cx;\r
35762                     var cy = posInfo.cy;\r
35763                     var r = posInfo.r;\r
35764 \r
35765                     var minVal = seriesModel.get('min');\r
35766                     var maxVal = seriesModel.get('max');\r
35767 \r
35768                     var splitLineModel = seriesModel.getModel('splitLine');\r
35769                     var tickModel = seriesModel.getModel('axisTick');\r
35770                     var labelModel = seriesModel.getModel('axisLabel');\r
35771 \r
35772                     var splitNumber = seriesModel.get('splitNumber');\r
35773                     var subSplitNumber = tickModel.get('splitNumber');\r
35774 \r
35775                     var splitLineLen = parsePercent(\r
35776                         splitLineModel.get('length'), r\r
35777                     );\r
35778                     var tickLen = parsePercent(\r
35779                         tickModel.get('length'), r\r
35780                     );\r
35781 \r
35782                     var angle = startAngle;\r
35783                     var step = (endAngle - startAngle) / splitNumber;\r
35784                     var subStep = step / subSplitNumber;\r
35785 \r
35786                     var splitLineStyle = splitLineModel.getModel('lineStyle').getLineStyle();\r
35787                     var tickLineStyle = tickModel.getModel('lineStyle').getLineStyle();\r
35788                     var textStyleModel = labelModel.getModel('textStyle');\r
35789 \r
35790                     for (var i = 0; i <= splitNumber; i++) {\r
35791                         var unitX = Math.cos(angle);\r
35792                         var unitY = Math.sin(angle);\r
35793                         // Split line\r
35794                         if (splitLineModel.get('show')) {\r
35795                             var splitLine = new graphic.Line({\r
35796                                 shape: {\r
35797                                     x1: unitX * r + cx,\r
35798                                     y1: unitY * r + cy,\r
35799                                     x2: unitX * (r - splitLineLen) + cx,\r
35800                                     y2: unitY * (r - splitLineLen) + cy\r
35801                                 },\r
35802                                 style: splitLineStyle,\r
35803                                 silent: true\r
35804                             });\r
35805                             if (splitLineStyle.stroke === 'auto') {\r
35806                                 splitLine.setStyle({\r
35807                                     stroke: getColor(i / splitNumber)\r
35808                                 });\r
35809                             }\r
35810 \r
35811                             group.add(splitLine);\r
35812                         }\r
35813 \r
35814                         // Label\r
35815                         if (labelModel.get('show')) {\r
35816                             var label = formatLabel(\r
35817                                 numberUtil.round(i / splitNumber * (maxVal - minVal) + minVal),\r
35818                                 labelModel.get('formatter')\r
35819                             );\r
35820 \r
35821                             var text = new graphic.Text({\r
35822                                 style: {\r
35823                                     text: label,\r
35824                                     x: unitX * (r - splitLineLen - 5) + cx,\r
35825                                     y: unitY * (r - splitLineLen - 5) + cy,\r
35826                                     fill: textStyleModel.getTextColor(),\r
35827                                     textFont: textStyleModel.getFont(),\r
35828                                     textVerticalAlign: unitY < -0.4 ? 'top' : (unitY > 0.4 ? 'bottom' : 'middle'),\r
35829                                     textAlign: unitX < -0.4 ? 'left' : (unitX > 0.4 ? 'right' : 'center')\r
35830                                 },\r
35831                                 silent: true\r
35832                             });\r
35833                             if (text.style.fill === 'auto') {\r
35834                                 text.setStyle({\r
35835                                     fill: getColor(i / splitNumber)\r
35836                                 });\r
35837                             }\r
35838 \r
35839                             group.add(text);\r
35840                         }\r
35841 \r
35842                         // Axis tick\r
35843                         if (tickModel.get('show') && i !== splitNumber) {\r
35844                             for (var j = 0; j <= subSplitNumber; j++) {\r
35845                                 var unitX = Math.cos(angle);\r
35846                                 var unitY = Math.sin(angle);\r
35847                                 var tickLine = new graphic.Line({\r
35848                                     shape: {\r
35849                                         x1: unitX * r + cx,\r
35850                                         y1: unitY * r + cy,\r
35851                                         x2: unitX * (r - tickLen) + cx,\r
35852                                         y2: unitY * (r - tickLen) + cy\r
35853                                     },\r
35854                                     silent: true,\r
35855                                     style: tickLineStyle\r
35856                                 });\r
35857 \r
35858                                 if (tickLineStyle.stroke === 'auto') {\r
35859                                     tickLine.setStyle({\r
35860                                         stroke: getColor((i + j / subSplitNumber) / splitNumber)\r
35861                                     });\r
35862                                 }\r
35863 \r
35864                                 group.add(tickLine);\r
35865                                 angle += subStep;\r
35866                             }\r
35867                             angle -= subStep;\r
35868                         }\r
35869                         else {\r
35870                             angle += step;\r
35871                         }\r
35872                     }\r
35873                 },\r
35874 \r
35875                 _renderPointer: function (\r
35876                     seriesModel, ecModel, api, getColor, posInfo,\r
35877                     startAngle, endAngle, clockwise\r
35878                 ) {\r
35879                     var linearMap = numberUtil.linearMap;\r
35880                     var valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];\r
35881                     var angleExtent = [startAngle, endAngle];\r
35882 \r
35883                     if (!clockwise) {\r
35884                         angleExtent = angleExtent.reverse();\r
35885                     }\r
35886 \r
35887                     var data = seriesModel.getData();\r
35888                     var oldData = this._data;\r
35889 \r
35890                     var group = this.group;\r
35891 \r
35892                     data.diff(oldData)\r
35893                         .add(function (idx) {\r
35894                             var pointer = new PointerPath({\r
35895                                 shape: {\r
35896                                     angle: startAngle\r
35897                                 }\r
35898                             });\r
35899 \r
35900                             graphic.updateProps(pointer, {\r
35901                                 shape: {\r
35902                                     angle: linearMap(data.get('value', idx), valueExtent, angleExtent)\r
35903                                 }\r
35904                             }, seriesModel);\r
35905 \r
35906                             group.add(pointer);\r
35907                             data.setItemGraphicEl(idx, pointer);\r
35908                         })\r
35909                         .update(function (newIdx, oldIdx) {\r
35910                             var pointer = oldData.getItemGraphicEl(oldIdx);\r
35911 \r
35912                             graphic.updateProps(pointer, {\r
35913                                 shape: {\r
35914                                     angle: linearMap(data.get('value', newIdx), valueExtent, angleExtent)\r
35915                                 }\r
35916                             }, seriesModel);\r
35917 \r
35918                             group.add(pointer);\r
35919                             data.setItemGraphicEl(newIdx, pointer);\r
35920                         })\r
35921                         .remove(function (idx) {\r
35922                             var pointer = oldData.getItemGraphicEl(idx);\r
35923                             group.remove(pointer);\r
35924                         })\r
35925                         .execute();\r
35926 \r
35927                     data.eachItemGraphicEl(function (pointer, idx) {\r
35928                         var itemModel = data.getItemModel(idx);\r
35929                         var pointerModel = itemModel.getModel('pointer');\r
35930 \r
35931                         pointer.attr({\r
35932                             shape: {\r
35933                                 x: posInfo.cx,\r
35934                                 y: posInfo.cy,\r
35935                                 width: parsePercent(\r
35936                                     pointerModel.get('width'), posInfo.r\r
35937                                 ),\r
35938                                 r: parsePercent(pointerModel.get('length'), posInfo.r)\r
35939                             },\r
35940                             style: itemModel.getModel('itemStyle.normal').getItemStyle()\r
35941                         });\r
35942 \r
35943                         if (pointer.style.fill === 'auto') {\r
35944                             pointer.setStyle('fill', getColor(\r
35945                                 (data.get('value', idx) - valueExtent[0]) / (valueExtent[1] - valueExtent[0])\r
35946                             ));\r
35947                         }\r
35948 \r
35949                         graphic.setHoverStyle(\r
35950                             pointer, itemModel.getModel('itemStyle.emphasis').getItemStyle()\r
35951                         );\r
35952                     });\r
35953 \r
35954                     this._data = data;\r
35955                 },\r
35956 \r
35957                 _renderTitle: function (\r
35958                     seriesModel, ecModel, api, getColor, posInfo\r
35959                 ) {\r
35960                     var titleModel = seriesModel.getModel('title');\r
35961                     if (titleModel.get('show')) {\r
35962                         var textStyleModel = titleModel.getModel('textStyle');\r
35963                         var offsetCenter = titleModel.get('offsetCenter');\r
35964                         var x = posInfo.cx + parsePercent(offsetCenter[0], posInfo.r);\r
35965                         var y = posInfo.cy + parsePercent(offsetCenter[1], posInfo.r);\r
35966                         var text = new graphic.Text({\r
35967                             style: {\r
35968                                 x: x,\r
35969                                 y: y,\r
35970                                 // FIXME First data name ?\r
35971                                 text: seriesModel.getData().getName(0),\r
35972                                 fill: textStyleModel.getTextColor(),\r
35973                                 textFont: textStyleModel.getFont(),\r
35974                                 textAlign: 'center',\r
35975                                 textVerticalAlign: 'middle'\r
35976                             }\r
35977                         });\r
35978                         this.group.add(text);\r
35979                     }\r
35980                 },\r
35981 \r
35982                 _renderDetail: function (\r
35983                     seriesModel, ecModel, api, getColor, posInfo\r
35984                 ) {\r
35985                     var detailModel = seriesModel.getModel('detail');\r
35986                     var minVal = seriesModel.get('min');\r
35987                     var maxVal = seriesModel.get('max');\r
35988                     if (detailModel.get('show')) {\r
35989                         var textStyleModel = detailModel.getModel('textStyle');\r
35990                         var offsetCenter = detailModel.get('offsetCenter');\r
35991                         var x = posInfo.cx + parsePercent(offsetCenter[0], posInfo.r);\r
35992                         var y = posInfo.cy + parsePercent(offsetCenter[1], posInfo.r);\r
35993                         var width = parsePercent(detailModel.get('width'), posInfo.r);\r
35994                         var height = parsePercent(detailModel.get('height'), posInfo.r);\r
35995                         var value = seriesModel.getData().get('value', 0);\r
35996                         var rect = new graphic.Rect({\r
35997                             shape: {\r
35998                                 x: x - width / 2,\r
35999                                 y: y - height / 2,\r
36000                                 width: width,\r
36001                                 height: height\r
36002                             },\r
36003                             style: {\r
36004                                 text: formatLabel(\r
36005                                     // FIXME First data name ?\r
36006                                     value, detailModel.get('formatter')\r
36007                                 ),\r
36008                                 fill: detailModel.get('backgroundColor'),\r
36009                                 textFill: textStyleModel.getTextColor(),\r
36010                                 textFont: textStyleModel.getFont()\r
36011                             }\r
36012                         });\r
36013                         if (rect.style.textFill === 'auto') {\r
36014                             rect.setStyle('textFill', getColor((value - minVal) / (maxVal - minVal)));\r
36015                         }\r
36016                         rect.setStyle(detailModel.getItemStyle(['color']));\r
36017                         this.group.add(rect);\r
36018                     }\r
36019                 }\r
36020             });\r
36021 \r
36022             module.exports = GaugeView;\r
36023 \r
36024 \r
36025 /***/ },\r
36026 /* 210 */\r
36027 /***/ function(module, exports, __webpack_require__) {\r
36028 \r
36029         \r
36030 \r
36031             module.exports = __webpack_require__(44).extend({\r
36032 \r
36033                 type: 'echartsGaugePointer',\r
36034 \r
36035                 shape: {\r
36036                     angle: 0,\r
36037 \r
36038                     width: 10,\r
36039 \r
36040                     r: 10,\r
36041 \r
36042                     x: 0,\r
36043 \r
36044                     y: 0\r
36045                 },\r
36046 \r
36047                 buildPath: function (ctx, shape) {\r
36048                     var mathCos = Math.cos;\r
36049                     var mathSin = Math.sin;\r
36050 \r
36051                     var r = shape.r;\r
36052                     var width = shape.width;\r
36053                     var angle = shape.angle;\r
36054                     var x = shape.x - mathCos(angle) * width * (width >= r / 3 ? 1 : 2);\r
36055                     var y = shape.y - mathSin(angle) * width * (width >= r / 3 ? 1 : 2);\r
36056 \r
36057                     angle = shape.angle - Math.PI / 2;\r
36058                     ctx.moveTo(x, y);\r
36059                     ctx.lineTo(\r
36060                         shape.x + mathCos(angle) * width,\r
36061                         shape.y + mathSin(angle) * width\r
36062                     );\r
36063                     ctx.lineTo(\r
36064                         shape.x + mathCos(shape.angle) * r,\r
36065                         shape.y + mathSin(shape.angle) * r\r
36066                     );\r
36067                     ctx.lineTo(\r
36068                         shape.x - mathCos(angle) * width,\r
36069                         shape.y - mathSin(angle) * width\r
36070                     );\r
36071                     ctx.lineTo(x, y);\r
36072                     return;\r
36073                 }\r
36074             });\r
36075 \r
36076 \r
36077 /***/ },\r
36078 /* 211 */\r
36079 /***/ function(module, exports, __webpack_require__) {\r
36080 \r
36081         \r
36082 \r
36083             var zrUtil = __webpack_require__(3);\r
36084             var echarts = __webpack_require__(1);\r
36085 \r
36086             __webpack_require__(212);\r
36087             __webpack_require__(213);\r
36088 \r
36089             echarts.registerVisualCoding(\r
36090                 'chart',  zrUtil.curry(__webpack_require__(137), 'funnel')\r
36091             );\r
36092             echarts.registerLayout(__webpack_require__(214));\r
36093 \r
36094             echarts.registerProcessor(\r
36095                 'filter', zrUtil.curry(__webpack_require__(140), 'funnel')\r
36096             );\r
36097 \r
36098 \r
36099 /***/ },\r
36100 /* 212 */\r
36101 /***/ function(module, exports, __webpack_require__) {\r
36102 \r
36103         'use strict';\r
36104 \r
36105 \r
36106             var List = __webpack_require__(94);\r
36107             var modelUtil = __webpack_require__(5);\r
36108             var completeDimensions = __webpack_require__(96);\r
36109 \r
36110             var FunnelSeries = __webpack_require__(1).extendSeriesModel({\r
36111 \r
36112                 type: 'series.funnel',\r
36113 \r
36114                 init: function (option) {\r
36115                     FunnelSeries.superApply(this, 'init', arguments);\r
36116 \r
36117                     // Enable legend selection for each data item\r
36118                     // Use a function instead of direct access because data reference may changed\r
36119                     this.legendDataProvider = function () {\r
36120                         return this._dataBeforeProcessed;\r
36121                     };\r
36122                     // Extend labelLine emphasis\r
36123                     this._defaultLabelLine(option);\r
36124                 },\r
36125 \r
36126                 getInitialData: function (option, ecModel) {\r
36127                     var dimensions = completeDimensions(['value'], option.data);\r
36128                     var list = new List(dimensions, this);\r
36129                     list.initData(option.data);\r
36130                     return list;\r
36131                 },\r
36132 \r
36133                 _defaultLabelLine: function (option) {\r
36134                     // Extend labelLine emphasis\r
36135                     modelUtil.defaultEmphasis(option.labelLine, ['show']);\r
36136 \r
36137                     var labelLineNormalOpt = option.labelLine.normal;\r
36138                     var labelLineEmphasisOpt = option.labelLine.emphasis;\r
36139                     // Not show label line if `label.normal.show = false`\r
36140                     labelLineNormalOpt.show = labelLineNormalOpt.show\r
36141                         && option.label.normal.show;\r
36142                     labelLineEmphasisOpt.show = labelLineEmphasisOpt.show\r
36143                         && option.label.emphasis.show;\r
36144                 },\r
36145 \r
36146                 defaultOption: {\r
36147                     zlevel: 0,                  // 一级层叠\r
36148                     z: 2,                       // 二级层叠\r
36149                     legendHoverLink: true,\r
36150                     left: 80,\r
36151                     top: 60,\r
36152                     right: 80,\r
36153                     bottom: 60,\r
36154                     // width: {totalWidth} - left - right,\r
36155                     // height: {totalHeight} - top - bottom,\r
36156 \r
36157                     // 默认取数据最小最大值\r
36158                     // min: 0,\r
36159                     // max: 100,\r
36160                     minSize: '0%',\r
36161                     maxSize: '100%',\r
36162                     sort: 'descending', // 'ascending', 'descending'\r
36163                     gap: 0,\r
36164                     funnelAlign: 'center',\r
36165                     label: {\r
36166                         normal: {\r
36167                             show: true,\r
36168                             position: 'outer'\r
36169                             // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
36170                             // textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE\r
36171                         },\r
36172                         emphasis: {\r
36173                             show: true\r
36174                         }\r
36175                     },\r
36176                     labelLine: {\r
36177                         normal: {\r
36178                             show: true,\r
36179                             length: 20,\r
36180                             lineStyle: {\r
36181                                 // color: 各异,\r
36182                                 width: 1,\r
36183                                 type: 'solid'\r
36184                             }\r
36185                         },\r
36186                         emphasis: {}\r
36187                     },\r
36188                     itemStyle: {\r
36189                         normal: {\r
36190                             // color: 各异,\r
36191                             borderColor: '#fff',\r
36192                             borderWidth: 1\r
36193                         },\r
36194                         emphasis: {\r
36195                             // color: 各异,\r
36196                         }\r
36197                     }\r
36198                 }\r
36199             });\r
36200 \r
36201             module.exports = FunnelSeries;\r
36202 \r
36203 \r
36204 /***/ },\r
36205 /* 213 */\r
36206 /***/ function(module, exports, __webpack_require__) {\r
36207 \r
36208         \r
36209 \r
36210             var graphic = __webpack_require__(42);\r
36211             var zrUtil = __webpack_require__(3);\r
36212 \r
36213             /**\r
36214              * Piece of pie including Sector, Label, LabelLine\r
36215              * @constructor\r
36216              * @extends {module:zrender/graphic/Group}\r
36217              */\r
36218             function FunnelPiece(data, idx) {\r
36219 \r
36220                 graphic.Group.call(this);\r
36221 \r
36222                 var polygon = new graphic.Polygon();\r
36223                 var labelLine = new graphic.Polyline();\r
36224                 var text = new graphic.Text();\r
36225                 this.add(polygon);\r
36226                 this.add(labelLine);\r
36227                 this.add(text);\r
36228 \r
36229                 this.updateData(data, idx, true);\r
36230 \r
36231                 // Hover to change label and labelLine\r
36232                 function onEmphasis() {\r
36233                     labelLine.ignore = labelLine.hoverIgnore;\r
36234                     text.ignore = text.hoverIgnore;\r
36235                 }\r
36236                 function onNormal() {\r
36237                     labelLine.ignore = labelLine.normalIgnore;\r
36238                     text.ignore = text.normalIgnore;\r
36239                 }\r
36240                 this.on('emphasis', onEmphasis)\r
36241                     .on('normal', onNormal)\r
36242                     .on('mouseover', onEmphasis)\r
36243                     .on('mouseout', onNormal);\r
36244             }\r
36245 \r
36246             var funnelPieceProto = FunnelPiece.prototype;\r
36247 \r
36248             function getLabelStyle(data, idx, state, labelModel) {\r
36249                 var textStyleModel = labelModel.getModel('textStyle');\r
36250                 var position = labelModel.get('position');\r
36251                 var isLabelInside = position === 'inside' || position === 'inner' || position === 'center';\r
36252                 return {\r
36253                     fill: textStyleModel.getTextColor()\r
36254                         || (isLabelInside ? '#fff' : data.getItemVisual(idx, 'color')),\r
36255                     textFont: textStyleModel.getFont(),\r
36256                     text: zrUtil.retrieve(\r
36257                         data.hostModel.getFormattedLabel(idx, state),\r
36258                         data.getName(idx)\r
36259                     )\r
36260                 };\r
36261             }\r
36262 \r
36263             var opacityAccessPath = ['itemStyle', 'normal', 'opacity'];\r
36264             funnelPieceProto.updateData = function (data, idx, firstCreate) {\r
36265 \r
36266                 var polygon = this.childAt(0);\r
36267 \r
36268                 var seriesModel = data.hostModel;\r
36269                 var itemModel = data.getItemModel(idx);\r
36270                 var layout = data.getItemLayout(idx);\r
36271                 var opacity = data.getItemModel(idx).get(opacityAccessPath);\r
36272                 opacity = opacity == null ? 1 : opacity;\r
36273                 if (firstCreate) {\r
36274                     polygon.setShape({\r
36275                         points: layout.points\r
36276                     });\r
36277                     polygon.setStyle({ opacity : 0 });\r
36278                     graphic.updateProps(polygon, {\r
36279                         style: {\r
36280                             opacity: opacity\r
36281                         }\r
36282                     }, seriesModel);\r
36283                 }\r
36284                 else {\r
36285                     graphic.initProps(polygon, {\r
36286                         shape: {\r
36287                             points: layout.points\r
36288                         }\r
36289                     }, seriesModel);\r
36290                 }\r
36291 \r
36292                 // Update common style\r
36293                 var itemStyleModel = itemModel.getModel('itemStyle');\r
36294                 var visualColor = data.getItemVisual(idx, 'color');\r
36295 \r
36296                 polygon.setStyle(\r
36297                     zrUtil.defaults(\r
36298                         {\r
36299                             fill: visualColor\r
36300                         },\r
36301                         itemStyleModel.getModel('normal').getItemStyle()\r
36302                     )\r
36303                 );\r
36304                 polygon.hoverStyle = itemStyleModel.getModel('emphasis').getItemStyle();\r
36305 \r
36306                 this._updateLabel(data, idx);\r
36307 \r
36308                 graphic.setHoverStyle(this);\r
36309             };\r
36310 \r
36311             funnelPieceProto._updateLabel = function (data, idx) {\r
36312 \r
36313                 var labelLine = this.childAt(1);\r
36314                 var labelText = this.childAt(2);\r
36315 \r
36316                 var seriesModel = data.hostModel;\r
36317                 var itemModel = data.getItemModel(idx);\r
36318                 var layout = data.getItemLayout(idx);\r
36319                 var labelLayout = layout.label;\r
36320                 var visualColor = data.getItemVisual(idx, 'color');\r
36321 \r
36322                 graphic.updateProps(labelLine, {\r
36323                     shape: {\r
36324                         points: labelLayout.linePoints || labelLayout.linePoints\r
36325                     }\r
36326                 }, seriesModel);\r
36327 \r
36328                 graphic.updateProps(labelText, {\r
36329                     style: {\r
36330                         x: labelLayout.x,\r
36331                         y: labelLayout.y\r
36332                     }\r
36333                 }, seriesModel);\r
36334                 labelText.attr({\r
36335                     style: {\r
36336                         textAlign: labelLayout.textAlign,\r
36337                         textVerticalAlign: labelLayout.verticalAlign,\r
36338                         textFont: labelLayout.font\r
36339                     },\r
36340                     rotation: labelLayout.rotation,\r
36341                     origin: [labelLayout.x, labelLayout.y],\r
36342                     z2: 10\r
36343                 });\r
36344 \r
36345                 var labelModel = itemModel.getModel('label.normal');\r
36346                 var labelHoverModel = itemModel.getModel('label.emphasis');\r
36347                 var labelLineModel = itemModel.getModel('labelLine.normal');\r
36348                 var labelLineHoverModel = itemModel.getModel('labelLine.emphasis');\r
36349 \r
36350                 labelText.setStyle(getLabelStyle(data, idx, 'normal', labelModel));\r
36351 \r
36352                 labelText.ignore = labelText.normalIgnore = !labelModel.get('show');\r
36353                 labelText.hoverIgnore = !labelHoverModel.get('show');\r
36354 \r
36355                 labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show');\r
36356                 labelLine.hoverIgnore = !labelLineHoverModel.get('show');\r
36357 \r
36358                 // Default use item visual color\r
36359                 labelLine.setStyle({\r
36360                     stroke: visualColor\r
36361                 });\r
36362                 labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());\r
36363 \r
36364                 labelText.hoverStyle = getLabelStyle(data, idx, 'emphasis', labelHoverModel);\r
36365                 labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();\r
36366             };\r
36367 \r
36368             zrUtil.inherits(FunnelPiece, graphic.Group);\r
36369 \r
36370 \r
36371             var Funnel = __webpack_require__(41).extend({\r
36372 \r
36373                 type: 'funnel',\r
36374 \r
36375                 render: function (seriesModel, ecModel, api) {\r
36376                     var data = seriesModel.getData();\r
36377                     var oldData = this._data;\r
36378 \r
36379                     var group = this.group;\r
36380 \r
36381                     data.diff(oldData)\r
36382                         .add(function (idx) {\r
36383                             var funnelPiece = new FunnelPiece(data, idx);\r
36384 \r
36385                             data.setItemGraphicEl(idx, funnelPiece);\r
36386 \r
36387                             group.add(funnelPiece);\r
36388                         })\r
36389                         .update(function (newIdx, oldIdx) {\r
36390                             var piePiece = oldData.getItemGraphicEl(oldIdx);\r
36391 \r
36392                             piePiece.updateData(data, newIdx);\r
36393 \r
36394                             group.add(piePiece);\r
36395                             data.setItemGraphicEl(newIdx, piePiece);\r
36396                         })\r
36397                         .remove(function (idx) {\r
36398                             var piePiece = oldData.getItemGraphicEl(idx);\r
36399                             group.remove(piePiece);\r
36400                         })\r
36401                         .execute();\r
36402 \r
36403                     this._data = data;\r
36404                 },\r
36405 \r
36406                 remove: function () {\r
36407                     this.group.removeAll();\r
36408                     this._data = null;\r
36409                 }\r
36410             });\r
36411 \r
36412             module.exports = Funnel;\r
36413 \r
36414 \r
36415 /***/ },\r
36416 /* 214 */\r
36417 /***/ function(module, exports, __webpack_require__) {\r
36418 \r
36419         \r
36420 \r
36421             var layout = __webpack_require__(21);\r
36422             var number = __webpack_require__(7);\r
36423 \r
36424             var parsePercent = number.parsePercent;\r
36425 \r
36426             function getViewRect(seriesModel, api) {\r
36427                 return layout.getLayoutRect(\r
36428                     seriesModel.getBoxLayoutParams(), {\r
36429                         width: api.getWidth(),\r
36430                         height: api.getHeight()\r
36431                     }\r
36432                 );\r
36433             }\r
36434 \r
36435             function getSortedIndices(data, sort) {\r
36436                 var valueArr = data.mapArray('value', function (val) {\r
36437                     return val;\r
36438                 });\r
36439                 var indices = [];\r
36440                 var isAscending = sort === 'ascending';\r
36441                 for (var i = 0, len = data.count(); i < len; i++) {\r
36442                     indices[i] = i;\r
36443                 }\r
36444                 indices.sort(function (a, b) {\r
36445                     return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a];\r
36446                 });\r
36447                 return indices;\r
36448             }\r
36449 \r
36450             function labelLayout (data) {\r
36451                 data.each(function (idx) {\r
36452                     var itemModel = data.getItemModel(idx);\r
36453                     var labelModel = itemModel.getModel('label.normal');\r
36454                     var labelPosition = labelModel.get('position');\r
36455 \r
36456                     var labelLineModel = itemModel.getModel('labelLine.normal');\r
36457 \r
36458                     var layout = data.getItemLayout(idx);\r
36459                     var points = layout.points;\r
36460 \r
36461                     var isLabelInside = labelPosition === 'inner'\r
36462                         || labelPosition === 'inside' || labelPosition === 'center';\r
36463 \r
36464                     var textAlign;\r
36465                     var textX;\r
36466                     var textY;\r
36467                     var linePoints;\r
36468 \r
36469                     if (isLabelInside) {\r
36470                         textX = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4;\r
36471                         textY = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4;\r
36472                         textAlign = 'center';\r
36473                         linePoints = [\r
36474                             [textX, textY], [textX, textY]\r
36475                         ];\r
36476                     }\r
36477                     else {\r
36478                         var x1;\r
36479                         var y1;\r
36480                         var x2;\r
36481                         var labelLineLen = labelLineModel.get('length');\r
36482                         if (labelPosition === 'left') {\r
36483                             // Left side\r
36484                             x1 = (points[3][0] + points[0][0]) / 2;\r
36485                             y1 = (points[3][1] + points[0][1]) / 2;\r
36486                             x2 = x1 - labelLineLen;\r
36487                             textX = x2 - 5;\r
36488                             textAlign = 'right';\r
36489                         }\r
36490                         else {\r
36491                             // Right side\r
36492                             x1 = (points[1][0] + points[2][0]) / 2;\r
36493                             y1 = (points[1][1] + points[2][1]) / 2;\r
36494                             x2 = x1 + labelLineLen;\r
36495                             textX = x2 + 5;\r
36496                             textAlign = 'left';\r
36497                         }\r
36498                         var y2 = y1;\r
36499 \r
36500                         linePoints = [[x1, y1], [x2, y2]];\r
36501                         textY = y2;\r
36502                     }\r
36503 \r
36504                     layout.label = {\r
36505                         linePoints: linePoints,\r
36506                         x: textX,\r
36507                         y: textY,\r
36508                         verticalAlign: 'middle',\r
36509                         textAlign: textAlign,\r
36510                         inside: isLabelInside\r
36511                     };\r
36512                 });\r
36513             }\r
36514 \r
36515             module.exports = function (ecModel, api) {\r
36516                 ecModel.eachSeriesByType('funnel', function (seriesModel) {\r
36517                     var data = seriesModel.getData();\r
36518                     var sort = seriesModel.get('sort');\r
36519                     var viewRect = getViewRect(seriesModel, api);\r
36520                     var indices = getSortedIndices(data, sort);\r
36521 \r
36522                     var sizeExtent = [\r
36523                         parsePercent(seriesModel.get('minSize'), viewRect.width),\r
36524                         parsePercent(seriesModel.get('maxSize'), viewRect.width)\r
36525                     ];\r
36526                     var dataExtent = data.getDataExtent('value');\r
36527                     var min = seriesModel.get('min');\r
36528                     var max = seriesModel.get('max');\r
36529                     if (min == null) {\r
36530                         min = Math.min(dataExtent[0], 0);\r
36531                     }\r
36532                     if (max == null) {\r
36533                         max = dataExtent[1];\r
36534                     }\r
36535 \r
36536                     var funnelAlign = seriesModel.get('funnelAlign');\r
36537                     var gap = seriesModel.get('gap');\r
36538                     var itemHeight = (viewRect.height - gap * (data.count() - 1)) / data.count();\r
36539 \r
36540                     var y = viewRect.y;\r
36541 \r
36542                     var getLinePoints = function (idx, offY) {\r
36543                         // End point index is data.count() and we assign it 0\r
36544                         var val = data.get('value', idx) || 0;\r
36545                         var itemWidth = number.linearMap(val, [min, max], sizeExtent, true);\r
36546                         var x0;\r
36547                         switch (funnelAlign) {\r
36548                             case 'left':\r
36549                                 x0 = viewRect.x;\r
36550                                 break;\r
36551                             case 'center':\r
36552                                 x0 = viewRect.x + (viewRect.width - itemWidth) / 2;\r
36553                                 break;\r
36554                             case 'right':\r
36555                                 x0 = viewRect.x + viewRect.width - itemWidth;\r
36556                                 break;\r
36557                         }\r
36558                         return [\r
36559                             [x0, offY],\r
36560                             [x0 + itemWidth, offY]\r
36561                         ];\r
36562                     };\r
36563 \r
36564                     if (sort === 'ascending') {\r
36565                         // From bottom to top\r
36566                         itemHeight = -itemHeight;\r
36567                         gap = -gap;\r
36568                         y += viewRect.height;\r
36569                         indices = indices.reverse();\r
36570                     }\r
36571 \r
36572                     for (var i = 0; i < indices.length; i++) {\r
36573                         var idx = indices[i];\r
36574                         var nextIdx = indices[i + 1];\r
36575                         var start = getLinePoints(idx, y);\r
36576                         var end = getLinePoints(nextIdx, y + itemHeight);\r
36577 \r
36578                         y += itemHeight + gap;\r
36579 \r
36580                         data.setItemLayout(idx, {\r
36581                             points: start.concat(end.slice().reverse())\r
36582                         });\r
36583                     }\r
36584 \r
36585                     labelLayout(data);\r
36586                 });\r
36587             };\r
36588 \r
36589 \r
36590 /***/ },\r
36591 /* 215 */\r
36592 /***/ function(module, exports, __webpack_require__) {\r
36593 \r
36594         \r
36595 \r
36596             var echarts = __webpack_require__(1);\r
36597 \r
36598             __webpack_require__(216);\r
36599 \r
36600             __webpack_require__(227);\r
36601             __webpack_require__(228);\r
36602 \r
36603             echarts.registerVisualCoding('chart', __webpack_require__(229));\r
36604 \r
36605 \r
36606 \r
36607 /***/ },\r
36608 /* 216 */\r
36609 /***/ function(module, exports, __webpack_require__) {\r
36610 \r
36611         \r
36612 \r
36613             __webpack_require__(217);\r
36614             __webpack_require__(220);\r
36615             __webpack_require__(222);\r
36616 \r
36617             var echarts = __webpack_require__(1);\r
36618 \r
36619             // Parallel view\r
36620             echarts.extendComponentView({\r
36621                 type: 'parallel'\r
36622             });\r
36623 \r
36624             echarts.registerPreprocessor(\r
36625                 __webpack_require__(226)\r
36626             );\r
36627 \r
36628 \r
36629 \r
36630 /***/ },\r
36631 /* 217 */\r
36632 /***/ function(module, exports, __webpack_require__) {\r
36633 \r
36634         /**\r
36635          * Parallel coordinate system creater.\r
36636          */\r
36637 \r
36638 \r
36639             var Parallel = __webpack_require__(218);\r
36640 \r
36641             function create(ecModel, api) {\r
36642                 var coordSysList = [];\r
36643 \r
36644                 ecModel.eachComponent('parallel', function (parallelModel, idx) {\r
36645                     var coordSys = new Parallel(parallelModel, ecModel, api);\r
36646 \r
36647                     coordSys.name = 'parallel_' + idx;\r
36648                     coordSys.resize(parallelModel, api);\r
36649 \r
36650                     parallelModel.coordinateSystem = coordSys;\r
36651                     coordSys.model = parallelModel;\r
36652 \r
36653                     coordSysList.push(coordSys);\r
36654                 });\r
36655 \r
36656                 // Inject the coordinateSystems into seriesModel\r
36657                 ecModel.eachSeries(function (seriesModel) {\r
36658                     if (seriesModel.get('coordinateSystem') === 'parallel') {\r
36659                         var parallelIndex = seriesModel.get('parallelIndex');\r
36660                         seriesModel.coordinateSystem = coordSysList[parallelIndex];\r
36661                     }\r
36662                 });\r
36663 \r
36664                 return coordSysList;\r
36665             }\r
36666 \r
36667             __webpack_require__(25).register('parallel', {create: create});\r
36668 \r
36669 \r
36670 \r
36671 /***/ },\r
36672 /* 218 */\r
36673 /***/ function(module, exports, __webpack_require__) {\r
36674 \r
36675         /**\r
36676          * Parallel Coordinates\r
36677          * <https://en.wikipedia.org/wiki/Parallel_coordinates>\r
36678          */\r
36679 \r
36680 \r
36681             var layout = __webpack_require__(21);\r
36682             var axisHelper = __webpack_require__(108);\r
36683             var zrUtil = __webpack_require__(3);\r
36684             var ParallelAxis = __webpack_require__(219);\r
36685             var matrix = __webpack_require__(17);\r
36686             var vector = __webpack_require__(16);\r
36687 \r
36688             var each = zrUtil.each;\r
36689 \r
36690             var PI = Math.PI;\r
36691 \r
36692             function Parallel(parallelModel, ecModel, api) {\r
36693 \r
36694                 /**\r
36695                  * key: dimension\r
36696                  * @type {Object.<string, module:echarts/coord/parallel/Axis>}\r
36697                  * @private\r
36698                  */\r
36699                 this._axesMap = {};\r
36700 \r
36701                 /**\r
36702                  * key: dimension\r
36703                  * value: {position: [], rotation, }\r
36704                  * @type {Object.<string, Object>}\r
36705                  * @private\r
36706                  */\r
36707                 this._axesLayout = {};\r
36708 \r
36709                 /**\r
36710                  * Always follow axis order.\r
36711                  * @type {Array.<string>}\r
36712                  * @readOnly\r
36713                  */\r
36714                 this.dimensions = parallelModel.dimensions;\r
36715 \r
36716                 /**\r
36717                  * @type {module:zrender/core/BoundingRect}\r
36718                  */\r
36719                 this._rect;\r
36720 \r
36721                 /**\r
36722                  * @type {module:echarts/coord/parallel/ParallelModel}\r
36723                  */\r
36724                 this._model = parallelModel;\r
36725 \r
36726                 this._init(parallelModel, ecModel, api);\r
36727             }\r
36728 \r
36729             Parallel.prototype = {\r
36730 \r
36731                 type: 'parallel',\r
36732 \r
36733                 constructor: Parallel,\r
36734 \r
36735                 /**\r
36736                  * Initialize cartesian coordinate systems\r
36737                  * @private\r
36738                  */\r
36739                 _init: function (parallelModel, ecModel, api) {\r
36740 \r
36741                     var dimensions = parallelModel.dimensions;\r
36742                     var parallelAxisIndex = parallelModel.parallelAxisIndex;\r
36743 \r
36744                     each(dimensions, function (dim, idx) {\r
36745 \r
36746                         var axisIndex = parallelAxisIndex[idx];\r
36747                         var axisModel = ecModel.getComponent('parallelAxis', axisIndex);\r
36748 \r
36749                         var axis = this._axesMap[dim] = new ParallelAxis(\r
36750                             dim,\r
36751                             axisHelper.createScaleByModel(axisModel),\r
36752                             [0, 0],\r
36753                             axisModel.get('type'),\r
36754                             axisIndex\r
36755                         );\r
36756 \r
36757                         var isCategory = axis.type === 'category';\r
36758                         axis.onBand = isCategory && axisModel.get('boundaryGap');\r
36759                         axis.inverse = axisModel.get('inverse');\r
36760 \r
36761                         // Inject axis into axisModel\r
36762                         axisModel.axis = axis;\r
36763 \r
36764                         // Inject axisModel into axis\r
36765                         axis.model = axisModel;\r
36766                     }, this);\r
36767                 },\r
36768 \r
36769                 /**\r
36770                  * Update axis scale after data processed\r
36771                  * @param  {module:echarts/model/Global} ecModel\r
36772                  * @param  {module:echarts/ExtensionAPI} api\r
36773                  */\r
36774                 update: function (ecModel, api) {\r
36775                     this._updateAxesFromSeries(this._model, ecModel);\r
36776                 },\r
36777 \r
36778                 /**\r
36779                  * Update properties from series\r
36780                  * @private\r
36781                  */\r
36782                 _updateAxesFromSeries: function (parallelModel, ecModel) {\r
36783                     ecModel.eachSeries(function (seriesModel) {\r
36784 \r
36785                         if (!parallelModel.contains(seriesModel, ecModel)) {\r
36786                             return;\r
36787                         }\r
36788 \r
36789                         var data = seriesModel.getData();\r
36790 \r
36791                         each(this.dimensions, function (dim) {\r
36792                             var axis = this._axesMap[dim];\r
36793                             axis.scale.unionExtent(data.getDataExtent(dim));\r
36794                             axisHelper.niceScaleExtent(axis, axis.model);\r
36795                         }, this);\r
36796                     }, this);\r
36797                 },\r
36798 \r
36799                 /**\r
36800                  * Resize the parallel coordinate system.\r
36801                  * @param {module:echarts/coord/parallel/ParallelModel} parallelModel\r
36802                  * @param {module:echarts/ExtensionAPI} api\r
36803                  */\r
36804                 resize: function (parallelModel, api) {\r
36805                     this._rect = layout.getLayoutRect(\r
36806                         parallelModel.getBoxLayoutParams(),\r
36807                         {\r
36808                             width: api.getWidth(),\r
36809                             height: api.getHeight()\r
36810                         }\r
36811                     );\r
36812 \r
36813                     this._layoutAxes(parallelModel);\r
36814                 },\r
36815 \r
36816                 /**\r
36817                  * @return {module:zrender/core/BoundingRect}\r
36818                  */\r
36819                 getRect: function () {\r
36820                     return this._rect;\r
36821                 },\r
36822 \r
36823                 /**\r
36824                  * @private\r
36825                  */\r
36826                 _layoutAxes: function (parallelModel) {\r
36827                     var rect = this._rect;\r
36828                     var layout = parallelModel.get('layout');\r
36829                     var axes = this._axesMap;\r
36830                     var dimensions = this.dimensions;\r
36831 \r
36832                     var size = [rect.width, rect.height];\r
36833                     var sizeIdx = layout === 'horizontal' ? 0 : 1;\r
36834                     var layoutLength = size[sizeIdx];\r
36835                     var axisLength = size[1 - sizeIdx];\r
36836                     var axisExtent = [0, axisLength];\r
36837 \r
36838                     each(axes, function (axis) {\r
36839                         var idx = axis.inverse ? 1 : 0;\r
36840                         axis.setExtent(axisExtent[idx], axisExtent[1 - idx]);\r
36841                     });\r
36842 \r
36843                     each(dimensions, function (dim, idx) {\r
36844                         var pos = layoutLength * idx / (dimensions.length - 1);\r
36845 \r
36846                         var positionTable = {\r
36847                             horizontal: {\r
36848                                 x: pos,\r
36849                                 y: axisLength\r
36850                             },\r
36851                             vertical: {\r
36852                                 x: 0,\r
36853                                 y: pos\r
36854                             }\r
36855                         };\r
36856                         var rotationTable = {\r
36857                             horizontal: PI / 2,\r
36858                             vertical: 0\r
36859                         };\r
36860 \r
36861                         var position = [\r
36862                             positionTable[layout].x + rect.x,\r
36863                             positionTable[layout].y + rect.y\r
36864                         ];\r
36865 \r
36866                         var rotation = rotationTable[layout];\r
36867                         var transform = matrix.create();\r
36868                         matrix.rotate(transform, transform, rotation);\r
36869                         matrix.translate(transform, transform, position);\r
36870 \r
36871                         // TODO\r
36872                         // tick等排布信息。\r
36873 \r
36874                         // TODO\r
36875                         // 根据axis order 更新 dimensions顺序。\r
36876 \r
36877                         this._axesLayout[dim] = {\r
36878                             position: position,\r
36879                             rotation: rotation,\r
36880                             transform: transform,\r
36881                             tickDirection: 1,\r
36882                             labelDirection: 1\r
36883                         };\r
36884                     }, this);\r
36885                 },\r
36886 \r
36887                 /**\r
36888                  * Get axis by dim.\r
36889                  * @param {string} dim\r
36890                  * @return {module:echarts/coord/parallel/ParallelAxis} [description]\r
36891                  */\r
36892                 getAxis: function (dim) {\r
36893                     return this._axesMap[dim];\r
36894                 },\r
36895 \r
36896                 /**\r
36897                  * Convert a dim value of a single item of series data to Point.\r
36898                  * @param {*} value\r
36899                  * @param {string} dim\r
36900                  * @return {Array}\r
36901                  */\r
36902                 dataToPoint: function (value, dim) {\r
36903                     return this.axisCoordToPoint(\r
36904                         this._axesMap[dim].dataToCoord(value),\r
36905                         dim\r
36906                     );\r
36907                 },\r
36908 \r
36909                 /**\r
36910                  * @param {module:echarts/data/List} data\r
36911                  * @param {Functio} cb param: {string} activeState 'active' or 'inactive' or 'normal'\r
36912                  *                            {number} dataIndex\r
36913                  * @param {Object} context\r
36914                  */\r
36915                 eachActiveState: function (data, callback, context) {\r
36916                     var dimensions = this.dimensions;\r
36917                     var axesMap = this._axesMap;\r
36918                     var hasActiveSet = false;\r
36919 \r
36920                     for (var j = 0, lenj = dimensions.length; j < lenj; j++) {\r
36921                         if (axesMap[dimensions[j]].model.getActiveState() !== 'normal') {\r
36922                             hasActiveSet = true;\r
36923                         }\r
36924                     }\r
36925 \r
36926                     for (var i = 0, len = data.count(); i < len; i++) {\r
36927                         var values = data.getValues(dimensions, i);\r
36928                         var activeState;\r
36929 \r
36930                         if (!hasActiveSet) {\r
36931                             activeState = 'normal';\r
36932                         }\r
36933                         else {\r
36934                             activeState = 'active';\r
36935                             for (var j = 0, lenj = dimensions.length; j < lenj; j++) {\r
36936                                 var dimName = dimensions[j];\r
36937                                 var state = axesMap[dimName].model.getActiveState(values[j], j);\r
36938 \r
36939                                 if (state === 'inactive') {\r
36940                                     activeState = 'inactive';\r
36941                                     break;\r
36942                                 }\r
36943                             }\r
36944                         }\r
36945 \r
36946                         callback.call(context, activeState, i);\r
36947                     }\r
36948                 },\r
36949 \r
36950                 /**\r
36951                  * Convert coords of each axis to Point.\r
36952                  *  Return point. For example: [10, 20]\r
36953                  * @param {Array.<number>} coords\r
36954                  * @param {string} dim\r
36955                  * @return {Array.<number>}\r
36956                  */\r
36957                 axisCoordToPoint: function (coord, dim) {\r
36958                     var axisLayout = this._axesLayout[dim];\r
36959                     var point = [coord, 0];\r
36960                     vector.applyTransform(point, point, axisLayout.transform);\r
36961                     return point;\r
36962                 },\r
36963 \r
36964                 /**\r
36965                  * Get axis layout.\r
36966                  */\r
36967                 getAxisLayout: function (dim) {\r
36968                     return zrUtil.clone(this._axesLayout[dim]);\r
36969                 }\r
36970 \r
36971             };\r
36972 \r
36973             module.exports = Parallel;\r
36974 \r
36975 \r
36976 /***/ },\r
36977 /* 219 */\r
36978 /***/ function(module, exports, __webpack_require__) {\r
36979 \r
36980         \r
36981 \r
36982             var zrUtil = __webpack_require__(3);\r
36983             var Axis = __webpack_require__(117);\r
36984 \r
36985             /**\r
36986              * @constructor module:echarts/coord/parallel/ParallelAxis\r
36987              * @extends {module:echarts/coord/Axis}\r
36988              * @param {string} dim\r
36989              * @param {*} scale\r
36990              * @param {Array.<number>} coordExtent\r
36991              * @param {string} axisType\r
36992              */\r
36993             var ParallelAxis = function (dim, scale, coordExtent, axisType, axisIndex) {\r
36994 \r
36995                 Axis.call(this, dim, scale, coordExtent);\r
36996 \r
36997                 /**\r
36998                  * Axis type\r
36999                  *  - 'category'\r
37000                  *  - 'value'\r
37001                  *  - 'time'\r
37002                  *  - 'log'\r
37003                  * @type {string}\r
37004                  */\r
37005                 this.type = axisType || 'value';\r
37006 \r
37007                 /**\r
37008                  * @type {number}\r
37009                  * @readOnly\r
37010                  */\r
37011                 this.axisIndex = axisIndex;\r
37012             };\r
37013 \r
37014             ParallelAxis.prototype = {\r
37015 \r
37016                 constructor: ParallelAxis,\r
37017 \r
37018                 /**\r
37019                  * Axis model\r
37020                  * @param {module:echarts/coord/parallel/AxisModel}\r
37021                  */\r
37022                 model: null\r
37023 \r
37024             };\r
37025 \r
37026             zrUtil.inherits(ParallelAxis, Axis);\r
37027 \r
37028             module.exports = ParallelAxis;\r
37029 \r
37030 \r
37031 /***/ },\r
37032 /* 220 */\r
37033 /***/ function(module, exports, __webpack_require__) {\r
37034 \r
37035         \r
37036 \r
37037             var zrUtil = __webpack_require__(3);\r
37038             var Component = __webpack_require__(19);\r
37039 \r
37040             __webpack_require__(221);\r
37041 \r
37042             Component.extend({\r
37043 \r
37044                 type: 'parallel',\r
37045 \r
37046                 dependencies: ['parallelAxis'],\r
37047 \r
37048                 /**\r
37049                  * @type {module:echarts/coord/parallel/Parallel}\r
37050                  */\r
37051                 coordinateSystem: null,\r
37052 \r
37053                 /**\r
37054                  * Each item like: 'dim0', 'dim1', 'dim2', ...\r
37055                  * @type {Array.<string>}\r
37056                  * @readOnly\r
37057                  */\r
37058                 dimensions: null,\r
37059 \r
37060                 /**\r
37061                  * Coresponding to dimensions.\r
37062                  * @type {Array.<number>}\r
37063                  * @readOnly\r
37064                  */\r
37065                 parallelAxisIndex: null,\r
37066 \r
37067                 defaultOption: {\r
37068                     zlevel: 0,                  // 一级层叠\r
37069                     z: 0,                       // 二级层叠\r
37070                     left: 80,\r
37071                     top: 60,\r
37072                     right: 80,\r
37073                     bottom: 60,\r
37074                     // width: {totalWidth} - left - right,\r
37075                     // height: {totalHeight} - top - bottom,\r
37076 \r
37077                     layout: 'horizontal',      // 'horizontal' or 'vertical'\r
37078 \r
37079                     parallelAxisDefault: null\r
37080                 },\r
37081 \r
37082                 /**\r
37083                  * @override\r
37084                  */\r
37085                 init: function () {\r
37086                     Component.prototype.init.apply(this, arguments);\r
37087 \r
37088                     this.mergeOption({});\r
37089                 },\r
37090 \r
37091                 /**\r
37092                  * @override\r
37093                  */\r
37094                 mergeOption: function (newOption) {\r
37095                     var thisOption = this.option;\r
37096 \r
37097                     newOption && zrUtil.merge(thisOption, newOption, true);\r
37098 \r
37099                     this._initDimensions();\r
37100                 },\r
37101 \r
37102                 /**\r
37103                  * Whether series or axis is in this coordinate system.\r
37104                  * @param {module:echarts/model/Series|module:echarts/coord/parallel/AxisModel} model\r
37105                  * @param {module:echarts/model/Global} ecModel\r
37106                  */\r
37107                 contains: function (model, ecModel) {\r
37108                     var parallelIndex = model.get('parallelIndex');\r
37109                     return parallelIndex != null\r
37110                         && ecModel.getComponent('parallel', parallelIndex) === this;\r
37111                 },\r
37112 \r
37113                 /**\r
37114                  * @private\r
37115                  */\r
37116                 _initDimensions: function () {\r
37117                     var dimensions = this.dimensions = [];\r
37118                     var parallelAxisIndex = this.parallelAxisIndex = [];\r
37119 \r
37120                     var axisModels = zrUtil.filter(this.dependentModels.parallelAxis, function (axisModel) {\r
37121                         // Can not use this.contains here, because\r
37122                         // initialization has not been completed yet.\r
37123                         return axisModel.get('parallelIndex') === this.componentIndex;\r
37124                     });\r
37125 \r
37126                     zrUtil.each(axisModels, function (axisModel) {\r
37127                         dimensions.push('dim' + axisModel.get('dim'));\r
37128                         parallelAxisIndex.push(axisModel.componentIndex);\r
37129                     });\r
37130                 }\r
37131 \r
37132             });\r
37133 \r
37134 \r
37135 \r
37136 /***/ },\r
37137 /* 221 */\r
37138 /***/ function(module, exports, __webpack_require__) {\r
37139 \r
37140         \r
37141 \r
37142             var ComponentModel = __webpack_require__(19);\r
37143             var zrUtil = __webpack_require__(3);\r
37144             var makeStyleMapper = __webpack_require__(11);\r
37145             var axisModelCreator = __webpack_require__(121);\r
37146             var numberUtil = __webpack_require__(7);\r
37147 \r
37148             var AxisModel = ComponentModel.extend({\r
37149 \r
37150                 type: 'baseParallelAxis',\r
37151 \r
37152                 /**\r
37153                  * @type {module:echarts/coord/parallel/Axis}\r
37154                  */\r
37155                 axis: null,\r
37156 \r
37157                 /**\r
37158                  * @type {Array.<Array.<number>}\r
37159                  * @readOnly\r
37160                  */\r
37161                 activeIntervals: [],\r
37162 \r
37163                 /**\r
37164                  * @return {Object}\r
37165                  */\r
37166                 getAreaSelectStyle: function () {\r
37167                     return makeStyleMapper(\r
37168                         [\r
37169                             ['fill', 'color'],\r
37170                             ['lineWidth', 'borderWidth'],\r
37171                             ['stroke', 'borderColor'],\r
37172                             ['width', 'width'],\r
37173                             ['opacity', 'opacity']\r
37174                         ]\r
37175                     ).call(this.getModel('areaSelectStyle'));\r
37176                 },\r
37177 \r
37178                 /**\r
37179                  * The code of this feature is put on AxisModel but not ParallelAxis,\r
37180                  * because axisModel can be alive after echarts updating but instance of\r
37181                  * ParallelAxis having been disposed. this._activeInterval should be kept\r
37182                  * when action dispatched (i.e. legend click).\r
37183                  *\r
37184                  * @param {Array.<Array<number>>} intervals interval.length === 0\r
37185                  *                                          means set all active.\r
37186                  * @public\r
37187                  */\r
37188                 setActiveIntervals: function (intervals) {\r
37189                     var activeIntervals = this.activeIntervals = zrUtil.clone(intervals);\r
37190 \r
37191                     // Normalize\r
37192                     if (activeIntervals) {\r
37193                         for (var i = activeIntervals.length - 1; i >= 0; i--) {\r
37194                             numberUtil.asc(activeIntervals[i]);\r
37195                         }\r
37196                     }\r
37197                 },\r
37198 \r
37199                 /**\r
37200                  * @param {number|string} [value] When attempting to detect 'no activeIntervals set',\r
37201                  *                         value can not be input.\r
37202                  * @return {string} 'normal': no activeIntervals set,\r
37203                  *                  'active',\r
37204                  *                  'inactive'.\r
37205                  * @public\r
37206                  */\r
37207                 getActiveState: function (value) {\r
37208                     var activeIntervals = this.activeIntervals;\r
37209 \r
37210                     if (!activeIntervals.length) {\r
37211                         return 'normal';\r
37212                     }\r
37213 \r
37214                     if (value == null) {\r
37215                         return 'inactive';\r
37216                     }\r
37217 \r
37218                     for (var i = 0, len = activeIntervals.length; i < len; i++) {\r
37219                         if (activeIntervals[i][0] <= value && value <= activeIntervals[i][1]) {\r
37220                             return 'active';\r
37221                         }\r
37222                     }\r
37223                     return 'inactive';\r
37224                 }\r
37225 \r
37226             });\r
37227 \r
37228             var defaultOption = {\r
37229 \r
37230                 type: 'value',\r
37231 \r
37232                 /**\r
37233                  * @type {Array.<number>}\r
37234                  */\r
37235                 dim: null, // 0, 1, 2, ...\r
37236 \r
37237                 parallelIndex: null,\r
37238 \r
37239                 areaSelectStyle: {\r
37240                     width: 20,\r
37241                     borderWidth: 1,\r
37242                     borderColor: 'rgba(160,197,232)',\r
37243                     color: 'rgba(160,197,232)',\r
37244                     opacity: 0.3\r
37245                 },\r
37246 \r
37247                 z: 10\r
37248             };\r
37249 \r
37250             zrUtil.merge(AxisModel.prototype, __webpack_require__(123));\r
37251 \r
37252             function getAxisType(axisName, option) {\r
37253                 return option.type || (option.data ? 'category' : 'value');\r
37254             }\r
37255 \r
37256             axisModelCreator('parallel', AxisModel, getAxisType, defaultOption);\r
37257 \r
37258             module.exports = AxisModel;\r
37259 \r
37260 \r
37261 /***/ },\r
37262 /* 222 */\r
37263 /***/ function(module, exports, __webpack_require__) {\r
37264 \r
37265         \r
37266 \r
37267             __webpack_require__(217);\r
37268             __webpack_require__(223);\r
37269             __webpack_require__(224);\r
37270 \r
37271 \r
37272 \r
37273 /***/ },\r
37274 /* 223 */\r
37275 /***/ function(module, exports, __webpack_require__) {\r
37276 \r
37277         \r
37278 \r
37279             var echarts = __webpack_require__(1);\r
37280 \r
37281             var actionInfo = {\r
37282                 type: 'axisAreaSelect',\r
37283                 event: 'axisAreaSelected',\r
37284                 update: 'updateVisual'\r
37285             };\r
37286 \r
37287             /**\r
37288              * @payload\r
37289              * @property {string} parallelAxisId\r
37290              * @property {Array.<Array.<number>>} intervals\r
37291              */\r
37292             echarts.registerAction(actionInfo, function (payload, ecModel) {\r
37293                 ecModel.eachComponent(\r
37294                     {mainType: 'parallelAxis', query: payload},\r
37295                     function (parallelAxisModel) {\r
37296                         parallelAxisModel.axis.model.setActiveIntervals(payload.intervals);\r
37297                     }\r
37298                 );\r
37299 \r
37300             });\r
37301 \r
37302 \r
37303 /***/ },\r
37304 /* 224 */\r
37305 /***/ function(module, exports, __webpack_require__) {\r
37306 \r
37307         \r
37308 \r
37309             var zrUtil = __webpack_require__(3);\r
37310             var AxisBuilder = __webpack_require__(126);\r
37311             var SelectController = __webpack_require__(225);\r
37312 \r
37313             var elementList = ['axisLine', 'axisLabel', 'axisTick', 'axisName'];\r
37314 \r
37315             var AxisView = __webpack_require__(1).extendComponentView({\r
37316 \r
37317                 type: 'parallelAxis',\r
37318 \r
37319                 /**\r
37320                  * @type {module:echarts/component/helper/SelectController}\r
37321                  */\r
37322                 _selectController: null,\r
37323 \r
37324                 /**\r
37325                  * @override\r
37326                  */\r
37327                 render: function (axisModel, ecModel, api, payload) {\r
37328                     if (fromAxisAreaSelect(axisModel, ecModel, payload)) {\r
37329                         return;\r
37330                     }\r
37331 \r
37332                     this.axisModel = axisModel;\r
37333                     this.api = api;\r
37334 \r
37335                     this.group.removeAll();\r
37336 \r
37337                     if (!axisModel.get('show')) {\r
37338                         return;\r
37339                     }\r
37340 \r
37341                     var coordSys = ecModel.getComponent(\r
37342                         'parallel', axisModel.get('parallelIndex')\r
37343                     ).coordinateSystem;\r
37344 \r
37345                     var areaSelectStyle = axisModel.getAreaSelectStyle();\r
37346                     var areaWidth = areaSelectStyle.width;\r
37347 \r
37348                     var axisLayout = coordSys.getAxisLayout(axisModel.axis.dim);\r
37349                     var builderOpt = zrUtil.extend(\r
37350                         {\r
37351                             strokeContainThreshold: areaWidth,\r
37352                             // lineWidth === 0 or no value.\r
37353                             silent: !(areaWidth > 0) // jshint ignore:line\r
37354                         },\r
37355                         axisLayout\r
37356                     );\r
37357 \r
37358                     var axisBuilder = new AxisBuilder(axisModel, builderOpt);\r
37359 \r
37360                     zrUtil.each(elementList, axisBuilder.add, axisBuilder);\r
37361 \r
37362                     var axisGroup = axisBuilder.getGroup();\r
37363 \r
37364                     this.group.add(axisGroup);\r
37365 \r
37366                     this._buildSelectController(\r
37367                         axisGroup, areaSelectStyle, axisModel, api\r
37368                     );\r
37369                 },\r
37370 \r
37371                 _buildSelectController: function (axisGroup, areaSelectStyle, axisModel, api) {\r
37372 \r
37373                     var axis = axisModel.axis;\r
37374                     var selectController = this._selectController;\r
37375 \r
37376                     if (!selectController) {\r
37377                         selectController = this._selectController = new SelectController(\r
37378                             'line',\r
37379                             api.getZr(),\r
37380                             areaSelectStyle\r
37381                         );\r
37382 \r
37383                         selectController.on('selected', zrUtil.bind(this._onSelected, this));\r
37384                     }\r
37385 \r
37386                     selectController.enable(axisGroup);\r
37387 \r
37388                     // After filtering, axis may change, select area needs to be update.\r
37389                     var ranges = zrUtil.map(axisModel.activeIntervals, function (interval) {\r
37390                         return [\r
37391                             axis.dataToCoord(interval[0], true),\r
37392                             axis.dataToCoord(interval[1], true)\r
37393                         ];\r
37394                     });\r
37395                     selectController.update(ranges);\r
37396                 },\r
37397 \r
37398                 _onSelected: function (ranges) {\r
37399                     // Do not cache these object, because the mey be changed.\r
37400                     var axisModel = this.axisModel;\r
37401                     var axis = axisModel.axis;\r
37402 \r
37403                     var intervals = zrUtil.map(ranges, function (range) {\r
37404                         return [\r
37405                             axis.coordToData(range[0], true),\r
37406                             axis.coordToData(range[1], true)\r
37407                         ];\r
37408                     });\r
37409                     this.api.dispatchAction({\r
37410                         type: 'axisAreaSelect',\r
37411                         parallelAxisId: axisModel.id,\r
37412                         intervals: intervals\r
37413                     });\r
37414                 },\r
37415 \r
37416                 /**\r
37417                  * @override\r
37418                  */\r
37419                 remove: function () {\r
37420                     this._selectController && this._selectController.disable();\r
37421                 },\r
37422 \r
37423                 /**\r
37424                  * @override\r
37425                  */\r
37426                 dispose: function () {\r
37427                     if (this._selectController) {\r
37428                         this._selectController.dispose();\r
37429                         this._selectController = null;\r
37430                     }\r
37431                 }\r
37432             });\r
37433 \r
37434             function fromAxisAreaSelect(axisModel, ecModel, payload) {\r
37435                 return payload\r
37436                     && payload.type === 'axisAreaSelect'\r
37437                     && ecModel.findComponents(\r
37438                         {mainType: 'parallelAxis', query: payload}\r
37439                     )[0] === axisModel;\r
37440             }\r
37441 \r
37442             module.exports = AxisView;\r
37443 \r
37444 \r
37445 /***/ },\r
37446 /* 225 */\r
37447 /***/ function(module, exports, __webpack_require__) {\r
37448 \r
37449         /**\r
37450          * Box selection tool.\r
37451          *\r
37452          * @module echarts/component/helper/SelectController\r
37453          */\r
37454 \r
37455 \r
37456 \r
37457             var Eventful = __webpack_require__(32);\r
37458             var zrUtil = __webpack_require__(3);\r
37459             var graphic = __webpack_require__(42);\r
37460             var bind = zrUtil.bind;\r
37461             var each = zrUtil.each;\r
37462             var mathMin = Math.min;\r
37463             var mathMax = Math.max;\r
37464             var mathPow = Math.pow;\r
37465 \r
37466             var COVER_Z = 10000;\r
37467             var UNSELECT_THRESHOLD = 2;\r
37468             var EVENTS = ['mousedown', 'mousemove', 'mouseup'];\r
37469 \r
37470             /**\r
37471              * @alias module:echarts/component/helper/SelectController\r
37472              * @constructor\r
37473              * @mixin {module:zrender/mixin/Eventful}\r
37474              *\r
37475              * @param {string} type 'line', 'rect'\r
37476              * @param {module:zrender/zrender~ZRender} zr\r
37477              * @param {Object} [opt]\r
37478              * @param {number} [opt.width]\r
37479              * @param {number} [opt.lineWidth]\r
37480              * @param {string} [opt.stroke]\r
37481              * @param {string} [opt.fill]\r
37482              */\r
37483             function SelectController(type, zr, opt) {\r
37484 \r
37485                 Eventful.call(this);\r
37486 \r
37487                 /**\r
37488                  * @type {string}\r
37489                  * @readOnly\r
37490                  */\r
37491                 this.type = type;\r
37492 \r
37493                 /**\r
37494                  * @type {module:zrender/zrender~ZRender}\r
37495                  */\r
37496                 this.zr = zr;\r
37497 \r
37498                 /**\r
37499                  * @type {Object}\r
37500                  * @readOnly\r
37501                  */\r
37502                 this.opt = zrUtil.clone(opt);\r
37503 \r
37504                 /**\r
37505                  * @type {module:zrender/container/Group}\r
37506                  * @readOnly\r
37507                  */\r
37508                 this.group = new graphic.Group();\r
37509 \r
37510                 /**\r
37511                  * @type {module:zrender/core/BoundingRect}\r
37512                  */\r
37513                 this._containerRect = null;\r
37514 \r
37515                 /**\r
37516                  * @type {Array.<nubmer>}\r
37517                  * @private\r
37518                  */\r
37519                 this._track = [];\r
37520 \r
37521                 /**\r
37522                  * @type {boolean}\r
37523                  */\r
37524                 this._dragging;\r
37525 \r
37526                 /**\r
37527                  * @type {module:zrender/Element}\r
37528                  * @private\r
37529                  */\r
37530                 this._cover;\r
37531 \r
37532                 /**\r
37533                  * @type {boolean}\r
37534                  * @private\r
37535                  */\r
37536                 this._disabled = true;\r
37537 \r
37538                 /**\r
37539                  * @type {Object}\r
37540                  * @private\r
37541                  */\r
37542                 this._handlers = {\r
37543                     mousedown: bind(mousedown, this),\r
37544                     mousemove: bind(mousemove, this),\r
37545                     mouseup: bind(mouseup, this)\r
37546                 };\r
37547 \r
37548                 each(EVENTS, function (eventName) {\r
37549                     this.zr.on(eventName, this._handlers[eventName]);\r
37550                 }, this);\r
37551             }\r
37552 \r
37553             SelectController.prototype = {\r
37554 \r
37555                 constructor: SelectController,\r
37556 \r
37557                 /**\r
37558                  * @param {module:zrender/mixin/Transformable} container\r
37559                  * @param {module:zrender/core/BoundingRect|boolean} [rect] If not specified,\r
37560                  *                                                  use container.getBoundingRect().\r
37561                  *                                                  If false, do not use containerRect.\r
37562                  */\r
37563                 enable: function (container, rect) {\r
37564 \r
37565                     this._disabled = false;\r
37566 \r
37567                     // Remove from old container.\r
37568                     removeGroup.call(this);\r
37569 \r
37570                     // boundingRect will change when dragging, so we have\r
37571                     // to keep initial boundingRect.\r
37572                     this._containerRect = rect !== false\r
37573                     ? (rect || container.getBoundingRect()) : null;\r
37574 \r
37575                     // Add to new container.\r
37576                     container.add(this.group);\r
37577                 },\r
37578 \r
37579                 /**\r
37580                  * Update cover location.\r
37581                  * @param {Array.<number>|Object} ranges If null/undefined, remove cover.\r
37582                  */\r
37583                 update: function (ranges) {\r
37584                     // TODO\r
37585                     // Only support one interval yet.\r
37586                     renderCover.call(this, ranges && zrUtil.clone(ranges));\r
37587                 },\r
37588 \r
37589                 disable: function () {\r
37590                     this._disabled = true;\r
37591 \r
37592                     removeGroup.call(this);\r
37593                 },\r
37594 \r
37595                 dispose: function () {\r
37596                     this.disable();\r
37597 \r
37598                     each(EVENTS, function (eventName) {\r
37599                         this.zr.off(eventName, this._handlers[eventName]);\r
37600                     }, this);\r
37601                 }\r
37602             };\r
37603 \r
37604 \r
37605             zrUtil.mixin(SelectController, Eventful);\r
37606 \r
37607             function updateZ(group) {\r
37608                 group.traverse(function (el) {\r
37609                     el.z = COVER_Z;\r
37610                 });\r
37611             }\r
37612 \r
37613             function isInContainer(x, y) {\r
37614                 var localPos = this.group.transformCoordToLocal(x, y);\r
37615                 return !this._containerRect\r
37616                     || this._containerRect.contain(localPos[0], localPos[1]);\r
37617             }\r
37618 \r
37619             function preventDefault(e) {\r
37620                 var rawE = e.event;\r
37621                 rawE.preventDefault && rawE.preventDefault();\r
37622             }\r
37623 \r
37624             function mousedown(e) {\r
37625                 if (this._disabled || (e.target && e.target.draggable)) {\r
37626                     return;\r
37627                 }\r
37628 \r
37629                 preventDefault(e);\r
37630 \r
37631                 var x = e.offsetX;\r
37632                 var y = e.offsetY;\r
37633 \r
37634                 if (isInContainer.call(this, x, y)) {\r
37635                     this._dragging = true;\r
37636                     this._track = [[x, y]];\r
37637                 }\r
37638             }\r
37639 \r
37640             function mousemove(e) {\r
37641                 if (!this._dragging || this._disabled) {\r
37642                     return;\r
37643                 }\r
37644 \r
37645                 preventDefault(e);\r
37646 \r
37647                 updateViewByCursor.call(this, e);\r
37648             }\r
37649 \r
37650             function mouseup(e) {\r
37651                 if (!this._dragging || this._disabled) {\r
37652                     return;\r
37653                 }\r
37654 \r
37655                 preventDefault(e);\r
37656 \r
37657                 updateViewByCursor.call(this, e, true);\r
37658 \r
37659                 this._dragging = false;\r
37660                 this._track = [];\r
37661             }\r
37662 \r
37663             function updateViewByCursor(e, isEnd) {\r
37664                 var x = e.offsetX;\r
37665                 var y = e.offsetY;\r
37666 \r
37667                 if (isInContainer.call(this, x, y)) {\r
37668                     this._track.push([x, y]);\r
37669 \r
37670                     // Create or update cover.\r
37671                     var ranges = shouldShowCover.call(this)\r
37672                         ? coverRenderers[this.type].getRanges.call(this)\r
37673                         // Remove cover.\r
37674                         : [];\r
37675 \r
37676                     renderCover.call(this, ranges);\r
37677 \r
37678                     this.trigger('selected', zrUtil.clone(ranges));\r
37679 \r
37680                     if (isEnd) {\r
37681                         this.trigger('selectEnd', zrUtil.clone(ranges));\r
37682                     }\r
37683                 }\r
37684             }\r
37685 \r
37686             function shouldShowCover() {\r
37687                 var track = this._track;\r
37688 \r
37689                 if (!track.length) {\r
37690                     return false;\r
37691                 }\r
37692 \r
37693                 var p2 = track[track.length - 1];\r
37694                 var p1 = track[0];\r
37695                 var dx = p2[0] - p1[0];\r
37696                 var dy = p2[1] - p1[1];\r
37697                 var dist = mathPow(dx * dx + dy * dy, 0.5);\r
37698 \r
37699                 return dist > UNSELECT_THRESHOLD;\r
37700             }\r
37701 \r
37702             function renderCover(ranges) {\r
37703                 var coverRenderer = coverRenderers[this.type];\r
37704 \r
37705                 if (ranges && ranges.length) {\r
37706                     if (!this._cover) {\r
37707                         this._cover = coverRenderer.create.call(this);\r
37708                         this.group.add(this._cover);\r
37709                     }\r
37710                     coverRenderer.update.call(this, ranges);\r
37711                 }\r
37712                 else {\r
37713                     this.group.remove(this._cover);\r
37714                     this._cover = null;\r
37715                 }\r
37716 \r
37717                 updateZ(this.group);\r
37718             }\r
37719 \r
37720             function removeGroup() {\r
37721                 // container may 'removeAll' outside.\r
37722                 var group = this.group;\r
37723                 var container = group.parent;\r
37724                 if (container) {\r
37725                     container.remove(group);\r
37726                 }\r
37727             }\r
37728 \r
37729             function createRectCover() {\r
37730                 var opt = this.opt;\r
37731                 return new graphic.Rect({\r
37732                     // FIXME\r
37733                     // customize style.\r
37734                     style: {\r
37735                         stroke: opt.stroke,\r
37736                         fill: opt.fill,\r
37737                         lineWidth: opt.lineWidth,\r
37738                         opacity: opt.opacity\r
37739                     }\r
37740                 });\r
37741             }\r
37742 \r
37743             function getLocalTrack() {\r
37744                 return zrUtil.map(this._track, function (point) {\r
37745                     return this.group.transformCoordToLocal(point[0], point[1]);\r
37746                 }, this);\r
37747             }\r
37748 \r
37749             function getLocalTrackEnds() {\r
37750                 var localTrack = getLocalTrack.call(this);\r
37751                 var tail = localTrack.length - 1;\r
37752                 tail < 0 && (tail = 0);\r
37753                 return [localTrack[0], localTrack[tail]];\r
37754             }\r
37755 \r
37756             /**\r
37757              * key: this.type\r
37758              * @type {Object}\r
37759              */\r
37760             var coverRenderers = {\r
37761 \r
37762                 line: {\r
37763 \r
37764                     create: createRectCover,\r
37765 \r
37766                     getRanges: function () {\r
37767                         var ends = getLocalTrackEnds.call(this);\r
37768                         var min = mathMin(ends[0][0], ends[1][0]);\r
37769                         var max = mathMax(ends[0][0], ends[1][0]);\r
37770 \r
37771                         return [[min, max]];\r
37772                     },\r
37773 \r
37774                     update: function (ranges) {\r
37775                         var range = ranges[0];\r
37776                         var width = this.opt.width;\r
37777                         this._cover.setShape({\r
37778                             x: range[0],\r
37779                             y: -width / 2,\r
37780                             width: range[1] - range[0],\r
37781                             height: width\r
37782                         });\r
37783                     }\r
37784                 },\r
37785 \r
37786                 rect: {\r
37787 \r
37788                     create: createRectCover,\r
37789 \r
37790                     getRanges: function () {\r
37791                         var ends = getLocalTrackEnds.call(this);\r
37792 \r
37793                         var min = [\r
37794                             mathMin(ends[1][0], ends[0][0]),\r
37795                             mathMin(ends[1][1], ends[0][1])\r
37796                         ];\r
37797                         var max = [\r
37798                             mathMax(ends[1][0], ends[0][0]),\r
37799                             mathMax(ends[1][1], ends[0][1])\r
37800                         ];\r
37801 \r
37802                         return [[\r
37803                             [min[0], max[0]], // x range\r
37804                             [min[1], max[1]] // y range\r
37805                         ]];\r
37806                     },\r
37807 \r
37808                     update: function (ranges) {\r
37809                         var range = ranges[0];\r
37810                         this._cover.setShape({\r
37811                             x: range[0][0],\r
37812                             y: range[1][0],\r
37813                             width: range[0][1] - range[0][0],\r
37814                             height: range[1][1] - range[1][0]\r
37815                         });\r
37816                     }\r
37817                 }\r
37818             };\r
37819 \r
37820             module.exports = SelectController;\r
37821 \r
37822 \r
37823 /***/ },\r
37824 /* 226 */\r
37825 /***/ function(module, exports, __webpack_require__) {\r
37826 \r
37827         \r
37828 \r
37829             var zrUtil = __webpack_require__(3);\r
37830             var modelUtil = __webpack_require__(5);\r
37831 \r
37832             module.exports = function (option) {\r
37833                 createParallelIfNeeded(option);\r
37834                 mergeAxisOptionFromParallel(option);\r
37835             };\r
37836 \r
37837             /**\r
37838              * Create a parallel coordinate if not exists.\r
37839              * @inner\r
37840              */\r
37841             function createParallelIfNeeded(option) {\r
37842                 if (option.parallel) {\r
37843                     return;\r
37844                 }\r
37845 \r
37846                 var hasParallelSeries = false;\r
37847 \r
37848                 zrUtil.each(option.series, function (seriesOpt) {\r
37849                     if (seriesOpt && seriesOpt.type === 'parallel') {\r
37850                         hasParallelSeries = true;\r
37851                     }\r
37852                 });\r
37853 \r
37854                 if (hasParallelSeries) {\r
37855                     option.parallel = [{}];\r
37856                 }\r
37857             }\r
37858 \r
37859             /**\r
37860              * Merge aixs definition from parallel option (if exists) to axis option.\r
37861              * @inner\r
37862              */\r
37863             function mergeAxisOptionFromParallel(option) {\r
37864                 var axes = modelUtil.normalizeToArray(option.parallelAxis);\r
37865 \r
37866                 zrUtil.each(axes, function (axisOption) {\r
37867                     if (!zrUtil.isObject(axisOption)) {\r
37868                         return;\r
37869                     }\r
37870 \r
37871                     var parallelIndex = axisOption.parallelIndex || 0;\r
37872                     var parallelOption = modelUtil.normalizeToArray(option.parallel)[parallelIndex];\r
37873 \r
37874                     if (parallelOption && parallelOption.parallelAxisDefault) {\r
37875                         zrUtil.merge(axisOption, parallelOption.parallelAxisDefault, false);\r
37876                     }\r
37877                 });\r
37878             }\r
37879 \r
37880 \r
37881 \r
37882 /***/ },\r
37883 /* 227 */\r
37884 /***/ function(module, exports, __webpack_require__) {\r
37885 \r
37886         \r
37887 \r
37888             var List = __webpack_require__(94);\r
37889             var zrUtil = __webpack_require__(3);\r
37890             var SeriesModel = __webpack_require__(27);\r
37891 \r
37892             module.exports = SeriesModel.extend({\r
37893 \r
37894                 type: 'series.parallel',\r
37895 \r
37896                 dependencies: ['parallel'],\r
37897 \r
37898                 getInitialData: function (option, ecModel) {\r
37899                     var parallelModel = ecModel.getComponent(\r
37900                         'parallel', this.get('parallelIndex')\r
37901                     );\r
37902                     var dimensions = parallelModel.dimensions;\r
37903                     var parallelAxisIndices = parallelModel.parallelAxisIndex;\r
37904 \r
37905                     var rawData = option.data;\r
37906 \r
37907                     var dimensionsInfo = zrUtil.map(dimensions, function (dim, index) {\r
37908                         var axisModel = ecModel.getComponent(\r
37909                             'parallelAxis', parallelAxisIndices[index]\r
37910                         );\r
37911                         if (axisModel.get('type') === 'category') {\r
37912                             translateCategoryValue(axisModel, dim, rawData);\r
37913                             return {name: dim, type: 'ordinal'};\r
37914                         }\r
37915                         else {\r
37916                             return dim;\r
37917                         }\r
37918                     });\r
37919 \r
37920                     var list = new List(dimensionsInfo, this);\r
37921                     list.initData(rawData);\r
37922 \r
37923                     return list;\r
37924                 },\r
37925 \r
37926                 defaultOption: {\r
37927                     zlevel: 0,                  // 一级层叠\r
37928                     z: 2,                       // 二级层叠\r
37929 \r
37930                     coordinateSystem: 'parallel',\r
37931                     parallelIndex: 0,\r
37932 \r
37933                     // FIXME 尚无用\r
37934                     label: {\r
37935                         normal: {\r
37936                             show: false\r
37937                             // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
37938                             // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为\r
37939                             //           'inside'|'left'|'right'|'top'|'bottom'\r
37940                             // textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE\r
37941                         },\r
37942                         emphasis: {\r
37943                             show: false\r
37944                             // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
37945                             // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为\r
37946                             //           'inside'|'left'|'right'|'top'|'bottom'\r
37947                             // textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE\r
37948                         }\r
37949                     },\r
37950 \r
37951                     inactiveOpacity: 0.05,\r
37952                     activeOpacity: 1,\r
37953 \r
37954                     lineStyle: {\r
37955                         normal: {\r
37956                             width: 2,\r
37957                             opacity: 0.45,\r
37958                             type: 'solid'\r
37959                         }\r
37960                     },\r
37961                     // smooth: false\r
37962 \r
37963                     animationEasing: 'linear'\r
37964                 }\r
37965             });\r
37966 \r
37967             function translateCategoryValue(axisModel, dim, rawData) {\r
37968                 var axisData = axisModel.get('data');\r
37969                 var numberDim = +dim.replace('dim', '');\r
37970 \r
37971                 if (axisData && axisData.length) {\r
37972                     zrUtil.each(rawData, function (dataItem) {\r
37973                         if (!dataItem) {\r
37974                             return;\r
37975                         }\r
37976                         var index = zrUtil.indexOf(axisData, dataItem[numberDim]);\r
37977                         dataItem[numberDim] = index >= 0 ? index : NaN;\r
37978                     });\r
37979                 }\r
37980                 // FIXME\r
37981                 // 如果没有设置axis data, 应自动算出,或者提示。\r
37982             }\r
37983 \r
37984 \r
37985 /***/ },\r
37986 /* 228 */\r
37987 /***/ function(module, exports, __webpack_require__) {\r
37988 \r
37989         \r
37990 \r
37991             var graphic = __webpack_require__(42);\r
37992             var zrUtil = __webpack_require__(3);\r
37993 \r
37994             var ParallelView = __webpack_require__(41).extend({\r
37995 \r
37996                 type: 'parallel',\r
37997 \r
37998                 init: function () {\r
37999 \r
38000                     /**\r
38001                      * @type {module:zrender/container/Group}\r
38002                      * @private\r
38003                      */\r
38004                     this._dataGroup = new graphic.Group();\r
38005 \r
38006                     this.group.add(this._dataGroup);\r
38007                     /**\r
38008                      * @type {module:echarts/data/List}\r
38009                      */\r
38010                     this._data;\r
38011                 },\r
38012 \r
38013                 /**\r
38014                  * @override\r
38015                  */\r
38016                 render: function (seriesModel, ecModel, api, payload) {\r
38017 \r
38018                     var dataGroup = this._dataGroup;\r
38019                     var data = seriesModel.getData();\r
38020                     var oldData = this._data;\r
38021                     var coordSys = seriesModel.coordinateSystem;\r
38022                     var dimensions = coordSys.dimensions;\r
38023 \r
38024                     data.diff(oldData)\r
38025                         .add(add)\r
38026                         .update(update)\r
38027                         .remove(remove)\r
38028                         .execute();\r
38029 \r
38030                     // Update style\r
38031                     data.eachItemGraphicEl(function (elGroup, idx) {\r
38032                         var itemModel = data.getItemModel(idx);\r
38033                         var lineStyleModel = itemModel.getModel('lineStyle.normal');\r
38034                         elGroup.eachChild(function (child) {\r
38035                             child.setStyle(zrUtil.extend(\r
38036                                 lineStyleModel.getLineStyle(),\r
38037                                 {\r
38038                                     stroke: data.getItemVisual(idx, 'color'),\r
38039                                     opacity: data.getItemVisual(idx, 'opacity')\r
38040                                 }\r
38041                             ));\r
38042                         });\r
38043                     });\r
38044 \r
38045                     // First create\r
38046                     if (!this._data) {\r
38047                         dataGroup.setClipPath(createGridClipShape(\r
38048                             coordSys, seriesModel, function () {\r
38049                                 dataGroup.removeClipPath();\r
38050                             }\r
38051                         ));\r
38052                     }\r
38053 \r
38054                     this._data = data;\r
38055 \r
38056                     function add(newDataIndex) {\r
38057                         var values = data.getValues(dimensions, newDataIndex);\r
38058                         var elGroup = new graphic.Group();\r
38059                         dataGroup.add(elGroup);\r
38060 \r
38061                         eachAxisPair(\r
38062                             values, dimensions, coordSys,\r
38063                             function (pointPair, pairIndex) {\r
38064                                 // FIXME\r
38065                                 // init animation\r
38066                                 if (pointPair) {\r
38067                                     elGroup.add(createEl(pointPair));\r
38068                                 }\r
38069                             }\r
38070                         );\r
38071 \r
38072                         data.setItemGraphicEl(newDataIndex, elGroup);\r
38073                     }\r
38074 \r
38075                     function update(newDataIndex, oldDataIndex) {\r
38076                         var values = data.getValues(dimensions, newDataIndex);\r
38077                         var elGroup = oldData.getItemGraphicEl(oldDataIndex);\r
38078                         var newEls = [];\r
38079                         var elGroupIndex = 0;\r
38080 \r
38081                         eachAxisPair(\r
38082                             values, dimensions, coordSys,\r
38083                             function (pointPair, pairIndex) {\r
38084                                 var el = elGroup.childAt(elGroupIndex++);\r
38085 \r
38086                                 if (pointPair && !el) {\r
38087                                     newEls.push(createEl(pointPair));\r
38088                                 }\r
38089                                 else if (pointPair) {\r
38090                                     graphic.updateProps(el, {\r
38091                                         shape: {\r
38092                                             points: pointPair\r
38093                                         }\r
38094                                     }, seriesModel);\r
38095                                 }\r
38096                             }\r
38097                         );\r
38098 \r
38099                         // Remove redundent els\r
38100                         for (var i = elGroup.childCount() - 1; i >= elGroupIndex; i--) {\r
38101                             elGroup.remove(elGroup.childAt(i));\r
38102                         }\r
38103 \r
38104                         // Add new els\r
38105                         for (var i = 0, len = newEls.length; i < len; i++) {\r
38106                             elGroup.add(newEls[i]);\r
38107                         }\r
38108 \r
38109                         data.setItemGraphicEl(newDataIndex, elGroup);\r
38110                     }\r
38111 \r
38112                     function remove(oldDataIndex) {\r
38113                         var elGroup = oldData.getItemGraphicEl(oldDataIndex);\r
38114                         dataGroup.remove(elGroup);\r
38115                     }\r
38116                 },\r
38117 \r
38118                 /**\r
38119                  * @override\r
38120                  */\r
38121                 remove: function () {\r
38122                     this._dataGroup && this._dataGroup.removeAll();\r
38123                     this._data = null;\r
38124                 }\r
38125             });\r
38126 \r
38127             function createGridClipShape(coordSys, seriesModel, cb) {\r
38128                 var parallelModel = coordSys.model;\r
38129                 var rect = coordSys.getRect();\r
38130                 var rectEl = new graphic.Rect({\r
38131                     shape: {\r
38132                         x: rect.x,\r
38133                         y: rect.y,\r
38134                         width: rect.width,\r
38135                         height: rect.height\r
38136                     }\r
38137                 });\r
38138                 var dim = parallelModel.get('layout') === 'horizontal' ? 'width' : 'height';\r
38139                 rectEl.setShape(dim, 0);\r
38140                 graphic.initProps(rectEl, {\r
38141                     shape: {\r
38142                         width: rect.width,\r
38143                         height: rect.height\r
38144                     }\r
38145                 }, seriesModel, cb);\r
38146                 return rectEl;\r
38147             }\r
38148 \r
38149             function eachAxisPair(values, dimensions, coordSys, cb) {\r
38150                 for (var i = 0, len = dimensions.length - 1; i < len; i++) {\r
38151                     var dimA = dimensions[i];\r
38152                     var dimB = dimensions[i + 1];\r
38153                     var valueA = values[i];\r
38154                     var valueB = values[i + 1];\r
38155 \r
38156                     cb(\r
38157                         (isEmptyValue(valueA, coordSys.getAxis(dimA).type)\r
38158                             || isEmptyValue(valueB, coordSys.getAxis(dimB).type)\r
38159                         )\r
38160                             ? null\r
38161                             : [\r
38162                                 coordSys.dataToPoint(valueA, dimA),\r
38163                                 coordSys.dataToPoint(valueB, dimB)\r
38164                             ],\r
38165                         i\r
38166                     );\r
38167                 }\r
38168             }\r
38169 \r
38170             function createEl(pointPair) {\r
38171                 return new graphic.Polyline({\r
38172                     shape: {points: pointPair},\r
38173                     silent: true\r
38174                 });\r
38175             }\r
38176 \r
38177 \r
38178             // FIXME\r
38179             // 公用方法?\r
38180             function isEmptyValue(val, axisType) {\r
38181                 return axisType === 'category'\r
38182                     ? val == null\r
38183                     : (val == null || isNaN(val)); // axisType === 'value'\r
38184             }\r
38185 \r
38186             module.exports = ParallelView;\r
38187 \r
38188 \r
38189 /***/ },\r
38190 /* 229 */\r
38191 /***/ function(module, exports) {\r
38192 \r
38193         \r
38194 \r
38195             /**\r
38196              * @payload\r
38197              * @property {string} parallelAxisId\r
38198              * @property {Array.<number>} extent\r
38199              */\r
38200             module.exports = function (ecModel, payload) {\r
38201 \r
38202                 ecModel.eachSeriesByType('parallel', function (seriesModel) {\r
38203 \r
38204                     var itemStyleModel = seriesModel.getModel('itemStyle.normal');\r
38205                     var globalColors = ecModel.get('color');\r
38206 \r
38207                     var color = itemStyleModel.get('color')\r
38208                         || globalColors[seriesModel.seriesIndex % globalColors.length];\r
38209                     var inactiveOpacity = seriesModel.get('inactiveOpacity');\r
38210                     var activeOpacity = seriesModel.get('activeOpacity');\r
38211                     var lineStyle = seriesModel.getModel('lineStyle.normal').getLineStyle();\r
38212 \r
38213                     var coordSys = seriesModel.coordinateSystem;\r
38214                     var data = seriesModel.getData();\r
38215 \r
38216                     var opacityMap = {\r
38217                         normal: lineStyle.opacity,\r
38218                         active: activeOpacity,\r
38219                         inactive: inactiveOpacity\r
38220                     };\r
38221 \r
38222                     coordSys.eachActiveState(data, function (activeState, dataIndex) {\r
38223                         data.setItemVisual(dataIndex, 'opacity', opacityMap[activeState]);\r
38224                     });\r
38225 \r
38226                     data.setVisual('color', color);\r
38227                 });\r
38228             };\r
38229 \r
38230 \r
38231 /***/ },\r
38232 /* 230 */\r
38233 /***/ function(module, exports, __webpack_require__) {\r
38234 \r
38235         \r
38236 \r
38237             var echarts = __webpack_require__(1);\r
38238 \r
38239             __webpack_require__(231);\r
38240             __webpack_require__(232);\r
38241             echarts.registerLayout(__webpack_require__(233));\r
38242             echarts.registerVisualCoding('chart', __webpack_require__(235));\r
38243 \r
38244 \r
38245 /***/ },\r
38246 /* 231 */\r
38247 /***/ function(module, exports, __webpack_require__) {\r
38248 \r
38249         'use strict';\r
38250 \r
38251 \r
38252             var SeriesModel = __webpack_require__(27);\r
38253             var createGraphFromNodeEdge = __webpack_require__(191);\r
38254 \r
38255             module.exports = SeriesModel.extend({\r
38256 \r
38257                 type: 'series.sankey',\r
38258 \r
38259                 layoutInfo: null,\r
38260 \r
38261                 getInitialData: function (option, ecModel) {\r
38262                     var links = option.edges || option.links;\r
38263                     var nodes = option.data || option.nodes;\r
38264                     if (nodes && links) {\r
38265                         var graph = createGraphFromNodeEdge(nodes, links, this, true);\r
38266                         return graph.data;\r
38267                     }\r
38268                 },\r
38269 \r
38270                 /**\r
38271                  * @return {module:echarts/data/Graph}\r
38272                  */\r
38273                 getGraph: function () {\r
38274                     return this.getData().graph;\r
38275                 },\r
38276 \r
38277                 /**\r
38278                  * return {module:echarts/data/List}\r
38279                  */\r
38280                 getEdgeData: function() {\r
38281                     return this.getGraph().edgeData;\r
38282                 },\r
38283 \r
38284                 defaultOption: {\r
38285                     zlevel: 0,\r
38286                     z: 2,\r
38287 \r
38288                     coordinateSystem: 'view',\r
38289 \r
38290                     layout : null,\r
38291 \r
38292                     // the position of the whole view\r
38293                     left: '5%',\r
38294                     top: '5%',\r
38295                     right: '20%',\r
38296                     bottom: '5%',\r
38297 \r
38298                     // the dx of the node\r
38299                     nodeWidth: 20,\r
38300 \r
38301                     // the distance between two nodes\r
38302                     nodeGap: 8,\r
38303 \r
38304                     // the number of iterations to change the position of the node\r
38305                     layoutIterations: 32,\r
38306 \r
38307                     label: {\r
38308                         normal: {\r
38309                             show: true,\r
38310                             position: 'right',\r
38311                             textStyle: {\r
38312                                 color: '#000',\r
38313                                 fontSize: 12\r
38314                             }\r
38315                         },\r
38316                         emphasis: {\r
38317                             show: true\r
38318                         }\r
38319                     },\r
38320 \r
38321                     itemStyle: {\r
38322                         normal: {\r
38323                             borderWidth: 1,\r
38324                             borderColor: '#aaa'\r
38325                         }\r
38326                     },\r
38327 \r
38328                     lineStyle: {\r
38329                         normal: {\r
38330                             color: '#314656',\r
38331                             opacity: 0.2,\r
38332                             curveness: 0.5\r
38333                         },\r
38334                         emphasis: {\r
38335                             opacity: 0.6\r
38336                         }\r
38337                     },\r
38338 \r
38339 \r
38340                     // colorEncoded node\r
38341 \r
38342                     color: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b','#ffffbf',\r
38343                             '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'],\r
38344 \r
38345                     animationEasing: 'linear',\r
38346 \r
38347                     animationDuration: 1000\r
38348                 }\r
38349 \r
38350             });\r
38351 \r
38352 \r
38353 \r
38354 /***/ },\r
38355 /* 232 */\r
38356 /***/ function(module, exports, __webpack_require__) {\r
38357 \r
38358         \r
38359 \r
38360             var graphic = __webpack_require__(42);\r
38361             var modelUtil = __webpack_require__(5);\r
38362             var zrUtil = __webpack_require__(3);\r
38363 \r
38364             var SankeyShape = graphic.extendShape({\r
38365                 shape: {\r
38366                     x1: 0, y1: 0,\r
38367                     x2: 0, y2: 0,\r
38368                     cpx1: 0, cpy1: 0,\r
38369                     cpx2: 0, cpy2: 0,\r
38370 \r
38371                     extent: 0\r
38372                 },\r
38373 \r
38374                 buildPath: function (ctx, shape) {\r
38375                     var halfExtent = shape.extent / 2;\r
38376                     ctx.moveTo(shape.x1, shape.y1 - halfExtent);\r
38377                     ctx.bezierCurveTo(\r
38378                         shape.cpx1, shape.cpy1 - halfExtent,\r
38379                         shape.cpx2, shape.cpy2 - halfExtent,\r
38380                         shape.x2, shape.y2 - halfExtent\r
38381                     );\r
38382                     ctx.lineTo(shape.x2, shape.y2 + halfExtent);\r
38383                     ctx.bezierCurveTo(\r
38384                         shape.cpx2, shape.cpy2 + halfExtent,\r
38385                         shape.cpx1, shape.cpy1 + halfExtent,\r
38386                         shape.x1, shape.y1 + halfExtent\r
38387                     );\r
38388                     ctx.closePath();\r
38389                 }\r
38390             });\r
38391 \r
38392             module.exports = __webpack_require__(1).extendChartView({\r
38393 \r
38394                 type: 'sankey',\r
38395 \r
38396                 /**\r
38397                  * @private\r
38398                  * @type {module:echarts/chart/sankey/SankeySeries}\r
38399                  */\r
38400                 _model: null,\r
38401 \r
38402                 render: function(seriesModel, ecModel, api) {\r
38403                     var graph = seriesModel.getGraph();\r
38404                     var group = this.group;\r
38405                     var layoutInfo = seriesModel.layoutInfo;\r
38406 \r
38407                     this._model = seriesModel;\r
38408 \r
38409                     group.removeAll();\r
38410 \r
38411                     group.position = [layoutInfo.x, layoutInfo.y];\r
38412 \r
38413                     var edgeData = graph.edgeData;\r
38414                     var rawOption = seriesModel.option;\r
38415                     var formatModel = modelUtil.createDataFormatModel(\r
38416                         seriesModel, edgeData, rawOption.edges || rawOption.links\r
38417                     );\r
38418 \r
38419                     formatModel.formatTooltip = function (dataIndex) {\r
38420                         var params = this.getDataParams(dataIndex);\r
38421                         var rawDataOpt = params.data;\r
38422                         var html = rawDataOpt.source + ' -- ' + rawDataOpt.target;\r
38423                         if (params.value) {\r
38424                             html += ':' + params.value;\r
38425                         }\r
38426                         return html;\r
38427                     };\r
38428 \r
38429                     // generate a rect  for each node\r
38430                     graph.eachNode(function (node) {\r
38431                         var layout = node.getLayout();\r
38432                         var itemModel = node.getModel();\r
38433                         var labelModel = itemModel.getModel('label.normal');\r
38434                         var textStyleModel = labelModel.getModel('textStyle');\r
38435                         var labelHoverModel = itemModel.getModel('label.emphasis');\r
38436                         var textStyleHoverModel = labelHoverModel.getModel('textStyle');\r
38437 \r
38438                         var rect = new graphic.Rect({\r
38439                             shape: {\r
38440                                 x: layout.x,\r
38441                                 y: layout.y,\r
38442                                 width: node.getLayout().dx,\r
38443                                 height: node.getLayout().dy\r
38444                             },\r
38445                             style: {\r
38446                                 // Get formatted label in label.normal option. Use node id if it is not specified\r
38447                                 text: labelModel.get('show')\r
38448                                     ? seriesModel.getFormattedLabel(node.dataIndex, 'normal') || node.id\r
38449                                     // Use empty string to hide the label\r
38450                                     : '',\r
38451                                 textFont: textStyleModel.getFont(),\r
38452                                 textFill: textStyleModel.getTextColor(),\r
38453                                 textPosition: labelModel.get('position')\r
38454                             }\r
38455                         });\r
38456 \r
38457                         rect.setStyle(zrUtil.defaults(\r
38458                             {\r
38459                                 fill: node.getVisual('color')\r
38460                             },\r
38461                             itemModel.getModel('itemStyle.normal').getItemStyle()\r
38462                         ));\r
38463 \r
38464                         graphic.setHoverStyle(rect, zrUtil.extend(\r
38465                             node.getModel('itemStyle.emphasis'),\r
38466                             {\r
38467                                 text: labelHoverModel.get('show')\r
38468                                     ? seriesModel.getFormattedLabel(node.dataIndex, 'emphasis') || node.id\r
38469                                     : '',\r
38470                                 textFont: textStyleHoverModel.getFont(),\r
38471                                 textFill: textStyleHoverModel.getTextColor(),\r
38472                                 textPosition: labelHoverModel.get('position')\r
38473                             }\r
38474                         ));\r
38475 \r
38476                         group.add(rect);\r
38477                     });\r
38478 \r
38479                     // generate a bezire Curve for each edge\r
38480                     graph.eachEdge(function (edge) {\r
38481                         var curve = new SankeyShape();\r
38482 \r
38483                         curve.dataIndex = edge.dataIndex;\r
38484                         curve.dataModel = formatModel;\r
38485 \r
38486                         var lineStyleModel = edge.getModel('lineStyle.normal');\r
38487                         var curvature = lineStyleModel.get('curveness');\r
38488                         var n1Layout = edge.node1.getLayout();\r
38489                         var n2Layout = edge.node2.getLayout();\r
38490                         var edgeLayout = edge.getLayout();\r
38491 \r
38492                         curve.shape.extent = Math.max(1, edgeLayout.dy);\r
38493 \r
38494                         var x1 = n1Layout.x + n1Layout.dx;\r
38495                         var y1 = n1Layout.y + edgeLayout.sy + edgeLayout.dy / 2;\r
38496                         var x2 = n2Layout.x;\r
38497                         var y2 = n2Layout.y + edgeLayout.ty + edgeLayout.dy /2;\r
38498                         var cpx1 = x1 * (1 - curvature) + x2 * curvature;\r
38499                         var cpy1 = y1;\r
38500                         var cpx2 = x1 * curvature + x2 * (1 - curvature);\r
38501                         var cpy2 = y2;\r
38502 \r
38503                         curve.setShape({\r
38504                             x1: x1,\r
38505                             y1: y1,\r
38506                             x2: x2,\r
38507                             y2: y2,\r
38508                             cpx1: cpx1,\r
38509                             cpy1: cpy1,\r
38510                             cpx2: cpx2,\r
38511                             cpy2: cpy2\r
38512                         });\r
38513 \r
38514                         curve.setStyle(lineStyleModel.getItemStyle());\r
38515                         graphic.setHoverStyle(curve, edge.getModel('lineStyle.emphasis').getItemStyle());\r
38516 \r
38517                         group.add(curve);\r
38518 \r
38519                     });\r
38520                     if (!this._data) {\r
38521                         group.setClipPath(createGridClipShape(group.getBoundingRect(), seriesModel, function () {\r
38522                             group.removeClipPath();\r
38523                         }));\r
38524                     }\r
38525                     this._data = seriesModel.getData();\r
38526                 }\r
38527             });\r
38528 \r
38529             //add animation to the view\r
38530             function createGridClipShape(rect, seriesModel, cb) {\r
38531                 var rectEl = new graphic.Rect({\r
38532                     shape: {\r
38533                         x: rect.x - 10,\r
38534                         y: rect.y - 10,\r
38535                         width: 0,\r
38536                         height: rect.height + 20\r
38537                     }\r
38538                 });\r
38539                 graphic.initProps(rectEl, {\r
38540                     shape: {\r
38541                         width: rect.width + 20,\r
38542                         height: rect.height + 20\r
38543                     }\r
38544                 }, seriesModel, cb);\r
38545 \r
38546                 return rectEl;\r
38547             }\r
38548 \r
38549 \r
38550 /***/ },\r
38551 /* 233 */\r
38552 /***/ function(module, exports, __webpack_require__) {\r
38553 \r
38554         \r
38555 \r
38556             var layout = __webpack_require__(21);\r
38557             var nest = __webpack_require__(234);\r
38558             var zrUtil = __webpack_require__(3);\r
38559 \r
38560             module.exports = function (ecModel, api) {\r
38561 \r
38562                 ecModel.eachSeriesByType('sankey', function (seriesModel) {\r
38563 \r
38564                     var nodeWidth = seriesModel.get('nodeWidth');\r
38565                     var nodeGap = seriesModel.get('nodeGap');\r
38566 \r
38567                     var layoutInfo = getViewRect(seriesModel, api);\r
38568 \r
38569                     seriesModel.layoutInfo = layoutInfo;\r
38570 \r
38571                     var width = layoutInfo.width;\r
38572                     var height = layoutInfo.height;\r
38573 \r
38574                     var graph = seriesModel.getGraph();\r
38575 \r
38576                     var nodes = graph.nodes;\r
38577                     var edges = graph.edges;\r
38578 \r
38579                     computeNodeValues(nodes);\r
38580 \r
38581                     var filteredNodes = nodes.filter(function (node) {\r
38582                         return node.getLayout().value === 0;\r
38583                     });\r
38584 \r
38585                     var iterations = filteredNodes.length !== 0\r
38586                         ? 0 : seriesModel.get('layoutIterations');\r
38587 \r
38588                     layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations);\r
38589                 });\r
38590             };\r
38591 \r
38592             /**\r
38593              * get the layout position of the whole view.\r
38594              */\r
38595             function getViewRect(seriesModel, api) {\r
38596                 return layout.getLayoutRect(\r
38597                     seriesModel.getBoxLayoutParams(), {\r
38598                         width: api.getWidth(),\r
38599                         height: api.getHeight()\r
38600                     }\r
38601                 );\r
38602             }\r
38603 \r
38604             function layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations) {\r
38605                 computeNodeBreadths(nodes, nodeWidth, width);\r
38606                 computeNodeDepths(nodes, edges, height, nodeGap, iterations);\r
38607                 computeEdgeDepths(nodes);\r
38608             }\r
38609 \r
38610             /**\r
38611              * compute the value of each node by summing the associated edge's value.\r
38612              * @param {module:echarts/data/Graph~Node} nodes\r
38613              */\r
38614             function computeNodeValues(nodes) {\r
38615                 zrUtil.each(nodes, function (node) {\r
38616                     var value1 = sum(node.outEdges, getEdgeValue);\r
38617                     var value2 = sum(node.inEdges, getEdgeValue);\r
38618                     var value = Math.max(value1, value2);\r
38619                     node.setLayout({value: value}, true);\r
38620                 });\r
38621             }\r
38622 \r
38623             /**\r
38624              * compute the x-position for each node.\r
38625              * @param {module:echarts/data/Graph~Node} nodes\r
38626              * @param  {number} nodeWidth\r
38627              * @param  {number} width\r
38628              */\r
38629             function computeNodeBreadths(nodes, nodeWidth, width) {\r
38630                 var remainNodes = nodes;\r
38631                 var nextNode = null;\r
38632                 var x = 0;\r
38633                 var kx = 0;\r
38634 \r
38635                 while (remainNodes.length) {\r
38636                     nextNode = [];\r
38637 \r
38638                     for (var i = 0, len = remainNodes.length; i < len; i++) {\r
38639                         var node = remainNodes[i];\r
38640                         node.setLayout({x: x}, true);\r
38641                         node.setLayout({dx: nodeWidth}, true);\r
38642 \r
38643                         for (var j = 0, lenj = node.outEdges.length; j < lenj; j++) {\r
38644                             nextNode.push(node.outEdges[j].node2);\r
38645                         }\r
38646                     }\r
38647                     remainNodes = nextNode;\r
38648                     ++x;\r
38649                 }\r
38650 \r
38651                 moveSinksRight(nodes, x);\r
38652                 kx = (width - nodeWidth) / (x - 1);\r
38653 \r
38654                 scaleNodeBreadths(nodes, kx);\r
38655             }\r
38656 \r
38657             /**\r
38658              * all the node without outEgdes are assigned maximum breadth and\r
38659              * be aligned in the last column.\r
38660              * @param {module:echarts/data/Graph~Node} nodes\r
38661              * @param {number} x\r
38662              */\r
38663             function moveSinksRight(nodes, x) {\r
38664                 zrUtil.each(nodes, function (node) {\r
38665                     if(!node.outEdges.length) {\r
38666                         node.setLayout({x: x-1}, true);\r
38667                     }\r
38668                 });\r
38669             }\r
38670 \r
38671             /**\r
38672              * scale node x-position to the width.\r
38673              * @param {module:echarts/data/Graph~Node} nodes\r
38674              * @param {number} kx\r
38675              */\r
38676             function scaleNodeBreadths(nodes, kx) {\r
38677                 zrUtil.each(nodes, function(node) {\r
38678                     var nodeX = node.getLayout().x * kx;\r
38679                     node.setLayout({x: nodeX}, true);\r
38680                 });\r
38681             }\r
38682 \r
38683             /**\r
38684              * using Gauss-Seidel iterations method to compute the node depth(y-position).\r
38685              * @param {module:echarts/data/Graph~Node} nodes\r
38686              * @param {module:echarts/data/Graph~Edge} edges\r
38687              * @param {number} height\r
38688              * @param {numbber} nodeGap\r
38689              * @param {number} iterations\r
38690              */\r
38691             function computeNodeDepths(nodes, edges, height, nodeGap, iterations) {\r
38692                 var nodesByBreadth = nest()\r
38693                     .key(function (d) {\r
38694                         return d.getLayout().x;\r
38695                     })\r
38696                     .sortKeys(ascending)\r
38697                     .entries(nodes)\r
38698                     .map(function (d) {\r
38699                         return d.values;\r
38700                     });\r
38701 \r
38702                 initializeNodeDepth(nodes, nodesByBreadth, edges, height, nodeGap);\r
38703                 resolveCollisions(nodesByBreadth, nodeGap, height);\r
38704 \r
38705                 for (var alpha = 1; iterations > 0; iterations--) {\r
38706                     alpha *= 0.99;\r
38707                     relaxRightToLeft(nodesByBreadth, alpha);\r
38708                     resolveCollisions(nodesByBreadth, nodeGap, height);\r
38709                     relaxLeftToRight(nodesByBreadth, alpha);\r
38710                     resolveCollisions(nodesByBreadth, nodeGap, height);\r
38711                 }\r
38712             }\r
38713 \r
38714             /**\r
38715              * compute the original y-position for each node.\r
38716              * @param {module:echarts/data/Graph~Node} nodes\r
38717              * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth\r
38718              * @param {module:echarts/data/Graph~Edge} edges\r
38719              * @param {number} height\r
38720              * @param {number} nodeGap\r
38721              */\r
38722             function initializeNodeDepth(nodes, nodesByBreadth, edges, height, nodeGap) {\r
38723                 var kyArray = [];\r
38724                 zrUtil.each(nodesByBreadth, function (nodes) {\r
38725                     var n = nodes.length;\r
38726                     var sum = 0;\r
38727                     zrUtil.each(nodes, function (node) {\r
38728                         sum += node.getLayout().value;\r
38729                     });\r
38730                     var ky = (height - (n-1) * nodeGap) / sum;\r
38731                     kyArray.push(ky);\r
38732                 });\r
38733                 kyArray.sort(function (a, b) {\r
38734                     return a - b;\r
38735                 });\r
38736                 var ky0 = kyArray[0];\r
38737 \r
38738                 zrUtil.each(nodesByBreadth, function (nodes) {\r
38739                     zrUtil.each(nodes, function (node, i) {\r
38740                         node.setLayout({y: i}, true);\r
38741                         var nodeDy = node.getLayout().value * ky0;\r
38742                         node.setLayout({dy: nodeDy}, true);\r
38743                     });\r
38744                 });\r
38745 \r
38746                 zrUtil.each(edges, function (edge) {\r
38747                     var edgeDy = +edge.getValue() * ky0;\r
38748                     edge.setLayout({dy: edgeDy}, true);\r
38749                 });\r
38750             }\r
38751 \r
38752             /**\r
38753              * resolve the collision of initialized depth.\r
38754              * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth\r
38755              * @param {number} nodeGap\r
38756              * @param {number} height\r
38757              */\r
38758             function resolveCollisions(nodesByBreadth, nodeGap, height) {\r
38759                 zrUtil.each(nodesByBreadth, function (nodes) {\r
38760                     var node;\r
38761                     var dy;\r
38762                     var y0 = 0;\r
38763                     var n = nodes.length;\r
38764                     var i;\r
38765 \r
38766                     nodes.sort(ascendingDepth);\r
38767 \r
38768                     for (i = 0; i < n; i++) {\r
38769                         node = nodes[i];\r
38770                         dy = y0 - node.getLayout().y;\r
38771                         if(dy > 0) {\r
38772                             var nodeY = node.getLayout().y + dy;\r
38773                             node.setLayout({y: nodeY}, true);\r
38774                         }\r
38775                         y0 = node.getLayout().y + node.getLayout().dy + nodeGap;\r
38776                     }\r
38777 \r
38778                     // if the bottommost node goes outside the biunds, push it back up\r
38779                     dy = y0 - nodeGap - height;\r
38780                     if (dy > 0) {\r
38781                         var nodeY = node.getLayout().y -dy;\r
38782                         node.setLayout({y: nodeY}, true);\r
38783                         y0 = node.getLayout().y;\r
38784                         for (i = n - 2; i >= 0; --i) {\r
38785                             node = nodes[i];\r
38786                             dy = node.getLayout().y + node.getLayout().dy + nodeGap - y0;\r
38787                             if (dy > 0) {\r
38788                                 nodeY = node.getLayout().y - dy;\r
38789                                 node.setLayout({y: nodeY}, true);\r
38790                             }\r
38791                             y0 = node.getLayout().y;\r
38792                         }\r
38793                     }\r
38794                 });\r
38795             }\r
38796 \r
38797             /**\r
38798              * change the y-position of the nodes, except most the right side nodes.\r
38799              * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth\r
38800              * @param {number} alpha\r
38801              */\r
38802             function relaxRightToLeft(nodesByBreadth, alpha) {\r
38803                 zrUtil.each(nodesByBreadth.slice().reverse(), function (nodes) {\r
38804                     zrUtil.each(nodes, function (node) {\r
38805                         if (node.outEdges.length) {\r
38806                             var y = sum(node.outEdges, weightedTarget) / sum(node.outEdges, getEdgeValue);\r
38807                             var nodeY = node.getLayout().y + (y - center(node)) * alpha;\r
38808                             node.setLayout({y: nodeY}, true);\r
38809                         }\r
38810                     });\r
38811                 });\r
38812             }\r
38813 \r
38814             function weightedTarget(edge) {\r
38815                 return center(edge.node2) * edge.getValue();\r
38816             }\r
38817 \r
38818             /**\r
38819              * change the y-position of the nodes, except most the left side nodes.\r
38820              * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth\r
38821              * @param {number} alpha\r
38822              */\r
38823             function relaxLeftToRight(nodesByBreadth, alpha) {\r
38824                 zrUtil.each(nodesByBreadth, function (nodes) {\r
38825                     zrUtil.each(nodes, function (node) {\r
38826                         if (node.inEdges.length) {\r
38827                             var y = sum(node.inEdges, weightedSource) / sum(node.inEdges, getEdgeValue);\r
38828                             var nodeY = node.getLayout().y + (y - center(node)) * alpha;\r
38829                             node.setLayout({y: nodeY}, true);\r
38830                         }\r
38831                     });\r
38832                 });\r
38833             }\r
38834 \r
38835             function weightedSource(edge) {\r
38836                 return center(edge.node1) * edge.getValue();\r
38837             }\r
38838 \r
38839             /**\r
38840              * compute the depth(y-position) of each edge.\r
38841              * @param {module:echarts/data/Graph~Node} nodes\r
38842              */\r
38843             function computeEdgeDepths(nodes) {\r
38844                 zrUtil.each(nodes, function (node) {\r
38845                     node.outEdges.sort(ascendingTargetDepth);\r
38846                     node.inEdges.sort(ascendingSourceDepth);\r
38847                 });\r
38848                 zrUtil.each(nodes, function (node) {\r
38849                     var sy = 0;\r
38850                     var ty = 0;\r
38851                     zrUtil.each(node.outEdges, function (edge) {\r
38852                         edge.setLayout({sy: sy}, true);\r
38853                         sy += edge.getLayout().dy;\r
38854                     });\r
38855                     zrUtil.each(node.inEdges, function (edge) {\r
38856                         edge.setLayout({ty: ty}, true);\r
38857                         ty += edge.getLayout().dy;\r
38858                     });\r
38859                 });\r
38860             }\r
38861 \r
38862             function ascendingTargetDepth(a, b) {\r
38863                 return a.node2.getLayout().y - b.node2.getLayout().y;\r
38864             }\r
38865 \r
38866             function ascendingSourceDepth(a, b) {\r
38867                 return a.node1.getLayout().y - b.node1.getLayout().y;\r
38868             }\r
38869 \r
38870             function sum(array, f) {\r
38871                 var s = 0;\r
38872                 var n = array.length;\r
38873                 var a;\r
38874                 var i = -1;\r
38875                 if (arguments.length === 1) {\r
38876                     while (++i < n) {\r
38877                         a = +array[i];\r
38878                         if (!isNaN(a)) {\r
38879                             s += a;\r
38880                         }\r
38881                     }\r
38882                 }\r
38883                 else {\r
38884                     while (++i < n) {\r
38885                         a = +f.call(array, array[i], i);\r
38886                         if(!isNaN(a)) {\r
38887                             s += a;\r
38888                         }\r
38889                     }\r
38890                 }\r
38891                 return s;\r
38892             }\r
38893 \r
38894             function center(node) {\r
38895                 return node.getLayout().y + node.getLayout().dy / 2;\r
38896             }\r
38897 \r
38898             function ascendingDepth(a, b) {\r
38899                 return a.getLayout().y - b.getLayout().y;\r
38900             }\r
38901 \r
38902             function ascending(a, b) {\r
38903                 return a < b ? -1 : a > b ? 1 : a == b ? 0 : NaN;\r
38904             }\r
38905 \r
38906             function getEdgeValue(edge) {\r
38907                 return edge.getValue();\r
38908             }\r
38909 \r
38910 \r
38911 \r
38912 /***/ },\r
38913 /* 234 */\r
38914 /***/ function(module, exports, __webpack_require__) {\r
38915 \r
38916         \r
38917 \r
38918             var zrUtil = __webpack_require__(3);\r
38919 \r
38920             /**\r
38921              * nest helper used to group by the array.\r
38922              * can specified the keys and sort the keys.\r
38923              */\r
38924             function nest() {\r
38925 \r
38926                 var keysFunction = [];\r
38927                 var sortKeysFunction = [];\r
38928 \r
38929                 /**\r
38930                  * map an Array into the mapObject.\r
38931                  * @param {Array} array\r
38932                  * @param {number} depth\r
38933                  */\r
38934                 function map(array, depth) {\r
38935                     if (depth >= keysFunction.length) {\r
38936                         return array;\r
38937                     }\r
38938                     var i = -1;\r
38939                     var n = array.length;\r
38940                     var keyFunction = keysFunction[depth++];\r
38941                     var mapObject = {};\r
38942                     var valuesByKey = {};\r
38943 \r
38944                     while (++i < n) {\r
38945                         var keyValue = keyFunction(array[i]);\r
38946                         var values = valuesByKey[keyValue];\r
38947 \r
38948                         if (values) {\r
38949                             values.push(array[i]);\r
38950                         }\r
38951                         else {\r
38952                             valuesByKey[keyValue] = [array[i]];\r
38953                         }\r
38954                     }\r
38955 \r
38956                     zrUtil.each(valuesByKey, function (value, key) {\r
38957                         mapObject[key] = map(value, depth);\r
38958                     });\r
38959 \r
38960                     return mapObject;\r
38961                 }\r
38962 \r
38963                 /**\r
38964                  * transform the Map Object to multidimensional Array\r
38965                  * @param {Object} map\r
38966                  * @param {number} depth\r
38967                  */\r
38968                 function entriesMap(mapObject, depth) {\r
38969                     if (depth >= keysFunction.length) {\r
38970                         return mapObject;\r
38971                     }\r
38972                     var array = [];\r
38973                     var sortKeyFunction = sortKeysFunction[depth++];\r
38974 \r
38975                     zrUtil.each(mapObject, function (value, key) {\r
38976                         array.push({\r
38977                             key: key, values: entriesMap(value, depth)\r
38978                         });\r
38979                     });\r
38980 \r
38981                     if (sortKeyFunction) {\r
38982                         return array.sort(function (a, b) {\r
38983                             return sortKeyFunction(a.key, b.key);\r
38984                         });\r
38985                     }\r
38986                     else {\r
38987                         return array;\r
38988                     }\r
38989                 }\r
38990 \r
38991                 return {\r
38992                     /**\r
38993                      * specified the key to groupby the arrays.\r
38994                      * users can specified one more keys.\r
38995                      * @param {Function} d\r
38996                      */\r
38997                     key: function (d) {\r
38998                         keysFunction.push(d);\r
38999                         return this;\r
39000                     },\r
39001 \r
39002                     /**\r
39003                      * specified the comparator to sort the keys\r
39004                      * @param {Function} order\r
39005                      */\r
39006                     sortKeys: function (order) {\r
39007                         sortKeysFunction[keysFunction.length - 1] = order;\r
39008                         return this;\r
39009                     },\r
39010 \r
39011                     /**\r
39012                      * the array to be grouped by.\r
39013                      * @param {Array} array\r
39014                      */\r
39015                     entries: function (array) {\r
39016                         return entriesMap(map(array, 0), 0);\r
39017                     }\r
39018                 };\r
39019             }\r
39020             module.exports = nest;\r
39021 \r
39022 \r
39023 /***/ },\r
39024 /* 235 */\r
39025 /***/ function(module, exports, __webpack_require__) {\r
39026 \r
39027         \r
39028 \r
39029             var VisualMapping = __webpack_require__(187);\r
39030 \r
39031             module.exports = function (ecModel, payload) {\r
39032                 ecModel.eachSeriesByType('sankey', function (seriesModel) {\r
39033                     var graph = seriesModel.getGraph();\r
39034                     var nodes = graph.nodes;\r
39035 \r
39036                     nodes.sort(function (a, b) {\r
39037                         return a.getLayout().value - b.getLayout().value;\r
39038                     });\r
39039 \r
39040                     var minValue = nodes[0].getLayout().value;\r
39041                     var maxValue = nodes[nodes.length - 1].getLayout().value;\r
39042 \r
39043                     nodes.forEach(function (node) {\r
39044                         var mapping = new VisualMapping({\r
39045                             type: 'color',\r
39046                             mappingMethod: 'linear',\r
39047                             dataExtent: [minValue, maxValue],\r
39048                             visual: seriesModel.get('color')\r
39049                         });\r
39050 \r
39051                         var mapValueToColor = mapping.mapValueToVisual(node.getLayout().value);\r
39052                         node.setVisual('color', mapValueToColor);\r
39053                     });\r
39054 \r
39055                 }) ;   \r
39056             };  \r
39057 \r
39058 \r
39059 /***/ },\r
39060 /* 236 */\r
39061 /***/ function(module, exports, __webpack_require__) {\r
39062 \r
39063         \r
39064 \r
39065             var echarts = __webpack_require__(1);\r
39066 \r
39067             __webpack_require__(237);\r
39068             __webpack_require__(240);\r
39069 \r
39070             echarts.registerVisualCoding('chart', __webpack_require__(241));\r
39071             echarts.registerLayout(__webpack_require__(242));\r
39072 \r
39073 \r
39074 \r
39075 /***/ },\r
39076 /* 237 */\r
39077 /***/ function(module, exports, __webpack_require__) {\r
39078 \r
39079         'use strict';\r
39080 \r
39081 \r
39082             var zrUtil = __webpack_require__(3);\r
39083             var SeriesModel = __webpack_require__(27);\r
39084             var whiskerBoxCommon = __webpack_require__(238);\r
39085 \r
39086             var BoxplotSeries = SeriesModel.extend({\r
39087 \r
39088                 type: 'series.boxplot',\r
39089 \r
39090                 dependencies: ['xAxis', 'yAxis', 'grid'],\r
39091 \r
39092                 // TODO\r
39093                 // box width represents group size, so dimension should have 'size'.\r
39094 \r
39095                 /**\r
39096                  * @see <https://en.wikipedia.org/wiki/Box_plot>\r
39097                  * The meanings of 'min' and 'max' depend on user,\r
39098                  * and echarts do not need to know it.\r
39099                  * @readOnly\r
39100                  */\r
39101                 valueDimensions: ['min', 'Q1', 'median', 'Q3', 'max'],\r
39102 \r
39103                 /**\r
39104                  * @type {Array.<string>}\r
39105                  * @readOnly\r
39106                  */\r
39107                 dimensions: null,\r
39108 \r
39109                 /**\r
39110                  * @override\r
39111                  */\r
39112                 defaultOption: {\r
39113                     zlevel: 0,                  // 一级层叠\r
39114                     z: 2,                       // 二级层叠\r
39115                     coordinateSystem: 'cartesian2d',\r
39116                     legendHoverLink: true,\r
39117 \r
39118                     hoverAnimation: true,\r
39119 \r
39120                     xAxisIndex: 0,\r
39121                     yAxisIndex: 0,\r
39122 \r
39123                     layout: null,               // 'horizontal' or 'vertical'\r
39124                     boxWidth: [7, 50],       // [min, max] can be percent of band width.\r
39125 \r
39126                     itemStyle: {\r
39127                         normal: {\r
39128                             color: '#fff',\r
39129                             borderWidth: 1\r
39130                         },\r
39131                         emphasis: {\r
39132                             borderWidth: 2,\r
39133                             shadowBlur: 5,\r
39134                             shadowOffsetX: 2,\r
39135                             shadowOffsetY: 2,\r
39136                             shadowColor: 'rgba(0,0,0,0.4)'\r
39137                         }\r
39138                     },\r
39139 \r
39140                     animationEasing: 'elasticOut',\r
39141                     animationDuration: 800\r
39142                 }\r
39143             });\r
39144 \r
39145             zrUtil.mixin(BoxplotSeries, whiskerBoxCommon.seriesModelMixin, true);\r
39146 \r
39147             module.exports = BoxplotSeries;\r
39148 \r
39149 \r
39150 \r
39151 /***/ },\r
39152 /* 238 */\r
39153 /***/ function(module, exports, __webpack_require__) {\r
39154 \r
39155         'use strict';\r
39156 \r
39157 \r
39158             var List = __webpack_require__(94);\r
39159             var completeDimensions = __webpack_require__(96);\r
39160             var WhiskerBoxDraw = __webpack_require__(239);\r
39161             var zrUtil = __webpack_require__(3);\r
39162 \r
39163             function getItemValue(item) {\r
39164                 return item.value == null ? item : item.value;\r
39165             }\r
39166 \r
39167             var seriesModelMixin = {\r
39168 \r
39169                 /**\r
39170                  * @private\r
39171                  * @type {string}\r
39172                  */\r
39173                 _baseAxisDim: null,\r
39174 \r
39175                 /**\r
39176                  * @override\r
39177                  */\r
39178                 getInitialData: function (option, ecModel) {\r
39179                     // When both types of xAxis and yAxis are 'value', layout is\r
39180                     // needed to be specified by user. Otherwise, layout can be\r
39181                     // judged by which axis is category.\r
39182 \r
39183                     var categories;\r
39184 \r
39185                     var xAxisModel = ecModel.getComponent('xAxis', this.get('xAxisIndex'));\r
39186                     var yAxisModel = ecModel.getComponent('yAxis', this.get('yAxisIndex'));\r
39187                     var xAxisType = xAxisModel.get('type');\r
39188                     var yAxisType = yAxisModel.get('type');\r
39189                     var addOrdinal;\r
39190 \r
39191                     // FIXME\r
39192                     // 考虑时间轴\r
39193 \r
39194                     if (xAxisType === 'category') {\r
39195                         option.layout = 'horizontal';\r
39196                         categories = xAxisModel.getCategories();\r
39197                         addOrdinal = true;\r
39198                     }\r
39199                     else if (yAxisType  === 'category') {\r
39200                         option.layout = 'vertical';\r
39201                         categories = yAxisModel.getCategories();\r
39202                         addOrdinal = true;\r
39203                     }\r
39204                     else {\r
39205                         option.layout = option.layout || 'horizontal';\r
39206                     }\r
39207 \r
39208                     this._baseAxisDim = option.layout === 'horizontal' ? 'x' : 'y';\r
39209 \r
39210                     var data = option.data;\r
39211                     var dimensions = this.dimensions = ['base'].concat(this.valueDimensions);\r
39212                     completeDimensions(dimensions, data);\r
39213 \r
39214                     var list = new List(dimensions, this);\r
39215                     list.initData(data, categories ? categories.slice() : null, function (dataItem, dimName, idx, dimIdx) {\r
39216                         var value = getItemValue(dataItem);\r
39217                         return addOrdinal ? (dimName === 'base' ? idx : value[dimIdx - 1]) : value[dimIdx];\r
39218                     });\r
39219 \r
39220                     return list;\r
39221                 },\r
39222 \r
39223                 /**\r
39224                  * Used by Gird.\r
39225                  * @param {string} axisDim 'x' or 'y'\r
39226                  * @return {Array.<string>} dimensions on the axis.\r
39227                  */\r
39228                 coordDimToDataDim: function (axisDim) {\r
39229                     var dims = this.valueDimensions.slice();\r
39230                     var baseDim = ['base'];\r
39231                     var map = {\r
39232                         horizontal: {x: baseDim, y: dims},\r
39233                         vertical: {x: dims, y: baseDim}\r
39234                     };\r
39235                     return map[this.get('layout')][axisDim];\r
39236                 },\r
39237 \r
39238                 /**\r
39239                  * @override\r
39240                  * @param {string|number} dataDim\r
39241                  * @return {string} coord dimension\r
39242                  */\r
39243                 dataDimToCoordDim: function (dataDim) {\r
39244                     var dim;\r
39245 \r
39246                     zrUtil.each(['x', 'y'], function (coordDim, index) {\r
39247                         var dataDims = this.coordDimToDataDim(coordDim);\r
39248                         if (zrUtil.indexOf(dataDims, dataDim) >= 0) {\r
39249                             dim = coordDim;\r
39250                         }\r
39251                     }, this);\r
39252 \r
39253                     return dim;\r
39254                 },\r
39255 \r
39256                 /**\r
39257                  * If horizontal, base axis is x, otherwise y.\r
39258                  * @override\r
39259                  */\r
39260                 getBaseAxis: function () {\r
39261                     var dim = this._baseAxisDim;\r
39262                     return this.ecModel.getComponent(dim + 'Axis', this.get(dim + 'AxisIndex')).axis;\r
39263                 }\r
39264             };\r
39265 \r
39266             var viewMixin = {\r
39267 \r
39268                 init: function () {\r
39269                     /**\r
39270                      * Old data.\r
39271                      * @private\r
39272                      * @type {module:echarts/chart/helper/WhiskerBoxDraw}\r
39273                      */\r
39274                     var whiskerBoxDraw = this._whiskerBoxDraw = new WhiskerBoxDraw(\r
39275                         this.getStyleUpdater()\r
39276                     );\r
39277                     this.group.add(whiskerBoxDraw.group);\r
39278                 },\r
39279 \r
39280                 render: function (seriesModel, ecModel, api) {\r
39281                     this._whiskerBoxDraw.updateData(seriesModel.getData());\r
39282                 },\r
39283 \r
39284                 remove: function (ecModel) {\r
39285                     this._whiskerBoxDraw.remove();\r
39286                 }\r
39287             };\r
39288 \r
39289             module.exports = {\r
39290                 seriesModelMixin: seriesModelMixin,\r
39291                 viewMixin: viewMixin\r
39292             };\r
39293 \r
39294 \r
39295 /***/ },\r
39296 /* 239 */\r
39297 /***/ function(module, exports, __webpack_require__) {\r
39298 \r
39299         /**\r
39300          * @module echarts/chart/helper/Symbol\r
39301          */\r
39302 \r
39303 \r
39304             var zrUtil = __webpack_require__(3);\r
39305             var graphic = __webpack_require__(42);\r
39306             var Path = __webpack_require__(44);\r
39307 \r
39308             var WhiskerPath = Path.extend({\r
39309 \r
39310                 type: 'whiskerInBox',\r
39311 \r
39312                 shape: {},\r
39313 \r
39314                 buildPath: function (ctx, shape) {\r
39315                     for (var i in shape) {\r
39316                         if (i.indexOf('ends') === 0) {\r
39317                             var pts = shape[i];\r
39318                             ctx.moveTo(pts[0][0], pts[0][1]);\r
39319                             ctx.lineTo(pts[1][0], pts[1][1]);\r
39320                         }\r
39321                     }\r
39322                 }\r
39323             });\r
39324 \r
39325             /**\r
39326              * @constructor\r
39327              * @alias {module:echarts/chart/helper/WhiskerBox}\r
39328              * @param {module:echarts/data/List} data\r
39329              * @param {number} idx\r
39330              * @param {Function} styleUpdater\r
39331              * @param {boolean} isInit\r
39332              * @extends {module:zrender/graphic/Group}\r
39333              */\r
39334             function WhiskerBox(data, idx, styleUpdater, isInit) {\r
39335                 graphic.Group.call(this);\r
39336 \r
39337                 /**\r
39338                  * @type {number}\r
39339                  * @readOnly\r
39340                  */\r
39341                 this.bodyIndex;\r
39342 \r
39343                 /**\r
39344                  * @type {number}\r
39345                  * @readOnly\r
39346                  */\r
39347                 this.whiskerIndex;\r
39348 \r
39349                 /**\r
39350                  * @type {Function}\r
39351                  */\r
39352                 this.styleUpdater = styleUpdater;\r
39353 \r
39354                 this._createContent(data, idx, isInit);\r
39355 \r
39356                 this.updateData(data, idx, isInit);\r
39357 \r
39358                 /**\r
39359                  * Last series model.\r
39360                  * @type {module:echarts/model/Series}\r
39361                  */\r
39362                 this._seriesModel;\r
39363             }\r
39364 \r
39365             var whiskerBoxProto = WhiskerBox.prototype;\r
39366 \r
39367             whiskerBoxProto._createContent = function (data, idx, isInit) {\r
39368                 var itemLayout = data.getItemLayout(idx);\r
39369                 var constDim = itemLayout.chartLayout === 'horizontal' ? 1 : 0;\r
39370                 var count = 0;\r
39371 \r
39372                 // Whisker element.\r
39373                 this.add(new graphic.Polygon({\r
39374                     shape: {\r
39375                         points: isInit\r
39376                             ? transInit(itemLayout.bodyEnds, constDim, itemLayout)\r
39377                             : itemLayout.bodyEnds\r
39378                     },\r
39379                     style: {strokeNoScale: true},\r
39380                     z2: 100\r
39381                 }));\r
39382                 this.bodyIndex = count++;\r
39383 \r
39384                 // Box element.\r
39385                 var whiskerEnds = zrUtil.map(itemLayout.whiskerEnds, function (ends) {\r
39386                     return isInit ? transInit(ends, constDim, itemLayout) : ends;\r
39387                 });\r
39388                 this.add(new WhiskerPath({\r
39389                     shape: makeWhiskerEndsShape(whiskerEnds),\r
39390                     style: {strokeNoScale: true},\r
39391                     z2: 100\r
39392                 }));\r
39393                 this.whiskerIndex = count++;\r
39394             };\r
39395 \r
39396             function transInit(points, dim, itemLayout) {\r
39397                 return zrUtil.map(points, function (point) {\r
39398                     point = point.slice();\r
39399                     point[dim] = itemLayout.initBaseline;\r
39400                     return point;\r
39401                 });\r
39402             }\r
39403 \r
39404             function makeWhiskerEndsShape(whiskerEnds) {\r
39405                 // zr animation only support 2-dim array.\r
39406                 var shape = {};\r
39407                 zrUtil.each(whiskerEnds, function (ends, i) {\r
39408                     shape['ends' + i] = ends;\r
39409                 });\r
39410                 return shape;\r
39411             }\r
39412 \r
39413             /**\r
39414              * Update symbol properties\r
39415              * @param  {module:echarts/data/List} data\r
39416              * @param  {number} idx\r
39417              */\r
39418             whiskerBoxProto.updateData = function (data, idx, isInit) {\r
39419                 var seriesModel = this._seriesModel = data.hostModel;\r
39420                 var itemLayout = data.getItemLayout(idx);\r
39421                 var updateMethod = graphic[isInit ? 'initProps' : 'updateProps'];\r
39422                 // this.childAt(this.bodyIndex).stopAnimation(true);\r
39423                 // this.childAt(this.whiskerIndex).stopAnimation(true);\r
39424                 updateMethod(\r
39425                     this.childAt(this.bodyIndex),\r
39426                     {shape: {points: itemLayout.bodyEnds}},\r
39427                     seriesModel\r
39428                 );\r
39429                 updateMethod(\r
39430                     this.childAt(this.whiskerIndex),\r
39431                     {shape: makeWhiskerEndsShape(itemLayout.whiskerEnds)},\r
39432                     seriesModel\r
39433                 );\r
39434 \r
39435                 this.styleUpdater.call(null, this, data, idx);\r
39436             };\r
39437 \r
39438             zrUtil.inherits(WhiskerBox, graphic.Group);\r
39439 \r
39440 \r
39441             /**\r
39442              * @constructor\r
39443              * @alias module:echarts/chart/helper/WhiskerBoxDraw\r
39444              */\r
39445             function WhiskerBoxDraw(styleUpdater) {\r
39446                 this.group = new graphic.Group();\r
39447                 this.styleUpdater = styleUpdater;\r
39448             }\r
39449 \r
39450             var whiskerBoxDrawProto = WhiskerBoxDraw.prototype;\r
39451 \r
39452             /**\r
39453              * Update symbols draw by new data\r
39454              * @param {module:echarts/data/List} data\r
39455              */\r
39456             whiskerBoxDrawProto.updateData = function (data) {\r
39457                 var group = this.group;\r
39458                 var oldData = this._data;\r
39459                 var styleUpdater = this.styleUpdater;\r
39460 \r
39461                 data.diff(oldData)\r
39462                     .add(function (newIdx) {\r
39463                         if (data.hasValue(newIdx)) {\r
39464                             var symbolEl = new WhiskerBox(data, newIdx, styleUpdater, true);\r
39465                             data.setItemGraphicEl(newIdx, symbolEl);\r
39466                             group.add(symbolEl);\r
39467                         }\r
39468                     })\r
39469                     .update(function (newIdx, oldIdx) {\r
39470                         var symbolEl = oldData.getItemGraphicEl(oldIdx);\r
39471 \r
39472                         // Empty data\r
39473                         if (!data.hasValue(newIdx)) {\r
39474                             group.remove(symbolEl);\r
39475                             return;\r
39476                         }\r
39477 \r
39478                         if (!symbolEl) {\r
39479                             symbolEl = new WhiskerBox(data, newIdx, styleUpdater);\r
39480                         }\r
39481                         else {\r
39482                             symbolEl.updateData(data, newIdx);\r
39483                         }\r
39484 \r
39485                         // Add back\r
39486                         group.add(symbolEl);\r
39487 \r
39488                         data.setItemGraphicEl(newIdx, symbolEl);\r
39489                     })\r
39490                     .remove(function (oldIdx) {\r
39491                         var el = oldData.getItemGraphicEl(oldIdx);\r
39492                         el && group.remove(el);\r
39493                     })\r
39494                     .execute();\r
39495 \r
39496                 this._data = data;\r
39497             };\r
39498 \r
39499             /**\r
39500              * Remove symbols.\r
39501              * @param {module:echarts/data/List} data\r
39502              */\r
39503             whiskerBoxDrawProto.remove = function () {\r
39504                 var group = this.group;\r
39505                 var data = this._data;\r
39506                 this._data = null;\r
39507                 data && data.eachItemGraphicEl(function (el) {\r
39508                     el && group.remove(el);\r
39509                 });\r
39510             };\r
39511 \r
39512             module.exports = WhiskerBoxDraw;\r
39513 \r
39514 \r
39515 /***/ },\r
39516 /* 240 */\r
39517 /***/ function(module, exports, __webpack_require__) {\r
39518 \r
39519         'use strict';\r
39520 \r
39521 \r
39522             var zrUtil = __webpack_require__(3);\r
39523             var ChartView = __webpack_require__(41);\r
39524             var graphic = __webpack_require__(42);\r
39525             var whiskerBoxCommon = __webpack_require__(238);\r
39526 \r
39527             var BoxplotView = ChartView.extend({\r
39528 \r
39529                 type: 'boxplot',\r
39530 \r
39531                 getStyleUpdater: function () {\r
39532                     return updateStyle;\r
39533                 }\r
39534             });\r
39535 \r
39536             zrUtil.mixin(BoxplotView, whiskerBoxCommon.viewMixin, true);\r
39537 \r
39538             // Update common properties\r
39539             var normalStyleAccessPath = ['itemStyle', 'normal'];\r
39540             var emphasisStyleAccessPath = ['itemStyle', 'emphasis'];\r
39541 \r
39542             function updateStyle(itemGroup, data, idx) {\r
39543                 var itemModel = data.getItemModel(idx);\r
39544                 var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);\r
39545                 var borderColor = data.getItemVisual(idx, 'color');\r
39546 \r
39547                 // Exclude borderColor.\r
39548                 var itemStyle = normalItemStyleModel.getItemStyle(['borderColor']);\r
39549 \r
39550                 var whiskerEl = itemGroup.childAt(itemGroup.whiskerIndex);\r
39551                 whiskerEl.style.set(itemStyle);\r
39552                 whiskerEl.style.stroke = borderColor;\r
39553                 whiskerEl.dirty();\r
39554 \r
39555                 var bodyEl = itemGroup.childAt(itemGroup.bodyIndex);\r
39556                 bodyEl.style.set(itemStyle);\r
39557                 bodyEl.style.stroke = borderColor;\r
39558                 bodyEl.dirty();\r
39559 \r
39560                 var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();\r
39561                 graphic.setHoverStyle(itemGroup, hoverStyle);\r
39562             }\r
39563 \r
39564             module.exports = BoxplotView;\r
39565 \r
39566 \r
39567 \r
39568 /***/ },\r
39569 /* 241 */\r
39570 /***/ function(module, exports) {\r
39571 \r
39572         \r
39573 \r
39574             var borderColorQuery = ['itemStyle', 'normal', 'borderColor'];\r
39575 \r
39576             module.exports = function (ecModel, api) {\r
39577 \r
39578                 var globalColors = ecModel.get('color');\r
39579 \r
39580                 ecModel.eachRawSeriesByType('boxplot', function (seriesModel) {\r
39581 \r
39582                     var defaulColor = globalColors[seriesModel.seriesIndex % globalColors.length];\r
39583                     var data = seriesModel.getData();\r
39584 \r
39585                     data.setVisual({\r
39586                         legendSymbol: 'roundRect',\r
39587                         // Use name 'color' but not 'borderColor' for legend usage and\r
39588                         // visual coding from other component like dataRange.\r
39589                         color: seriesModel.get(borderColorQuery) || defaulColor\r
39590                     });\r
39591 \r
39592                     // Only visible series has each data be visual encoded\r
39593                     if (!ecModel.isSeriesFiltered(seriesModel)) {\r
39594                         data.each(function (idx) {\r
39595                             var itemModel = data.getItemModel(idx);\r
39596                             data.setItemVisual(\r
39597                                 idx,\r
39598                                 {color: itemModel.get(borderColorQuery, true)}\r
39599                             );\r
39600                         });\r
39601                     }\r
39602                 });\r
39603 \r
39604             };\r
39605 \r
39606 \r
39607 /***/ },\r
39608 /* 242 */\r
39609 /***/ function(module, exports, __webpack_require__) {\r
39610 \r
39611         \r
39612 \r
39613             var zrUtil = __webpack_require__(3);\r
39614             var numberUtil = __webpack_require__(7);\r
39615             var parsePercent = numberUtil.parsePercent;\r
39616             var each = zrUtil.each;\r
39617 \r
39618             module.exports = function (ecModel, api) {\r
39619 \r
39620                 var groupResult = groupSeriesByAxis(ecModel);\r
39621 \r
39622                 each(groupResult, function (groupItem) {\r
39623                     var seriesModels = groupItem.seriesModels;\r
39624 \r
39625                     if (!seriesModels.length) {\r
39626                         return;\r
39627                     }\r
39628 \r
39629                     calculateBase(groupItem);\r
39630 \r
39631                     each(seriesModels, function (seriesModel, idx) {\r
39632                         layoutSingleSeries(\r
39633                             seriesModel,\r
39634                             groupItem.boxOffsetList[idx],\r
39635                             groupItem.boxWidthList[idx]\r
39636                         );\r
39637                     });\r
39638                 });\r
39639             };\r
39640 \r
39641             /**\r
39642              * Group series by axis.\r
39643              */\r
39644             function groupSeriesByAxis(ecModel) {\r
39645                 var result = [];\r
39646                 var axisList = [];\r
39647 \r
39648                 ecModel.eachSeriesByType('boxplot', function (seriesModel) {\r
39649                     var baseAxis = seriesModel.getBaseAxis();\r
39650                     var idx = zrUtil.indexOf(axisList, baseAxis);\r
39651 \r
39652                     if (idx < 0) {\r
39653                         idx = axisList.length;\r
39654                         axisList[idx] = baseAxis;\r
39655                         result[idx] = {axis: baseAxis, seriesModels: []};\r
39656                     }\r
39657 \r
39658                     result[idx].seriesModels.push(seriesModel);\r
39659                 });\r
39660 \r
39661                 return result;\r
39662             }\r
39663 \r
39664             /**\r
39665              * Calculate offset and box width for each series.\r
39666              */\r
39667             function calculateBase(groupItem) {\r
39668                 var extent;\r
39669                 var baseAxis = groupItem.axis;\r
39670                 var seriesModels = groupItem.seriesModels;\r
39671                 var seriesCount = seriesModels.length;\r
39672 \r
39673                 var boxWidthList = groupItem.boxWidthList = [];\r
39674                 var boxOffsetList = groupItem.boxOffsetList = [];\r
39675                 var boundList = [];\r
39676 \r
39677                 var bandWidth;\r
39678                 if (baseAxis.type === 'category') {\r
39679                     bandWidth = baseAxis.getBandWidth();\r
39680                 }\r
39681                 else {\r
39682                     var maxDataCount = 0;\r
39683                     each(seriesModels, function (seriesModel) {\r
39684                         maxDataCount = Math.max(maxDataCount, seriesModel.getData().count());\r
39685                     });\r
39686                     extent = baseAxis.getExtent(),\r
39687                     Math.abs(extent[1] - extent[0]) / maxDataCount;\r
39688                 }\r
39689 \r
39690                 each(seriesModels, function (seriesModel) {\r
39691                     var boxWidthBound = seriesModel.get('boxWidth');\r
39692                     if (!zrUtil.isArray(boxWidthBound)) {\r
39693                         boxWidthBound = [boxWidthBound, boxWidthBound];\r
39694                     }\r
39695                     boundList.push([\r
39696                         parsePercent(boxWidthBound[0], bandWidth) || 0,\r
39697                         parsePercent(boxWidthBound[1], bandWidth) || 0\r
39698                     ]);\r
39699                 });\r
39700 \r
39701                 var availableWidth = bandWidth * 0.8 - 2;\r
39702                 var boxGap = availableWidth / seriesCount * 0.3;\r
39703                 var boxWidth = (availableWidth - boxGap * (seriesCount - 1)) / seriesCount;\r
39704                 var base = boxWidth / 2 - availableWidth / 2;\r
39705 \r
39706                 each(seriesModels, function (seriesModel, idx) {\r
39707                     boxOffsetList.push(base);\r
39708                     base += boxGap + boxWidth;\r
39709 \r
39710                     boxWidthList.push(\r
39711                         Math.min(Math.max(boxWidth, boundList[idx][0]), boundList[idx][1])\r
39712                     );\r
39713                 });\r
39714             }\r
39715 \r
39716             /**\r
39717              * Calculate points location for each series.\r
39718              */\r
39719             function layoutSingleSeries(seriesModel, offset, boxWidth) {\r
39720                 var coordSys = seriesModel.coordinateSystem;\r
39721                 var data = seriesModel.getData();\r
39722                 var dimensions = seriesModel.dimensions;\r
39723                 var chartLayout = seriesModel.get('layout');\r
39724                 var halfWidth = boxWidth / 2;\r
39725 \r
39726                 data.each(dimensions, function () {\r
39727                     var args = arguments;\r
39728                     var dimLen = dimensions.length;\r
39729                     var axisDimVal = args[0];\r
39730                     var idx = args[dimLen];\r
39731                     var variableDim = chartLayout === 'horizontal' ? 0 : 1;\r
39732                     var constDim = 1 - variableDim;\r
39733 \r
39734                     var median = getPoint(args[3]);\r
39735                     var end1 = getPoint(args[1]);\r
39736                     var end5 = getPoint(args[5]);\r
39737                     var whiskerEnds = [\r
39738                         [end1, getPoint(args[2])],\r
39739                         [end5, getPoint(args[4])]\r
39740                     ];\r
39741                     layEndLine(end1);\r
39742                     layEndLine(end5);\r
39743                     layEndLine(median);\r
39744 \r
39745                     var bodyEnds = [];\r
39746                     addBodyEnd(whiskerEnds[0][1], 0);\r
39747                     addBodyEnd(whiskerEnds[1][1], 1);\r
39748 \r
39749                     data.setItemLayout(idx, {\r
39750                         chartLayout: chartLayout,\r
39751                         initBaseline: median[constDim],\r
39752                         median: median,\r
39753                         bodyEnds: bodyEnds,\r
39754                         whiskerEnds: whiskerEnds\r
39755                     });\r
39756 \r
39757                     function getPoint(val) {\r
39758                         var p = [];\r
39759                         p[variableDim] = axisDimVal;\r
39760                         p[constDim] = val;\r
39761                         var point;\r
39762                         if (isNaN(axisDimVal) || isNaN(val)) {\r
39763                             point = [NaN, NaN];\r
39764                         }\r
39765                         else {\r
39766                             point = coordSys.dataToPoint(p);\r
39767                             point[variableDim] += offset;\r
39768                         }\r
39769                         return point;\r
39770                     }\r
39771 \r
39772                     function addBodyEnd(point, start) {\r
39773                         var point1 = point.slice();\r
39774                         var point2 = point.slice();\r
39775                         point1[variableDim] += halfWidth;\r
39776                         point2[variableDim] -= halfWidth;\r
39777                         start\r
39778                             ? bodyEnds.push(point1, point2)\r
39779                             : bodyEnds.push(point2, point1);\r
39780                     }\r
39781 \r
39782                     function layEndLine(endCenter) {\r
39783                         var line = [endCenter.slice(), endCenter.slice()];\r
39784                         line[0][variableDim] -= halfWidth;\r
39785                         line[1][variableDim] += halfWidth;\r
39786                         whiskerEnds.push(line);\r
39787                     }\r
39788                 });\r
39789             }\r
39790 \r
39791 \r
39792 \r
39793 /***/ },\r
39794 /* 243 */\r
39795 /***/ function(module, exports, __webpack_require__) {\r
39796 \r
39797         \r
39798 \r
39799             var echarts = __webpack_require__(1);\r
39800 \r
39801             __webpack_require__(244);\r
39802             __webpack_require__(245);\r
39803 \r
39804             echarts.registerPreprocessor(\r
39805                 __webpack_require__(246)\r
39806             );\r
39807 \r
39808             echarts.registerVisualCoding('chart', __webpack_require__(247));\r
39809             echarts.registerLayout(__webpack_require__(248));\r
39810 \r
39811 \r
39812 \r
39813 /***/ },\r
39814 /* 244 */\r
39815 /***/ function(module, exports, __webpack_require__) {\r
39816 \r
39817         'use strict';\r
39818 \r
39819 \r
39820             var zrUtil = __webpack_require__(3);\r
39821             var SeriesModel = __webpack_require__(27);\r
39822             var whiskerBoxCommon = __webpack_require__(238);\r
39823             var formatUtil = __webpack_require__(6);\r
39824             var encodeHTML = formatUtil.encodeHTML;\r
39825             var addCommas = formatUtil.addCommas;\r
39826 \r
39827             var CandlestickSeries = SeriesModel.extend({\r
39828 \r
39829                 type: 'series.candlestick',\r
39830 \r
39831                 dependencies: ['xAxis', 'yAxis', 'grid'],\r
39832 \r
39833                 /**\r
39834                  * @readOnly\r
39835                  */\r
39836                 valueDimensions: ['open', 'close', 'lowest', 'highest'],\r
39837 \r
39838                 /**\r
39839                  * @type {Array.<string>}\r
39840                  * @readOnly\r
39841                  */\r
39842                 dimensions: null,\r
39843 \r
39844                 /**\r
39845                  * @override\r
39846                  */\r
39847                 defaultOption: {\r
39848                     zlevel: 0,                  // 一级层叠\r
39849                     z: 2,                       // 二级层叠\r
39850                     coordinateSystem: 'cartesian2d',\r
39851                     legendHoverLink: true,\r
39852 \r
39853                     hoverAnimation: true,\r
39854 \r
39855                     xAxisIndex: 0,\r
39856                     yAxisIndex: 0,\r
39857 \r
39858                     layout: null, // 'horizontal' or 'vertical'\r
39859 \r
39860                     itemStyle: {\r
39861                         normal: {\r
39862                             color: '#c23531', // 阳线 positive\r
39863                             color0: '#314656', // 阴线 negative     '#c23531', '#314656'\r
39864                             borderWidth: 1,\r
39865                             // FIXME\r
39866                             // ec2中使用的是lineStyle.color 和 lineStyle.color0\r
39867                             borderColor: '#c23531',\r
39868                             borderColor0: '#314656'\r
39869                         },\r
39870                         emphasis: {\r
39871                             borderWidth: 2\r
39872                         }\r
39873                     },\r
39874 \r
39875                     animationUpdate: false,\r
39876                     animationEasing: 'linear',\r
39877                     animationDuration: 300\r
39878                 },\r
39879 \r
39880                 /**\r
39881                  * Get dimension for shadow in dataZoom\r
39882                  * @return {string} dimension name\r
39883                  */\r
39884                 getShadowDim: function () {\r
39885                     return 'open';\r
39886                 },\r
39887 \r
39888                 /**\r
39889                  * @override\r
39890                  */\r
39891                 formatTooltip: function (dataIndex, mutipleSeries) {\r
39892                     // It rearly use mutiple candlestick series in one cartesian,\r
39893                     // so only consider one series in this default tooltip.\r
39894                     var valueHTMLArr = zrUtil.map(this.valueDimensions, function (dim) {\r
39895                         return dim + ': ' + addCommas(this._data.get(dim, dataIndex));\r
39896                     }, this);\r
39897 \r
39898                     return encodeHTML(this.name) + '<br />' + valueHTMLArr.join('<br />');\r
39899                 }\r
39900 \r
39901             });\r
39902 \r
39903             zrUtil.mixin(CandlestickSeries, whiskerBoxCommon.seriesModelMixin, true);\r
39904 \r
39905             module.exports = CandlestickSeries;\r
39906 \r
39907 \r
39908 \r
39909 /***/ },\r
39910 /* 245 */\r
39911 /***/ function(module, exports, __webpack_require__) {\r
39912 \r
39913         'use strict';\r
39914 \r
39915 \r
39916             var zrUtil = __webpack_require__(3);\r
39917             var ChartView = __webpack_require__(41);\r
39918             var graphic = __webpack_require__(42);\r
39919             var whiskerBoxCommon = __webpack_require__(238);\r
39920 \r
39921             var CandlestickView = ChartView.extend({\r
39922 \r
39923                 type: 'candlestick',\r
39924 \r
39925                 getStyleUpdater: function () {\r
39926                     return updateStyle;\r
39927                 }\r
39928 \r
39929             });\r
39930 \r
39931             zrUtil.mixin(CandlestickView, whiskerBoxCommon.viewMixin, true);\r
39932 \r
39933             // Update common properties\r
39934             var normalStyleAccessPath = ['itemStyle', 'normal'];\r
39935             var emphasisStyleAccessPath = ['itemStyle', 'emphasis'];\r
39936 \r
39937             function updateStyle(itemGroup, data, idx) {\r
39938                 var itemModel = data.getItemModel(idx);\r
39939                 var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);\r
39940                 var color = data.getItemVisual(idx, 'color');\r
39941                 var borderColor = data.getItemVisual(idx, 'borderColor');\r
39942 \r
39943                 // Color must be excluded.\r
39944                 // Because symbol provide setColor individually to set fill and stroke\r
39945                 var itemStyle = normalItemStyleModel.getItemStyle(\r
39946                     ['color', 'color0', 'borderColor', 'borderColor0']\r
39947                 );\r
39948 \r
39949                 var whiskerEl = itemGroup.childAt(itemGroup.whiskerIndex);\r
39950                 whiskerEl.style.set(itemStyle);\r
39951                 whiskerEl.style.stroke = borderColor;\r
39952                 whiskerEl.dirty();\r
39953 \r
39954                 var bodyEl = itemGroup.childAt(itemGroup.bodyIndex);\r
39955                 bodyEl.style.set(itemStyle);\r
39956                 bodyEl.style.fill = color;\r
39957                 bodyEl.style.stroke = borderColor;\r
39958                 bodyEl.dirty();\r
39959 \r
39960                 var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();\r
39961                 graphic.setHoverStyle(itemGroup, hoverStyle);\r
39962             }\r
39963 \r
39964 \r
39965             module.exports = CandlestickView;\r
39966 \r
39967 \r
39968 \r
39969 /***/ },\r
39970 /* 246 */\r
39971 /***/ function(module, exports, __webpack_require__) {\r
39972 \r
39973         \r
39974 \r
39975             var zrUtil = __webpack_require__(3);\r
39976 \r
39977             module.exports = function (option) {\r
39978                 if (!option || !zrUtil.isArray(option.series)) {\r
39979                     return;\r
39980                 }\r
39981 \r
39982                 // Translate 'k' to 'candlestick'.\r
39983                 zrUtil.each(option.series, function (seriesItem) {\r
39984                     if (zrUtil.isObject(seriesItem) && seriesItem.type === 'k') {\r
39985                         seriesItem.type = 'candlestick';\r
39986                     }\r
39987                 });\r
39988             };\r
39989 \r
39990 \r
39991 \r
39992 /***/ },\r
39993 /* 247 */\r
39994 /***/ function(module, exports) {\r
39995 \r
39996         \r
39997 \r
39998             var positiveBorderColorQuery = ['itemStyle', 'normal', 'borderColor'];\r
39999             var negativeBorderColorQuery = ['itemStyle', 'normal', 'borderColor0'];\r
40000             var positiveColorQuery = ['itemStyle', 'normal', 'color'];\r
40001             var negativeColorQuery = ['itemStyle', 'normal', 'color0'];\r
40002 \r
40003             module.exports = function (ecModel, api) {\r
40004 \r
40005                 ecModel.eachRawSeriesByType('candlestick', function (seriesModel) {\r
40006 \r
40007                     var data = seriesModel.getData();\r
40008 \r
40009                     data.setVisual({\r
40010                         legendSymbol: 'roundRect'\r
40011                     });\r
40012 \r
40013                     // Only visible series has each data be visual encoded\r
40014                     if (!ecModel.isSeriesFiltered(seriesModel)) {\r
40015                         data.each(function (idx) {\r
40016                             var itemModel = data.getItemModel(idx);\r
40017                             var sign = data.getItemLayout(idx).sign;\r
40018 \r
40019                             data.setItemVisual(\r
40020                                 idx,\r
40021                                 {\r
40022                                     color: itemModel.get(\r
40023                                         sign > 0 ? positiveColorQuery : negativeColorQuery\r
40024                                     ),\r
40025                                     borderColor: itemModel.get(\r
40026                                         sign > 0 ? positiveBorderColorQuery : negativeBorderColorQuery\r
40027                                     )\r
40028                                 }\r
40029                             );\r
40030                         });\r
40031                     }\r
40032                 });\r
40033 \r
40034             };\r
40035 \r
40036 \r
40037 /***/ },\r
40038 /* 248 */\r
40039 /***/ function(module, exports) {\r
40040 \r
40041         \r
40042 \r
40043             var CANDLE_MIN_WIDTH = 2;\r
40044             var CANDLE_MIN_NICE_WIDTH = 5;\r
40045             var GPA_MIN = 4;\r
40046 \r
40047             module.exports = function (ecModel, api) {\r
40048 \r
40049                 ecModel.eachSeriesByType('candlestick', function (seriesModel) {\r
40050 \r
40051                     var coordSys = seriesModel.coordinateSystem;\r
40052                     var data = seriesModel.getData();\r
40053                     var dimensions = seriesModel.dimensions;\r
40054                     var chartLayout = seriesModel.get('layout');\r
40055 \r
40056                     var candleWidth = calculateCandleWidth(seriesModel, data);\r
40057 \r
40058                     data.each(dimensions, function () {\r
40059                         var args = arguments;\r
40060                         var dimLen = dimensions.length;\r
40061                         var axisDimVal = args[0];\r
40062                         var idx = args[dimLen];\r
40063                         var variableDim = chartLayout === 'horizontal' ? 0 : 1;\r
40064                         var constDim = 1 - variableDim;\r
40065 \r
40066                         var openVal = args[1];\r
40067                         var closeVal = args[2];\r
40068                         var lowestVal = args[3];\r
40069                         var highestVal = args[4];\r
40070 \r
40071                         var ocLow = Math.min(openVal, closeVal);\r
40072                         var ocHigh = Math.max(openVal, closeVal);\r
40073 \r
40074                         var ocLowPoint = getPoint(ocLow);\r
40075                         var ocHighPoint = getPoint(ocHigh);\r
40076                         var lowestPoint = getPoint(lowestVal);\r
40077                         var highestPoint = getPoint(highestVal);\r
40078 \r
40079                         var whiskerEnds = [\r
40080                             [highestPoint, ocHighPoint],\r
40081                             [lowestPoint, ocLowPoint]\r
40082                         ];\r
40083 \r
40084                         var bodyEnds = [];\r
40085                         addBodyEnd(ocHighPoint, 0);\r
40086                         addBodyEnd(ocLowPoint, 1);\r
40087 \r
40088                         data.setItemLayout(idx, {\r
40089                             chartLayout: chartLayout,\r
40090                             sign: openVal > closeVal ? -1 : openVal < closeVal ? 1 : 0,\r
40091                             initBaseline: openVal > closeVal\r
40092                                 ? ocHighPoint[constDim] : ocLowPoint[constDim], // open point.\r
40093                             bodyEnds: bodyEnds,\r
40094                             whiskerEnds: whiskerEnds\r
40095                         });\r
40096 \r
40097                         function getPoint(val) {\r
40098                             var p = [];\r
40099                             p[variableDim] = axisDimVal;\r
40100                             p[constDim] = val;\r
40101                             return (isNaN(axisDimVal) || isNaN(val))\r
40102                                 ? [NaN, NaN]\r
40103                                 : coordSys.dataToPoint(p);\r
40104                         }\r
40105 \r
40106                         function addBodyEnd(point, start) {\r
40107                             var point1 = point.slice();\r
40108                             var point2 = point.slice();\r
40109                             point1[variableDim] += candleWidth / 2;\r
40110                             point2[variableDim] -= candleWidth / 2;\r
40111                             start\r
40112                                 ? bodyEnds.push(point1, point2)\r
40113                                 : bodyEnds.push(point2, point1);\r
40114                         }\r
40115 \r
40116                     }, true);\r
40117                 });\r
40118             };\r
40119 \r
40120             function calculateCandleWidth(seriesModel, data) {\r
40121                 var baseAxis = seriesModel.getBaseAxis();\r
40122                 var extent;\r
40123 \r
40124                 var bandWidth = baseAxis.type === 'category'\r
40125                     ? baseAxis.getBandWidth()\r
40126                     : (\r
40127                         extent = baseAxis.getExtent(),\r
40128                         Math.abs(extent[1] - extent[0]) / data.count()\r
40129                     );\r
40130 \r
40131                 // Half band width is perfect when space is enouph, otherwise\r
40132                 // try not to be smaller than CANDLE_MIN_NICE_WIDTH (and only\r
40133                 // gap is compressed), otherwise ensure not to be smaller than\r
40134                 // CANDLE_MIN_WIDTH in spite of overlap.\r
40135 \r
40136                 return bandWidth / 2 - 2 > CANDLE_MIN_NICE_WIDTH // "- 2" is minus border width\r
40137                     ? bandWidth / 2 - 2\r
40138                     : bandWidth - CANDLE_MIN_NICE_WIDTH > GPA_MIN\r
40139                     ? CANDLE_MIN_NICE_WIDTH\r
40140                     : Math.max(bandWidth - GPA_MIN, CANDLE_MIN_WIDTH);\r
40141             }\r
40142 \r
40143 \r
40144 \r
40145 /***/ },\r
40146 /* 249 */\r
40147 /***/ function(module, exports, __webpack_require__) {\r
40148 \r
40149         \r
40150 \r
40151             var zrUtil = __webpack_require__(3);\r
40152             var echarts = __webpack_require__(1);\r
40153 \r
40154             __webpack_require__(250);\r
40155             __webpack_require__(251);\r
40156 \r
40157             echarts.registerVisualCoding('chart', zrUtil.curry(\r
40158                 __webpack_require__(103), 'effectScatter', 'circle', null\r
40159             ));\r
40160             echarts.registerLayout(zrUtil.curry(\r
40161                 __webpack_require__(104), 'effectScatter'\r
40162             ));\r
40163 \r
40164 \r
40165 /***/ },\r
40166 /* 250 */\r
40167 /***/ function(module, exports, __webpack_require__) {\r
40168 \r
40169         'use strict';\r
40170 \r
40171 \r
40172             var createListFromArray = __webpack_require__(93);\r
40173             var SeriesModel = __webpack_require__(27);\r
40174 \r
40175             module.exports = SeriesModel.extend({\r
40176 \r
40177                 type: 'series.effectScatter',\r
40178 \r
40179                 dependencies: ['grid', 'polar'],\r
40180 \r
40181                 getInitialData: function (option, ecModel) {\r
40182                     var list = createListFromArray(option.data, this, ecModel);\r
40183                     return list;\r
40184                 },\r
40185 \r
40186                 defaultOption: {\r
40187                     coordinateSystem: 'cartesian2d',\r
40188                     zlevel: 0,\r
40189                     z: 2,\r
40190                     legendHoverLink: true,\r
40191 \r
40192                     effectType: 'ripple',\r
40193 \r
40194                     // When to show the effect, option: 'render'|'emphasis'\r
40195                     showEffectOn: 'render',\r
40196 \r
40197                     // Ripple effect config\r
40198                     rippleEffect: {\r
40199                         period: 4,\r
40200                         // Scale of ripple\r
40201                         scale: 2.5,\r
40202                         // Brush type can be fill or stroke\r
40203                         brushType: 'fill'\r
40204                     },\r
40205 \r
40206                     // Cartesian coordinate system\r
40207                     xAxisIndex: 0,\r
40208                     yAxisIndex: 0,\r
40209 \r
40210                     // Polar coordinate system\r
40211                     polarIndex: 0,\r
40212 \r
40213                     // Geo coordinate system\r
40214                     geoIndex: 0,\r
40215 \r
40216                     // symbol: null,        // 图形类型\r
40217                     symbolSize: 10          // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2\r
40218                     // symbolRotate: null,  // 图形旋转控制\r
40219 \r
40220                     // large: false,\r
40221                     // Available when large is true\r
40222                     // largeThreshold: 2000,\r
40223 \r
40224                     // itemStyle: {\r
40225                     //     normal: {\r
40226                     //         opacity: 1\r
40227                     //     }\r
40228                     // }\r
40229                 }\r
40230             });\r
40231 \r
40232 \r
40233 /***/ },\r
40234 /* 251 */\r
40235 /***/ function(module, exports, __webpack_require__) {\r
40236 \r
40237         \r
40238 \r
40239             var SymbolDraw = __webpack_require__(98);\r
40240             var EffectSymbol = __webpack_require__(252);\r
40241 \r
40242             __webpack_require__(1).extendChartView({\r
40243 \r
40244                 type: 'effectScatter',\r
40245 \r
40246                 init: function () {\r
40247                     this._symbolDraw = new SymbolDraw(EffectSymbol);\r
40248                 },\r
40249 \r
40250                 render: function (seriesModel, ecModel, api) {\r
40251                     var data = seriesModel.getData();\r
40252                     var effectSymbolDraw = this._symbolDraw;\r
40253                     effectSymbolDraw.updateData(data);\r
40254                     this.group.add(effectSymbolDraw.group);\r
40255                 },\r
40256 \r
40257                 updateLayout: function () {\r
40258                     this._symbolDraw.updateLayout();\r
40259                 },\r
40260 \r
40261                 remove: function (ecModel, api) {\r
40262                     this._symbolDraw && this._symbolDraw.remove(api);\r
40263                 }\r
40264             });\r
40265 \r
40266 \r
40267 /***/ },\r
40268 /* 252 */\r
40269 /***/ function(module, exports, __webpack_require__) {\r
40270 \r
40271         /**\r
40272          * Symbol with ripple effect\r
40273          * @module echarts/chart/helper/EffectSymbol\r
40274          */\r
40275 \r
40276 \r
40277             var zrUtil = __webpack_require__(3);\r
40278             var symbolUtil = __webpack_require__(100);\r
40279             var graphic = __webpack_require__(42);\r
40280             var numberUtil = __webpack_require__(7);\r
40281             var Symbol = __webpack_require__(99);\r
40282             var Group = graphic.Group;\r
40283 \r
40284             var EFFECT_RIPPLE_NUMBER = 3;\r
40285 \r
40286             function normalizeSymbolSize(symbolSize) {\r
40287                 if (!zrUtil.isArray(symbolSize)) {\r
40288                     symbolSize = [+symbolSize, +symbolSize];\r
40289                 }\r
40290                 return symbolSize;\r
40291             }\r
40292             /**\r
40293              * @constructor\r
40294              * @param {module:echarts/data/List} data\r
40295              * @param {number} idx\r
40296              * @extends {module:zrender/graphic/Group}\r
40297              */\r
40298             function EffectSymbol(data, idx) {\r
40299                 Group.call(this);\r
40300 \r
40301                 var symbol = new Symbol(data, idx);\r
40302                 var rippleGroup = new Group();\r
40303                 this.add(symbol);\r
40304                 this.add(rippleGroup);\r
40305 \r
40306                 rippleGroup.beforeUpdate = function () {\r
40307                     this.attr(symbol.getScale());\r
40308                 };\r
40309                 this.updateData(data, idx);\r
40310             }\r
40311 \r
40312             var effectSymbolProto = EffectSymbol.prototype;\r
40313 \r
40314             effectSymbolProto.stopEffectAnimation = function () {\r
40315                 this.childAt(1).removeAll();\r
40316             };\r
40317 \r
40318             effectSymbolProto.startEffectAnimation = function (\r
40319                 period, brushType, rippleScale, effectOffset, z, zlevel\r
40320             ) {\r
40321                 var symbolType = this._symbolType;\r
40322                 var color = this._color;\r
40323 \r
40324                 var rippleGroup = this.childAt(1);\r
40325 \r
40326                 for (var i = 0; i < EFFECT_RIPPLE_NUMBER; i++) {\r
40327                     var ripplePath = symbolUtil.createSymbol(\r
40328                         symbolType, -0.5, -0.5, 1, 1, color\r
40329                     );\r
40330                     ripplePath.attr({\r
40331                         style: {\r
40332                             stroke: brushType === 'stroke' ? color : null,\r
40333                             fill: brushType === 'fill' ? color : null,\r
40334                             strokeNoScale: true\r
40335                         },\r
40336                         z2: 99,\r
40337                         silent: true,\r
40338                         scale: [1, 1],\r
40339                         z: z,\r
40340                         zlevel: zlevel\r
40341                     });\r
40342 \r
40343                     var delay = -i / EFFECT_RIPPLE_NUMBER * period + effectOffset;\r
40344                     // TODO Configurable period\r
40345                     ripplePath.animate('', true)\r
40346                         .when(period, {\r
40347                             scale: [rippleScale, rippleScale]\r
40348                         })\r
40349                         .delay(delay)\r
40350                         .start();\r
40351                     ripplePath.animateStyle(true)\r
40352                         .when(period, {\r
40353                             opacity: 0\r
40354                         })\r
40355                         .delay(delay)\r
40356                         .start();\r
40357 \r
40358                     rippleGroup.add(ripplePath);\r
40359                 }\r
40360             };\r
40361 \r
40362             /**\r
40363              * Highlight symbol\r
40364              */\r
40365             effectSymbolProto.highlight = function () {\r
40366                 this.trigger('emphasis');\r
40367             };\r
40368 \r
40369             /**\r
40370              * Downplay symbol\r
40371              */\r
40372             effectSymbolProto.downplay = function () {\r
40373                 this.trigger('normal');\r
40374             };\r
40375 \r
40376             /**\r
40377              * Update symbol properties\r
40378              * @param  {module:echarts/data/List} data\r
40379              * @param  {number} idx\r
40380              */\r
40381             effectSymbolProto.updateData = function (data, idx) {\r
40382                 var seriesModel = data.hostModel;\r
40383 \r
40384                 this.childAt(0).updateData(data, idx);\r
40385 \r
40386                 var rippleGroup = this.childAt(1);\r
40387                 var itemModel = data.getItemModel(idx);\r
40388                 var symbolType = data.getItemVisual(idx, 'symbol');\r
40389                 var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));\r
40390                 var color = data.getItemVisual(idx, 'color');\r
40391 \r
40392                 rippleGroup.attr('scale', symbolSize);\r
40393 \r
40394                 rippleGroup.traverse(function (ripplePath) {\r
40395                     ripplePath.attr({\r
40396                         fill: color\r
40397                     });\r
40398                 });\r
40399 \r
40400                 var symbolOffset = itemModel.getShallow('symbolOffset');\r
40401                 if (symbolOffset) {\r
40402                     var pos = rippleGroup.position;\r
40403                     pos[0] = numberUtil.parsePercent(symbolOffset[0], symbolSize[0]);\r
40404                     pos[1] = numberUtil.parsePercent(symbolOffset[1], symbolSize[1]);\r
40405                 }\r
40406 \r
40407                 this._symbolType = symbolType;\r
40408                 this._color = color;\r
40409 \r
40410                 var showEffectOn = seriesModel.get('showEffectOn');\r
40411                 var rippleScale = itemModel.get('rippleEffect.scale');\r
40412                 var brushType = itemModel.get('rippleEffect.brushType');\r
40413                 var effectPeriod = itemModel.get('rippleEffect.period') * 1000;\r
40414                 var effectOffset = idx / data.count();\r
40415                 var z = itemModel.getShallow('z') || 0;\r
40416                 var zlevel = itemModel.getShallow('zlevel') || 0;\r
40417 \r
40418                 this.stopEffectAnimation();\r
40419                 if (showEffectOn === 'render') {\r
40420                     this.startEffectAnimation(\r
40421                         effectPeriod, brushType, rippleScale, effectOffset, z, zlevel\r
40422                     );\r
40423                 }\r
40424                 var symbol = this.childAt(0);\r
40425                 function onEmphasis() {\r
40426                     symbol.trigger('emphasis');\r
40427                     if (showEffectOn !== 'render') {\r
40428                         this.startEffectAnimation(\r
40429                             effectPeriod, brushType, rippleScale, effectOffset, z, zlevel\r
40430                         );\r
40431                     }\r
40432                 }\r
40433                 function onNormal() {\r
40434                     symbol.trigger('normal');\r
40435                     if (showEffectOn !== 'render') {\r
40436                         this.stopEffectAnimation();\r
40437                     }\r
40438                 }\r
40439                 this.on('mouseover', onEmphasis, this)\r
40440                     .on('mouseout', onNormal, this)\r
40441                     .on('emphasis', onEmphasis, this)\r
40442                     .on('normal', onNormal, this);\r
40443             };\r
40444 \r
40445             effectSymbolProto.fadeOut = function (cb) {\r
40446                 cb && cb();\r
40447             };\r
40448 \r
40449             zrUtil.inherits(EffectSymbol, Group);\r
40450 \r
40451             module.exports = EffectSymbol;\r
40452 \r
40453 \r
40454 /***/ },\r
40455 /* 253 */\r
40456 /***/ function(module, exports, __webpack_require__) {\r
40457 \r
40458         \r
40459 \r
40460             __webpack_require__(254);\r
40461             __webpack_require__(255);\r
40462 \r
40463             var zrUtil = __webpack_require__(3);\r
40464             var echarts = __webpack_require__(1);\r
40465             echarts.registerLayout(\r
40466                 __webpack_require__(257)\r
40467             );\r
40468 \r
40469             echarts.registerVisualCoding(\r
40470                 'chart', zrUtil.curry(__webpack_require__(88), 'lines', 'lineStyle')\r
40471             );\r
40472 \r
40473 \r
40474 /***/ },\r
40475 /* 254 */\r
40476 /***/ function(module, exports, __webpack_require__) {\r
40477 \r
40478         'use strict';\r
40479 \r
40480 \r
40481             var SeriesModel = __webpack_require__(27);\r
40482             var List = __webpack_require__(94);\r
40483             var zrUtil = __webpack_require__(3);\r
40484             var CoordinateSystem = __webpack_require__(25);\r
40485 \r
40486             module.exports = SeriesModel.extend({\r
40487 \r
40488                 type: 'series.lines',\r
40489 \r
40490                 dependencies: ['grid', 'polar'],\r
40491 \r
40492                 getInitialData: function (option, ecModel) {\r
40493                     var fromDataArr = [];\r
40494                     var toDataArr = [];\r
40495                     var lineDataArr = [];\r
40496                     zrUtil.each(option.data, function (opt) {\r
40497                         fromDataArr.push(opt[0]);\r
40498                         toDataArr.push(opt[1]);\r
40499                         lineDataArr.push(zrUtil.extend(\r
40500                             zrUtil.extend({}, zrUtil.isArray(opt[0]) ? null : opt[0]),\r
40501                             zrUtil.isArray(opt[1]) ? null : opt[1]\r
40502                         ));\r
40503                     });\r
40504 \r
40505                     // var coordSys = option.coordinateSystem;\r
40506                     // if (coordSys !== 'cartesian2d' && coordSys !== 'geo') {\r
40507                     //     throw new Error('Coordinate system can only be cartesian2d or geo in lines');\r
40508                     // }\r
40509 \r
40510                     // var dimensions = coordSys === 'geo' ? ['lng', 'lat'] : ['x', 'y'];\r
40511                     var coordSys = CoordinateSystem.get(option.coordinateSystem);\r
40512                     if (!coordSys) {\r
40513                         throw new Error('Invalid coordinate system');\r
40514                     }\r
40515                     var dimensions = coordSys.dimensions;\r
40516 \r
40517                     var fromData = new List(dimensions, this);\r
40518                     var toData = new List(dimensions, this);\r
40519                     var lineData = new List(['value'], this);\r
40520 \r
40521                     function geoCoordGetter(item, dim, dataIndex, dimIndex) {\r
40522                         return item.coord && item.coord[dimIndex];\r
40523                     }\r
40524 \r
40525                     fromData.initData(fromDataArr, null, geoCoordGetter);\r
40526                     toData.initData(toDataArr, null, geoCoordGetter);\r
40527                     lineData.initData(lineDataArr);\r
40528 \r
40529                     this.fromData = fromData;\r
40530                     this.toData = toData;\r
40531 \r
40532                     return lineData;\r
40533                 },\r
40534 \r
40535                 formatTooltip: function (dataIndex) {\r
40536                     var fromName = this.fromData.getName(dataIndex);\r
40537                     var toName = this.toData.getName(dataIndex);\r
40538                     return fromName + ' > ' + toName;\r
40539                 },\r
40540 \r
40541                 defaultOption: {\r
40542                     coordinateSystem: 'geo',\r
40543                     zlevel: 0,\r
40544                     z: 2,\r
40545                     legendHoverLink: true,\r
40546 \r
40547                     hoverAnimation: true,\r
40548                     // Cartesian coordinate system\r
40549                     xAxisIndex: 0,\r
40550                     yAxisIndex: 0,\r
40551 \r
40552                     // Geo coordinate system\r
40553                     geoIndex: 0,\r
40554 \r
40555                     // symbol: null,\r
40556                     // symbolSize: 10,\r
40557                     // symbolRotate: null,\r
40558 \r
40559                     effect: {\r
40560                         show: false,\r
40561                         period: 4,\r
40562                         symbol: 'circle',\r
40563                         symbolSize: 3,\r
40564                         // Length of trail, 0 - 1\r
40565                         trailLength: 0.2\r
40566                         // Same with lineStyle.normal.color\r
40567                         // color\r
40568                     },\r
40569 \r
40570                     large: false,\r
40571                     // Available when large is true\r
40572                     largeThreshold: 2000,\r
40573 \r
40574                     label: {\r
40575                         normal: {\r
40576                             show: false,\r
40577                             position: 'end'\r
40578                             // distance: 5,\r
40579                             // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调\r
40580                         }\r
40581                     },\r
40582                     // itemStyle: {\r
40583                     //     normal: {\r
40584                     //     }\r
40585                     // },\r
40586                     lineStyle: {\r
40587                         normal: {\r
40588                             opacity: 0.5\r
40589                         }\r
40590                     }\r
40591                 }\r
40592             });\r
40593 \r
40594 \r
40595 /***/ },\r
40596 /* 255 */\r
40597 /***/ function(module, exports, __webpack_require__) {\r
40598 \r
40599         \r
40600 \r
40601             var LineDraw = __webpack_require__(194);\r
40602             var EffectLine = __webpack_require__(256);\r
40603             var Line = __webpack_require__(195);\r
40604 \r
40605             __webpack_require__(1).extendChartView({\r
40606 \r
40607                 type: 'lines',\r
40608 \r
40609                 init: function () {},\r
40610 \r
40611                 render: function (seriesModel, ecModel, api) {\r
40612                     var data = seriesModel.getData();\r
40613                     var lineDraw = this._lineDraw;\r
40614 \r
40615                     var hasEffect = seriesModel.get('effect.show');\r
40616                     if (hasEffect !== this._hasEffet) {\r
40617                         if (lineDraw) {\r
40618                             lineDraw.remove();\r
40619                         }\r
40620                         lineDraw = this._lineDraw = new LineDraw(\r
40621                             hasEffect ? EffectLine : Line\r
40622                         );\r
40623                         this._hasEffet = hasEffect;\r
40624                     }\r
40625 \r
40626                     var zlevel = seriesModel.get('zlevel');\r
40627                     var trailLength = seriesModel.get('effect.trailLength');\r
40628 \r
40629                     var zr = api.getZr();\r
40630                     // Avoid the drag cause ghost shadow\r
40631                     // FIXME Better way ?\r
40632                     zr.painter.getLayer(zlevel).clear(true);\r
40633                     // Config layer with motion blur\r
40634                     if (this._lastZlevel != null) {\r
40635                         zr.configLayer(this._lastZlevel, {\r
40636                             motionBlur: false\r
40637                         });\r
40638                     }\r
40639                     if (hasEffect && trailLength) {\r
40640                         zr.configLayer(zlevel, {\r
40641                             motionBlur: true,\r
40642                             lastFrameAlpha: Math.max(Math.min(trailLength / 10 + 0.9, 1), 0)\r
40643                         });\r
40644                     }\r
40645 \r
40646                     this.group.add(lineDraw.group);\r
40647 \r
40648                     lineDraw.updateData(data);\r
40649 \r
40650                     this._lastZlevel = zlevel;\r
40651                 },\r
40652 \r
40653                 updateLayout: function (seriesModel, ecModel, api) {\r
40654                     this._lineDraw.updateLayout();\r
40655                     // Not use motion when dragging or zooming\r
40656                     var zr = api.getZr();\r
40657                     zr.painter.getLayer(this._lastZlevel).clear(true);\r
40658                 },\r
40659 \r
40660                 remove: function (ecModel, api) {\r
40661                     this._lineDraw && this._lineDraw.remove(api, true);\r
40662                 }\r
40663             });\r
40664 \r
40665 \r
40666 /***/ },\r
40667 /* 256 */\r
40668 /***/ function(module, exports, __webpack_require__) {\r
40669 \r
40670         /**\r
40671          * @module echarts/chart/helper/EffectLine\r
40672          */\r
40673 \r
40674 \r
40675             var graphic = __webpack_require__(42);\r
40676             var Line = __webpack_require__(195);\r
40677             var zrUtil = __webpack_require__(3);\r
40678             var symbolUtil = __webpack_require__(100);\r
40679 \r
40680             var curveUtil = __webpack_require__(49);\r
40681 \r
40682             /**\r
40683              * @constructor\r
40684              * @extends {module:zrender/graphic/Group}\r
40685              * @alias {module:echarts/chart/helper/Line}\r
40686              */\r
40687             function EffectLine(lineData, fromData, toData, idx) {\r
40688                 graphic.Group.call(this);\r
40689 \r
40690                 var line = new Line(lineData, fromData, toData, idx);\r
40691                 this.add(line);\r
40692 \r
40693                 this._updateEffectSymbol(lineData, idx);\r
40694             }\r
40695 \r
40696             var effectLineProto = EffectLine.prototype;\r
40697 \r
40698             function setAnimationPoints(symbol, points) {\r
40699                 symbol.__p1 = points[0];\r
40700                 symbol.__p2 = points[1];\r
40701                 symbol.__cp1 = points[2] || [\r
40702                     (points[0][0] + points[1][0]) / 2,\r
40703                     (points[0][1] + points[1][1]) / 2\r
40704                 ];\r
40705             }\r
40706 \r
40707             function updateSymbolPosition() {\r
40708                 var p1 = this.__p1;\r
40709                 var p2 = this.__p2;\r
40710                 var cp1 = this.__cp1;\r
40711                 var t = this.__t;\r
40712                 var pos = this.position;\r
40713                 var quadraticAt = curveUtil.quadraticAt;\r
40714                 var quadraticDerivativeAt = curveUtil.quadraticDerivativeAt;\r
40715                 pos[0] = quadraticAt(p1[0], cp1[0], p2[0], t);\r
40716                 pos[1] = quadraticAt(p1[1], cp1[1], p2[1], t);\r
40717 \r
40718                 // Tangent\r
40719                 var tx = quadraticDerivativeAt(p1[0], cp1[0], p2[0], t);\r
40720                 var ty = quadraticDerivativeAt(p1[1], cp1[1], p2[1], t);\r
40721 \r
40722                 this.rotation = -Math.atan2(ty, tx) - Math.PI / 2;\r
40723 \r
40724                 this.ignore = false;\r
40725             }\r
40726 \r
40727             effectLineProto._updateEffectSymbol = function (lineData, idx) {\r
40728                 var itemModel = lineData.getItemModel(idx);\r
40729                 var effectModel = itemModel.getModel('effect');\r
40730                 var size = effectModel.get('symbolSize');\r
40731                 var symbolType = effectModel.get('symbol');\r
40732                 if (!zrUtil.isArray(size)) {\r
40733                     size = [size, size];\r
40734                 }\r
40735                 var color = effectModel.get('color') || lineData.getItemVisual(idx, 'color');\r
40736                 var symbol = this.childAt(1);\r
40737                 var period = effectModel.get('period') * 1000;\r
40738                 if (this._symbolType !== symbolType || period !== this._period) {\r
40739                     symbol = symbolUtil.createSymbol(\r
40740                         symbolType, -0.5, -0.5, 1, 1, color\r
40741                     );\r
40742                     symbol.ignore = true;\r
40743                     symbol.z2 = 100;\r
40744                     this._symbolType = symbolType;\r
40745                     this._period = period;\r
40746 \r
40747                     this.add(symbol);\r
40748 \r
40749                     symbol.__t = 0;\r
40750                     symbol.animate('', true)\r
40751                         .when(period, {\r
40752                             __t: 1\r
40753                         })\r
40754                         .delay(idx / lineData.count() * period / 2)\r
40755                         .during(zrUtil.bind(updateSymbolPosition, symbol))\r
40756                         .start();\r
40757                 }\r
40758                 // Shadow color is same with color in default\r
40759                 symbol.setStyle('shadowColor', color);\r
40760                 symbol.setStyle(effectModel.getItemStyle(['color']));\r
40761 \r
40762                 symbol.attr('scale', size);\r
40763                 var points = lineData.getItemLayout(idx);\r
40764                 setAnimationPoints(symbol, points);\r
40765 \r
40766                 symbol.setColor(color);\r
40767                 symbol.attr('scale', size);\r
40768             };\r
40769 \r
40770             effectLineProto.updateData = function (lineData, fromData, toData, idx) {\r
40771                 this.childAt(0).updateData(lineData, fromData, toData, idx);\r
40772                 this._updateEffectSymbol(lineData, idx);\r
40773             };\r
40774 \r
40775             effectLineProto.updateLayout = function (lineData, fromData, toData, idx) {\r
40776                 this.childAt(0).updateLayout(lineData, fromData, toData, idx);\r
40777                 var symbol = this.childAt(1);\r
40778                 var points = lineData.getItemLayout(idx);\r
40779                 setAnimationPoints(symbol, points);\r
40780             };\r
40781 \r
40782             zrUtil.inherits(EffectLine, graphic.Group);\r
40783 \r
40784             module.exports = EffectLine;\r
40785 \r
40786 \r
40787 /***/ },\r
40788 /* 257 */\r
40789 /***/ function(module, exports) {\r
40790 \r
40791         \r
40792 \r
40793             module.exports = function (ecModel) {\r
40794                 ecModel.eachSeriesByType('lines', function (seriesModel) {\r
40795                     var coordSys = seriesModel.coordinateSystem;\r
40796                     var fromData = seriesModel.fromData;\r
40797                     var toData = seriesModel.toData;\r
40798                     var lineData = seriesModel.getData();\r
40799 \r
40800                     var dims = coordSys.dimensions;\r
40801                     fromData.each(dims, function (x, y, idx) {\r
40802                         fromData.setItemLayout(idx, coordSys.dataToPoint([x, y]));\r
40803                     });\r
40804                     toData.each(dims, function (x, y, idx) {\r
40805                         toData.setItemLayout(idx, coordSys.dataToPoint([x, y]));\r
40806                     });\r
40807                     lineData.each(function (idx) {\r
40808                         var p1 = fromData.getItemLayout(idx);\r
40809                         var p2 = toData.getItemLayout(idx);\r
40810                         var curveness = lineData.getItemModel(idx).get('lineStyle.normal.curveness');\r
40811                         var cp1;\r
40812                         if (curveness > 0) {\r
40813                             cp1 = [\r
40814                                 (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * curveness,\r
40815                                 (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * curveness\r
40816                             ];\r
40817                         }\r
40818                         lineData.setItemLayout(idx, [p1, p2, cp1]);\r
40819                     });\r
40820                 });\r
40821             };\r
40822 \r
40823 \r
40824 /***/ },\r
40825 /* 258 */\r
40826 /***/ function(module, exports, __webpack_require__) {\r
40827 \r
40828         \r
40829 \r
40830             __webpack_require__(259);\r
40831             __webpack_require__(260);\r
40832 \r
40833 \r
40834 /***/ },\r
40835 /* 259 */\r
40836 /***/ function(module, exports, __webpack_require__) {\r
40837 \r
40838         \r
40839 \r
40840             var SeriesModel = __webpack_require__(27);\r
40841             var createListFromArray = __webpack_require__(93);\r
40842 \r
40843             module.exports = SeriesModel.extend({\r
40844                 type: 'series.heatmap',\r
40845 \r
40846                 getInitialData: function (option, ecModel) {\r
40847                     return createListFromArray(option.data, this, ecModel);\r
40848                 },\r
40849 \r
40850                 defaultOption: {\r
40851 \r
40852                     // Cartesian2D or geo\r
40853                     coordinateSystem: 'cartesian2d',\r
40854 \r
40855                     zlevel: 0,\r
40856 \r
40857                     z: 2,\r
40858 \r
40859                     // Cartesian coordinate system\r
40860                     xAxisIndex: 0,\r
40861                     yAxisIndex: 0,\r
40862 \r
40863                     // Geo coordinate system\r
40864                     geoIndex: 0,\r
40865 \r
40866                     blurSize: 30,\r
40867 \r
40868                     pointSize: 20,\r
40869 \r
40870                     maxOpacity: 1,\r
40871 \r
40872                     minOpacity: 0\r
40873                 }\r
40874             });\r
40875 \r
40876 \r
40877 /***/ },\r
40878 /* 260 */\r
40879 /***/ function(module, exports, __webpack_require__) {\r
40880 \r
40881         \r
40882 \r
40883             var graphic = __webpack_require__(42);\r
40884             var HeatmapLayer = __webpack_require__(261);\r
40885             var zrUtil = __webpack_require__(3);\r
40886 \r
40887             function getIsInPiecewiseRange(dataExtent, pieceList, selected) {\r
40888                 var dataSpan = dataExtent[1] - dataExtent[0];\r
40889                 pieceList = zrUtil.map(pieceList, function (piece) {\r
40890                     return {\r
40891                         interval: [\r
40892                             (piece.interval[0] - dataExtent[0]) / dataSpan,\r
40893                             (piece.interval[1] - dataExtent[0]) / dataSpan\r
40894                         ]\r
40895                     };\r
40896                 });\r
40897                 var len = pieceList.length;\r
40898                 var lastIndex = 0;\r
40899                 return function (val) {\r
40900                     // Try to find in the location of the last found\r
40901                     for (var i = lastIndex; i < len; i++) {\r
40902                         var interval = pieceList[i].interval;\r
40903                         if (interval[0] <= val && val <= interval[1]) {\r
40904                             lastIndex = i;\r
40905                             break;\r
40906                         }\r
40907                     }\r
40908                     if (i === len) { // Not found, back interation\r
40909                         for (var i = lastIndex - 1; i >= 0; i--) {\r
40910                             var interval = pieceList[i].interval;\r
40911                             if (interval[0] <= val && val <= interval[1]) {\r
40912                                 lastIndex = i;\r
40913                                 break;\r
40914                             }\r
40915                         }\r
40916                     }\r
40917                     return i >= 0 && i < len && selected[i];\r
40918                 };\r
40919             }\r
40920 \r
40921             function getIsInContinuousRange(dataExtent, range) {\r
40922                 var dataSpan = dataExtent[1] - dataExtent[0];\r
40923                 range = [\r
40924                     (range[0] - dataExtent[0]) / dataSpan,\r
40925                     (range[1] - dataExtent[0]) / dataSpan\r
40926                 ];\r
40927                 return function (val) {\r
40928                     return val >= range[0] && val <= range[1];\r
40929                 };\r
40930             }\r
40931 \r
40932             function isGeoCoordSys(coordSys) {\r
40933                 var dimensions = coordSys.dimensions;\r
40934                 // Not use coorSys.type === 'geo' because coordSys maybe extended\r
40935                 return dimensions[0] === 'lng' && dimensions[1] === 'lat';\r
40936             }\r
40937 \r
40938             module.exports = __webpack_require__(1).extendChartView({\r
40939 \r
40940                 type: 'heatmap',\r
40941 \r
40942                 render: function (seriesModel, ecModel, api) {\r
40943                     var visualMapOfThisSeries;\r
40944                     ecModel.eachComponent('visualMap', function (visualMap) {\r
40945                         visualMap.eachTargetSeries(function (targetSeries) {\r
40946                             if (targetSeries === seriesModel) {\r
40947                                 visualMapOfThisSeries = visualMap;\r
40948                             }\r
40949                         });\r
40950                     });\r
40951 \r
40952                     if (!visualMapOfThisSeries) {\r
40953                         throw new Error('Heatmap must use with visualMap');\r
40954                     }\r
40955 \r
40956                     this.group.removeAll();\r
40957                     var coordSys = seriesModel.coordinateSystem;\r
40958                     if (coordSys.type === 'cartesian2d') {\r
40959                         this._renderOnCartesian(coordSys, seriesModel, api);\r
40960                     }\r
40961                     else if (isGeoCoordSys(coordSys)) {\r
40962                         this._renderOnGeo(\r
40963                             coordSys, seriesModel, visualMapOfThisSeries, api\r
40964                         );\r
40965                     }\r
40966                 },\r
40967 \r
40968                 _renderOnCartesian: function (cartesian, seriesModel, api) {\r
40969                     var xAxis = cartesian.getAxis('x');\r
40970                     var yAxis = cartesian.getAxis('y');\r
40971                     var group = this.group;\r
40972 \r
40973                     if (!(xAxis.type === 'category' && yAxis.type === 'category')) {\r
40974                         throw new Error('Heatmap on cartesian must have two category axes');\r
40975                     }\r
40976                     if (!(xAxis.onBand && yAxis.onBand)) {\r
40977                         throw new Error('Heatmap on cartesian must have two axes with boundaryGap true');\r
40978                     }\r
40979                     var width = xAxis.getBandWidth();\r
40980                     var height = yAxis.getBandWidth();\r
40981 \r
40982                     var data = seriesModel.getData();\r
40983                     data.each(['x', 'y', 'z'], function (x, y, z, idx) {\r
40984                         var itemModel = data.getItemModel(idx);\r
40985                         var point = cartesian.dataToPoint([x, y]);\r
40986                         // Ignore empty data\r
40987                         if (isNaN(z)) {\r
40988                             return;\r
40989                         }\r
40990                         var rect = new graphic.Rect({\r
40991                             shape: {\r
40992                                 x: point[0] - width / 2,\r
40993                                 y: point[1] - height / 2,\r
40994                                 width: width,\r
40995                                 height: height\r
40996                             },\r
40997                             style: {\r
40998                                 fill: data.getItemVisual(idx, 'color')\r
40999                             }\r
41000                         });\r
41001                         var style = itemModel.getModel('itemStyle.normal').getItemStyle(['color']);\r
41002                         var hoverStl = itemModel.getModel('itemStyle.emphasis').getItemStyle();\r
41003                         var labelModel = itemModel.getModel('label.normal');\r
41004                         var hoverLabelModel = itemModel.getModel('label.emphasis');\r
41005 \r
41006                         var rawValue = seriesModel.getRawValue(idx);\r
41007                         var defaultText = '-';\r
41008                         if (rawValue && rawValue[2] != null) {\r
41009                             defaultText = rawValue[2];\r
41010                         }\r
41011                         if (labelModel.get('show')) {\r
41012                             graphic.setText(style, labelModel);\r
41013                             style.text = seriesModel.getFormattedLabel(idx, 'normal') || defaultText;\r
41014                         }\r
41015                         if (hoverLabelModel.get('show')) {\r
41016                             graphic.setText(hoverStl, hoverLabelModel);\r
41017                             hoverStl.text = seriesModel.getFormattedLabel(idx, 'emphasis') || defaultText;\r
41018                         }\r
41019 \r
41020                         rect.setStyle(style);\r
41021 \r
41022                         graphic.setHoverStyle(rect, hoverStl);\r
41023 \r
41024                         group.add(rect);\r
41025                         data.setItemGraphicEl(idx, rect);\r
41026                     });\r
41027                 },\r
41028 \r
41029                 _renderOnGeo: function (geo, seriesModel, visualMapModel, api) {\r
41030                     var inRangeVisuals = visualMapModel.targetVisuals.inRange;\r
41031                     var outOfRangeVisuals = visualMapModel.targetVisuals.outOfRange;\r
41032                     // if (!visualMapping) {\r
41033                     //     throw new Error('Data range must have color visuals');\r
41034                     // }\r
41035 \r
41036                     var data = seriesModel.getData();\r
41037                     var hmLayer = this._hmLayer || (this._hmLayer || new HeatmapLayer());\r
41038                     hmLayer.blurSize = seriesModel.get('blurSize');\r
41039                     hmLayer.pointSize = seriesModel.get('pointSize');\r
41040                     hmLayer.minOpacity = seriesModel.get('minOpacity');\r
41041                     hmLayer.maxOpacity = seriesModel.get('maxOpacity');\r
41042 \r
41043                     var rect = geo.getViewRect().clone();\r
41044                     var roamTransform = geo.getRoamTransform();\r
41045                     rect.applyTransform(roamTransform);\r
41046 \r
41047                     // Clamp on viewport\r
41048                     var x = Math.max(rect.x, 0);\r
41049                     var y = Math.max(rect.y, 0);\r
41050                     var x2 = Math.min(rect.width + rect.x, api.getWidth());\r
41051                     var y2 = Math.min(rect.height + rect.y, api.getHeight());\r
41052                     var width = x2 - x;\r
41053                     var height = y2 - y;\r
41054 \r
41055                     var points = data.mapArray(['lng', 'lat', 'value'], function (lng, lat, value) {\r
41056                         var pt = geo.dataToPoint([lng, lat]);\r
41057                         pt[0] -= x;\r
41058                         pt[1] -= y;\r
41059                         pt.push(value);\r
41060                         return pt;\r
41061                     });\r
41062 \r
41063                     var dataExtent = visualMapModel.getExtent();\r
41064                     var isInRange = visualMapModel.type === 'visualMap.continuous'\r
41065                         ? getIsInContinuousRange(dataExtent, visualMapModel.option.range)\r
41066                         : getIsInPiecewiseRange(\r
41067                             dataExtent, visualMapModel.getPieceList(), visualMapModel.option.selected\r
41068                         );\r
41069 \r
41070                     hmLayer.update(\r
41071                         points, width, height,\r
41072                         inRangeVisuals.color.getNormalizer(),\r
41073                         {\r
41074                             inRange: inRangeVisuals.color.getColorMapper(),\r
41075                             outOfRange: outOfRangeVisuals.color.getColorMapper()\r
41076                         },\r
41077                         isInRange\r
41078                     );\r
41079                     var img = new graphic.Image({\r
41080                         style: {\r
41081                             width: width,\r
41082                             height: height,\r
41083                             x: x,\r
41084                             y: y,\r
41085                             image: hmLayer.canvas\r
41086                         },\r
41087                         silent: true\r
41088                     });\r
41089                     this.group.add(img);\r
41090                 }\r
41091             });\r
41092 \r
41093 \r
41094 /***/ },\r
41095 /* 261 */\r
41096 /***/ function(module, exports, __webpack_require__) {\r
41097 \r
41098         /**\r
41099          * @file defines echarts Heatmap Chart\r
41100          * @author Ovilia (me@zhangwenli.com)\r
41101          * Inspired by https://github.com/mourner/simpleheat\r
41102          *\r
41103          * @module\r
41104          */\r
41105 \r
41106 \r
41107             var GRADIENT_LEVELS = 256;\r
41108             var zrUtil = __webpack_require__(3);\r
41109 \r
41110             /**\r
41111              * Heatmap Chart\r
41112              *\r
41113              * @class\r
41114              */\r
41115             function Heatmap() {\r
41116                 var canvas = zrUtil.createCanvas();\r
41117                 this.canvas = canvas;\r
41118 \r
41119                 this.blurSize = 30;\r
41120                 this.pointSize = 20;\r
41121 \r
41122                 this.maxOpacity = 1;\r
41123                 this.minOpacity = 0;\r
41124 \r
41125                 this._gradientPixels = {};\r
41126             }\r
41127 \r
41128             Heatmap.prototype = {\r
41129                 /**\r
41130                  * Renders Heatmap and returns the rendered canvas\r
41131                  * @param {Array} data array of data, each has x, y, value\r
41132                  * @param {number} width canvas width\r
41133                  * @param {number} height canvas height\r
41134                  */\r
41135                 update: function(data, width, height, normalize, colorFunc, isInRange) {\r
41136                     var brush = this._getBrush();\r
41137                     var gradientInRange = this._getGradient(data, colorFunc, 'inRange');\r
41138                     var gradientOutOfRange = this._getGradient(data, colorFunc, 'outOfRange');\r
41139                     var r = this.pointSize + this.blurSize;\r
41140 \r
41141                     var canvas = this.canvas;\r
41142                     var ctx = canvas.getContext('2d');\r
41143                     var len = data.length;\r
41144                     canvas.width = width;\r
41145                     canvas.height = height;\r
41146                     for (var i = 0; i < len; ++i) {\r
41147                         var p = data[i];\r
41148                         var x = p[0];\r
41149                         var y = p[1];\r
41150                         var value = p[2];\r
41151 \r
41152                         // calculate alpha using value\r
41153                         var alpha = normalize(value);\r
41154 \r
41155                         // draw with the circle brush with alpha\r
41156                         ctx.globalAlpha = alpha;\r
41157                         ctx.drawImage(brush, x - r, y - r);\r
41158                     }\r
41159 \r
41160                     // colorize the canvas using alpha value and set with gradient\r
41161                     var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\r
41162                     var pixels = imageData.data;\r
41163                     var offset = 0;\r
41164                     var pixelLen = pixels.length;\r
41165                     var minOpacity = this.minOpacity;\r
41166                     var maxOpacity = this.maxOpacity;\r
41167                     var diffOpacity = maxOpacity - minOpacity;\r
41168 \r
41169                     while(offset < pixelLen) {\r
41170                         var alpha = pixels[offset + 3] / 256;\r
41171                         var gradientOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1)) * 4;\r
41172                         // Simple optimize to ignore the empty data\r
41173                         if (alpha > 0) {\r
41174                             var gradient = isInRange(alpha) ? gradientInRange : gradientOutOfRange;\r
41175                             // Any alpha > 0 will be mapped to [minOpacity, maxOpacity]\r
41176                             alpha > 0 && (alpha = alpha * diffOpacity + minOpacity);\r
41177                             pixels[offset++] = gradient[gradientOffset];\r
41178                             pixels[offset++] = gradient[gradientOffset + 1];\r
41179                             pixels[offset++] = gradient[gradientOffset + 2];\r
41180                             pixels[offset++] = gradient[gradientOffset + 3] * alpha * 256;\r
41181                         }\r
41182                         else {\r
41183                             offset += 4;\r
41184                         }\r
41185                     }\r
41186                     ctx.putImageData(imageData, 0, 0);\r
41187 \r
41188                     return canvas;\r
41189                 },\r
41190 \r
41191                 /**\r
41192                  * get canvas of a black circle brush used for canvas to draw later\r
41193                  * @private\r
41194                  * @returns {Object} circle brush canvas\r
41195                  */\r
41196                 _getBrush: function() {\r
41197                     var brushCanvas = this._brushCanvas || (this._brushCanvas = zrUtil.createCanvas());\r
41198                     // set brush size\r
41199                     var r = this.pointSize + this.blurSize;\r
41200                     var d = r * 2;\r
41201                     brushCanvas.width = d;\r
41202                     brushCanvas.height = d;\r
41203 \r
41204                     var ctx = brushCanvas.getContext('2d');\r
41205                     ctx.clearRect(0, 0, d, d);\r
41206 \r
41207                     // in order to render shadow without the distinct circle,\r
41208                     // draw the distinct circle in an invisible place,\r
41209                     // and use shadowOffset to draw shadow in the center of the canvas\r
41210                     ctx.shadowOffsetX = d;\r
41211                     ctx.shadowBlur = this.blurSize;\r
41212                     // draw the shadow in black, and use alpha and shadow blur to generate\r
41213                     // color in color map\r
41214                     ctx.shadowColor = '#000';\r
41215 \r
41216                     // draw circle in the left to the canvas\r
41217                     ctx.beginPath();\r
41218                     ctx.arc(-r, r, this.pointSize, 0, Math.PI * 2, true);\r
41219                     ctx.closePath();\r
41220                     ctx.fill();\r
41221                     return brushCanvas;\r
41222                 },\r
41223 \r
41224                 /**\r
41225                  * get gradient color map\r
41226                  * @private\r
41227                  */\r
41228                 _getGradient: function (data, colorFunc, state) {\r
41229                     var gradientPixels = this._gradientPixels;\r
41230                     var pixelsSingleState = gradientPixels[state] || (gradientPixels[state] = new Uint8ClampedArray(256 * 4));\r
41231                     var color = [];\r
41232                     var off = 0;\r
41233                     for (var i = 0; i < 256; i++) {\r
41234                         colorFunc[state](i / 255, true, color);\r
41235                         pixelsSingleState[off++] = color[0];\r
41236                         pixelsSingleState[off++] = color[1];\r
41237                         pixelsSingleState[off++] = color[2];\r
41238                         pixelsSingleState[off++] = color[3];\r
41239                     }\r
41240                     return pixelsSingleState;\r
41241                 }\r
41242             };\r
41243 \r
41244             module.exports = Heatmap;\r
41245 \r
41246 \r
41247 \r
41248 /***/ },\r
41249 /* 262 */\r
41250 /***/ function(module, exports, __webpack_require__) {\r
41251 \r
41252         /**\r
41253          * Legend component entry file8\r
41254          */\r
41255 \r
41256 \r
41257             __webpack_require__(263);\r
41258             __webpack_require__(264);\r
41259             __webpack_require__(265);\r
41260 \r
41261             var echarts = __webpack_require__(1);\r
41262             // Series Filter\r
41263             echarts.registerProcessor('filter', __webpack_require__(267));\r
41264 \r
41265 \r
41266 /***/ },\r
41267 /* 263 */\r
41268 /***/ function(module, exports, __webpack_require__) {\r
41269 \r
41270         'use strict';\r
41271 \r
41272 \r
41273             var zrUtil = __webpack_require__(3);\r
41274             var Model = __webpack_require__(8);\r
41275 \r
41276             var LegendModel = __webpack_require__(1).extendComponentModel({\r
41277 \r
41278                 type: 'legend',\r
41279 \r
41280                 dependencies: ['series'],\r
41281 \r
41282                 layoutMode: {\r
41283                     type: 'box',\r
41284                     ignoreSize: true\r
41285                 },\r
41286 \r
41287                 init: function (option, parentModel, ecModel) {\r
41288                     this.mergeDefaultAndTheme(option, ecModel);\r
41289 \r
41290                     option.selected = option.selected || {};\r
41291 \r
41292                     this._updateData(ecModel);\r
41293 \r
41294                     var legendData = this._data;\r
41295                     // If has any selected in option.selected\r
41296                     var selectedMap = this.option.selected;\r
41297                     // If selectedMode is single, try to select one\r
41298                     if (legendData[0] && this.get('selectedMode') === 'single') {\r
41299                         var hasSelected = false;\r
41300                         for (var name in selectedMap) {\r
41301                             if (selectedMap[name]) {\r
41302                                 this.select(name);\r
41303                                 hasSelected = true;\r
41304                             }\r
41305                         }\r
41306                         // Try select the first if selectedMode is single\r
41307                         !hasSelected && this.select(legendData[0].get('name'));\r
41308                     }\r
41309                 },\r
41310 \r
41311                 mergeOption: function (option) {\r
41312                     LegendModel.superCall(this, 'mergeOption', option);\r
41313 \r
41314                     this._updateData(this.ecModel);\r
41315                 },\r
41316 \r
41317                 _updateData: function (ecModel) {\r
41318                     var legendData = zrUtil.map(this.get('data') || [], function (dataItem) {\r
41319                         if (typeof dataItem === 'string') {\r
41320                             dataItem = {\r
41321                                 name: dataItem\r
41322                             };\r
41323                         }\r
41324                         return new Model(dataItem, this, this.ecModel);\r
41325                     }, this);\r
41326                     this._data = legendData;\r
41327 \r
41328                     var availableNames = zrUtil.map(ecModel.getSeries(), function (series) {\r
41329                         return series.name;\r
41330                     });\r
41331                     ecModel.eachSeries(function (seriesModel) {\r
41332                         if (seriesModel.legendDataProvider) {\r
41333                             var data = seriesModel.legendDataProvider();\r
41334                             availableNames = availableNames.concat(data.mapArray(data.getName));\r
41335                         }\r
41336                     });\r
41337                     /**\r
41338                      * @type {Array.<string>}\r
41339                      * @private\r
41340                      */\r
41341                     this._availableNames = availableNames;\r
41342                 },\r
41343 \r
41344                 /**\r
41345                  * @return {Array.<module:echarts/model/Model>}\r
41346                  */\r
41347                 getData: function () {\r
41348                     return this._data;\r
41349                 },\r
41350 \r
41351                 /**\r
41352                  * @param {string} name\r
41353                  */\r
41354                 select: function (name) {\r
41355                     var selected = this.option.selected;\r
41356                     var selectedMode = this.get('selectedMode');\r
41357                     if (selectedMode === 'single') {\r
41358                         var data = this._data;\r
41359                         zrUtil.each(data, function (dataItem) {\r
41360                             selected[dataItem.get('name')] = false;\r
41361                         });\r
41362                     }\r
41363                     selected[name] = true;\r
41364                 },\r
41365 \r
41366                 /**\r
41367                  * @param {string} name\r
41368                  */\r
41369                 unSelect: function (name) {\r
41370                     if (this.get('selectedMode') !== 'single') {\r
41371                         this.option.selected[name] = false;\r
41372                     }\r
41373                 },\r
41374 \r
41375                 /**\r
41376                  * @param {string} name\r
41377                  */\r
41378                 toggleSelected: function (name) {\r
41379                     var selected = this.option.selected;\r
41380                     // Default is true\r
41381                     if (!(name in selected)) {\r
41382                         selected[name] = true;\r
41383                     }\r
41384                     this[selected[name] ? 'unSelect' : 'select'](name);\r
41385                 },\r
41386 \r
41387                 /**\r
41388                  * @param {string} name\r
41389                  */\r
41390                 isSelected: function (name) {\r
41391                     var selected = this.option.selected;\r
41392                     return !((name in selected) && !selected[name])\r
41393                         && zrUtil.indexOf(this._availableNames, name) >= 0;\r
41394                 },\r
41395 \r
41396                 defaultOption: {\r
41397                     // 一级层叠\r
41398                     zlevel: 0,\r
41399                     // 二级层叠\r
41400                     z: 4,\r
41401                     show: true,\r
41402 \r
41403                     // 布局方式,默认为水平布局,可选为:\r
41404                     // 'horizontal' | 'vertical'\r
41405                     orient: 'horizontal',\r
41406 \r
41407                     left: 'center',\r
41408                     // right: 'center',\r
41409 \r
41410                     top: 'top',\r
41411                     // bottom: 'top',\r
41412 \r
41413                     // 水平对齐\r
41414                     // 'auto' | 'left' | 'right'\r
41415                     // 默认为 'auto', 根据 x 的位置判断是左对齐还是右对齐\r
41416                     align: 'auto',\r
41417 \r
41418                     backgroundColor: 'rgba(0,0,0,0)',\r
41419                     // 图例边框颜色\r
41420                     borderColor: '#ccc',\r
41421                     // 图例边框线宽,单位px,默认为0(无边框)\r
41422                     borderWidth: 0,\r
41423                     // 图例内边距,单位px,默认各方向内边距为5,\r
41424                     // 接受数组分别设定上右下左边距,同css\r
41425                     padding: 5,\r
41426                     // 各个item之间的间隔,单位px,默认为10,\r
41427                     // 横向布局时为水平间隔,纵向布局时为纵向间隔\r
41428                     itemGap: 10,\r
41429                     // 图例图形宽度\r
41430                     itemWidth: 25,\r
41431                     // 图例图形高度\r
41432                     itemHeight: 14,\r
41433                     textStyle: {\r
41434                         // 图例文字颜色\r
41435                         color: '#333'\r
41436                     },\r
41437                     // formatter: '',\r
41438                     // 选择模式,默认开启图例开关\r
41439                     selectedMode: true\r
41440                     // 配置默认选中状态,可配合LEGEND.SELECTED事件做动态数据载入\r
41441                     // selected: null,\r
41442                     // 图例内容(详见legend.data,数组中每一项代表一个item\r
41443                     // data: [],\r
41444                 }\r
41445             });\r
41446 \r
41447             module.exports = LegendModel;\r
41448 \r
41449 \r
41450 /***/ },\r
41451 /* 264 */\r
41452 /***/ function(module, exports, __webpack_require__) {\r
41453 \r
41454         /**\r
41455          * @file Legend action\r
41456          */\r
41457 \r
41458 \r
41459             var echarts = __webpack_require__(1);\r
41460             var zrUtil = __webpack_require__(3);\r
41461 \r
41462             function legendSelectActionHandler(methodName, payload, ecModel) {\r
41463                 var selectedMap = {};\r
41464                 var isToggleSelect = methodName === 'toggleSelected';\r
41465                 var isSelected;\r
41466                 // Update all legend components\r
41467                 ecModel.eachComponent('legend', function (legendModel) {\r
41468                     if (isToggleSelect && isSelected != null) {\r
41469                         // Force other legend has same selected status\r
41470                         // Or the first is toggled to true and other are toggled to false\r
41471                         // In the case one legend has some item unSelected in option. And if other legend\r
41472                         // doesn't has the item, they will assume it is selected.\r
41473                         legendModel[isSelected ? 'select' : 'unSelect'](payload.name);\r
41474                     }\r
41475                     else {\r
41476                         legendModel[methodName](payload.name);\r
41477                         isSelected = legendModel.isSelected(payload.name);\r
41478                     }\r
41479                     var legendData = legendModel.getData();\r
41480                     zrUtil.each(legendData, function (model) {\r
41481                         var name = model.get('name');\r
41482                         // Wrap element\r
41483                         if (name === '\n' || name === '') {\r
41484                             return;\r
41485                         }\r
41486                         var isItemSelected = legendModel.isSelected(name);\r
41487                         if (name in selectedMap) {\r
41488                             // Unselected if any legend is unselected\r
41489                             selectedMap[name] = selectedMap[name] && isItemSelected;\r
41490                         }\r
41491                         else {\r
41492                             selectedMap[name] = isItemSelected;\r
41493                         }\r
41494                     });\r
41495                 });\r
41496                 // Return the event explicitly\r
41497                 return {\r
41498                     name: payload.name,\r
41499                     selected: selectedMap\r
41500                 };\r
41501             }\r
41502             /**\r
41503              * @event legendToggleSelect\r
41504              * @type {Object}\r
41505              * @property {string} type 'legendToggleSelect'\r
41506              * @property {string} [from]\r
41507              * @property {string} name Series name or data item name\r
41508              */\r
41509             echarts.registerAction(\r
41510                 'legendToggleSelect', 'legendselectchanged',\r
41511                 zrUtil.curry(legendSelectActionHandler, 'toggleSelected')\r
41512             );\r
41513 \r
41514             /**\r
41515              * @event legendSelect\r
41516              * @type {Object}\r
41517              * @property {string} type 'legendSelect'\r
41518              * @property {string} name Series name or data item name\r
41519              */\r
41520             echarts.registerAction(\r
41521                 'legendSelect', 'legendselected',\r
41522                 zrUtil.curry(legendSelectActionHandler, 'select')\r
41523             );\r
41524 \r
41525             /**\r
41526              * @event legendUnSelect\r
41527              * @type {Object}\r
41528              * @property {string} type 'legendUnSelect'\r
41529              * @property {string} name Series name or data item name\r
41530              */\r
41531             echarts.registerAction(\r
41532                 'legendUnSelect', 'legendunselected',\r
41533                 zrUtil.curry(legendSelectActionHandler, 'unSelect')\r
41534             );\r
41535 \r
41536 \r
41537 /***/ },\r
41538 /* 265 */\r
41539 /***/ function(module, exports, __webpack_require__) {\r
41540 \r
41541         \r
41542 \r
41543             var zrUtil = __webpack_require__(3);\r
41544             var symbolCreator = __webpack_require__(100);\r
41545             var graphic = __webpack_require__(42);\r
41546             var listComponentHelper = __webpack_require__(266);\r
41547 \r
41548             var curry = zrUtil.curry;\r
41549 \r
41550             var LEGEND_DISABLE_COLOR = '#ccc';\r
41551 \r
41552             function dispatchSelectAction(name, api) {\r
41553                 api.dispatchAction({\r
41554                     type: 'legendToggleSelect',\r
41555                     name: name\r
41556                 });\r
41557             }\r
41558 \r
41559             function dispatchHighlightAction(seriesModel, dataName, api) {\r
41560                 seriesModel.get('legendHoverLink') && api.dispatchAction({\r
41561                     type: 'highlight',\r
41562                     seriesName: seriesModel.name,\r
41563                     name: dataName\r
41564                 });\r
41565             }\r
41566 \r
41567             function dispatchDownplayAction(seriesModel, dataName, api) {\r
41568                 seriesModel.get('legendHoverLink') && api.dispatchAction({\r
41569                     type: 'downplay',\r
41570                     seriesName: seriesModel.name,\r
41571                     name: dataName\r
41572                 });\r
41573             }\r
41574 \r
41575             module.exports = __webpack_require__(1).extendComponentView({\r
41576 \r
41577                 type: 'legend',\r
41578 \r
41579                 init: function () {\r
41580                     this._symbolTypeStore = {};\r
41581                 },\r
41582 \r
41583                 render: function (legendModel, ecModel, api) {\r
41584                     var group = this.group;\r
41585                     group.removeAll();\r
41586 \r
41587                     if (!legendModel.get('show')) {\r
41588                         return;\r
41589                     }\r
41590 \r
41591                     var selectMode = legendModel.get('selectedMode');\r
41592                     var itemAlign = legendModel.get('align');\r
41593 \r
41594                     if (itemAlign === 'auto') {\r
41595                         itemAlign = (legendModel.get('left') === 'right'\r
41596                             && legendModel.get('orient') === 'vertical')\r
41597                             ? 'right' : 'left';\r
41598                     }\r
41599 \r
41600                     var legendItemMap = {};\r
41601                     var legendDrawedMap = {};\r
41602                     zrUtil.each(legendModel.getData(), function (itemModel) {\r
41603                         var seriesName = itemModel.get('name');\r
41604                         // Use empty string or \n as a newline string\r
41605                         if (seriesName === '' || seriesName === '\n') {\r
41606                             group.add(new graphic.Group({\r
41607                                 newline: true\r
41608                             }));\r
41609                         }\r
41610 \r
41611                         var seriesModel = ecModel.getSeriesByName(seriesName)[0];\r
41612 \r
41613                         legendItemMap[seriesName] = itemModel;\r
41614 \r
41615                         if (!seriesModel || legendDrawedMap[seriesName]) {\r
41616                             // Series not exists\r
41617                             return;\r
41618                         }\r
41619 \r
41620                         var data = seriesModel.getData();\r
41621                         var color = data.getVisual('color');\r
41622 \r
41623                         // If color is a callback function\r
41624                         if (typeof color === 'function') {\r
41625                             // Use the first data\r
41626                             color = color(seriesModel.getDataParams(0));\r
41627                         }\r
41628 \r
41629                         // Using rect symbol defaultly\r
41630                         var legendSymbolType = data.getVisual('legendSymbol') || 'roundRect';\r
41631                         var symbolType = data.getVisual('symbol');\r
41632 \r
41633                         var itemGroup = this._createItem(\r
41634                             seriesName, itemModel, legendModel,\r
41635                             legendSymbolType, symbolType,\r
41636                             itemAlign, color,\r
41637                             selectMode\r
41638                         );\r
41639 \r
41640                         itemGroup.on('click', curry(dispatchSelectAction, seriesName, api))\r
41641                             .on('mouseover', curry(dispatchHighlightAction, seriesModel, '', api))\r
41642                             .on('mouseout', curry(dispatchDownplayAction, seriesModel, '', api));\r
41643 \r
41644                         legendDrawedMap[seriesName] = true;\r
41645                     }, this);\r
41646 \r
41647                     ecModel.eachRawSeries(function (seriesModel) {\r
41648                         if (seriesModel.legendDataProvider) {\r
41649                             var data = seriesModel.legendDataProvider();\r
41650                             data.each(function (idx) {\r
41651                                 var name = data.getName(idx);\r
41652 \r
41653                                 // Avoid mutiple series use the same data name\r
41654                                 if (!legendItemMap[name] || legendDrawedMap[name]) {\r
41655                                     return;\r
41656                                 }\r
41657 \r
41658                                 var color = data.getItemVisual(idx, 'color');\r
41659 \r
41660                                 var legendSymbolType = 'roundRect';\r
41661 \r
41662                                 var itemGroup = this._createItem(\r
41663                                     name, legendItemMap[name], legendModel,\r
41664                                     legendSymbolType, null,\r
41665                                     itemAlign, color,\r
41666                                     selectMode\r
41667                                 );\r
41668 \r
41669                                 itemGroup.on('click', curry(dispatchSelectAction, name, api))\r
41670                                     // FIXME Should not specify the series name\r
41671                                     .on('mouseover', curry(dispatchHighlightAction, seriesModel, name, api))\r
41672                                     .on('mouseout', curry(dispatchDownplayAction, seriesModel, name, api));\r
41673 \r
41674                                 legendDrawedMap[name] = true;\r
41675                             }, false, this);\r
41676                         }\r
41677                     }, this);\r
41678 \r
41679                     listComponentHelper.layout(group, legendModel, api);\r
41680                     // Render background after group is layout\r
41681                     // FIXME\r
41682                     listComponentHelper.addBackground(group, legendModel);\r
41683                 },\r
41684 \r
41685                 _createItem: function (\r
41686                     name, itemModel, legendModel,\r
41687                     legendSymbolType, symbolType,\r
41688                     itemAlign, color, selectMode\r
41689                 ) {\r
41690                     var itemWidth = legendModel.get('itemWidth');\r
41691                     var itemHeight = legendModel.get('itemHeight');\r
41692 \r
41693                     var isSelected = legendModel.isSelected(name);\r
41694                     var itemGroup = new graphic.Group();\r
41695 \r
41696                     var textStyleModel = itemModel.getModel('textStyle');\r
41697 \r
41698                     var itemIcon = itemModel.get('icon');\r
41699 \r
41700                     // Use user given icon first\r
41701                     legendSymbolType = itemIcon || legendSymbolType;\r
41702                     itemGroup.add(symbolCreator.createSymbol(\r
41703                         legendSymbolType, 0, 0, itemWidth, itemHeight, isSelected ? color : LEGEND_DISABLE_COLOR\r
41704                     ));\r
41705 \r
41706                     // Compose symbols\r
41707                     // PENDING\r
41708                     if (!itemIcon && symbolType\r
41709                         // At least show one symbol, can't be all none\r
41710                         && ((symbolType !== legendSymbolType) || symbolType == 'none')\r
41711                     ) {\r
41712                         var size = itemHeight * 0.8;\r
41713                         if (symbolType === 'none') {\r
41714                             symbolType = 'circle';\r
41715                         }\r
41716                         // Put symbol in the center\r
41717                         itemGroup.add(symbolCreator.createSymbol(\r
41718                             symbolType, (itemWidth - size) / 2, (itemHeight - size) / 2, size, size,\r
41719                             isSelected ? color : LEGEND_DISABLE_COLOR\r
41720                         ));\r
41721                     }\r
41722 \r
41723                     // Text\r
41724                     var textX = itemAlign === 'left' ? itemWidth + 5 : -5;\r
41725                     var textAlign = itemAlign;\r
41726 \r
41727                     var formatter = legendModel.get('formatter');\r
41728                     if (typeof formatter === 'string' && formatter) {\r
41729                         name = formatter.replace('{name}', name);\r
41730                     }\r
41731                     else if (typeof formatter === 'function') {\r
41732                         name = formatter(name);\r
41733                     }\r
41734 \r
41735                     var text = new graphic.Text({\r
41736                         style: {\r
41737                             text: name,\r
41738                             x: textX,\r
41739                             y: itemHeight / 2,\r
41740                             fill: isSelected ? textStyleModel.getTextColor() : LEGEND_DISABLE_COLOR,\r
41741                             textFont: textStyleModel.getFont(),\r
41742                             textAlign: textAlign,\r
41743                             textVerticalAlign: 'middle'\r
41744                         }\r
41745                     });\r
41746                     itemGroup.add(text);\r
41747 \r
41748                     // Add a invisible rect to increase the area of mouse hover\r
41749                     itemGroup.add(new graphic.Rect({\r
41750                         shape: itemGroup.getBoundingRect(),\r
41751                         invisible: true\r
41752                     }));\r
41753 \r
41754                     itemGroup.eachChild(function (child) {\r
41755                         child.silent = !selectMode;\r
41756                     });\r
41757 \r
41758                     this.group.add(itemGroup);\r
41759 \r
41760                     graphic.setHoverStyle(itemGroup);\r
41761 \r
41762                     return itemGroup;\r
41763                 }\r
41764             });\r
41765 \r
41766 \r
41767 /***/ },\r
41768 /* 266 */\r
41769 /***/ function(module, exports, __webpack_require__) {\r
41770 \r
41771         \r
41772             // List layout\r
41773             var layout = __webpack_require__(21);\r
41774             var formatUtil = __webpack_require__(6);\r
41775             var graphic = __webpack_require__(42);\r
41776 \r
41777             function positionGroup(group, model, api) {\r
41778                 layout.positionGroup(\r
41779                     group, model.getBoxLayoutParams(),\r
41780                     {\r
41781                         width: api.getWidth(),\r
41782                         height: api.getHeight()\r
41783                     },\r
41784                     model.get('padding')\r
41785                 );\r
41786             }\r
41787 \r
41788             module.exports = {\r
41789                 /**\r
41790                  * Layout list like component.\r
41791                  * It will box layout each items in group of component and then position the whole group in the viewport\r
41792                  * @param {module:zrender/group/Group} group\r
41793                  * @param {module:echarts/model/Component} componentModel\r
41794                  * @param {module:echarts/ExtensionAPI}\r
41795                  */\r
41796                 layout: function (group, componentModel, api) {\r
41797                     var rect = layout.getLayoutRect(componentModel.getBoxLayoutParams(), {\r
41798                         width: api.getWidth(),\r
41799                         height: api.getHeight()\r
41800                     }, componentModel.get('padding'));\r
41801                     layout.box(\r
41802                         componentModel.get('orient'),\r
41803                         group,\r
41804                         componentModel.get('itemGap'),\r
41805                         rect.width,\r
41806                         rect.height\r
41807                     );\r
41808 \r
41809                     positionGroup(group, componentModel, api);\r
41810                 },\r
41811 \r
41812                 addBackground: function (group, componentModel) {\r
41813                     var padding = formatUtil.normalizeCssArray(\r
41814                         componentModel.get('padding')\r
41815                     );\r
41816                     var boundingRect = group.getBoundingRect();\r
41817                     var style = componentModel.getItemStyle(['color', 'opacity']);\r
41818                     style.fill = componentModel.get('backgroundColor');\r
41819                     var rect = new graphic.Rect({\r
41820                         shape: {\r
41821                             x: boundingRect.x - padding[3],\r
41822                             y: boundingRect.y - padding[0],\r
41823                             width: boundingRect.width + padding[1] + padding[3],\r
41824                             height: boundingRect.height + padding[0] + padding[2]\r
41825                         },\r
41826                         style: style,\r
41827                         silent: true,\r
41828                         z2: -1\r
41829                     });\r
41830                     graphic.subPixelOptimizeRect(rect);\r
41831 \r
41832                     group.add(rect);\r
41833                 }\r
41834             };\r
41835 \r
41836 \r
41837 /***/ },\r
41838 /* 267 */\r
41839 /***/ function(module, exports) {\r
41840 \r
41841         \r
41842            module.exports = function (ecModel) {\r
41843                 var legendModels = ecModel.findComponents({\r
41844                     mainType: 'legend'\r
41845                 });\r
41846                 if (legendModels && legendModels.length) {\r
41847                     ecModel.filterSeries(function (series) {\r
41848                         // If in any legend component the status is not selected.\r
41849                         // Because in legend series is assumed selected when it is not in the legend data.\r
41850                         for (var i = 0; i < legendModels.length; i++) {\r
41851                             if (!legendModels[i].isSelected(series.name)) {\r
41852                                 return false;\r
41853                             }\r
41854                         }\r
41855                         return true;\r
41856                     });\r
41857                 }\r
41858             };\r
41859 \r
41860 \r
41861 /***/ },\r
41862 /* 268 */\r
41863 /***/ function(module, exports, __webpack_require__) {\r
41864 \r
41865         // FIXME Better way to pack data in graphic element\r
41866 \r
41867 \r
41868             __webpack_require__(269);\r
41869 \r
41870             __webpack_require__(270);\r
41871 \r
41872             // Show tip action\r
41873             /**\r
41874              * @action\r
41875              * @property {string} type\r
41876              * @property {number} seriesIndex\r
41877              * @property {number} dataIndex\r
41878              * @property {number} [x]\r
41879              * @property {number} [y]\r
41880              */\r
41881             __webpack_require__(1).registerAction(\r
41882                 {\r
41883                     type: 'showTip',\r
41884                     event: 'showTip',\r
41885                     update: 'none'\r
41886                 },\r
41887                 // noop\r
41888                 function () {}\r
41889             );\r
41890             // Hide tip action\r
41891             __webpack_require__(1).registerAction(\r
41892                 {\r
41893                     type: 'hideTip',\r
41894                     event: 'hideTip',\r
41895                     update: 'none'\r
41896                 },\r
41897                 // noop\r
41898                 function () {}\r
41899             );\r
41900 \r
41901 \r
41902 /***/ },\r
41903 /* 269 */\r
41904 /***/ function(module, exports, __webpack_require__) {\r
41905 \r
41906         \r
41907 \r
41908             __webpack_require__(1).extendComponentModel({\r
41909 \r
41910                 type: 'tooltip',\r
41911 \r
41912                 defaultOption: {\r
41913                     zlevel: 0,\r
41914 \r
41915                     z: 8,\r
41916 \r
41917                     show: true,\r
41918 \r
41919                     // tooltip主体内容\r
41920                     showContent: true,\r
41921 \r
41922                     // 触发类型,默认数据触发,见下图,可选为:'item' ¦ 'axis'\r
41923                     trigger: 'item',\r
41924 \r
41925                     // 触发条件,支持 'click' | 'mousemove'\r
41926                     triggerOn: 'mousemove',\r
41927 \r
41928                     // 是否永远显示 content\r
41929                     alwaysShowContent: false,\r
41930 \r
41931                     // 位置 {Array} | {Function}\r
41932                     // position: null\r
41933 \r
41934                     // 内容格式器:{string}(Template) ¦ {Function}\r
41935                     // formatter: null\r
41936 \r
41937                     // 隐藏延迟,单位ms\r
41938                     hideDelay: 100,\r
41939 \r
41940                     // 动画变换时间,单位s\r
41941                     transitionDuration: 0.4,\r
41942 \r
41943                     enterable: false,\r
41944 \r
41945                     // 提示背景颜色,默认为透明度为0.7的黑色\r
41946                     backgroundColor: 'rgba(50,50,50,0.7)',\r
41947 \r
41948                     // 提示边框颜色\r
41949                     borderColor: '#333',\r
41950 \r
41951                     // 提示边框圆角,单位px,默认为4\r
41952                     borderRadius: 4,\r
41953 \r
41954                     // 提示边框线宽,单位px,默认为0(无边框)\r
41955                     borderWidth: 0,\r
41956 \r
41957                     // 提示内边距,单位px,默认各方向内边距为5,\r
41958                     // 接受数组分别设定上右下左边距,同css\r
41959                     padding: 5,\r
41960 \r
41961                     // Extra css text\r
41962                     extraCssText: '',\r
41963 \r
41964                     // 坐标轴指示器,坐标轴触发有效\r
41965                     axisPointer: {\r
41966                         // 默认为直线\r
41967                         // 可选为:'line' | 'shadow' | 'cross'\r
41968                         type: 'line',\r
41969 \r
41970                         // type 为 line 的时候有效,指定 tooltip line 所在的轴,可选\r
41971                         // 可选 'x' | 'y' | 'angle' | 'radius' | 'auto'\r
41972                         // 默认 'auto',会选择类型为 cateogry 的轴,对于双数值轴,笛卡尔坐标系会默认选择 x 轴\r
41973                         // 极坐标系会默认选择 angle 轴\r
41974                         axis: 'auto',\r
41975 \r
41976                         animation: true,\r
41977                         animationDurationUpdate: 200,\r
41978                         animationEasingUpdate: 'exponentialOut',\r
41979 \r
41980                         // 直线指示器样式设置\r
41981                         lineStyle: {\r
41982                             color: '#555',\r
41983                             width: 1,\r
41984                             type: 'solid'\r
41985                         },\r
41986 \r
41987                         crossStyle: {\r
41988                             color: '#555',\r
41989                             width: 1,\r
41990                             type: 'dashed',\r
41991 \r
41992                             // TODO formatter\r
41993                             textStyle: {}\r
41994                         },\r
41995 \r
41996                         // 阴影指示器样式设置\r
41997                         shadowStyle: {\r
41998                             color: 'rgba(150,150,150,0.3)'\r
41999                         }\r
42000                     },\r
42001                     textStyle: {\r
42002                         color: '#fff',\r
42003                         fontSize: 14\r
42004                     }\r
42005                 }\r
42006             });\r
42007 \r
42008 \r
42009 /***/ },\r
42010 /* 270 */\r
42011 /***/ function(module, exports, __webpack_require__) {\r
42012 \r
42013         \r
42014 \r
42015             var TooltipContent = __webpack_require__(271);\r
42016             var graphic = __webpack_require__(42);\r
42017             var zrUtil = __webpack_require__(3);\r
42018             var formatUtil = __webpack_require__(6);\r
42019             var numberUtil = __webpack_require__(7);\r
42020             var parsePercent = numberUtil.parsePercent;\r
42021             var env = __webpack_require__(78);\r
42022 \r
42023             function dataEqual(a, b) {\r
42024                 if (!a || !b) {\r
42025                     return false;\r
42026                 }\r
42027                 var round = numberUtil.round;\r
42028                 return round(a[0]) === round(b[0])\r
42029                     && round(a[1]) === round(b[1]);\r
42030             }\r
42031             /**\r
42032              * @inner\r
42033              */\r
42034             function makeLineShape(x1, y1, x2, y2) {\r
42035                 return {\r
42036                     x1: x1,\r
42037                     y1: y1,\r
42038                     x2: x2,\r
42039                     y2: y2\r
42040                 };\r
42041             }\r
42042 \r
42043             /**\r
42044              * @inner\r
42045              */\r
42046             function makeRectShape(x, y, width, height) {\r
42047                 return {\r
42048                     x: x,\r
42049                     y: y,\r
42050                     width: width,\r
42051                     height: height\r
42052                 };\r
42053             }\r
42054 \r
42055             /**\r
42056              * @inner\r
42057              */\r
42058             function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) {\r
42059                 return {\r
42060                     cx: cx,\r
42061                     cy: cy,\r
42062                     r0: r0,\r
42063                     r: r,\r
42064                     startAngle: startAngle,\r
42065                     endAngle: endAngle,\r
42066                     clockwise: true\r
42067                 };\r
42068             }\r
42069 \r
42070             function refixTooltipPosition(x, y, el, viewWidth, viewHeight) {\r
42071                 var width = el.clientWidth;\r
42072                 var height = el.clientHeight;\r
42073                 var gap = 20;\r
42074 \r
42075                 if (x + width + gap > viewWidth) {\r
42076                     x -= width + gap;\r
42077                 }\r
42078                 else {\r
42079                     x += gap;\r
42080                 }\r
42081                 if (y + height + gap > viewHeight) {\r
42082                     y -= height + gap;\r
42083                 }\r
42084                 else {\r
42085                     y += gap;\r
42086                 }\r
42087                 return [x, y];\r
42088             }\r
42089 \r
42090             function calcTooltipPosition(position, rect, dom) {\r
42091                 var domWidth = dom.clientWidth;\r
42092                 var domHeight = dom.clientHeight;\r
42093                 var gap = 5;\r
42094                 var x = 0;\r
42095                 var y = 0;\r
42096                 var rectWidth = rect.width;\r
42097                 var rectHeight = rect.height;\r
42098                 switch (position) {\r
42099                     case 'inside':\r
42100                         x = rect.x + rectWidth / 2 - domWidth / 2;\r
42101                         y = rect.y + rectHeight / 2 - domHeight / 2;\r
42102                         break;\r
42103                     case 'top':\r
42104                         x = rect.x + rectWidth / 2 - domWidth / 2;\r
42105                         y = rect.y - domHeight - gap;\r
42106                         break;\r
42107                     case 'bottom':\r
42108                         x = rect.x + rectWidth / 2 - domWidth / 2;\r
42109                         y = rect.y + rectHeight + gap;\r
42110                         break;\r
42111                     case 'left':\r
42112                         x = rect.x - domWidth - gap;\r
42113                         y = rect.y + rectHeight / 2 - domHeight / 2;\r
42114                         break;\r
42115                     case 'right':\r
42116                         x = rect.x + rectWidth + gap;\r
42117                         y = rect.y + rectHeight / 2 - domHeight / 2;\r
42118                 }\r
42119                 return [x, y];\r
42120             }\r
42121 \r
42122             /**\r
42123              * @param  {string|Function|Array.<number>} positionExpr\r
42124              * @param  {number} x Mouse x\r
42125              * @param  {number} y Mouse y\r
42126              * @param  {module:echarts/component/tooltip/TooltipContent} content\r
42127              * @param  {Object|<Array.<Object>} params\r
42128              * @param  {module:zrender/Element} el target element\r
42129              * @param  {module:echarts/ExtensionAPI} api\r
42130              * @return {Array.<number>}\r
42131              */\r
42132             function updatePosition(positionExpr, x, y, content, params, el, api) {\r
42133                 var viewWidth = api.getWidth();\r
42134                 var viewHeight = api.getHeight();\r
42135 \r
42136                 var rect = el && el.getBoundingRect().clone();\r
42137                 el && rect.applyTransform(el.transform);\r
42138                 if (typeof positionExpr === 'function') {\r
42139                     // Callback of position can be an array or a string specify the positiont\r
42140                     positionExpr = positionExpr([x, y], params, rect);\r
42141                 }\r
42142 \r
42143                 if (zrUtil.isArray(positionExpr)) {\r
42144                     x = parsePercent(positionExpr[0], viewWidth);\r
42145                     y = parsePercent(positionExpr[1], viewHeight);\r
42146                 }\r
42147                 // Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element\r
42148                 else if (typeof positionExpr === 'string' && el) {\r
42149                     var pos = calcTooltipPosition(\r
42150                         positionExpr, rect, content.el\r
42151                     );\r
42152                     x = pos[0];\r
42153                     y = pos[1];\r
42154                 }\r
42155                 else {\r
42156                     var pos = refixTooltipPosition(\r
42157                         x, y, content.el, viewWidth, viewHeight\r
42158                     );\r
42159                     x = pos[0];\r
42160                     y = pos[1];\r
42161                 }\r
42162 \r
42163                 content.moveTo(x, y);\r
42164             }\r
42165 \r
42166             function ifSeriesSupportAxisTrigger(seriesModel) {\r
42167                 var coordSys = seriesModel.coordinateSystem;\r
42168                 var trigger = seriesModel.get('tooltip.trigger', true);\r
42169                 // Ignore series use item tooltip trigger and series coordinate system is not cartesian or\r
42170                 return !(!coordSys\r
42171                     || (coordSys.type !== 'cartesian2d' && coordSys.type !== 'polar' && coordSys.type !== 'single')\r
42172                     || trigger === 'item');\r
42173             }\r
42174 \r
42175             __webpack_require__(1).extendComponentView({\r
42176 \r
42177                 type: 'tooltip',\r
42178 \r
42179                 _axisPointers: {},\r
42180 \r
42181                 init: function (ecModel, api) {\r
42182                     if (env.node) {\r
42183                         return;\r
42184                     }\r
42185                     var tooltipContent = new TooltipContent(api.getDom(), api);\r
42186                     this._tooltipContent = tooltipContent;\r
42187 \r
42188                     api.on('showTip', this._manuallyShowTip, this);\r
42189                     api.on('hideTip', this._manuallyHideTip, this);\r
42190                 },\r
42191 \r
42192                 render: function (tooltipModel, ecModel, api) {\r
42193                     if (env.node) {\r
42194                         return;\r
42195                     }\r
42196 \r
42197                     // Reset\r
42198                     this.group.removeAll();\r
42199 \r
42200                     /**\r
42201                      * @type {Object}\r
42202                      * @private\r
42203                      */\r
42204                     this._axisPointers = {};\r
42205 \r
42206                     /**\r
42207                      * @private\r
42208                      * @type {module:echarts/component/tooltip/TooltipModel}\r
42209                      */\r
42210                     this._tooltipModel = tooltipModel;\r
42211 \r
42212                     /**\r
42213                      * @private\r
42214                      * @type {module:echarts/model/Global}\r
42215                      */\r
42216                     this._ecModel = ecModel;\r
42217 \r
42218                     /**\r
42219                      * @private\r
42220                      * @type {module:echarts/ExtensionAPI}\r
42221                      */\r
42222                     this._api = api;\r
42223 \r
42224                     /**\r
42225                      * @type {Object}\r
42226                      * @private\r
42227                      */\r
42228                     this._lastHover = {\r
42229                         // data\r
42230                         // payloadBatch\r
42231                     };\r
42232 \r
42233                     var tooltipContent = this._tooltipContent;\r
42234                     tooltipContent.update();\r
42235                     tooltipContent.enterable = tooltipModel.get('enterable');\r
42236                     this._alwaysShowContent = tooltipModel.get('alwaysShowContent');\r
42237 \r
42238                     /**\r
42239                      * @type {Object.<string, Array>}\r
42240                      */\r
42241                     this._seriesGroupByAxis = this._prepareAxisTriggerData(\r
42242                         tooltipModel, ecModel\r
42243                     );\r
42244 \r
42245                     var crossText = this._crossText;\r
42246                     if (crossText) {\r
42247                         this.group.add(crossText);\r
42248                     }\r
42249 \r
42250                     // Try to keep the tooltip show when refreshing\r
42251                     if (this._lastX != null && this._lastY != null) {\r
42252                         var self = this;\r
42253                         clearTimeout(this._refreshUpdateTimeout);\r
42254                         this._refreshUpdateTimeout = setTimeout(function () {\r
42255                             // Show tip next tick after other charts are rendered\r
42256                             // In case highlight action has wrong result\r
42257                             // FIXME\r
42258                             self._manuallyShowTip({\r
42259                                 x: self._lastX,\r
42260                                 y: self._lastY\r
42261                             });\r
42262                         });\r
42263                     }\r
42264 \r
42265                     var zr = this._api.getZr();\r
42266                     var tryShow = this._tryShow;\r
42267                     zr.off('click', tryShow);\r
42268                     zr.off('mousemove', tryShow);\r
42269                     zr.off('mouseout', this._hide);\r
42270                     if (tooltipModel.get('triggerOn') === 'click') {\r
42271                         zr.on('click', tryShow, this);\r
42272                     }\r
42273                     else {\r
42274                         zr.on('mousemove', tryShow, this);\r
42275                         zr.on('mouseout', this._hide, this);\r
42276                     }\r
42277 \r
42278                 },\r
42279 \r
42280                 /**\r
42281                  * Show tip manually by\r
42282                  *  dispatchAction({\r
42283                  *      type: 'showTip',\r
42284                  *      x: 10,\r
42285                  *      y: 10\r
42286                  *  });\r
42287                  * Or\r
42288                  *  dispatchAction({\r
42289                  *      type: 'showTip',\r
42290                  *      seriesIndex: 0,\r
42291                  *      dataIndex: 1\r
42292                  *  });\r
42293                  *\r
42294                  *  TODO Batch\r
42295                  */\r
42296                 _manuallyShowTip: function (event) {\r
42297                     // From self\r
42298                     if (event.from === this.uid) {\r
42299                         return;\r
42300                     }\r
42301 \r
42302                     var ecModel = this._ecModel;\r
42303                     var seriesIndex = event.seriesIndex;\r
42304                     var dataIndex = event.dataIndex;\r
42305                     var seriesModel = ecModel.getSeriesByIndex(seriesIndex);\r
42306                     var api = this._api;\r
42307 \r
42308                     if (event.x == null || event.y == null) {\r
42309                         if (!seriesModel) {\r
42310                             // Find the first series can use axis trigger\r
42311                             ecModel.eachSeries(function (_series) {\r
42312                                 if (ifSeriesSupportAxisTrigger(_series) && !seriesModel) {\r
42313                                     seriesModel = _series;\r
42314                                 }\r
42315                             });\r
42316                         }\r
42317                         if (seriesModel) {\r
42318                             var data = seriesModel.getData();\r
42319                             if (dataIndex == null) {\r
42320                                 dataIndex = data.indexOfName(event.name);\r
42321                             }\r
42322                             var el = data.getItemGraphicEl(dataIndex);\r
42323                             var cx, cy;\r
42324                             // Try to get the point in coordinate system\r
42325                             var coordSys = seriesModel.coordinateSystem;\r
42326                             if (coordSys && coordSys.dataToPoint) {\r
42327                                 var point = coordSys.dataToPoint(\r
42328                                     data.getValues(coordSys.dimensions, dataIndex, true)\r
42329                                 );\r
42330                                 cx = point && point[0];\r
42331                                 cy = point && point[1];\r
42332                             }\r
42333                             else if (el) {\r
42334                                 // Use graphic bounding rect\r
42335                                 var rect = el.getBoundingRect().clone();\r
42336                                 rect.applyTransform(el.transform);\r
42337                                 cx = rect.x + rect.width / 2;\r
42338                                 cy = rect.y + rect.height / 2;\r
42339                             }\r
42340                             if (cx != null && cy != null) {\r
42341                                 this._tryShow({\r
42342                                     offsetX: cx,\r
42343                                     offsetY: cy,\r
42344                                     target: el,\r
42345                                     event: {}\r
42346                                 });\r
42347                             }\r
42348                         }\r
42349                     }\r
42350                     else {\r
42351                         var el = api.getZr().handler.findHover(event.x, event.y);\r
42352                         this._tryShow({\r
42353                             offsetX: event.x,\r
42354                             offsetY: event.y,\r
42355                             target: el,\r
42356                             event: {}\r
42357                         });\r
42358                     }\r
42359                 },\r
42360 \r
42361                 _manuallyHideTip: function (e) {\r
42362                     if (e.from === this.uid) {\r
42363                         return;\r
42364                     }\r
42365 \r
42366                     this._hide();\r
42367                 },\r
42368 \r
42369                 _prepareAxisTriggerData: function (tooltipModel, ecModel) {\r
42370                     // Prepare data for axis trigger\r
42371                     var seriesGroupByAxis = {};\r
42372                     ecModel.eachSeries(function (seriesModel) {\r
42373                         if (ifSeriesSupportAxisTrigger(seriesModel)) {\r
42374                             var coordSys = seriesModel.coordinateSystem;\r
42375                             var baseAxis;\r
42376                             var key;\r
42377 \r
42378                             // Only cartesian2d, polar and single support axis trigger\r
42379                             if (coordSys.type === 'cartesian2d') {\r
42380                                 // FIXME `axisPointer.axis` is not baseAxis\r
42381                                 baseAxis = coordSys.getBaseAxis();\r
42382                                 key = baseAxis.dim + baseAxis.index;\r
42383                             }\r
42384                             else if (coordSys.type === 'single') {\r
42385                                 baseAxis = coordSys.getAxis();\r
42386                                 key = baseAxis.dim + baseAxis.type;\r
42387                             }\r
42388                             else {\r
42389                                 baseAxis = coordSys.getBaseAxis();\r
42390                                 key = baseAxis.dim + coordSys.name;\r
42391                             }\r
42392 \r
42393                             seriesGroupByAxis[key] = seriesGroupByAxis[key] || {\r
42394                                 coordSys: [],\r
42395                                 series: []\r
42396                             };\r
42397                             seriesGroupByAxis[key].coordSys.push(coordSys);\r
42398                             seriesGroupByAxis[key].series.push(seriesModel);\r
42399                         }\r
42400                     }, this);\r
42401 \r
42402                     return seriesGroupByAxis;\r
42403                 },\r
42404 \r
42405                 /**\r
42406                  * mousemove handler\r
42407                  * @param {Object} e\r
42408                  * @private\r
42409                  */\r
42410                 _tryShow: function (e) {\r
42411                     var el = e.target;\r
42412                     var tooltipModel = this._tooltipModel;\r
42413                     var globalTrigger = tooltipModel.get('trigger');\r
42414                     var ecModel = this._ecModel;\r
42415                     var api = this._api;\r
42416 \r
42417                     if (!tooltipModel) {\r
42418                         return;\r
42419                     }\r
42420 \r
42421                     // Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed\r
42422                     this._lastX = e.offsetX;\r
42423                     this._lastY = e.offsetY;\r
42424 \r
42425                     // Always show item tooltip if mouse is on the element with dataIndex\r
42426                     if (el && el.dataIndex != null) {\r
42427                         // Use dataModel in element if possible\r
42428                         // Used when mouseover on a element like markPoint or edge\r
42429                         // In which case, the data is not main data in series.\r
42430                         var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex);\r
42431                         var dataIndex = el.dataIndex;\r
42432                         var itemModel = dataModel.getData().getItemModel(dataIndex);\r
42433                         // Series or single data may use item trigger when global is axis trigger\r
42434                         if ((itemModel.get('tooltip.trigger') || globalTrigger) === 'axis') {\r
42435                             this._showAxisTooltip(tooltipModel, ecModel, e);\r
42436                         }\r
42437                         else {\r
42438                             // Reset ticket\r
42439                             this._ticket = '';\r
42440                             // If either single data or series use item trigger\r
42441                             this._hideAxisPointer();\r
42442                             // Reset last hover and dispatch downplay action\r
42443                             this._resetLastHover();\r
42444 \r
42445                             this._showItemTooltipContent(dataModel, dataIndex, e);\r
42446                         }\r
42447 \r
42448                         api.dispatchAction({\r
42449                             type: 'showTip',\r
42450                             from: this.uid,\r
42451                             dataIndex: el.dataIndex,\r
42452                             seriesIndex: el.seriesIndex\r
42453                         });\r
42454                     }\r
42455                     else {\r
42456                         if (globalTrigger === 'item') {\r
42457                             this._hide();\r
42458                         }\r
42459                         else {\r
42460                             // Try show axis tooltip\r
42461                             this._showAxisTooltip(tooltipModel, ecModel, e);\r
42462                         }\r
42463 \r
42464                         // Action of cross pointer\r
42465                         // other pointer types will trigger action in _dispatchAndShowSeriesTooltipContent method\r
42466                         if (tooltipModel.get('axisPointer.type') === 'cross') {\r
42467                             api.dispatchAction({\r
42468                                 type: 'showTip',\r
42469                                 from: this.uid,\r
42470                                 x: e.offsetX,\r
42471                                 y: e.offsetY\r
42472                             });\r
42473                         }\r
42474                     }\r
42475                 },\r
42476 \r
42477                 /**\r
42478                  * Show tooltip on axis\r
42479                  * @param {module:echarts/component/tooltip/TooltipModel} tooltipModel\r
42480                  * @param {module:echarts/model/Global} ecModel\r
42481                  * @param {Object} e\r
42482                  * @private\r
42483                  */\r
42484                 _showAxisTooltip: function (tooltipModel, ecModel, e) {\r
42485                     var axisPointerModel = tooltipModel.getModel('axisPointer');\r
42486                     var axisPointerType = axisPointerModel.get('type');\r
42487 \r
42488                     if (axisPointerType === 'cross') {\r
42489                         var el = e.target;\r
42490                         if (el && el.dataIndex != null) {\r
42491                             var seriesModel = ecModel.getSeriesByIndex(el.seriesIndex);\r
42492                             var dataIndex = el.dataIndex;\r
42493                             this._showItemTooltipContent(seriesModel, dataIndex, e);\r
42494                         }\r
42495                     }\r
42496 \r
42497                     this._showAxisPointer();\r
42498                     var allNotShow = true;\r
42499                     zrUtil.each(this._seriesGroupByAxis, function (seriesCoordSysSameAxis) {\r
42500                         // Try show the axis pointer\r
42501                         var allCoordSys = seriesCoordSysSameAxis.coordSys;\r
42502                         var coordSys = allCoordSys[0];\r
42503 \r
42504                         // If mouse position is not in the grid or polar\r
42505                         var point = [e.offsetX, e.offsetY];\r
42506 \r
42507                         if (!coordSys.containPoint(point)) {\r
42508                             // Hide axis pointer\r
42509                             this._hideAxisPointer(coordSys.name);\r
42510                             return;\r
42511                         }\r
42512 \r
42513                         allNotShow = false;\r
42514                         // Make sure point is discrete on cateogry axis\r
42515                         var dimensions = coordSys.dimensions;\r
42516                         var value = coordSys.pointToData(point, true);\r
42517                         point = coordSys.dataToPoint(value);\r
42518                         var baseAxis = coordSys.getBaseAxis();\r
42519                         var axisType = axisPointerModel.get('axis');\r
42520                         if (axisType === 'auto') {\r
42521                             axisType = baseAxis.dim;\r
42522                         }\r
42523 \r
42524                         var contentNotChange = false;\r
42525                         var lastHover = this._lastHover;\r
42526                         if (axisPointerType === 'cross') {\r
42527                             // If hover data not changed\r
42528                             // Possible when two axes are all category\r
42529                             if (dataEqual(lastHover.data, value)) {\r
42530                                 contentNotChange = true;\r
42531                             }\r
42532                             lastHover.data = value;\r
42533                         }\r
42534                         else {\r
42535                             var valIndex = zrUtil.indexOf(dimensions, axisType);\r
42536 \r
42537                             // If hover data not changed on the axis dimension\r
42538                             if (lastHover.data === value[valIndex]) {\r
42539                                 contentNotChange = true;\r
42540                             }\r
42541                             lastHover.data = value[valIndex];\r
42542                         }\r
42543 \r
42544                         if (coordSys.type === 'cartesian2d' && !contentNotChange) {\r
42545                             this._showCartesianPointer(\r
42546                                 axisPointerModel, coordSys, axisType, point\r
42547                             );\r
42548                         }\r
42549                         else if (coordSys.type === 'polar' && !contentNotChange) {\r
42550                             this._showPolarPointer(\r
42551                                 axisPointerModel, coordSys, axisType, point\r
42552                             );\r
42553                         }\r
42554                         else if (coordSys.type === 'single' && !contentNotChange) {\r
42555                             this._showSinglePointer(\r
42556                                 axisPointerModel, coordSys, axisType, point\r
42557                             );\r
42558                         }\r
42559 \r
42560                         if (axisPointerType !== 'cross') {\r
42561                             this._dispatchAndShowSeriesTooltipContent(\r
42562                                 coordSys, seriesCoordSysSameAxis.series, point, value, contentNotChange\r
42563                             );\r
42564                         }\r
42565                     }, this);\r
42566 \r
42567                     if (allNotShow) {\r
42568                         this._hide();\r
42569                     }\r
42570                 },\r
42571 \r
42572                 /**\r
42573                  * Show tooltip on axis of cartesian coordinate\r
42574                  * @param {module:echarts/model/Model} axisPointerModel\r
42575                  * @param {module:echarts/coord/cartesian/Cartesian2D} cartesians\r
42576                  * @param {string} axisType\r
42577                  * @param {Array.<number>} point\r
42578                  * @private\r
42579                  */\r
42580                 _showCartesianPointer: function (axisPointerModel, cartesian, axisType, point) {\r
42581                     var self = this;\r
42582 \r
42583                     var axisPointerType = axisPointerModel.get('type');\r
42584                     var moveAnimation = axisPointerType !== 'cross';\r
42585 \r
42586                     if (axisPointerType === 'cross') {\r
42587                         moveGridLine('x', point, cartesian.getAxis('y').getGlobalExtent());\r
42588                         moveGridLine('y', point, cartesian.getAxis('x').getGlobalExtent());\r
42589 \r
42590                         this._updateCrossText(cartesian, point, axisPointerModel);\r
42591                     }\r
42592                     else {\r
42593                         var otherAxis = cartesian.getAxis(axisType === 'x' ? 'y' : 'x');\r
42594                         var otherExtent = otherAxis.getGlobalExtent();\r
42595 \r
42596                         if (cartesian.type === 'cartesian2d') {\r
42597                             (axisPointerType === 'line' ? moveGridLine : moveGridShadow)(\r
42598                                 axisType, point, otherExtent\r
42599                             );\r
42600                         }\r
42601                     }\r
42602 \r
42603                     /**\r
42604                      * @inner\r
42605                      */\r
42606                     function moveGridLine(axisType, point, otherExtent) {\r
42607                         var targetShape = axisType === 'x'\r
42608                             ? makeLineShape(point[0], otherExtent[0], point[0], otherExtent[1])\r
42609                             : makeLineShape(otherExtent[0], point[1], otherExtent[1], point[1]);\r
42610 \r
42611                         var pointerEl = self._getPointerElement(\r
42612                             cartesian, axisPointerModel, axisType, targetShape\r
42613                         );\r
42614                         moveAnimation\r
42615                             ? graphic.updateProps(pointerEl, {\r
42616                                 shape: targetShape\r
42617                             }, axisPointerModel)\r
42618                             :  pointerEl.attr({\r
42619                                 shape: targetShape\r
42620                             });\r
42621                     }\r
42622 \r
42623                     /**\r
42624                      * @inner\r
42625                      */\r
42626                     function moveGridShadow(axisType, point, otherExtent) {\r
42627                         var axis = cartesian.getAxis(axisType);\r
42628                         var bandWidth = axis.getBandWidth();\r
42629                         var span = otherExtent[1] - otherExtent[0];\r
42630                         var targetShape = axisType === 'x'\r
42631                             ? makeRectShape(point[0] - bandWidth / 2, otherExtent[0], bandWidth, span)\r
42632                             : makeRectShape(otherExtent[0], point[1] - bandWidth / 2, span, bandWidth);\r
42633 \r
42634                         var pointerEl = self._getPointerElement(\r
42635                             cartesian, axisPointerModel, axisType, targetShape\r
42636                         );\r
42637                         moveAnimation\r
42638                             ? graphic.updateProps(pointerEl, {\r
42639                                 shape: targetShape\r
42640                             }, axisPointerModel)\r
42641                             :  pointerEl.attr({\r
42642                                 shape: targetShape\r
42643                             });\r
42644                     }\r
42645                 },\r
42646 \r
42647                 _showSinglePointer: function (axisPointerModel, single, axisType, point) {\r
42648                     var self = this;\r
42649                     var axisPointerType = axisPointerModel.get('type');\r
42650                     var moveAnimation = axisPointerType !== 'cross';\r
42651                     var rect = single.getRect();\r
42652                     var otherExtent = [rect.y, rect.y + rect.height];\r
42653 \r
42654                     moveSingleLine(axisType, point, otherExtent);\r
42655 \r
42656                     /**\r
42657                      * @inner\r
42658                      */\r
42659                     function moveSingleLine(axisType, point, otherExtent) {\r
42660                         var axis = single.getAxis();\r
42661                         var orient = axis.orient;\r
42662 \r
42663                         var targetShape = orient === 'horizontal'\r
42664                             ? makeLineShape(point[0], otherExtent[0], point[0], otherExtent[1])\r
42665                             : makeLineShape(otherExtent[0], point[1], otherExtent[1], point[1]);\r
42666 \r
42667                         var pointerEl = self._getPointerElement(\r
42668                             single, axisPointerModel, axisType, targetShape\r
42669                         );\r
42670                         moveAnimation\r
42671                             ? graphic.updateProps(pointerEl, {\r
42672                                 shape: targetShape\r
42673                             }, axisPointerModel)\r
42674                             :  pointerEl.attr({\r
42675                                 shape: targetShape\r
42676                             });\r
42677                     }\r
42678 \r
42679                 },\r
42680 \r
42681                 /**\r
42682                  * Show tooltip on axis of polar coordinate\r
42683                  * @param {module:echarts/model/Model} axisPointerModel\r
42684                  * @param {Array.<module:echarts/coord/polar/Polar>} polar\r
42685                  * @param {string} axisType\r
42686                  * @param {Array.<number>} point\r
42687                  */\r
42688                 _showPolarPointer: function (axisPointerModel, polar, axisType, point) {\r
42689                     var self = this;\r
42690 \r
42691                     var axisPointerType = axisPointerModel.get('type');\r
42692 \r
42693                     var angleAxis = polar.getAngleAxis();\r
42694                     var radiusAxis = polar.getRadiusAxis();\r
42695 \r
42696                     var moveAnimation = axisPointerType !== 'cross';\r
42697 \r
42698                     if (axisPointerType === 'cross') {\r
42699                         movePolarLine('angle', point, radiusAxis.getExtent());\r
42700                         movePolarLine('radius', point, angleAxis.getExtent());\r
42701 \r
42702                         this._updateCrossText(polar, point, axisPointerModel);\r
42703                     }\r
42704                     else {\r
42705                         var otherAxis = polar.getAxis(axisType === 'radius' ? 'angle' : 'radius');\r
42706                         var otherExtent = otherAxis.getExtent();\r
42707 \r
42708                         (axisPointerType === 'line' ? movePolarLine : movePolarShadow)(\r
42709                             axisType, point, otherExtent\r
42710                         );\r
42711                     }\r
42712                     /**\r
42713                      * @inner\r
42714                      */\r
42715                     function movePolarLine(axisType, point, otherExtent) {\r
42716                         var mouseCoord = polar.pointToCoord(point);\r
42717 \r
42718                         var targetShape;\r
42719 \r
42720                         if (axisType === 'angle') {\r
42721                             var p1 = polar.coordToPoint([otherExtent[0], mouseCoord[1]]);\r
42722                             var p2 = polar.coordToPoint([otherExtent[1], mouseCoord[1]]);\r
42723                             targetShape = makeLineShape(p1[0], p1[1], p2[0], p2[1]);\r
42724                         }\r
42725                         else {\r
42726                             targetShape = {\r
42727                                 cx: polar.cx,\r
42728                                 cy: polar.cy,\r
42729                                 r: mouseCoord[0]\r
42730                             };\r
42731                         }\r
42732 \r
42733                         var pointerEl = self._getPointerElement(\r
42734                             polar, axisPointerModel, axisType, targetShape\r
42735                         );\r
42736 \r
42737                         moveAnimation\r
42738                             ? graphic.updateProps(pointerEl, {\r
42739                                 shape: targetShape\r
42740                             }, axisPointerModel)\r
42741                             :  pointerEl.attr({\r
42742                                 shape: targetShape\r
42743                             });\r
42744                     }\r
42745 \r
42746                     /**\r
42747                      * @inner\r
42748                      */\r
42749                     function movePolarShadow(axisType, point, otherExtent) {\r
42750                         var axis = polar.getAxis(axisType);\r
42751                         var bandWidth = axis.getBandWidth();\r
42752 \r
42753                         var mouseCoord = polar.pointToCoord(point);\r
42754 \r
42755                         var targetShape;\r
42756 \r
42757                         var radian = Math.PI / 180;\r
42758 \r
42759                         if (axisType === 'angle') {\r
42760                             targetShape = makeSectorShape(\r
42761                                 polar.cx, polar.cy,\r
42762                                 otherExtent[0], otherExtent[1],\r
42763                                 // In ECharts y is negative if angle is positive\r
42764                                 (-mouseCoord[1] - bandWidth / 2) * radian,\r
42765                                 (-mouseCoord[1] + bandWidth / 2) * radian\r
42766                             );\r
42767                         }\r
42768                         else {\r
42769                             targetShape = makeSectorShape(\r
42770                                 polar.cx, polar.cy,\r
42771                                 mouseCoord[0] - bandWidth / 2,\r
42772                                 mouseCoord[0] + bandWidth / 2,\r
42773                                 0, Math.PI * 2\r
42774                             );\r
42775                         }\r
42776 \r
42777                         var pointerEl = self._getPointerElement(\r
42778                             polar, axisPointerModel, axisType, targetShape\r
42779                         );\r
42780                         moveAnimation\r
42781                             ? graphic.updateProps(pointerEl, {\r
42782                                 shape: targetShape\r
42783                             }, axisPointerModel)\r
42784                             :  pointerEl.attr({\r
42785                                 shape: targetShape\r
42786                             });\r
42787                     }\r
42788                 },\r
42789 \r
42790                 _updateCrossText: function (coordSys, point, axisPointerModel) {\r
42791                     var crossStyleModel = axisPointerModel.getModel('crossStyle');\r
42792                     var textStyleModel = crossStyleModel.getModel('textStyle');\r
42793 \r
42794                     var tooltipModel = this._tooltipModel;\r
42795 \r
42796                     var text = this._crossText;\r
42797                     if (!text) {\r
42798                         text = this._crossText = new graphic.Text({\r
42799                             style: {\r
42800                                 textAlign: 'left',\r
42801                                 textVerticalAlign: 'bottom'\r
42802                             }\r
42803                         });\r
42804                         this.group.add(text);\r
42805                     }\r
42806 \r
42807                     var value = coordSys.pointToData(point);\r
42808 \r
42809                     var dims = coordSys.dimensions;\r
42810                     value = zrUtil.map(value, function (val, idx) {\r
42811                         var axis = coordSys.getAxis(dims[idx]);\r
42812                         if (axis.type === 'category' || axis.type === 'time') {\r
42813                             val = axis.scale.getLabel(val);\r
42814                         }\r
42815                         else {\r
42816                             val = formatUtil.addCommas(\r
42817                                 val.toFixed(axis.getPixelPrecision())\r
42818                             );\r
42819                         }\r
42820                         return val;\r
42821                     });\r
42822 \r
42823                     text.setStyle({\r
42824                         fill: textStyleModel.getTextColor() || crossStyleModel.get('color'),\r
42825                         textFont: textStyleModel.getFont(),\r
42826                         text: value.join(', '),\r
42827                         x: point[0] + 5,\r
42828                         y: point[1] - 5\r
42829                     });\r
42830                     text.z = tooltipModel.get('z');\r
42831                     text.zlevel = tooltipModel.get('zlevel');\r
42832                 },\r
42833 \r
42834                 _getPointerElement: function (coordSys, pointerModel, axisType, initShape) {\r
42835                     var tooltipModel = this._tooltipModel;\r
42836                     var z = tooltipModel.get('z');\r
42837                     var zlevel = tooltipModel.get('zlevel');\r
42838                     var axisPointers = this._axisPointers;\r
42839                     var coordSysName = coordSys.name;\r
42840                     axisPointers[coordSysName] = axisPointers[coordSysName] || {};\r
42841                     if (axisPointers[coordSysName][axisType]) {\r
42842                         return axisPointers[coordSysName][axisType];\r
42843                     }\r
42844 \r
42845                     // Create if not exists\r
42846                     var pointerType = pointerModel.get('type');\r
42847                     var styleModel = pointerModel.getModel(pointerType + 'Style');\r
42848                     var isShadow = pointerType === 'shadow';\r
42849                     var style = styleModel[isShadow ? 'getAreaStyle' : 'getLineStyle']();\r
42850 \r
42851                     var elementType = coordSys.type === 'polar'\r
42852                         ? (isShadow ? 'Sector' : (axisType === 'radius' ? 'Circle' : 'Line'))\r
42853                         : (isShadow ? 'Rect' : 'Line');\r
42854 \r
42855                    isShadow ? (style.stroke = null) : (style.fill = null);\r
42856 \r
42857                     var el = axisPointers[coordSysName][axisType] = new graphic[elementType]({\r
42858                         style: style,\r
42859                         z: z,\r
42860                         zlevel: zlevel,\r
42861                         silent: true,\r
42862                         shape: initShape\r
42863                     });\r
42864 \r
42865                     this.group.add(el);\r
42866                     return el;\r
42867                 },\r
42868 \r
42869                 /**\r
42870                  * Dispatch actions and show tooltip on series\r
42871                  * @param {Array.<module:echarts/model/Series>} seriesList\r
42872                  * @param {Array.<number>} point\r
42873                  * @param {Array.<number>} value\r
42874                  * @param {boolean} contentNotChange\r
42875                  * @param {Object} e\r
42876                  */\r
42877                 _dispatchAndShowSeriesTooltipContent: function (\r
42878                     coordSys, seriesList, point, value, contentNotChange\r
42879                 ) {\r
42880 \r
42881                     var rootTooltipModel = this._tooltipModel;\r
42882                     var tooltipContent = this._tooltipContent;\r
42883 \r
42884                     var baseAxis = coordSys.getBaseAxis();\r
42885 \r
42886                     var payloadBatch = zrUtil.map(seriesList, function (series) {\r
42887                         return {\r
42888                             seriesIndex: series.seriesIndex,\r
42889                             dataIndex: series.getAxisTooltipDataIndex\r
42890                                 ? series.getAxisTooltipDataIndex(series.coordDimToDataDim(baseAxis.dim), value, baseAxis)\r
42891                                 : series.getData().indexOfNearest(\r
42892                                     series.coordDimToDataDim(baseAxis.dim)[0],\r
42893                                     value[baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1]\r
42894                                 )\r
42895                         };\r
42896                     });\r
42897 \r
42898                     var lastHover = this._lastHover;\r
42899                     var api = this._api;\r
42900                     // Dispatch downplay action\r
42901                     if (lastHover.payloadBatch && !contentNotChange) {\r
42902                         api.dispatchAction({\r
42903                             type: 'downplay',\r
42904                             batch: lastHover.payloadBatch\r
42905                         });\r
42906                     }\r
42907                     // Dispatch highlight action\r
42908                     if (!contentNotChange) {\r
42909                         api.dispatchAction({\r
42910                             type: 'highlight',\r
42911                             batch: payloadBatch\r
42912                         });\r
42913                         lastHover.payloadBatch = payloadBatch;\r
42914                     }\r
42915                     // Dispatch showTip action\r
42916                     api.dispatchAction({\r
42917                         type: 'showTip',\r
42918                         dataIndex: payloadBatch[0].dataIndex,\r
42919                         seriesIndex: payloadBatch[0].seriesIndex,\r
42920                         from: this.uid\r
42921                     });\r
42922 \r
42923                     if (baseAxis && rootTooltipModel.get('showContent')) {\r
42924 \r
42925                         var formatter = rootTooltipModel.get('formatter');\r
42926                         var positionExpr = rootTooltipModel.get('position');\r
42927                         var html;\r
42928 \r
42929                         var paramsList = zrUtil.map(seriesList, function (series, index) {\r
42930                             return series.getDataParams(payloadBatch[index].dataIndex);\r
42931                         });\r
42932                         // If only one series\r
42933                         // FIXME\r
42934                         // if (paramsList.length === 1) {\r
42935                         //     paramsList = paramsList[0];\r
42936                         // }\r
42937 \r
42938                         tooltipContent.show(rootTooltipModel);\r
42939 \r
42940                         // Update html content\r
42941                         var firstDataIndex = payloadBatch[0].dataIndex;\r
42942                         if (!contentNotChange) {\r
42943                             // Reset ticket\r
42944                             this._ticket = '';\r
42945                             if (!formatter) {\r
42946                                 // Default tooltip content\r
42947                                 // FIXME\r
42948                                 // (1) shold be the first data which has name?\r
42949                                 // (2) themeRiver, firstDataIndex is array, and first line is unnecessary.\r
42950                                 var firstLine = seriesList[0].getData().getName(firstDataIndex);\r
42951                                 html = (firstLine ? firstLine + '<br />' : '')\r
42952                                     + zrUtil.map(seriesList, function (series, index) {\r
42953                                         return series.formatTooltip(payloadBatch[index].dataIndex, true);\r
42954                                     }).join('<br />');\r
42955                             }\r
42956                             else {\r
42957                                 if (typeof formatter === 'string') {\r
42958                                     html = formatUtil.formatTpl(formatter, paramsList);\r
42959                                 }\r
42960                                 else if (typeof formatter === 'function') {\r
42961                                     var self = this;\r
42962                                     var ticket = 'axis_' + coordSys.name + '_' + firstDataIndex;\r
42963                                     var callback = function (cbTicket, html) {\r
42964                                         if (cbTicket === self._ticket) {\r
42965                                             tooltipContent.setContent(html);\r
42966 \r
42967                                             updatePosition(\r
42968                                                 positionExpr, point[0], point[1],\r
42969                                                 tooltipContent, paramsList, null, api\r
42970                                             );\r
42971                                         }\r
42972                                     };\r
42973                                     self._ticket = ticket;\r
42974                                     html = formatter(paramsList, ticket, callback);\r
42975                                 }\r
42976                             }\r
42977 \r
42978                             tooltipContent.setContent(html);\r
42979                         }\r
42980 \r
42981                         updatePosition(\r
42982                             positionExpr, point[0], point[1],\r
42983                             tooltipContent, paramsList, null, api\r
42984                         );\r
42985                     }\r
42986                 },\r
42987 \r
42988                 /**\r
42989                  * Show tooltip on item\r
42990                  * @param {module:echarts/model/Series} seriesModel\r
42991                  * @param {number} dataIndex\r
42992                  * @param {Object} e\r
42993                  */\r
42994                 _showItemTooltipContent: function (seriesModel, dataIndex, e) {\r
42995                     // FIXME Graph data\r
42996                     var api = this._api;\r
42997                     var data = seriesModel.getData();\r
42998                     var itemModel = data.getItemModel(dataIndex);\r
42999 \r
43000                     var rootTooltipModel = this._tooltipModel;\r
43001 \r
43002                     var tooltipContent = this._tooltipContent;\r
43003 \r
43004                     var tooltipModel = itemModel.getModel('tooltip');\r
43005 \r
43006                     // If series model\r
43007                     if (tooltipModel.parentModel) {\r
43008                         tooltipModel.parentModel.parentModel = rootTooltipModel;\r
43009                     }\r
43010                     else {\r
43011                         tooltipModel.parentModel = this._tooltipModel;\r
43012                     }\r
43013 \r
43014                     if (tooltipModel.get('showContent')) {\r
43015                         var formatter = tooltipModel.get('formatter');\r
43016                         var positionExpr = tooltipModel.get('position');\r
43017                         var params = seriesModel.getDataParams(dataIndex);\r
43018                         var html;\r
43019                         if (!formatter) {\r
43020                             html = seriesModel.formatTooltip(dataIndex);\r
43021                         }\r
43022                         else {\r
43023                             if (typeof formatter === 'string') {\r
43024                                 html = formatUtil.formatTpl(formatter, params);\r
43025                             }\r
43026                             else if (typeof formatter === 'function') {\r
43027                                 var self = this;\r
43028                                 var ticket = 'item_' + seriesModel.name + '_' + dataIndex;\r
43029                                 var callback = function (cbTicket, html) {\r
43030                                     if (cbTicket === self._ticket) {\r
43031                                         tooltipContent.setContent(html);\r
43032 \r
43033                                         updatePosition(\r
43034                                             positionExpr, e.offsetX, e.offsetY,\r
43035                                             tooltipContent, params, e.target, api\r
43036                                         );\r
43037                                     }\r
43038                                 };\r
43039                                 self._ticket = ticket;\r
43040                                 html = formatter(params, ticket, callback);\r
43041                             }\r
43042                         }\r
43043 \r
43044                         tooltipContent.show(tooltipModel);\r
43045                         tooltipContent.setContent(html);\r
43046 \r
43047                         updatePosition(\r
43048                             positionExpr, e.offsetX, e.offsetY,\r
43049                             tooltipContent, params, e.target, api\r
43050                         );\r
43051                     }\r
43052                 },\r
43053 \r
43054                 /**\r
43055                  * Show axis pointer\r
43056                  * @param {string} [coordSysName]\r
43057                  */\r
43058                 _showAxisPointer: function (coordSysName) {\r
43059                     if (coordSysName) {\r
43060                         var axisPointers = this._axisPointers[coordSysName];\r
43061                         axisPointers && zrUtil.each(axisPointers, function (el) {\r
43062                             el.show();\r
43063                         });\r
43064                     }\r
43065                     else {\r
43066                         this.group.eachChild(function (child) {\r
43067                             child.show();\r
43068                         });\r
43069                         this.group.show();\r
43070                     }\r
43071                 },\r
43072 \r
43073                 _resetLastHover: function () {\r
43074                     var lastHover = this._lastHover;\r
43075                     if (lastHover.payloadBatch) {\r
43076                         this._api.dispatchAction({\r
43077                             type: 'downplay',\r
43078                             batch: lastHover.payloadBatch\r
43079                         });\r
43080                     }\r
43081                     // Reset lastHover\r
43082                     this._lastHover = {};\r
43083                 },\r
43084                 /**\r
43085                  * Hide axis pointer\r
43086                  * @param {string} [coordSysName]\r
43087                  */\r
43088                 _hideAxisPointer: function (coordSysName) {\r
43089                     if (coordSysName) {\r
43090                         var axisPointers = this._axisPointers[coordSysName];\r
43091                         axisPointers && zrUtil.each(axisPointers, function (el) {\r
43092                             el.hide();\r
43093                         });\r
43094                     }\r
43095                     else {\r
43096                         this.group.hide();\r
43097                     }\r
43098                 },\r
43099 \r
43100                 _hide: function () {\r
43101                     this._hideAxisPointer();\r
43102                     this._resetLastHover();\r
43103                     if (!this._alwaysShowContent) {\r
43104                         this._tooltipContent.hideLater(this._tooltipModel.get('hideDelay'));\r
43105                     }\r
43106 \r
43107                     this._api.dispatchAction({\r
43108                         type: 'hideTip',\r
43109                         from: this.uid\r
43110                     });\r
43111                 },\r
43112 \r
43113                 dispose: function (ecModel, api) {\r
43114                     if (env.node) {\r
43115                         return;\r
43116                     }\r
43117                     var zr = api.getZr();\r
43118                     this._tooltipContent.hide();\r
43119 \r
43120                     zr.off('click', this._tryShow);\r
43121                     zr.off('mousemove', this._tryShow);\r
43122                     zr.off('mouseout', this._hide);\r
43123 \r
43124                     api.off('showTip', this._manuallyShowTip);\r
43125                     api.off('hideTip', this._manuallyHideTip);\r
43126                 }\r
43127             });\r
43128 \r
43129 \r
43130 /***/ },\r
43131 /* 271 */\r
43132 /***/ function(module, exports, __webpack_require__) {\r
43133 \r
43134         /**\r
43135          * @module echarts/component/tooltip/TooltipContent\r
43136          */\r
43137 \r
43138 \r
43139             var zrUtil = __webpack_require__(3);\r
43140             var zrColor = __webpack_require__(38);\r
43141             var eventUtil = __webpack_require__(80);\r
43142             var formatUtil = __webpack_require__(6);\r
43143             var each = zrUtil.each;\r
43144             var toCamelCase = formatUtil.toCamelCase;\r
43145 \r
43146             var vendors = ['', '-webkit-', '-moz-', '-o-'];\r
43147 \r
43148             var gCssText = 'position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;';\r
43149 \r
43150             /**\r
43151              * @param {number} duration\r
43152              * @return {string}\r
43153              * @inner\r
43154              */\r
43155             function assembleTransition(duration) {\r
43156                 var transitionCurve = 'cubic-bezier(0.23, 1, 0.32, 1)';\r
43157                 var transitionText = 'left ' + duration + 's ' + transitionCurve + ','\r
43158                                     + 'top ' + duration + 's ' + transitionCurve;\r
43159                 return zrUtil.map(vendors, function (vendorPrefix) {\r
43160                     return vendorPrefix + 'transition:' + transitionText;\r
43161                 }).join(';');\r
43162             }\r
43163 \r
43164             /**\r
43165              * @param {Object} textStyle\r
43166              * @return {string}\r
43167              * @inner\r
43168              */\r
43169             function assembleFont(textStyleModel) {\r
43170                 var cssText = [];\r
43171 \r
43172                 var fontSize = textStyleModel.get('fontSize');\r
43173                 var color = textStyleModel.getTextColor();\r
43174 \r
43175                 color && cssText.push('color:' + color);\r
43176 \r
43177                 cssText.push('font:' + textStyleModel.getFont());\r
43178 \r
43179                 fontSize &&\r
43180                     cssText.push('line-height:' + Math.round(fontSize * 3 / 2) + 'px');\r
43181 \r
43182                 each(['decoration', 'align'], function (name) {\r
43183                     var val = textStyleModel.get(name);\r
43184                     val && cssText.push('text-' + name + ':' + val);\r
43185                 });\r
43186 \r
43187                 return cssText.join(';');\r
43188             }\r
43189 \r
43190             /**\r
43191              * @param {Object} tooltipModel\r
43192              * @return {string}\r
43193              * @inner\r
43194              */\r
43195             function assembleCssText(tooltipModel) {\r
43196 \r
43197                 tooltipModel = tooltipModel;\r
43198 \r
43199                 var cssText = [];\r
43200 \r
43201                 var transitionDuration = tooltipModel.get('transitionDuration');\r
43202                 var backgroundColor = tooltipModel.get('backgroundColor');\r
43203                 var textStyleModel = tooltipModel.getModel('textStyle');\r
43204                 var padding = tooltipModel.get('padding');\r
43205 \r
43206                 // Animation transition\r
43207                 transitionDuration &&\r
43208                     cssText.push(assembleTransition(transitionDuration));\r
43209 \r
43210                 if (backgroundColor) {\r
43211                     // for ie\r
43212                     cssText.push(\r
43213                         'background-Color:' + zrColor.toHex(backgroundColor)\r
43214                     );\r
43215                     cssText.push('filter:alpha(opacity=70)');\r
43216                     cssText.push('background-Color:' + backgroundColor);\r
43217                 }\r
43218 \r
43219                 // Border style\r
43220                 each(['width', 'color', 'radius'], function (name) {\r
43221                     var borderName = 'border-' + name;\r
43222                     var camelCase = toCamelCase(borderName);\r
43223                     var val = tooltipModel.get(camelCase);\r
43224                     val != null &&\r
43225                         cssText.push(borderName + ':' + val + (name === 'color' ? '' : 'px'));\r
43226                 });\r
43227 \r
43228                 // Text style\r
43229                 cssText.push(assembleFont(textStyleModel));\r
43230 \r
43231                 // Padding\r
43232                 if (padding != null) {\r
43233                     cssText.push('padding:' + formatUtil.normalizeCssArray(padding).join('px ') + 'px');\r
43234                 }\r
43235 \r
43236                 return cssText.join(';') + ';';\r
43237             }\r
43238 \r
43239             /**\r
43240              * @alias module:echarts/component/tooltip/TooltipContent\r
43241              * @constructor\r
43242              */\r
43243             function TooltipContent(container, api) {\r
43244                 var el = document.createElement('div');\r
43245                 var zr = api.getZr();\r
43246 \r
43247                 this.el = el;\r
43248 \r
43249                 this._x = api.getWidth() / 2;\r
43250                 this._y = api.getHeight() / 2;\r
43251 \r
43252                 container.appendChild(el);\r
43253 \r
43254                 this._container = container;\r
43255 \r
43256                 this._show = false;\r
43257 \r
43258                 /**\r
43259                  * @private\r
43260                  */\r
43261                 this._hideTimeout;\r
43262 \r
43263                 var self = this;\r
43264                 el.onmouseenter = function () {\r
43265                     // clear the timeout in hideLater and keep showing tooltip\r
43266                     if (self.enterable) {\r
43267                         clearTimeout(self._hideTimeout);\r
43268                         self._show = true;\r
43269                     }\r
43270                     self._inContent = true;\r
43271                 };\r
43272                 el.onmousemove = function (e) {\r
43273                     if (!self.enterable) {\r
43274                         // Try trigger zrender event to avoid mouse\r
43275                         // in and out shape too frequently\r
43276                         var handler = zr.handler;\r
43277                         eventUtil.normalizeEvent(container, e);\r
43278                         handler.dispatch('mousemove', e);\r
43279                     }\r
43280                 };\r
43281                 el.onmouseleave = function () {\r
43282                     if (self.enterable) {\r
43283                         if (self._show) {\r
43284                             self.hideLater(self._hideDelay);\r
43285                         }\r
43286                     }\r
43287                     self._inContent = false;\r
43288                 };\r
43289 \r
43290                 compromiseMobile(el, container);\r
43291             }\r
43292 \r
43293             function compromiseMobile(tooltipContentEl, container) {\r
43294                 // Prevent default behavior on mobile. For example,\r
43295                 // defuault pinch gesture will cause browser zoom.\r
43296                 // We do not preventing event on tooltip contnet el,\r
43297                 // because user may need customization in tooltip el.\r
43298                 eventUtil.addEventListener(container, 'touchstart', preventDefault);\r
43299                 eventUtil.addEventListener(container, 'touchmove', preventDefault);\r
43300                 eventUtil.addEventListener(container, 'touchend', preventDefault);\r
43301 \r
43302                 function preventDefault(e) {\r
43303                     if (contains(e.target)) {\r
43304                         e.preventDefault();\r
43305                     }\r
43306                 }\r
43307 \r
43308                 function contains(targetEl) {\r
43309                     while (targetEl && targetEl !== container) {\r
43310                         if (targetEl === tooltipContentEl) {\r
43311                             return true;\r
43312                         }\r
43313                         targetEl = targetEl.parentNode;\r
43314                     }\r
43315                 }\r
43316             }\r
43317 \r
43318             TooltipContent.prototype = {\r
43319 \r
43320                 constructor: TooltipContent,\r
43321 \r
43322                 enterable: true,\r
43323 \r
43324                 /**\r
43325                  * Update when tooltip is rendered\r
43326                  */\r
43327                 update: function () {\r
43328                     var container = this._container;\r
43329                     var stl = container.currentStyle\r
43330                         || document.defaultView.getComputedStyle(container);\r
43331                     var domStyle = container.style;\r
43332                     if (domStyle.position !== 'absolute' && stl.position !== 'absolute') {\r
43333                         domStyle.position = 'relative';\r
43334                     }\r
43335                     // Hide the tooltip\r
43336                     // PENDING\r
43337                     // this.hide();\r
43338                 },\r
43339 \r
43340                 show: function (tooltipModel) {\r
43341                     clearTimeout(this._hideTimeout);\r
43342 \r
43343                     this.el.style.cssText = gCssText + assembleCssText(tooltipModel)\r
43344                         // http://stackoverflow.com/questions/21125587/css3-transition-not-working-in-chrome-anymore\r
43345                         + ';left:' + this._x + 'px;top:' + this._y + 'px;'\r
43346                         + (tooltipModel.get('extraCssText') || '');\r
43347 \r
43348                     this._show = true;\r
43349                 },\r
43350 \r
43351                 setContent: function (content) {\r
43352                     var el = this.el;\r
43353                     el.innerHTML = content;\r
43354                     el.style.display = content ? 'block' : 'none';\r
43355                 },\r
43356 \r
43357                 moveTo: function (x, y) {\r
43358                     var style = this.el.style;\r
43359                     style.left = x + 'px';\r
43360                     style.top = y + 'px';\r
43361 \r
43362                     this._x = x;\r
43363                     this._y = y;\r
43364                 },\r
43365 \r
43366                 hide: function () {\r
43367                     this.el.style.display = 'none';\r
43368                     this._show = false;\r
43369                 },\r
43370 \r
43371                 // showLater: function ()\r
43372 \r
43373                 hideLater: function (time) {\r
43374                     if (this._show && !(this._inContent && this.enterable)) {\r
43375                         if (time) {\r
43376                             this._hideDelay = time;\r
43377                             // Set show false to avoid invoke hideLater mutiple times\r
43378                             this._show = false;\r
43379                             this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time);\r
43380                         }\r
43381                         else {\r
43382                             this.hide();\r
43383                         }\r
43384                     }\r
43385                 },\r
43386 \r
43387                 isShow: function () {\r
43388                     return this._show;\r
43389                 }\r
43390             };\r
43391 \r
43392             module.exports = TooltipContent;\r
43393 \r
43394 \r
43395 /***/ },\r
43396 /* 272 */\r
43397 /***/ function(module, exports, __webpack_require__) {\r
43398 \r
43399         'use strict';\r
43400 \r
43401 \r
43402             __webpack_require__(273);\r
43403             __webpack_require__(279);\r
43404             __webpack_require__(281);\r
43405 \r
43406             // Polar view\r
43407             __webpack_require__(1).extendComponentView({\r
43408                 type: 'polar'\r
43409             });\r
43410 \r
43411 \r
43412 /***/ },\r
43413 /* 273 */\r
43414 /***/ function(module, exports, __webpack_require__) {\r
43415 \r
43416         // TODO Axis scale\r
43417 \r
43418 \r
43419             var Polar = __webpack_require__(274);\r
43420             var numberUtil = __webpack_require__(7);\r
43421 \r
43422             var axisHelper = __webpack_require__(108);\r
43423             var niceScaleExtent = axisHelper.niceScaleExtent;\r
43424 \r
43425             // 依赖 PolarModel 做预处理\r
43426             __webpack_require__(277);\r
43427 \r
43428             /**\r
43429              * Resize method bound to the polar\r
43430              * @param {module:echarts/coord/polar/PolarModel} polarModel\r
43431              * @param {module:echarts/ExtensionAPI} api\r
43432              */\r
43433             function resizePolar(polarModel, api) {\r
43434                 var center = polarModel.get('center');\r
43435                 var radius = polarModel.get('radius');\r
43436                 var width = api.getWidth();\r
43437                 var height = api.getHeight();\r
43438                 var parsePercent = numberUtil.parsePercent;\r
43439 \r
43440                 this.cx = parsePercent(center[0], width);\r
43441                 this.cy = parsePercent(center[1], height);\r
43442 \r
43443                 var radiusAxis = this.getRadiusAxis();\r
43444                 var size = Math.min(width, height) / 2;\r
43445                 // var idx = radiusAxis.inverse ? 1 : 0;\r
43446                 radiusAxis.setExtent(0, parsePercent(radius, size));\r
43447             }\r
43448 \r
43449             /**\r
43450              * Update polar\r
43451              */\r
43452             function updatePolarScale(ecModel, api) {\r
43453                 var polar = this;\r
43454                 var angleAxis = polar.getAngleAxis();\r
43455                 var radiusAxis = polar.getRadiusAxis();\r
43456                 // Reset scale\r
43457                 angleAxis.scale.setExtent(Infinity, -Infinity);\r
43458                 radiusAxis.scale.setExtent(Infinity, -Infinity);\r
43459 \r
43460                 ecModel.eachSeries(function (seriesModel) {\r
43461                     if (seriesModel.coordinateSystem === polar) {\r
43462                         var data = seriesModel.getData();\r
43463                         radiusAxis.scale.unionExtent(\r
43464                             data.getDataExtent('radius', radiusAxis.type !== 'category')\r
43465                         );\r
43466                         angleAxis.scale.unionExtent(\r
43467                             data.getDataExtent('angle', angleAxis.type !== 'category')\r
43468                         );\r
43469                     }\r
43470                 });\r
43471 \r
43472                 niceScaleExtent(angleAxis, angleAxis.model);\r
43473                 niceScaleExtent(radiusAxis, radiusAxis.model);\r
43474 \r
43475                 // Fix extent of category angle axis\r
43476                 if (angleAxis.type === 'category' && !angleAxis.onBand) {\r
43477                     var extent = angleAxis.getExtent();\r
43478                     var diff = 360 / angleAxis.scale.count();\r
43479                     angleAxis.inverse ? (extent[1] += diff) : (extent[1] -= diff);\r
43480                     angleAxis.setExtent(extent[0], extent[1]);\r
43481                 }\r
43482             }\r
43483 \r
43484             /**\r
43485              * Set common axis properties\r
43486              * @param {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}\r
43487              * @param {module:echarts/coord/polar/AxisModel}\r
43488              * @inner\r
43489              */\r
43490             function setAxis(axis, axisModel) {\r
43491                 axis.type = axisModel.get('type');\r
43492                 axis.scale = axisHelper.createScaleByModel(axisModel);\r
43493                 axis.onBand = axisModel.get('boundaryGap') && axis.type === 'category';\r
43494 \r
43495                 // FIXME Radius axis not support inverse axis\r
43496                 if (axisModel.mainType === 'angleAxis') {\r
43497                     var startAngle = axisModel.get('startAngle');\r
43498                     axis.inverse = axisModel.get('inverse') ^ axisModel.get('clockwise');\r
43499                     axis.setExtent(startAngle, startAngle + (axis.inverse ? -360 : 360));\r
43500                 }\r
43501 \r
43502                 // Inject axis instance\r
43503                 axisModel.axis = axis;\r
43504                 axis.model = axisModel;\r
43505             }\r
43506 \r
43507 \r
43508             var polarCreator = {\r
43509 \r
43510                 dimensions: Polar.prototype.dimensions,\r
43511 \r
43512                 create: function (ecModel, api) {\r
43513                     var polarList = [];\r
43514                     ecModel.eachComponent('polar', function (polarModel, idx) {\r
43515                         var polar = new Polar(idx);\r
43516                         // Inject resize and update method\r
43517                         polar.resize = resizePolar;\r
43518                         polar.update = updatePolarScale;\r
43519 \r
43520                         var radiusAxis = polar.getRadiusAxis();\r
43521                         var angleAxis = polar.getAngleAxis();\r
43522 \r
43523                         var radiusAxisModel = polarModel.findAxisModel('radiusAxis');\r
43524                         var angleAxisModel = polarModel.findAxisModel('angleAxis');\r
43525 \r
43526                         setAxis(radiusAxis, radiusAxisModel);\r
43527                         setAxis(angleAxis, angleAxisModel);\r
43528 \r
43529                         polar.resize(polarModel, api);\r
43530                         polarList.push(polar);\r
43531 \r
43532                         polarModel.coordinateSystem = polar;\r
43533                     });\r
43534                     // Inject coordinateSystem to series\r
43535                     ecModel.eachSeries(function (seriesModel) {\r
43536                         if (seriesModel.get('coordinateSystem') === 'polar') {\r
43537                             seriesModel.coordinateSystem = polarList[seriesModel.get('polarIndex')];\r
43538                         }\r
43539                     });\r
43540 \r
43541                     return polarList;\r
43542                 }\r
43543             };\r
43544 \r
43545             __webpack_require__(25).register('polar', polarCreator);\r
43546 \r
43547 \r
43548 /***/ },\r
43549 /* 274 */\r
43550 /***/ function(module, exports, __webpack_require__) {\r
43551 \r
43552         'use strict';\r
43553         /**\r
43554          * @module echarts/coord/polar/Polar\r
43555          */\r
43556 \r
43557 \r
43558             var RadiusAxis = __webpack_require__(275);\r
43559             var AngleAxis = __webpack_require__(276);\r
43560 \r
43561             /**\r
43562              * @alias {module:echarts/coord/polar/Polar}\r
43563              * @constructor\r
43564              * @param {string} name\r
43565              */\r
43566             var Polar = function (name) {\r
43567 \r
43568                 /**\r
43569                  * @type {string}\r
43570                  */\r
43571                 this.name = name || '';\r
43572 \r
43573                 /**\r
43574                  * x of polar center\r
43575                  * @type {number}\r
43576                  */\r
43577                 this.cx = 0;\r
43578 \r
43579                 /**\r
43580                  * y of polar center\r
43581                  * @type {number}\r
43582                  */\r
43583                 this.cy = 0;\r
43584 \r
43585                 /**\r
43586                  * @type {module:echarts/coord/polar/RadiusAxis}\r
43587                  * @private\r
43588                  */\r
43589                 this._radiusAxis = new RadiusAxis();\r
43590 \r
43591                 /**\r
43592                  * @type {module:echarts/coord/polar/AngleAxis}\r
43593                  * @private\r
43594                  */\r
43595                 this._angleAxis = new AngleAxis();\r
43596             };\r
43597 \r
43598             Polar.prototype = {\r
43599 \r
43600                 constructor: Polar,\r
43601 \r
43602                 type: 'polar',\r
43603 \r
43604                 /**\r
43605                  * @param {Array.<string>}\r
43606                  * @readOnly\r
43607                  */\r
43608                 dimensions: ['radius', 'angle'],\r
43609 \r
43610                 /**\r
43611                  * If contain coord\r
43612                  * @param {Array.<number>} point\r
43613                  * @return {boolean}\r
43614                  */\r
43615                 containPoint: function (point) {\r
43616                     var coord = this.pointToCoord(point);\r
43617                     return this._radiusAxis.contain(coord[0])\r
43618                         && this._angleAxis.contain(coord[1]);\r
43619                 },\r
43620 \r
43621                 /**\r
43622                  * If contain data\r
43623                  * @param {Array.<number>} data\r
43624                  * @return {boolean}\r
43625                  */\r
43626                 containData: function (data) {\r
43627                     return this._radiusAxis.containData(data[0])\r
43628                         && this._angleAxis.containData(data[1]);\r
43629                 },\r
43630 \r
43631                 /**\r
43632                  * @param {string} axisType\r
43633                  * @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}\r
43634                  */\r
43635                 getAxis: function (axisType) {\r
43636                     return this['_' + axisType + 'Axis'];\r
43637                 },\r
43638 \r
43639                 /**\r
43640                  * Get axes by type of scale\r
43641                  * @param {string} scaleType\r
43642                  * @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}\r
43643                  */\r
43644                 getAxesByScale: function (scaleType) {\r
43645                     var axes = [];\r
43646                     var angleAxis = this._angleAxis;\r
43647                     var radiusAxis = this._radiusAxis;\r
43648                     angleAxis.scale.type === scaleType && axes.push(angleAxis);\r
43649                     radiusAxis.scale.type === scaleType && axes.push(radiusAxis);\r
43650 \r
43651                     return axes;\r
43652                 },\r
43653 \r
43654                 /**\r
43655                  * @return {module:echarts/coord/polar/AngleAxis}\r
43656                  */\r
43657                 getAngleAxis: function () {\r
43658                     return this._angleAxis;\r
43659                 },\r
43660 \r
43661                 /**\r
43662                  * @return {module:echarts/coord/polar/RadiusAxis}\r
43663                  */\r
43664                 getRadiusAxis: function () {\r
43665                     return this._radiusAxis;\r
43666                 },\r
43667 \r
43668                 /**\r
43669                  * @param {module:echarts/coord/polar/Axis}\r
43670                  * @return {module:echarts/coord/polar/Axis}\r
43671                  */\r
43672                 getOtherAxis: function (axis) {\r
43673                     var angleAxis = this._angleAxis;\r
43674                     return axis === angleAxis ? this._radiusAxis : angleAxis;\r
43675                 },\r
43676 \r
43677                 /**\r
43678                  * Base axis will be used on stacking.\r
43679                  *\r
43680                  * @return {module:echarts/coord/polar/Axis}\r
43681                  */\r
43682                 getBaseAxis: function () {\r
43683                     return this.getAxesByScale('ordinal')[0]\r
43684                         || this.getAxesByScale('time')[0]\r
43685                         || this.getAngleAxis();\r
43686                 },\r
43687 \r
43688                 /**\r
43689                  * Convert series data to a list of (x, y) points\r
43690                  * @param {module:echarts/data/List} data\r
43691                  * @return {Array}\r
43692                  *  Return list of coordinates. For example:\r
43693                  *  `[[10, 10], [20, 20], [30, 30]]`\r
43694                  */\r
43695                 dataToPoints: function (data) {\r
43696                     return data.mapArray(this.dimensions, function (radius, angle) {\r
43697                         return this.dataToPoint([radius, angle]);\r
43698                     }, this);\r
43699                 },\r
43700 \r
43701                 /**\r
43702                  * Convert a single data item to (x, y) point.\r
43703                  * Parameter data is an array which the first element is radius and the second is angle\r
43704                  * @param {Array.<number>} data\r
43705                  * @param {boolean} [clamp=false]\r
43706                  * @return {Array.<number>}\r
43707                  */\r
43708                 dataToPoint: function (data, clamp) {\r
43709                     return this.coordToPoint([\r
43710                         this._radiusAxis.dataToRadius(data[0], clamp),\r
43711                         this._angleAxis.dataToAngle(data[1], clamp)\r
43712                     ]);\r
43713                 },\r
43714 \r
43715                 /**\r
43716                  * Convert a (x, y) point to data\r
43717                  * @param {Array.<number>} point\r
43718                  * @param {boolean} [clamp=false]\r
43719                  * @return {Array.<number>}\r
43720                  */\r
43721                 pointToData: function (point, clamp) {\r
43722                     var coord = this.pointToCoord(point);\r
43723                     return [\r
43724                         this._radiusAxis.radiusToData(coord[0], clamp),\r
43725                         this._angleAxis.angleToData(coord[1], clamp)\r
43726                     ];\r
43727                 },\r
43728 \r
43729                 /**\r
43730                  * Convert a (x, y) point to (radius, angle) coord\r
43731                  * @param {Array.<number>} point\r
43732                  * @return {Array.<number>}\r
43733                  */\r
43734                 pointToCoord: function (point) {\r
43735                     var dx = point[0] - this.cx;\r
43736                     var dy = point[1] - this.cy;\r
43737                     var angleAxis = this.getAngleAxis();\r
43738                     var extent = angleAxis.getExtent();\r
43739                     var minAngle = Math.min(extent[0], extent[1]);\r
43740                     var maxAngle = Math.max(extent[0], extent[1]);\r
43741                     // Fix fixed extent in polarCreator\r
43742                     // FIXME\r
43743                     angleAxis.inverse\r
43744                         ? (minAngle = maxAngle - 360)\r
43745                         : (maxAngle = minAngle + 360);\r
43746 \r
43747                     var radius = Math.sqrt(dx * dx + dy * dy);\r
43748                     dx /= radius;\r
43749                     dy /= radius;\r
43750 \r
43751                     var radian = Math.atan2(-dy, dx) / Math.PI * 180;\r
43752 \r
43753                     // move to angleExtent\r
43754                     var dir = radian < minAngle ? 1 : -1;\r
43755                     while (radian < minAngle || radian > maxAngle) {\r
43756                         radian += dir * 360;\r
43757                     }\r
43758 \r
43759                     return [radius, radian];\r
43760                 },\r
43761 \r
43762                 /**\r
43763                  * Convert a (radius, angle) coord to (x, y) point\r
43764                  * @param {Array.<number>} coord\r
43765                  * @return {Array.<number>}\r
43766                  */\r
43767                 coordToPoint: function (coord) {\r
43768                     var radius = coord[0];\r
43769                     var radian = coord[1] / 180 * Math.PI;\r
43770                     var x = Math.cos(radian) * radius + this.cx;\r
43771                     // Inverse the y\r
43772                     var y = -Math.sin(radian) * radius + this.cy;\r
43773 \r
43774                     return [x, y];\r
43775                 }\r
43776             };\r
43777 \r
43778             module.exports = Polar;\r
43779 \r
43780 \r
43781 /***/ },\r
43782 /* 275 */\r
43783 /***/ function(module, exports, __webpack_require__) {\r
43784 \r
43785         'use strict';\r
43786 \r
43787 \r
43788             var zrUtil = __webpack_require__(3);\r
43789             var Axis = __webpack_require__(117);\r
43790 \r
43791             function RadiusAxis(scale, radiusExtent) {\r
43792 \r
43793                 Axis.call(this, 'radius', scale, radiusExtent);\r
43794 \r
43795                 /**\r
43796                  * Axis type\r
43797                  *  - 'category'\r
43798                  *  - 'value'\r
43799                  *  - 'time'\r
43800                  *  - 'log'\r
43801                  * @type {string}\r
43802                  */\r
43803                 this.type = 'category';\r
43804             }\r
43805 \r
43806             RadiusAxis.prototype = {\r
43807 \r
43808                 constructor: RadiusAxis,\r
43809 \r
43810                 dataToRadius: Axis.prototype.dataToCoord,\r
43811 \r
43812                 radiusToData: Axis.prototype.coordToData\r
43813             };\r
43814 \r
43815             zrUtil.inherits(RadiusAxis, Axis);\r
43816 \r
43817             module.exports = RadiusAxis;\r
43818 \r
43819 \r
43820 /***/ },\r
43821 /* 276 */\r
43822 /***/ function(module, exports, __webpack_require__) {\r
43823 \r
43824         'use strict';\r
43825 \r
43826 \r
43827             var zrUtil = __webpack_require__(3);\r
43828             var Axis = __webpack_require__(117);\r
43829 \r
43830             function AngleAxis(scale, angleExtent) {\r
43831 \r
43832                 angleExtent = angleExtent || [0, 360];\r
43833 \r
43834                 Axis.call(this, 'angle', scale, angleExtent);\r
43835 \r
43836                 /**\r
43837                  * Axis type\r
43838                  *  - 'category'\r
43839                  *  - 'value'\r
43840                  *  - 'time'\r
43841                  *  - 'log'\r
43842                  * @type {string}\r
43843                  */\r
43844                 this.type = 'category';\r
43845             }\r
43846 \r
43847             AngleAxis.prototype = {\r
43848 \r
43849                 constructor: AngleAxis,\r
43850 \r
43851                 dataToAngle: Axis.prototype.dataToCoord,\r
43852 \r
43853                 angleToData: Axis.prototype.coordToData\r
43854             };\r
43855 \r
43856             zrUtil.inherits(AngleAxis, Axis);\r
43857 \r
43858             module.exports = AngleAxis;\r
43859 \r
43860 \r
43861 /***/ },\r
43862 /* 277 */\r
43863 /***/ function(module, exports, __webpack_require__) {\r
43864 \r
43865         'use strict';\r
43866 \r
43867 \r
43868             __webpack_require__(278);\r
43869 \r
43870             __webpack_require__(1).extendComponentModel({\r
43871 \r
43872                 type: 'polar',\r
43873 \r
43874                 dependencies: ['polarAxis', 'angleAxis'],\r
43875 \r
43876                 /**\r
43877                  * @type {module:echarts/coord/polar/Polar}\r
43878                  */\r
43879                 coordinateSystem: null,\r
43880 \r
43881                 /**\r
43882                  * @param {string} axisType\r
43883                  * @return {module:echarts/coord/polar/AxisModel}\r
43884                  */\r
43885                 findAxisModel: function (axisType) {\r
43886                     var angleAxisModel;\r
43887                     var ecModel = this.ecModel;\r
43888                     ecModel.eachComponent(axisType, function (axisModel) {\r
43889                         if (ecModel.getComponent(\r
43890                                 'polar', axisModel.getShallow('polarIndex')\r
43891                             ) === this) {\r
43892                             angleAxisModel = axisModel;\r
43893                         }\r
43894                     }, this);\r
43895                     return angleAxisModel;\r
43896                 },\r
43897 \r
43898                 defaultOption: {\r
43899 \r
43900                     zlevel: 0,\r
43901 \r
43902                     z: 0,\r
43903 \r
43904                     center: ['50%', '50%'],\r
43905 \r
43906                     radius: '80%'\r
43907                 }\r
43908             });\r
43909 \r
43910 \r
43911 /***/ },\r
43912 /* 278 */\r
43913 /***/ function(module, exports, __webpack_require__) {\r
43914 \r
43915         'use strict';\r
43916 \r
43917 \r
43918             var zrUtil = __webpack_require__(3);\r
43919             var ComponentModel = __webpack_require__(19);\r
43920             var axisModelCreator = __webpack_require__(121);\r
43921 \r
43922             var PolarAxisModel = ComponentModel.extend({\r
43923                 type: 'polarAxis',\r
43924                 /**\r
43925                  * @type {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}\r
43926                  */\r
43927                 axis: null\r
43928             });\r
43929 \r
43930             zrUtil.merge(PolarAxisModel.prototype, __webpack_require__(123));\r
43931 \r
43932             var polarAxisDefaultExtendedOption = {\r
43933                 angle: {\r
43934                     polarIndex: 0,\r
43935 \r
43936                     startAngle: 90,\r
43937 \r
43938                     clockwise: true,\r
43939 \r
43940                     splitNumber: 12,\r
43941 \r
43942                     axisLabel: {\r
43943                         rotate: false\r
43944                     }\r
43945                 },\r
43946                 radius: {\r
43947                     polarIndex: 0,\r
43948 \r
43949                     splitNumber: 5\r
43950                 }\r
43951             };\r
43952 \r
43953             function getAxisType(axisDim, option) {\r
43954                 // Default axis with data is category axis\r
43955                 return option.type || (option.data ? 'category' : 'value');\r
43956             }\r
43957 \r
43958             axisModelCreator('angle', PolarAxisModel, getAxisType, polarAxisDefaultExtendedOption.angle);\r
43959             axisModelCreator('radius', PolarAxisModel, getAxisType, polarAxisDefaultExtendedOption.radius);\r
43960 \r
43961 \r
43962 \r
43963 /***/ },\r
43964 /* 279 */\r
43965 /***/ function(module, exports, __webpack_require__) {\r
43966 \r
43967         'use strict';\r
43968 \r
43969 \r
43970             __webpack_require__(273);\r
43971 \r
43972             __webpack_require__(280);\r
43973 \r
43974 \r
43975 /***/ },\r
43976 /* 280 */\r
43977 /***/ function(module, exports, __webpack_require__) {\r
43978 \r
43979         'use strict';\r
43980 \r
43981 \r
43982             var zrUtil = __webpack_require__(3);\r
43983             var graphic = __webpack_require__(42);\r
43984             var Model = __webpack_require__(8);\r
43985 \r
43986             var elementList = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea'];\r
43987 \r
43988             function getAxisLineShape(polar, r0, r, angle) {\r
43989                 var start = polar.coordToPoint([r0, angle]);\r
43990                 var end = polar.coordToPoint([r, angle]);\r
43991 \r
43992                 return {\r
43993                     x1: start[0],\r
43994                     y1: start[1],\r
43995                     x2: end[0],\r
43996                     y2: end[1]\r
43997                 };\r
43998             }\r
43999             __webpack_require__(1).extendComponentView({\r
44000 \r
44001                 type: 'angleAxis',\r
44002 \r
44003                 render: function (angleAxisModel, ecModel) {\r
44004                     this.group.removeAll();\r
44005                     if (!angleAxisModel.get('show')) {\r
44006                         return;\r
44007                     }\r
44008 \r
44009                     var polarModel = ecModel.getComponent('polar', angleAxisModel.get('polarIndex'));\r
44010                     var angleAxis = angleAxisModel.axis;\r
44011                     var polar = polarModel.coordinateSystem;\r
44012                     var radiusExtent = polar.getRadiusAxis().getExtent();\r
44013                     var ticksAngles = angleAxis.getTicksCoords();\r
44014 \r
44015                     if (angleAxis.type !== 'category') {\r
44016                         // Remove the last tick which will overlap the first tick\r
44017                         ticksAngles.pop();\r
44018                     }\r
44019 \r
44020                     zrUtil.each(elementList, function (name) {\r
44021                         if (angleAxisModel.get(name +'.show')) {\r
44022                             this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent);\r
44023                         }\r
44024                     }, this);\r
44025                 },\r
44026 \r
44027                 /**\r
44028                  * @private\r
44029                  */\r
44030                 _axisLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {\r
44031                     var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle');\r
44032 \r
44033                     var circle = new graphic.Circle({\r
44034                         shape: {\r
44035                             cx: polar.cx,\r
44036                             cy: polar.cy,\r
44037                             r: radiusExtent[1]\r
44038                         },\r
44039                         style: lineStyleModel.getLineStyle(),\r
44040                         z2: 1,\r
44041                         silent: true\r
44042                     });\r
44043                     circle.style.fill = null;\r
44044 \r
44045                     this.group.add(circle);\r
44046                 },\r
44047 \r
44048                 /**\r
44049                  * @private\r
44050                  */\r
44051                 _axisTick: function (angleAxisModel, polar, ticksAngles, radiusExtent) {\r
44052                     var tickModel = angleAxisModel.getModel('axisTick');\r
44053 \r
44054                     var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');\r
44055 \r
44056                     var lines = zrUtil.map(ticksAngles, function (tickAngle) {\r
44057                         return new graphic.Line({\r
44058                             shape: getAxisLineShape(polar, radiusExtent[1], radiusExtent[1] + tickLen, tickAngle)\r
44059                         });\r
44060                     });\r
44061                     this.group.add(graphic.mergePath(\r
44062                         lines, {\r
44063                             style: tickModel.getModel('lineStyle').getLineStyle()\r
44064                         }\r
44065                     ));\r
44066                 },\r
44067 \r
44068                 /**\r
44069                  * @private\r
44070                  */\r
44071                 _axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent) {\r
44072                     var axis = angleAxisModel.axis;\r
44073 \r
44074                     var categoryData = angleAxisModel.get('data');\r
44075 \r
44076                     var labelModel = angleAxisModel.getModel('axisLabel');\r
44077                     var axisTextStyleModel = labelModel.getModel('textStyle');\r
44078 \r
44079                     var labels = angleAxisModel.getFormattedLabels();\r
44080 \r
44081                     var labelMargin = labelModel.get('margin');\r
44082                     var labelsAngles = axis.getLabelsCoords();\r
44083 \r
44084                     // Use length of ticksAngles because it may remove the last tick to avoid overlapping\r
44085                     for (var i = 0; i < ticksAngles.length; i++) {\r
44086                         var r = radiusExtent[1];\r
44087                         var p = polar.coordToPoint([r + labelMargin, labelsAngles[i]]);\r
44088                         var cx = polar.cx;\r
44089                         var cy = polar.cy;\r
44090 \r
44091                         var labelTextAlign = Math.abs(p[0] - cx) / r < 0.3\r
44092                             ? 'center' : (p[0] > cx ? 'left' : 'right');\r
44093                         var labelTextBaseline = Math.abs(p[1] - cy) / r < 0.3\r
44094                             ? 'middle' : (p[1] > cy ? 'top' : 'bottom');\r
44095 \r
44096                         var textStyleModel = axisTextStyleModel;\r
44097                         if (categoryData && categoryData[i] && categoryData[i].textStyle) {\r
44098                             textStyleModel = new Model(\r
44099                                 categoryData[i].textStyle, axisTextStyleModel\r
44100                             );\r
44101                         }\r
44102                         this.group.add(new graphic.Text({\r
44103                             style: {\r
44104                                 x: p[0],\r
44105                                 y: p[1],\r
44106                                 fill: textStyleModel.getTextColor(),\r
44107                                 text: labels[i],\r
44108                                 textAlign: labelTextAlign,\r
44109                                 textVerticalAlign: labelTextBaseline,\r
44110                                 textFont: textStyleModel.getFont()\r
44111                             },\r
44112                             silent: true\r
44113                         }));\r
44114                     }\r
44115                 },\r
44116 \r
44117                 /**\r
44118                  * @private\r
44119                  */\r
44120                 _splitLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {\r
44121                     var splitLineModel = angleAxisModel.getModel('splitLine');\r
44122                     var lineStyleModel = splitLineModel.getModel('lineStyle');\r
44123                     var lineColors = lineStyleModel.get('color');\r
44124                     var lineCount = 0;\r
44125 \r
44126                     lineColors = lineColors instanceof Array ? lineColors : [lineColors];\r
44127 \r
44128                     var splitLines = [];\r
44129 \r
44130                     for (var i = 0; i < ticksAngles.length; i++) {\r
44131                         var colorIndex = (lineCount++) % lineColors.length;\r
44132                         splitLines[colorIndex] = splitLines[colorIndex] || [];\r
44133                         splitLines[colorIndex].push(new graphic.Line({\r
44134                             shape: getAxisLineShape(polar, radiusExtent[0], radiusExtent[1], ticksAngles[i])\r
44135                         }));\r
44136                     }\r
44137 \r
44138                     // Simple optimization\r
44139                     // Batching the lines if color are the same\r
44140                     for (var i = 0; i < splitLines.length; i++) {\r
44141                         this.group.add(graphic.mergePath(splitLines[i], {\r
44142                             style: zrUtil.defaults({\r
44143                                 stroke: lineColors[i % lineColors.length]\r
44144                             }, lineStyleModel.getLineStyle()),\r
44145                             silent: true,\r
44146                             z: angleAxisModel.get('z')\r
44147                         }));\r
44148                     }\r
44149                 },\r
44150 \r
44151                 /**\r
44152                  * @private\r
44153                  */\r
44154                 _splitArea: function (angleAxisModel, polar, ticksAngles, radiusExtent) {\r
44155 \r
44156                     var splitAreaModel = angleAxisModel.getModel('splitArea');\r
44157                     var areaStyleModel = splitAreaModel.getModel('areaStyle');\r
44158                     var areaColors = areaStyleModel.get('color');\r
44159                     var lineCount = 0;\r
44160 \r
44161                     areaColors = areaColors instanceof Array ? areaColors : [areaColors];\r
44162 \r
44163                     var splitAreas = [];\r
44164 \r
44165                     var RADIAN = Math.PI / 180;\r
44166                     var prevAngle = -ticksAngles[0] * RADIAN;\r
44167                     var r0 = Math.min(radiusExtent[0], radiusExtent[1]);\r
44168                     var r1 = Math.max(radiusExtent[0], radiusExtent[1]);\r
44169 \r
44170                     var clockwise = angleAxisModel.get('clockwise');\r
44171 \r
44172                     for (var i = 1; i < ticksAngles.length; i++) {\r
44173                         var colorIndex = (lineCount++) % areaColors.length;\r
44174                         splitAreas[colorIndex] = splitAreas[colorIndex] || [];\r
44175                         splitAreas[colorIndex].push(new graphic.Sector({\r
44176                             shape: {\r
44177                                 cx: polar.cx,\r
44178                                 cy: polar.cy,\r
44179                                 r0: r0,\r
44180                                 r: r1,\r
44181                                 startAngle: prevAngle,\r
44182                                 endAngle: -ticksAngles[i] * RADIAN,\r
44183                                 clockwise: clockwise\r
44184                             },\r
44185                             silent: true\r
44186                         }));\r
44187                         prevAngle = -ticksAngles[i] * RADIAN;\r
44188                     }\r
44189 \r
44190                     // Simple optimization\r
44191                     // Batching the lines if color are the same\r
44192                     for (var i = 0; i < splitAreas.length; i++) {\r
44193                         this.group.add(graphic.mergePath(splitAreas[i], {\r
44194                             style: zrUtil.defaults({\r
44195                                 fill: areaColors[i % areaColors.length]\r
44196                             }, areaStyleModel.getAreaStyle()),\r
44197                             silent: true\r
44198                         }));\r
44199                     }\r
44200                 }\r
44201             });\r
44202 \r
44203 \r
44204 /***/ },\r
44205 /* 281 */\r
44206 /***/ function(module, exports, __webpack_require__) {\r
44207 \r
44208         \r
44209 \r
44210             __webpack_require__(273);\r
44211 \r
44212             __webpack_require__(282);\r
44213 \r
44214 \r
44215 /***/ },\r
44216 /* 282 */\r
44217 /***/ function(module, exports, __webpack_require__) {\r
44218 \r
44219         'use strict';\r
44220 \r
44221 \r
44222             var zrUtil = __webpack_require__(3);\r
44223             var graphic = __webpack_require__(42);\r
44224             var AxisBuilder = __webpack_require__(126);\r
44225 \r
44226             var axisBuilderAttrs = [\r
44227                 'axisLine', 'axisLabel', 'axisTick', 'axisName'\r
44228             ];\r
44229             var selfBuilderAttrs = [\r
44230                 'splitLine', 'splitArea'\r
44231             ];\r
44232 \r
44233             __webpack_require__(1).extendComponentView({\r
44234 \r
44235                 type: 'radiusAxis',\r
44236 \r
44237                 render: function (radiusAxisModel, ecModel) {\r
44238                     this.group.removeAll();\r
44239                     if (!radiusAxisModel.get('show')) {\r
44240                         return;\r
44241                     }\r
44242                     var polarModel = ecModel.getComponent('polar', radiusAxisModel.get('polarIndex'));\r
44243                     var angleAxis = polarModel.coordinateSystem.getAngleAxis();\r
44244                     var radiusAxis = radiusAxisModel.axis;\r
44245                     var polar = polarModel.coordinateSystem;\r
44246                     var ticksCoords = radiusAxis.getTicksCoords();\r
44247                     var axisAngle = angleAxis.getExtent()[0];\r
44248                     var radiusExtent = radiusAxis.getExtent();\r
44249 \r
44250                     var layout = layoutAxis(polar, radiusAxisModel, axisAngle);\r
44251                     var axisBuilder = new AxisBuilder(radiusAxisModel, layout);\r
44252                     zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);\r
44253                     this.group.add(axisBuilder.getGroup());\r
44254 \r
44255                     zrUtil.each(selfBuilderAttrs, function (name) {\r
44256                         if (radiusAxisModel.get(name +'.show')) {\r
44257                             this['_' + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords);\r
44258                         }\r
44259                     }, this);\r
44260                 },\r
44261 \r
44262                 /**\r
44263                  * @private\r
44264                  */\r
44265                 _splitLine: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {\r
44266                     var splitLineModel = radiusAxisModel.getModel('splitLine');\r
44267                     var lineStyleModel = splitLineModel.getModel('lineStyle');\r
44268                     var lineColors = lineStyleModel.get('color');\r
44269                     var lineCount = 0;\r
44270 \r
44271                     lineColors = lineColors instanceof Array ? lineColors : [lineColors];\r
44272 \r
44273                     var splitLines = [];\r
44274 \r
44275                     for (var i = 0; i < ticksCoords.length; i++) {\r
44276                         var colorIndex = (lineCount++) % lineColors.length;\r
44277                         splitLines[colorIndex] = splitLines[colorIndex] || [];\r
44278                         splitLines[colorIndex].push(new graphic.Circle({\r
44279                             shape: {\r
44280                                 cx: polar.cx,\r
44281                                 cy: polar.cy,\r
44282                                 r: ticksCoords[i]\r
44283                             },\r
44284                             silent: true\r
44285                         }));\r
44286                     }\r
44287 \r
44288                     // Simple optimization\r
44289                     // Batching the lines if color are the same\r
44290                     for (var i = 0; i < splitLines.length; i++) {\r
44291                         this.group.add(graphic.mergePath(splitLines[i], {\r
44292                             style: zrUtil.defaults({\r
44293                                 stroke: lineColors[i % lineColors.length],\r
44294                                 fill: null\r
44295                             }, lineStyleModel.getLineStyle()),\r
44296                             silent: true\r
44297                         }));\r
44298                     }\r
44299                 },\r
44300 \r
44301                 /**\r
44302                  * @private\r
44303                  */\r
44304                 _splitArea: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {\r
44305 \r
44306                     var splitAreaModel = radiusAxisModel.getModel('splitArea');\r
44307                     var areaStyleModel = splitAreaModel.getModel('areaStyle');\r
44308                     var areaColors = areaStyleModel.get('color');\r
44309                     var lineCount = 0;\r
44310 \r
44311                     areaColors = areaColors instanceof Array ? areaColors : [areaColors];\r
44312 \r
44313                     var splitAreas = [];\r
44314 \r
44315                     var prevRadius = ticksCoords[0];\r
44316                     for (var i = 1; i < ticksCoords.length; i++) {\r
44317                         var colorIndex = (lineCount++) % areaColors.length;\r
44318                         splitAreas[colorIndex] = splitAreas[colorIndex] || [];\r
44319                         splitAreas[colorIndex].push(new graphic.Sector({\r
44320                             shape: {\r
44321                                 cx: polar.cx,\r
44322                                 cy: polar.cy,\r
44323                                 r0: prevRadius,\r
44324                                 r: ticksCoords[i],\r
44325                                 startAngle: 0,\r
44326                                 endAngle: Math.PI * 2\r
44327                             },\r
44328                             silent: true\r
44329                         }));\r
44330                         prevRadius = ticksCoords[i];\r
44331                     }\r
44332 \r
44333                     // Simple optimization\r
44334                     // Batching the lines if color are the same\r
44335                     for (var i = 0; i < splitAreas.length; i++) {\r
44336                         this.group.add(graphic.mergePath(splitAreas[i], {\r
44337                             style: zrUtil.defaults({\r
44338                                 fill: areaColors[i % areaColors.length]\r
44339                             }, areaStyleModel.getAreaStyle()),\r
44340                             silent: true\r
44341                         }));\r
44342                     }\r
44343                 }\r
44344             });\r
44345 \r
44346             /**\r
44347              * @inner\r
44348              */\r
44349             function layoutAxis(polar, radiusAxisModel, axisAngle) {\r
44350                 return {\r
44351                     position: [polar.cx, polar.cy],\r
44352                     rotation: axisAngle / 180 * Math.PI,\r
44353                     labelDirection: -1,\r
44354                     tickDirection: -1,\r
44355                     nameDirection: 1,\r
44356                     labelRotation: radiusAxisModel.getModel('axisLabel').get('rotate'),\r
44357                     // Over splitLine and splitArea\r
44358                     z2: 1\r
44359                 };\r
44360             }\r
44361 \r
44362 \r
44363 /***/ },\r
44364 /* 283 */\r
44365 /***/ function(module, exports, __webpack_require__) {\r
44366 \r
44367         \r
44368 \r
44369             __webpack_require__(163);\r
44370 \r
44371             __webpack_require__(284);\r
44372 \r
44373             __webpack_require__(161);\r
44374 \r
44375 \r
44376 /***/ },\r
44377 /* 284 */\r
44378 /***/ function(module, exports, __webpack_require__) {\r
44379 \r
44380         'use strict';\r
44381 \r
44382 \r
44383             var MapDraw = __webpack_require__(158);\r
44384 \r
44385             module.exports = __webpack_require__(1).extendComponentView({\r
44386 \r
44387                 type: 'geo',\r
44388 \r
44389                 init: function (ecModel, api) {\r
44390                     var mapDraw = new MapDraw(api, true);\r
44391                     this._mapDraw = mapDraw;\r
44392 \r
44393                     this.group.add(mapDraw.group);\r
44394                 },\r
44395 \r
44396                 render: function (geoModel, ecModel, api) {\r
44397                     geoModel.get('show') &&\r
44398                         this._mapDraw.draw(geoModel, ecModel, api);\r
44399                 }\r
44400             });\r
44401 \r
44402 \r
44403 /***/ },\r
44404 /* 285 */\r
44405 /***/ function(module, exports, __webpack_require__) {\r
44406 \r
44407         'use strict';\r
44408 \r
44409 \r
44410             var echarts = __webpack_require__(1);\r
44411             var graphic = __webpack_require__(42);\r
44412             var layout = __webpack_require__(21);\r
44413 \r
44414             // Model\r
44415             echarts.extendComponentModel({\r
44416 \r
44417                 type: 'title',\r
44418 \r
44419                 layoutMode: {type: 'box', ignoreSize: true},\r
44420 \r
44421                 defaultOption: {\r
44422                     // 一级层叠\r
44423                     zlevel: 0,\r
44424                     // 二级层叠\r
44425                     z: 6,\r
44426                     show: true,\r
44427 \r
44428                     text: '',\r
44429                     // 超链接跳转\r
44430                     // link: null,\r
44431                     // 仅支持self | blank\r
44432                     target: 'blank',\r
44433                     subtext: '',\r
44434 \r
44435                     // 超链接跳转\r
44436                     // sublink: null,\r
44437                     // 仅支持self | blank\r
44438                     subtarget: 'blank',\r
44439 \r
44440                     // 'center' ¦ 'left' ¦ 'right'\r
44441                     // ¦ {number}(x坐标,单位px)\r
44442                     left: 0,\r
44443                     // 'top' ¦ 'bottom' ¦ 'center'\r
44444                     // ¦ {number}(y坐标,单位px)\r
44445                     top: 0,\r
44446 \r
44447                     // 水平对齐\r
44448                     // 'auto' | 'left' | 'right'\r
44449                     // 默认根据 x 的位置判断是左对齐还是右对齐\r
44450                     //textAlign: null\r
44451 \r
44452                     backgroundColor: 'rgba(0,0,0,0)',\r
44453 \r
44454                     // 标题边框颜色\r
44455                     borderColor: '#ccc',\r
44456 \r
44457                     // 标题边框线宽,单位px,默认为0(无边框)\r
44458                     borderWidth: 0,\r
44459 \r
44460                     // 标题内边距,单位px,默认各方向内边距为5,\r
44461                     // 接受数组分别设定上右下左边距,同css\r
44462                     padding: 5,\r
44463 \r
44464                     // 主副标题纵向间隔,单位px,默认为10,\r
44465                     itemGap: 10,\r
44466                     textStyle: {\r
44467                         fontSize: 18,\r
44468                         fontWeight: 'bolder',\r
44469                         // 主标题文字颜色\r
44470                         color: '#333'\r
44471                     },\r
44472                     subtextStyle: {\r
44473                         // 副标题文字颜色\r
44474                         color: '#aaa'\r
44475                     }\r
44476                 }\r
44477             });\r
44478 \r
44479             // View\r
44480             echarts.extendComponentView({\r
44481 \r
44482                 type: 'title',\r
44483 \r
44484                 render: function (titleModel, ecModel, api) {\r
44485                     this.group.removeAll();\r
44486 \r
44487                     if (!titleModel.get('show')) {\r
44488                         return;\r
44489                     }\r
44490 \r
44491                     var group = this.group;\r
44492 \r
44493                     var textStyleModel = titleModel.getModel('textStyle');\r
44494                     var subtextStyleModel = titleModel.getModel('subtextStyle');\r
44495 \r
44496                     var textAlign = titleModel.get('textAlign');\r
44497 \r
44498                     var textEl = new graphic.Text({\r
44499                         style: {\r
44500                             text: titleModel.get('text'),\r
44501                             textFont: textStyleModel.getFont(),\r
44502                             fill: textStyleModel.getTextColor(),\r
44503                             textBaseline: 'top'\r
44504                         },\r
44505                         z2: 10\r
44506                     });\r
44507 \r
44508                     var textRect = textEl.getBoundingRect();\r
44509 \r
44510                     var subText = titleModel.get('subtext');\r
44511                     var subTextEl = new graphic.Text({\r
44512                         style: {\r
44513                             text: subText,\r
44514                             textFont: subtextStyleModel.getFont(),\r
44515                             fill: subtextStyleModel.getTextColor(),\r
44516                             y: textRect.height + titleModel.get('itemGap'),\r
44517                             textBaseline: 'top'\r
44518                         },\r
44519                         z2: 10\r
44520                     });\r
44521 \r
44522                     var link = titleModel.get('link');\r
44523                     var sublink = titleModel.get('sublink');\r
44524 \r
44525                     textEl.silent = !link;\r
44526                     subTextEl.silent = !sublink;\r
44527 \r
44528                     if (link) {\r
44529                         textEl.on('click', function () {\r
44530                             window.open(link, titleModel.get('target'));\r
44531                         });\r
44532                     }\r
44533                     if (sublink) {\r
44534                         subTextEl.on('click', function () {\r
44535                             window.open(sublink, titleModel.get('subtarget'));\r
44536                         });\r
44537                     }\r
44538 \r
44539                     group.add(textEl);\r
44540                     subText && group.add(subTextEl);\r
44541                     // If no subText, but add subTextEl, there will be an empty line.\r
44542 \r
44543                     var groupRect = group.getBoundingRect();\r
44544                     var layoutOption = titleModel.getBoxLayoutParams();\r
44545                     layoutOption.width = groupRect.width;\r
44546                     layoutOption.height = groupRect.height;\r
44547                     var layoutRect = layout.getLayoutRect(\r
44548                         layoutOption, {\r
44549                             width: api.getWidth(),\r
44550                             height: api.getHeight()\r
44551                         }, titleModel.get('padding')\r
44552                     );\r
44553                     // Adjust text align based on position\r
44554                     if (!textAlign) {\r
44555                         // Align left if title is on the left. center and right is same\r
44556                         textAlign = titleModel.get('left') || titleModel.get('right');\r
44557                         if (textAlign === 'middle') {\r
44558                             textAlign = 'center';\r
44559                         }\r
44560                         // Adjust layout by text align\r
44561                         if (textAlign === 'right') {\r
44562                             layoutRect.x += layoutRect.width;\r
44563                         }\r
44564                         else if (textAlign === 'center') {\r
44565                             layoutRect.x += layoutRect.width / 2;\r
44566                         }\r
44567                     }\r
44568                     group.position = [layoutRect.x, layoutRect.y];\r
44569                     textEl.setStyle('textAlign', textAlign);\r
44570                     subTextEl.setStyle('textAlign', textAlign);\r
44571 \r
44572                     // Render background\r
44573                     // Get groupRect again because textAlign has been changed\r
44574                     groupRect = group.getBoundingRect();\r
44575                     var padding = layoutRect.margin;\r
44576                     var style = titleModel.getItemStyle(['color', 'opacity']);\r
44577                     style.fill = titleModel.get('backgroundColor');\r
44578                     var rect = new graphic.Rect({\r
44579                         shape: {\r
44580                             x: groupRect.x - padding[3],\r
44581                             y: groupRect.y - padding[0],\r
44582                             width: groupRect.width + padding[1] + padding[3],\r
44583                             height: groupRect.height + padding[0] + padding[2]\r
44584                         },\r
44585                         style: style,\r
44586                         silent: true\r
44587                     });\r
44588                     graphic.subPixelOptimizeRect(rect);\r
44589 \r
44590                     group.add(rect);\r
44591                 }\r
44592             });\r
44593 \r
44594 \r
44595 /***/ },\r
44596 /* 286 */\r
44597 /***/ function(module, exports, __webpack_require__) {\r
44598 \r
44599         /**\r
44600          * DataZoom component entry\r
44601          */\r
44602 \r
44603 \r
44604             __webpack_require__(287);\r
44605 \r
44606             __webpack_require__(288);\r
44607             __webpack_require__(290);\r
44608 \r
44609             __webpack_require__(291);\r
44610             __webpack_require__(292);\r
44611 \r
44612             __webpack_require__(295);\r
44613             __webpack_require__(296);\r
44614 \r
44615             __webpack_require__(298);\r
44616             __webpack_require__(299);\r
44617 \r
44618 \r
44619 \r
44620 /***/ },\r
44621 /* 287 */\r
44622 /***/ function(module, exports, __webpack_require__) {\r
44623 \r
44624         \r
44625 \r
44626             __webpack_require__(19).registerSubTypeDefaulter('dataZoom', function (option) {\r
44627                 // Default 'slider' when no type specified.\r
44628                 return 'slider';\r
44629             });\r
44630 \r
44631 \r
44632 \r
44633 /***/ },\r
44634 /* 288 */\r
44635 /***/ function(module, exports, __webpack_require__) {\r
44636 \r
44637         /**\r
44638          * @file Data zoom model\r
44639          */\r
44640 \r
44641 \r
44642             var zrUtil = __webpack_require__(3);\r
44643             var env = __webpack_require__(78);\r
44644             var echarts = __webpack_require__(1);\r
44645             var modelUtil = __webpack_require__(5);\r
44646             var AxisProxy = __webpack_require__(289);\r
44647             var each = zrUtil.each;\r
44648             var eachAxisDim = modelUtil.eachAxisDim;\r
44649 \r
44650             var DataZoomModel = echarts.extendComponentModel({\r
44651 \r
44652                 type: 'dataZoom',\r
44653 \r
44654                 dependencies: [\r
44655                     'xAxis', 'yAxis', 'zAxis', 'radiusAxis', 'angleAxis', 'series'\r
44656                 ],\r
44657 \r
44658                 /**\r
44659                  * @protected\r
44660                  */\r
44661                 defaultOption: {\r
44662                     zlevel: 0,\r
44663                     z: 4,                   // Higher than normal component (z: 2).\r
44664                     orient: null,           // Default auto by axisIndex. Possible value: 'horizontal', 'vertical'.\r
44665                     xAxisIndex: null,       // Default all horizontal category axis.\r
44666                     yAxisIndex: null,       // Default all vertical category axis.\r
44667                     angleAxisIndex: null,\r
44668                     radiusAxisIndex: null,\r
44669                     filterMode: 'filter',   // Possible values: 'filter' or 'empty'.\r
44670                                             // 'filter': data items which are out of window will be removed.\r
44671                                             //           This option is applicable when filtering outliers.\r
44672                                             // 'empty': data items which are out of window will be set to empty.\r
44673                                             //          This option is applicable when user should not neglect\r
44674                                             //          that there are some data items out of window.\r
44675                                             // Taking line chart as an example, line will be broken in\r
44676                                             // the filtered points when filterModel is set to 'empty', but\r
44677                                             // be connected when set to 'filter'.\r
44678 \r
44679                     throttle: 100,          // Dispatch action by the fixed rate, avoid frequency.\r
44680                                             // default 100. Do not throttle when use null/undefined.\r
44681                     start: 0,               // Start percent. 0 ~ 100\r
44682                     end: 100,               // End percent. 0 ~ 100\r
44683                     startValue: null,       // Start value. If startValue specified, start is ignored.\r
44684                     endValue: null          // End value. If endValue specified, end is ignored.\r
44685                 },\r
44686 \r
44687                 /**\r
44688                  * @override\r
44689                  */\r
44690                 init: function (option, parentModel, ecModel) {\r
44691 \r
44692                     /**\r
44693                      * key like x_0, y_1\r
44694                      * @private\r
44695                      * @type {Object}\r
44696                      */\r
44697                     this._dataIntervalByAxis = {};\r
44698 \r
44699                     /**\r
44700                      * @private\r
44701                      */\r
44702                     this._dataInfo = {};\r
44703 \r
44704                     /**\r
44705                      * key like x_0, y_1\r
44706                      * @private\r
44707                      */\r
44708                     this._axisProxies = {};\r
44709 \r
44710                     /**\r
44711                      * @readOnly\r
44712                      */\r
44713                     this.textStyleModel;\r
44714 \r
44715                     var rawOption = retrieveRaw(option);\r
44716 \r
44717                     this.mergeDefaultAndTheme(option, ecModel);\r
44718 \r
44719                     this.doInit(rawOption);\r
44720                 },\r
44721 \r
44722                 /**\r
44723                  * @override\r
44724                  */\r
44725                 mergeOption: function (newOption) {\r
44726                     var rawOption = retrieveRaw(newOption);\r
44727 \r
44728                     //FIX #2591\r
44729                     zrUtil.merge(this.option, newOption, true);\r
44730 \r
44731                     this.doInit(rawOption);\r
44732                 },\r
44733 \r
44734                 /**\r
44735                  * @protected\r
44736                  */\r
44737                 doInit: function (rawOption) {\r
44738                     var thisOption = this.option;\r
44739 \r
44740                     // Disable realtime view update if canvas is not supported.\r
44741                     if (!env.canvasSupported) {\r
44742                         thisOption.realtime = false;\r
44743                     }\r
44744 \r
44745                     processRangeProp('start', 'startValue', rawOption, thisOption);\r
44746                     processRangeProp('end', 'endValue', rawOption, thisOption);\r
44747 \r
44748                     this.textStyleModel = this.getModel('textStyle');\r
44749 \r
44750                     this._resetTarget();\r
44751 \r
44752                     this._giveAxisProxies();\r
44753                 },\r
44754 \r
44755                 /**\r
44756                  * @private\r
44757                  */\r
44758                 _giveAxisProxies: function () {\r
44759                     var axisProxies = this._axisProxies;\r
44760 \r
44761                     this.eachTargetAxis(function (dimNames, axisIndex, dataZoomModel, ecModel) {\r
44762                         var axisModel = this.dependentModels[dimNames.axis][axisIndex];\r
44763 \r
44764                         // If exists, share axisProxy with other dataZoomModels.\r
44765                         var axisProxy = axisModel.__dzAxisProxy || (\r
44766                             // Use the first dataZoomModel as the main model of axisProxy.\r
44767                             axisModel.__dzAxisProxy = new AxisProxy(\r
44768                                 dimNames.name, axisIndex, this, ecModel\r
44769                             )\r
44770                         );\r
44771                         // FIXME\r
44772                         // dispose __dzAxisProxy\r
44773 \r
44774                         axisProxies[dimNames.name + '_' + axisIndex] = axisProxy;\r
44775                     }, this);\r
44776                 },\r
44777 \r
44778                 /**\r
44779                  * @private\r
44780                  */\r
44781                 _resetTarget: function () {\r
44782                     var thisOption = this.option;\r
44783 \r
44784                     var autoMode = this._judgeAutoMode();\r
44785 \r
44786                     eachAxisDim(function (dimNames) {\r
44787                         var axisIndexName = dimNames.axisIndex;\r
44788                         thisOption[axisIndexName] = modelUtil.normalizeToArray(\r
44789                             thisOption[axisIndexName]\r
44790                         );\r
44791                     }, this);\r
44792 \r
44793                     if (autoMode === 'axisIndex') {\r
44794                         this._autoSetAxisIndex();\r
44795                     }\r
44796                     else if (autoMode === 'orient') {\r
44797                         this._autoSetOrient();\r
44798                     }\r
44799                 },\r
44800 \r
44801                 /**\r
44802                  * @private\r
44803                  */\r
44804                 _judgeAutoMode: function () {\r
44805                     // Auto set only works for setOption at the first time.\r
44806                     // The following is user's reponsibility. So using merged\r
44807                     // option is OK.\r
44808                     var thisOption = this.option;\r
44809 \r
44810                     var hasIndexSpecified = false;\r
44811                     eachAxisDim(function (dimNames) {\r
44812                         // When user set axisIndex as a empty array, we think that user specify axisIndex\r
44813                         // but do not want use auto mode. Because empty array may be encountered when\r
44814                         // some error occured.\r
44815                         if (thisOption[dimNames.axisIndex] != null) {\r
44816                             hasIndexSpecified = true;\r
44817                         }\r
44818                     }, this);\r
44819 \r
44820                     var orient = thisOption.orient;\r
44821 \r
44822                     if (orient == null && hasIndexSpecified) {\r
44823                         return 'orient';\r
44824                     }\r
44825                     else if (!hasIndexSpecified) {\r
44826                         if (orient == null) {\r
44827                             thisOption.orient = 'horizontal';\r
44828                         }\r
44829                         return 'axisIndex';\r
44830                     }\r
44831                 },\r
44832 \r
44833                 /**\r
44834                  * @private\r
44835                  */\r
44836                 _autoSetAxisIndex: function () {\r
44837                     var autoAxisIndex = true;\r
44838                     var orient = this.get('orient', true);\r
44839                     var thisOption = this.option;\r
44840 \r
44841                     if (autoAxisIndex) {\r
44842                         // Find axis that parallel to dataZoom as default.\r
44843                         var dimNames = orient === 'vertical'\r
44844                             ? {dim: 'y', axisIndex: 'yAxisIndex', axis: 'yAxis'}\r
44845                             : {dim: 'x', axisIndex: 'xAxisIndex', axis: 'xAxis'};\r
44846 \r
44847                         if (this.dependentModels[dimNames.axis].length) {\r
44848                             thisOption[dimNames.axisIndex] = [0];\r
44849                             autoAxisIndex = false;\r
44850                         }\r
44851                     }\r
44852 \r
44853                     if (autoAxisIndex) {\r
44854                         // Find the first category axis as default. (consider polar)\r
44855                         eachAxisDim(function (dimNames) {\r
44856                             if (!autoAxisIndex) {\r
44857                                 return;\r
44858                             }\r
44859                             var axisIndices = [];\r
44860                             var axisModels = this.dependentModels[dimNames.axis];\r
44861                             if (axisModels.length && !axisIndices.length) {\r
44862                                 for (var i = 0, len = axisModels.length; i < len; i++) {\r
44863                                     if (axisModels[i].get('type') === 'category') {\r
44864                                         axisIndices.push(i);\r
44865                                     }\r
44866                                 }\r
44867                             }\r
44868                             thisOption[dimNames.axisIndex] = axisIndices;\r
44869                             if (axisIndices.length) {\r
44870                                 autoAxisIndex = false;\r
44871                             }\r
44872                         }, this);\r
44873                     }\r
44874 \r
44875                     if (autoAxisIndex) {\r
44876                         // FIXME\r
44877                         // 这里是兼容ec2的写法(没指定xAxisIndex和yAxisIndex时把scatter和双数值轴折柱纳入dataZoom控制),\r
44878                         // 但是实际是否需要Grid.js#getScaleByOption来判断(考虑time,log等axis type)?\r
44879 \r
44880                         // If both dataZoom.xAxisIndex and dataZoom.yAxisIndex is not specified,\r
44881                         // dataZoom component auto adopts series that reference to\r
44882                         // both xAxis and yAxis which type is 'value'.\r
44883                         this.ecModel.eachSeries(function (seriesModel) {\r
44884                             if (this._isSeriesHasAllAxesTypeOf(seriesModel, 'value')) {\r
44885                                 eachAxisDim(function (dimNames) {\r
44886                                     var axisIndices = thisOption[dimNames.axisIndex];\r
44887                                     var axisIndex = seriesModel.get(dimNames.axisIndex);\r
44888                                     if (zrUtil.indexOf(axisIndices, axisIndex) < 0) {\r
44889                                         axisIndices.push(axisIndex);\r
44890                                     }\r
44891                                 });\r
44892                             }\r
44893                         }, this);\r
44894                     }\r
44895                 },\r
44896 \r
44897                 /**\r
44898                  * @private\r
44899                  */\r
44900                 _autoSetOrient: function () {\r
44901                     var dim;\r
44902 \r
44903                     // Find the first axis\r
44904                     this.eachTargetAxis(function (dimNames) {\r
44905                         !dim && (dim = dimNames.name);\r
44906                     }, this);\r
44907 \r
44908                     this.option.orient = dim === 'y' ? 'vertical' : 'horizontal';\r
44909                 },\r
44910 \r
44911                 /**\r
44912                  * @private\r
44913                  */\r
44914                 _isSeriesHasAllAxesTypeOf: function (seriesModel, axisType) {\r
44915                     // FIXME\r
44916                     // 需要series的xAxisIndex和yAxisIndex都首先自动设置上。\r
44917                     // 例如series.type === scatter时。\r
44918 \r
44919                     var is = true;\r
44920                     eachAxisDim(function (dimNames) {\r
44921                         var seriesAxisIndex = seriesModel.get(dimNames.axisIndex);\r
44922                         var axisModel = this.dependentModels[dimNames.axis][seriesAxisIndex];\r
44923 \r
44924                         if (!axisModel || axisModel.get('type') !== axisType) {\r
44925                             is = false;\r
44926                         }\r
44927                     }, this);\r
44928                     return is;\r
44929                 },\r
44930 \r
44931                 /**\r
44932                  * @public\r
44933                  */\r
44934                 getFirstTargetAxisModel: function () {\r
44935                     var firstAxisModel;\r
44936                     eachAxisDim(function (dimNames) {\r
44937                         if (firstAxisModel == null) {\r
44938                             var indices = this.get(dimNames.axisIndex);\r
44939                             if (indices.length) {\r
44940                                 firstAxisModel = this.dependentModels[dimNames.axis][indices[0]];\r
44941                             }\r
44942                         }\r
44943                     }, this);\r
44944 \r
44945                     return firstAxisModel;\r
44946                 },\r
44947 \r
44948                 /**\r
44949                  * @public\r
44950                  * @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel\r
44951                  */\r
44952                 eachTargetAxis: function (callback, context) {\r
44953                     var ecModel = this.ecModel;\r
44954                     eachAxisDim(function (dimNames) {\r
44955                         each(\r
44956                             this.get(dimNames.axisIndex),\r
44957                             function (axisIndex) {\r
44958                                 callback.call(context, dimNames, axisIndex, this, ecModel);\r
44959                             },\r
44960                             this\r
44961                         );\r
44962                     }, this);\r
44963                 },\r
44964 \r
44965                 getAxisProxy: function (dimName, axisIndex) {\r
44966                     return this._axisProxies[dimName + '_' + axisIndex];\r
44967                 },\r
44968 \r
44969                 /**\r
44970                  * If not specified, set to undefined.\r
44971                  *\r
44972                  * @public\r
44973                  * @param {Object} opt\r
44974                  * @param {number} [opt.start]\r
44975                  * @param {number} [opt.end]\r
44976                  * @param {number} [opt.startValue]\r
44977                  * @param {number} [opt.endValue]\r
44978                  */\r
44979                 setRawRange: function (opt) {\r
44980                     each(['start', 'end', 'startValue', 'endValue'], function (name) {\r
44981                         // If any of those prop is null/undefined, we should alos set\r
44982                         // them, because only one pair between start/end and\r
44983                         // startValue/endValue can work.\r
44984                         this.option[name] = opt[name];\r
44985                     }, this);\r
44986                 },\r
44987 \r
44988                 /**\r
44989                  * @public\r
44990                  * @return {Array.<number>} [startPercent, endPercent]\r
44991                  */\r
44992                 getPercentRange: function () {\r
44993                     var axisProxy = this.findRepresentativeAxisProxy();\r
44994                     if (axisProxy) {\r
44995                         return axisProxy.getDataPercentWindow();\r
44996                     }\r
44997                 },\r
44998 \r
44999                 /**\r
45000                  * @public\r
45001                  * For example, chart.getModel().getComponent('dataZoom').getValueRange('y', 0);\r
45002                  *\r
45003                  * @param {string} [axisDimName]\r
45004                  * @param {number} [axisIndex]\r
45005                  * @return {Array.<number>} [startValue, endValue]\r
45006                  */\r
45007                 getValueRange: function (axisDimName, axisIndex) {\r
45008                     if (axisDimName == null && axisIndex == null) {\r
45009                         var axisProxy = this.findRepresentativeAxisProxy();\r
45010                         if (axisProxy) {\r
45011                             return axisProxy.getDataValueWindow();\r
45012                         }\r
45013                     }\r
45014                     else {\r
45015                         return this.getAxisProxy(axisDimName, axisIndex).getDataValueWindow();\r
45016                     }\r
45017                 },\r
45018 \r
45019                 /**\r
45020                  * @public\r
45021                  * @return {module:echarts/component/dataZoom/AxisProxy}\r
45022                  */\r
45023                 findRepresentativeAxisProxy: function () {\r
45024                     // Find the first hosted axisProxy\r
45025                     var axisProxies = this._axisProxies;\r
45026                     for (var key in axisProxies) {\r
45027                         if (axisProxies.hasOwnProperty(key) && axisProxies[key].hostedBy(this)) {\r
45028                             return axisProxies[key];\r
45029                         }\r
45030                     }\r
45031 \r
45032                     // If no hosted axis find not hosted axisProxy.\r
45033                     // Consider this case: dataZoomModel1 and dataZoomModel2 control the same axis,\r
45034                     // and the option.start or option.end settings are different. The percentRange\r
45035                     // should follow axisProxy.\r
45036                     // (We encounter this problem in toolbox data zoom.)\r
45037                     for (var key in axisProxies) {\r
45038                         if (axisProxies.hasOwnProperty(key) && !axisProxies[key].hostedBy(this)) {\r
45039                             return axisProxies[key];\r
45040                         }\r
45041                     }\r
45042                 }\r
45043 \r
45044             });\r
45045 \r
45046             function retrieveRaw(option) {\r
45047                 var ret = {};\r
45048                 each(\r
45049                     ['start', 'end', 'startValue', 'endValue'],\r
45050                     function (name) {\r
45051                         ret[name] = option[name];\r
45052                     }\r
45053                 );\r
45054                 return ret;\r
45055             }\r
45056 \r
45057             function processRangeProp(percentProp, valueProp, rawOption, thisOption) {\r
45058                 // start/end has higher priority over startValue/endValue,\r
45059                 // but we should make chart.setOption({endValue: 1000}) effective,\r
45060                 // rather than chart.setOption({endValue: 1000, end: null}).\r
45061                 if (rawOption[valueProp] != null && rawOption[percentProp] == null) {\r
45062                     thisOption[percentProp] = null;\r
45063                 }\r
45064                 // Otherwise do nothing and use the merge result.\r
45065             }\r
45066 \r
45067             module.exports = DataZoomModel;\r
45068 \r
45069 \r
45070 \r
45071 /***/ },\r
45072 /* 289 */\r
45073 /***/ function(module, exports, __webpack_require__) {\r
45074 \r
45075         /**\r
45076          * @file Axis operator\r
45077          */\r
45078 \r
45079 \r
45080             var zrUtil = __webpack_require__(3);\r
45081             var numberUtil = __webpack_require__(7);\r
45082             var each = zrUtil.each;\r
45083             var asc = numberUtil.asc;\r
45084 \r
45085             /**\r
45086              * Operate single axis.\r
45087              * One axis can only operated by one axis operator.\r
45088              * Different dataZoomModels may be defined to operate the same axis.\r
45089              * (i.e. 'inside' data zoom and 'slider' data zoom components)\r
45090              * So dataZoomModels share one axisProxy in that case.\r
45091              *\r
45092              * @class\r
45093              */\r
45094             var AxisProxy = function (dimName, axisIndex, dataZoomModel, ecModel) {\r
45095 \r
45096                 /**\r
45097                  * @private\r
45098                  * @type {string}\r
45099                  */\r
45100                 this._dimName = dimName;\r
45101 \r
45102                 /**\r
45103                  * @private\r
45104                  */\r
45105                 this._axisIndex = axisIndex;\r
45106 \r
45107                 /**\r
45108                  * @private\r
45109                  * @type {Array.<number>}\r
45110                  */\r
45111                 this._valueWindow;\r
45112 \r
45113                 /**\r
45114                  * @private\r
45115                  * @type {Array.<number>}\r
45116                  */\r
45117                 this._percentWindow;\r
45118 \r
45119                 /**\r
45120                  * @private\r
45121                  * @type {Array.<number>}\r
45122                  */\r
45123                 this._dataExtent;\r
45124 \r
45125                 /**\r
45126                  * @readOnly\r
45127                  * @type {module: echarts/model/Global}\r
45128                  */\r
45129                 this.ecModel = ecModel;\r
45130 \r
45131                 /**\r
45132                  * @private\r
45133                  * @type {module: echarts/component/dataZoom/DataZoomModel}\r
45134                  */\r
45135                 this._dataZoomModel = dataZoomModel;\r
45136             };\r
45137 \r
45138             AxisProxy.prototype = {\r
45139 \r
45140                 constructor: AxisProxy,\r
45141 \r
45142                 /**\r
45143                  * Whether the axisProxy is hosted by dataZoomModel.\r
45144                  *\r
45145                  * @public\r
45146                  * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel\r
45147                  * @return {boolean}\r
45148                  */\r
45149                 hostedBy: function (dataZoomModel) {\r
45150                     return this._dataZoomModel === dataZoomModel;\r
45151                 },\r
45152 \r
45153                 /**\r
45154                  * @return {Array.<number>}\r
45155                  */\r
45156                 getDataExtent: function () {\r
45157                     return this._dataExtent.slice();\r
45158                 },\r
45159 \r
45160                 /**\r
45161                  * @return {Array.<number>}\r
45162                  */\r
45163                 getDataValueWindow: function () {\r
45164                     return this._valueWindow.slice();\r
45165                 },\r
45166 \r
45167                 /**\r
45168                  * @return {Array.<number>}\r
45169                  */\r
45170                 getDataPercentWindow: function () {\r
45171                     return this._percentWindow.slice();\r
45172                 },\r
45173 \r
45174                 /**\r
45175                  * @public\r
45176                  * @param {number} axisIndex\r
45177                  * @return {Array} seriesModels\r
45178                  */\r
45179                 getTargetSeriesModels: function () {\r
45180                     var seriesModels = [];\r
45181 \r
45182                     this.ecModel.eachSeries(function (seriesModel) {\r
45183                         if (this._axisIndex === seriesModel.get(this._dimName + 'AxisIndex')) {\r
45184                             seriesModels.push(seriesModel);\r
45185                         }\r
45186                     }, this);\r
45187 \r
45188                     return seriesModels;\r
45189                 },\r
45190 \r
45191                 getAxisModel: function () {\r
45192                     return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex);\r
45193                 },\r
45194 \r
45195                 getOtherAxisModel: function () {\r
45196                     var axisDim = this._dimName;\r
45197                     var ecModel = this.ecModel;\r
45198                     var axisModel = this.getAxisModel();\r
45199                     var isCartesian = axisDim === 'x' || axisDim === 'y';\r
45200                     var otherAxisDim;\r
45201                     var coordSysIndexName;\r
45202                     if (isCartesian) {\r
45203                         coordSysIndexName = 'gridIndex';\r
45204                         otherAxisDim = axisDim === 'x' ? 'y' : 'x';\r
45205                     }\r
45206                     else {\r
45207                         coordSysIndexName = 'polarIndex';\r
45208                         otherAxisDim = axisDim === 'angle' ? 'radius' : 'angle';\r
45209                     }\r
45210                     var foundOtherAxisModel;\r
45211                     ecModel.eachComponent(otherAxisDim + 'Axis', function (otherAxisModel) {\r
45212                         if ((otherAxisModel.get(coordSysIndexName) || 0)\r
45213                             === (axisModel.get(coordSysIndexName) || 0)) {\r
45214                             foundOtherAxisModel = otherAxisModel;\r
45215                         }\r
45216                     });\r
45217                     return foundOtherAxisModel;\r
45218                 },\r
45219 \r
45220                 /**\r
45221                  * Notice: reset should not be called before series.restoreData() called,\r
45222                  * so it is recommanded to be called in "process stage" but not "model init\r
45223                  * stage".\r
45224                  *\r
45225                  * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel\r
45226                  */\r
45227                 reset: function (dataZoomModel) {\r
45228                     if (dataZoomModel !== this._dataZoomModel) {\r
45229                         return;\r
45230                     }\r
45231 \r
45232                     // Culculate data window and data extent, and record them.\r
45233                     var dataExtent = this._dataExtent = calculateDataExtent(\r
45234                         this._dimName, this.getTargetSeriesModels()\r
45235                     );\r
45236                     var dataWindow = calculateDataWindow(\r
45237                         dataZoomModel.option, dataExtent, this\r
45238                     );\r
45239                     this._valueWindow = dataWindow.valueWindow;\r
45240                     this._percentWindow = dataWindow.percentWindow;\r
45241 \r
45242                     // Update axis setting then.\r
45243                     setAxisModel(this);\r
45244                 },\r
45245 \r
45246                 /**\r
45247                  * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel\r
45248                  */\r
45249                 restore: function (dataZoomModel) {\r
45250                     if (dataZoomModel !== this._dataZoomModel) {\r
45251                         return;\r
45252                     }\r
45253 \r
45254                     this._valueWindow = this._percentWindow = null;\r
45255                     setAxisModel(this, true);\r
45256                 },\r
45257 \r
45258                 /**\r
45259                  * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel\r
45260                  */\r
45261                 filterData: function (dataZoomModel) {\r
45262                     if (dataZoomModel !== this._dataZoomModel) {\r
45263                         return;\r
45264                     }\r
45265 \r
45266                     var axisDim = this._dimName;\r
45267                     var seriesModels = this.getTargetSeriesModels();\r
45268                     var filterMode = dataZoomModel.get('filterMode');\r
45269                     var valueWindow = this._valueWindow;\r
45270 \r
45271                     // FIXME\r
45272                     // Toolbox may has dataZoom injected. And if there are stacked bar chart\r
45273                     // with NaN data. NaN will be filtered and stack will be wrong.\r
45274                     // So we need to force the mode to be set empty\r
45275                     var otherAxisModel = this.getOtherAxisModel();\r
45276                     if (dataZoomModel.get('$fromToolbox')\r
45277                         && otherAxisModel && otherAxisModel.get('type') === 'category') {\r
45278                         filterMode = 'empty';\r
45279                     }\r
45280                     // Process series data\r
45281                     each(seriesModels, function (seriesModel) {\r
45282                         var seriesData = seriesModel.getData();\r
45283                         if (!seriesData) {\r
45284                             return;\r
45285                         }\r
45286 \r
45287                         each(seriesModel.coordDimToDataDim(axisDim), function (dim) {\r
45288                             if (filterMode === 'empty') {\r
45289                                 seriesModel.setData(\r
45290                                     seriesData.map(dim, function (value) {\r
45291                                         return !isInWindow(value) ? NaN : value;\r
45292                                     })\r
45293                                 );\r
45294                             }\r
45295                             else {\r
45296                                 seriesData.filterSelf(dim, isInWindow);\r
45297                             }\r
45298                         });\r
45299                     });\r
45300 \r
45301                     function isInWindow(value) {\r
45302                         return value >= valueWindow[0] && value <= valueWindow[1];\r
45303                     }\r
45304                 }\r
45305             };\r
45306 \r
45307             function calculateDataExtent(axisDim, seriesModels) {\r
45308                 var dataExtent = [Infinity, -Infinity];\r
45309 \r
45310                 each(seriesModels, function (seriesModel) {\r
45311                     var seriesData = seriesModel.getData();\r
45312                     if (seriesData) {\r
45313                         each(seriesModel.coordDimToDataDim(axisDim), function (dim) {\r
45314                             var seriesExtent = seriesData.getDataExtent(dim);\r
45315                             seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]);\r
45316                             seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[1]);\r
45317                         });\r
45318                     }\r
45319                 }, this);\r
45320 \r
45321                 return dataExtent;\r
45322             }\r
45323 \r
45324             function calculateDataWindow(opt, dataExtent, axisProxy) {\r
45325                 var axisModel = axisProxy.getAxisModel();\r
45326                 var scale = axisModel.axis.scale;\r
45327                 var percentExtent = [0, 100];\r
45328                 var percentWindow = [\r
45329                     opt.start,\r
45330                     opt.end\r
45331                 ];\r
45332                 var valueWindow = [];\r
45333 \r
45334                 // In percent range is used and axis min/max/scale is set,\r
45335                 // window should be based on min/max/0, but should not be\r
45336                 // based on the extent of filtered data.\r
45337                 dataExtent = dataExtent.slice();\r
45338                 fixExtendByAxis(dataExtent, axisModel, scale);\r
45339 \r
45340                 each(['startValue', 'endValue'], function (prop) {\r
45341                     valueWindow.push(\r
45342                         opt[prop] != null\r
45343                             ? scale.parse(opt[prop])\r
45344                             : null\r
45345                     );\r
45346                 });\r
45347 \r
45348                 // Normalize bound.\r
45349                 each([0, 1], function (idx) {\r
45350                     var boundValue = valueWindow[idx];\r
45351                     var boundPercent = percentWindow[idx];\r
45352 \r
45353                     // start/end has higher priority over startValue/endValue,\r
45354                     // because start/end can be consistent among different type\r
45355                     // of axis but startValue/endValue not.\r
45356 \r
45357                     if (boundPercent != null || boundValue == null) {\r
45358                         if (boundPercent == null) {\r
45359                             boundPercent = percentExtent[idx];\r
45360                         }\r
45361                         // Use scale.parse to math round for category or time axis.\r
45362                         boundValue = scale.parse(numberUtil.linearMap(\r
45363                             boundPercent, percentExtent, dataExtent, true\r
45364                         ));\r
45365                     }\r
45366                     else { // boundPercent == null && boundValue != null\r
45367                         boundPercent = numberUtil.linearMap(\r
45368                             boundValue, dataExtent, percentExtent, true\r
45369                         );\r
45370                     }\r
45371                     // Avoid rounding error\r
45372                     valueWindow[idx] = numberUtil.round(boundValue);\r
45373                     percentWindow[idx] = numberUtil.round(boundPercent);\r
45374                 });\r
45375 \r
45376                 return {\r
45377                     valueWindow: asc(valueWindow),\r
45378                     percentWindow: asc(percentWindow)\r
45379                 };\r
45380             }\r
45381 \r
45382             function fixExtendByAxis(dataExtent, axisModel, scale) {\r
45383                 each(['min', 'max'], function (minMax, index) {\r
45384                     var axisMax = axisModel.get(minMax, true);\r
45385                     // Consider 'dataMin', 'dataMax'\r
45386                     if (axisMax != null && (axisMax + '').toLowerCase() !== 'data' + minMax) {\r
45387                         dataExtent[index] = scale.parse(axisMax);\r
45388                     }\r
45389                 });\r
45390 \r
45391                 if (!axisModel.get('scale', true)) {\r
45392                     dataExtent[0] > 0 && (dataExtent[0] = 0);\r
45393                     dataExtent[1] < 0 && (dataExtent[1] = 0);\r
45394                 }\r
45395 \r
45396                 return dataExtent;\r
45397             }\r
45398 \r
45399             function setAxisModel(axisProxy, isRestore) {\r
45400                 var axisModel = axisProxy.getAxisModel();\r
45401 \r
45402                 var percentWindow = axisProxy._percentWindow;\r
45403                 var valueWindow = axisProxy._valueWindow;\r
45404 \r
45405                 if (!percentWindow) {\r
45406                     return;\r
45407                 }\r
45408 \r
45409                 var isFull = isRestore || (percentWindow[0] === 0 && percentWindow[1] === 100);\r
45410                 // [0, 500]: arbitrary value, guess axis extent.\r
45411                 var precision = !isRestore && numberUtil.getPixelPrecision(valueWindow, [0, 500]);\r
45412                 // toFixed() digits argument must be between 0 and 20\r
45413                 var invalidPrecision = !isRestore && !(precision < 20 && precision >= 0);\r
45414 \r
45415                 var useOrigin = isRestore || isFull || invalidPrecision;\r
45416 \r
45417                 axisModel.setRange && axisModel.setRange(\r
45418                     useOrigin ? null : +valueWindow[0].toFixed(precision),\r
45419                     useOrigin ? null : +valueWindow[1].toFixed(precision)\r
45420                 );\r
45421             }\r
45422 \r
45423             module.exports = AxisProxy;\r
45424 \r
45425 \r
45426 \r
45427 /***/ },\r
45428 /* 290 */\r
45429 /***/ function(module, exports, __webpack_require__) {\r
45430 \r
45431         \r
45432 \r
45433             var ComponentView = __webpack_require__(28);\r
45434 \r
45435             module.exports = ComponentView.extend({\r
45436 \r
45437                 type: 'dataZoom',\r
45438 \r
45439                 render: function (dataZoomModel, ecModel, api, payload) {\r
45440                     this.dataZoomModel = dataZoomModel;\r
45441                     this.ecModel = ecModel;\r
45442                     this.api = api;\r
45443                 },\r
45444 \r
45445                 /**\r
45446                  * Find the first target coordinate system.\r
45447                  *\r
45448                  * @protected\r
45449                  * @return {Object} {\r
45450                  *                   cartesians: [\r
45451                  *                       {model: coord0, axisModels: [axis1, axis3], coordIndex: 1},\r
45452                  *                       {model: coord1, axisModels: [axis0, axis2], coordIndex: 0},\r
45453                  *                       ...\r
45454                  *                   ],  // cartesians must not be null/undefined.\r
45455                  *                   polars: [\r
45456                  *                       {model: coord0, axisModels: [axis4], coordIndex: 0},\r
45457                  *                       ...\r
45458                  *                   ],  // polars must not be null/undefined.\r
45459                  *                   axisModels: [axis0, axis1, axis2, axis3, axis4]\r
45460                  *                       // axisModels must not be null/undefined.\r
45461                  *                  }\r
45462                  */\r
45463                 getTargetInfo: function () {\r
45464                     var dataZoomModel = this.dataZoomModel;\r
45465                     var ecModel = this.ecModel;\r
45466                     var cartesians = [];\r
45467                     var polars = [];\r
45468                     var axisModels = [];\r
45469 \r
45470                     dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {\r
45471                         var axisModel = ecModel.getComponent(dimNames.axis, axisIndex);\r
45472                         if (axisModel) {\r
45473                             axisModels.push(axisModel);\r
45474 \r
45475                             var gridIndex = axisModel.get('gridIndex');\r
45476                             var polarIndex = axisModel.get('polarIndex');\r
45477 \r
45478                             if (gridIndex != null) {\r
45479                                 var coordModel = ecModel.getComponent('grid', gridIndex);\r
45480                                 save(coordModel, axisModel, cartesians, gridIndex);\r
45481                             }\r
45482                             else if (polarIndex != null) {\r
45483                                 var coordModel = ecModel.getComponent('polar', polarIndex);\r
45484                                 save(coordModel, axisModel, polars, polarIndex);\r
45485                             }\r
45486                         }\r
45487                     }, this);\r
45488 \r
45489                     function save(coordModel, axisModel, store, coordIndex) {\r
45490                         var item;\r
45491                         for (var i = 0; i < store.length; i++) {\r
45492                             if (store[i].model === coordModel) {\r
45493                                 item = store[i];\r
45494                                 break;\r
45495                             }\r
45496                         }\r
45497                         if (!item) {\r
45498                             store.push(item = {\r
45499                                 model: coordModel, axisModels: [], coordIndex: coordIndex\r
45500                             });\r
45501                         }\r
45502                         item.axisModels.push(axisModel);\r
45503                     }\r
45504 \r
45505                     return {\r
45506                         cartesians: cartesians,\r
45507                         polars: polars,\r
45508                         axisModels: axisModels\r
45509                     };\r
45510                 }\r
45511 \r
45512             });\r
45513 \r
45514 \r
45515 \r
45516 /***/ },\r
45517 /* 291 */\r
45518 /***/ function(module, exports, __webpack_require__) {\r
45519 \r
45520         /**\r
45521          * @file Data zoom model\r
45522          */\r
45523 \r
45524 \r
45525             var DataZoomModel = __webpack_require__(288);\r
45526             var layout = __webpack_require__(21);\r
45527             var zrUtil = __webpack_require__(3);\r
45528 \r
45529             var SliderZoomModel = DataZoomModel.extend({\r
45530 \r
45531                 type: 'dataZoom.slider',\r
45532 \r
45533                 layoutMode: 'box',\r
45534 \r
45535                 /**\r
45536                  * @protected\r
45537                  */\r
45538                 defaultOption: {\r
45539                     show: true,\r
45540 \r
45541                     // ph => placeholder. Using placehoder here because\r
45542                     // deault value can only be drived in view stage.\r
45543                     right: 'ph',  // Default align to grid rect.\r
45544                     top: 'ph',    // Default align to grid rect.\r
45545                     width: 'ph',  // Default align to grid rect.\r
45546                     height: 'ph', // Default align to grid rect.\r
45547                     left: null,   // Default align to grid rect.\r
45548                     bottom: null, // Default align to grid rect.\r
45549 \r
45550                     backgroundColor: 'rgba(47,69,84,0)',    // Background of slider zoom component.\r
45551                     dataBackgroundColor: '#ddd',            // Background of data shadow.\r
45552                     fillerColor: 'rgba(47,69,84,0.15)',     // Color of selected area.\r
45553                     handleColor: 'rgba(148,164,165,0.95)',     // Color of handle.\r
45554                     handleSize: 10,\r
45555 \r
45556                     labelPrecision: null,\r
45557                     labelFormatter: null,\r
45558                     showDetail: true,\r
45559                     showDataShadow: 'auto',                 // Default auto decision.\r
45560                     realtime: true,\r
45561                     zoomLock: false,                        // Whether disable zoom.\r
45562                     textStyle: {\r
45563                         color: '#333'\r
45564                     }\r
45565                 },\r
45566 \r
45567                 /**\r
45568                  * @override\r
45569                  */\r
45570                 mergeOption: function (option) {\r
45571                     SliderZoomModel.superApply(this, 'mergeOption', arguments);\r
45572                 }\r
45573 \r
45574             });\r
45575 \r
45576             module.exports = SliderZoomModel;\r
45577 \r
45578 \r
45579 \r
45580 /***/ },\r
45581 /* 292 */\r
45582 /***/ function(module, exports, __webpack_require__) {\r
45583 \r
45584         \r
45585 \r
45586             var zrUtil = __webpack_require__(3);\r
45587             var graphic = __webpack_require__(42);\r
45588             var throttle = __webpack_require__(293);\r
45589             var DataZoomView = __webpack_require__(290);\r
45590             var Rect = graphic.Rect;\r
45591             var numberUtil = __webpack_require__(7);\r
45592             var linearMap = numberUtil.linearMap;\r
45593             var layout = __webpack_require__(21);\r
45594             var sliderMove = __webpack_require__(294);\r
45595             var asc = numberUtil.asc;\r
45596             var bind = zrUtil.bind;\r
45597             var mathRound = Math.round;\r
45598             var mathMax = Math.max;\r
45599             var each = zrUtil.each;\r
45600 \r
45601             // Constants\r
45602             var DEFAULT_LOCATION_EDGE_GAP = 7;\r
45603             var DEFAULT_FRAME_BORDER_WIDTH = 1;\r
45604             var DEFAULT_FILLER_SIZE = 30;\r
45605             var HORIZONTAL = 'horizontal';\r
45606             var VERTICAL = 'vertical';\r
45607             var LABEL_GAP = 5;\r
45608             var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter'];\r
45609 \r
45610             var SliderZoomView = DataZoomView.extend({\r
45611 \r
45612                 type: 'dataZoom.slider',\r
45613 \r
45614                 init: function (ecModel, api) {\r
45615 \r
45616                     /**\r
45617                      * @private\r
45618                      * @type {Object}\r
45619                      */\r
45620                     this._displayables = {};\r
45621 \r
45622                     /**\r
45623                      * @private\r
45624                      * @type {string}\r
45625                      */\r
45626                     this._orient;\r
45627 \r
45628                     /**\r
45629                      * [0, 100]\r
45630                      * @private\r
45631                      */\r
45632                     this._range;\r
45633 \r
45634                     /**\r
45635                      * [coord of the first handle, coord of the second handle]\r
45636                      * @private\r
45637                      */\r
45638                     this._handleEnds;\r
45639 \r
45640                     /**\r
45641                      * [length, thick]\r
45642                      * @private\r
45643                      * @type {Array.<number>}\r
45644                      */\r
45645                     this._size;\r
45646 \r
45647                     /**\r
45648                      * @private\r
45649                      * @type {number}\r
45650                      */\r
45651                     this._halfHandleSize;\r
45652 \r
45653                     /**\r
45654                      * @private\r
45655                      */\r
45656                     this._location;\r
45657 \r
45658                     /**\r
45659                      * @private\r
45660                      */\r
45661                     this._dragging;\r
45662 \r
45663                     /**\r
45664                      * @private\r
45665                      */\r
45666                     this._dataShadowInfo;\r
45667 \r
45668                     this.api = api;\r
45669                 },\r
45670 \r
45671                 /**\r
45672                  * @override\r
45673                  */\r
45674                 render: function (dataZoomModel, ecModel, api, payload) {\r
45675                     SliderZoomView.superApply(this, 'render', arguments);\r
45676 \r
45677                     throttle.createOrUpdate(\r
45678                         this,\r
45679                         '_dispatchZoomAction',\r
45680                         this.dataZoomModel.get('throttle'),\r
45681                         'fixRate'\r
45682                     );\r
45683 \r
45684                     this._orient = dataZoomModel.get('orient');\r
45685                     this._halfHandleSize = mathRound(dataZoomModel.get('handleSize') / 2);\r
45686 \r
45687                     if (this.dataZoomModel.get('show') === false) {\r
45688                         this.group.removeAll();\r
45689                         return;\r
45690                     }\r
45691 \r
45692                     // Notice: this._resetInterval() should not be executed when payload.type\r
45693                     // is 'dataZoom', origin this._range should be maintained, otherwise 'pan'\r
45694                     // or 'zoom' info will be missed because of 'throttle' of this.dispatchAction,\r
45695                     if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) {\r
45696                         this._buildView();\r
45697                     }\r
45698 \r
45699                     this._updateView();\r
45700                 },\r
45701 \r
45702                 /**\r
45703                  * @override\r
45704                  */\r
45705                 remove: function () {\r
45706                     SliderZoomView.superApply(this, 'remove', arguments);\r
45707                     throttle.clear(this, '_dispatchZoomAction');\r
45708                 },\r
45709 \r
45710                 /**\r
45711                  * @override\r
45712                  */\r
45713                 dispose: function () {\r
45714                     SliderZoomView.superApply(this, 'dispose', arguments);\r
45715                     throttle.clear(this, '_dispatchZoomAction');\r
45716                 },\r
45717 \r
45718                 _buildView: function () {\r
45719                     var thisGroup = this.group;\r
45720 \r
45721                     thisGroup.removeAll();\r
45722 \r
45723                     this._resetLocation();\r
45724                     this._resetInterval();\r
45725 \r
45726                     var barGroup = this._displayables.barGroup = new graphic.Group();\r
45727 \r
45728                     this._renderBackground();\r
45729                     this._renderDataShadow();\r
45730                     this._renderHandle();\r
45731 \r
45732                     thisGroup.add(barGroup);\r
45733 \r
45734                     this._positionGroup();\r
45735                 },\r
45736 \r
45737                 /**\r
45738                  * @private\r
45739                  */\r
45740                 _resetLocation: function () {\r
45741                     var dataZoomModel = this.dataZoomModel;\r
45742                     var api = this.api;\r
45743 \r
45744                     // If some of x/y/width/height are not specified,\r
45745                     // auto-adapt according to target grid.\r
45746                     var coordRect = this._findCoordRect();\r
45747                     var ecSize = {width: api.getWidth(), height: api.getHeight()};\r
45748                     // Default align by coordinate system rect.\r
45749                     var positionInfo = this._orient === HORIZONTAL\r
45750                         ? {\r
45751                             // Why using 'right', because right should be used in vertical,\r
45752                             // and it is better to be consistent for dealing with position param merge.\r
45753                             right: ecSize.width - coordRect.x - coordRect.width,\r
45754                             top: (ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP),\r
45755                             width: coordRect.width,\r
45756                             height: DEFAULT_FILLER_SIZE\r
45757                         }\r
45758                         : { // vertical\r
45759                             right: DEFAULT_LOCATION_EDGE_GAP,\r
45760                             top: coordRect.y,\r
45761                             width: DEFAULT_FILLER_SIZE,\r
45762                             height: coordRect.height\r
45763                         };\r
45764 \r
45765                     // Do not write back to option and replace value 'ph', because\r
45766                     // the 'ph' value should be recalculated when resize.\r
45767                     var layoutParams = layout.getLayoutParams(dataZoomModel.option);\r
45768 \r
45769                     // Replace the placeholder value.\r
45770                     zrUtil.each(['right', 'top', 'width', 'height'], function (name) {\r
45771                         if (layoutParams[name] === 'ph') {\r
45772                             layoutParams[name] = positionInfo[name];\r
45773                         }\r
45774                     });\r
45775 \r
45776                     var layoutRect = layout.getLayoutRect(\r
45777                         layoutParams,\r
45778                         ecSize,\r
45779                         dataZoomModel.padding\r
45780                     );\r
45781 \r
45782                     this._location = {x: layoutRect.x, y: layoutRect.y};\r
45783                     this._size = [layoutRect.width, layoutRect.height];\r
45784                     this._orient === VERTICAL && this._size.reverse();\r
45785                 },\r
45786 \r
45787                 /**\r
45788                  * @private\r
45789                  */\r
45790                 _positionGroup: function () {\r
45791                     var thisGroup = this.group;\r
45792                     var location = this._location;\r
45793                     var orient = this._orient;\r
45794 \r
45795                     // Just use the first axis to determine mapping.\r
45796                     var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel();\r
45797                     var inverse = targetAxisModel && targetAxisModel.get('inverse');\r
45798 \r
45799                     var barGroup = this._displayables.barGroup;\r
45800                     var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse;\r
45801 \r
45802                     // Transform barGroup.\r
45803                     barGroup.attr(\r
45804                         (orient === HORIZONTAL && !inverse)\r
45805                         ? {scale: otherAxisInverse ? [1, 1] : [1, -1]}\r
45806                         : (orient === HORIZONTAL && inverse)\r
45807                         ? {scale: otherAxisInverse ? [-1, 1] : [-1, -1]}\r
45808                         : (orient === VERTICAL && !inverse)\r
45809                         ? {scale: otherAxisInverse ? [1, -1] : [1, 1], rotation: Math.PI / 2}\r
45810                         // Dont use Math.PI, considering shadow direction.\r
45811                         : {scale: otherAxisInverse ? [-1, -1] : [-1, 1], rotation: Math.PI / 2}\r
45812                     );\r
45813 \r
45814                     // Position barGroup\r
45815                     var rect = thisGroup.getBoundingRect([barGroup]);\r
45816                     thisGroup.position[0] = location.x - rect.x;\r
45817                     thisGroup.position[1] = location.y - rect.y;\r
45818                 },\r
45819 \r
45820                 /**\r
45821                  * @private\r
45822                  */\r
45823                 _getViewExtent: function () {\r
45824                     // View total length.\r
45825                     var halfHandleSize = this._halfHandleSize;\r
45826                     var totalLength = mathMax(this._size[0], halfHandleSize * 4);\r
45827                     var extent = [halfHandleSize, totalLength - halfHandleSize];\r
45828 \r
45829                     return extent;\r
45830                 },\r
45831 \r
45832                 _renderBackground : function () {\r
45833                     var dataZoomModel = this.dataZoomModel;\r
45834                     var size = this._size;\r
45835 \r
45836                     this._displayables.barGroup.add(new Rect({\r
45837                         silent: true,\r
45838                         shape: {\r
45839                             x: 0, y: 0, width: size[0], height: size[1]\r
45840                         },\r
45841                         style: {\r
45842                             fill: dataZoomModel.get('backgroundColor')\r
45843                         }\r
45844                     }));\r
45845                 },\r
45846 \r
45847                 _renderDataShadow: function () {\r
45848                     var info = this._dataShadowInfo = this._prepareDataShadowInfo();\r
45849 \r
45850                     if (!info) {\r
45851                         return;\r
45852                     }\r
45853 \r
45854                     var size = this._size;\r
45855                     var seriesModel = info.series;\r
45856                     var data = seriesModel.getRawData();\r
45857                     var otherDim = seriesModel.getShadowDim\r
45858                         ? seriesModel.getShadowDim() // @see candlestick\r
45859                         : info.otherDim;\r
45860 \r
45861                     var otherDataExtent = data.getDataExtent(otherDim);\r
45862                     // Nice extent.\r
45863                     var otherOffset = (otherDataExtent[1] - otherDataExtent[0]) * 0.3;\r
45864                     otherDataExtent = [\r
45865                         otherDataExtent[0] - otherOffset,\r
45866                         otherDataExtent[1] + otherOffset\r
45867                     ];\r
45868                     var otherShadowExtent = [0, size[1]];\r
45869 \r
45870                     var thisShadowExtent = [0, size[0]];\r
45871 \r
45872                     var points = [[size[0], 0], [0, 0]];\r
45873                     var step = thisShadowExtent[1] / (data.count() - 1);\r
45874                     var thisCoord = 0;\r
45875 \r
45876                     // Optimize for large data shadow\r
45877                     var stride = Math.round(data.count() / size[0]);\r
45878                     data.each([otherDim], function (value, index) {\r
45879                         if (stride > 0 && (index % stride)) {\r
45880                             thisCoord += step;\r
45881                             return;\r
45882                         }\r
45883                         // FIXME\r
45884                         // 应该使用统计的空判断?还是在list里进行空判断?\r
45885                         var otherCoord = (value == null || isNaN(value) || value === '')\r
45886                             ? null\r
45887                             : linearMap(value, otherDataExtent, otherShadowExtent, true);\r
45888                         otherCoord != null && points.push([thisCoord, otherCoord]);\r
45889 \r
45890                         thisCoord += step;\r
45891                     });\r
45892 \r
45893                     this._displayables.barGroup.add(new graphic.Polyline({\r
45894                         shape: {points: points},\r
45895                         style: {fill: this.dataZoomModel.get('dataBackgroundColor'), lineWidth: 0},\r
45896                         silent: true,\r
45897                         z2: -20\r
45898                     }));\r
45899                 },\r
45900 \r
45901                 _prepareDataShadowInfo: function () {\r
45902                     var dataZoomModel = this.dataZoomModel;\r
45903                     var showDataShadow = dataZoomModel.get('showDataShadow');\r
45904 \r
45905                     if (showDataShadow === false) {\r
45906                         return;\r
45907                     }\r
45908 \r
45909                     // Find a representative series.\r
45910                     var result;\r
45911                     var ecModel = this.ecModel;\r
45912 \r
45913                     dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {\r
45914                         var seriesModels = dataZoomModel\r
45915                             .getAxisProxy(dimNames.name, axisIndex)\r
45916                             .getTargetSeriesModels();\r
45917 \r
45918                         zrUtil.each(seriesModels, function (seriesModel) {\r
45919                             if (result) {\r
45920                                 return;\r
45921                             }\r
45922 \r
45923                             if (showDataShadow !== true && zrUtil.indexOf(\r
45924                                     SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')\r
45925                                 ) < 0\r
45926                             ) {\r
45927                                 return;\r
45928                             }\r
45929 \r
45930                             var otherDim = getOtherDim(dimNames.name);\r
45931 \r
45932                             var thisAxis = ecModel.getComponent(dimNames.axis, axisIndex).axis;\r
45933 \r
45934                             result = {\r
45935                                 thisAxis: thisAxis,\r
45936                                 series: seriesModel,\r
45937                                 thisDim: dimNames.name,\r
45938                                 otherDim: otherDim,\r
45939                                 otherAxisInverse: seriesModel\r
45940                                     .coordinateSystem.getOtherAxis(thisAxis).inverse\r
45941                             };\r
45942 \r
45943                         }, this);\r
45944 \r
45945                     }, this);\r
45946 \r
45947                     return result;\r
45948                 },\r
45949 \r
45950                 _renderHandle: function () {\r
45951                     var displaybles = this._displayables;\r
45952                     var handles = displaybles.handles = [];\r
45953                     var handleLabels = displaybles.handleLabels = [];\r
45954                     var barGroup = this._displayables.barGroup;\r
45955                     var size = this._size;\r
45956 \r
45957                     barGroup.add(displaybles.filler = new Rect({\r
45958                         draggable: true,\r
45959                         cursor: 'move',\r
45960                         drift: bind(this._onDragMove, this, 'all'),\r
45961                         ondragend: bind(this._onDragEnd, this),\r
45962                         onmouseover: bind(this._showDataInfo, this, true),\r
45963                         onmouseout: bind(this._showDataInfo, this, false),\r
45964                         style: {\r
45965                             fill: this.dataZoomModel.get('fillerColor'),\r
45966                             // text: ':::',\r
45967                             textPosition : 'inside'\r
45968                         }\r
45969                     }));\r
45970 \r
45971                     // Frame border.\r
45972                     barGroup.add(new Rect(graphic.subPixelOptimizeRect({\r
45973                         silent: true,\r
45974                         shape: {\r
45975                             x: 0,\r
45976                             y: 0,\r
45977                             width: size[0],\r
45978                             height: size[1]\r
45979                         },\r
45980                         style: {\r
45981                             stroke: this.dataZoomModel.get('dataBackgroundColor'),\r
45982                             lineWidth: DEFAULT_FRAME_BORDER_WIDTH,\r
45983                             fill: 'rgba(0,0,0,0)'\r
45984                         }\r
45985                     })));\r
45986 \r
45987                     each([0, 1], function (handleIndex) {\r
45988 \r
45989                         barGroup.add(handles[handleIndex] = new Rect({\r
45990                             style: {\r
45991                                 fill: this.dataZoomModel.get('handleColor')\r
45992                             },\r
45993                             cursor: 'move',\r
45994                             draggable: true,\r
45995                             drift: bind(this._onDragMove, this, handleIndex),\r
45996                             ondragend: bind(this._onDragEnd, this),\r
45997                             onmouseover: bind(this._showDataInfo, this, true),\r
45998                             onmouseout: bind(this._showDataInfo, this, false)\r
45999                         }));\r
46000 \r
46001                         var textStyleModel = this.dataZoomModel.textStyleModel;\r
46002 \r
46003                         this.group.add(\r
46004                             handleLabels[handleIndex] = new graphic.Text({\r
46005                             silent: true,\r
46006                             invisible: true,\r
46007                             style: {\r
46008                                 x: 0, y: 0, text: '',\r
46009                                 textVerticalAlign: 'middle',\r
46010                                 textAlign: 'center',\r
46011                                 fill: textStyleModel.getTextColor(),\r
46012                                 textFont: textStyleModel.getFont()\r
46013                             }\r
46014                         }));\r
46015 \r
46016                     }, this);\r
46017                 },\r
46018 \r
46019                 /**\r
46020                  * @private\r
46021                  */\r
46022                 _resetInterval: function () {\r
46023                     var range = this._range = this.dataZoomModel.getPercentRange();\r
46024                     var viewExtent = this._getViewExtent();\r
46025 \r
46026                     this._handleEnds = [\r
46027                         linearMap(range[0], [0, 100], viewExtent, true),\r
46028                         linearMap(range[1], [0, 100], viewExtent, true)\r
46029                     ];\r
46030                 },\r
46031 \r
46032                 /**\r
46033                  * @private\r
46034                  * @param {(number|string)} handleIndex 0 or 1 or 'all'\r
46035                  * @param {number} dx\r
46036                  * @param {number} dy\r
46037                  */\r
46038                 _updateInterval: function (handleIndex, delta) {\r
46039                     var handleEnds = this._handleEnds;\r
46040                     var viewExtend = this._getViewExtent();\r
46041 \r
46042                     sliderMove(\r
46043                         delta,\r
46044                         handleEnds,\r
46045                         viewExtend,\r
46046                         (handleIndex === 'all' || this.dataZoomModel.get('zoomLock'))\r
46047                             ? 'rigid' : 'cross',\r
46048                         handleIndex\r
46049                     );\r
46050 \r
46051                     this._range = asc([\r
46052                         linearMap(handleEnds[0], viewExtend, [0, 100], true),\r
46053                         linearMap(handleEnds[1], viewExtend, [0, 100], true)\r
46054                     ]);\r
46055                 },\r
46056 \r
46057                 /**\r
46058                  * @private\r
46059                  */\r
46060                 _updateView: function () {\r
46061                     var displaybles = this._displayables;\r
46062                     var handleEnds = this._handleEnds;\r
46063                     var handleInterval = asc(handleEnds.slice());\r
46064                     var size = this._size;\r
46065                     var halfHandleSize = this._halfHandleSize;\r
46066 \r
46067                     each([0, 1], function (handleIndex) {\r
46068 \r
46069                         // Handles\r
46070                         var handle = displaybles.handles[handleIndex];\r
46071                         handle.setShape({\r
46072                             x: handleEnds[handleIndex] - halfHandleSize,\r
46073                             y: -1,\r
46074                             width: halfHandleSize * 2,\r
46075                             height: size[1] + 2,\r
46076                             r: 1\r
46077                         });\r
46078 \r
46079                     }, this);\r
46080 \r
46081                     // Filler\r
46082                     displaybles.filler.setShape({\r
46083                         x: handleInterval[0],\r
46084                         y: 0,\r
46085                         width: handleInterval[1] - handleInterval[0],\r
46086                         height: this._size[1]\r
46087                     });\r
46088 \r
46089                     this._updateDataInfo();\r
46090                 },\r
46091 \r
46092                 /**\r
46093                  * @private\r
46094                  */\r
46095                 _updateDataInfo: function () {\r
46096                     var dataZoomModel = this.dataZoomModel;\r
46097                     var displaybles = this._displayables;\r
46098                     var handleLabels = displaybles.handleLabels;\r
46099                     var orient = this._orient;\r
46100                     var labelTexts = ['', ''];\r
46101 \r
46102                     // FIXME\r
46103                     // date型,支持formatter,autoformatter(ec2 date.getAutoFormatter)\r
46104                     if (dataZoomModel.get('showDetail')) {\r
46105                         var dataInterval;\r
46106                         var axis;\r
46107                         dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {\r
46108                             // Using dataInterval of the first axis.\r
46109                             if (!dataInterval) {\r
46110                                 dataInterval = dataZoomModel\r
46111                                     .getAxisProxy(dimNames.name, axisIndex)\r
46112                                     .getDataValueWindow();\r
46113                                 axis = this.ecModel.getComponent(dimNames.axis, axisIndex).axis;\r
46114                             }\r
46115                         }, this);\r
46116 \r
46117                         if (dataInterval) {\r
46118                             labelTexts = [\r
46119                                 this._formatLabel(dataInterval[0], axis),\r
46120                                 this._formatLabel(dataInterval[1], axis)\r
46121                             ];\r
46122                         }\r
46123                     }\r
46124 \r
46125                     var orderedHandleEnds = asc(this._handleEnds.slice());\r
46126 \r
46127                     setLabel.call(this, 0);\r
46128                     setLabel.call(this, 1);\r
46129 \r
46130                     function setLabel(handleIndex) {\r
46131                         // Label\r
46132                         // Text should not transform by barGroup.\r
46133                         var barTransform = graphic.getTransform(\r
46134                             displaybles.handles[handleIndex], this.group\r
46135                         );\r
46136                         var direction = graphic.transformDirection(\r
46137                             handleIndex === 0 ? 'right' : 'left', barTransform\r
46138                         );\r
46139                         var offset = this._halfHandleSize + LABEL_GAP;\r
46140                         var textPoint = graphic.applyTransform(\r
46141                             [\r
46142                                 orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset),\r
46143                                 this._size[1] / 2\r
46144                             ],\r
46145                             barTransform\r
46146                         );\r
46147                         handleLabels[handleIndex].setStyle({\r
46148                             x: textPoint[0],\r
46149                             y: textPoint[1],\r
46150                             textVerticalAlign: orient === HORIZONTAL ? 'middle' : direction,\r
46151                             textAlign: orient === HORIZONTAL ? direction : 'center',\r
46152                             text: labelTexts[handleIndex]\r
46153                         });\r
46154                     }\r
46155                 },\r
46156 \r
46157                 /**\r
46158                  * @private\r
46159                  */\r
46160                 _formatLabel: function (value, axis) {\r
46161                     var dataZoomModel = this.dataZoomModel;\r
46162                     var labelFormatter = dataZoomModel.get('labelFormatter');\r
46163                     if (zrUtil.isFunction(labelFormatter)) {\r
46164                         return labelFormatter(value);\r
46165                     }\r
46166 \r
46167                     var labelPrecision = dataZoomModel.get('labelPrecision');\r
46168                     if (labelPrecision == null || labelPrecision === 'auto') {\r
46169                         labelPrecision = axis.getPixelPrecision();\r
46170                     }\r
46171 \r
46172                     value = (value == null && isNaN(value))\r
46173                         ? ''\r
46174                         // FIXME Glue code\r
46175                         : (axis.type === 'category' || axis.type === 'time')\r
46176                             ? axis.scale.getLabel(Math.round(value))\r
46177                             // param of toFixed should less then 20.\r
46178                             : value.toFixed(Math.min(labelPrecision, 20));\r
46179 \r
46180                     if (zrUtil.isString(labelFormatter)) {\r
46181                         value = labelFormatter.replace('{value}', value);\r
46182                     }\r
46183 \r
46184                     return value;\r
46185                 },\r
46186 \r
46187                 /**\r
46188                  * @private\r
46189                  * @param {boolean} showOrHide true: show, false: hide\r
46190                  */\r
46191                 _showDataInfo: function (showOrHide) {\r
46192                     // Always show when drgging.\r
46193                     showOrHide = this._dragging || showOrHide;\r
46194 \r
46195                     var handleLabels = this._displayables.handleLabels;\r
46196                     handleLabels[0].attr('invisible', !showOrHide);\r
46197                     handleLabels[1].attr('invisible', !showOrHide);\r
46198                 },\r
46199 \r
46200                 _onDragMove: function (handleIndex, dx, dy) {\r
46201                     this._dragging = true;\r
46202 \r
46203                     // Transform dx, dy to bar coordination.\r
46204                     var vertex = this._applyBarTransform([dx, dy], true);\r
46205 \r
46206                     this._updateInterval(handleIndex, vertex[0]);\r
46207                     this._updateView();\r
46208 \r
46209                     if (this.dataZoomModel.get('realtime')) {\r
46210                         this._dispatchZoomAction();\r
46211                     }\r
46212                 },\r
46213 \r
46214                 _onDragEnd: function () {\r
46215                     this._dragging = false;\r
46216                     this._showDataInfo(false);\r
46217                     this._dispatchZoomAction();\r
46218                 },\r
46219 \r
46220                 /**\r
46221                  * This action will be throttled.\r
46222                  * @private\r
46223                  */\r
46224                 _dispatchZoomAction: function () {\r
46225                     var range = this._range;\r
46226 \r
46227                     this.api.dispatchAction({\r
46228                         type: 'dataZoom',\r
46229                         from: this.uid,\r
46230                         dataZoomId: this.dataZoomModel.id,\r
46231                         start: range[0],\r
46232                         end: range[1]\r
46233                     });\r
46234                 },\r
46235 \r
46236                 /**\r
46237                  * @private\r
46238                  */\r
46239                 _applyBarTransform: function (vertex, inverse) {\r
46240                     var barTransform = this._displayables.barGroup.getLocalTransform();\r
46241                     return graphic.applyTransform(vertex, barTransform, inverse);\r
46242                 },\r
46243 \r
46244                 /**\r
46245                  * @private\r
46246                  */\r
46247                 _findCoordRect: function () {\r
46248                     // Find the grid coresponding to the first axis referred by dataZoom.\r
46249                     var targetInfo = this.getTargetInfo();\r
46250 \r
46251                     // FIXME\r
46252                     // 判断是catesian还是polar\r
46253                     var rect;\r
46254                     if (targetInfo.cartesians.length) {\r
46255                         rect = targetInfo.cartesians[0].model.coordinateSystem.getRect();\r
46256                     }\r
46257                     else { // Polar\r
46258                         // FIXME\r
46259                         // 暂时随便写的\r
46260                         var width = this.api.getWidth();\r
46261                         var height = this.api.getHeight();\r
46262                         rect = {\r
46263                             x: width * 0.2,\r
46264                             y: height * 0.2,\r
46265                             width: width * 0.6,\r
46266                             height: height * 0.6\r
46267                         };\r
46268                     }\r
46269 \r
46270                     return rect;\r
46271                 }\r
46272 \r
46273             });\r
46274 \r
46275             function getOtherDim(thisDim) {\r
46276                 // FIXME\r
46277                 // 这个逻辑和getOtherAxis里一致,但是写在这里是否不好\r
46278                 return thisDim === 'x' ? 'y' : 'x';\r
46279             }\r
46280 \r
46281             module.exports = SliderZoomView;\r
46282 \r
46283 \r
46284 \r
46285 /***/ },\r
46286 /* 293 */\r
46287 /***/ function(module, exports) {\r
46288 \r
46289         \r
46290 \r
46291             var lib = {};\r
46292 \r
46293             var ORIGIN_METHOD = '\0__throttleOriginMethod';\r
46294             var RATE = '\0__throttleRate';\r
46295 \r
46296             /**\r
46297              * 频率控制 返回函数连续调用时,fn 执行频率限定为每多少时间执行一次\r
46298              * 例如常见效果:\r
46299              * notifyWhenChangesStop\r
46300              *      频繁调用时,只保证最后一次执行\r
46301              *      配成:trailing:true;debounce:true 即可\r
46302              * notifyAtFixRate\r
46303              *      频繁调用时,按规律心跳执行\r
46304              *      配成:trailing:true;debounce:false 即可\r
46305              * 注意:\r
46306              *     根据model更新view的时候,可以使用throttle,\r
46307              *     但是根据view更新model的时候,避免使用这种延迟更新的方式。\r
46308              *     因为这可能导致model和server同步出现问题。\r
46309              *\r
46310              * @public\r
46311              * @param {(Function|Array.<Function>)} fn 需要调用的函数\r
46312              *                                         如果fn为array,则表示可以对多个函数进行throttle。\r
46313              *                                         他们共享同一个timer。\r
46314              * @param {number} delay 延迟时间,单位毫秒\r
46315              * @param {bool} trailing 是否保证最后一次触发的执行\r
46316              *                        true:表示保证最后一次调用会触发执行。\r
46317              *                        但任何调用后不可能立即执行,总会delay。\r
46318              *                        false:表示不保证最后一次调用会触发执行。\r
46319              *                        但只要间隔大于delay,调用就会立即执行。\r
46320              * @param {bool} debounce 节流\r
46321              *                        true:表示:频繁调用(间隔小于delay)时,根本不执行\r
46322              *                        false:表示:频繁调用(间隔小于delay)时,按规律心跳执行\r
46323              * @return {(Function|Array.<Function>)} 实际调用函数。\r
46324              *                                       当输入的fn为array时,返回值也为array。\r
46325              *                                       每项是Function。\r
46326              */\r
46327             lib.throttle = function (fn, delay, trailing, debounce) {\r
46328 \r
46329                 var currCall = (new Date()).getTime();\r
46330                 var lastCall = 0;\r
46331                 var lastExec = 0;\r
46332                 var timer = null;\r
46333                 var diff;\r
46334                 var scope;\r
46335                 var args;\r
46336                 var isSingle = typeof fn === 'function';\r
46337                 delay = delay || 0;\r
46338 \r
46339                 if (isSingle) {\r
46340                     return createCallback();\r
46341                 }\r
46342                 else {\r
46343                     var ret = [];\r
46344                     for (var i = 0; i < fn.length; i++) {\r
46345                         ret[i] = createCallback(i);\r
46346                     }\r
46347                     return ret;\r
46348                 }\r
46349 \r
46350                 function createCallback(index) {\r
46351 \r
46352                     function exec() {\r
46353                         lastExec = (new Date()).getTime();\r
46354                         timer = null;\r
46355                         (isSingle ? fn : fn[index]).apply(scope, args || []);\r
46356                     }\r
46357 \r
46358                     var cb = function () {\r
46359                         currCall = (new Date()).getTime();\r
46360                         scope = this;\r
46361                         args = arguments;\r
46362                         diff = currCall - (debounce ? lastCall : lastExec) - delay;\r
46363 \r
46364                         clearTimeout(timer);\r
46365 \r
46366                         if (debounce) {\r
46367                             if (trailing) {\r
46368                                 timer = setTimeout(exec, delay);\r
46369                             }\r
46370                             else if (diff >= 0) {\r
46371                                 exec();\r
46372                             }\r
46373                         }\r
46374                         else {\r
46375                             if (diff >= 0) {\r
46376                                 exec();\r
46377                             }\r
46378                             else if (trailing) {\r
46379                                 timer = setTimeout(exec, -diff);\r
46380                             }\r
46381                         }\r
46382 \r
46383                         lastCall = currCall;\r
46384                     };\r
46385 \r
46386                     /**\r
46387                      * Clear throttle.\r
46388                      * @public\r
46389                      */\r
46390                     cb.clear = function () {\r
46391                         if (timer) {\r
46392                             clearTimeout(timer);\r
46393                             timer = null;\r
46394                         }\r
46395                     };\r
46396 \r
46397                     return cb;\r
46398                 }\r
46399             };\r
46400 \r
46401             /**\r
46402              * 按一定频率执行,最后一次调用总归会执行\r
46403              *\r
46404              * @public\r
46405              */\r
46406             lib.fixRate = function (fn, delay) {\r
46407                 return delay != null\r
46408                     ? lib.throttle(fn, delay, true, false)\r
46409                     : fn;\r
46410             };\r
46411 \r
46412             /**\r
46413              * 直到不频繁调用了才会执行,最后一次调用总归会执行\r
46414              *\r
46415              * @public\r
46416              */\r
46417             lib.debounce = function (fn, delay) {\r
46418                 return delay != null\r
46419                      ? lib.throttle(fn, delay, true, true)\r
46420                      : fn;\r
46421             };\r
46422 \r
46423 \r
46424             /**\r
46425              * Create throttle method or update throttle rate.\r
46426              *\r
46427              * @example\r
46428              * ComponentView.prototype.render = function () {\r
46429              *     ...\r
46430              *     throttle.createOrUpdate(\r
46431              *         this,\r
46432              *         '_dispatchAction',\r
46433              *         this.model.get('throttle'),\r
46434              *         'fixRate'\r
46435              *     );\r
46436              * };\r
46437              * ComponentView.prototype.remove = function () {\r
46438              *     throttle.clear(this, '_dispatchAction');\r
46439              * };\r
46440              * ComponentView.prototype.dispose = function () {\r
46441              *     throttle.clear(this, '_dispatchAction');\r
46442              * };\r
46443              *\r
46444              * @public\r
46445              * @param {Object} obj\r
46446              * @param {string} fnAttr\r
46447              * @param {number} rate\r
46448              * @param {string} throttleType 'fixRate' or 'debounce'\r
46449              */\r
46450             lib.createOrUpdate = function (obj, fnAttr, rate, throttleType) {\r
46451                 var fn = obj[fnAttr];\r
46452 \r
46453                 if (!fn || rate == null || !throttleType) {\r
46454                     return;\r
46455                 }\r
46456 \r
46457                 var originFn = fn[ORIGIN_METHOD] || fn;\r
46458                 var lastRate = fn[RATE];\r
46459 \r
46460                 if (lastRate !== rate) {\r
46461                     fn = obj[fnAttr] = lib[throttleType](originFn, rate);\r
46462                     fn[ORIGIN_METHOD] = originFn;\r
46463                     fn[RATE] = rate;\r
46464                 }\r
46465             };\r
46466 \r
46467             /**\r
46468              * Clear throttle. Example see throttle.createOrUpdate.\r
46469              *\r
46470              * @public\r
46471              * @param {Object} obj\r
46472              * @param {string} fnAttr\r
46473              */\r
46474             lib.clear = function (obj, fnAttr) {\r
46475                 var fn = obj[fnAttr];\r
46476                 if (fn && fn[ORIGIN_METHOD]) {\r
46477                     obj[fnAttr] = fn[ORIGIN_METHOD];\r
46478                 }\r
46479             };\r
46480 \r
46481             module.exports = lib;\r
46482 \r
46483 \r
46484 \r
46485 /***/ },\r
46486 /* 294 */\r
46487 /***/ function(module, exports) {\r
46488 \r
46489         \r
46490 \r
46491             /**\r
46492              * Calculate slider move result.\r
46493              *\r
46494              * @param {number} delta Move length.\r
46495              * @param {Array.<number>} handleEnds handleEnds[0] and be bigger then handleEnds[1].\r
46496              *                                    handleEnds will be modified in this method.\r
46497              * @param {Array.<number>} extent handleEnds is restricted by extent.\r
46498              *                                extent[0] should less or equals than extent[1].\r
46499              * @param {string} mode 'rigid': Math.abs(handleEnds[0] - handleEnds[1]) remain unchanged,\r
46500              *                      'cross' handleEnds[0] can be bigger then handleEnds[1],\r
46501              *                      'push' handleEnds[0] can not be bigger then handleEnds[1],\r
46502              *                              when they touch, one push other.\r
46503              * @param {number} handleIndex If mode is 'rigid', handleIndex is not required.\r
46504              * @param {Array.<number>} The input handleEnds.\r
46505              */\r
46506             module.exports = function (delta, handleEnds, extent, mode, handleIndex) {\r
46507                 if (!delta) {\r
46508                     return handleEnds;\r
46509                 }\r
46510 \r
46511                 if (mode === 'rigid') {\r
46512                     delta = getRealDelta(delta, handleEnds, extent);\r
46513                     handleEnds[0] += delta;\r
46514                     handleEnds[1] += delta;\r
46515                 }\r
46516                 else {\r
46517                     delta = getRealDelta(delta, handleEnds[handleIndex], extent);\r
46518                     handleEnds[handleIndex] += delta;\r
46519 \r
46520                     if (mode === 'push' && handleEnds[0] > handleEnds[1]) {\r
46521                         handleEnds[1 - handleIndex] = handleEnds[handleIndex];\r
46522                     }\r
46523                 }\r
46524 \r
46525                 return handleEnds;\r
46526 \r
46527                 function getRealDelta(delta, handleEnds, extent) {\r
46528                     var handleMinMax = !handleEnds.length\r
46529                         ? [handleEnds, handleEnds]\r
46530                         : handleEnds.slice();\r
46531                     handleEnds[0] > handleEnds[1] && handleMinMax.reverse();\r
46532 \r
46533                     if (delta < 0 && handleMinMax[0] + delta < extent[0]) {\r
46534                         delta = extent[0] - handleMinMax[0];\r
46535                     }\r
46536                     if (delta > 0 && handleMinMax[1] + delta > extent[1]) {\r
46537                         delta = extent[1] - handleMinMax[1];\r
46538                     }\r
46539                     return delta;\r
46540                 }\r
46541             };\r
46542 \r
46543 \r
46544 /***/ },\r
46545 /* 295 */\r
46546 /***/ function(module, exports, __webpack_require__) {\r
46547 \r
46548         /**\r
46549          * @file Data zoom model\r
46550          */\r
46551 \r
46552 \r
46553             module.exports = __webpack_require__(288).extend({\r
46554 \r
46555                 type: 'dataZoom.inside',\r
46556 \r
46557                 /**\r
46558                  * @protected\r
46559                  */\r
46560                 defaultOption: {\r
46561                     zoomLock: false // Whether disable zoom but only pan.\r
46562                 }\r
46563             });\r
46564 \r
46565 \r
46566 /***/ },\r
46567 /* 296 */\r
46568 /***/ function(module, exports, __webpack_require__) {\r
46569 \r
46570         \r
46571 \r
46572             var DataZoomView = __webpack_require__(290);\r
46573             var zrUtil = __webpack_require__(3);\r
46574             var sliderMove = __webpack_require__(294);\r
46575             var roams = __webpack_require__(297);\r
46576             var bind = zrUtil.bind;\r
46577 \r
46578             var InsideZoomView = DataZoomView.extend({\r
46579 \r
46580                 type: 'dataZoom.inside',\r
46581 \r
46582                 /**\r
46583                  * @override\r
46584                  */\r
46585                 init: function (ecModel, api) {\r
46586                     /**\r
46587                      * 'throttle' is used in this.dispatchAction, so we save range\r
46588                      * to avoid missing some 'pan' info.\r
46589                      * @private\r
46590                      * @type {Array.<number>}\r
46591                      */\r
46592                     this._range;\r
46593                 },\r
46594 \r
46595                 /**\r
46596                  * @override\r
46597                  */\r
46598                 render: function (dataZoomModel, ecModel, api, payload) {\r
46599                     InsideZoomView.superApply(this, 'render', arguments);\r
46600 \r
46601                     // Notice: origin this._range should be maintained, and should not be re-fetched\r
46602                     // from dataZoomModel when payload.type is 'dataZoom', otherwise 'pan' or 'zoom'\r
46603                     // info will be missed because of 'throttle' of this.dispatchAction.\r
46604                     if (roams.shouldRecordRange(payload, dataZoomModel.id)) {\r
46605                         this._range = dataZoomModel.getPercentRange();\r
46606                     }\r
46607 \r
46608                     // Reset controllers.\r
46609                     var coordInfoList = this.getTargetInfo().cartesians;\r
46610                     var allCoordIds = zrUtil.map(coordInfoList, function (coordInfo) {\r
46611                         return roams.generateCoordId(coordInfo.model);\r
46612                     });\r
46613                     zrUtil.each(coordInfoList, function (coordInfo) {\r
46614                         var coordModel = coordInfo.model;\r
46615                         roams.register(\r
46616                             api,\r
46617                             {\r
46618                                 coordId: roams.generateCoordId(coordModel),\r
46619                                 allCoordIds: allCoordIds,\r
46620                                 coordinateSystem: coordModel.coordinateSystem,\r
46621                                 dataZoomId: dataZoomModel.id,\r
46622                                 throttleRage: dataZoomModel.get('throttle', true),\r
46623                                 panGetRange: bind(this._onPan, this, coordInfo),\r
46624                                 zoomGetRange: bind(this._onZoom, this, coordInfo)\r
46625                             }\r
46626                         );\r
46627                     }, this);\r
46628 \r
46629                     // TODO\r
46630                     // polar支持\r
46631                 },\r
46632 \r
46633                 /**\r
46634                  * @override\r
46635                  */\r
46636                 remove: function () {\r
46637                     roams.unregister(this.api, this.dataZoomModel.id);\r
46638                     InsideZoomView.superApply(this, 'remove', arguments);\r
46639                     this._range = null;\r
46640                 },\r
46641 \r
46642                 /**\r
46643                  * @override\r
46644                  */\r
46645                 dispose: function () {\r
46646                     roams.unregister(this.api, this.dataZoomModel.id);\r
46647                     InsideZoomView.superApply(this, 'dispose', arguments);\r
46648                     this._range = null;\r
46649                 },\r
46650 \r
46651                 /**\r
46652                  * @private\r
46653                  */\r
46654                 _onPan: function (coordInfo, controller, dx, dy) {\r
46655                     return (\r
46656                         this._range = panCartesian(\r
46657                             [dx, dy], this._range, controller, coordInfo\r
46658                         )\r
46659                     );\r
46660                 },\r
46661 \r
46662                 /**\r
46663                  * @private\r
46664                  */\r
46665                 _onZoom: function (coordInfo, controller, scale, mouseX, mouseY) {\r
46666                     var dataZoomModel = this.dataZoomModel;\r
46667 \r
46668                     if (dataZoomModel.option.zoomLock) {\r
46669                         return this._range;\r
46670                     }\r
46671 \r
46672                     return (\r
46673                         this._range = scaleCartesian(\r
46674                             1 / scale, [mouseX, mouseY], this._range,\r
46675                             controller, coordInfo, dataZoomModel\r
46676                         )\r
46677                     );\r
46678                 }\r
46679 \r
46680             });\r
46681 \r
46682             function panCartesian(pixelDeltas, range, controller, coordInfo) {\r
46683                 range = range.slice();\r
46684 \r
46685                 // Calculate transform by the first axis.\r
46686                 var axisModel = coordInfo.axisModels[0];\r
46687                 if (!axisModel) {\r
46688                     return;\r
46689                 }\r
46690 \r
46691                 var directionInfo = getDirectionInfo(pixelDeltas, axisModel, controller);\r
46692 \r
46693                 var percentDelta = directionInfo.signal\r
46694                     * (range[1] - range[0])\r
46695                     * directionInfo.pixel / directionInfo.pixelLength;\r
46696 \r
46697                 sliderMove(\r
46698                     percentDelta,\r
46699                     range,\r
46700                     [0, 100],\r
46701                     'rigid'\r
46702                 );\r
46703 \r
46704                 return range;\r
46705             }\r
46706 \r
46707             function scaleCartesian(scale, mousePoint, range, controller, coordInfo, dataZoomModel) {\r
46708                 range = range.slice();\r
46709 \r
46710                 // Calculate transform by the first axis.\r
46711                 var axisModel = coordInfo.axisModels[0];\r
46712                 if (!axisModel) {\r
46713                     return;\r
46714                 }\r
46715 \r
46716                 var directionInfo = getDirectionInfo(mousePoint, axisModel, controller);\r
46717 \r
46718                 var mouse = directionInfo.pixel - directionInfo.pixelStart;\r
46719                 var percentPoint = mouse / directionInfo.pixelLength * (range[1] - range[0]) + range[0];\r
46720 \r
46721                 scale = Math.max(scale, 0);\r
46722                 range[0] = (range[0] - percentPoint) * scale + percentPoint;\r
46723                 range[1] = (range[1] - percentPoint) * scale + percentPoint;\r
46724 \r
46725                 return fixRange(range);\r
46726             }\r
46727 \r
46728             function getDirectionInfo(xy, axisModel, controller) {\r
46729                 var axis = axisModel.axis;\r
46730                 var rect = controller.rect;\r
46731                 var ret = {};\r
46732 \r
46733                 if (axis.dim === 'x') {\r
46734                     ret.pixel = xy[0];\r
46735                     ret.pixelLength = rect.width;\r
46736                     ret.pixelStart = rect.x;\r
46737                     ret.signal = axis.inverse ? 1 : -1;\r
46738                 }\r
46739                 else { // axis.dim === 'y'\r
46740                     ret.pixel = xy[1];\r
46741                     ret.pixelLength = rect.height;\r
46742                     ret.pixelStart = rect.y;\r
46743                     ret.signal = axis.inverse ? -1 : 1;\r
46744                 }\r
46745 \r
46746                 return ret;\r
46747             }\r
46748 \r
46749             function fixRange(range) {\r
46750                 // Clamp, using !(<= or >=) to handle NaN.\r
46751                 // jshint ignore:start\r
46752                 var bound = [0, 100];\r
46753                 !(range[0] <= bound[1]) && (range[0] = bound[1]);\r
46754                 !(range[1] <= bound[1]) && (range[1] = bound[1]);\r
46755                 !(range[0] >= bound[0]) && (range[0] = bound[0]);\r
46756                 !(range[1] >= bound[0]) && (range[1] = bound[0]);\r
46757                 // jshint ignore:end\r
46758 \r
46759                 return range;\r
46760             }\r
46761 \r
46762             module.exports = InsideZoomView;\r
46763 \r
46764 \r
46765 /***/ },\r
46766 /* 297 */\r
46767 /***/ function(module, exports, __webpack_require__) {\r
46768 \r
46769         /**\r
46770          * @file Roam controller manager.\r
46771          */\r
46772 \r
46773 \r
46774             // Only create one roam controller for each coordinate system.\r
46775             // one roam controller might be refered by two inside data zoom\r
46776             // components (for example, one for x and one for y). When user\r
46777             // pan or zoom, only dispatch one action for those data zoom\r
46778             // components.\r
46779 \r
46780             var zrUtil = __webpack_require__(3);\r
46781             var RoamController = __webpack_require__(159);\r
46782             var throttle = __webpack_require__(293);\r
46783             var curry = zrUtil.curry;\r
46784 \r
46785             var ATTR = '\0_ec_dataZoom_roams';\r
46786 \r
46787             var roams = {\r
46788 \r
46789                 /**\r
46790                  * @public\r
46791                  * @param {module:echarts/ExtensionAPI} api\r
46792                  * @param {Object} dataZoomInfo\r
46793                  * @param {string} dataZoomInfo.coordId\r
46794                  * @param {Object} dataZoomInfo.coordinateSystem\r
46795                  * @param {Array.<string>} dataZoomInfo.allCoordIds\r
46796                  * @param {string} dataZoomInfo.dataZoomId\r
46797                  * @param {number} dataZoomInfo.throttleRate\r
46798                  * @param {Function} dataZoomInfo.panGetRange\r
46799                  * @param {Function} dataZoomInfo.zoomGetRange\r
46800                  */\r
46801                 register: function (api, dataZoomInfo) {\r
46802                     var store = giveStore(api);\r
46803                     var theDataZoomId = dataZoomInfo.dataZoomId;\r
46804                     var theCoordId = dataZoomInfo.coordId;\r
46805 \r
46806                     // Do clean when a dataZoom changes its target coordnate system.\r
46807                     zrUtil.each(store, function (record, coordId) {\r
46808                         var dataZoomInfos = record.dataZoomInfos;\r
46809                         if (dataZoomInfos[theDataZoomId]\r
46810                             && zrUtil.indexOf(dataZoomInfo.allCoordIds, theCoordId) < 0\r
46811                         ) {\r
46812                             delete dataZoomInfos[theDataZoomId];\r
46813                             record.count--;\r
46814                         }\r
46815                     });\r
46816 \r
46817                     cleanStore(store);\r
46818 \r
46819                     var record = store[theCoordId];\r
46820 \r
46821                     // Create if needed.\r
46822                     if (!record) {\r
46823                         record = store[theCoordId] = {\r
46824                             coordId: theCoordId,\r
46825                             dataZoomInfos: {},\r
46826                             count: 0\r
46827                         };\r
46828                         record.controller = createController(api, dataZoomInfo, record);\r
46829                         record.dispatchAction = zrUtil.curry(dispatchAction, api);\r
46830                     }\r
46831 \r
46832                     // Consider resize, area should be always updated.\r
46833                     record.controller.rect = dataZoomInfo.coordinateSystem.getRect().clone();\r
46834 \r
46835                     // Update throttle.\r
46836                     throttle.createOrUpdate(\r
46837                         record,\r
46838                         'dispatchAction',\r
46839                         dataZoomInfo.throttleRate,\r
46840                         'fixRate'\r
46841                     );\r
46842 \r
46843                     // Update reference of dataZoom.\r
46844                     !(record.dataZoomInfos[theDataZoomId]) && record.count++;\r
46845                     record.dataZoomInfos[theDataZoomId] = dataZoomInfo;\r
46846                 },\r
46847 \r
46848                 /**\r
46849                  * @public\r
46850                  * @param {module:echarts/ExtensionAPI} api\r
46851                  * @param {string} dataZoomId\r
46852                  */\r
46853                 unregister: function (api, dataZoomId) {\r
46854                     var store = giveStore(api);\r
46855 \r
46856                     zrUtil.each(store, function (record) {\r
46857                         var dataZoomInfos = record.dataZoomInfos;\r
46858                         if (dataZoomInfos[dataZoomId]) {\r
46859                             delete dataZoomInfos[dataZoomId];\r
46860                             record.count--;\r
46861                         }\r
46862                     });\r
46863 \r
46864                     cleanStore(store);\r
46865                 },\r
46866 \r
46867                 /**\r
46868                  * @public\r
46869                  */\r
46870                 shouldRecordRange: function (payload, dataZoomId) {\r
46871                     if (payload && payload.type === 'dataZoom' && payload.batch) {\r
46872                         for (var i = 0, len = payload.batch.length; i < len; i++) {\r
46873                             if (payload.batch[i].dataZoomId === dataZoomId) {\r
46874                                 return false;\r
46875                             }\r
46876                         }\r
46877                     }\r
46878                     return true;\r
46879                 },\r
46880 \r
46881                 /**\r
46882                  * @public\r
46883                  */\r
46884                 generateCoordId: function (coordModel) {\r
46885                     return coordModel.type + '\0_' + coordModel.id;\r
46886                 }\r
46887             };\r
46888 \r
46889             /**\r
46890              * Key: coordId, value: {dataZoomInfos: [], count, controller}\r
46891              * @type {Array.<Object>}\r
46892              */\r
46893             function giveStore(api) {\r
46894                 // Mount store on zrender instance, so that we do not\r
46895                 // need to worry about dispose.\r
46896                 var zr = api.getZr();\r
46897                 return zr[ATTR] || (zr[ATTR] = {});\r
46898             }\r
46899 \r
46900             function createController(api, dataZoomInfo, newRecord) {\r
46901                 var controller = new RoamController(api.getZr());\r
46902                 controller.enable();\r
46903                 controller.on('pan', curry(onPan, newRecord));\r
46904                 controller.on('zoom', curry(onZoom, newRecord));\r
46905 \r
46906                 return controller;\r
46907             }\r
46908 \r
46909             function cleanStore(store) {\r
46910                 zrUtil.each(store, function (record, coordId) {\r
46911                     if (!record.count) {\r
46912                         record.controller.off('pan').off('zoom');\r
46913                         delete store[coordId];\r
46914                     }\r
46915                 });\r
46916             }\r
46917 \r
46918             function onPan(record, dx, dy) {\r
46919                 wrapAndDispatch(record, function (info) {\r
46920                     return info.panGetRange(record.controller, dx, dy);\r
46921                 });\r
46922             }\r
46923 \r
46924             function onZoom(record, scale, mouseX, mouseY) {\r
46925                 wrapAndDispatch(record, function (info) {\r
46926                     return info.zoomGetRange(record.controller, scale, mouseX, mouseY);\r
46927                 });\r
46928             }\r
46929 \r
46930             function wrapAndDispatch(record, getRange) {\r
46931                 var batch = [];\r
46932 \r
46933                 zrUtil.each(record.dataZoomInfos, function (info) {\r
46934                     var range = getRange(info);\r
46935                     range && batch.push({\r
46936                         dataZoomId: info.dataZoomId,\r
46937                         start: range[0],\r
46938                         end: range[1]\r
46939                     });\r
46940                 });\r
46941 \r
46942                 record.dispatchAction(batch);\r
46943             }\r
46944 \r
46945             /**\r
46946              * This action will be throttled.\r
46947              */\r
46948             function dispatchAction(api, batch) {\r
46949                 api.dispatchAction({\r
46950                     type: 'dataZoom',\r
46951                     batch: batch\r
46952                 });\r
46953             }\r
46954 \r
46955             module.exports = roams;\r
46956 \r
46957 \r
46958 \r
46959 /***/ },\r
46960 /* 298 */\r
46961 /***/ function(module, exports, __webpack_require__) {\r
46962 \r
46963         /**\r
46964          * @file Data zoom processor\r
46965          */\r
46966 \r
46967 \r
46968             var echarts = __webpack_require__(1);\r
46969 \r
46970             echarts.registerProcessor('filter', function (ecModel, api) {\r
46971 \r
46972                 ecModel.eachComponent('dataZoom', function (dataZoomModel) {\r
46973                     // We calculate window and reset axis here but not in model\r
46974                     // init stage and not after action dispatch handler, because\r
46975                     // reset should be called after seriesData.restoreData.\r
46976                     dataZoomModel.eachTargetAxis(resetSingleAxis);\r
46977 \r
46978                     // Caution: data zoom filtering is order sensitive when using\r
46979                     // percent range and no min/max/scale set on axis.\r
46980                     // For example, we have dataZoom definition:\r
46981                     // [\r
46982                     //      {xAxisIndex: 0, start: 30, end: 70},\r
46983                     //      {yAxisIndex: 0, start: 20, end: 80}\r
46984                     // ]\r
46985                     // In this case, [20, 80] of y-dataZoom should be based on data\r
46986                     // that have filtered by x-dataZoom using range of [30, 70],\r
46987                     // but should not be based on full raw data. Thus sliding\r
46988                     // x-dataZoom will change both ranges of xAxis and yAxis,\r
46989                     // while sliding y-dataZoom will only change the range of yAxis.\r
46990                     // So we should filter x-axis after reset x-axis immediately,\r
46991                     // and then reset y-axis and filter y-axis.\r
46992                     dataZoomModel.eachTargetAxis(filterSingleAxis);\r
46993                 });\r
46994 \r
46995                 ecModel.eachComponent('dataZoom', function (dataZoomModel) {\r
46996                     // Fullfill all of the range props so that user\r
46997                     // is able to get them from chart.getOption().\r
46998                     var axisProxy = dataZoomModel.findRepresentativeAxisProxy();\r
46999                     var percentRange = axisProxy.getDataPercentWindow();\r
47000                     var valueRange = axisProxy.getDataValueWindow();\r
47001                     dataZoomModel.setRawRange({\r
47002                         start: percentRange[0],\r
47003                         end: percentRange[1],\r
47004                         startValue: valueRange[0],\r
47005                         endValue: valueRange[1]\r
47006                     });\r
47007                 });\r
47008             });\r
47009 \r
47010             function resetSingleAxis(dimNames, axisIndex, dataZoomModel) {\r
47011                 dataZoomModel.getAxisProxy(dimNames.name, axisIndex).reset(dataZoomModel);\r
47012             }\r
47013 \r
47014             function filterSingleAxis(dimNames, axisIndex, dataZoomModel) {\r
47015                 dataZoomModel.getAxisProxy(dimNames.name, axisIndex).filterData(dataZoomModel);\r
47016             }\r
47017 \r
47018 \r
47019 \r
47020 \r
47021 /***/ },\r
47022 /* 299 */\r
47023 /***/ function(module, exports, __webpack_require__) {\r
47024 \r
47025         /**\r
47026          * @file Data zoom action\r
47027          */\r
47028 \r
47029 \r
47030             var zrUtil = __webpack_require__(3);\r
47031             var modelUtil = __webpack_require__(5);\r
47032             var echarts = __webpack_require__(1);\r
47033 \r
47034 \r
47035             echarts.registerAction('dataZoom', function (payload, ecModel) {\r
47036 \r
47037                 var linkedNodesFinder = modelUtil.createLinkedNodesFinder(\r
47038                     zrUtil.bind(ecModel.eachComponent, ecModel, 'dataZoom'),\r
47039                     modelUtil.eachAxisDim,\r
47040                     function (model, dimNames) {\r
47041                         return model.get(dimNames.axisIndex);\r
47042                     }\r
47043                 );\r
47044 \r
47045                 var effectedModels = [];\r
47046 \r
47047                 ecModel.eachComponent(\r
47048                     {mainType: 'dataZoom', query: payload},\r
47049                     function (model, index) {\r
47050                         effectedModels.push.apply(\r
47051                             effectedModels, linkedNodesFinder(model).nodes\r
47052                         );\r
47053                     }\r
47054                 );\r
47055 \r
47056                 zrUtil.each(effectedModels, function (dataZoomModel, index) {\r
47057                     dataZoomModel.setRawRange({\r
47058                         start: payload.start,\r
47059                         end: payload.end,\r
47060                         startValue: payload.startValue,\r
47061                         endValue: payload.endValue\r
47062                     });\r
47063                 });\r
47064 \r
47065             });\r
47066 \r
47067 \r
47068 \r
47069 /***/ },\r
47070 /* 300 */\r
47071 /***/ function(module, exports, __webpack_require__) {\r
47072 \r
47073         /**\r
47074          * visualMap component entry\r
47075          */\r
47076 \r
47077 \r
47078             __webpack_require__(301);\r
47079             __webpack_require__(312);\r
47080 \r
47081 \r
47082 \r
47083 /***/ },\r
47084 /* 301 */\r
47085 /***/ function(module, exports, __webpack_require__) {\r
47086 \r
47087         /**\r
47088          * DataZoom component entry\r
47089          */\r
47090 \r
47091 \r
47092             __webpack_require__(1).registerPreprocessor(\r
47093                 __webpack_require__(302)\r
47094             );\r
47095 \r
47096             __webpack_require__(303);\r
47097             __webpack_require__(304);\r
47098             __webpack_require__(305);\r
47099             __webpack_require__(308);\r
47100             __webpack_require__(311);\r
47101 \r
47102 \r
47103 \r
47104 /***/ },\r
47105 /* 302 */\r
47106 /***/ function(module, exports, __webpack_require__) {\r
47107 \r
47108         /**\r
47109          * @file VisualMap preprocessor\r
47110          */\r
47111 \r
47112 \r
47113             var zrUtil = __webpack_require__(3);\r
47114             var each = zrUtil.each;\r
47115 \r
47116             module.exports = function (option) {\r
47117                 var visualMap = option && option.visualMap;\r
47118 \r
47119                 if (!zrUtil.isArray(visualMap)) {\r
47120                     visualMap = visualMap ? [visualMap] : [];\r
47121                 }\r
47122 \r
47123                 each(visualMap, function (opt) {\r
47124                     if (!opt) {\r
47125                         return;\r
47126                     }\r
47127 \r
47128                     // rename splitList to pieces\r
47129                     if (has(opt, 'splitList') && !has(opt, 'pieces')) {\r
47130                         opt.pieces = opt.splitList;\r
47131                         delete opt.splitList;\r
47132                     }\r
47133 \r
47134                     var pieces = opt.pieces;\r
47135                     if (pieces && zrUtil.isArray(pieces)) {\r
47136                         each(pieces, function (piece) {\r
47137                             if (zrUtil.isObject(piece)) {\r
47138                                 if (has(piece, 'start') && !has(piece, 'min')) {\r
47139                                     piece.min = piece.start;\r
47140                                 }\r
47141                                 if (has(piece, 'end') && !has(piece, 'max')) {\r
47142                                     piece.max = piece.end;\r
47143                                 }\r
47144                             }\r
47145                         });\r
47146                     }\r
47147                 });\r
47148             };\r
47149 \r
47150             function has(obj, name) {\r
47151                 return obj && obj.hasOwnProperty && obj.hasOwnProperty(name);\r
47152             }\r
47153 \r
47154 \r
47155 \r
47156 /***/ },\r
47157 /* 303 */\r
47158 /***/ function(module, exports, __webpack_require__) {\r
47159 \r
47160         \r
47161 \r
47162             __webpack_require__(19).registerSubTypeDefaulter('visualMap', function (option) {\r
47163                 // Compatible with ec2, when splitNumber === 0, continuous visualMap will be used.\r
47164                 return (\r
47165                         !option.categories\r
47166                         && (\r
47167                             !(\r
47168                                 option.pieces\r
47169                                     ? option.pieces.length > 0\r
47170                                     : option.splitNumber > 0\r
47171                             )\r
47172                             || option.calculable\r
47173                         )\r
47174                     )\r
47175                     ? 'continuous' : 'piecewise';\r
47176             });\r
47177 \r
47178 \r
47179 \r
47180 /***/ },\r
47181 /* 304 */\r
47182 /***/ function(module, exports, __webpack_require__) {\r
47183 \r
47184         /**\r
47185          * @file Data range visual coding.\r
47186          */\r
47187 \r
47188 \r
47189             var echarts = __webpack_require__(1);\r
47190             var VisualMapping = __webpack_require__(187);\r
47191             var zrUtil = __webpack_require__(3);\r
47192 \r
47193             echarts.registerVisualCoding('component', function (ecModel) {\r
47194                 ecModel.eachComponent('visualMap', function (visualMapModel) {\r
47195                     processSingleVisualMap(visualMapModel, ecModel);\r
47196                 });\r
47197             });\r
47198 \r
47199             function processSingleVisualMap(visualMapModel, ecModel) {\r
47200                 var visualMappings = visualMapModel.targetVisuals;\r
47201                 var visualTypesMap = {};\r
47202                 zrUtil.each(['inRange', 'outOfRange'], function (state) {\r
47203                     var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);\r
47204                     visualTypesMap[state] = visualTypes;\r
47205                 });\r
47206 \r
47207                 visualMapModel.eachTargetSeries(function (seriesModel) {\r
47208                     var data = seriesModel.getData();\r
47209                     var dimension = visualMapModel.getDataDimension(data);\r
47210                     var dataIndex;\r
47211 \r
47212                     function getVisual(key) {\r
47213                         return data.getItemVisual(dataIndex, key);\r
47214                     }\r
47215 \r
47216                     function setVisual(key, value) {\r
47217                         data.setItemVisual(dataIndex, key, value);\r
47218                     }\r
47219 \r
47220                     data.each([dimension], function (value, index) {\r
47221                         // For performance consideration, do not use curry.\r
47222                         dataIndex = index;\r
47223                         var valueState = visualMapModel.getValueState(value);\r
47224                         var mappings = visualMappings[valueState];\r
47225                         var visualTypes = visualTypesMap[valueState];\r
47226                         for (var i = 0, len = visualTypes.length; i < len; i++) {\r
47227                             var type = visualTypes[i];\r
47228                             mappings[type] && mappings[type].applyVisual(value, getVisual, setVisual);\r
47229                         }\r
47230                     });\r
47231                 });\r
47232             }\r
47233 \r
47234 \r
47235 \r
47236 \r
47237 /***/ },\r
47238 /* 305 */\r
47239 /***/ function(module, exports, __webpack_require__) {\r
47240 \r
47241         \r
47242         /**\r
47243          * @file Data zoom model\r
47244          */\r
47245 \r
47246 \r
47247             var VisualMapModel = __webpack_require__(306);\r
47248             var zrUtil = __webpack_require__(3);\r
47249             var numberUtil = __webpack_require__(7);\r
47250 \r
47251             // Constant\r
47252             var DEFAULT_BAR_BOUND = [20, 140];\r
47253 \r
47254             var ContinuousModel = VisualMapModel.extend({\r
47255 \r
47256                 type: 'visualMap.continuous',\r
47257 \r
47258                 /**\r
47259                  * @protected\r
47260                  */\r
47261                 defaultOption: {\r
47262                     handlePosition: 'auto',     // 'auto', 'left', 'right', 'top', 'bottom'\r
47263                     calculable: false,         // 是否值域漫游,启用后无视splitNumber和pieces,线性渐变\r
47264                     range: [-Infinity, Infinity], // 当前选中范围\r
47265                     hoverLink: true,\r
47266                     realtime: true,\r
47267                     itemWidth: null,            // 值域图形宽度\r
47268                     itemHeight: null            // 值域图形高度\r
47269                 },\r
47270 \r
47271                 /**\r
47272                  * @override\r
47273                  */\r
47274                 doMergeOption: function (newOption, isInit) {\r
47275                     ContinuousModel.superApply(this, 'doMergeOption', arguments);\r
47276 \r
47277                     this.resetTargetSeries(newOption, isInit);\r
47278                     this.resetExtent();\r
47279 \r
47280                     this.resetVisual(function (mappingOption) {\r
47281                         mappingOption.mappingMethod = 'linear';\r
47282                     });\r
47283 \r
47284                     this._resetRange();\r
47285                 },\r
47286 \r
47287                 /**\r
47288                  * @protected\r
47289                  * @override\r
47290                  */\r
47291                 resetItemSize: function () {\r
47292                     VisualMapModel.prototype.resetItemSize.apply(this, arguments);\r
47293 \r
47294                     var itemSize = this.itemSize;\r
47295 \r
47296                     this._orient === 'horizontal' && itemSize.reverse();\r
47297 \r
47298                     (itemSize[0] == null || isNaN(itemSize[0])) && (itemSize[0] = DEFAULT_BAR_BOUND[0]);\r
47299                     (itemSize[1] == null || isNaN(itemSize[1])) && (itemSize[1] = DEFAULT_BAR_BOUND[1]);\r
47300                 },\r
47301 \r
47302                 /**\r
47303                  * @private\r
47304                  */\r
47305                 _resetRange: function () {\r
47306                     var dataExtent = this.getExtent();\r
47307                     var range = this.option.range;\r
47308                     if (range[0] > range[1]) {\r
47309                         range.reverse();\r
47310                     }\r
47311                     range[0] = Math.max(range[0], dataExtent[0]);\r
47312                     range[1] = Math.min(range[1], dataExtent[1]);\r
47313                 },\r
47314 \r
47315                 /**\r
47316                  * @protected\r
47317                  * @override\r
47318                  */\r
47319                 completeVisualOption: function () {\r
47320                     VisualMapModel.prototype.completeVisualOption.apply(this, arguments);\r
47321 \r
47322                     zrUtil.each(this.stateList, function (state) {\r
47323                         var symbolSize = this.option.controller[state].symbolSize;\r
47324                         if (symbolSize && symbolSize[0] !== symbolSize[1]) {\r
47325                             symbolSize[0] = 0; // For good looking.\r
47326                         }\r
47327                     }, this);\r
47328                 },\r
47329 \r
47330                 /**\r
47331                  * @public\r
47332                  * @override\r
47333                  */\r
47334                 setSelected: function (selected) {\r
47335                     this.option.range = selected.slice();\r
47336                     this._resetRange();\r
47337                 },\r
47338 \r
47339                 /**\r
47340                  * @public\r
47341                  */\r
47342                 getSelected: function () {\r
47343                     var dataExtent = this.getExtent();\r
47344 \r
47345                     var dataInterval = numberUtil.asc(\r
47346                         (this.get('range') || []).slice()\r
47347                     );\r
47348 \r
47349                     // Clamp\r
47350                     dataInterval[0] > dataExtent[1] && (dataInterval[0] = dataExtent[1]);\r
47351                     dataInterval[1] > dataExtent[1] && (dataInterval[1] = dataExtent[1]);\r
47352                     dataInterval[0] < dataExtent[0] && (dataInterval[0] = dataExtent[0]);\r
47353                     dataInterval[1] < dataExtent[0] && (dataInterval[1] = dataExtent[0]);\r
47354 \r
47355                     return dataInterval;\r
47356                 },\r
47357 \r
47358                 /**\r
47359                  * @public\r
47360                  * @override\r
47361                  */\r
47362                 getValueState: function (value) {\r
47363                     var range = this.option.range;\r
47364                     var dataExtent = this.getExtent();\r
47365 \r
47366                     // When range[0] === dataExtent[0], any value larger than dataExtent[0] maps to 'inRange'.\r
47367                     // range[1] is processed likewise.\r
47368                     return (\r
47369                         (range[0] <= dataExtent[0] || range[0] <= value)\r
47370                         && (range[1] >= dataExtent[1] || value <= range[1])\r
47371                     ) ? 'inRange' : 'outOfRange';\r
47372                 }\r
47373 \r
47374             });\r
47375 \r
47376             module.exports = ContinuousModel;\r
47377 \r
47378 \r
47379 \r
47380 /***/ },\r
47381 /* 306 */\r
47382 /***/ function(module, exports, __webpack_require__) {\r
47383 \r
47384         /**\r
47385          * @file Data zoom model\r
47386          */\r
47387 \r
47388 \r
47389             var zrUtil = __webpack_require__(3);\r
47390             var env = __webpack_require__(78);\r
47391             var echarts = __webpack_require__(1);\r
47392             var modelUtil = __webpack_require__(5);\r
47393             var visualDefault = __webpack_require__(307);\r
47394             var VisualMapping = __webpack_require__(187);\r
47395             var mapVisual = VisualMapping.mapVisual;\r
47396             var eachVisual = VisualMapping.eachVisual;\r
47397             var numberUtil = __webpack_require__(7);\r
47398             var isArray = zrUtil.isArray;\r
47399             var each = zrUtil.each;\r
47400             var asc = numberUtil.asc;\r
47401             var linearMap = numberUtil.linearMap;\r
47402 \r
47403             var VisualMapModel = echarts.extendComponentModel({\r
47404 \r
47405                 type: 'visualMap',\r
47406 \r
47407                 dependencies: ['series'],\r
47408 \r
47409                 /**\r
47410                  * [lowerBound, upperBound]\r
47411                  *\r
47412                  * @readOnly\r
47413                  * @type {Array.<number>}\r
47414                  */\r
47415                 dataBound: [-Infinity, Infinity],\r
47416 \r
47417                 /**\r
47418                  * @readOnly\r
47419                  * @type {Array.<string>}\r
47420                  */\r
47421                 stateList: ['inRange', 'outOfRange'],\r
47422 \r
47423                 /**\r
47424                  * @readOnly\r
47425                  * @type {string|Object}\r
47426                  */\r
47427                 layoutMode: {type: 'box', ignoreSize: true},\r
47428 \r
47429                 /**\r
47430                  * @protected\r
47431                  */\r
47432                 defaultOption: {\r
47433                     show: true,\r
47434 \r
47435                     zlevel: 0,\r
47436                     z: 4,\r
47437 \r
47438                                             // set min: 0, max: 200, only for campatible with ec2.\r
47439                                             // In fact min max should not have default value.\r
47440                     min: 0,                 // min value, must specified if pieces is not specified.\r
47441                     max: 200,               // max value, must specified if pieces is not specified.\r
47442 \r
47443                     dimension: null,\r
47444                     inRange: null,          // 'color', 'colorHue', 'colorSaturation', 'colorLightness', 'colorAlpha',\r
47445                                             // 'symbol', 'symbolSize'\r
47446                     outOfRange: null,       // 'color', 'colorHue', 'colorSaturation',\r
47447                                             // 'colorLightness', 'colorAlpha',\r
47448                                             // 'symbol', 'symbolSize'\r
47449 \r
47450                     left: 0,                // 'center' ¦ 'left' ¦ 'right' ¦ {number} (px)\r
47451                     right: null,            // The same as left.\r
47452                     top: null,              // 'top' ¦ 'bottom' ¦ 'center' ¦ {number} (px)\r
47453                     bottom: 0,              // The same as top.\r
47454 \r
47455                     itemWidth: null,\r
47456                     itemHeight: null,\r
47457                     inverse: false,\r
47458                     orient: 'vertical',        // 'horizontal' ¦ 'vertical'\r
47459 \r
47460                     seriesIndex: null,          // 所控制的series indices,默认所有有value的series.\r
47461                     backgroundColor: 'rgba(0,0,0,0)',\r
47462                     borderColor: '#ccc',       // 值域边框颜色\r
47463                     contentColor: '#5793f3',\r
47464                     inactiveColor: '#aaa',\r
47465                     borderWidth: 0,            // 值域边框线宽,单位px,默认为0(无边框)\r
47466                     padding: 5,                // 值域内边距,单位px,默认各方向内边距为5,\r
47467                                                // 接受数组分别设定上右下左边距,同css\r
47468                     textGap: 10,               //\r
47469                     precision: 0,              // 小数精度,默认为0,无小数点\r
47470                     color: ['#bf444c', '#d88273', '#f6efa6'], //颜色(deprecated,兼容ec2,顺序同pieces,不同于inRange/outOfRange)\r
47471 \r
47472                     formatter: null,\r
47473                     text: null,                // 文本,如['高', '低'],兼容ec2,text[0]对应高值,text[1]对应低值\r
47474                     textStyle: {\r
47475                         color: '#333'          // 值域文字颜色\r
47476                     }\r
47477                 },\r
47478 \r
47479                 /**\r
47480                  * @protected\r
47481                  */\r
47482                 init: function (option, parentModel, ecModel) {\r
47483                     /**\r
47484                      * @private\r
47485                      * @type {boolean}\r
47486                      */\r
47487                     this._autoSeriesIndex = false;\r
47488 \r
47489                     /**\r
47490                      * @private\r
47491                      * @type {Array.<number>}\r
47492                      */\r
47493                     this._dataExtent;\r
47494 \r
47495                     /**\r
47496                      * @readOnly\r
47497                      */\r
47498                     this.controllerVisuals = {};\r
47499 \r
47500                     /**\r
47501                      * @readOnly\r
47502                      */\r
47503                     this.targetVisuals = {};\r
47504 \r
47505                     /**\r
47506                      * @readOnly\r
47507                      */\r
47508                     this.textStyleModel;\r
47509 \r
47510                     /**\r
47511                      * [width, height]\r
47512                      * @readOnly\r
47513                      * @type {Array.<number>}\r
47514                      */\r
47515                     this.itemSize;\r
47516 \r
47517                     this.mergeDefaultAndTheme(option, ecModel);\r
47518 \r
47519                     this.doMergeOption({}, true);\r
47520                 },\r
47521 \r
47522                 /**\r
47523                  * @public\r
47524                  */\r
47525                 mergeOption: function (option) {\r
47526                     VisualMapModel.superApply(this, 'mergeOption', arguments);\r
47527                     this.doMergeOption(option, false);\r
47528                 },\r
47529 \r
47530                 /**\r
47531                  * @protected\r
47532                  */\r
47533                 doMergeOption: function (newOption, isInit) {\r
47534                     var thisOption = this.option;\r
47535 \r
47536                     // Visual attributes merge is not supported, otherwise it\r
47537                     // brings overcomplicated merge logic. See #2853.\r
47538                     !isInit && replaceVisualOption(thisOption, newOption);\r
47539 \r
47540                     // FIXME\r
47541                     // necessary?\r
47542                     // Disable realtime view update if canvas is not supported.\r
47543                     if (!env.canvasSupported) {\r
47544                         thisOption.realtime = false;\r
47545                     }\r
47546 \r
47547                     this.textStyleModel = this.getModel('textStyle');\r
47548 \r
47549                     this.resetItemSize();\r
47550 \r
47551                     this.completeVisualOption();\r
47552                 },\r
47553 \r
47554                 /**\r
47555                  * @example\r
47556                  * this.formatValueText(someVal); // format single numeric value to text.\r
47557                  * this.formatValueText(someVal, true); // format single category value to text.\r
47558                  * this.formatValueText([min, max]); // format numeric min-max to text.\r
47559                  * this.formatValueText([this.dataBound[0], max]); // using data lower bound.\r
47560                  * this.formatValueText([min, this.dataBound[1]]); // using data upper bound.\r
47561                  *\r
47562                  * @param {number|Array.<number>} value Real value, or this.dataBound[0 or 1].\r
47563                  * @param {boolean} [isCategory=false] Only available when value is number.\r
47564                  * @return {string}\r
47565                  * @protected\r
47566                  */\r
47567                 formatValueText: function(value, isCategory) {\r
47568                     var option = this.option;\r
47569                     var precision = option.precision;\r
47570                     var dataBound = this.dataBound;\r
47571                     var formatter = option.formatter;\r
47572                     var isMinMax;\r
47573                     var textValue;\r
47574 \r
47575                     if (zrUtil.isArray(value)) {\r
47576                         value = value.slice();\r
47577                         isMinMax = true;\r
47578                     }\r
47579 \r
47580                     textValue = isCategory\r
47581                         ? value\r
47582                         : (isMinMax\r
47583                             ? [toFixed(value[0]), toFixed(value[1])]\r
47584                             : toFixed(value)\r
47585                         );\r
47586 \r
47587                     if (zrUtil.isString(formatter)) {\r
47588                         return formatter\r
47589                             .replace('{value}', isMinMax ? textValue[0] : textValue)\r
47590                             .replace('{value2}', isMinMax ? textValue[1] : textValue);\r
47591                     }\r
47592                     else if (zrUtil.isFunction(formatter)) {\r
47593                         return isMinMax\r
47594                             ? formatter(value[0], value[1])\r
47595                             : formatter(value);\r
47596                     }\r
47597 \r
47598                     if (isMinMax) {\r
47599                         if (value[0] === dataBound[0]) {\r
47600                             return '< ' + textValue[1];\r
47601                         }\r
47602                         else if (value[1] === dataBound[1]) {\r
47603                             return '> ' + textValue[0];\r
47604                         }\r
47605                         else {\r
47606                             return textValue[0] + ' - ' + textValue[1];\r
47607                         }\r
47608                     }\r
47609                     else { // Format single value (includes category case).\r
47610                         return textValue;\r
47611                     }\r
47612 \r
47613                     function toFixed(val) {\r
47614                         return val === dataBound[0]\r
47615                             ? 'min'\r
47616                             : val === dataBound[1]\r
47617                             ? 'max'\r
47618                             : (+val).toFixed(precision);\r
47619                     }\r
47620                 },\r
47621 \r
47622                 /**\r
47623                  * @protected\r
47624                  */\r
47625                 resetTargetSeries: function (newOption, isInit) {\r
47626                     var thisOption = this.option;\r
47627                     var autoSeriesIndex = this._autoSeriesIndex =\r
47628                         (isInit ? thisOption : newOption).seriesIndex == null;\r
47629                     thisOption.seriesIndex = autoSeriesIndex\r
47630                         ? [] : modelUtil.normalizeToArray(thisOption.seriesIndex);\r
47631 \r
47632                     autoSeriesIndex && this.ecModel.eachSeries(function (seriesModel, index) {\r
47633                         var data = seriesModel.getData();\r
47634                         // FIXME\r
47635                         // 只考虑了list,还没有考虑map等。\r
47636 \r
47637                         // FIXME\r
47638                         // 这里可能应该这么判断:data.dimensions中有超出其所属coordSystem的量。\r
47639                         if (data.type === 'list') {\r
47640                             thisOption.seriesIndex.push(index);\r
47641                         }\r
47642                     });\r
47643                 },\r
47644 \r
47645                 /**\r
47646                  * @protected\r
47647                  */\r
47648                 resetExtent: function () {\r
47649                     var thisOption = this.option;\r
47650 \r
47651                     // Can not calculate data extent by data here.\r
47652                     // Because series and data may be modified in processing stage.\r
47653                     // So we do not support the feature "auto min/max".\r
47654 \r
47655                     var extent = asc([thisOption.min, thisOption.max]);\r
47656 \r
47657                     this._dataExtent = extent;\r
47658                 },\r
47659 \r
47660                 /**\r
47661                  * @protected\r
47662                  */\r
47663                 getDataDimension: function (list) {\r
47664                     var optDim = this.option.dimension;\r
47665                     return optDim != null\r
47666                         ? optDim : list.dimensions.length - 1;\r
47667                 },\r
47668 \r
47669                 /**\r
47670                  * @public\r
47671                  * @override\r
47672                  */\r
47673                 getExtent: function () {\r
47674                     return this._dataExtent.slice();\r
47675                 },\r
47676 \r
47677                 /**\r
47678                  * @protected\r
47679                  */\r
47680                 resetVisual: function (fillVisualOption) {\r
47681                     var dataExtent = this.getExtent();\r
47682 \r
47683                     doReset.call(this, 'controller', this.controllerVisuals);\r
47684                     doReset.call(this, 'target', this.targetVisuals);\r
47685 \r
47686                     function doReset(baseAttr, visualMappings) {\r
47687                         each(this.stateList, function (state) {\r
47688                             var mappings = visualMappings[state] || (visualMappings[state] = {});\r
47689                             var visaulOption = this.option[baseAttr][state] || {};\r
47690                             each(visaulOption, function (visualData, visualType) {\r
47691                                 if (!VisualMapping.isValidType(visualType)) {\r
47692                                     return;\r
47693                                 }\r
47694                                 var mappingOption = {\r
47695                                     type: visualType,\r
47696                                     dataExtent: dataExtent,\r
47697                                     visual: visualData\r
47698                                 };\r
47699                                 fillVisualOption && fillVisualOption.call(this, mappingOption, state);\r
47700                                 mappings[visualType] = new VisualMapping(mappingOption);\r
47701                             }, this);\r
47702                         }, this);\r
47703                     }\r
47704                 },\r
47705 \r
47706                 /**\r
47707                  * @protected\r
47708                  */\r
47709                 completeVisualOption: function () {\r
47710                     var thisOption = this.option;\r
47711                     var base = {inRange: thisOption.inRange, outOfRange: thisOption.outOfRange};\r
47712 \r
47713                     var target = thisOption.target || (thisOption.target = {});\r
47714                     var controller = thisOption.controller || (thisOption.controller = {});\r
47715 \r
47716                     zrUtil.merge(target, base); // Do not override\r
47717                     zrUtil.merge(controller, base); // Do not override\r
47718 \r
47719                     var isCategory = this.isCategory();\r
47720 \r
47721                     completeSingle.call(this, target);\r
47722                     completeSingle.call(this, controller);\r
47723                     completeInactive.call(this, target, 'inRange', 'outOfRange');\r
47724                     completeInactive.call(this, target, 'outOfRange', 'inRange');\r
47725                     completeController.call(this, controller);\r
47726 \r
47727                     function completeSingle(base) {\r
47728                         // Compatible with ec2 dataRange.color.\r
47729                         // The mapping order of dataRange.color is: [high value, ..., low value]\r
47730                         // whereas inRange.color and outOfRange.color is [low value, ..., high value]\r
47731                         // Notice: ec2 has no inverse.\r
47732                         if (isArray(thisOption.color)\r
47733                             // If there has been inRange: {symbol: ...}, adding color is a mistake.\r
47734                             // So adding color only when no inRange defined.\r
47735                             && !base.inRange\r
47736                         ) {\r
47737                             base.inRange = {color: thisOption.color.slice().reverse()};\r
47738                         }\r
47739 \r
47740                         // If using shortcut like: {inRange: 'symbol'}, complete default value.\r
47741                         each(this.stateList, function (state) {\r
47742                             var visualType = base[state];\r
47743 \r
47744                             if (zrUtil.isString(visualType)) {\r
47745                                 var defa = visualDefault.get(visualType, 'active', isCategory);\r
47746                                 if (defa) {\r
47747                                     base[state] = {};\r
47748                                     base[state][visualType] = defa;\r
47749                                 }\r
47750                                 else {\r
47751                                     // Mark as not specified.\r
47752                                     delete base[state];\r
47753                                 }\r
47754                             }\r
47755                         }, this);\r
47756                     }\r
47757 \r
47758                     function completeInactive(base, stateExist, stateAbsent) {\r
47759                         var optExist = base[stateExist];\r
47760                         var optAbsent = base[stateAbsent];\r
47761 \r
47762                         if (optExist && !optAbsent) {\r
47763                             optAbsent = base[stateAbsent] = {};\r
47764                             each(optExist, function (visualData, visualType) {\r
47765                                 var defa = visualDefault.get(visualType, 'inactive', isCategory);\r
47766                                 if (VisualMapping.isValidType(visualType) && defa) {\r
47767                                     optAbsent[visualType] = defa;\r
47768                                 }\r
47769                             });\r
47770                         }\r
47771                     }\r
47772 \r
47773                     function completeController(controller) {\r
47774                         var symbolExists = (controller.inRange || {}).symbol\r
47775                             || (controller.outOfRange || {}).symbol;\r
47776                         var symbolSizeExists = (controller.inRange || {}).symbolSize\r
47777                             || (controller.outOfRange || {}).symbolSize;\r
47778                         var inactiveColor = this.get('inactiveColor');\r
47779 \r
47780                         each(this.stateList, function (state) {\r
47781 \r
47782                             var itemSize = this.itemSize;\r
47783                             var visuals = controller[state];\r
47784 \r
47785                             // Set inactive color for controller if no other color attr (like colorAlpha) specified.\r
47786                             if (!visuals) {\r
47787                                 visuals = controller[state] = {\r
47788                                     color: isCategory ? inactiveColor : [inactiveColor]\r
47789                                 };\r
47790                             }\r
47791 \r
47792                             // Consistent symbol and symbolSize if not specified.\r
47793                             if (!visuals.symbol) {\r
47794                                 visuals.symbol = symbolExists\r
47795                                     && zrUtil.clone(symbolExists)\r
47796                                     || (isCategory ? 'roundRect' : ['roundRect']);\r
47797                             }\r
47798                             if (!visuals.symbolSize) {\r
47799                                 visuals.symbolSize = symbolSizeExists\r
47800                                     && zrUtil.clone(symbolSizeExists)\r
47801                                     || (isCategory ? itemSize[0] : [itemSize[0], itemSize[0]]);\r
47802                             }\r
47803 \r
47804                             // Filter square and none.\r
47805                             visuals.symbol = mapVisual(visuals.symbol, function (symbol) {\r
47806                                 return (symbol === 'none' || symbol === 'square') ? 'roundRect' : symbol;\r
47807                             });\r
47808 \r
47809                             // Normalize symbolSize\r
47810                             var symbolSize = visuals.symbolSize;\r
47811 \r
47812                             if (symbolSize) {\r
47813                                 var max = -Infinity;\r
47814                                 // symbolSize can be object when categories defined.\r
47815                                 eachVisual(symbolSize, function (value) {\r
47816                                     value > max && (max = value);\r
47817                                 });\r
47818                                 visuals.symbolSize = mapVisual(symbolSize, function (value) {\r
47819                                     return linearMap(value, [0, max], [0, itemSize[0]], true);\r
47820                                 });\r
47821                             }\r
47822 \r
47823                         }, this);\r
47824                     }\r
47825                 },\r
47826 \r
47827                 /**\r
47828                  * @public\r
47829                  */\r
47830                 eachTargetSeries: function (callback, context) {\r
47831                     zrUtil.each(this.option.seriesIndex, function (seriesIndex) {\r
47832                         callback.call(context, this.ecModel.getSeriesByIndex(seriesIndex));\r
47833                     }, this);\r
47834                 },\r
47835 \r
47836                 /**\r
47837                  * @public\r
47838                  */\r
47839                 isCategory: function () {\r
47840                     return !!this.option.categories;\r
47841                 },\r
47842 \r
47843                 /**\r
47844                  * @protected\r
47845                  */\r
47846                 resetItemSize: function () {\r
47847                     this.itemSize = [\r
47848                         parseFloat(this.get('itemWidth')),\r
47849                         parseFloat(this.get('itemHeight'))\r
47850                     ];\r
47851                 },\r
47852 \r
47853                 /**\r
47854                  * @public\r
47855                  * @abstract\r
47856                  */\r
47857                 setSelected: zrUtil.noop,\r
47858 \r
47859                 /**\r
47860                  * @public\r
47861                  * @abstract\r
47862                  */\r
47863                 getValueState: zrUtil.noop\r
47864 \r
47865             });\r
47866 \r
47867             function replaceVisualOption(targetOption, sourceOption) {\r
47868                 zrUtil.each(\r
47869                     ['inRange', 'outOfRange', 'target', 'controller', 'color'],\r
47870                     function (key) {\r
47871                         if (sourceOption.hasOwnProperty(key)) {\r
47872                             targetOption[key] = zrUtil.clone(sourceOption[key]);\r
47873                         }\r
47874                         else {\r
47875                             delete targetOption[key];\r
47876                         }\r
47877                     }\r
47878                 );\r
47879             }\r
47880 \r
47881             module.exports = VisualMapModel;\r
47882 \r
47883 \r
47884 \r
47885 /***/ },\r
47886 /* 307 */\r
47887 /***/ function(module, exports, __webpack_require__) {\r
47888 \r
47889         /**\r
47890          * @file Visual mapping.\r
47891          */\r
47892 \r
47893 \r
47894             var zrUtil = __webpack_require__(3);\r
47895 \r
47896             var visualDefault = {\r
47897 \r
47898                 /**\r
47899                  * @public\r
47900                  */\r
47901                 get: function (visualType, key, isCategory) {\r
47902                     var value = zrUtil.clone(\r
47903                         (defaultOption[visualType] || {})[key]\r
47904                     );\r
47905 \r
47906                     return isCategory\r
47907                         ? (zrUtil.isArray(value) ? value[value.length - 1] : value)\r
47908                         : value;\r
47909                 }\r
47910 \r
47911             };\r
47912 \r
47913             var defaultOption = {\r
47914 \r
47915                 color: {\r
47916                     active: ['#006edd', '#e0ffff'],\r
47917                     inactive: ['rgba(0,0,0,0)']\r
47918                 },\r
47919 \r
47920                 colorHue: {\r
47921                     active: [0, 360],\r
47922                     inactive: [0, 0]\r
47923                 },\r
47924 \r
47925                 colorSaturation: {\r
47926                     active: [0.3, 1],\r
47927                     inactive: [0, 0]\r
47928                 },\r
47929 \r
47930                 colorLightness: {\r
47931                     active: [0.9, 0.5],\r
47932                     inactive: [0, 0]\r
47933                 },\r
47934 \r
47935                 colorAlpha: {\r
47936                     active: [0.3, 1],\r
47937                     inactive: [0, 0]\r
47938                 },\r
47939 \r
47940                 symbol: {\r
47941                     active: ['circle', 'roundRect', 'diamond'],\r
47942                     inactive: ['none']\r
47943                 },\r
47944 \r
47945                 symbolSize: {\r
47946                     active: [10, 50],\r
47947                     inactive: [0, 0]\r
47948                 }\r
47949             };\r
47950 \r
47951             module.exports = visualDefault;\r
47952 \r
47953 \r
47954 \r
47955 \r
47956 /***/ },\r
47957 /* 308 */\r
47958 /***/ function(module, exports, __webpack_require__) {\r
47959 \r
47960         \r
47961 \r
47962             var VisualMapView = __webpack_require__(309);\r
47963             var graphic = __webpack_require__(42);\r
47964             var zrUtil = __webpack_require__(3);\r
47965             var numberUtil = __webpack_require__(7);\r
47966             var sliderMove = __webpack_require__(294);\r
47967             var linearMap = numberUtil.linearMap;\r
47968             var LinearGradient = __webpack_require__(75);\r
47969             var helper = __webpack_require__(310);\r
47970             var each = zrUtil.each;\r
47971 \r
47972             // Notice:\r
47973             // Any "interval" should be by the order of [low, high].\r
47974             // "handle0" (handleIndex === 0) maps to\r
47975             // low data value: this._dataInterval[0] and has low coord.\r
47976             // "handle1" (handleIndex === 1) maps to\r
47977             // high data value: this._dataInterval[1] and has high coord.\r
47978             // The logic of transform is implemented in this._createBarGroup.\r
47979 \r
47980             var ContinuousVisualMapView = VisualMapView.extend({\r
47981 \r
47982                 type: 'visualMap.continuous',\r
47983 \r
47984                 /**\r
47985                  * @override\r
47986                  */\r
47987                 init: function () {\r
47988 \r
47989                     VisualMapView.prototype.init.apply(this, arguments);\r
47990 \r
47991                     /**\r
47992                      * @private\r
47993                      */\r
47994                     this._shapes = {};\r
47995 \r
47996                     /**\r
47997                      * @private\r
47998                      */\r
47999                     this._dataInterval = [];\r
48000 \r
48001                     /**\r
48002                      * @private\r
48003                      */\r
48004                     this._handleEnds = [];\r
48005 \r
48006                     /**\r
48007                      * @private\r
48008                      */\r
48009                     this._orient;\r
48010 \r
48011                     /**\r
48012                      * @private\r
48013                      */\r
48014                     this._useHandle;\r
48015                 },\r
48016 \r
48017                 /**\r
48018                  * @protected\r
48019                  * @override\r
48020                  */\r
48021                 doRender: function (visualMapModel, ecModel, api, payload) {\r
48022                     if (!payload || payload.type !== 'selectDataRange' || payload.from !== this.uid) {\r
48023                         this._buildView();\r
48024                     }\r
48025                     else {\r
48026                         this._updateView();\r
48027                     }\r
48028                 },\r
48029 \r
48030                 /**\r
48031                  * @private\r
48032                  */\r
48033                 _buildView: function () {\r
48034                     this.group.removeAll();\r
48035 \r
48036                     var visualMapModel = this.visualMapModel;\r
48037                     var thisGroup = this.group;\r
48038 \r
48039                     this._orient = visualMapModel.get('orient');\r
48040                     this._useHandle = visualMapModel.get('calculable');\r
48041 \r
48042                     this._resetInterval();\r
48043 \r
48044                     this._renderBar(thisGroup);\r
48045 \r
48046                     var dataRangeText = visualMapModel.get('text');\r
48047                     this._renderEndsText(thisGroup, dataRangeText, 0);\r
48048                     this._renderEndsText(thisGroup, dataRangeText, 1);\r
48049 \r
48050                     // Do this for background size calculation.\r
48051                     this._updateView(true);\r
48052 \r
48053                     // After updating view, inner shapes is built completely,\r
48054                     // and then background can be rendered.\r
48055                     this.renderBackground(thisGroup);\r
48056 \r
48057                     // Real update view\r
48058                     this._updateView();\r
48059 \r
48060                     this.positionGroup(thisGroup);\r
48061                 },\r
48062 \r
48063                 /**\r
48064                  * @private\r
48065                  */\r
48066                 _renderEndsText: function (group, dataRangeText, endsIndex) {\r
48067                     if (!dataRangeText) {\r
48068                         return;\r
48069                     }\r
48070 \r
48071                     // Compatible with ec2, text[0] map to high value, text[1] map low value.\r
48072                     var text = dataRangeText[1 - endsIndex];\r
48073                     text = text != null ? text + '' : '';\r
48074 \r
48075                     var visualMapModel = this.visualMapModel;\r
48076                     var textGap = visualMapModel.get('textGap');\r
48077                     var itemSize = visualMapModel.itemSize;\r
48078 \r
48079                     var barGroup = this._shapes.barGroup;\r
48080                     var position = this._applyTransform(\r
48081                         [\r
48082                             itemSize[0] / 2,\r
48083                             endsIndex === 0 ? -textGap : itemSize[1] + textGap\r
48084                         ],\r
48085                         barGroup\r
48086                     );\r
48087                     var align = this._applyTransform(\r
48088                         endsIndex === 0 ? 'bottom' : 'top',\r
48089                         barGroup\r
48090                     );\r
48091                     var orient = this._orient;\r
48092                     var textStyleModel = this.visualMapModel.textStyleModel;\r
48093 \r
48094                     this.group.add(new graphic.Text({\r
48095                         style: {\r
48096                             x: position[0],\r
48097                             y: position[1],\r
48098                             textVerticalAlign: orient === 'horizontal' ? 'middle' : align,\r
48099                             textAlign: orient === 'horizontal' ? align : 'center',\r
48100                             text: text,\r
48101                             textFont: textStyleModel.getFont(),\r
48102                             fill: textStyleModel.getTextColor()\r
48103                         }\r
48104                     }));\r
48105                 },\r
48106 \r
48107                 /**\r
48108                  * @private\r
48109                  */\r
48110                 _renderBar: function (targetGroup) {\r
48111                     var visualMapModel = this.visualMapModel;\r
48112                     var shapes = this._shapes;\r
48113                     var itemSize = visualMapModel.itemSize;\r
48114                     var orient = this._orient;\r
48115                     var useHandle = this._useHandle;\r
48116                     var itemAlign = helper.getItemAlign(visualMapModel, this.api, itemSize);\r
48117                     var barGroup = shapes.barGroup = this._createBarGroup(itemAlign);\r
48118 \r
48119                     // Bar\r
48120                     barGroup.add(shapes.outOfRange = createPolygon());\r
48121                     barGroup.add(shapes.inRange = createPolygon(\r
48122                         null,\r
48123                         zrUtil.bind(this._modifyHandle, this, 'all'),\r
48124                         useHandle ? 'move' : null\r
48125                     ));\r
48126 \r
48127                     var textRect = visualMapModel.textStyleModel.getTextRect('国');\r
48128                     var textSize = Math.max(textRect.width, textRect.height);\r
48129 \r
48130                     // Handle\r
48131                     if (useHandle) {\r
48132                         shapes.handleGroups = [];\r
48133                         shapes.handleThumbs = [];\r
48134                         shapes.handleLabels = [];\r
48135                         shapes.handleLabelPoints = [];\r
48136 \r
48137                         this._createHandle(barGroup, 0, itemSize, textSize, orient, itemAlign);\r
48138                         this._createHandle(barGroup, 1, itemSize, textSize, orient, itemAlign);\r
48139                     }\r
48140 \r
48141                     // Indicator\r
48142                     // FIXME\r
48143 \r
48144                     targetGroup.add(barGroup);\r
48145                 },\r
48146 \r
48147                 /**\r
48148                  * @private\r
48149                  */\r
48150                 _createHandle: function (barGroup, handleIndex, itemSize, textSize, orient) {\r
48151                     var handleGroup = new graphic.Group({position: [itemSize[0], 0]});\r
48152                     var handleThumb = createPolygon(\r
48153                         createHandlePoints(handleIndex, textSize),\r
48154                         zrUtil.bind(this._modifyHandle, this, handleIndex),\r
48155                         'move'\r
48156                     );\r
48157                     handleGroup.add(handleThumb);\r
48158 \r
48159                     // For text locating. Text is always horizontal layout\r
48160                     // but should not be effected by transform.\r
48161                     var handleLabelPoint = {\r
48162                         x: orient === 'horizontal'\r
48163                             ? textSize / 2\r
48164                             : textSize * 1.5,\r
48165                         y: orient === 'horizontal'\r
48166                             ? (handleIndex === 0 ? -(textSize * 1.5) : (textSize * 1.5))\r
48167                             : (handleIndex === 0 ? -textSize / 2 : textSize / 2)\r
48168                     };\r
48169 \r
48170                     var textStyleModel = this.visualMapModel.textStyleModel;\r
48171                     var handleLabel = new graphic.Text({\r
48172                         silent: true,\r
48173                         style: {\r
48174                             x: 0, y: 0, text: '',\r
48175                             textVerticalAlign: 'middle',\r
48176                             textFont: textStyleModel.getFont(),\r
48177                             fill: textStyleModel.getTextColor()\r
48178                         }\r
48179                     });\r
48180 \r
48181                     this.group.add(handleLabel); // Text do not transform\r
48182 \r
48183                     var shapes = this._shapes;\r
48184                     shapes.handleThumbs[handleIndex] = handleThumb;\r
48185                     shapes.handleGroups[handleIndex] = handleGroup;\r
48186                     shapes.handleLabelPoints[handleIndex] = handleLabelPoint;\r
48187                     shapes.handleLabels[handleIndex] = handleLabel;\r
48188 \r
48189                     barGroup.add(handleGroup);\r
48190                 },\r
48191 \r
48192                 /**\r
48193                  * @private\r
48194                  */\r
48195                 _modifyHandle: function (handleIndex, dx, dy) {\r
48196                     if (!this._useHandle) {\r
48197                         return;\r
48198                     }\r
48199 \r
48200                     // Transform dx, dy to bar coordination.\r
48201                     var vertex = this._applyTransform([dx, dy], this._shapes.barGroup, true);\r
48202                     this._updateInterval(handleIndex, vertex[1]);\r
48203 \r
48204                     this.api.dispatchAction({\r
48205                         type: 'selectDataRange',\r
48206                         from: this.uid,\r
48207                         visualMapId: this.visualMapModel.id,\r
48208                         selected: this._dataInterval.slice()\r
48209                     });\r
48210                 },\r
48211 \r
48212                 /**\r
48213                  * @private\r
48214                  */\r
48215                 _resetInterval: function () {\r
48216                     var visualMapModel = this.visualMapModel;\r
48217 \r
48218                     var dataInterval = this._dataInterval = visualMapModel.getSelected();\r
48219                     var dataExtent = visualMapModel.getExtent();\r
48220                     var sizeExtent = [0, visualMapModel.itemSize[1]];\r
48221 \r
48222                     this._handleEnds = [\r
48223                         linearMap(dataInterval[0], dataExtent, sizeExtent,true),\r
48224                         linearMap(dataInterval[1], dataExtent, sizeExtent,true)\r
48225                     ];\r
48226                 },\r
48227 \r
48228                 /**\r
48229                  * @private\r
48230                  * @param {(number|string)} handleIndex 0 or 1 or 'all'\r
48231                  * @param {number} dx\r
48232                  * @param {number} dy\r
48233                  */\r
48234                 _updateInterval: function (handleIndex, delta) {\r
48235                     delta = delta || 0;\r
48236                     var visualMapModel = this.visualMapModel;\r
48237                     var handleEnds = this._handleEnds;\r
48238 \r
48239                     sliderMove(\r
48240                         delta,\r
48241                         handleEnds,\r
48242                         [0, visualMapModel.itemSize[1]],\r
48243                         handleIndex === 'all' ? 'rigid' : 'push',\r
48244                         handleIndex\r
48245                     );\r
48246                     var dataExtent = visualMapModel.getExtent();\r
48247                     var sizeExtent = [0, visualMapModel.itemSize[1]];\r
48248                     // Update data interval.\r
48249                     this._dataInterval = [\r
48250                         linearMap(handleEnds[0], sizeExtent, dataExtent, true),\r
48251                         linearMap(handleEnds[1], sizeExtent, dataExtent, true)\r
48252                     ];\r
48253                 },\r
48254 \r
48255                 /**\r
48256                  * @private\r
48257                  */\r
48258                 _updateView: function (forSketch) {\r
48259                     var visualMapModel = this.visualMapModel;\r
48260                     var dataExtent = visualMapModel.getExtent();\r
48261                     var shapes = this._shapes;\r
48262                     var dataInterval = this._dataInterval;\r
48263 \r
48264                     var outOfRangeHandleEnds = [0, visualMapModel.itemSize[1]];\r
48265                     var inRangeHandleEnds = forSketch ? outOfRangeHandleEnds : this._handleEnds;\r
48266 \r
48267                     var visualInRange = this._createBarVisual(\r
48268                         dataInterval, dataExtent, inRangeHandleEnds, 'inRange'\r
48269                     );\r
48270                     var visualOutOfRange = this._createBarVisual(\r
48271                         dataExtent, dataExtent, outOfRangeHandleEnds, 'outOfRange'\r
48272                     );\r
48273 \r
48274                     shapes.inRange\r
48275                         .setStyle('fill', visualInRange.barColor)\r
48276                         .setShape('points', visualInRange.barPoints);\r
48277                     shapes.outOfRange\r
48278                         .setStyle('fill', visualOutOfRange.barColor)\r
48279                         .setShape('points', visualOutOfRange.barPoints);\r
48280 \r
48281                     this._useHandle && each([0, 1], function (handleIndex) {\r
48282 \r
48283                         shapes.handleThumbs[handleIndex].setStyle(\r
48284                             'fill', visualInRange.handlesColor[handleIndex]\r
48285                         );\r
48286 \r
48287                         shapes.handleLabels[handleIndex].setStyle({\r
48288                             text: visualMapModel.formatValueText(dataInterval[handleIndex]),\r
48289                             textAlign: this._applyTransform(\r
48290                                 this._orient === 'horizontal'\r
48291                                     ? (handleIndex === 0 ? 'bottom' : 'top')\r
48292                                     : 'left',\r
48293                                 shapes.barGroup\r
48294                             )\r
48295                         });\r
48296 \r
48297                     }, this);\r
48298 \r
48299                     this._updateHandlePosition(inRangeHandleEnds);\r
48300                 },\r
48301 \r
48302                 /**\r
48303                  * @private\r
48304                  */\r
48305                 _createBarVisual: function (dataInterval, dataExtent, handleEnds, forceState) {\r
48306                     var colorStops = this.getControllerVisual(dataInterval, forceState, 'color').color;\r
48307 \r
48308                     var symbolSizes = [\r
48309                         this.getControllerVisual(dataInterval[0], forceState, 'symbolSize').symbolSize,\r
48310                         this.getControllerVisual(dataInterval[1], forceState, 'symbolSize').symbolSize\r
48311                     ];\r
48312                     var barPoints = this._createBarPoints(handleEnds, symbolSizes);\r
48313 \r
48314                     return {\r
48315                         barColor: new LinearGradient(0, 0, 1, 1, colorStops),\r
48316                         barPoints: barPoints,\r
48317                         handlesColor: [\r
48318                             colorStops[0].color,\r
48319                             colorStops[colorStops.length - 1].color\r
48320                         ]\r
48321                     };\r
48322                 },\r
48323 \r
48324                 /**\r
48325                  * @private\r
48326                  */\r
48327                 _createBarPoints: function (handleEnds, symbolSizes) {\r
48328                     var itemSize = this.visualMapModel.itemSize;\r
48329 \r
48330                     return [\r
48331                         [itemSize[0] - symbolSizes[0], handleEnds[0]],\r
48332                         [itemSize[0], handleEnds[0]],\r
48333                         [itemSize[0], handleEnds[1]],\r
48334                         [itemSize[0] - symbolSizes[1], handleEnds[1]]\r
48335                     ];\r
48336                 },\r
48337 \r
48338                 /**\r
48339                  * @private\r
48340                  */\r
48341                 _createBarGroup: function (itemAlign) {\r
48342                     var orient = this._orient;\r
48343                     var inverse = this.visualMapModel.get('inverse');\r
48344 \r
48345                     return new graphic.Group(\r
48346                         (orient === 'horizontal' && !inverse)\r
48347                         ? {scale: itemAlign === 'bottom' ? [1, 1] : [-1, 1], rotation: Math.PI / 2}\r
48348                         : (orient === 'horizontal' && inverse)\r
48349                         ? {scale: itemAlign === 'bottom' ? [-1, 1] : [1, 1], rotation: -Math.PI / 2}\r
48350                         : (orient === 'vertical' && !inverse)\r
48351                         ? {scale: itemAlign === 'left' ? [1, -1] : [-1, -1]}\r
48352                         : {scale: itemAlign === 'left' ? [1, 1] : [-1, 1]}\r
48353                     );\r
48354                 },\r
48355 \r
48356                 /**\r
48357                  * @private\r
48358                  */\r
48359                 _updateHandlePosition: function (handleEnds) {\r
48360                     if (!this._useHandle) {\r
48361                         return;\r
48362                     }\r
48363 \r
48364                     var shapes = this._shapes;\r
48365 \r
48366                     each([0, 1], function (handleIndex) {\r
48367                         var handleGroup = shapes.handleGroups[handleIndex];\r
48368                         handleGroup.position[1] = handleEnds[handleIndex];\r
48369 \r
48370                         // Update handle label position.\r
48371                         var labelPoint = shapes.handleLabelPoints[handleIndex];\r
48372                         var textPoint = graphic.applyTransform(\r
48373                             [labelPoint.x, labelPoint.y],\r
48374                             graphic.getTransform(handleGroup, this.group)\r
48375                         );\r
48376 \r
48377                         shapes.handleLabels[handleIndex].setStyle({\r
48378                             x: textPoint[0], y: textPoint[1]\r
48379                         });\r
48380                     }, this);\r
48381                 },\r
48382 \r
48383                 /**\r
48384                  * @private\r
48385                  */\r
48386                 _applyTransform: function (vertex, element, inverse) {\r
48387                     var transform = graphic.getTransform(element, this.group);\r
48388 \r
48389                     return graphic[\r
48390                         zrUtil.isArray(vertex)\r
48391                             ? 'applyTransform' : 'transformDirection'\r
48392                     ](vertex, transform, inverse);\r
48393                 }\r
48394 \r
48395             });\r
48396 \r
48397             function createPolygon(points, onDrift, cursor) {\r
48398                 return new graphic.Polygon({\r
48399                     shape: {points: points},\r
48400                     draggable: !!onDrift,\r
48401                     cursor: cursor,\r
48402                     drift: onDrift\r
48403                 });\r
48404             }\r
48405 \r
48406             function createHandlePoints(handleIndex, textSize) {\r
48407                 return handleIndex === 0\r
48408                     ? [[0, 0], [textSize, 0], [textSize, -textSize]]\r
48409                     : [[0, 0], [textSize, 0], [textSize, textSize]];\r
48410             }\r
48411 \r
48412             module.exports = ContinuousVisualMapView;\r
48413 \r
48414 \r
48415 \r
48416 /***/ },\r
48417 /* 309 */\r
48418 /***/ function(module, exports, __webpack_require__) {\r
48419 \r
48420         \r
48421 \r
48422             var echarts = __webpack_require__(1);\r
48423             var zrUtil = __webpack_require__(3);\r
48424             var graphic = __webpack_require__(42);\r
48425             var formatUtil = __webpack_require__(6);\r
48426             var layout = __webpack_require__(21);\r
48427             var VisualMapping = __webpack_require__(187);\r
48428 \r
48429             module.exports = echarts.extendComponentView({\r
48430 \r
48431                 type: 'visualMap',\r
48432 \r
48433                 /**\r
48434                  * @readOnly\r
48435                  * @type {Object}\r
48436                  */\r
48437                 autoPositionValues: {left: 1, right: 1, top: 1, bottom: 1},\r
48438 \r
48439                 init: function (ecModel, api) {\r
48440                     /**\r
48441                      * @readOnly\r
48442                      * @type {module:echarts/model/Global}\r
48443                      */\r
48444                     this.ecModel = ecModel;\r
48445 \r
48446                     /**\r
48447                      * @readOnly\r
48448                      * @type {module:echarts/ExtensionAPI}\r
48449                      */\r
48450                     this.api = api;\r
48451 \r
48452                     /**\r
48453                      * @readOnly\r
48454                      * @type {module:echarts/component/visualMap/visualMapModel}\r
48455                      */\r
48456                     this.visualMapModel;\r
48457 \r
48458                     /**\r
48459                      * @private\r
48460                      * @type {Object}\r
48461                      */\r
48462                     this._updatableShapes = {};\r
48463                 },\r
48464 \r
48465                 /**\r
48466                  * @protected\r
48467                  */\r
48468                 render: function (visualMapModel, ecModel, api, payload) {\r
48469                     this.visualMapModel = visualMapModel;\r
48470 \r
48471                     if (visualMapModel.get('show') === false) {\r
48472                         this.group.removeAll();\r
48473                         return;\r
48474                     }\r
48475 \r
48476                     this.doRender.apply(this, arguments);\r
48477                 },\r
48478 \r
48479                 /**\r
48480                  * @protected\r
48481                  */\r
48482                 renderBackground: function (group) {\r
48483                     var visualMapModel = this.visualMapModel;\r
48484                     var padding = formatUtil.normalizeCssArray(visualMapModel.get('padding') || 0);\r
48485                     var rect = group.getBoundingRect();\r
48486 \r
48487                     group.add(new graphic.Rect({\r
48488                         z2: -1, // Lay background rect on the lowest layer.\r
48489                         silent: true,\r
48490                         shape: {\r
48491                             x: rect.x - padding[3],\r
48492                             y: rect.y - padding[0],\r
48493                             width: rect.width + padding[3] + padding[1],\r
48494                             height: rect.height + padding[0] + padding[2]\r
48495                         },\r
48496                         style: {\r
48497                             fill: visualMapModel.get('backgroundColor'),\r
48498                             stroke: visualMapModel.get('borderColor'),\r
48499                             lineWidth: visualMapModel.get('borderWidth')\r
48500                         }\r
48501                     }));\r
48502                 },\r
48503 \r
48504                 /**\r
48505                  * @protected\r
48506                  * @param {(number|Array)} targetValue\r
48507                  * @param {string=} forceState Specify state, instead of using getValueState method.\r
48508                  * @param {string=} visualCluster Specify visual type, defualt all available visualClusters.\r
48509                  */\r
48510                 getControllerVisual: function (targetValue, forceState, visualCluster) {\r
48511                     var visualMapModel = this.visualMapModel;\r
48512                     var targetIsArray = zrUtil.isArray(targetValue);\r
48513 \r
48514                     // targetValue is array when caculate gradient color,\r
48515                     // where forceState is required.\r
48516                     if (targetIsArray && (!forceState || visualCluster !== 'color')) {\r
48517                         throw new Error(targetValue);\r
48518                     }\r
48519 \r
48520                     var mappings = visualMapModel.controllerVisuals[\r
48521                         forceState || visualMapModel.getValueState(targetValue)\r
48522                     ];\r
48523                     var defaultColor = visualMapModel.get('contentColor');\r
48524                     var visualObj = {\r
48525                         symbol: visualMapModel.get('itemSymbol'),\r
48526                         color: targetIsArray\r
48527                             ? [{color: defaultColor, offset: 0}, {color: defaultColor, offset: 1}]\r
48528                             : defaultColor\r
48529                     };\r
48530 \r
48531                     function getter(key) {\r
48532                         return visualObj[key];\r
48533                     }\r
48534 \r
48535                     function setter(key, value) {\r
48536                         visualObj[key] = value;\r
48537                     }\r
48538 \r
48539                     var visualTypes = VisualMapping.prepareVisualTypes(mappings);\r
48540 \r
48541                     zrUtil.each(visualTypes, function (type) {\r
48542                         var visualMapping = mappings[type];\r
48543                         if (!visualCluster || VisualMapping.isInVisualCluster(type, visualCluster)) {\r
48544                             visualMapping && visualMapping.applyVisual(targetValue, getter, setter);\r
48545                         }\r
48546                     });\r
48547 \r
48548                     return visualObj;\r
48549                 },\r
48550 \r
48551                 /**\r
48552                  * @protected\r
48553                  */\r
48554                 positionGroup: function (group) {\r
48555                     var model = this.visualMapModel;\r
48556                     var api = this.api;\r
48557 \r
48558                     layout.positionGroup(\r
48559                         group,\r
48560                         model.getBoxLayoutParams(),\r
48561                         {width: api.getWidth(), height: api.getHeight()}\r
48562                     );\r
48563                 },\r
48564 \r
48565                 /**\r
48566                  * @protected\r
48567                  * @abstract\r
48568                  */\r
48569                 doRender: zrUtil.noop\r
48570 \r
48571             });\r
48572 \r
48573 \r
48574 /***/ },\r
48575 /* 310 */\r
48576 /***/ function(module, exports, __webpack_require__) {\r
48577 \r
48578         \r
48579 \r
48580             var layout = __webpack_require__(21);\r
48581 \r
48582             var helper = {\r
48583 \r
48584                 /**\r
48585                  * @param {module:echarts/component/visualMap/VisualMapModel} visualMapModel\\r
48586                  * @param {module:echarts/ExtensionAPI} api\r
48587                  * @param {Array.<number>} itemSize always [short, long]\r
48588                  * @return {string} 'left' or 'right' or 'top' or 'bottom'\r
48589                  */\r
48590                 getItemAlign: function (visualMapModel, api, itemSize) {\r
48591                     var modelOption = visualMapModel.option;\r
48592                     var itemAlign = modelOption.align;\r
48593 \r
48594                     if (itemAlign != null && itemAlign !== 'auto') {\r
48595                         return itemAlign;\r
48596                     }\r
48597 \r
48598                     // Auto decision align.\r
48599                     var ecSize = {width: api.getWidth(), height: api.getHeight()};\r
48600                     var realIndex = modelOption.orient === 'horizontal' ? 1 : 0;\r
48601 \r
48602                     var paramsSet = [\r
48603                         ['left', 'right', 'width'],\r
48604                         ['top', 'bottom', 'height']\r
48605                     ];\r
48606                     var reals = paramsSet[realIndex];\r
48607                     var fakeValue = [0, null, 10];\r
48608 \r
48609                     var layoutInput = {};\r
48610                     for (var i = 0; i < 3; i++) {\r
48611                         layoutInput[paramsSet[1 - realIndex][i]] = fakeValue[i];\r
48612                         layoutInput[reals[i]] = i === 2 ? itemSize[0] : modelOption[reals[i]];\r
48613                     }\r
48614 \r
48615                     var rParam = [['x', 'width', 3], ['y', 'height', 0]][realIndex];\r
48616                     var rect = layout.getLayoutRect(layoutInput, ecSize, modelOption.padding);\r
48617 \r
48618                     return reals[\r
48619                         (rect.margin[rParam[2]] || 0) + rect[rParam[0]] + rect[rParam[1]] * 0.5\r
48620                             < ecSize[rParam[1]] * 0.5 ? 0 : 1\r
48621                     ];\r
48622                 }\r
48623             };\r
48624 \r
48625             module.exports = helper;\r
48626 \r
48627 \r
48628 \r
48629 /***/ },\r
48630 /* 311 */\r
48631 /***/ function(module, exports, __webpack_require__) {\r
48632 \r
48633         /**\r
48634          * @file Data range action\r
48635          */\r
48636 \r
48637 \r
48638             var echarts = __webpack_require__(1);\r
48639 \r
48640             var actionInfo = {\r
48641                 type: 'selectDataRange',\r
48642                 event: 'dataRangeSelected',\r
48643                 // FIXME use updateView appears wrong\r
48644                 update: 'update'\r
48645             };\r
48646 \r
48647             echarts.registerAction(actionInfo, function (payload, ecModel) {\r
48648 \r
48649                 ecModel.eachComponent({mainType: 'visualMap', query: payload}, function (model) {\r
48650                     model.setSelected(payload.selected);\r
48651                 });\r
48652 \r
48653             });\r
48654 \r
48655 \r
48656 \r
48657 /***/ },\r
48658 /* 312 */\r
48659 /***/ function(module, exports, __webpack_require__) {\r
48660 \r
48661         /**\r
48662          * DataZoom component entry\r
48663          */\r
48664 \r
48665 \r
48666             __webpack_require__(1).registerPreprocessor(\r
48667                 __webpack_require__(302)\r
48668             );\r
48669 \r
48670             __webpack_require__(303);\r
48671             __webpack_require__(304);\r
48672             __webpack_require__(313);\r
48673             __webpack_require__(314);\r
48674             __webpack_require__(311);\r
48675 \r
48676 \r
48677 \r
48678 /***/ },\r
48679 /* 313 */\r
48680 /***/ function(module, exports, __webpack_require__) {\r
48681 \r
48682         \r
48683 \r
48684             var VisualMapModel = __webpack_require__(306);\r
48685             var zrUtil = __webpack_require__(3);\r
48686             var VisualMapping = __webpack_require__(187);\r
48687 \r
48688             var PiecewiseModel = VisualMapModel.extend({\r
48689 \r
48690                 type: 'visualMap.piecewise',\r
48691 \r
48692                 /**\r
48693                  * Order Rule:\r
48694                  *\r
48695                  * option.categories / option.pieces / option.text / option.selected:\r
48696                  *     If !option.inverse,\r
48697                  *     Order when vertical: ['top', ..., 'bottom'].\r
48698                  *     Order when horizontal: ['left', ..., 'right'].\r
48699                  *     If option.inverse, the meaning of\r
48700                  *     the order should be reversed.\r
48701                  *\r
48702                  * this._pieceList:\r
48703                  *     The order is always [low, ..., high].\r
48704                  *\r
48705                  * Mapping from location to low-high:\r
48706                  *     If !option.inverse\r
48707                  *     When vertical, top is high.\r
48708                  *     When horizontal, right is high.\r
48709                  *     If option.inverse, reverse.\r
48710                  */\r
48711 \r
48712                 /**\r
48713                  * @protected\r
48714                  */\r
48715                 defaultOption: {\r
48716                     selected: null,             // Object. If not specified, means selected.\r
48717                                                 // When pieces and splitNumber: {'0': true, '5': true}\r
48718                                                 // When categories: {'cate1': false, 'cate3': true}\r
48719                                                 // When selected === false, means all unselected.\r
48720                     align: 'auto',              // 'auto', 'left', 'right'\r
48721                     itemWidth: 20,              // 值域图形宽度\r
48722                     itemHeight: 14,             // 值域图形高度\r
48723                     itemSymbol: 'roundRect',\r
48724                     pieceList: null,            // 值顺序:由高到低, item can be:\r
48725                                                 // {min, max, value, color, colorSaturation, colorAlpha, symbol, symbolSize}\r
48726                     categories: null,           // 描述 category 数据。如:['some1', 'some2', 'some3'],设置后,min max失效。\r
48727                     splitNumber: 5,             // 分割段数,默认为5,为0时为线性渐变 (continous)\r
48728                     selectedMode: 'multiple',\r
48729                     itemGap: 10                 // 各个item之间的间隔,单位px,默认为10,\r
48730                                                 // 横向布局时为水平间隔,纵向布局时为纵向间隔\r
48731                 },\r
48732 \r
48733                 /**\r
48734                  * @override\r
48735                  */\r
48736                 doMergeOption: function (newOption, isInit) {\r
48737                     PiecewiseModel.superApply(this, 'doMergeOption', arguments);\r
48738 \r
48739                     /**\r
48740                      * The order is always [low, ..., high].\r
48741                      * [{text: string, interval: Array.<number>}, ...]\r
48742                      * @private\r
48743                      * @type {Array.<Object>}\r
48744                      */\r
48745                     this._pieceList = [];\r
48746 \r
48747                     this.resetTargetSeries(newOption, isInit);\r
48748                     this.resetExtent();\r
48749 \r
48750                     /**\r
48751                      * 'pieces', 'categories', 'splitNumber'\r
48752                      * @type {string}\r
48753                      */\r
48754                     var mode = this._mode = this._decideMode();\r
48755 \r
48756                     resetMethods[this._mode].call(this);\r
48757 \r
48758                     this._resetSelected(newOption, isInit);\r
48759 \r
48760                     var categories = this.option.categories;\r
48761                     this.resetVisual(function (mappingOption, state) {\r
48762                         if (mode === 'categories') {\r
48763                             mappingOption.mappingMethod = 'category';\r
48764                             mappingOption.categories = zrUtil.clone(categories);\r
48765                         }\r
48766                         else {\r
48767                             mappingOption.mappingMethod = 'piecewise';\r
48768                             mappingOption.pieceList = zrUtil.map(this._pieceList, function (piece) {\r
48769                                 var piece = zrUtil.clone(piece);\r
48770                                 if (state !== 'inRange') {\r
48771                                     piece.visual = null;\r
48772                                 }\r
48773                                 return piece;\r
48774                             });\r
48775                         }\r
48776                     });\r
48777                 },\r
48778 \r
48779                 _resetSelected: function (newOption, isInit) {\r
48780                     var thisOption = this.option;\r
48781                     var pieceList = this._pieceList;\r
48782 \r
48783                     // Selected do not merge but all override.\r
48784                     var selected = (isInit ? thisOption : newOption).selected || {};\r
48785                     thisOption.selected = selected;\r
48786 \r
48787                     // Consider 'not specified' means true.\r
48788                     zrUtil.each(pieceList, function (piece, index) {\r
48789                         var key = this.getSelectedMapKey(piece);\r
48790                         if (!(key in selected)) {\r
48791                             selected[key] = true;\r
48792                         }\r
48793                     }, this);\r
48794 \r
48795                     if (thisOption.selectedMode === 'single') {\r
48796                         // Ensure there is only one selected.\r
48797                         var hasSel = false;\r
48798 \r
48799                         zrUtil.each(pieceList, function (piece, index) {\r
48800                             var key = this.getSelectedMapKey(piece);\r
48801                             if (selected[key]) {\r
48802                                 hasSel\r
48803                                     ? (selected[key] = false)\r
48804                                     : (hasSel = true);\r
48805                             }\r
48806                         }, this);\r
48807                     }\r
48808                     // thisOption.selectedMode === 'multiple', default: all selected.\r
48809                 },\r
48810 \r
48811                 /**\r
48812                  * @public\r
48813                  */\r
48814                 getSelectedMapKey: function (piece) {\r
48815                     return this._mode === 'categories'\r
48816                         ? piece.value + '' : piece.index + '';\r
48817                 },\r
48818 \r
48819                 /**\r
48820                  * @public\r
48821                  */\r
48822                 getPieceList: function () {\r
48823                     return this._pieceList;\r
48824                 },\r
48825 \r
48826                 /**\r
48827                  * @private\r
48828                  * @return {string}\r
48829                  */\r
48830                 _decideMode: function () {\r
48831                     var option = this.option;\r
48832 \r
48833                     return option.pieces && option.pieces.length > 0\r
48834                         ? 'pieces'\r
48835                         : this.option.categories\r
48836                         ? 'categories'\r
48837                         : 'splitNumber';\r
48838                 },\r
48839 \r
48840                 /**\r
48841                  * @public\r
48842                  * @override\r
48843                  */\r
48844                 setSelected: function (selected) {\r
48845                     this.option.selected = zrUtil.clone(selected);\r
48846                 },\r
48847 \r
48848                 /**\r
48849                  * @public\r
48850                  * @override\r
48851                  */\r
48852                 getValueState: function (value) {\r
48853                     var pieceList = this._pieceList;\r
48854                     var index = VisualMapping.findPieceIndex(value, pieceList);\r
48855 \r
48856                     return index != null\r
48857                         ? (this.option.selected[this.getSelectedMapKey(pieceList[index])]\r
48858                             ? 'inRange' : 'outOfRange'\r
48859                         )\r
48860                         : 'outOfRange';\r
48861                 }\r
48862 \r
48863             });\r
48864 \r
48865             /**\r
48866              * Key is this._mode\r
48867              * @type {Object}\r
48868              * @this {module:echarts/component/viusalMap/PiecewiseMode}\r
48869              */\r
48870             var resetMethods = {\r
48871 \r
48872                 splitNumber: function () {\r
48873                     var thisOption = this.option;\r
48874                     var precision = thisOption.precision;\r
48875                     var dataExtent = this.getExtent();\r
48876                     var splitNumber = thisOption.splitNumber;\r
48877                     splitNumber = Math.max(parseInt(splitNumber, 10), 1);\r
48878                     thisOption.splitNumber = splitNumber;\r
48879 \r
48880                     var splitStep = (dataExtent[1] - dataExtent[0]) / splitNumber;\r
48881                     // Precision auto-adaption\r
48882                     while (+splitStep.toFixed(precision) !== splitStep && precision < 5) {\r
48883                         precision++;\r
48884                     }\r
48885                     thisOption.precision = precision;\r
48886                     splitStep = +splitStep.toFixed(precision);\r
48887 \r
48888                     for (var i = 0, curr = dataExtent[0]; i < splitNumber; i++, curr += splitStep) {\r
48889                         var max = i === splitNumber - 1 ? dataExtent[1] : (curr + splitStep);\r
48890 \r
48891                         this._pieceList.push({\r
48892                             text: this.formatValueText([curr, max]),\r
48893                             index: i,\r
48894                             interval: [curr, max]\r
48895                         });\r
48896                     }\r
48897                 },\r
48898 \r
48899                 categories: function () {\r
48900                     var thisOption = this.option;\r
48901                     zrUtil.each(thisOption.categories, function (cate) {\r
48902                         // FIXME category模式也使用pieceList,但在visualMapping中不是使用pieceList。\r
48903                         // 是否改一致。\r
48904                         this._pieceList.push({\r
48905                             text: this.formatValueText(cate, true),\r
48906                             value: cate\r
48907                         });\r
48908                     }, this);\r
48909 \r
48910                     // See "Order Rule".\r
48911                     normalizeReverse(thisOption, this._pieceList);\r
48912                 },\r
48913 \r
48914                 pieces: function () {\r
48915                     var thisOption = this.option;\r
48916                     zrUtil.each(thisOption.pieces, function (pieceListItem, index) {\r
48917 \r
48918                         if (!zrUtil.isObject(pieceListItem)) {\r
48919                             pieceListItem = {value: pieceListItem};\r
48920                         }\r
48921 \r
48922                         var item = {text: '', index: index};\r
48923                         var hasLabel;\r
48924 \r
48925                         if (pieceListItem.label != null) {\r
48926                             item.text = pieceListItem.label;\r
48927                             hasLabel = true;\r
48928                         }\r
48929 \r
48930                         if (pieceListItem.hasOwnProperty('value')) {\r
48931                             item.value = pieceListItem.value;\r
48932 \r
48933                             if (!hasLabel) {\r
48934                                 item.text = this.formatValueText(item.value);\r
48935                             }\r
48936                         }\r
48937                         else {\r
48938                             var min = pieceListItem.min;\r
48939                             var max = pieceListItem.max;\r
48940                             min == null && (min = -Infinity);\r
48941                             max == null && (max = Infinity);\r
48942                             if (min === max) {\r
48943                                 // Consider: [{min: 5, max: 5, visual: {...}}, {min: 0, max: 5}],\r
48944                                 // we use value to lift the priority when min === max\r
48945                                 item.value = min;\r
48946                             }\r
48947                             item.interval = [min, max];\r
48948 \r
48949                             if (!hasLabel) {\r
48950                                 item.text = this.formatValueText([min, max]);\r
48951                             }\r
48952                         }\r
48953 \r
48954                         item.visual = VisualMapping.retrieveVisuals(pieceListItem);\r
48955 \r
48956                         this._pieceList.push(item);\r
48957 \r
48958                     }, this);\r
48959 \r
48960                     // See "Order Rule".\r
48961                     normalizeReverse(thisOption, this._pieceList);\r
48962                 }\r
48963             };\r
48964 \r
48965             function normalizeReverse(thisOption, arr) {\r
48966                 var inverse = thisOption.inverse;\r
48967                 if (thisOption.orient === 'vertical' ? !inverse : inverse) {\r
48968                      arr.reverse();\r
48969                 }\r
48970             }\r
48971 \r
48972             module.exports = PiecewiseModel;\r
48973 \r
48974 \r
48975 \r
48976 /***/ },\r
48977 /* 314 */\r
48978 /***/ function(module, exports, __webpack_require__) {\r
48979 \r
48980         \r
48981 \r
48982             var VisualMapView = __webpack_require__(309);\r
48983             var zrUtil = __webpack_require__(3);\r
48984             var graphic = __webpack_require__(42);\r
48985             var symbolCreators = __webpack_require__(100);\r
48986             var layout = __webpack_require__(21);\r
48987             var helper = __webpack_require__(310);\r
48988 \r
48989             var PiecewiseVisualMapView = VisualMapView.extend({\r
48990 \r
48991                 type: 'visualMap.piecewise',\r
48992 \r
48993                 /**\r
48994                  * @protected\r
48995                  * @override\r
48996                  */\r
48997                 doRender: function () {\r
48998                     var thisGroup = this.group;\r
48999 \r
49000                     thisGroup.removeAll();\r
49001 \r
49002                     var visualMapModel = this.visualMapModel;\r
49003                     var textGap = visualMapModel.get('textGap');\r
49004                     var textStyleModel = visualMapModel.textStyleModel;\r
49005                     var textFont = textStyleModel.getFont();\r
49006                     var textFill = textStyleModel.getTextColor();\r
49007                     var itemAlign = this._getItemAlign();\r
49008                     var itemSize = visualMapModel.itemSize;\r
49009 \r
49010                     var viewData = this._getViewData();\r
49011                     var showLabel = !viewData.endsText;\r
49012                     var showEndsText = !showLabel;\r
49013 \r
49014                     showEndsText && this._renderEndsText(thisGroup, viewData.endsText[0], itemSize);\r
49015 \r
49016                     zrUtil.each(viewData.pieceList, renderItem, this);\r
49017 \r
49018                     showEndsText && this._renderEndsText(thisGroup, viewData.endsText[1], itemSize);\r
49019 \r
49020                     layout.box(\r
49021                         visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap')\r
49022                     );\r
49023 \r
49024                     this.renderBackground(thisGroup);\r
49025 \r
49026                     this.positionGroup(thisGroup);\r
49027 \r
49028                     function renderItem(item) {\r
49029                         var itemGroup = new graphic.Group();\r
49030                         itemGroup.onclick = zrUtil.bind(this._onItemClick, this, item.piece);\r
49031 \r
49032                         this._createItemSymbol(itemGroup, item.piece, [0, 0, itemSize[0], itemSize[1]]);\r
49033 \r
49034                         if (showLabel) {\r
49035                             itemGroup.add(new graphic.Text({\r
49036                                 style: {\r
49037                                     x: itemAlign === 'right' ? -textGap : itemSize[0] + textGap,\r
49038                                     y: itemSize[1] / 2,\r
49039                                     text: item.piece.text,\r
49040                                     textVerticalAlign: 'middle',\r
49041                                     textAlign: itemAlign,\r
49042                                     textFont: textFont,\r
49043                                     fill: textFill\r
49044                                 }\r
49045                             }));\r
49046                         }\r
49047 \r
49048                         thisGroup.add(itemGroup);\r
49049                     }\r
49050                 },\r
49051 \r
49052                 /**\r
49053                  * @private\r
49054                  */\r
49055                 _getItemAlign: function () {\r
49056                     var visualMapModel = this.visualMapModel;\r
49057                     var modelOption = visualMapModel.option;\r
49058                     if (modelOption.orient === 'vertical') {\r
49059                         return helper.getItemAlign(\r
49060                             visualMapModel, this.api, visualMapModel.itemSize\r
49061                         );\r
49062                     }\r
49063                     else { // horizontal, most case left unless specifying right.\r
49064                         var align = modelOption.align;\r
49065                         if (!align || align === 'auto') {\r
49066                             align = 'left';\r
49067                         }\r
49068                         return align;\r
49069                     }\r
49070                 },\r
49071 \r
49072                 /**\r
49073                  * @private\r
49074                  */\r
49075                 _renderEndsText: function (group, text, itemSize) {\r
49076                     if (!text) {\r
49077                         return;\r
49078                     }\r
49079                     var itemGroup = new graphic.Group();\r
49080                     var textStyleModel = this.visualMapModel.textStyleModel;\r
49081                     itemGroup.add(new graphic.Text({\r
49082                         style: {\r
49083                             x: itemSize[0] / 2,\r
49084                             y: itemSize[1] / 2,\r
49085                             textVerticalAlign: 'middle',\r
49086                             textAlign: 'center',\r
49087                             text: text,\r
49088                             textFont: textStyleModel.getFont(),\r
49089                             fill: textStyleModel.getTextColor()\r
49090                         }\r
49091                     }));\r
49092 \r
49093                     group.add(itemGroup);\r
49094                 },\r
49095 \r
49096                 /**\r
49097                  * @private\r
49098                  * @return {Object} {peiceList, endsText} The order is the same as screen pixel order.\r
49099                  */\r
49100                 _getViewData: function () {\r
49101                     var visualMapModel = this.visualMapModel;\r
49102 \r
49103                     var pieceList = zrUtil.map(visualMapModel.getPieceList(), function (piece, index) {\r
49104                         return {piece: piece, index: index};\r
49105                     });\r
49106                     var endsText = visualMapModel.get('text');\r
49107 \r
49108                     // Consider orient and inverse.\r
49109                     var orient = visualMapModel.get('orient');\r
49110                     var inverse = visualMapModel.get('inverse');\r
49111 \r
49112                     // Order of pieceList is always [low, ..., high]\r
49113                     if (orient === 'horizontal' ? inverse : !inverse) {\r
49114                         pieceList.reverse();\r
49115                     }\r
49116                     // Origin order of endsText is [high, low]\r
49117                     else if (endsText) {\r
49118                         endsText = endsText.slice().reverse();\r
49119                     }\r
49120 \r
49121                     return {pieceList: pieceList, endsText: endsText};\r
49122                 },\r
49123 \r
49124                 /**\r
49125                  * @private\r
49126                  */\r
49127                 _createItemSymbol: function (group, piece, shapeParam) {\r
49128                     var representValue;\r
49129                     if (this.visualMapModel.isCategory()) {\r
49130                         representValue = piece.value;\r
49131                     }\r
49132                     else {\r
49133                         if (piece.value != null) {\r
49134                             representValue = piece.value;\r
49135                         }\r
49136                         else {\r
49137                             var pieceInterval = piece.interval || [];\r
49138                             representValue = (pieceInterval[0] + pieceInterval[1]) / 2;\r
49139                         }\r
49140                     }\r
49141 \r
49142                     var visualObj = this.getControllerVisual(representValue);\r
49143 \r
49144                     group.add(symbolCreators.createSymbol(\r
49145                         visualObj.symbol,\r
49146                         shapeParam[0], shapeParam[1], shapeParam[2], shapeParam[3],\r
49147                         visualObj.color\r
49148                     ));\r
49149                 },\r
49150 \r
49151                 /**\r
49152                  * @private\r
49153                  */\r
49154                 _onItemClick: function (piece) {\r
49155                     var visualMapModel = this.visualMapModel;\r
49156                     var option = visualMapModel.option;\r
49157                     var selected = zrUtil.clone(option.selected);\r
49158                     var newKey = visualMapModel.getSelectedMapKey(piece);\r
49159 \r
49160                     if (option.selectedMode === 'single') {\r
49161                         selected[newKey] = true;\r
49162                         zrUtil.each(selected, function (o, key) {\r
49163                             selected[key] = key === newKey;\r
49164                         });\r
49165                     }\r
49166                     else {\r
49167                         selected[newKey] = !selected[newKey];\r
49168                     }\r
49169 \r
49170                     this.api.dispatchAction({\r
49171                         type: 'selectDataRange',\r
49172                         from: this.uid,\r
49173                         visualMapId: this.visualMapModel.id,\r
49174                         selected: selected\r
49175                     });\r
49176                 }\r
49177             });\r
49178 \r
49179             module.exports = PiecewiseVisualMapView;\r
49180 \r
49181 \r
49182 \r
49183 /***/ },\r
49184 /* 315 */\r
49185 /***/ function(module, exports, __webpack_require__) {\r
49186 \r
49187         // HINT Markpoint can't be used too much\r
49188 \r
49189 \r
49190             __webpack_require__(316);\r
49191             __webpack_require__(317);\r
49192 \r
49193             __webpack_require__(1).registerPreprocessor(function (opt) {\r
49194                 // Make sure markPoint component is enabled\r
49195                 opt.markPoint = opt.markPoint || {};\r
49196             });\r
49197 \r
49198 \r
49199 /***/ },\r
49200 /* 316 */\r
49201 /***/ function(module, exports, __webpack_require__) {\r
49202 \r
49203         \r
49204             // Default enable markPoint\r
49205             // var globalDefault = require('../../model/globalDefault');\r
49206             var modelUtil = __webpack_require__(5);\r
49207             // // Force to load markPoint component\r
49208             // globalDefault.markPoint = {};\r
49209 \r
49210             var MarkPointModel = __webpack_require__(1).extendComponentModel({\r
49211 \r
49212                 type: 'markPoint',\r
49213 \r
49214                 dependencies: ['series', 'grid', 'polar'],\r
49215                 /**\r
49216                  * @overrite\r
49217                  */\r
49218                 init: function (option, parentModel, ecModel, extraOpt) {\r
49219                     this.mergeDefaultAndTheme(option, ecModel);\r
49220                     this.mergeOption(option, ecModel, extraOpt.createdBySelf, true);\r
49221                 },\r
49222 \r
49223                 mergeOption: function (newOpt, ecModel, createdBySelf, isInit) {\r
49224                     if (!createdBySelf) {\r
49225                         ecModel.eachSeries(function (seriesModel) {\r
49226                             var markPointOpt = seriesModel.get('markPoint');\r
49227                             var mpModel = seriesModel.markPointModel;\r
49228                             if (!markPointOpt || !markPointOpt.data) {\r
49229                                 seriesModel.markPointModel = null;\r
49230                                 return;\r
49231                             }\r
49232                             if (!mpModel) {\r
49233                                 if (isInit) {\r
49234                                     // Default label emphasis `position` and `show`\r
49235                                     modelUtil.defaultEmphasis(\r
49236                                         markPointOpt.label,\r
49237                                         ['position', 'show', 'textStyle', 'distance', 'formatter']\r
49238                                     );\r
49239                                 }\r
49240                                 var opt = {\r
49241                                     // Use the same series index and name\r
49242                                     seriesIndex: seriesModel.seriesIndex,\r
49243                                     name: seriesModel.name,\r
49244                                     createdBySelf: true\r
49245                                 };\r
49246                                 mpModel = new MarkPointModel(\r
49247                                     markPointOpt, this, ecModel, opt\r
49248                                 );\r
49249                             }\r
49250                             else {\r
49251                                 mpModel.mergeOption(markPointOpt, ecModel, true);\r
49252                             }\r
49253                             seriesModel.markPointModel = mpModel;\r
49254                         }, this);\r
49255                     }\r
49256                 },\r
49257 \r
49258                 defaultOption: {\r
49259                     zlevel: 0,\r
49260                     z: 5,\r
49261                     symbol: 'pin',         // 标注类型\r
49262                     symbolSize: 50,  // 标注大小\r
49263                     // symbolRotate: null, // 标注旋转控制\r
49264                     tooltip: {\r
49265                         trigger: 'item'\r
49266                     },\r
49267                     label: {\r
49268                         normal: {\r
49269                             show: true,\r
49270                             // 标签文本格式器,同Tooltip.formatter,不支持回调\r
49271                             // formatter: null,\r
49272                             // 可选为'left'|'right'|'top'|'bottom'\r
49273                             position: 'inside'\r
49274                             // 默认使用全局文本样式,详见TEXTSTYLE\r
49275                             // textStyle: null\r
49276                         },\r
49277                         emphasis: {\r
49278                             show: true\r
49279                             // 标签文本格式器,同Tooltip.formatter,不支持回调\r
49280                             // formatter: null,\r
49281                             // position: 'inside'  // 'left'|'right'|'top'|'bottom'\r
49282                             // textStyle: null     // 默认使用全局文本样式,详见TEXTSTYLE\r
49283                         }\r
49284                     },\r
49285                     itemStyle: {\r
49286                         normal: {\r
49287                             // color: 各异,\r
49288                             // 标注边线颜色,优先于color\r
49289                             // borderColor: 各异,\r
49290                             // 标注边线线宽,单位px,默认为1\r
49291                             borderWidth: 2\r
49292                         },\r
49293                         emphasis: {\r
49294                             // color: 各异\r
49295                         }\r
49296                     }\r
49297                 }\r
49298             });\r
49299 \r
49300             module.exports = MarkPointModel;\r
49301 \r
49302 \r
49303 /***/ },\r
49304 /* 317 */\r
49305 /***/ function(module, exports, __webpack_require__) {\r
49306 \r
49307         \r
49308 \r
49309             var SymbolDraw = __webpack_require__(98);\r
49310             var zrUtil = __webpack_require__(3);\r
49311             var formatUtil = __webpack_require__(6);\r
49312             var modelUtil = __webpack_require__(5);\r
49313             var numberUtil = __webpack_require__(7);\r
49314 \r
49315             var addCommas = formatUtil.addCommas;\r
49316             var encodeHTML = formatUtil.encodeHTML;\r
49317 \r
49318             var List = __webpack_require__(94);\r
49319 \r
49320             var markerHelper = __webpack_require__(318);\r
49321 \r
49322             function updateMarkerLayout(mpData, seriesModel, api) {\r
49323                 var coordSys = seriesModel.coordinateSystem;\r
49324                 mpData.each(function (idx) {\r
49325                     var itemModel = mpData.getItemModel(idx);\r
49326                     var point;\r
49327                     var xPx = itemModel.getShallow('x');\r
49328                     var yPx = itemModel.getShallow('y');\r
49329                     if (xPx != null && yPx != null) {\r
49330                         point = [\r
49331                             numberUtil.parsePercent(xPx, api.getWidth()),\r
49332                             numberUtil.parsePercent(yPx, api.getHeight())\r
49333                         ];\r
49334                     }\r
49335                     // Chart like bar may have there own marker positioning logic\r
49336                     else if (seriesModel.getMarkerPosition) {\r
49337                         // Use the getMarkerPoisition\r
49338                         point = seriesModel.getMarkerPosition(\r
49339                             mpData.getValues(mpData.dimensions, idx)\r
49340                         );\r
49341                     }\r
49342                     else if (coordSys) {\r
49343                         var x = mpData.get(coordSys.dimensions[0], idx);\r
49344                         var y = mpData.get(coordSys.dimensions[1], idx);\r
49345                         point = coordSys.dataToPoint([x, y]);\r
49346                     }\r
49347 \r
49348                     mpData.setItemLayout(idx, point);\r
49349                 });\r
49350             }\r
49351 \r
49352             // FIXME\r
49353             var markPointFormatMixin = {\r
49354                 getRawDataArray: function () {\r
49355                     return this.option.data;\r
49356                 },\r
49357 \r
49358                 formatTooltip: function (dataIndex) {\r
49359                     var data = this.getData();\r
49360                     var value = this.getRawValue(dataIndex);\r
49361                     var formattedValue = zrUtil.isArray(value)\r
49362                         ? zrUtil.map(value, addCommas).join(', ') : addCommas(value);\r
49363                     var name = data.getName(dataIndex);\r
49364                     return this.name + '<br />'\r
49365                         + ((name ? encodeHTML(name) + ' : ' : '') + formattedValue);\r
49366                 },\r
49367 \r
49368                 getData: function () {\r
49369                     return this._data;\r
49370                 },\r
49371 \r
49372                 setData: function (data) {\r
49373                     this._data = data;\r
49374                 }\r
49375             };\r
49376 \r
49377             zrUtil.defaults(markPointFormatMixin, modelUtil.dataFormatMixin);\r
49378 \r
49379             __webpack_require__(1).extendComponentView({\r
49380 \r
49381                 type: 'markPoint',\r
49382 \r
49383                 init: function () {\r
49384                     this._symbolDrawMap = {};\r
49385                 },\r
49386 \r
49387                 render: function (markPointModel, ecModel, api) {\r
49388                     var symbolDrawMap = this._symbolDrawMap;\r
49389                     for (var name in symbolDrawMap) {\r
49390                         symbolDrawMap[name].__keep = false;\r
49391                     }\r
49392 \r
49393                     ecModel.eachSeries(function (seriesModel) {\r
49394                         var mpModel = seriesModel.markPointModel;\r
49395                         mpModel && this._renderSeriesMP(seriesModel, mpModel, api);\r
49396                     }, this);\r
49397 \r
49398                     for (var name in symbolDrawMap) {\r
49399                         if (!symbolDrawMap[name].__keep) {\r
49400                             symbolDrawMap[name].remove();\r
49401                             this.group.remove(symbolDrawMap[name].group);\r
49402                         }\r
49403                     }\r
49404                 },\r
49405 \r
49406                 updateLayout: function (markPointModel, ecModel, api) {\r
49407                     ecModel.eachSeries(function (seriesModel) {\r
49408                         var mpModel = seriesModel.markPointModel;\r
49409                         if (mpModel) {\r
49410                             updateMarkerLayout(mpModel.getData(), seriesModel, api);\r
49411                             this._symbolDrawMap[seriesModel.name].updateLayout(mpModel);\r
49412                         }\r
49413                     }, this);\r
49414                 },\r
49415 \r
49416                 _renderSeriesMP: function (seriesModel, mpModel, api) {\r
49417                     var coordSys = seriesModel.coordinateSystem;\r
49418                     var seriesName = seriesModel.name;\r
49419                     var seriesData = seriesModel.getData();\r
49420 \r
49421                     var symbolDrawMap = this._symbolDrawMap;\r
49422                     var symbolDraw = symbolDrawMap[seriesName];\r
49423                     if (!symbolDraw) {\r
49424                         symbolDraw = symbolDrawMap[seriesName] = new SymbolDraw();\r
49425                     }\r
49426 \r
49427                     var mpData = createList(coordSys, seriesModel, mpModel);\r
49428 \r
49429                     // FIXME\r
49430                     zrUtil.mixin(mpModel, markPointFormatMixin);\r
49431                     mpModel.setData(mpData);\r
49432 \r
49433                     updateMarkerLayout(mpModel.getData(), seriesModel, api);\r
49434 \r
49435                     mpData.each(function (idx) {\r
49436                         var itemModel = mpData.getItemModel(idx);\r
49437                         var symbolSize = itemModel.getShallow('symbolSize');\r
49438                         if (typeof symbolSize === 'function') {\r
49439                             // FIXME 这里不兼容 ECharts 2.x,2.x 貌似参数是整个数据?\r
49440                             symbolSize = symbolSize(\r
49441                                 mpModel.getRawValue(idx), mpModel.getDataParams(idx)\r
49442                             );\r
49443                         }\r
49444                         mpData.setItemVisual(idx, {\r
49445                             symbolSize: symbolSize,\r
49446                             color: itemModel.get('itemStyle.normal.color')\r
49447                                 || seriesData.getVisual('color'),\r
49448                             symbol: itemModel.getShallow('symbol')\r
49449                         });\r
49450                     });\r
49451 \r
49452                     // TODO Text are wrong\r
49453                     symbolDraw.updateData(mpData);\r
49454                     this.group.add(symbolDraw.group);\r
49455 \r
49456                     // Set host model for tooltip\r
49457                     // FIXME\r
49458                     mpData.eachItemGraphicEl(function (el) {\r
49459                         el.traverse(function (child) {\r
49460                             child.dataModel = mpModel;\r
49461                         });\r
49462                     });\r
49463 \r
49464                     symbolDraw.__keep = true;\r
49465                 }\r
49466             });\r
49467 \r
49468             /**\r
49469              * @inner\r
49470              * @param {module:echarts/coord/*} [coordSys]\r
49471              * @param {module:echarts/model/Series} seriesModel\r
49472              * @param {module:echarts/model/Model} mpModel\r
49473              */\r
49474             function createList(coordSys, seriesModel, mpModel) {\r
49475                 var coordDimsInfos;\r
49476                 if (coordSys) {\r
49477                     coordDimsInfos = zrUtil.map(coordSys && coordSys.dimensions, function (coordDim) {\r
49478                         var info = seriesModel.getData().getDimensionInfo(\r
49479                             seriesModel.coordDimToDataDim(coordDim)[0]\r
49480                         ) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys\r
49481                         info.name = coordDim;\r
49482                         return info;\r
49483                     });\r
49484                 }\r
49485                 else {\r
49486                     coordDimsInfos =[{\r
49487                         name: 'value',\r
49488                         type: 'float'\r
49489                     }];\r
49490                 }\r
49491 \r
49492                 var mpData = new List(coordDimsInfos, mpModel);\r
49493                 var dataOpt = zrUtil.map(mpModel.get('data'), zrUtil.curry(\r
49494                         markerHelper.dataTransform, seriesModel\r
49495                     ));\r
49496                 if (coordSys) {\r
49497                     dataOpt = zrUtil.filter(\r
49498                         dataOpt, zrUtil.curry(markerHelper.dataFilter, coordSys)\r
49499                     );\r
49500                 }\r
49501 \r
49502                 mpData.initData(dataOpt, null,\r
49503                     coordSys ? markerHelper.dimValueGetter : function (item) {\r
49504                         return item.value;\r
49505                     }\r
49506                 );\r
49507                 return mpData;\r
49508             }\r
49509 \r
49510 \r
49511 \r
49512 /***/ },\r
49513 /* 318 */\r
49514 /***/ function(module, exports, __webpack_require__) {\r
49515 \r
49516         \r
49517 \r
49518             var zrUtil = __webpack_require__(3);\r
49519             var numberUtil = __webpack_require__(7);\r
49520             var indexOf = zrUtil.indexOf;\r
49521 \r
49522             function getPrecision(data, valueAxisDim, dataIndex) {\r
49523                 var precision = -1;\r
49524                 do {\r
49525                     precision = Math.max(\r
49526                         numberUtil.getPrecision(data.get(\r
49527                             valueAxisDim, dataIndex\r
49528                         )),\r
49529                         precision\r
49530                     );\r
49531                     data = data.stackedOn;\r
49532                 } while (data);\r
49533 \r
49534                 return precision;\r
49535             }\r
49536 \r
49537             function markerTypeCalculatorWithExtent(\r
49538                 mlType, data, baseDataDim, valueDataDim, baseCoordIndex, valueCoordIndex\r
49539             ) {\r
49540                 var coordArr = [];\r
49541                 var value = numCalculate(data, valueDataDim, mlType);\r
49542 \r
49543                 var dataIndex = data.indexOfNearest(valueDataDim, value, true);\r
49544                 coordArr[baseCoordIndex] = data.get(baseDataDim, dataIndex, true);\r
49545                 coordArr[valueCoordIndex] = data.get(valueDataDim, dataIndex, true);\r
49546 \r
49547                 var precision = getPrecision(data, valueDataDim, dataIndex);\r
49548                 if (precision >= 0) {\r
49549                     coordArr[valueCoordIndex] = +coordArr[valueCoordIndex].toFixed(precision);\r
49550                 }\r
49551 \r
49552                 return coordArr;\r
49553             }\r
49554 \r
49555             var curry = zrUtil.curry;\r
49556             // TODO Specified percent\r
49557             var markerTypeCalculator = {\r
49558                 /**\r
49559                  * @method\r
49560                  * @param {module:echarts/data/List} data\r
49561                  * @param {string} baseAxisDim\r
49562                  * @param {string} valueAxisDim\r
49563                  */\r
49564                 min: curry(markerTypeCalculatorWithExtent, 'min'),\r
49565                 /**\r
49566                  * @method\r
49567                  * @param {module:echarts/data/List} data\r
49568                  * @param {string} baseAxisDim\r
49569                  * @param {string} valueAxisDim\r
49570                  */\r
49571                 max: curry(markerTypeCalculatorWithExtent, 'max'),\r
49572                 /**\r
49573                  * @method\r
49574                  * @param {module:echarts/data/List} data\r
49575                  * @param {string} baseAxisDim\r
49576                  * @param {string} valueAxisDim\r
49577                  */\r
49578                 average: curry(markerTypeCalculatorWithExtent, 'average')\r
49579             };\r
49580 \r
49581             /**\r
49582              * Transform markPoint data item to format used in List by do the following\r
49583              * 1. Calculate statistic like `max`, `min`, `average`\r
49584              * 2. Convert `item.xAxis`, `item.yAxis` to `item.coord` array\r
49585              * @param  {module:echarts/model/Series} seriesModel\r
49586              * @param  {module:echarts/coord/*} [coordSys]\r
49587              * @param  {Object} item\r
49588              * @return {Object}\r
49589              */\r
49590             var dataTransform = function (seriesModel, item) {\r
49591                 var data = seriesModel.getData();\r
49592                 var coordSys = seriesModel.coordinateSystem;\r
49593 \r
49594                 // 1. If not specify the position with pixel directly\r
49595                 // 2. If `coord` is not a data array. Which uses `xAxis`,\r
49596                 // `yAxis` to specify the coord on each dimension\r
49597                 if ((isNaN(item.x) || isNaN(item.y))\r
49598                     && !zrUtil.isArray(item.coord)\r
49599                     && coordSys\r
49600                 ) {\r
49601                     var axisInfo = getAxisInfo(item, data, coordSys, seriesModel);\r
49602 \r
49603                     // Clone the option\r
49604                     // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value\r
49605                     item = zrUtil.clone(item);\r
49606 \r
49607                     if (item.type\r
49608                         && markerTypeCalculator[item.type]\r
49609                         && axisInfo.baseAxis && axisInfo.valueAxis\r
49610                     ) {\r
49611                         var dims = coordSys.dimensions;\r
49612                         var baseCoordIndex = indexOf(dims, axisInfo.baseAxis.dim);\r
49613                         var valueCoordIndex = indexOf(dims, axisInfo.valueAxis.dim);\r
49614 \r
49615                         item.coord = markerTypeCalculator[item.type](\r
49616                             data, axisInfo.baseDataDim, axisInfo.valueDataDim,\r
49617                             baseCoordIndex, valueCoordIndex\r
49618                         );\r
49619                         // Force to use the value of calculated value.\r
49620                         item.value = item.coord[valueCoordIndex];\r
49621                     }\r
49622                     else {\r
49623                         // FIXME Only has one of xAxis and yAxis.\r
49624                         item.coord = [\r
49625                             item.xAxis != null ? item.xAxis : item.radiusAxis,\r
49626                             item.yAxis != null ? item.yAxis : item.angleAxis\r
49627                         ];\r
49628                     }\r
49629                 }\r
49630                 return item;\r
49631             };\r
49632 \r
49633             var getAxisInfo = function (item, data, coordSys, seriesModel) {\r
49634                 var ret = {};\r
49635 \r
49636                 if (item.valueIndex != null || item.valueDim != null) {\r
49637                     ret.valueDataDim = item.valueIndex != null\r
49638                         ? data.getDimension(item.valueIndex) : item.valueDim;\r
49639                     ret.valueAxis = coordSys.getAxis(seriesModel.dataDimToCoordDim(ret.valueDataDim));\r
49640                     ret.baseAxis = coordSys.getOtherAxis(ret.valueAxis);\r
49641                     ret.baseDataDim = seriesModel.coordDimToDataDim(ret.baseAxis.dim)[0];\r
49642                 }\r
49643                 else {\r
49644                     ret.baseAxis = seriesModel.getBaseAxis();\r
49645                     ret.valueAxis = coordSys.getOtherAxis(ret.baseAxis);\r
49646                     ret.baseDataDim = seriesModel.coordDimToDataDim(ret.baseAxis.dim)[0];\r
49647                     ret.valueDataDim = seriesModel.coordDimToDataDim(ret.valueAxis.dim)[0];\r
49648                 }\r
49649 \r
49650                 return ret;\r
49651             };\r
49652 \r
49653             /**\r
49654              * Filter data which is out of coordinateSystem range\r
49655              * [dataFilter description]\r
49656              * @param  {module:echarts/coord/*} [coordSys]\r
49657              * @param  {Object} item\r
49658              * @return {boolean}\r
49659              */\r
49660             var dataFilter = function (coordSys, item) {\r
49661                 // Alwalys return true if there is no coordSys\r
49662                 return (coordSys && coordSys.containData && item.coord && (item.x == null || item.y == null))\r
49663                     ? coordSys.containData(item.coord) : true;\r
49664             };\r
49665 \r
49666             var dimValueGetter = function (item, dimName, dataIndex, dimIndex) {\r
49667                 // x, y, radius, angle\r
49668                 if (dimIndex < 2) {\r
49669                     return item.coord && item.coord[dimIndex];\r
49670                 }\r
49671                 else {\r
49672                     return item.value;\r
49673                 }\r
49674             };\r
49675 \r
49676             var numCalculate = function (data, valueDataDim, mlType) {\r
49677                 return mlType === 'average'\r
49678                     ? data.getSum(valueDataDim, true) / data.count()\r
49679                     : data.getDataExtent(valueDataDim, true)[mlType === 'max' ? 1 : 0];\r
49680             };\r
49681 \r
49682             module.exports = {\r
49683                 dataTransform: dataTransform,\r
49684                 dataFilter: dataFilter,\r
49685                 dimValueGetter: dimValueGetter,\r
49686                 getAxisInfo: getAxisInfo,\r
49687                 numCalculate: numCalculate\r
49688             };\r
49689 \r
49690 \r
49691 /***/ },\r
49692 /* 319 */\r
49693 /***/ function(module, exports, __webpack_require__) {\r
49694 \r
49695         \r
49696 \r
49697             __webpack_require__(320);\r
49698             __webpack_require__(321);\r
49699 \r
49700             __webpack_require__(1).registerPreprocessor(function (opt) {\r
49701                 // Make sure markLine component is enabled\r
49702                 opt.markLine = opt.markLine || {};\r
49703             });\r
49704 \r
49705 \r
49706 /***/ },\r
49707 /* 320 */\r
49708 /***/ function(module, exports, __webpack_require__) {\r
49709 \r
49710         \r
49711 \r
49712             // Default enable markLine\r
49713             // var globalDefault = require('../../model/globalDefault');\r
49714             var modelUtil = __webpack_require__(5);\r
49715 \r
49716             // // Force to load markLine component\r
49717             // globalDefault.markLine = {};\r
49718 \r
49719             var MarkLineModel = __webpack_require__(1).extendComponentModel({\r
49720 \r
49721                 type: 'markLine',\r
49722 \r
49723                 dependencies: ['series', 'grid', 'polar'],\r
49724                 /**\r
49725                  * @overrite\r
49726                  */\r
49727                 init: function (option, parentModel, ecModel, extraOpt) {\r
49728                     this.mergeDefaultAndTheme(option, ecModel);\r
49729                     this.mergeOption(option, ecModel, extraOpt.createdBySelf, true);\r
49730                 },\r
49731 \r
49732                 mergeOption: function (newOpt, ecModel, createdBySelf, isInit) {\r
49733                     if (!createdBySelf) {\r
49734                         ecModel.eachSeries(function (seriesModel) {\r
49735                             var markLineOpt = seriesModel.get('markLine');\r
49736                             var mlModel = seriesModel.markLineModel;\r
49737                             if (!markLineOpt || !markLineOpt.data) {\r
49738                                 seriesModel.markLineModel = null;\r
49739                                 return;\r
49740                             }\r
49741                             if (!mlModel) {\r
49742                                 if (isInit) {\r
49743                                     // Default label emphasis `position` and `show`\r
49744                                     modelUtil.defaultEmphasis(\r
49745                                         markLineOpt.label,\r
49746                                         ['position', 'show', 'textStyle', 'distance', 'formatter']\r
49747                                     );\r
49748                                 }\r
49749                                 var opt = {\r
49750                                     // Use the same series index and name\r
49751                                     seriesIndex: seriesModel.seriesIndex,\r
49752                                     name: seriesModel.name,\r
49753                                     createdBySelf: true\r
49754                                 };\r
49755                                 mlModel = new MarkLineModel(\r
49756                                     markLineOpt, this, ecModel, opt\r
49757                                 );\r
49758                             }\r
49759                             else {\r
49760                                 mlModel.mergeOption(markLineOpt, ecModel, true);\r
49761                             }\r
49762                             seriesModel.markLineModel = mlModel;\r
49763                         }, this);\r
49764                     }\r
49765                 },\r
49766 \r
49767                 defaultOption: {\r
49768                     zlevel: 0,\r
49769                     z: 5,\r
49770                     // 标线起始和结束的symbol介绍类型,如果都一样,可以直接传string\r
49771                     symbol: ['circle', 'arrow'],\r
49772                     // 标线起始和结束的symbol大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2\r
49773                     symbolSize: [8, 16],\r
49774                     // 标线起始和结束的symbol旋转控制\r
49775                     //symbolRotate: null,\r
49776                     //smooth: false,\r
49777                     precision: 2,\r
49778                     tooltip: {\r
49779                         trigger: 'item'\r
49780                     },\r
49781                     label: {\r
49782                         normal: {\r
49783                             show: true,\r
49784                             // 标签文本格式器,同Tooltip.formatter,不支持回调\r
49785                             // formatter: null,\r
49786                             // 可选为 'start'|'end'|'left'|'right'|'top'|'bottom'\r
49787                             position: 'end'\r
49788                             // 默认使用全局文本样式,详见TEXTSTYLE\r
49789                             // textStyle: null\r
49790                         },\r
49791                         emphasis: {\r
49792                             show: true\r
49793                         }\r
49794                     },\r
49795                     lineStyle: {\r
49796                         normal: {\r
49797                             // color\r
49798                             // width\r
49799                             type: 'dashed'\r
49800                             // shadowColor: 'rgba(0,0,0,0)',\r
49801                             // shadowBlur: 0,\r
49802                             // shadowOffsetX: 0,\r
49803                             // shadowOffsetY: 0\r
49804                         },\r
49805                         emphasis: {\r
49806                             width: 3\r
49807                         }\r
49808                     },\r
49809                     animationEasing: 'linear'\r
49810                 }\r
49811             });\r
49812 \r
49813             module.exports = MarkLineModel;\r
49814 \r
49815 \r
49816 /***/ },\r
49817 /* 321 */\r
49818 /***/ function(module, exports, __webpack_require__) {\r
49819 \r
49820         \r
49821 \r
49822             var zrUtil = __webpack_require__(3);\r
49823             var List = __webpack_require__(94);\r
49824             var formatUtil = __webpack_require__(6);\r
49825             var modelUtil = __webpack_require__(5);\r
49826             var numberUtil = __webpack_require__(7);\r
49827 \r
49828             var addCommas = formatUtil.addCommas;\r
49829             var encodeHTML = formatUtil.encodeHTML;\r
49830 \r
49831             var markerHelper = __webpack_require__(318);\r
49832 \r
49833             var LineDraw = __webpack_require__(194);\r
49834 \r
49835             var markLineTransform = function (seriesModel, coordSys, mlModel, item) {\r
49836                 var data = seriesModel.getData();\r
49837                 // Special type markLine like 'min', 'max', 'average'\r
49838                 var mlType = item.type;\r
49839 \r
49840                 if (!zrUtil.isArray(item)\r
49841                     && (mlType === 'min' || mlType === 'max' || mlType === 'average')\r
49842                 ) {\r
49843                     var axisInfo = markerHelper.getAxisInfo(item, data, coordSys, seriesModel);\r
49844 \r
49845                     var baseAxisKey = axisInfo.baseAxis.dim + 'Axis';\r
49846                     var valueAxisKey = axisInfo.valueAxis.dim + 'Axis';\r
49847                     var baseScaleExtent = axisInfo.baseAxis.scale.getExtent();\r
49848 \r
49849                     var mlFrom = zrUtil.clone(item);\r
49850                     var mlTo = {};\r
49851 \r
49852                     mlFrom.type = null;\r
49853 \r
49854                     // FIXME Polar should use circle\r
49855                     mlFrom[baseAxisKey] = baseScaleExtent[0];\r
49856                     mlTo[baseAxisKey] = baseScaleExtent[1];\r
49857 \r
49858                     var value = markerHelper.numCalculate(data, axisInfo.valueDataDim, mlType);\r
49859 \r
49860                     // Round if axis is cateogry\r
49861                     value = axisInfo.valueAxis.coordToData(axisInfo.valueAxis.dataToCoord(value));\r
49862 \r
49863                     var precision = mlModel.get('precision');\r
49864                     if (precision >= 0) {\r
49865                         value = +value.toFixed(precision);\r
49866                     }\r
49867 \r
49868                     mlFrom[valueAxisKey] = mlTo[valueAxisKey] = value;\r
49869 \r
49870                     item = [mlFrom, mlTo, { // Extra option for tooltip and label\r
49871                         type: mlType,\r
49872                         valueIndex: item.valueIndex,\r
49873                         // Force to use the value of calculated value.\r
49874                         value: value\r
49875                     }];\r
49876                 }\r
49877 \r
49878                 item = [\r
49879                     markerHelper.dataTransform(seriesModel, item[0]),\r
49880                     markerHelper.dataTransform(seriesModel, item[1]),\r
49881                     zrUtil.extend({}, item[2])\r
49882                 ];\r
49883 \r
49884                 // Avoid line data type is extended by from(to) data type\r
49885                 item[2].type = item[2].type || '';\r
49886 \r
49887                 // Merge from option and to option into line option\r
49888                 zrUtil.merge(item[2], item[0]);\r
49889                 zrUtil.merge(item[2], item[1]);\r
49890 \r
49891                 return item;\r
49892             };\r
49893 \r
49894             function markLineFilter(coordSys, item) {\r
49895                 return markerHelper.dataFilter(coordSys, item[0])\r
49896                     && markerHelper.dataFilter(coordSys, item[1]);\r
49897             }\r
49898 \r
49899             function updateSingleMarkerEndLayout(\r
49900                 data, idx, isFrom, mlType, valueIndex, seriesModel, api\r
49901             ) {\r
49902                 var coordSys = seriesModel.coordinateSystem;\r
49903                 var itemModel = data.getItemModel(idx);\r
49904 \r
49905                 var point;\r
49906                 var xPx = itemModel.get('x');\r
49907                 var yPx = itemModel.get('y');\r
49908                 if (xPx != null && yPx != null) {\r
49909                     point = [\r
49910                         numberUtil.parsePercent(xPx, api.getWidth()),\r
49911                         numberUtil.parsePercent(yPx, api.getHeight())\r
49912                     ];\r
49913                 }\r
49914                 else {\r
49915                     // Chart like bar may have there own marker positioning logic\r
49916                     if (seriesModel.getMarkerPosition) {\r
49917                         // Use the getMarkerPoisition\r
49918                         point = seriesModel.getMarkerPosition(\r
49919                             data.getValues(data.dimensions, idx)\r
49920                         );\r
49921                     }\r
49922                     else {\r
49923                         var dims = coordSys.dimensions;\r
49924                         var x = data.get(dims[0], idx);\r
49925                         var y = data.get(dims[1], idx);\r
49926                         point = coordSys.dataToPoint([x, y]);\r
49927                     }\r
49928                     // Expand min, max, average line to the edge of grid\r
49929                     // FIXME Glue code\r
49930                     if (mlType && coordSys.type === 'cartesian2d') {\r
49931                         var mlOnAxis = valueIndex != null\r
49932                             ? coordSys.getAxis(valueIndex === 1 ? 'x' : 'y')\r
49933                             : coordSys.getAxesByScale('ordinal')[0];\r
49934                         if (mlOnAxis && mlOnAxis.onBand) {\r
49935                             point[mlOnAxis.dim === 'x' ? 0 : 1] =\r
49936                                 mlOnAxis.toGlobalCoord(mlOnAxis.getExtent()[isFrom ? 0 : 1]);\r
49937                         }\r
49938                     }\r
49939                 }\r
49940 \r
49941                 data.setItemLayout(idx, point);\r
49942             }\r
49943 \r
49944             var markLineFormatMixin = {\r
49945                 formatTooltip: function (dataIndex) {\r
49946                     var data = this._data;\r
49947                     var value = this.getRawValue(dataIndex);\r
49948                     var formattedValue = zrUtil.isArray(value)\r
49949                         ? zrUtil.map(value, addCommas).join(', ') : addCommas(value);\r
49950                     var name = data.getName(dataIndex);\r
49951                     return this.name + '<br />'\r
49952                         + ((name ? encodeHTML(name) + ' : ' : '') + formattedValue);\r
49953                 },\r
49954 \r
49955                 getRawDataArray: function () {\r
49956                     return this.option.data;\r
49957                 },\r
49958 \r
49959                 getData: function () {\r
49960                     return this._data;\r
49961                 },\r
49962 \r
49963                 setData: function (data) {\r
49964                     this._data = data;\r
49965                 }\r
49966             };\r
49967 \r
49968             zrUtil.defaults(markLineFormatMixin, modelUtil.dataFormatMixin);\r
49969 \r
49970             __webpack_require__(1).extendComponentView({\r
49971 \r
49972                 type: 'markLine',\r
49973 \r
49974                 init: function () {\r
49975                     /**\r
49976                      * Markline grouped by series\r
49977                      * @private\r
49978                      * @type {Object}\r
49979                      */\r
49980                     this._markLineMap = {};\r
49981                 },\r
49982 \r
49983                 render: function (markLineModel, ecModel, api) {\r
49984                     var lineDrawMap = this._markLineMap;\r
49985                     for (var name in lineDrawMap) {\r
49986                         lineDrawMap[name].__keep = false;\r
49987                     }\r
49988 \r
49989                     ecModel.eachSeries(function (seriesModel) {\r
49990                         var mlModel = seriesModel.markLineModel;\r
49991                         mlModel && this._renderSeriesML(seriesModel, mlModel, ecModel, api);\r
49992                     }, this);\r
49993 \r
49994                     for (var name in lineDrawMap) {\r
49995                         if (!lineDrawMap[name].__keep) {\r
49996                             this.group.remove(lineDrawMap[name].group);\r
49997                         }\r
49998                     }\r
49999                 },\r
50000 \r
50001                 updateLayout: function (markLineModel, ecModel, api) {\r
50002                     ecModel.eachSeries(function (seriesModel) {\r
50003                         var mlModel = seriesModel.markLineModel;\r
50004                         if (mlModel) {\r
50005                             var mlData = mlModel.getData();\r
50006                             var fromData = mlModel.__from;\r
50007                             var toData = mlModel.__to;\r
50008                             // Update visual and layout of from symbol and to symbol\r
50009                             fromData.each(function (idx) {\r
50010                                 var lineModel = mlData.getItemModel(idx);\r
50011                                 var mlType = lineModel.get('type');\r
50012                                 var valueIndex = lineModel.get('valueIndex');\r
50013                                 updateSingleMarkerEndLayout(fromData, idx, true, mlType, valueIndex, seriesModel, api);\r
50014                                 updateSingleMarkerEndLayout(toData, idx, false, mlType, valueIndex, seriesModel, api);\r
50015                             });\r
50016                             // Update layout of line\r
50017                             mlData.each(function (idx) {\r
50018                                 mlData.setItemLayout(idx, [\r
50019                                     fromData.getItemLayout(idx),\r
50020                                     toData.getItemLayout(idx)\r
50021                                 ]);\r
50022                             });\r
50023 \r
50024                             this._markLineMap[seriesModel.name].updateLayout();\r
50025                         }\r
50026                     }, this);\r
50027                 },\r
50028 \r
50029                 _renderSeriesML: function (seriesModel, mlModel, ecModel, api) {\r
50030                     var coordSys = seriesModel.coordinateSystem;\r
50031                     var seriesName = seriesModel.name;\r
50032                     var seriesData = seriesModel.getData();\r
50033 \r
50034                     var lineDrawMap = this._markLineMap;\r
50035                     var lineDraw = lineDrawMap[seriesName];\r
50036                     if (!lineDraw) {\r
50037                         lineDraw = lineDrawMap[seriesName] = new LineDraw();\r
50038                     }\r
50039                     this.group.add(lineDraw.group);\r
50040 \r
50041                     var mlData = createList(coordSys, seriesModel, mlModel);\r
50042 \r
50043                     var fromData = mlData.from;\r
50044                     var toData = mlData.to;\r
50045                     var lineData = mlData.line;\r
50046 \r
50047                     mlModel.__from = fromData;\r
50048                     mlModel.__to = toData;\r
50049                     // Line data for tooltip and formatter\r
50050                     zrUtil.extend(mlModel, markLineFormatMixin);\r
50051                     mlModel.setData(lineData);\r
50052 \r
50053                     var symbolType = mlModel.get('symbol');\r
50054                     var symbolSize = mlModel.get('symbolSize');\r
50055                     if (!zrUtil.isArray(symbolType)) {\r
50056                         symbolType = [symbolType, symbolType];\r
50057                     }\r
50058                     if (typeof symbolSize === 'number') {\r
50059                         symbolSize = [symbolSize, symbolSize];\r
50060                     }\r
50061 \r
50062                     // Update visual and layout of from symbol and to symbol\r
50063                     mlData.from.each(function (idx) {\r
50064                         var lineModel = lineData.getItemModel(idx);\r
50065                         var mlType = lineModel.get('type');\r
50066                         var valueIndex = lineModel.get('valueIndex');\r
50067                         updateDataVisualAndLayout(fromData, idx, true, mlType, valueIndex);\r
50068                         updateDataVisualAndLayout(toData, idx, false, mlType, valueIndex);\r
50069                     });\r
50070 \r
50071                     // Update visual and layout of line\r
50072                     lineData.each(function (idx) {\r
50073                         var lineColor = lineData.getItemModel(idx).get('lineStyle.normal.color');\r
50074                         lineData.setItemVisual(idx, {\r
50075                             color: lineColor || fromData.getItemVisual(idx, 'color')\r
50076                         });\r
50077                         lineData.setItemLayout(idx, [\r
50078                             fromData.getItemLayout(idx),\r
50079                             toData.getItemLayout(idx)\r
50080                         ]);\r
50081                     });\r
50082 \r
50083                     lineDraw.updateData(lineData, fromData, toData);\r
50084 \r
50085                     // Set host model for tooltip\r
50086                     // FIXME\r
50087                     mlData.line.eachItemGraphicEl(function (el, idx) {\r
50088                         el.traverse(function (child) {\r
50089                             child.dataModel = mlModel;\r
50090                         });\r
50091                     });\r
50092 \r
50093                     function updateDataVisualAndLayout(data, idx, isFrom, mlType, valueIndex) {\r
50094                         var itemModel = data.getItemModel(idx);\r
50095 \r
50096                         updateSingleMarkerEndLayout(\r
50097                             data, idx, isFrom, mlType, valueIndex, seriesModel, api\r
50098                         );\r
50099 \r
50100                         data.setItemVisual(idx, {\r
50101                             symbolSize: itemModel.get('symbolSize')\r
50102                                 || symbolSize[isFrom ? 0 : 1],\r
50103                             symbol: itemModel.get('symbol', true)\r
50104                                 || symbolType[isFrom ? 0 : 1],\r
50105                             color: itemModel.get('itemStyle.normal.color')\r
50106                                 || seriesData.getVisual('color')\r
50107                         });\r
50108                     }\r
50109 \r
50110                     lineDraw.__keep = true;\r
50111                 }\r
50112             });\r
50113 \r
50114             /**\r
50115              * @inner\r
50116              * @param {module:echarts/coord/*} coordSys\r
50117              * @param {module:echarts/model/Series} seriesModel\r
50118              * @param {module:echarts/model/Model} mpModel\r
50119              */\r
50120             function createList(coordSys, seriesModel, mlModel) {\r
50121 \r
50122                 var coordDimsInfos;\r
50123                 if (coordSys) {\r
50124                     coordDimsInfos = zrUtil.map(coordSys && coordSys.dimensions, function (coordDim) {\r
50125                         var info = seriesModel.getData().getDimensionInfo(\r
50126                             seriesModel.coordDimToDataDim(coordDim)[0]\r
50127                         ) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys\r
50128                         info.name = coordDim;\r
50129                         return info;\r
50130                     });\r
50131                 }\r
50132                 else {\r
50133                     coordDimsInfos =[{\r
50134                         name: 'value',\r
50135                         type: 'float'\r
50136                     }];\r
50137                 }\r
50138 \r
50139                 var fromData = new List(coordDimsInfos, mlModel);\r
50140                 var toData = new List(coordDimsInfos, mlModel);\r
50141                 // No dimensions\r
50142                 var lineData = new List([], mlModel);\r
50143 \r
50144                 var optData = zrUtil.map(mlModel.get('data'), zrUtil.curry(\r
50145                     markLineTransform, seriesModel, coordSys, mlModel\r
50146                 ));\r
50147                 if (coordSys) {\r
50148                     optData = zrUtil.filter(\r
50149                         optData, zrUtil.curry(markLineFilter, coordSys)\r
50150                     );\r
50151                 }\r
50152                 var dimValueGetter = coordSys ? markerHelper.dimValueGetter : function (item) {\r
50153                     return item.value;\r
50154                 };\r
50155                 fromData.initData(\r
50156                     zrUtil.map(optData, function (item) { return item[0]; }),\r
50157                     null, dimValueGetter\r
50158                 );\r
50159                 toData.initData(\r
50160                     zrUtil.map(optData, function (item) { return item[1]; }),\r
50161                     null, dimValueGetter\r
50162                 );\r
50163                 lineData.initData(\r
50164                     zrUtil.map(optData, function (item) { return item[2]; })\r
50165                 );\r
50166                 return {\r
50167                     from: fromData,\r
50168                     to: toData,\r
50169                     line: lineData\r
50170                 };\r
50171             }\r
50172 \r
50173 \r
50174 /***/ },\r
50175 /* 322 */\r
50176 /***/ function(module, exports, __webpack_require__) {\r
50177 \r
50178         /**\r
50179          * DataZoom component entry\r
50180          */\r
50181 \r
50182 \r
50183             var echarts = __webpack_require__(1);\r
50184 \r
50185             echarts.registerPreprocessor(__webpack_require__(323));\r
50186 \r
50187             __webpack_require__(324);\r
50188             __webpack_require__(325);\r
50189             __webpack_require__(326);\r
50190             __webpack_require__(328);\r
50191 \r
50192 \r
50193 \r
50194 /***/ },\r
50195 /* 323 */\r
50196 /***/ function(module, exports, __webpack_require__) {\r
50197 \r
50198         /**\r
50199          * @file Timeline preprocessor\r
50200          */\r
50201 \r
50202 \r
50203             var zrUtil = __webpack_require__(3);\r
50204 \r
50205             module.exports = function (option) {\r
50206                 var timelineOpt = option && option.timeline;\r
50207 \r
50208                 if (!zrUtil.isArray(timelineOpt)) {\r
50209                     timelineOpt = timelineOpt ? [timelineOpt] : [];\r
50210                 }\r
50211 \r
50212                 zrUtil.each(timelineOpt, function (opt) {\r
50213                     if (!opt) {\r
50214                         return;\r
50215                     }\r
50216 \r
50217                     compatibleEC2(opt);\r
50218                 });\r
50219             };\r
50220 \r
50221             function compatibleEC2(opt) {\r
50222                 var type = opt.type;\r
50223 \r
50224                 var ec2Types = {'number': 'value', 'time': 'time'};\r
50225 \r
50226                 // Compatible with ec2\r
50227                 if (ec2Types[type]) {\r
50228                     opt.axisType = ec2Types[type];\r
50229                     delete opt.type;\r
50230                 }\r
50231 \r
50232                 transferItem(opt);\r
50233 \r
50234                 if (has(opt, 'controlPosition')) {\r
50235                     var controlStyle = opt.controlStyle || (opt.controlStyle = {});\r
50236                     if (!has(controlStyle, 'position')) {\r
50237                         controlStyle.position = opt.controlPosition;\r
50238                     }\r
50239                     if (controlStyle.position === 'none' && !has(controlStyle, 'show')) {\r
50240                         controlStyle.show = false;\r
50241                         delete controlStyle.position;\r
50242                     }\r
50243                     delete opt.controlPosition;\r
50244                 }\r
50245 \r
50246                 zrUtil.each(opt.data || [], function (dataItem) {\r
50247                     if (zrUtil.isObject(dataItem) && !zrUtil.isArray(dataItem)) {\r
50248                         if (!has(dataItem, 'value') && has(dataItem, 'name')) {\r
50249                             // In ec2, using name as value.\r
50250                             dataItem.value = dataItem.name;\r
50251                         }\r
50252                         transferItem(dataItem);\r
50253                     }\r
50254                 });\r
50255             }\r
50256 \r
50257             function transferItem(opt) {\r
50258                 var itemStyle = opt.itemStyle || (opt.itemStyle = {});\r
50259 \r
50260                 var itemStyleEmphasis = itemStyle.emphasis || (itemStyle.emphasis = {});\r
50261 \r
50262                 // Transfer label out\r
50263                 var label = opt.label || (opt.label || {});\r
50264                 var labelNormal = label.normal || (label.normal = {});\r
50265                 var excludeLabelAttr = {normal: 1, emphasis: 1};\r
50266 \r
50267                 zrUtil.each(label, function (value, name) {\r
50268                     if (!excludeLabelAttr[name] && !has(labelNormal, name)) {\r
50269                         labelNormal[name] = value;\r
50270                     }\r
50271                 });\r
50272 \r
50273                 if (itemStyleEmphasis.label && !has(label, 'emphasis')) {\r
50274                     label.emphasis = itemStyleEmphasis.label;\r
50275                     delete itemStyleEmphasis.label;\r
50276                 }\r
50277             }\r
50278 \r
50279             function has(obj, attr) {\r
50280                 return obj.hasOwnProperty(attr);\r
50281             }\r
50282 \r
50283 \r
50284 \r
50285 /***/ },\r
50286 /* 324 */\r
50287 /***/ function(module, exports, __webpack_require__) {\r
50288 \r
50289         \r
50290 \r
50291             __webpack_require__(19).registerSubTypeDefaulter('timeline', function () {\r
50292                 // Only slider now.\r
50293                 return 'slider';\r
50294             });\r
50295 \r
50296 \r
50297 \r
50298 /***/ },\r
50299 /* 325 */\r
50300 /***/ function(module, exports, __webpack_require__) {\r
50301 \r
50302         /**\r
50303          * @file Timeilne action\r
50304          */\r
50305 \r
50306 \r
50307             var echarts = __webpack_require__(1);\r
50308 \r
50309             echarts.registerAction(\r
50310 \r
50311                 {type: 'timelineChange', event: 'timelineChanged', update: 'prepareAndUpdate'},\r
50312 \r
50313                 function (payload, ecModel) {\r
50314 \r
50315                     var timelineModel = ecModel.getComponent('timeline');\r
50316                     if (timelineModel && payload.currentIndex != null) {\r
50317                         timelineModel.setCurrentIndex(payload.currentIndex);\r
50318 \r
50319                         if (!timelineModel.get('loop', true) && timelineModel.isIndexMax()) {\r
50320                             timelineModel.setPlayState(false);\r
50321                         }\r
50322                     }\r
50323 \r
50324                     ecModel.resetOption('timeline');\r
50325                 }\r
50326             );\r
50327 \r
50328             echarts.registerAction(\r
50329 \r
50330                 {type: 'timelinePlayChange', event: 'timelinePlayChanged', update: 'update'},\r
50331 \r
50332                 function (payload, ecModel) {\r
50333                     var timelineModel = ecModel.getComponent('timeline');\r
50334                     if (timelineModel && payload.playState != null) {\r
50335                         timelineModel.setPlayState(payload.playState);\r
50336                     }\r
50337                 }\r
50338             );\r
50339 \r
50340 \r
50341 \r
50342 /***/ },\r
50343 /* 326 */\r
50344 /***/ function(module, exports, __webpack_require__) {\r
50345 \r
50346         /**\r
50347          * @file Silder timeline model\r
50348          */\r
50349 \r
50350 \r
50351             var TimelineModel = __webpack_require__(327);\r
50352 \r
50353             module.exports = TimelineModel.extend({\r
50354 \r
50355                 type: 'timeline.slider',\r
50356 \r
50357                 /**\r
50358                  * @protected\r
50359                  */\r
50360                 defaultOption: {\r
50361 \r
50362                     backgroundColor: 'rgba(0,0,0,0)',   // 时间轴背景颜色\r
50363                     borderColor: '#ccc',               // 时间轴边框颜色\r
50364                     borderWidth: 0,                    // 时间轴边框线宽,单位px,默认为0(无边框)\r
50365 \r
50366                     orient: 'horizontal',              // 'vertical'\r
50367                     inverse: false,\r
50368 \r
50369                     tooltip: {                          // boolean or Object\r
50370                         trigger: 'item'                 // data item may also have tootip attr.\r
50371                     },\r
50372 \r
50373                     symbol: 'emptyCircle',\r
50374                     symbolSize: 10,\r
50375 \r
50376                     lineStyle: {\r
50377                         show: true,\r
50378                         width: 2,\r
50379                         color: '#304654'\r
50380                     },\r
50381                     label: {                            // 文本标签\r
50382                         position: 'auto',           // auto left right top bottom\r
50383                                                     // When using number, label position is not\r
50384                                                     // restricted by viewRect.\r
50385                                                     // positive: right/bottom, negative: left/top\r
50386                         normal: {\r
50387                             show: true,\r
50388                             interval: 'auto',\r
50389                             rotate: 0,\r
50390                             // formatter: null,\r
50391                             textStyle: {                // 其余属性默认使用全局文本样式,详见TEXTSTYLE\r
50392                                 color: '#304654'\r
50393                             }\r
50394                         },\r
50395                         emphasis: {\r
50396                             show: true,\r
50397                             textStyle: {                // 其余属性默认使用全局文本样式,详见TEXTSTYLE\r
50398                                 color: '#c23531'\r
50399                             }\r
50400                         }\r
50401                     },\r
50402                     itemStyle: {\r
50403                         normal: {\r
50404                             color: '#304654',\r
50405                             borderWidth: 1\r
50406                         },\r
50407                         emphasis: {\r
50408                             color: '#c23531'\r
50409                         }\r
50410                     },\r
50411 \r
50412                     checkpointStyle: {\r
50413                         symbol: 'circle',\r
50414                         symbolSize: 13,\r
50415                         color: '#c23531',\r
50416                         borderWidth: 5,\r
50417                         borderColor: 'rgba(194,53,49, 0.5)',\r
50418                         animation: true,\r
50419                         animationDuration: 300,\r
50420                         animationEasing: 'quinticInOut'\r
50421                     },\r
50422 \r
50423                     controlStyle: {\r
50424                         show: true,\r
50425                         showPlayBtn: true,\r
50426                         showPrevBtn: true,\r
50427                         showNextBtn: true,\r
50428                         itemSize: 22,\r
50429                         itemGap: 12,\r
50430                         position: 'left',  // 'left' 'right' 'top' 'bottom'\r
50431                         playIcon: 'path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z', // jshint ignore:line\r
50432                         stopIcon: 'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z', // jshint ignore:line\r
50433                         nextIcon: 'path://M18.6,50.8l22.5-22.5c0.2-0.2,0.3-0.4,0.3-0.7c0-0.3-0.1-0.5-0.3-0.7L18.7,4.4c-0.1-0.1-0.2-0.3-0.2-0.5 c0-0.4,0.3-0.8,0.8-0.8c0.2,0,0.5,0.1,0.6,0.3l23.5,23.5l0,0c0.2,0.2,0.3,0.4,0.3,0.7c0,0.3-0.1,0.5-0.3,0.7l-0.1,0.1L19.7,52 c-0.1,0.1-0.3,0.2-0.5,0.2c-0.4,0-0.8-0.3-0.8-0.8C18.4,51.2,18.5,51,18.6,50.8z', // jshint ignore:line\r
50434                         prevIcon: 'path://M43,52.8L20.4,30.3c-0.2-0.2-0.3-0.4-0.3-0.7c0-0.3,0.1-0.5,0.3-0.7L42.9,6.4c0.1-0.1,0.2-0.3,0.2-0.5 c0-0.4-0.3-0.8-0.8-0.8c-0.2,0-0.5,0.1-0.6,0.3L18.3,28.8l0,0c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.3,0.1,0.5,0.3,0.7l0.1,0.1L41.9,54 c0.1,0.1,0.3,0.2,0.5,0.2c0.4,0,0.8-0.3,0.8-0.8C43.2,53.2,43.1,53,43,52.8z', // jshint ignore:line\r
50435                         normal: {\r
50436                             color: '#304654',\r
50437                             borderColor: '#304654',\r
50438                             borderWidth: 1\r
50439                         },\r
50440                         emphasis: {\r
50441                             color: '#c23531',\r
50442                             borderColor: '#c23531',\r
50443                             borderWidth: 2\r
50444                         }\r
50445                     },\r
50446                     data: []\r
50447                 }\r
50448 \r
50449             });\r
50450 \r
50451 \r
50452 \r
50453 /***/ },\r
50454 /* 327 */\r
50455 /***/ function(module, exports, __webpack_require__) {\r
50456 \r
50457         /**\r
50458          * @file Timeline model\r
50459          */\r
50460 \r
50461 \r
50462             var ComponentModel = __webpack_require__(19);\r
50463             var List = __webpack_require__(94);\r
50464             var zrUtil = __webpack_require__(3);\r
50465             var modelUtil = __webpack_require__(5);\r
50466 \r
50467             var TimelineModel = ComponentModel.extend({\r
50468 \r
50469                 type: 'timeline',\r
50470 \r
50471                 layoutMode: 'box',\r
50472 \r
50473                 /**\r
50474                  * @protected\r
50475                  */\r
50476                 defaultOption: {\r
50477 \r
50478                     zlevel: 0,                  // 一级层叠\r
50479                     z: 4,                       // 二级层叠\r
50480                     show: true,\r
50481 \r
50482                     axisType: 'time',  // 模式是时间类型,支持 value, category\r
50483 \r
50484                     realtime: true,\r
50485 \r
50486                     left: '20%',\r
50487                     top: null,\r
50488                     right: '20%',\r
50489                     bottom: 0,\r
50490                     width: null,\r
50491                     height: 40,\r
50492                     padding: 5,\r
50493 \r
50494                     controlPosition: 'left',           // 'left' 'right' 'top' 'bottom' 'none'\r
50495                     autoPlay: false,\r
50496                     rewind: false,                     // 反向播放\r
50497                     loop: true,\r
50498                     playInterval: 2000,                // 播放时间间隔,单位ms\r
50499 \r
50500                     currentIndex: 0,\r
50501 \r
50502                     itemStyle: {\r
50503                         normal: {},\r
50504                         emphasis: {}\r
50505                     },\r
50506                     label: {\r
50507                         normal: {\r
50508                             textStyle: {\r
50509                                 color: '#000'\r
50510                             }\r
50511                         },\r
50512                         emphasis: {}\r
50513                     },\r
50514 \r
50515                     data: []\r
50516                 },\r
50517 \r
50518                 /**\r
50519                  * @override\r
50520                  */\r
50521                 init: function (option, parentModel, ecModel) {\r
50522 \r
50523                     /**\r
50524                      * @private\r
50525                      * @type {module:echarts/data/List}\r
50526                      */\r
50527                     this._data;\r
50528 \r
50529                     /**\r
50530                      * @private\r
50531                      * @type {Array.<string>}\r
50532                      */\r
50533                     this._names;\r
50534 \r
50535                     this.mergeDefaultAndTheme(option, ecModel);\r
50536                     this._initData();\r
50537                 },\r
50538 \r
50539                 /**\r
50540                  * @override\r
50541                  */\r
50542                 mergeOption: function (option) {\r
50543                     TimelineModel.superApply(this, 'mergeOption', arguments);\r
50544                     this._initData();\r
50545                 },\r
50546 \r
50547                 /**\r
50548                  * @param {number} [currentIndex]\r
50549                  */\r
50550                 setCurrentIndex: function (currentIndex) {\r
50551                     if (currentIndex == null) {\r
50552                         currentIndex = this.option.currentIndex;\r
50553                     }\r
50554                     var count = this._data.count();\r
50555 \r
50556                     if (this.option.loop) {\r
50557                         currentIndex = (currentIndex % count + count) % count;\r
50558                     }\r
50559                     else {\r
50560                         currentIndex >= count && (currentIndex = count - 1);\r
50561                         currentIndex < 0 && (currentIndex = 0);\r
50562                     }\r
50563 \r
50564                     this.option.currentIndex = currentIndex;\r
50565                 },\r
50566 \r
50567                 /**\r
50568                  * @return {number} currentIndex\r
50569                  */\r
50570                 getCurrentIndex: function () {\r
50571                     return this.option.currentIndex;\r
50572                 },\r
50573 \r
50574                 /**\r
50575                  * @return {boolean}\r
50576                  */\r
50577                 isIndexMax: function () {\r
50578                     return this.getCurrentIndex() >= this._data.count() - 1;\r
50579                 },\r
50580 \r
50581                 /**\r
50582                  * @param {boolean} state true: play, false: stop\r
50583                  */\r
50584                 setPlayState: function (state) {\r
50585                     this.option.autoPlay = !!state;\r
50586                 },\r
50587 \r
50588                 /**\r
50589                  * @return {boolean} true: play, false: stop\r
50590                  */\r
50591                 getPlayState: function () {\r
50592                     return !!this.option.autoPlay;\r
50593                 },\r
50594 \r
50595                 /**\r
50596                  * @private\r
50597                  */\r
50598                 _initData: function () {\r
50599                     var thisOption = this.option;\r
50600                     var dataArr = thisOption.data || [];\r
50601                     var axisType = thisOption.axisType;\r
50602                     var names = this._names = [];\r
50603 \r
50604                     if (axisType === 'category') {\r
50605                         var idxArr = [];\r
50606                         zrUtil.each(dataArr, function (item, index) {\r
50607                             var value = modelUtil.getDataItemValue(item);\r
50608                             var newItem;\r
50609 \r
50610                             if (zrUtil.isObject(item)) {\r
50611                                 newItem = zrUtil.clone(item);\r
50612                                 newItem.value = index;\r
50613                             }\r
50614                             else {\r
50615                                 newItem = index;\r
50616                             }\r
50617 \r
50618                             idxArr.push(newItem);\r
50619 \r
50620                             if (!zrUtil.isString(value) && (value == null || isNaN(value))) {\r
50621                                 value = '';\r
50622                             }\r
50623 \r
50624                             names.push(value + '');\r
50625                         });\r
50626                         dataArr = idxArr;\r
50627                     }\r
50628 \r
50629                     var dimType = ({category: 'ordinal', time: 'time'})[axisType] || 'number';\r
50630 \r
50631                     var data = this._data = new List([{name: 'value', type: dimType}], this);\r
50632 \r
50633                     data.initData(dataArr, names);\r
50634                 },\r
50635 \r
50636                 getData: function () {\r
50637                     return this._data;\r
50638                 },\r
50639 \r
50640                 /**\r
50641                  * @public\r
50642                  * @return {Array.<string>} categoreis\r
50643                  */\r
50644                 getCategories: function () {\r
50645                     if (this.get('axisType') === 'category') {\r
50646                         return this._names.slice();\r
50647                     }\r
50648                 }\r
50649 \r
50650             });\r
50651 \r
50652             module.exports = TimelineModel;\r
50653 \r
50654 \r
50655 /***/ },\r
50656 /* 328 */\r
50657 /***/ function(module, exports, __webpack_require__) {\r
50658 \r
50659         /**\r
50660          * @file Silder timeline view\r
50661          */\r
50662 \r
50663 \r
50664             var zrUtil = __webpack_require__(3);\r
50665             var graphic = __webpack_require__(42);\r
50666             var layout = __webpack_require__(21);\r
50667             var TimelineView = __webpack_require__(329);\r
50668             var TimelineAxis = __webpack_require__(330);\r
50669             var symbolUtil = __webpack_require__(100);\r
50670             var axisHelper = __webpack_require__(108);\r
50671             var BoundingRect = __webpack_require__(15);\r
50672             var matrix = __webpack_require__(17);\r
50673             var numberUtil = __webpack_require__(7);\r
50674             var modelUtil = __webpack_require__(5);\r
50675             var formatUtil = __webpack_require__(6);\r
50676             var encodeHTML = formatUtil.encodeHTML;\r
50677 \r
50678             var bind = zrUtil.bind;\r
50679             var each = zrUtil.each;\r
50680 \r
50681             var PI = Math.PI;\r
50682 \r
50683             module.exports = TimelineView.extend({\r
50684 \r
50685                 type: 'timeline.slider',\r
50686 \r
50687                 init: function (ecModel, api) {\r
50688 \r
50689                     this.api = api;\r
50690 \r
50691                     /**\r
50692                      * @private\r
50693                      * @type {module:echarts/component/timeline/TimelineAxis}\r
50694                      */\r
50695                     this._axis;\r
50696 \r
50697                     /**\r
50698                      * @private\r
50699                      * @type {module:zrender/core/BoundingRect}\r
50700                      */\r
50701                     this._viewRect;\r
50702 \r
50703                     /**\r
50704                      * @type {number}\r
50705                      */\r
50706                     this._timer;\r
50707 \r
50708                     /**\r
50709                      * @type {module:zrende/Element}\r
50710                      */\r
50711                     this._currentPointer;\r
50712 \r
50713                     /**\r
50714                      * @type {module:zrender/container/Group}\r
50715                      */\r
50716                     this._mainGroup;\r
50717 \r
50718                     /**\r
50719                      * @type {module:zrender/container/Group}\r
50720                      */\r
50721                     this._labelGroup;\r
50722                 },\r
50723 \r
50724                 /**\r
50725                  * @override\r
50726                  */\r
50727                 render: function (timelineModel, ecModel, api, payload) {\r
50728                     this.model = timelineModel;\r
50729                     this.api = api;\r
50730                     this.ecModel = ecModel;\r
50731 \r
50732                     this.group.removeAll();\r
50733 \r
50734                     if (timelineModel.get('show', true)) {\r
50735 \r
50736                         var layoutInfo = this._layout(timelineModel, api);\r
50737                         var mainGroup = this._createGroup('mainGroup');\r
50738                         var labelGroup = this._createGroup('labelGroup');\r
50739 \r
50740                         /**\r
50741                          * @private\r
50742                          * @type {module:echarts/component/timeline/TimelineAxis}\r
50743                          */\r
50744                         var axis = this._axis = this._createAxis(layoutInfo, timelineModel);\r
50745 \r
50746                         each(\r
50747                             ['AxisLine', 'AxisTick', 'Control', 'CurrentPointer'],\r
50748                             function (name) {\r
50749                                 this['_render' + name](layoutInfo, mainGroup, axis, timelineModel);\r
50750                             },\r
50751                             this\r
50752                         );\r
50753 \r
50754                         this._renderAxisLabel(layoutInfo, labelGroup, axis, timelineModel);\r
50755 \r
50756                         this._position(layoutInfo, timelineModel);\r
50757                     }\r
50758 \r
50759                     this._doPlayStop();\r
50760                 },\r
50761 \r
50762                 /**\r
50763                  * @override\r
50764                  */\r
50765                 remove: function () {\r
50766                     this._clearTimer();\r
50767                     this.group.removeAll();\r
50768                 },\r
50769 \r
50770                 /**\r
50771                  * @override\r
50772                  */\r
50773                 dispose: function () {\r
50774                     this._clearTimer();\r
50775                 },\r
50776 \r
50777                 _layout: function (timelineModel, api) {\r
50778                     var labelPosOpt = timelineModel.get('label.normal.position');\r
50779                     var orient = timelineModel.get('orient');\r
50780                     var viewRect = getViewRect(timelineModel, api);\r
50781                     // Auto label offset.\r
50782                     if (labelPosOpt == null || labelPosOpt === 'auto') {\r
50783                         labelPosOpt = orient === 'horizontal'\r
50784                             ? ((viewRect.y + viewRect.height / 2) < api.getHeight() / 2 ? '-' : '+')\r
50785                             : ((viewRect.x + viewRect.width / 2) < api.getWidth() / 2 ? '+' : '-');\r
50786                     }\r
50787                     else if (isNaN(labelPosOpt)) {\r
50788                         labelPosOpt = ({\r
50789                             horizontal: {top: '-', bottom: '+'},\r
50790                             vertical: {left: '-', right: '+'}\r
50791                         })[orient][labelPosOpt];\r
50792                     }\r
50793 \r
50794                     // FIXME\r
50795                     // 暂没有实现用户传入\r
50796                     // var labelAlign = timelineModel.get('label.normal.textStyle.align');\r
50797                     // var labelBaseline = timelineModel.get('label.normal.textStyle.baseline');\r
50798                     var labelAlignMap = {\r
50799                         horizontal: 'center',\r
50800                         vertical: (labelPosOpt >= 0 || labelPosOpt === '+') ? 'left' : 'right'\r
50801                     };\r
50802 \r
50803                     var labelBaselineMap = {\r
50804                         horizontal: (labelPosOpt >= 0 || labelPosOpt === '+') ? 'top' : 'bottom',\r
50805                         vertical: 'middle'\r
50806                     };\r
50807                     var rotationMap = {\r
50808                         horizontal: 0,\r
50809                         vertical: PI / 2\r
50810                     };\r
50811 \r
50812                     // Position\r
50813                     var mainLength = orient === 'vertical' ? viewRect.height : viewRect.width;\r
50814 \r
50815                     var controlModel = timelineModel.getModel('controlStyle');\r
50816                     var showControl = controlModel.get('show');\r
50817                     var controlSize = showControl ? controlModel.get('itemSize') : 0;\r
50818                     var controlGap = showControl ? controlModel.get('itemGap') : 0;\r
50819                     var sizePlusGap = controlSize + controlGap;\r
50820 \r
50821                     // Special label rotate.\r
50822                     var labelRotation = timelineModel.get('label.normal.rotate') || 0;\r
50823                     labelRotation = labelRotation * PI / 180; // To radian.\r
50824 \r
50825                     var playPosition;\r
50826                     var prevBtnPosition;\r
50827                     var nextBtnPosition;\r
50828                     var axisExtent;\r
50829                     var controlPosition = controlModel.get('position', true);\r
50830                     var showControl = controlModel.get('show', true);\r
50831                     var showPlayBtn = showControl && controlModel.get('showPlayBtn', true);\r
50832                     var showPrevBtn = showControl && controlModel.get('showPrevBtn', true);\r
50833                     var showNextBtn = showControl && controlModel.get('showNextBtn', true);\r
50834                     var xLeft = 0;\r
50835                     var xRight = mainLength;\r
50836 \r
50837                     // position[0] means left, position[1] means middle.\r
50838                     if (controlPosition === 'left' || controlPosition === 'bottom') {\r
50839                         showPlayBtn && (playPosition = [0, 0], xLeft += sizePlusGap);\r
50840                         showPrevBtn && (prevBtnPosition = [xLeft, 0], xLeft += sizePlusGap);\r
50841                         showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);\r
50842                     }\r
50843                     else { // 'top' 'right'\r
50844                         showPlayBtn && (playPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);\r
50845                         showPrevBtn && (prevBtnPosition = [0, 0], xLeft += sizePlusGap);\r
50846                         showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);\r
50847                     }\r
50848                     axisExtent = [xLeft, xRight];\r
50849 \r
50850                     if (timelineModel.get('inverse')) {\r
50851                         axisExtent.reverse();\r
50852                     }\r
50853 \r
50854                     return {\r
50855                         viewRect: viewRect,\r
50856                         mainLength: mainLength,\r
50857                         orient: orient,\r
50858 \r
50859                         rotation: rotationMap[orient],\r
50860                         labelRotation: labelRotation,\r
50861                         labelPosOpt: labelPosOpt,\r
50862                         labelAlign: labelAlignMap[orient],\r
50863                         labelBaseline: labelBaselineMap[orient],\r
50864 \r
50865                         // Based on mainGroup.\r
50866                         playPosition: playPosition,\r
50867                         prevBtnPosition: prevBtnPosition,\r
50868                         nextBtnPosition: nextBtnPosition,\r
50869                         axisExtent: axisExtent,\r
50870 \r
50871                         controlSize: controlSize,\r
50872                         controlGap: controlGap\r
50873                     };\r
50874                 },\r
50875 \r
50876                 _position: function (layoutInfo, timelineModel) {\r
50877                     // Position is be called finally, because bounding rect is needed for\r
50878                     // adapt content to fill viewRect (auto adapt offset).\r
50879 \r
50880                     // Timeline may be not all in the viewRect when 'offset' is specified\r
50881                     // as a number, because it is more appropriate that label aligns at\r
50882                     // 'offset' but not the other edge defined by viewRect.\r
50883 \r
50884                     var mainGroup = this._mainGroup;\r
50885                     var labelGroup = this._labelGroup;\r
50886 \r
50887                     var viewRect = layoutInfo.viewRect;\r
50888                     if (layoutInfo.orient === 'vertical') {\r
50889                         // transfrom to horizontal, inverse rotate by left-top point.\r
50890                         var m = matrix.create();\r
50891                         var rotateOriginX = viewRect.x;\r
50892                         var rotateOriginY = viewRect.y + viewRect.height;\r
50893                         matrix.translate(m, m, [-rotateOriginX, -rotateOriginY]);\r
50894                         matrix.rotate(m, m, -PI / 2);\r
50895                         matrix.translate(m, m, [rotateOriginX, rotateOriginY]);\r
50896                         viewRect = viewRect.clone();\r
50897                         viewRect.applyTransform(m);\r
50898                     }\r
50899 \r
50900                     var viewBound = getBound(viewRect);\r
50901                     var mainBound = getBound(mainGroup.getBoundingRect());\r
50902                     var labelBound = getBound(labelGroup.getBoundingRect());\r
50903 \r
50904                     var mainPosition = mainGroup.position;\r
50905                     var labelsPosition = labelGroup.position;\r
50906 \r
50907                     labelsPosition[0] = mainPosition[0] = viewBound[0][0];\r
50908 \r
50909                     var labelPosOpt = layoutInfo.labelPosOpt;\r
50910 \r
50911                     if (isNaN(labelPosOpt)) { // '+' or '-'\r
50912                         var mainBoundIdx = labelPosOpt === '+' ? 0 : 1;\r
50913                         toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx);\r
50914                         toBound(labelsPosition, labelBound, viewBound, 1, 1 - mainBoundIdx);\r
50915                     }\r
50916                     else {\r
50917                         var mainBoundIdx = labelPosOpt >= 0 ? 0 : 1;\r
50918                         toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx);\r
50919                         labelsPosition[1] = mainPosition[1] + labelPosOpt;\r
50920                     }\r
50921 \r
50922                     mainGroup.position = mainPosition;\r
50923                     labelGroup.position = labelsPosition;\r
50924                     mainGroup.rotation = labelGroup.rotation = layoutInfo.rotation;\r
50925 \r
50926                     setOrigin(mainGroup);\r
50927                     setOrigin(labelGroup);\r
50928 \r
50929                     function setOrigin(targetGroup) {\r
50930                         var pos = targetGroup.position;\r
50931                         targetGroup.origin = [\r
50932                             viewBound[0][0] - pos[0],\r
50933                             viewBound[1][0] - pos[1]\r
50934                         ];\r
50935                     }\r
50936 \r
50937                     function getBound(rect) {\r
50938                         // [[xmin, xmax], [ymin, ymax]]\r
50939                         return [\r
50940                             [rect.x, rect.x + rect.width],\r
50941                             [rect.y, rect.y + rect.height]\r
50942                         ];\r
50943                     }\r
50944 \r
50945                     function toBound(fromPos, from, to, dimIdx, boundIdx) {\r
50946                         fromPos[dimIdx] += to[dimIdx][boundIdx] - from[dimIdx][boundIdx];\r
50947                     }\r
50948                 },\r
50949 \r
50950                 _createAxis: function (layoutInfo, timelineModel) {\r
50951                     var data = timelineModel.getData();\r
50952                     var axisType = timelineModel.get('axisType');\r
50953 \r
50954                     var scale = axisHelper.createScaleByModel(timelineModel, axisType);\r
50955                     var dataExtent = data.getDataExtent('value');\r
50956                     scale.setExtent(dataExtent[0], dataExtent[1]);\r
50957                     this._customizeScale(scale, data);\r
50958                     scale.niceTicks();\r
50959 \r
50960                     var axis = new TimelineAxis('value', scale, layoutInfo.axisExtent, axisType);\r
50961                     axis.model = timelineModel;\r
50962 \r
50963                     return axis;\r
50964                 },\r
50965 \r
50966                 _customizeScale: function (scale, data) {\r
50967 \r
50968                     scale.getTicks = function () {\r
50969                         return data.mapArray(['value'], function (value) {\r
50970                             return value;\r
50971                         });\r
50972                     };\r
50973 \r
50974                     scale.getTicksLabels = function () {\r
50975                         return zrUtil.map(this.getTicks(), scale.getLabel, scale);\r
50976                     };\r
50977                 },\r
50978 \r
50979                 _createGroup: function (name) {\r
50980                     var newGroup = this['_' + name] = new graphic.Group();\r
50981                     this.group.add(newGroup);\r
50982                     return newGroup;\r
50983                 },\r
50984 \r
50985                 _renderAxisLine: function (layoutInfo, group, axis, timelineModel) {\r
50986                     var axisExtent = axis.getExtent();\r
50987 \r
50988                     if (!timelineModel.get('lineStyle.show')) {\r
50989                         return;\r
50990                     }\r
50991 \r
50992                     group.add(new graphic.Line({\r
50993                         shape: {\r
50994                             x1: axisExtent[0], y1: 0,\r
50995                             x2: axisExtent[1], y2: 0\r
50996                         },\r
50997                         style: zrUtil.extend(\r
50998                             {lineCap: 'round'},\r
50999                             timelineModel.getModel('lineStyle').getLineStyle()\r
51000                         ),\r
51001                         silent: true,\r
51002                         z2: 1\r
51003                     }));\r
51004                 },\r
51005 \r
51006                 /**\r
51007                  * @private\r
51008                  */\r
51009                 _renderAxisTick: function (layoutInfo, group, axis, timelineModel) {\r
51010                     var data = timelineModel.getData();\r
51011                     var ticks = axis.scale.getTicks();\r
51012                     var tooltipHostModel = this._prepareTooltipHostModel(data, timelineModel);\r
51013 \r
51014                     each(ticks, function (value, dataIndex) {\r
51015 \r
51016                         var tickCoord = axis.dataToCoord(value);\r
51017                         var itemModel = data.getItemModel(dataIndex);\r
51018                         var itemStyleModel = itemModel.getModel('itemStyle.normal');\r
51019                         var hoverStyleModel = itemModel.getModel('itemStyle.emphasis');\r
51020                         var symbolOpt = {\r
51021                             position: [tickCoord, 0],\r
51022                             onclick: bind(this._changeTimeline, this, dataIndex)\r
51023                         };\r
51024                         var el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt);\r
51025                         graphic.setHoverStyle(el, hoverStyleModel.getItemStyle());\r
51026 \r
51027                         if (itemModel.get('tooltip')) {\r
51028                             el.dataIndex = dataIndex;\r
51029                             el.dataModel = tooltipHostModel;\r
51030                         }\r
51031                         else {\r
51032                             el.dataIndex = el.dataModel = null;\r
51033                         }\r
51034 \r
51035                     }, this);\r
51036                 },\r
51037 \r
51038                 /**\r
51039                  * @private\r
51040                  */\r
51041                 _prepareTooltipHostModel: function (data, timelineModel) {\r
51042                     var tooltipHostModel = modelUtil.createDataFormatModel(\r
51043                         {}, data, timelineModel.get('data')\r
51044                     );\r
51045                     var me = this;\r
51046 \r
51047                     tooltipHostModel.formatTooltip = function (dataIndex) {\r
51048                         return encodeHTML(me._axis.scale.getLabel(dataIndex));\r
51049                     };\r
51050 \r
51051                     return tooltipHostModel;\r
51052                 },\r
51053 \r
51054                 /**\r
51055                  * @private\r
51056                  */\r
51057                 _renderAxisLabel: function (layoutInfo, group, axis, timelineModel) {\r
51058                     var labelModel = timelineModel.getModel('label.normal');\r
51059 \r
51060                     if (!labelModel.get('show')) {\r
51061                         return;\r
51062                     }\r
51063 \r
51064                     var data = timelineModel.getData();\r
51065                     var ticks = axis.scale.getTicks();\r
51066                     var labels = axisHelper.getFormattedLabels(\r
51067                         axis, labelModel.get('formatter')\r
51068                     );\r
51069                     var labelInterval = axis.getLabelInterval();\r
51070 \r
51071                     each(ticks, function (tick, dataIndex) {\r
51072                         if (axis.isLabelIgnored(dataIndex, labelInterval)) {\r
51073                             return;\r
51074                         }\r
51075 \r
51076                         var itemModel = data.getItemModel(dataIndex);\r
51077                         var itemTextStyleModel = itemModel.getModel('label.normal.textStyle');\r
51078                         var hoverTextStyleModel = itemModel.getModel('label.emphasis.textStyle');\r
51079                         var tickCoord = axis.dataToCoord(tick);\r
51080                         var textEl = new graphic.Text({\r
51081                             style: {\r
51082                                 text: labels[dataIndex],\r
51083                                 textAlign: layoutInfo.labelAlign,\r
51084                                 textVerticalAlign: layoutInfo.labelBaseline,\r
51085                                 textFont: itemTextStyleModel.getFont(),\r
51086                                 fill: itemTextStyleModel.getTextColor()\r
51087                             },\r
51088                             position: [tickCoord, 0],\r
51089                             rotation: layoutInfo.labelRotation - layoutInfo.rotation,\r
51090                             onclick: bind(this._changeTimeline, this, dataIndex),\r
51091                             silent: false\r
51092                         });\r
51093 \r
51094                         group.add(textEl);\r
51095                         graphic.setHoverStyle(textEl, hoverTextStyleModel.getItemStyle());\r
51096 \r
51097                     }, this);\r
51098                 },\r
51099 \r
51100                 /**\r
51101                  * @private\r
51102                  */\r
51103                 _renderControl: function (layoutInfo, group, axis, timelineModel) {\r
51104                     var controlSize = layoutInfo.controlSize;\r
51105                     var rotation = layoutInfo.rotation;\r
51106 \r
51107                     var itemStyle = timelineModel.getModel('controlStyle.normal').getItemStyle();\r
51108                     var hoverStyle = timelineModel.getModel('controlStyle.emphasis').getItemStyle();\r
51109                     var rect = [0, -controlSize / 2, controlSize, controlSize];\r
51110                     var playState = timelineModel.getPlayState();\r
51111                     var inverse = timelineModel.get('inverse', true);\r
51112 \r
51113                     makeBtn(\r
51114                         layoutInfo.nextBtnPosition,\r
51115                         'controlStyle.nextIcon',\r
51116                         bind(this._changeTimeline, this, inverse ? '-' : '+')\r
51117                     );\r
51118                     makeBtn(\r
51119                         layoutInfo.prevBtnPosition,\r
51120                         'controlStyle.prevIcon',\r
51121                         bind(this._changeTimeline, this, inverse ? '+' : '-')\r
51122                     );\r
51123                     makeBtn(\r
51124                         layoutInfo.playPosition,\r
51125                         'controlStyle.' + (playState ? 'stopIcon' : 'playIcon'),\r
51126                         bind(this._handlePlayClick, this, !playState),\r
51127                         true\r
51128                     );\r
51129 \r
51130                     function makeBtn(position, iconPath, onclick, willRotate) {\r
51131                         if (!position) {\r
51132                             return;\r
51133                         }\r
51134                         var opt = {\r
51135                             position: position,\r
51136                             origin: [controlSize / 2, 0],\r
51137                             rotation: willRotate ? -rotation : 0,\r
51138                             rectHover: true,\r
51139                             style: itemStyle,\r
51140                             onclick: onclick\r
51141                         };\r
51142                         var btn = makeIcon(timelineModel, iconPath, rect, opt);\r
51143                         group.add(btn);\r
51144                         graphic.setHoverStyle(btn, hoverStyle);\r
51145                     }\r
51146                 },\r
51147 \r
51148                 _renderCurrentPointer: function (layoutInfo, group, axis, timelineModel) {\r
51149                     var data = timelineModel.getData();\r
51150                     var currentIndex = timelineModel.getCurrentIndex();\r
51151                     var pointerModel = data.getItemModel(currentIndex).getModel('checkpointStyle');\r
51152                     var me = this;\r
51153 \r
51154                     var callback = {\r
51155                         onCreate: function (pointer) {\r
51156                             pointer.draggable = true;\r
51157                             pointer.drift = bind(me._handlePointerDrag, me);\r
51158                             pointer.ondragend = bind(me._handlePointerDragend, me);\r
51159                             pointerMoveTo(pointer, currentIndex, axis, timelineModel, true);\r
51160                         },\r
51161                         onUpdate: function (pointer) {\r
51162                             pointerMoveTo(pointer, currentIndex, axis, timelineModel);\r
51163                         }\r
51164                     };\r
51165 \r
51166                     // Reuse when exists, for animation and drag.\r
51167                     this._currentPointer = giveSymbol(\r
51168                         pointerModel, pointerModel, this._mainGroup, {}, this._currentPointer, callback\r
51169                     );\r
51170                 },\r
51171 \r
51172                 _handlePlayClick: function (nextState) {\r
51173                     this._clearTimer();\r
51174                     this.api.dispatchAction({\r
51175                         type: 'timelinePlayChange',\r
51176                         playState: nextState,\r
51177                         from: this.uid\r
51178                     });\r
51179                 },\r
51180 \r
51181                 _handlePointerDrag: function (dx, dy, e) {\r
51182                     this._clearTimer();\r
51183                     this._pointerChangeTimeline([e.offsetX, e.offsetY]);\r
51184                 },\r
51185 \r
51186                 _handlePointerDragend: function (e) {\r
51187                     this._pointerChangeTimeline([e.offsetX, e.offsetY], true);\r
51188                 },\r
51189 \r
51190                 _pointerChangeTimeline: function (mousePos, trigger) {\r
51191                     var toCoord = this._toAxisCoord(mousePos)[0];\r
51192 \r
51193                     var axis = this._axis;\r
51194                     var axisExtent = numberUtil.asc(axis.getExtent().slice());\r
51195 \r
51196                     toCoord > axisExtent[1] && (toCoord = axisExtent[1]);\r
51197                     toCoord < axisExtent[0] && (toCoord = axisExtent[0]);\r
51198 \r
51199                     this._currentPointer.position[0] = toCoord;\r
51200                     this._currentPointer.dirty();\r
51201 \r
51202                     var targetDataIndex = this._findNearestTick(toCoord);\r
51203                     var timelineModel = this.model;\r
51204 \r
51205                     if (trigger || (\r
51206                         targetDataIndex !== timelineModel.getCurrentIndex()\r
51207                         && timelineModel.get('realtime')\r
51208                     )) {\r
51209                         this._changeTimeline(targetDataIndex);\r
51210                     }\r
51211                 },\r
51212 \r
51213                 _doPlayStop: function () {\r
51214                     this._clearTimer();\r
51215 \r
51216                     if (this.model.getPlayState()) {\r
51217                         this._timer = setTimeout(\r
51218                             bind(handleFrame, this),\r
51219                             this.model.get('playInterval')\r
51220                         );\r
51221                     }\r
51222 \r
51223                     function handleFrame() {\r
51224                         // Do not cache\r
51225                         var timelineModel = this.model;\r
51226                         this._changeTimeline(\r
51227                             timelineModel.getCurrentIndex()\r
51228                             + (timelineModel.get('rewind', true) ? -1 : 1)\r
51229                         );\r
51230                     }\r
51231                 },\r
51232 \r
51233                 _toAxisCoord: function (vertex) {\r
51234                     var trans = this._mainGroup.getLocalTransform();\r
51235                     return graphic.applyTransform(vertex, trans, true);\r
51236                 },\r
51237 \r
51238                 _findNearestTick: function (axisCoord) {\r
51239                     var data = this.model.getData();\r
51240                     var dist = Infinity;\r
51241                     var targetDataIndex;\r
51242                     var axis = this._axis;\r
51243 \r
51244                     data.each(['value'], function (value, dataIndex) {\r
51245                         var coord = axis.dataToCoord(value);\r
51246                         var d = Math.abs(coord - axisCoord);\r
51247                         if (d < dist) {\r
51248                             dist = d;\r
51249                             targetDataIndex = dataIndex;\r
51250                         }\r
51251                     });\r
51252 \r
51253                     return targetDataIndex;\r
51254                 },\r
51255 \r
51256                 _clearTimer: function () {\r
51257                     if (this._timer) {\r
51258                         clearTimeout(this._timer);\r
51259                         this._timer = null;\r
51260                     }\r
51261                 },\r
51262 \r
51263                 _changeTimeline: function (nextIndex) {\r
51264                     var currentIndex = this.model.getCurrentIndex();\r
51265 \r
51266                     if (nextIndex === '+') {\r
51267                         nextIndex = currentIndex + 1;\r
51268                     }\r
51269                     else if (nextIndex === '-') {\r
51270                         nextIndex = currentIndex - 1;\r
51271                     }\r
51272 \r
51273                     this.api.dispatchAction({\r
51274                         type: 'timelineChange',\r
51275                         currentIndex: nextIndex,\r
51276                         from: this.uid\r
51277                     });\r
51278                 }\r
51279 \r
51280             });\r
51281 \r
51282             function getViewRect(model, api) {\r
51283                 return layout.getLayoutRect(\r
51284                     model.getBoxLayoutParams(),\r
51285                     {\r
51286                         width: api.getWidth(),\r
51287                         height: api.getHeight()\r
51288                     },\r
51289                     model.get('padding')\r
51290                 );\r
51291             }\r
51292 \r
51293             function makeIcon(timelineModel, objPath, rect, opts) {\r
51294                 var icon = graphic.makePath(\r
51295                     timelineModel.get(objPath).replace(/^path:\/\//, ''),\r
51296                     zrUtil.clone(opts || {}),\r
51297                     new BoundingRect(rect[0], rect[1], rect[2], rect[3]),\r
51298                     'center'\r
51299                 );\r
51300 \r
51301                 return icon;\r
51302             }\r
51303 \r
51304             /**\r
51305              * Create symbol or update symbol\r
51306              */\r
51307             function giveSymbol(hostModel, itemStyleModel, group, opt, symbol, callback) {\r
51308                 var symbolType = hostModel.get('symbol');\r
51309                 var color = itemStyleModel.get('color');\r
51310                 var symbolSize = hostModel.get('symbolSize');\r
51311                 var halfSymbolSize = symbolSize / 2;\r
51312                 var itemStyle = itemStyleModel.getItemStyle(['color', 'symbol', 'symbolSize']);\r
51313 \r
51314                 if (!symbol) {\r
51315                     symbol = symbolUtil.createSymbol(\r
51316                         symbolType, -halfSymbolSize, -halfSymbolSize, symbolSize, symbolSize, color\r
51317                     );\r
51318                     group.add(symbol);\r
51319                     callback && callback.onCreate(symbol);\r
51320                 }\r
51321                 else {\r
51322                     symbol.setStyle(itemStyle);\r
51323                     symbol.setColor(color);\r
51324                     group.add(symbol); // Group may be new, also need to add.\r
51325                     callback && callback.onUpdate(symbol);\r
51326                 }\r
51327 \r
51328                 opt = zrUtil.merge({\r
51329                     rectHover: true,\r
51330                     style: itemStyle,\r
51331                     z2: 100\r
51332                 }, opt, true);\r
51333 \r
51334                 symbol.attr(opt);\r
51335 \r
51336                 return symbol;\r
51337             }\r
51338 \r
51339             function pointerMoveTo(pointer, dataIndex, axis, timelineModel, noAnimation) {\r
51340                 if (pointer.dragging) {\r
51341                     return;\r
51342                 }\r
51343 \r
51344                 var pointerModel = timelineModel.getModel('checkpointStyle');\r
51345                 var toCoord = axis.dataToCoord(timelineModel.getData().get(['value'], dataIndex));\r
51346 \r
51347                 if (noAnimation || !pointerModel.get('animation', true)) {\r
51348                     pointer.attr({position: [toCoord, 0]});\r
51349                 }\r
51350                 else {\r
51351                     pointer.stopAnimation(true);\r
51352                     pointer.animateTo(\r
51353                         {position: [toCoord, 0]},\r
51354                         pointerModel.get('animationDuration', true),\r
51355                         pointerModel.get('animationEasing', true)\r
51356                     );\r
51357                 }\r
51358             }\r
51359 \r
51360 \r
51361 \r
51362 /***/ },\r
51363 /* 329 */\r
51364 /***/ function(module, exports, __webpack_require__) {\r
51365 \r
51366         /**\r
51367          * @file Timeline view\r
51368          */\r
51369 \r
51370 \r
51371             // var zrUtil = require('zrender/lib/core/util');\r
51372             // var graphic = require('../../util/graphic');\r
51373             var ComponentView = __webpack_require__(28);\r
51374 \r
51375             module.exports = ComponentView.extend({\r
51376 \r
51377                 type: 'timeline'\r
51378             });\r
51379 \r
51380 \r
51381 \r
51382 /***/ },\r
51383 /* 330 */\r
51384 /***/ function(module, exports, __webpack_require__) {\r
51385 \r
51386         \r
51387 \r
51388             var zrUtil = __webpack_require__(3);\r
51389             var Axis = __webpack_require__(117);\r
51390             var axisHelper = __webpack_require__(108);\r
51391 \r
51392             /**\r
51393              * Extend axis 2d\r
51394              * @constructor module:echarts/coord/cartesian/Axis2D\r
51395              * @extends {module:echarts/coord/cartesian/Axis}\r
51396              * @param {string} dim\r
51397              * @param {*} scale\r
51398              * @param {Array.<number>} coordExtent\r
51399              * @param {string} axisType\r
51400              * @param {string} position\r
51401              */\r
51402             var TimelineAxis = function (dim, scale, coordExtent, axisType) {\r
51403 \r
51404                 Axis.call(this, dim, scale, coordExtent);\r
51405 \r
51406                 /**\r
51407                  * Axis type\r
51408                  *  - 'category'\r
51409                  *  - 'value'\r
51410                  *  - 'time'\r
51411                  *  - 'log'\r
51412                  * @type {string}\r
51413                  */\r
51414                 this.type = axisType || 'value';\r
51415 \r
51416                 /**\r
51417                  * @private\r
51418                  * @type {number}\r
51419                  */\r
51420                 this._autoLabelInterval;\r
51421 \r
51422                 /**\r
51423                  * Axis model\r
51424                  * @param {module:echarts/component/TimelineModel}\r
51425                  */\r
51426                 this.model = null;\r
51427             };\r
51428 \r
51429             TimelineAxis.prototype = {\r
51430 \r
51431                 constructor: TimelineAxis,\r
51432 \r
51433                 /**\r
51434                  * @public\r
51435                  * @return {number}\r
51436                  */\r
51437                 getLabelInterval: function () {\r
51438                     var timelineModel = this.model;\r
51439                     var labelModel = timelineModel.getModel('label.normal');\r
51440                     var labelInterval = labelModel.get('interval');\r
51441 \r
51442                     if (labelInterval != null && labelInterval != 'auto') {\r
51443                         return labelInterval;\r
51444                     }\r
51445 \r
51446                     var labelInterval = this._autoLabelInterval;\r
51447 \r
51448                     if (!labelInterval) {\r
51449                         labelInterval = this._autoLabelInterval = axisHelper.getAxisLabelInterval(\r
51450                             zrUtil.map(this.scale.getTicks(), this.dataToCoord, this),\r
51451                             axisHelper.getFormattedLabels(this, labelModel.get('formatter')),\r
51452                             labelModel.getModel('textStyle').getFont(),\r
51453                             timelineModel.get('orient') === 'horizontal'\r
51454                         );\r
51455                     }\r
51456 \r
51457                     return labelInterval;\r
51458                 },\r
51459 \r
51460                 /**\r
51461                  * If label is ignored.\r
51462                  * Automatically used when axis is category and label can not be all shown\r
51463                  * @public\r
51464                  * @param  {number} idx\r
51465                  * @return {boolean}\r
51466                  */\r
51467                 isLabelIgnored: function (idx) {\r
51468                     if (this.type === 'category') {\r
51469                         var labelInterval = this.getLabelInterval();\r
51470                         return ((typeof labelInterval === 'function')\r
51471                             && !labelInterval(idx, this.scale.getLabel(idx)))\r
51472                             || idx % (labelInterval + 1);\r
51473                     }\r
51474                 }\r
51475 \r
51476             };\r
51477 \r
51478             zrUtil.inherits(TimelineAxis, Axis);\r
51479 \r
51480             module.exports = TimelineAxis;\r
51481 \r
51482 \r
51483 /***/ },\r
51484 /* 331 */\r
51485 /***/ function(module, exports, __webpack_require__) {\r
51486 \r
51487         \r
51488 \r
51489             __webpack_require__(332);\r
51490             __webpack_require__(334);\r
51491 \r
51492             __webpack_require__(336);\r
51493             __webpack_require__(337);\r
51494             __webpack_require__(338);\r
51495             __webpack_require__(339);\r
51496             __webpack_require__(344);\r
51497 \r
51498 \r
51499 /***/ },\r
51500 /* 332 */\r
51501 /***/ function(module, exports, __webpack_require__) {\r
51502 \r
51503         \r
51504 \r
51505             var featureManager = __webpack_require__(333);\r
51506             var zrUtil = __webpack_require__(3);\r
51507 \r
51508             var ToolboxModel = __webpack_require__(1).extendComponentModel({\r
51509 \r
51510                 type: 'toolbox',\r
51511 \r
51512                 layoutMode: {\r
51513                     type: 'box',\r
51514                     ignoreSize: true\r
51515                 },\r
51516 \r
51517                 mergeDefaultAndTheme: function (option) {\r
51518                     ToolboxModel.superApply(this, 'mergeDefaultAndTheme', arguments);\r
51519 \r
51520                     zrUtil.each(this.option.feature, function (featureOpt, featureName) {\r
51521                         var Feature = featureManager.get(featureName);\r
51522                         Feature && zrUtil.merge(featureOpt, Feature.defaultOption);\r
51523                     });\r
51524                 },\r
51525 \r
51526                 defaultOption: {\r
51527 \r
51528                     show: true,\r
51529 \r
51530                     z: 6,\r
51531 \r
51532                     zlevel: 0,\r
51533 \r
51534                     orient: 'horizontal',\r
51535 \r
51536                     left: 'right',\r
51537 \r
51538                     top: 'top',\r
51539 \r
51540                     // right\r
51541                     // bottom\r
51542 \r
51543                     backgroundColor: 'transparent',\r
51544 \r
51545                     borderColor: '#ccc',\r
51546 \r
51547                     borderWidth: 0,\r
51548 \r
51549                     padding: 5,\r
51550 \r
51551                     itemSize: 15,\r
51552 \r
51553                     itemGap: 8,\r
51554 \r
51555                     showTitle: true,\r
51556 \r
51557                     iconStyle: {\r
51558                         normal: {\r
51559                             borderColor: '#666',\r
51560                             color: 'none'\r
51561                         },\r
51562                         emphasis: {\r
51563                             borderColor: '#3E98C5'\r
51564                         }\r
51565                     }\r
51566                     // textStyle: {},\r
51567 \r
51568                     // feature\r
51569                 }\r
51570             });\r
51571 \r
51572             module.exports = ToolboxModel;\r
51573 \r
51574 \r
51575 /***/ },\r
51576 /* 333 */\r
51577 /***/ function(module, exports) {\r
51578 \r
51579         'use strict';\r
51580 \r
51581 \r
51582             var features = {};\r
51583 \r
51584             module.exports = {\r
51585                 register: function (name, ctor) {\r
51586                     features[name] = ctor;\r
51587                 },\r
51588 \r
51589                 get: function (name) {\r
51590                     return features[name];\r
51591                 }\r
51592             };\r
51593 \r
51594 \r
51595 /***/ },\r
51596 /* 334 */\r
51597 /***/ function(module, exports, __webpack_require__) {\r
51598 \r
51599         /* WEBPACK VAR INJECTION */(function(process) {\r
51600 \r
51601             var featureManager = __webpack_require__(333);\r
51602             var zrUtil = __webpack_require__(3);\r
51603             var graphic = __webpack_require__(42);\r
51604             var Model = __webpack_require__(8);\r
51605             var DataDiffer = __webpack_require__(95);\r
51606             var listComponentHelper = __webpack_require__(266);\r
51607             var textContain = __webpack_require__(14);\r
51608 \r
51609             module.exports = __webpack_require__(1).extendComponentView({\r
51610 \r
51611                 type: 'toolbox',\r
51612 \r
51613                 render: function (toolboxModel, ecModel, api) {\r
51614                     var group = this.group;\r
51615                     group.removeAll();\r
51616 \r
51617                     if (!toolboxModel.get('show')) {\r
51618                         return;\r
51619                     }\r
51620 \r
51621                     var itemSize = +toolboxModel.get('itemSize');\r
51622                     var featureOpts = toolboxModel.get('feature') || {};\r
51623                     var features = this._features || (this._features = {});\r
51624 \r
51625                     var featureNames = [];\r
51626                     zrUtil.each(featureOpts, function (opt, name) {\r
51627                         featureNames.push(name);\r
51628                     });\r
51629 \r
51630                     (new DataDiffer(this._featureNames || [], featureNames))\r
51631                         .add(process)\r
51632                         .update(process)\r
51633                         .remove(zrUtil.curry(process, null))\r
51634                         .execute();\r
51635 \r
51636                     // Keep for diff.\r
51637                     this._featureNames = featureNames;\r
51638 \r
51639                     function process(newIndex, oldIndex) {\r
51640                         var featureName = featureNames[newIndex];\r
51641                         var oldName = featureNames[oldIndex];\r
51642                         var featureOpt = featureOpts[featureName];\r
51643                         var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel);\r
51644                         var feature;\r
51645 \r
51646                         if (featureName && !oldName) { // Create\r
51647                             if (isUserFeatureName(featureName)) {\r
51648                                 feature = {\r
51649                                     model: featureModel,\r
51650                                     onclick: featureModel.option.onclick,\r
51651                                     featureName: featureName\r
51652                                 };\r
51653                             }\r
51654                             else {\r
51655                                 var Feature = featureManager.get(featureName);\r
51656                                 if (!Feature) {\r
51657                                     return;\r
51658                                 }\r
51659                                 feature = new Feature(featureModel);\r
51660                             }\r
51661                             features[featureName] = feature;\r
51662                         }\r
51663                         else {\r
51664                             feature = features[oldName];\r
51665                             // If feature does not exsit.\r
51666                             if (!feature) {\r
51667                                 return;\r
51668                             }\r
51669                             feature.model = featureModel;\r
51670                         }\r
51671 \r
51672                         if (!featureName && oldName) {\r
51673                             feature.dispose && feature.dispose(ecModel, api);\r
51674                             return;\r
51675                         }\r
51676 \r
51677                         if (!featureModel.get('show') || feature.unusable) {\r
51678                             feature.remove && feature.remove(ecModel, api);\r
51679                             return;\r
51680                         }\r
51681 \r
51682                         createIconPaths(featureModel, feature, featureName);\r
51683 \r
51684                         featureModel.setIconStatus = function (iconName, status) {\r
51685                             var option = this.option;\r
51686                             var iconPaths = this.iconPaths;\r
51687                             option.iconStatus = option.iconStatus || {};\r
51688                             option.iconStatus[iconName] = status;\r
51689                             // FIXME\r
51690                             iconPaths[iconName] && iconPaths[iconName].trigger(status);\r
51691                         };\r
51692 \r
51693                         if (feature.render) {\r
51694                             feature.render(featureModel, ecModel, api);\r
51695                         }\r
51696                     }\r
51697 \r
51698                     function createIconPaths(featureModel, feature, featureName) {\r
51699                         var iconStyleModel = featureModel.getModel('iconStyle');\r
51700 \r
51701                         // If one feature has mutiple icon. they are orginaized as\r
51702                         // {\r
51703                         //     icon: {\r
51704                         //         foo: '',\r
51705                         //         bar: ''\r
51706                         //     },\r
51707                         //     title: {\r
51708                         //         foo: '',\r
51709                         //         bar: ''\r
51710                         //     }\r
51711                         // }\r
51712                         var icons = feature.getIcons ? feature.getIcons() : featureModel.get('icon');\r
51713                         var titles = featureModel.get('title') || {};\r
51714                         if (typeof icons === 'string') {\r
51715                             var icon = icons;\r
51716                             var title = titles;\r
51717                             icons = {};\r
51718                             titles = {};\r
51719                             icons[featureName] = icon;\r
51720                             titles[featureName] = title;\r
51721                         }\r
51722                         var iconPaths = featureModel.iconPaths = {};\r
51723                         zrUtil.each(icons, function (icon, iconName) {\r
51724                             var normalStyle = iconStyleModel.getModel('normal').getItemStyle();\r
51725                             var hoverStyle = iconStyleModel.getModel('emphasis').getItemStyle();\r
51726 \r
51727                             var style = {\r
51728                                 x: -itemSize / 2,\r
51729                                 y: -itemSize / 2,\r
51730                                 width: itemSize,\r
51731                                 height: itemSize\r
51732                             };\r
51733                             var path = icon.indexOf('image://') === 0\r
51734                                 ? (\r
51735                                     style.image = icon.slice(8),\r
51736                                     new graphic.Image({style: style})\r
51737                                 )\r
51738                                 : graphic.makePath(\r
51739                                     icon.replace('path://', ''),\r
51740                                     {\r
51741                                         style: normalStyle,\r
51742                                         hoverStyle: hoverStyle,\r
51743                                         rectHover: true\r
51744                                     },\r
51745                                     style,\r
51746                                     'center'\r
51747                                 );\r
51748 \r
51749                             graphic.setHoverStyle(path);\r
51750 \r
51751                             if (toolboxModel.get('showTitle')) {\r
51752                                 path.__title = titles[iconName];\r
51753                                 path.on('mouseover', function () {\r
51754                                         path.setStyle({\r
51755                                             text: titles[iconName],\r
51756                                             textPosition: hoverStyle.textPosition || 'bottom',\r
51757                                             textFill: hoverStyle.fill || hoverStyle.stroke || '#000',\r
51758                                             textAlign: hoverStyle.textAlign || 'center'\r
51759                                         });\r
51760                                     })\r
51761                                     .on('mouseout', function () {\r
51762                                         path.setStyle({\r
51763                                             textFill: null\r
51764                                         });\r
51765                                     });\r
51766                             }\r
51767                             path.trigger(featureModel.get('iconStatus.' + iconName) || 'normal');\r
51768 \r
51769                             group.add(path);\r
51770                             path.on('click', zrUtil.bind(\r
51771                                 feature.onclick, feature, ecModel, api, iconName\r
51772                             ));\r
51773 \r
51774                             iconPaths[iconName] = path;\r
51775                         });\r
51776                     }\r
51777 \r
51778                     listComponentHelper.layout(group, toolboxModel, api);\r
51779                     // Render background after group is layout\r
51780                     // FIXME\r
51781                     listComponentHelper.addBackground(group, toolboxModel);\r
51782 \r
51783                     // Adjust icon title positions to avoid them out of screen\r
51784                     group.eachChild(function (icon) {\r
51785                         var titleText = icon.__title;\r
51786                         var hoverStyle = icon.hoverStyle;\r
51787                         // May be background element\r
51788                         if (hoverStyle && titleText) {\r
51789                             var rect = textContain.getBoundingRect(\r
51790                                 titleText, hoverStyle.font\r
51791                             );\r
51792                             var offsetX = icon.position[0] + group.position[0];\r
51793                             var offsetY = icon.position[1] + group.position[1] + itemSize;\r
51794 \r
51795                             var needPutOnTop = false;\r
51796                             if (offsetY + rect.height > api.getHeight()) {\r
51797                                 hoverStyle.textPosition = 'top';\r
51798                                 needPutOnTop = true;\r
51799                             }\r
51800                             var topOffset = needPutOnTop ? (-5 - rect.height) : (itemSize + 8);\r
51801                             if (offsetX + rect.width /  2 > api.getWidth()) {\r
51802                                 hoverStyle.textPosition = ['100%', topOffset];\r
51803                                 hoverStyle.textAlign = 'right';\r
51804                             }\r
51805                             else if (offsetX - rect.width / 2 < 0) {\r
51806                                 hoverStyle.textPosition = [0, topOffset];\r
51807                                 hoverStyle.textAlign = 'left';\r
51808                             }\r
51809                         }\r
51810                     });\r
51811                 },\r
51812 \r
51813                 remove: function (ecModel, api) {\r
51814                     zrUtil.each(this._features, function (feature) {\r
51815                         feature.remove && feature.remove(ecModel, api);\r
51816                     });\r
51817                     this.group.removeAll();\r
51818                 },\r
51819 \r
51820                 dispose: function (ecModel, api) {\r
51821                     zrUtil.each(this._features, function (feature) {\r
51822                         feature.dispose && feature.dispose(ecModel, api);\r
51823                     });\r
51824                 }\r
51825             });\r
51826 \r
51827             function isUserFeatureName(featureName) {\r
51828                 return featureName.indexOf('my') === 0;\r
51829             }\r
51830 \r
51831 \r
51832         /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(335)))\r
51833 \r
51834 /***/ },\r
51835 /* 335 */\r
51836 /***/ function(module, exports) {\r
51837 \r
51838         // shim for using process in browser\r
51839 \r
51840         var process = module.exports = {};\r
51841         var queue = [];\r
51842         var draining = false;\r
51843         var currentQueue;\r
51844         var queueIndex = -1;\r
51845 \r
51846         function cleanUpNextTick() {\r
51847             draining = false;\r
51848             if (currentQueue.length) {\r
51849                 queue = currentQueue.concat(queue);\r
51850             } else {\r
51851                 queueIndex = -1;\r
51852             }\r
51853             if (queue.length) {\r
51854                 drainQueue();\r
51855             }\r
51856         }\r
51857 \r
51858         function drainQueue() {\r
51859             if (draining) {\r
51860                 return;\r
51861             }\r
51862             var timeout = setTimeout(cleanUpNextTick);\r
51863             draining = true;\r
51864 \r
51865             var len = queue.length;\r
51866             while(len) {\r
51867                 currentQueue = queue;\r
51868                 queue = [];\r
51869                 while (++queueIndex < len) {\r
51870                     if (currentQueue) {\r
51871                         currentQueue[queueIndex].run();\r
51872                     }\r
51873                 }\r
51874                 queueIndex = -1;\r
51875                 len = queue.length;\r
51876             }\r
51877             currentQueue = null;\r
51878             draining = false;\r
51879             clearTimeout(timeout);\r
51880         }\r
51881 \r
51882         process.nextTick = function (fun) {\r
51883             var args = new Array(arguments.length - 1);\r
51884             if (arguments.length > 1) {\r
51885                 for (var i = 1; i < arguments.length; i++) {\r
51886                     args[i - 1] = arguments[i];\r
51887                 }\r
51888             }\r
51889             queue.push(new Item(fun, args));\r
51890             if (queue.length === 1 && !draining) {\r
51891                 setTimeout(drainQueue, 0);\r
51892             }\r
51893         };\r
51894 \r
51895         // v8 likes predictible objects\r
51896         function Item(fun, array) {\r
51897             this.fun = fun;\r
51898             this.array = array;\r
51899         }\r
51900         Item.prototype.run = function () {\r
51901             this.fun.apply(null, this.array);\r
51902         };\r
51903         process.title = 'browser';\r
51904         process.browser = true;\r
51905         process.env = {};\r
51906         process.argv = [];\r
51907         process.version = ''; // empty string to avoid regexp issues\r
51908         process.versions = {};\r
51909 \r
51910         function noop() {}\r
51911 \r
51912         process.on = noop;\r
51913         process.addListener = noop;\r
51914         process.once = noop;\r
51915         process.off = noop;\r
51916         process.removeListener = noop;\r
51917         process.removeAllListeners = noop;\r
51918         process.emit = noop;\r
51919 \r
51920         process.binding = function (name) {\r
51921             throw new Error('process.binding is not supported');\r
51922         };\r
51923 \r
51924         process.cwd = function () { return '/' };\r
51925         process.chdir = function (dir) {\r
51926             throw new Error('process.chdir is not supported');\r
51927         };\r
51928         process.umask = function() { return 0; };\r
51929 \r
51930 \r
51931 /***/ },\r
51932 /* 336 */\r
51933 /***/ function(module, exports, __webpack_require__) {\r
51934 \r
51935         \r
51936 \r
51937             var env = __webpack_require__(78);\r
51938 \r
51939             function SaveAsImage (model) {\r
51940                 this.model = model;\r
51941             }\r
51942 \r
51943             SaveAsImage.defaultOption = {\r
51944                 show: true,\r
51945                 icon: 'M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0',\r
51946                 title: '保存为图片',\r
51947                 type: 'png',\r
51948                 // Default use option.backgroundColor\r
51949                 // backgroundColor: '#fff',\r
51950                 name: '',\r
51951                 excludeComponents: ['toolbox'],\r
51952                 pixelRatio: 1,\r
51953                 lang: ['右键另存为图片']\r
51954             };\r
51955 \r
51956             SaveAsImage.prototype.unusable = !env.canvasSupported;\r
51957 \r
51958             var proto = SaveAsImage.prototype;\r
51959 \r
51960             proto.onclick = function (ecModel, api) {\r
51961                 var model = this.model;\r
51962                 var title = model.get('name') || ecModel.get('title.0.text') || 'echarts';\r
51963                 var $a = document.createElement('a');\r
51964                 var type = model.get('type', true) || 'png';\r
51965                 $a.download = title + '.' + type;\r
51966                 $a.target = '_blank';\r
51967                 var url = api.getConnectedDataURL({\r
51968                     type: type,\r
51969                     backgroundColor: model.get('backgroundColor', true)\r
51970                         || ecModel.get('backgroundColor') || '#fff',\r
51971                     excludeComponents: model.get('excludeComponents'),\r
51972                     pixelRatio: model.get('pixelRatio')\r
51973                 });\r
51974                 $a.href = url;\r
51975                 // Chrome and Firefox\r
51976                 if (typeof MouseEvent === 'function') {\r
51977                     var evt = new MouseEvent('click', {\r
51978                         view: window,\r
51979                         bubbles: true,\r
51980                         cancelable: false\r
51981                     });\r
51982                     $a.dispatchEvent(evt);\r
51983                 }\r
51984                 // IE\r
51985                 else {\r
51986                     var lang = model.get('lang');\r
51987                     var html = ''\r
51988                         + '<body style="margin:0;">'\r
51989                         + '<img src="' + url + '" style="max-width:100%;" title="' + ((lang && lang[0]) || '') + '" />'\r
51990                         + '</body>';\r
51991                     var tab = window.open();\r
51992                     tab.document.write(html);\r
51993                 }\r
51994             };\r
51995 \r
51996             __webpack_require__(333).register(\r
51997                 'saveAsImage', SaveAsImage\r
51998             );\r
51999 \r
52000             module.exports = SaveAsImage;\r
52001 \r
52002 \r
52003 /***/ },\r
52004 /* 337 */\r
52005 /***/ function(module, exports, __webpack_require__) {\r
52006 \r
52007         'use strict';\r
52008 \r
52009 \r
52010             var zrUtil = __webpack_require__(3);\r
52011 \r
52012             function MagicType(model) {\r
52013                 this.model = model;\r
52014             }\r
52015 \r
52016             MagicType.defaultOption = {\r
52017                 show: true,\r
52018                 type: [],\r
52019                 // Icon group\r
52020                 icon: {\r
52021                     line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4',\r
52022                     bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7',\r
52023                     stack: 'M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z', // jshint ignore:line\r
52024                     tiled: 'M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z'\r
52025                 },\r
52026                 title: {\r
52027                     line: '切换为折线图',\r
52028                     bar: '切换为柱状图',\r
52029                     stack: '切换为堆叠',\r
52030                     tiled: '切换为平铺'\r
52031                 },\r
52032                 option: {},\r
52033                 seriesIndex: {}\r
52034             };\r
52035 \r
52036             var proto = MagicType.prototype;\r
52037 \r
52038             proto.getIcons = function () {\r
52039                 var model = this.model;\r
52040                 var availableIcons = model.get('icon');\r
52041                 var icons = {};\r
52042                 zrUtil.each(model.get('type'), function (type) {\r
52043                     if (availableIcons[type]) {\r
52044                         icons[type] = availableIcons[type];\r
52045                     }\r
52046                 });\r
52047                 return icons;\r
52048             };\r
52049 \r
52050             var seriesOptGenreator = {\r
52051                 'line': function (seriesType, seriesId, seriesModel, model) {\r
52052                     if (seriesType === 'bar') {\r
52053                         return zrUtil.merge({\r
52054                             id: seriesId,\r
52055                             type: 'line',\r
52056                             // Preserve data related option\r
52057                             data: seriesModel.get('data'),\r
52058                             stack: seriesModel.get('stack'),\r
52059                             markPoint: seriesModel.get('markPoint'),\r
52060                             markLine: seriesModel.get('markLine')\r
52061                         }, model.get('option.line') || {}, true);\r
52062                     }\r
52063                 },\r
52064                 'bar': function (seriesType, seriesId, seriesModel, model) {\r
52065                     if (seriesType === 'line') {\r
52066                         return zrUtil.merge({\r
52067                             id: seriesId,\r
52068                             type: 'bar',\r
52069                             // Preserve data related option\r
52070                             data: seriesModel.get('data'),\r
52071                             stack: seriesModel.get('stack'),\r
52072                             markPoint: seriesModel.get('markPoint'),\r
52073                             markLine: seriesModel.get('markLine')\r
52074                         }, model.get('option.bar') || {}, true);\r
52075                     }\r
52076                 },\r
52077                 'stack': function (seriesType, seriesId, seriesModel, model) {\r
52078                     if (seriesType === 'line' || seriesType === 'bar') {\r
52079                         return zrUtil.merge({\r
52080                             id: seriesId,\r
52081                             stack: '__ec_magicType_stack__'\r
52082                         }, model.get('option.stack') || {}, true);\r
52083                     }\r
52084                 },\r
52085                 'tiled': function (seriesType, seriesId, seriesModel, model) {\r
52086                     if (seriesType === 'line' || seriesType === 'bar') {\r
52087                         return zrUtil.merge({\r
52088                             id: seriesId,\r
52089                             stack: ''\r
52090                         }, model.get('option.tiled') || {}, true);\r
52091                     }\r
52092                 }\r
52093             };\r
52094 \r
52095             var radioTypes = [\r
52096                 ['line', 'bar'],\r
52097                 ['stack', 'tiled']\r
52098             ];\r
52099 \r
52100             proto.onclick = function (ecModel, api, type) {\r
52101                 var model = this.model;\r
52102                 var seriesIndex = model.get('seriesIndex.' + type);\r
52103                 // Not supported magicType\r
52104                 if (!seriesOptGenreator[type]) {\r
52105                     return;\r
52106                 }\r
52107                 var newOption = {\r
52108                     series: []\r
52109                 };\r
52110                 var generateNewSeriesTypes = function (seriesModel) {\r
52111                     var seriesType = seriesModel.subType;\r
52112                     var seriesId = seriesModel.id;\r
52113                     var newSeriesOpt = seriesOptGenreator[type](\r
52114                         seriesType, seriesId, seriesModel, model\r
52115                     );\r
52116                     if (newSeriesOpt) {\r
52117                         // PENDING If merge original option?\r
52118                         zrUtil.defaults(newSeriesOpt, seriesModel.option);\r
52119                         newOption.series.push(newSeriesOpt);\r
52120                     }\r
52121                     // Modify boundaryGap\r
52122                     var coordSys = seriesModel.coordinateSystem;\r
52123                     if (coordSys.type === 'cartesian2d') {\r
52124                         var categoryAxis = coordSys.getAxesByScale('ordinal')[0];\r
52125                         if (categoryAxis) {\r
52126                             var axisDim = categoryAxis.dim;\r
52127                             var axisIndex = seriesModel.get(axisDim + 'AxisIndex');\r
52128                             var axisKey = axisDim + 'Axis';\r
52129                             newOption[axisKey] = newOption[axisKey] || [];\r
52130                             for (var i = 0; i <= axisIndex; i++) {\r
52131                                 newOption[axisKey][axisIndex] = newOption[axisKey][axisIndex] || {};\r
52132                             }\r
52133                             newOption[axisKey][axisIndex].boundaryGap = type === 'bar' ? true : false;\r
52134                         }\r
52135                     }\r
52136                 };\r
52137 \r
52138                 zrUtil.each(radioTypes, function (radio) {\r
52139                     if (zrUtil.indexOf(radio, type) >= 0) {\r
52140                         zrUtil.each(radio, function (item) {\r
52141                             model.setIconStatus(item, 'normal');\r
52142                         });\r
52143                     }\r
52144                 });\r
52145 \r
52146                 model.setIconStatus(type, 'emphasis');\r
52147 \r
52148                 ecModel.eachComponent(\r
52149                     {\r
52150                         mainType: 'series',\r
52151                         query: seriesIndex == null ? null : {\r
52152                             seriesIndex: seriesIndex\r
52153                         }\r
52154                     }, generateNewSeriesTypes\r
52155                 );\r
52156                 api.dispatchAction({\r
52157                     type: 'changeMagicType',\r
52158                     currentType: type,\r
52159                     newOption: newOption\r
52160                 });\r
52161             };\r
52162 \r
52163             var echarts = __webpack_require__(1);\r
52164             echarts.registerAction({\r
52165                 type: 'changeMagicType',\r
52166                 event: 'magicTypeChanged',\r
52167                 update: 'prepareAndUpdate'\r
52168             }, function (payload, ecModel) {\r
52169                 ecModel.mergeOption(payload.newOption);\r
52170             });\r
52171 \r
52172             __webpack_require__(333).register('magicType', MagicType);\r
52173 \r
52174             module.exports = MagicType;\r
52175 \r
52176 \r
52177 /***/ },\r
52178 /* 338 */\r
52179 /***/ function(module, exports, __webpack_require__) {\r
52180 \r
52181         /**\r
52182          * @module echarts/component/toolbox/feature/DataView\r
52183          */\r
52184 \r
52185 \r
52186 \r
52187             var zrUtil = __webpack_require__(3);\r
52188             var eventTool = __webpack_require__(80);\r
52189 \r
52190 \r
52191             var BLOCK_SPLITER = new Array(60).join('-');\r
52192             var ITEM_SPLITER = '\t';\r
52193             /**\r
52194              * Group series into two types\r
52195              *  1. on category axis, like line, bar\r
52196              *  2. others, like scatter, pie\r
52197              * @param {module:echarts/model/Global} ecModel\r
52198              * @return {Object}\r
52199              * @inner\r
52200              */\r
52201             function groupSeries(ecModel) {\r
52202                 var seriesGroupByCategoryAxis = {};\r
52203                 var otherSeries = [];\r
52204                 var meta = [];\r
52205                 ecModel.eachRawSeries(function (seriesModel) {\r
52206                     var coordSys = seriesModel.coordinateSystem;\r
52207 \r
52208                     if (coordSys && (coordSys.type === 'cartesian2d' || coordSys.type === 'polar')) {\r
52209                         var baseAxis = coordSys.getBaseAxis();\r
52210                         if (baseAxis.type === 'category') {\r
52211                             var key = baseAxis.dim + '_' + baseAxis.index;\r
52212                             if (!seriesGroupByCategoryAxis[key]) {\r
52213                                 seriesGroupByCategoryAxis[key] = {\r
52214                                     categoryAxis: baseAxis,\r
52215                                     valueAxis: coordSys.getOtherAxis(baseAxis),\r
52216                                     series: []\r
52217                                 };\r
52218                                 meta.push({\r
52219                                     axisDim: baseAxis.dim,\r
52220                                     axisIndex: baseAxis.index\r
52221                                 });\r
52222                             }\r
52223                             seriesGroupByCategoryAxis[key].series.push(seriesModel);\r
52224                         }\r
52225                         else {\r
52226                             otherSeries.push(seriesModel);\r
52227                         }\r
52228                     }\r
52229                     else {\r
52230                         otherSeries.push(seriesModel);\r
52231                     }\r
52232                 });\r
52233 \r
52234                 return {\r
52235                     seriesGroupByCategoryAxis: seriesGroupByCategoryAxis,\r
52236                     other: otherSeries,\r
52237                     meta: meta\r
52238                 };\r
52239             }\r
52240 \r
52241             /**\r
52242              * Assemble content of series on cateogory axis\r
52243              * @param {Array.<module:echarts/model/Series>} series\r
52244              * @return {string}\r
52245              * @inner\r
52246              */\r
52247             function assembleSeriesWithCategoryAxis(series) {\r
52248                 var tables = [];\r
52249                 zrUtil.each(series, function (group, key) {\r
52250                     var categoryAxis = group.categoryAxis;\r
52251                     var valueAxis = group.valueAxis;\r
52252                     var valueAxisDim = valueAxis.dim;\r
52253 \r
52254                     var headers = [' '].concat(zrUtil.map(group.series, function (series) {\r
52255                         return series.name;\r
52256                     }));\r
52257                     var columns = [categoryAxis.model.getCategories()];\r
52258                     zrUtil.each(group.series, function (series) {\r
52259                         columns.push(series.getRawData().mapArray(valueAxisDim, function (val) {\r
52260                             return val;\r
52261                         }));\r
52262                     });\r
52263                     // Assemble table content\r
52264                     var lines = [headers.join(ITEM_SPLITER)];\r
52265                     for (var i = 0; i < columns[0].length; i++) {\r
52266                         var items = [];\r
52267                         for (var j = 0; j < columns.length; j++) {\r
52268                             items.push(columns[j][i]);\r
52269                         }\r
52270                         lines.push(items.join(ITEM_SPLITER));\r
52271                     }\r
52272                     tables.push(lines.join('\n'));\r
52273                 });\r
52274                 return tables.join('\n\n' +  BLOCK_SPLITER + '\n\n');\r
52275             }\r
52276 \r
52277             /**\r
52278              * Assemble content of other series\r
52279              * @param {Array.<module:echarts/model/Series>} series\r
52280              * @return {string}\r
52281              * @inner\r
52282              */\r
52283             function assembleOtherSeries(series) {\r
52284                 return zrUtil.map(series, function (series) {\r
52285                     var data = series.getRawData();\r
52286                     var lines = [series.name];\r
52287                     var vals = [];\r
52288                     data.each(data.dimensions, function () {\r
52289                         var argLen = arguments.length;\r
52290                         var dataIndex = arguments[argLen - 1];\r
52291                         var name = data.getName(dataIndex);\r
52292                         for (var i = 0; i < argLen - 1; i++) {\r
52293                             vals[i] = arguments[i];\r
52294                         }\r
52295                         lines.push((name ? (name + ITEM_SPLITER) : '') + vals.join(ITEM_SPLITER));\r
52296                     });\r
52297                     return lines.join('\n');\r
52298                 }).join('\n\n' + BLOCK_SPLITER + '\n\n');\r
52299             }\r
52300 \r
52301             /**\r
52302              * @param {module:echarts/model/Global}\r
52303              * @return {string}\r
52304              * @inner\r
52305              */\r
52306             function getContentFromModel(ecModel) {\r
52307 \r
52308                 var result = groupSeries(ecModel);\r
52309 \r
52310                 return {\r
52311                     value: zrUtil.filter([\r
52312                             assembleSeriesWithCategoryAxis(result.seriesGroupByCategoryAxis),\r
52313                             assembleOtherSeries(result.other)\r
52314                         ], function (str) {\r
52315                             return str.replace(/[\n\t\s]/g, '');\r
52316                         }).join('\n\n' + BLOCK_SPLITER + '\n\n'),\r
52317 \r
52318                     meta: result.meta\r
52319                 };\r
52320             }\r
52321 \r
52322 \r
52323             function trim(str) {\r
52324                 return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');\r
52325             }\r
52326             /**\r
52327              * If a block is tsv format\r
52328              */\r
52329             function isTSVFormat(block) {\r
52330                 // Simple method to find out if a block is tsv format\r
52331                 var firstLine = block.slice(0, block.indexOf('\n'));\r
52332                 if (firstLine.indexOf(ITEM_SPLITER) >= 0) {\r
52333                     return true;\r
52334                 }\r
52335             }\r
52336 \r
52337             var itemSplitRegex = new RegExp('[' + ITEM_SPLITER + ']+', 'g');\r
52338             /**\r
52339              * @param {string} tsv\r
52340              * @return {Array.<Object>}\r
52341              */\r
52342             function parseTSVContents(tsv) {\r
52343                 var tsvLines = tsv.split(/\n+/g);\r
52344                 var headers = trim(tsvLines.shift()).split(itemSplitRegex);\r
52345 \r
52346                 var categories = [];\r
52347                 var series = zrUtil.map(headers, function (header) {\r
52348                     return {\r
52349                         name: header,\r
52350                         data: []\r
52351                     };\r
52352                 });\r
52353                 for (var i = 0; i < tsvLines.length; i++) {\r
52354                     var items = trim(tsvLines[i]).split(itemSplitRegex);\r
52355                     categories.push(items.shift());\r
52356                     for (var j = 0; j < items.length; j++) {\r
52357                         series[j] && (series[j].data[i] = items[j]);\r
52358                     }\r
52359                 }\r
52360                 return {\r
52361                     series: series,\r
52362                     categories: categories\r
52363                 };\r
52364             }\r
52365 \r
52366             /**\r
52367              * @param {string} str\r
52368              * @return {Array.<Object>}\r
52369              * @inner\r
52370              */\r
52371             function parseListContents(str) {\r
52372                 var lines = str.split(/\n+/g);\r
52373                 var seriesName = trim(lines.shift());\r
52374 \r
52375                 var data = [];\r
52376                 for (var i = 0; i < lines.length; i++) {\r
52377                     var items = trim(lines[i]).split(itemSplitRegex);\r
52378                     var name = '';\r
52379                     var value;\r
52380                     var hasName = false;\r
52381                     if (isNaN(items[0])) { // First item is name\r
52382                         hasName = true;\r
52383                         name = items[0];\r
52384                         items = items.slice(1);\r
52385                         data[i] = {\r
52386                             name: name,\r
52387                             value: []\r
52388                         };\r
52389                         value = data[i].value;\r
52390                     }\r
52391                     else {\r
52392                         value = data[i] = [];\r
52393                     }\r
52394                     for (var j = 0; j < items.length; j++) {\r
52395                         value.push(+items[j]);\r
52396                     }\r
52397                     if (value.length === 1) {\r
52398                         hasName ? (data[i].value = value[0]) : (data[i] = value[0]);\r
52399                     }\r
52400                 }\r
52401 \r
52402                 return {\r
52403                     name: seriesName,\r
52404                     data: data\r
52405                 };\r
52406             }\r
52407 \r
52408             /**\r
52409              * @param {string} str\r
52410              * @param {Array.<Object>} blockMetaList\r
52411              * @return {Object}\r
52412              * @inner\r
52413              */\r
52414             function parseContents(str, blockMetaList) {\r
52415                 var blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g'));\r
52416                 var newOption = {\r
52417                     series: []\r
52418                 };\r
52419                 zrUtil.each(blocks, function (block, idx) {\r
52420                     if (isTSVFormat(block)) {\r
52421                         var result = parseTSVContents(block);\r
52422                         var blockMeta = blockMetaList[idx];\r
52423                         var axisKey = blockMeta.axisDim + 'Axis';\r
52424 \r
52425                         if (blockMeta) {\r
52426                             newOption[axisKey] = newOption[axisKey] || [];\r
52427                             newOption[axisKey][blockMeta.axisIndex] = {\r
52428                                 data: result.categories\r
52429                             };\r
52430                             newOption.series = newOption.series.concat(result.series);\r
52431                         }\r
52432                     }\r
52433                     else {\r
52434                         var result = parseListContents(block);\r
52435                         newOption.series.push(result);\r
52436                     }\r
52437                 });\r
52438                 return newOption;\r
52439             }\r
52440 \r
52441             /**\r
52442              * @alias {module:echarts/component/toolbox/feature/DataView}\r
52443              * @constructor\r
52444              * @param {module:echarts/model/Model} model\r
52445              */\r
52446             function DataView(model) {\r
52447 \r
52448                 this._dom = null;\r
52449 \r
52450                 this.model = model;\r
52451             }\r
52452 \r
52453             DataView.defaultOption = {\r
52454                 show: true,\r
52455                 readOnly: false,\r
52456                 optionToContent: null,\r
52457                 contentToOption: null,\r
52458 \r
52459                 icon: 'M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28',\r
52460                 title: '数据视图',\r
52461                 lang: ['数据视图', '关闭', '刷新'],\r
52462                 backgroundColor: '#fff',\r
52463                 textColor: '#000',\r
52464                 textareaColor: '#fff',\r
52465                 textareaBorderColor: '#333',\r
52466                 buttonColor: '#c23531',\r
52467                 buttonTextColor: '#fff'\r
52468             };\r
52469 \r
52470             DataView.prototype.onclick = function (ecModel, api) {\r
52471                 var container = api.getDom();\r
52472                 var model = this.model;\r
52473                 if (this._dom) {\r
52474                     container.removeChild(this._dom);\r
52475                 }\r
52476                 var root = document.createElement('div');\r
52477                 root.style.cssText = 'position:absolute;left:5px;top:5px;bottom:5px;right:5px;';\r
52478                 root.style.backgroundColor = model.get('backgroundColor') || '#fff';\r
52479 \r
52480                 // Create elements\r
52481                 var header = document.createElement('h4');\r
52482                 var lang = model.get('lang') || [];\r
52483                 header.innerHTML = lang[0] || model.get('title');\r
52484                 header.style.cssText = 'margin: 10px 20px;';\r
52485                 header.style.color = model.get('textColor');\r
52486 \r
52487                 var viewMain = document.createElement('div');\r
52488                 var textarea = document.createElement('textarea');\r
52489                 viewMain.style.cssText = 'display:block;width:100%;overflow:hidden;';\r
52490 \r
52491                 var optionToContent = model.get('optionToContent');\r
52492                 var contentToOption = model.get('contentToOption');\r
52493                 var result = getContentFromModel(ecModel);\r
52494                 if (typeof optionToContent === 'function') {\r
52495                     var htmlOrDom = optionToContent(api.getOption());\r
52496                     if (typeof htmlOrDom === 'string') {\r
52497                         viewMain.innerHTML = htmlOrDom;\r
52498                     }\r
52499                     else if (zrUtil.isDom(htmlOrDom)) {\r
52500                         viewMain.appendChild(htmlOrDom);\r
52501                     }\r
52502                 }\r
52503                 else {\r
52504                     // Use default textarea\r
52505                     viewMain.appendChild(textarea);\r
52506                     textarea.readOnly = model.get('readOnly');\r
52507                     textarea.style.cssText = 'width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;';\r
52508                     textarea.style.color = model.get('textColor');\r
52509                     textarea.style.borderColor = model.get('textareaBorderColor');\r
52510                     textarea.style.backgroundColor = model.get('textareaColor');\r
52511                     textarea.value = result.value;\r
52512                 }\r
52513 \r
52514                 var blockMetaList = result.meta;\r
52515 \r
52516                 var buttonContainer = document.createElement('div');\r
52517                 buttonContainer.style.cssText = 'position:absolute;bottom:0;left:0;right:0;';\r
52518 \r
52519                 var buttonStyle = 'float:right;margin-right:20px;border:none;'\r
52520                     + 'cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px';\r
52521                 var closeButton = document.createElement('div');\r
52522                 var refreshButton = document.createElement('div');\r
52523 \r
52524                 buttonStyle += ';background-color:' + model.get('buttonColor');\r
52525                 buttonStyle += ';color:' + model.get('buttonTextColor');\r
52526 \r
52527                 var self = this;\r
52528 \r
52529                 function close() {\r
52530                     container.removeChild(root);\r
52531                     self._dom = null;\r
52532                 }\r
52533                 eventTool.addEventListener(closeButton, 'click', close);\r
52534 \r
52535                 eventTool.addEventListener(refreshButton, 'click', function () {\r
52536                     var newOption;\r
52537                     try {\r
52538                         if (typeof contentToOption === 'function') {\r
52539                             newOption = contentToOption(viewMain, api.getOption());\r
52540                         }\r
52541                         else {\r
52542                             newOption = parseContents(textarea.value, blockMetaList);\r
52543                         }\r
52544                     }\r
52545                     catch (e) {\r
52546                         close();\r
52547                         throw new Error('Data view format error ' + e);\r
52548                     }\r
52549                     if (newOption) {\r
52550                         api.dispatchAction({\r
52551                             type: 'changeDataView',\r
52552                             newOption: newOption\r
52553                         });\r
52554                     }\r
52555 \r
52556                     close();\r
52557                 });\r
52558 \r
52559                 closeButton.innerHTML = lang[1];\r
52560                 refreshButton.innerHTML = lang[2];\r
52561                 refreshButton.style.cssText = buttonStyle;\r
52562                 closeButton.style.cssText = buttonStyle;\r
52563 \r
52564                 !model.get('readOnly') && buttonContainer.appendChild(refreshButton);\r
52565                 buttonContainer.appendChild(closeButton);\r
52566 \r
52567                 // http://stackoverflow.com/questions/6637341/use-tab-to-indent-in-textarea\r
52568                 eventTool.addEventListener(textarea, 'keydown', function (e) {\r
52569                     if ((e.keyCode || e.which) === 9) {\r
52570                         // get caret position/selection\r
52571                         var val = this.value;\r
52572                         var start = this.selectionStart;\r
52573                         var end = this.selectionEnd;\r
52574 \r
52575                         // set textarea value to: text before caret + tab + text after caret\r
52576                         this.value = val.substring(0, start) + ITEM_SPLITER + val.substring(end);\r
52577 \r
52578                         // put caret at right position again\r
52579                         this.selectionStart = this.selectionEnd = start + 1;\r
52580 \r
52581                         // prevent the focus lose\r
52582                         eventTool.stop(e);\r
52583                     }\r
52584                 });\r
52585 \r
52586                 root.appendChild(header);\r
52587                 root.appendChild(viewMain);\r
52588                 root.appendChild(buttonContainer);\r
52589 \r
52590                 viewMain.style.height = (container.clientHeight - 80) + 'px';\r
52591 \r
52592                 container.appendChild(root);\r
52593                 this._dom = root;\r
52594             };\r
52595 \r
52596             DataView.prototype.remove = function (ecModel, api) {\r
52597                 this._dom && api.getDom().removeChild(this._dom);\r
52598             };\r
52599 \r
52600             DataView.prototype.dispose = function (ecModel, api) {\r
52601                 this.remove(ecModel, api);\r
52602             };\r
52603 \r
52604             /**\r
52605              * @inner\r
52606              */\r
52607             function tryMergeDataOption(newData, originalData) {\r
52608                 return zrUtil.map(newData, function (newVal, idx) {\r
52609                     var original = originalData && originalData[idx];\r
52610                     if (zrUtil.isObject(original) && !zrUtil.isArray(original)) {\r
52611                         if (zrUtil.isObject(newVal) && !zrUtil.isArray(newVal)) {\r
52612                             newVal = newVal.value;\r
52613                         }\r
52614                         // Original data has option\r
52615                         return zrUtil.defaults({\r
52616                             value: newVal\r
52617                         }, original);\r
52618                     }\r
52619                     else {\r
52620                         return newVal;\r
52621                     }\r
52622                 });\r
52623             }\r
52624 \r
52625             __webpack_require__(333).register('dataView', DataView);\r
52626 \r
52627             __webpack_require__(1).registerAction({\r
52628                 type: 'changeDataView',\r
52629                 event: 'dataViewChanged',\r
52630                 update: 'prepareAndUpdate'\r
52631             }, function (payload, ecModel) {\r
52632                 var newSeriesOptList = [];\r
52633                 zrUtil.each(payload.newOption.series, function (seriesOpt) {\r
52634                     var seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0];\r
52635                     if (!seriesModel) {\r
52636                         // New created series\r
52637                         // Geuss the series type\r
52638                         newSeriesOptList.push(zrUtil.extend({\r
52639                             // Default is scatter\r
52640                             type: 'scatter'\r
52641                         }, seriesOpt));\r
52642                     }\r
52643                     else {\r
52644                         var originalData = seriesModel.get('data');\r
52645                         newSeriesOptList.push({\r
52646                             name: seriesOpt.name,\r
52647                             data: tryMergeDataOption(seriesOpt.data, originalData)\r
52648                         });\r
52649                     }\r
52650                 });\r
52651 \r
52652                 ecModel.mergeOption(zrUtil.defaults({\r
52653                     series: newSeriesOptList\r
52654                 }, payload.newOption));\r
52655             });\r
52656 \r
52657             module.exports = DataView;\r
52658 \r
52659 \r
52660 /***/ },\r
52661 /* 339 */\r
52662 /***/ function(module, exports, __webpack_require__) {\r
52663 \r
52664         'use strict';\r
52665 \r
52666 \r
52667             var zrUtil = __webpack_require__(3);\r
52668             var numberUtil = __webpack_require__(7);\r
52669             var SelectController = __webpack_require__(225);\r
52670             var BoundingRect = __webpack_require__(15);\r
52671             var Group = __webpack_require__(29);\r
52672             var history = __webpack_require__(340);\r
52673             var interactionMutex = __webpack_require__(160);\r
52674 \r
52675             var each = zrUtil.each;\r
52676             var asc = numberUtil.asc;\r
52677 \r
52678             // Use dataZoomSelect\r
52679             __webpack_require__(341);\r
52680 \r
52681             // Spectial component id start with \0ec\0, see echarts/model/Global.js~hasInnerId\r
52682             var DATA_ZOOM_ID_BASE = '\0_ec_\0toolbox-dataZoom_';\r
52683 \r
52684             function DataZoom(model) {\r
52685                 this.model = model;\r
52686 \r
52687                 /**\r
52688                  * @private\r
52689                  * @type {module:zrender/container/Group}\r
52690                  */\r
52691                 this._controllerGroup;\r
52692 \r
52693                 /**\r
52694                  * @private\r
52695                  * @type {module:echarts/component/helper/SelectController}\r
52696                  */\r
52697                 this._controller;\r
52698 \r
52699                 /**\r
52700                  * Is zoom active.\r
52701                  * @private\r
52702                  * @type {Object}\r
52703                  */\r
52704                 this._isZoomActive;\r
52705             }\r
52706 \r
52707             DataZoom.defaultOption = {\r
52708                 show: true,\r
52709                 // Icon group\r
52710                 icon: {\r
52711                     zoom: 'M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1',\r
52712                     back: 'M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26'\r
52713                 },\r
52714                 title: {\r
52715                     zoom: '区域缩放',\r
52716                     back: '区域缩放还原'\r
52717                 }\r
52718             };\r
52719 \r
52720             var proto = DataZoom.prototype;\r
52721 \r
52722             proto.render = function (featureModel, ecModel, api) {\r
52723                 updateBackBtnStatus(featureModel, ecModel);\r
52724             };\r
52725 \r
52726             proto.onclick = function (ecModel, api, type) {\r
52727                 var controllerGroup = this._controllerGroup;\r
52728                 if (!this._controllerGroup) {\r
52729                     controllerGroup = this._controllerGroup = new Group();\r
52730                     api.getZr().add(controllerGroup);\r
52731                 }\r
52732 \r
52733                 handlers[type].call(this, controllerGroup, this.model, ecModel, api);\r
52734             };\r
52735 \r
52736             proto.remove = function (ecModel, api) {\r
52737                 this._disposeController();\r
52738                 interactionMutex.release('globalPan', api.getZr());\r
52739             };\r
52740 \r
52741             proto.dispose = function (ecModel, api) {\r
52742                 var zr = api.getZr();\r
52743                 interactionMutex.release('globalPan', zr);\r
52744                 this._disposeController();\r
52745                 this._controllerGroup && zr.remove(this._controllerGroup);\r
52746             };\r
52747 \r
52748             /**\r
52749              * @private\r
52750              */\r
52751             var handlers = {\r
52752 \r
52753                 zoom: function (controllerGroup, featureModel, ecModel, api) {\r
52754                     var isZoomActive = this._isZoomActive = !this._isZoomActive;\r
52755                     var zr = api.getZr();\r
52756 \r
52757                     interactionMutex[isZoomActive ? 'take' : 'release']('globalPan', zr);\r
52758 \r
52759                     featureModel.setIconStatus('zoom', isZoomActive ? 'emphasis' : 'normal');\r
52760 \r
52761                     if (isZoomActive) {\r
52762                         zr.setDefaultCursorStyle('crosshair');\r
52763 \r
52764                         this._createController(\r
52765                             controllerGroup, featureModel, ecModel, api\r
52766                         );\r
52767                     }\r
52768                     else {\r
52769                         zr.setDefaultCursorStyle('default');\r
52770                         this._disposeController();\r
52771                     }\r
52772                 },\r
52773 \r
52774                 back: function (controllerGroup, featureModel, ecModel, api) {\r
52775                     this._dispatchAction(history.pop(ecModel), api);\r
52776                 }\r
52777             };\r
52778 \r
52779             /**\r
52780              * @private\r
52781              */\r
52782             proto._createController = function (\r
52783                 controllerGroup, featureModel, ecModel, api\r
52784             ) {\r
52785                 var controller = this._controller = new SelectController(\r
52786                     'rect',\r
52787                     api.getZr(),\r
52788                     {\r
52789                         // FIXME\r
52790                         lineWidth: 3,\r
52791                         stroke: '#333',\r
52792                         fill: 'rgba(0,0,0,0.2)'\r
52793                     }\r
52794                 );\r
52795                 controller.on(\r
52796                     'selectEnd',\r
52797                     zrUtil.bind(\r
52798                         this._onSelected, this, controller,\r
52799                         featureModel, ecModel, api\r
52800                     )\r
52801                 );\r
52802                 controller.enable(controllerGroup, false);\r
52803             };\r
52804 \r
52805             proto._disposeController = function () {\r
52806                 var controller = this._controller;\r
52807                 if (controller) {\r
52808                     controller.off('selected');\r
52809                     controller.dispose();\r
52810                 }\r
52811             };\r
52812 \r
52813             function prepareCoordInfo(grid, ecModel) {\r
52814                 // Default use the first axis.\r
52815                 // FIXME\r
52816                 var coordInfo = [\r
52817                     {axisModel: grid.getAxis('x').model, axisIndex: 0}, // x\r
52818                     {axisModel: grid.getAxis('y').model, axisIndex: 0}  // y\r
52819                 ];\r
52820                 coordInfo.grid = grid;\r
52821 \r
52822                 ecModel.eachComponent(\r
52823                     {mainType: 'dataZoom', subType: 'select'},\r
52824                     function (dzModel, dataZoomIndex) {\r
52825                         if (isTheAxis('xAxis', coordInfo[0].axisModel, dzModel, ecModel)) {\r
52826                             coordInfo[0].dataZoomModel = dzModel;\r
52827                         }\r
52828                         if (isTheAxis('yAxis', coordInfo[1].axisModel, dzModel, ecModel)) {\r
52829                             coordInfo[1].dataZoomModel = dzModel;\r
52830                         }\r
52831                     }\r
52832                 );\r
52833 \r
52834                 return coordInfo;\r
52835             }\r
52836 \r
52837             function isTheAxis(axisName, axisModel, dataZoomModel, ecModel) {\r
52838                 var axisIndex = dataZoomModel.get(axisName + 'Index');\r
52839                 return axisIndex != null\r
52840                     && ecModel.getComponent(axisName, axisIndex) === axisModel;\r
52841             }\r
52842 \r
52843             /**\r
52844              * @private\r
52845              */\r
52846             proto._onSelected = function (controller, featureModel, ecModel, api, selRanges) {\r
52847                 if (!selRanges.length) {\r
52848                     return;\r
52849                 }\r
52850                 var selRange = selRanges[0];\r
52851 \r
52852                 controller.update(); // remove cover\r
52853 \r
52854                 var snapshot = {};\r
52855 \r
52856                 // FIXME\r
52857                 // polar\r
52858 \r
52859                 ecModel.eachComponent('grid', function (gridModel, gridIndex) {\r
52860                     var grid = gridModel.coordinateSystem;\r
52861                     var coordInfo = prepareCoordInfo(grid, ecModel);\r
52862                     var selDataRange = pointToDataInCartesian(selRange, coordInfo);\r
52863 \r
52864                     if (selDataRange) {\r
52865                         var xBatchItem = scaleCartesianAxis(selDataRange, coordInfo, 0, 'x');\r
52866                         var yBatchItem = scaleCartesianAxis(selDataRange, coordInfo, 1, 'y');\r
52867 \r
52868                         xBatchItem && (snapshot[xBatchItem.dataZoomId] = xBatchItem);\r
52869                         yBatchItem && (snapshot[yBatchItem.dataZoomId] = yBatchItem);\r
52870                     }\r
52871                 }, this);\r
52872 \r
52873                 history.push(ecModel, snapshot);\r
52874 \r
52875                 this._dispatchAction(snapshot, api);\r
52876             };\r
52877 \r
52878             function pointToDataInCartesian(selRange, coordInfo) {\r
52879                 var grid = coordInfo.grid;\r
52880 \r
52881                 var selRect = new BoundingRect(\r
52882                     selRange[0][0],\r
52883                     selRange[1][0],\r
52884                     selRange[0][1] - selRange[0][0],\r
52885                     selRange[1][1] - selRange[1][0]\r
52886                 );\r
52887                 if (!selRect.intersect(grid.getRect())) {\r
52888                     return;\r
52889                 }\r
52890                 var cartesian = grid.getCartesian(coordInfo[0].axisIndex, coordInfo[1].axisIndex);\r
52891                 var dataLeftTop = cartesian.pointToData([selRange[0][0], selRange[1][0]], true);\r
52892                 var dataRightBottom = cartesian.pointToData([selRange[0][1], selRange[1][1]], true);\r
52893 \r
52894                 return [\r
52895                     asc([dataLeftTop[0], dataRightBottom[0]]), // x, using asc to handle inverse\r
52896                     asc([dataLeftTop[1], dataRightBottom[1]]) // y, using asc to handle inverse\r
52897                 ];\r
52898             }\r
52899 \r
52900             function scaleCartesianAxis(selDataRange, coordInfo, dimIdx, dimName) {\r
52901                 var dimCoordInfo = coordInfo[dimIdx];\r
52902                 var dataZoomModel = dimCoordInfo.dataZoomModel;\r
52903 \r
52904                 if (dataZoomModel) {\r
52905                     return {\r
52906                         dataZoomId: dataZoomModel.id,\r
52907                         startValue: selDataRange[dimIdx][0],\r
52908                         endValue: selDataRange[dimIdx][1]\r
52909                     };\r
52910                 }\r
52911             }\r
52912 \r
52913             /**\r
52914              * @private\r
52915              */\r
52916             proto._dispatchAction = function (snapshot, api) {\r
52917                 var batch = [];\r
52918 \r
52919                 each(snapshot, function (batchItem) {\r
52920                     batch.push(batchItem);\r
52921                 });\r
52922 \r
52923                 batch.length && api.dispatchAction({\r
52924                     type: 'dataZoom',\r
52925                     from: this.uid,\r
52926                     batch: zrUtil.clone(batch, true)\r
52927                 });\r
52928             };\r
52929 \r
52930             function updateBackBtnStatus(featureModel, ecModel) {\r
52931                 featureModel.setIconStatus(\r
52932                     'back',\r
52933                     history.count(ecModel) > 1 ? 'emphasis' : 'normal'\r
52934                 );\r
52935             }\r
52936 \r
52937 \r
52938             __webpack_require__(333).register('dataZoom', DataZoom);\r
52939 \r
52940 \r
52941             // Create special dataZoom option for select\r
52942             __webpack_require__(1).registerPreprocessor(function (option) {\r
52943                 if (!option) {\r
52944                     return;\r
52945                 }\r
52946 \r
52947                 var dataZoomOpts = option.dataZoom || (option.dataZoom = []);\r
52948                 if (!zrUtil.isArray(dataZoomOpts)) {\r
52949                     dataZoomOpts = [dataZoomOpts];\r
52950                 }\r
52951 \r
52952                 var toolboxOpt = option.toolbox;\r
52953                 if (toolboxOpt) {\r
52954                     // Assume there is only one toolbox\r
52955                     if (zrUtil.isArray(toolboxOpt)) {\r
52956                         toolboxOpt = toolboxOpt[0];\r
52957                     }\r
52958 \r
52959                     if (toolboxOpt && toolboxOpt.feature) {\r
52960                         var dataZoomOpt = toolboxOpt.feature.dataZoom;\r
52961                         addForAxis('xAxis', dataZoomOpt);\r
52962                         addForAxis('yAxis', dataZoomOpt);\r
52963                     }\r
52964                 }\r
52965 \r
52966                 function addForAxis(axisName, dataZoomOpt) {\r
52967                     if (!dataZoomOpt) {\r
52968                         return;\r
52969                     }\r
52970 \r
52971                     var axisIndicesName = axisName + 'Index';\r
52972                     var givenAxisIndices = dataZoomOpt[axisIndicesName];\r
52973                     if (givenAxisIndices != null && !zrUtil.isArray(givenAxisIndices)) {\r
52974                         givenAxisIndices = givenAxisIndices === false ? [] : [givenAxisIndices];\r
52975                     }\r
52976 \r
52977                     forEachComponent(axisName, function (axisOpt, axisIndex) {\r
52978                         if (givenAxisIndices != null\r
52979                             && zrUtil.indexOf(givenAxisIndices, axisIndex) === -1\r
52980                         ) {\r
52981                             return;\r
52982                         }\r
52983                         var newOpt = {\r
52984                             type: 'select',\r
52985                             $fromToolbox: true,\r
52986                             // Id for merge mapping.\r
52987                             id: DATA_ZOOM_ID_BASE + axisName + axisIndex\r
52988                         };\r
52989                         // FIXME\r
52990                         // Only support one axis now.\r
52991                         newOpt[axisIndicesName] = axisIndex;\r
52992                         dataZoomOpts.push(newOpt);\r
52993                     });\r
52994                 }\r
52995 \r
52996                 function forEachComponent(mainType, cb) {\r
52997                     var opts = option[mainType];\r
52998                     if (!zrUtil.isArray(opts)) {\r
52999                         opts = opts ? [opts] : [];\r
53000                     }\r
53001                     each(opts, cb);\r
53002                 }\r
53003             });\r
53004 \r
53005             module.exports = DataZoom;\r
53006 \r
53007 \r
53008 /***/ },\r
53009 /* 340 */\r
53010 /***/ function(module, exports, __webpack_require__) {\r
53011 \r
53012         /**\r
53013          * @file History manager.\r
53014          */\r
53015 \r
53016 \r
53017             var zrUtil = __webpack_require__(3);\r
53018             var each = zrUtil.each;\r
53019 \r
53020             var ATTR = '\0_ec_hist_store';\r
53021 \r
53022             var history = {\r
53023 \r
53024                 /**\r
53025                  * @public\r
53026                  * @param {module:echarts/model/Global} ecModel\r
53027                  * @param {Object} newSnapshot {dataZoomId, batch: [payloadInfo, ...]}\r
53028                  */\r
53029                 push: function (ecModel, newSnapshot) {\r
53030                     var store = giveStore(ecModel);\r
53031 \r
53032                     // If previous dataZoom can not be found,\r
53033                     // complete an range with current range.\r
53034                     each(newSnapshot, function (batchItem, dataZoomId) {\r
53035                         var i = store.length - 1;\r
53036                         for (; i >= 0; i--) {\r
53037                             var snapshot = store[i];\r
53038                             if (snapshot[dataZoomId]) {\r
53039                                 break;\r
53040                             }\r
53041                         }\r
53042                         if (i < 0) {\r
53043                             // No origin range set, create one by current range.\r
53044                             var dataZoomModel = ecModel.queryComponents(\r
53045                                 {mainType: 'dataZoom', subType: 'select', id: dataZoomId}\r
53046                             )[0];\r
53047                             if (dataZoomModel) {\r
53048                                 var percentRange = dataZoomModel.getPercentRange();\r
53049                                 store[0][dataZoomId] = {\r
53050                                     dataZoomId: dataZoomId,\r
53051                                     start: percentRange[0],\r
53052                                     end: percentRange[1]\r
53053                                 };\r
53054                             }\r
53055                         }\r
53056                     });\r
53057 \r
53058                     store.push(newSnapshot);\r
53059                 },\r
53060 \r
53061                 /**\r
53062                  * @public\r
53063                  * @param {module:echarts/model/Global} ecModel\r
53064                  * @return {Object} snapshot\r
53065                  */\r
53066                 pop: function (ecModel) {\r
53067                     var store = giveStore(ecModel);\r
53068                     var head = store[store.length - 1];\r
53069                     store.length > 1 && store.pop();\r
53070 \r
53071                     // Find top for all dataZoom.\r
53072                     var snapshot = {};\r
53073                     each(head, function (batchItem, dataZoomId) {\r
53074                         for (var i = store.length - 1; i >= 0; i--) {\r
53075                             var batchItem = store[i][dataZoomId];\r
53076                             if (batchItem) {\r
53077                                 snapshot[dataZoomId] = batchItem;\r
53078                                 break;\r
53079                             }\r
53080                         }\r
53081                     });\r
53082 \r
53083                     return snapshot;\r
53084                 },\r
53085 \r
53086                 /**\r
53087                  * @public\r
53088                  */\r
53089                 clear: function (ecModel) {\r
53090                     ecModel[ATTR] = null;\r
53091                 },\r
53092 \r
53093                 /**\r
53094                  * @public\r
53095                  * @param {module:echarts/model/Global} ecModel\r
53096                  * @return {number} records. always >= 1.\r
53097                  */\r
53098                 count: function (ecModel) {\r
53099                     return giveStore(ecModel).length;\r
53100                 }\r
53101 \r
53102             };\r
53103 \r
53104             /**\r
53105              * [{key: dataZoomId, value: {dataZoomId, range}}, ...]\r
53106              * History length of each dataZoom may be different.\r
53107              * this._history[0] is used to store origin range.\r
53108              * @type {Array.<Object>}\r
53109              */\r
53110             function giveStore(ecModel) {\r
53111                 var store = ecModel[ATTR];\r
53112                 if (!store) {\r
53113                     store = ecModel[ATTR] = [{}];\r
53114                 }\r
53115                 return store;\r
53116             }\r
53117 \r
53118             module.exports = history;\r
53119 \r
53120 \r
53121 \r
53122 /***/ },\r
53123 /* 341 */\r
53124 /***/ function(module, exports, __webpack_require__) {\r
53125 \r
53126         /**\r
53127          * DataZoom component entry\r
53128          */\r
53129 \r
53130 \r
53131             __webpack_require__(287);\r
53132 \r
53133             __webpack_require__(288);\r
53134             __webpack_require__(290);\r
53135 \r
53136             __webpack_require__(342);\r
53137             __webpack_require__(343);\r
53138 \r
53139             __webpack_require__(298);\r
53140             __webpack_require__(299);\r
53141 \r
53142 \r
53143 \r
53144 /***/ },\r
53145 /* 342 */\r
53146 /***/ function(module, exports, __webpack_require__) {\r
53147 \r
53148         /**\r
53149          * @file Data zoom model\r
53150          */\r
53151 \r
53152 \r
53153             var DataZoomModel = __webpack_require__(288);\r
53154 \r
53155             module.exports = DataZoomModel.extend({\r
53156 \r
53157                 type: 'dataZoom.select'\r
53158 \r
53159             });\r
53160 \r
53161 \r
53162 \r
53163 /***/ },\r
53164 /* 343 */\r
53165 /***/ function(module, exports, __webpack_require__) {\r
53166 \r
53167         \r
53168 \r
53169             module.exports = __webpack_require__(290).extend({\r
53170 \r
53171                 type: 'dataZoom.select'\r
53172 \r
53173             });\r
53174 \r
53175 \r
53176 \r
53177 /***/ },\r
53178 /* 344 */\r
53179 /***/ function(module, exports, __webpack_require__) {\r
53180 \r
53181         'use strict';\r
53182 \r
53183 \r
53184             var history = __webpack_require__(340);\r
53185 \r
53186             function Restore(model) {\r
53187                 this.model = model;\r
53188             }\r
53189 \r
53190             Restore.defaultOption = {\r
53191                 show: true,\r
53192                 icon: 'M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5',\r
53193                 title: '还原'\r
53194             };\r
53195 \r
53196             var proto = Restore.prototype;\r
53197 \r
53198             proto.onclick = function (ecModel, api, type) {\r
53199                 history.clear(ecModel);\r
53200 \r
53201                 api.dispatchAction({\r
53202                     type: 'restore',\r
53203                     from: this.uid\r
53204                 });\r
53205             };\r
53206 \r
53207 \r
53208             __webpack_require__(333).register('restore', Restore);\r
53209 \r
53210 \r
53211             __webpack_require__(1).registerAction(\r
53212                 {type: 'restore', event: 'restore', update: 'prepareAndUpdate'},\r
53213                 function (payload, ecModel) {\r
53214                     ecModel.resetOption('recreate');\r
53215                 }\r
53216             );\r
53217 \r
53218             module.exports = Restore;\r
53219 \r
53220 \r
53221 /***/ },\r
53222 /* 345 */\r
53223 /***/ function(module, exports, __webpack_require__) {\r
53224 \r
53225         \r
53226             __webpack_require__(346);\r
53227             __webpack_require__(77).registerPainter('vml', __webpack_require__(348));\r
53228 \r
53229 \r
53230 /***/ },\r
53231 /* 346 */\r
53232 /***/ function(module, exports, __webpack_require__) {\r
53233 \r
53234         // http://www.w3.org/TR/NOTE-VML\r
53235         // TODO Use proxy like svg instead of overwrite brush methods\r
53236 \r
53237 \r
53238         if (!__webpack_require__(78).canvasSupported) {\r
53239             var vec2 = __webpack_require__(16);\r
53240             var BoundingRect = __webpack_require__(15);\r
53241             var CMD = __webpack_require__(48).CMD;\r
53242             var colorTool = __webpack_require__(38);\r
53243             var textContain = __webpack_require__(14);\r
53244             var RectText = __webpack_require__(47);\r
53245             var Displayable = __webpack_require__(45);\r
53246             var ZImage = __webpack_require__(59);\r
53247             var Text = __webpack_require__(62);\r
53248             var Path = __webpack_require__(44);\r
53249 \r
53250             var Gradient = __webpack_require__(4);\r
53251 \r
53252             var vmlCore = __webpack_require__(347);\r
53253 \r
53254             var round = Math.round;\r
53255             var sqrt = Math.sqrt;\r
53256             var abs = Math.abs;\r
53257             var cos = Math.cos;\r
53258             var sin = Math.sin;\r
53259             var mathMax = Math.max;\r
53260 \r
53261             var applyTransform = vec2.applyTransform;\r
53262 \r
53263             var comma = ',';\r
53264             var imageTransformPrefix = 'progid:DXImageTransform.Microsoft';\r
53265 \r
53266             var Z = 21600;\r
53267             var Z2 = Z / 2;\r
53268 \r
53269             var ZLEVEL_BASE = 100000;\r
53270             var Z_BASE = 1000;\r
53271 \r
53272             var initRootElStyle = function (el) {\r
53273                 el.style.cssText = 'position:absolute;left:0;top:0;width:1px;height:1px;';\r
53274                 el.coordsize = Z + ','  + Z;\r
53275                 el.coordorigin = '0,0';\r
53276             };\r
53277 \r
53278             var encodeHtmlAttribute = function (s) {\r
53279                 return String(s).replace(/&/g, '&amp;').replace(/"/g, '&quot;');\r
53280             };\r
53281 \r
53282             var rgb2Str = function (r, g, b) {\r
53283                 return 'rgb(' + [r, g, b].join(',') + ')';\r
53284             };\r
53285 \r
53286             var append = function (parent, child) {\r
53287                 if (child && parent && child.parentNode !== parent) {\r
53288                     parent.appendChild(child);\r
53289                 }\r
53290             };\r
53291 \r
53292             var remove = function (parent, child) {\r
53293                 if (child && parent && child.parentNode === parent) {\r
53294                     parent.removeChild(child);\r
53295                 }\r
53296             };\r
53297 \r
53298             var getZIndex = function (zlevel, z, z2) {\r
53299                 // z 的取值范围为 [0, 1000]\r
53300                 return (parseFloat(zlevel) || 0) * ZLEVEL_BASE + (parseFloat(z) || 0) * Z_BASE + z2;\r
53301             };\r
53302 \r
53303             var parsePercent = function (value, maxValue) {\r
53304                 if (typeof value === 'string') {\r
53305                     if (value.lastIndexOf('%') >= 0) {\r
53306                         return parseFloat(value) / 100 * maxValue;\r
53307                     }\r
53308                     return parseFloat(value);\r
53309                 }\r
53310                 return value;\r
53311             };\r
53312 \r
53313             /***************************************************\r
53314              * PATH\r
53315              **************************************************/\r
53316 \r
53317             var setColorAndOpacity = function (el, color, opacity) {\r
53318                 var colorArr = colorTool.parse(color);\r
53319                 opacity = +opacity;\r
53320                 if (isNaN(opacity)) {\r
53321                     opacity = 1;\r
53322                 }\r
53323                 if (colorArr) {\r
53324                     el.color = rgb2Str(colorArr[0], colorArr[1], colorArr[2]);\r
53325                     el.opacity = opacity * colorArr[3];\r
53326                 }\r
53327             };\r
53328 \r
53329             var getColorAndAlpha = function (color) {\r
53330                 var colorArr = colorTool.parse(color);\r
53331                 return [\r
53332                     rgb2Str(colorArr[0], colorArr[1], colorArr[2]),\r
53333                     colorArr[3]\r
53334                 ];\r
53335             };\r
53336 \r
53337             var updateFillNode = function (el, style, zrEl) {\r
53338                 // TODO pattern\r
53339                 var fill = style.fill;\r
53340                 if (fill != null) {\r
53341                     // Modified from excanvas\r
53342                     if (fill instanceof Gradient) {\r
53343                         var gradientType;\r
53344                         var angle = 0;\r
53345                         var focus = [0, 0];\r
53346                         // additional offset\r
53347                         var shift = 0;\r
53348                         // scale factor for offset\r
53349                         var expansion = 1;\r
53350                         var rect = zrEl.getBoundingRect();\r
53351                         var rectWidth = rect.width;\r
53352                         var rectHeight = rect.height;\r
53353                         if (fill.type === 'linear') {\r
53354                             gradientType = 'gradient';\r
53355                             var transform = zrEl.transform;\r
53356                             var p0 = [fill.x * rectWidth, fill.y * rectHeight];\r
53357                             var p1 = [fill.x2 * rectWidth, fill.y2 * rectHeight];\r
53358                             if (transform) {\r
53359                                 applyTransform(p0, p0, transform);\r
53360                                 applyTransform(p1, p1, transform);\r
53361                             }\r
53362                             var dx = p1[0] - p0[0];\r
53363                             var dy = p1[1] - p0[1];\r
53364                             angle = Math.atan2(dx, dy) * 180 / Math.PI;\r
53365                             // The angle should be a non-negative number.\r
53366                             if (angle < 0) {\r
53367                                 angle += 360;\r
53368                             }\r
53369 \r
53370                             // Very small angles produce an unexpected result because they are\r
53371                             // converted to a scientific notation string.\r
53372                             if (angle < 1e-6) {\r
53373                                 angle = 0;\r
53374                             }\r
53375                         }\r
53376                         else {\r
53377                             gradientType = 'gradientradial';\r
53378                             var p0 = [fill.x * rectWidth, fill.y * rectHeight];\r
53379                             var transform = zrEl.transform;\r
53380                             var scale = zrEl.scale;\r
53381                             var width = rectWidth;\r
53382                             var height = rectHeight;\r
53383                             focus = [\r
53384                                 // Percent in bounding rect\r
53385                                 (p0[0] - rect.x) / width,\r
53386                                 (p0[1] - rect.y) / height\r
53387                             ];\r
53388                             if (transform) {\r
53389                                 applyTransform(p0, p0, transform);\r
53390                             }\r
53391 \r
53392                             width /= scale[0] * Z;\r
53393                             height /= scale[1] * Z;\r
53394                             var dimension = mathMax(width, height);\r
53395                             shift = 2 * 0 / dimension;\r
53396                             expansion = 2 * fill.r / dimension - shift;\r
53397                         }\r
53398 \r
53399                         // We need to sort the color stops in ascending order by offset,\r
53400                         // otherwise IE won't interpret it correctly.\r
53401                         var stops = fill.colorStops.slice();\r
53402                         stops.sort(function(cs1, cs2) {\r
53403                             return cs1.offset - cs2.offset;\r
53404                         });\r
53405 \r
53406                         var length = stops.length;\r
53407                         // Color and alpha list of first and last stop\r
53408                         var colorAndAlphaList = [];\r
53409                         var colors = [];\r
53410                         for (var i = 0; i < length; i++) {\r
53411                             var stop = stops[i];\r
53412                             var colorAndAlpha = getColorAndAlpha(stop.color);\r
53413                             colors.push(stop.offset * expansion + shift + ' ' + colorAndAlpha[0]);\r
53414                             if (i === 0 || i === length - 1) {\r
53415                                 colorAndAlphaList.push(colorAndAlpha);\r
53416                             }\r
53417                         }\r
53418 \r
53419                         if (length >= 2) {\r
53420                             var color1 = colorAndAlphaList[0][0];\r
53421                             var color2 = colorAndAlphaList[1][0];\r
53422                             var opacity1 = colorAndAlphaList[0][1] * style.opacity;\r
53423                             var opacity2 = colorAndAlphaList[1][1] * style.opacity;\r
53424 \r
53425                             el.type = gradientType;\r
53426                             el.method = 'none';\r
53427                             el.focus = '100%';\r
53428                             el.angle = angle;\r
53429                             el.color = color1;\r
53430                             el.color2 = color2;\r
53431                             el.colors = colors.join(',');\r
53432                             // When colors attribute is used, the meanings of opacity and o:opacity2\r
53433                             // are reversed.\r
53434                             el.opacity = opacity2;\r
53435                             // FIXME g_o_:opacity ?\r
53436                             el.opacity2 = opacity1;\r
53437                         }\r
53438                         if (gradientType === 'radial') {\r
53439                             el.focusposition = focus.join(',');\r
53440                         }\r
53441                     }\r
53442                     else {\r
53443                         // FIXME Change from Gradient fill to color fill\r
53444                         setColorAndOpacity(el, fill, style.opacity);\r
53445                     }\r
53446                 }\r
53447             };\r
53448 \r
53449             var updateStrokeNode = function (el, style) {\r
53450                 if (style.lineJoin != null) {\r
53451                     el.joinstyle = style.lineJoin;\r
53452                 }\r
53453                 if (style.miterLimit != null) {\r
53454                     el.miterlimit = style.miterLimit * Z;\r
53455                 }\r
53456                 if (style.lineCap != null) {\r
53457                     el.endcap = style.lineCap;\r
53458                 }\r
53459                 if (style.lineDash != null) {\r
53460                     el.dashstyle = style.lineDash.join(' ');\r
53461                 }\r
53462                 if (style.stroke != null && !(style.stroke instanceof Gradient)) {\r
53463                     setColorAndOpacity(el, style.stroke, style.opacity);\r
53464                 }\r
53465             };\r
53466 \r
53467             var updateFillAndStroke = function (vmlEl, type, style, zrEl) {\r
53468                 var isFill = type == 'fill';\r
53469                 var el = vmlEl.getElementsByTagName(type)[0];\r
53470                 // Stroke must have lineWidth\r
53471                 if (style[type] != null && style[type] !== 'none' && (isFill || (!isFill && style.lineWidth))) {\r
53472                     vmlEl[isFill ? 'filled' : 'stroked'] = 'true';\r
53473                     // FIXME Remove before updating, or set `colors` will throw error\r
53474                     if (style[type] instanceof Gradient) {\r
53475                         remove(vmlEl, el);\r
53476                     }\r
53477                     if (!el) {\r
53478                         el = vmlCore.createNode(type);\r
53479                     }\r
53480 \r
53481                     isFill ? updateFillNode(el, style, zrEl) : updateStrokeNode(el, style);\r
53482                     append(vmlEl, el);\r
53483                 }\r
53484                 else {\r
53485                     vmlEl[isFill ? 'filled' : 'stroked'] = 'false';\r
53486                     remove(vmlEl, el);\r
53487                 }\r
53488             };\r
53489 \r
53490             var points = [[], [], []];\r
53491             var pathDataToString = function (data, m) {\r
53492                 var M = CMD.M;\r
53493                 var C = CMD.C;\r
53494                 var L = CMD.L;\r
53495                 var A = CMD.A;\r
53496                 var Q = CMD.Q;\r
53497 \r
53498                 var str = [];\r
53499                 var nPoint;\r
53500                 var cmdStr;\r
53501                 var cmd;\r
53502                 var i;\r
53503                 var xi;\r
53504                 var yi;\r
53505                 for (i = 0; i < data.length;) {\r
53506                     cmd = data[i++];\r
53507                     cmdStr = '';\r
53508                     nPoint = 0;\r
53509                     switch (cmd) {\r
53510                         case M:\r
53511                             cmdStr = ' m ';\r
53512                             nPoint = 1;\r
53513                             xi = data[i++];\r
53514                             yi = data[i++];\r
53515                             points[0][0] = xi;\r
53516                             points[0][1] = yi;\r
53517                             break;\r
53518                         case L:\r
53519                             cmdStr = ' l ';\r
53520                             nPoint = 1;\r
53521                             xi = data[i++];\r
53522                             yi = data[i++];\r
53523                             points[0][0] = xi;\r
53524                             points[0][1] = yi;\r
53525                             break;\r
53526                         case Q:\r
53527                         case C:\r
53528                             cmdStr = ' c ';\r
53529                             nPoint = 3;\r
53530                             var x1 = data[i++];\r
53531                             var y1 = data[i++];\r
53532                             var x2 = data[i++];\r
53533                             var y2 = data[i++];\r
53534                             var x3;\r
53535                             var y3;\r
53536                             if (cmd === Q) {\r
53537                                 // Convert quadratic to cubic using degree elevation\r
53538                                 x3 = x2;\r
53539                                 y3 = y2;\r
53540                                 x2 = (x2 + 2 * x1) / 3;\r
53541                                 y2 = (y2 + 2 * y1) / 3;\r
53542                                 x1 = (xi + 2 * x1) / 3;\r
53543                                 y1 = (yi + 2 * y1) / 3;\r
53544                             }\r
53545                             else {\r
53546                                 x3 = data[i++];\r
53547                                 y3 = data[i++];\r
53548                             }\r
53549                             points[0][0] = x1;\r
53550                             points[0][1] = y1;\r
53551                             points[1][0] = x2;\r
53552                             points[1][1] = y2;\r
53553                             points[2][0] = x3;\r
53554                             points[2][1] = y3;\r
53555 \r
53556                             xi = x3;\r
53557                             yi = y3;\r
53558                             break;\r
53559                         case A:\r
53560                             var x = 0;\r
53561                             var y = 0;\r
53562                             var sx = 1;\r
53563                             var sy = 1;\r
53564                             var angle = 0;\r
53565                             if (m) {\r
53566                                 // Extract SRT from matrix\r
53567                                 x = m[4];\r
53568                                 y = m[5];\r
53569                                 sx = sqrt(m[0] * m[0] + m[1] * m[1]);\r
53570                                 sy = sqrt(m[2] * m[2] + m[3] * m[3]);\r
53571                                 angle = Math.atan2(-m[1] / sy, m[0] / sx);\r
53572                             }\r
53573 \r
53574                             var cx = data[i++];\r
53575                             var cy = data[i++];\r
53576                             var rx = data[i++];\r
53577                             var ry = data[i++];\r
53578                             var startAngle = data[i++] + angle;\r
53579                             var endAngle = data[i++] + startAngle + angle;\r
53580                             // FIXME\r
53581                             // var psi = data[i++];\r
53582                             i++;\r
53583                             var clockwise = data[i++];\r
53584 \r
53585                             var x0 = cx + cos(startAngle) * rx;\r
53586                             var y0 = cy + sin(startAngle) * ry;\r
53587 \r
53588                             var x1 = cx + cos(endAngle) * rx;\r
53589                             var y1 = cy + sin(endAngle) * ry;\r
53590 \r
53591                             var type = clockwise ? ' wa ' : ' at ';\r
53592 \r
53593                             str.push(\r
53594                                 type,\r
53595                                 round(((cx - rx) * sx + x) * Z - Z2), comma,\r
53596                                 round(((cy - ry) * sy + y) * Z - Z2), comma,\r
53597                                 round(((cx + rx) * sx + x) * Z - Z2), comma,\r
53598                                 round(((cy + ry) * sy + y) * Z - Z2), comma,\r
53599                                 round((x0 * sx + x) * Z - Z2), comma,\r
53600                                 round((y0 * sy + y) * Z - Z2), comma,\r
53601                                 round((x1 * sx + x) * Z - Z2), comma,\r
53602                                 round((y1 * sy + y) * Z - Z2)\r
53603                             );\r
53604 \r
53605                             xi = x1;\r
53606                             yi = y1;\r
53607                             break;\r
53608                         case CMD.R:\r
53609                             var p0 = points[0];\r
53610                             var p1 = points[1];\r
53611                             // x0, y0\r
53612                             p0[0] = data[i++];\r
53613                             p0[1] = data[i++];\r
53614                             // x1, y1\r
53615                             p1[0] = p0[0] + data[i++];\r
53616                             p1[1] = p0[1] + data[i++];\r
53617 \r
53618                             if (m) {\r
53619                                 applyTransform(p0, p0, m);\r
53620                                 applyTransform(p1, p1, m);\r
53621                             }\r
53622 \r
53623                             p0[0] = round(p0[0] * Z - Z2);\r
53624                             p1[0] = round(p1[0] * Z - Z2);\r
53625                             p0[1] = round(p0[1] * Z - Z2);\r
53626                             p1[1] = round(p1[1] * Z - Z2);\r
53627                             str.push(\r
53628                                 // x0, y0\r
53629                                 ' m ', p0[0], comma, p0[1],\r
53630                                 // x1, y0\r
53631                                 ' l ', p1[0], comma, p0[1],\r
53632                                 // x1, y1\r
53633                                 ' l ', p1[0], comma, p1[1],\r
53634                                 // x0, y1\r
53635                                 ' l ', p0[0], comma, p1[1]\r
53636                             );\r
53637                             break;\r
53638                         case CMD.Z:\r
53639                             // FIXME Update xi, yi\r
53640                             str.push(' x ');\r
53641                     }\r
53642 \r
53643                     if (nPoint > 0) {\r
53644                         str.push(cmdStr);\r
53645                         for (var k = 0; k < nPoint; k++) {\r
53646                             var p = points[k];\r
53647 \r
53648                             m && applyTransform(p, p, m);\r
53649                             // 不 round 会非常慢\r
53650                             str.push(\r
53651                                 round(p[0] * Z - Z2), comma, round(p[1] * Z - Z2),\r
53652                                 k < nPoint - 1 ? comma : ''\r
53653                             );\r
53654                         }\r
53655                     }\r
53656                 }\r
53657                 return str.join('');\r
53658             };\r
53659 \r
53660             // Rewrite the original path method\r
53661             Path.prototype.brushVML = function (vmlRoot) {\r
53662                 var style = this.style;\r
53663 \r
53664                 var vmlEl = this._vmlEl;\r
53665                 if (!vmlEl) {\r
53666                     vmlEl = vmlCore.createNode('shape');\r
53667                     initRootElStyle(vmlEl);\r
53668 \r
53669                     this._vmlEl = vmlEl;\r
53670                 }\r
53671 \r
53672                 updateFillAndStroke(vmlEl, 'fill', style, this);\r
53673                 updateFillAndStroke(vmlEl, 'stroke', style, this);\r
53674 \r
53675                 var m = this.transform;\r
53676                 var needTransform = m != null;\r
53677                 var strokeEl = vmlEl.getElementsByTagName('stroke')[0];\r
53678                 if (strokeEl) {\r
53679                     var lineWidth = style.lineWidth;\r
53680                     // Get the line scale.\r
53681                     // Determinant of this.m_ means how much the area is enlarged by the\r
53682                     // transformation. So its square root can be used as a scale factor\r
53683                     // for width.\r
53684                     if (needTransform && !style.strokeNoScale) {\r
53685                         var det = m[0] * m[3] - m[1] * m[2];\r
53686                         lineWidth *= sqrt(abs(det));\r
53687                     }\r
53688                     strokeEl.weight = lineWidth + 'px';\r
53689                 }\r
53690 \r
53691                 var path = this.path;\r
53692                 if (this.__dirtyPath) {\r
53693                     path.beginPath();\r
53694                     this.buildPath(path, this.shape);\r
53695                     this.__dirtyPath = false;\r
53696                 }\r
53697 \r
53698                 vmlEl.path = pathDataToString(path.data, this.transform);\r
53699 \r
53700                 vmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);\r
53701 \r
53702                 // Append to root\r
53703                 append(vmlRoot, vmlEl);\r
53704 \r
53705                 // Text\r
53706                 if (style.text) {\r
53707                     this.drawRectText(vmlRoot, this.getBoundingRect());\r
53708                 }\r
53709             };\r
53710 \r
53711             Path.prototype.onRemove = function (vmlRoot) {\r
53712                 remove(vmlRoot, this._vmlEl);\r
53713                 this.removeRectText(vmlRoot);\r
53714             };\r
53715 \r
53716             Path.prototype.onAdd = function (vmlRoot) {\r
53717                 append(vmlRoot, this._vmlEl);\r
53718                 this.appendRectText(vmlRoot);\r
53719             };\r
53720 \r
53721             /***************************************************\r
53722              * IMAGE\r
53723              **************************************************/\r
53724             var isImage = function (img) {\r
53725                 // FIXME img instanceof Image 如果 img 是一个字符串的时候,IE8 下会报错\r
53726                 return (typeof img === 'object') && img.tagName && img.tagName.toUpperCase() === 'IMG';\r
53727                 // return img instanceof Image;\r
53728             };\r
53729 \r
53730             // Rewrite the original path method\r
53731             ZImage.prototype.brushVML = function (vmlRoot) {\r
53732                 var style = this.style;\r
53733                 var image = style.image;\r
53734 \r
53735                 // Image original width, height\r
53736                 var ow;\r
53737                 var oh;\r
53738 \r
53739                 if (isImage(image)) {\r
53740                     var src = image.src;\r
53741                     if (src === this._imageSrc) {\r
53742                         ow = this._imageWidth;\r
53743                         oh = this._imageHeight;\r
53744                     }\r
53745                     else {\r
53746                         var imageRuntimeStyle = image.runtimeStyle;\r
53747                         var oldRuntimeWidth = imageRuntimeStyle.width;\r
53748                         var oldRuntimeHeight = imageRuntimeStyle.height;\r
53749                         imageRuntimeStyle.width = 'auto';\r
53750                         imageRuntimeStyle.height = 'auto';\r
53751 \r
53752                         // get the original size\r
53753                         ow = image.width;\r
53754                         oh = image.height;\r
53755 \r
53756                         // and remove overides\r
53757                         imageRuntimeStyle.width = oldRuntimeWidth;\r
53758                         imageRuntimeStyle.height = oldRuntimeHeight;\r
53759 \r
53760                         // Caching image original width, height and src\r
53761                         this._imageSrc = src;\r
53762                         this._imageWidth = ow;\r
53763                         this._imageHeight = oh;\r
53764                     }\r
53765                     image = src;\r
53766                 }\r
53767                 else {\r
53768                     if (image === this._imageSrc) {\r
53769                         ow = this._imageWidth;\r
53770                         oh = this._imageHeight;\r
53771                     }\r
53772                 }\r
53773                 if (!image) {\r
53774                     return;\r
53775                 }\r
53776 \r
53777                 var x = style.x || 0;\r
53778                 var y = style.y || 0;\r
53779 \r
53780                 var dw = style.width;\r
53781                 var dh = style.height;\r
53782 \r
53783                 var sw = style.sWidth;\r
53784                 var sh = style.sHeight;\r
53785                 var sx = style.sx || 0;\r
53786                 var sy = style.sy || 0;\r
53787 \r
53788                 var hasCrop = sw && sh;\r
53789 \r
53790                 var vmlEl = this._vmlEl;\r
53791                 if (!vmlEl) {\r
53792                     // FIXME 使用 group 在 left, top 都不是 0 的时候就无法显示了。\r
53793                     // vmlEl = vmlCore.createNode('group');\r
53794                     vmlEl = vmlCore.doc.createElement('div');\r
53795                     initRootElStyle(vmlEl);\r
53796 \r
53797                     this._vmlEl = vmlEl;\r
53798                 }\r
53799 \r
53800                 var vmlElStyle = vmlEl.style;\r
53801                 var hasRotation = false;\r
53802                 var m;\r
53803                 var scaleX = 1;\r
53804                 var scaleY = 1;\r
53805                 if (this.transform) {\r
53806                     m = this.transform;\r
53807                     scaleX = sqrt(m[0] * m[0] + m[1] * m[1]);\r
53808                     scaleY = sqrt(m[2] * m[2] + m[3] * m[3]);\r
53809 \r
53810                     hasRotation = m[1] || m[2];\r
53811                 }\r
53812                 if (hasRotation) {\r
53813                     // If filters are necessary (rotation exists), create them\r
53814                     // filters are bog-slow, so only create them if abbsolutely necessary\r
53815                     // The following check doesn't account for skews (which don't exist\r
53816                     // in the canvas spec (yet) anyway.\r
53817                     // From excanvas\r
53818                     var p0 = [x, y];\r
53819                     var p1 = [x + dw, y];\r
53820                     var p2 = [x, y + dh];\r
53821                     var p3 = [x + dw, y + dh];\r
53822                     applyTransform(p0, p0, m);\r
53823                     applyTransform(p1, p1, m);\r
53824                     applyTransform(p2, p2, m);\r
53825                     applyTransform(p3, p3, m);\r
53826 \r
53827                     var maxX = mathMax(p0[0], p1[0], p2[0], p3[0]);\r
53828                     var maxY = mathMax(p0[1], p1[1], p2[1], p3[1]);\r
53829 \r
53830                     var transformFilter = [];\r
53831                     transformFilter.push('M11=', m[0] / scaleX, comma,\r
53832                                 'M12=', m[2] / scaleY, comma,\r
53833                                 'M21=', m[1] / scaleX, comma,\r
53834                                 'M22=', m[3] / scaleY, comma,\r
53835                                 'Dx=', round(x * scaleX + m[4]), comma,\r
53836                                 'Dy=', round(y * scaleY + m[5]));\r
53837 \r
53838                     vmlElStyle.padding = '0 ' + round(maxX) + 'px ' + round(maxY) + 'px 0';\r
53839                     // FIXME DXImageTransform 在 IE11 的兼容模式下不起作用\r
53840                     vmlElStyle.filter = imageTransformPrefix + '.Matrix('\r
53841                         + transformFilter.join('') + ', SizingMethod=clip)';\r
53842 \r
53843                 }\r
53844                 else {\r
53845                     if (m) {\r
53846                         x = x * scaleX + m[4];\r
53847                         y = y * scaleY + m[5];\r
53848                     }\r
53849                     vmlElStyle.filter = '';\r
53850                     vmlElStyle.left = round(x) + 'px';\r
53851                     vmlElStyle.top = round(y) + 'px';\r
53852                 }\r
53853 \r
53854                 var imageEl = this._imageEl;\r
53855                 var cropEl = this._cropEl;\r
53856 \r
53857                 if (! imageEl) {\r
53858                     imageEl = vmlCore.doc.createElement('div');\r
53859                     this._imageEl = imageEl;\r
53860                 }\r
53861                 var imageELStyle = imageEl.style;\r
53862                 if (hasCrop) {\r
53863                     // Needs know image original width and height\r
53864                     if (! (ow && oh)) {\r
53865                         var tmpImage = new Image();\r
53866                         var self = this;\r
53867                         tmpImage.onload = function () {\r
53868                             tmpImage.onload = null;\r
53869                             ow = tmpImage.width;\r
53870                             oh = tmpImage.height;\r
53871                             // Adjust image width and height to fit the ratio destinationSize / sourceSize\r
53872                             imageELStyle.width = round(scaleX * ow * dw / sw) + 'px';\r
53873                             imageELStyle.height = round(scaleY * oh * dh / sh) + 'px';\r
53874 \r
53875                             // Caching image original width, height and src\r
53876                             self._imageWidth = ow;\r
53877                             self._imageHeight = oh;\r
53878                             self._imageSrc = image;\r
53879                         };\r
53880                         tmpImage.src = image;\r
53881                     }\r
53882                     else {\r
53883                         imageELStyle.width = round(scaleX * ow * dw / sw) + 'px';\r
53884                         imageELStyle.height = round(scaleY * oh * dh / sh) + 'px';\r
53885                     }\r
53886 \r
53887                     if (! cropEl) {\r
53888                         cropEl = vmlCore.doc.createElement('div');\r
53889                         cropEl.style.overflow = 'hidden';\r
53890                         this._cropEl = cropEl;\r
53891                     }\r
53892                     var cropElStyle = cropEl.style;\r
53893                     cropElStyle.width = round((dw + sx * dw / sw) * scaleX);\r
53894                     cropElStyle.height = round((dh + sy * dh / sh) * scaleY);\r
53895                     cropElStyle.filter = imageTransformPrefix + '.Matrix(Dx='\r
53896                             + (-sx * dw / sw * scaleX) + ',Dy=' + (-sy * dh / sh * scaleY) + ')';\r
53897 \r
53898                     if (! cropEl.parentNode) {\r
53899                         vmlEl.appendChild(cropEl);\r
53900                     }\r
53901                     if (imageEl.parentNode != cropEl) {\r
53902                         cropEl.appendChild(imageEl);\r
53903                     }\r
53904                 }\r
53905                 else {\r
53906                     imageELStyle.width = round(scaleX * dw) + 'px';\r
53907                     imageELStyle.height = round(scaleY * dh) + 'px';\r
53908 \r
53909                     vmlEl.appendChild(imageEl);\r
53910 \r
53911                     if (cropEl && cropEl.parentNode) {\r
53912                         vmlEl.removeChild(cropEl);\r
53913                         this._cropEl = null;\r
53914                     }\r
53915                 }\r
53916 \r
53917                 var filterStr = '';\r
53918                 var alpha = style.opacity;\r
53919                 if (alpha < 1) {\r
53920                     filterStr += '.Alpha(opacity=' + round(alpha * 100) + ') ';\r
53921                 }\r
53922                 filterStr += imageTransformPrefix + '.AlphaImageLoader(src=' + image + ', SizingMethod=scale)';\r
53923 \r
53924                 imageELStyle.filter = filterStr;\r
53925 \r
53926                 vmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);\r
53927 \r
53928                 // Append to root\r
53929                 append(vmlRoot, vmlEl);\r
53930 \r
53931                 // Text\r
53932                 if (style.text) {\r
53933                     this.drawRectText(vmlRoot, this.getBoundingRect());\r
53934                 }\r
53935             };\r
53936 \r
53937             ZImage.prototype.onRemove = function (vmlRoot) {\r
53938                 remove(vmlRoot, this._vmlEl);\r
53939 \r
53940                 this._vmlEl = null;\r
53941                 this._cropEl = null;\r
53942                 this._imageEl = null;\r
53943 \r
53944                 this.removeRectText(vmlRoot);\r
53945             };\r
53946 \r
53947             ZImage.prototype.onAdd = function (vmlRoot) {\r
53948                 append(vmlRoot, this._vmlEl);\r
53949                 this.appendRectText(vmlRoot);\r
53950             };\r
53951 \r
53952 \r
53953             /***************************************************\r
53954              * TEXT\r
53955              **************************************************/\r
53956 \r
53957             var DEFAULT_STYLE_NORMAL = 'normal';\r
53958 \r
53959             var fontStyleCache = {};\r
53960             var fontStyleCacheCount = 0;\r
53961             var MAX_FONT_CACHE_SIZE = 100;\r
53962             var fontEl = document.createElement('div');\r
53963 \r
53964             var getFontStyle = function (fontString) {\r
53965                 var fontStyle = fontStyleCache[fontString];\r
53966                 if (!fontStyle) {\r
53967                     // Clear cache\r
53968                     if (fontStyleCacheCount > MAX_FONT_CACHE_SIZE) {\r
53969                         fontStyleCacheCount = 0;\r
53970                         fontStyleCache = {};\r
53971                     }\r
53972 \r
53973                     var style = fontEl.style;\r
53974                     var fontFamily;\r
53975                     try {\r
53976                         style.font = fontString;\r
53977                         fontFamily = style.fontFamily.split(',')[0];\r
53978                     }\r
53979                     catch (e) {\r
53980                     }\r
53981 \r
53982                     fontStyle = {\r
53983                         style: style.fontStyle || DEFAULT_STYLE_NORMAL,\r
53984                         variant: style.fontVariant || DEFAULT_STYLE_NORMAL,\r
53985                         weight: style.fontWeight || DEFAULT_STYLE_NORMAL,\r
53986                         size: parseFloat(style.fontSize || 12) | 0,\r
53987                         family: fontFamily || 'Microsoft YaHei'\r
53988                     };\r
53989 \r
53990                     fontStyleCache[fontString] = fontStyle;\r
53991                     fontStyleCacheCount++;\r
53992                 }\r
53993                 return fontStyle;\r
53994             };\r
53995 \r
53996             var textMeasureEl;\r
53997             // Overwrite measure text method\r
53998             textContain.measureText = function (text, textFont) {\r
53999                 var doc = vmlCore.doc;\r
54000                 if (!textMeasureEl) {\r
54001                     textMeasureEl = doc.createElement('div');\r
54002                     textMeasureEl.style.cssText = 'position:absolute;top:-20000px;left:0;'\r
54003                         + 'padding:0;margin:0;border:none;white-space:pre;';\r
54004                     vmlCore.doc.body.appendChild(textMeasureEl);\r
54005                 }\r
54006 \r
54007                 try {\r
54008                     textMeasureEl.style.font = textFont;\r
54009                 } catch (ex) {\r
54010                     // Ignore failures to set to invalid font.\r
54011                 }\r
54012                 textMeasureEl.innerHTML = '';\r
54013                 // Don't use innerHTML or innerText because they allow markup/whitespace.\r
54014                 textMeasureEl.appendChild(doc.createTextNode(text));\r
54015                 return {\r
54016                     width: textMeasureEl.offsetWidth\r
54017                 };\r
54018             };\r
54019 \r
54020             var tmpRect = new BoundingRect();\r
54021 \r
54022             var drawRectText = function (vmlRoot, rect, textRect, fromTextEl) {\r
54023 \r
54024                 var style = this.style;\r
54025                 var text = style.text;\r
54026                 if (!text) {\r
54027                     return;\r
54028                 }\r
54029 \r
54030                 var x;\r
54031                 var y;\r
54032                 var align = style.textAlign;\r
54033                 var fontStyle = getFontStyle(style.textFont);\r
54034                 // FIXME encodeHtmlAttribute ?\r
54035                 var font = fontStyle.style + ' ' + fontStyle.variant + ' ' + fontStyle.weight + ' '\r
54036                     + fontStyle.size + 'px "' + fontStyle.family + '"';\r
54037                 var baseline = style.textBaseline;\r
54038                 var verticalAlign = style.textVerticalAlign;\r
54039 \r
54040                 textRect = textRect || textContain.getBoundingRect(text, font, align, baseline);\r
54041 \r
54042                 // Transform rect to view space\r
54043                 var m = this.transform;\r
54044                 // Ignore transform for text in other element\r
54045                 if (m && !fromTextEl) {\r
54046                     tmpRect.copy(rect);\r
54047                     tmpRect.applyTransform(m);\r
54048                     rect = tmpRect;\r
54049                 }\r
54050 \r
54051                 if (!fromTextEl) {\r
54052                     var textPosition = style.textPosition;\r
54053                     var distance = style.textDistance;\r
54054                     // Text position represented by coord\r
54055                     if (textPosition instanceof Array) {\r
54056                         x = rect.x + parsePercent(textPosition[0], rect.width);\r
54057                         y = rect.y + parsePercent(textPosition[1], rect.height);\r
54058 \r
54059                         align = align || 'left';\r
54060                         baseline = baseline || 'top';\r
54061                     }\r
54062                     else {\r
54063                         var res = textContain.adjustTextPositionOnRect(\r
54064                             textPosition, rect, textRect, distance\r
54065                         );\r
54066                         x = res.x;\r
54067                         y = res.y;\r
54068 \r
54069                         // Default align and baseline when has textPosition\r
54070                         align = align || res.textAlign;\r
54071                         baseline = baseline || res.textBaseline;\r
54072                     }\r
54073                 }\r
54074                 else {\r
54075                     x = rect.x;\r
54076                     y = rect.y;\r
54077                 }\r
54078                 if (verticalAlign) {\r
54079                     switch (verticalAlign) {\r
54080                         case 'middle':\r
54081                             y -= textRect.height / 2;\r
54082                             break;\r
54083                         case 'bottom':\r
54084                             y -= textRect.height;\r
54085                             break;\r
54086                         // 'top'\r
54087                     }\r
54088                     // Ignore baseline\r
54089                     baseline = 'top';\r
54090                 }\r
54091 \r
54092                 var fontSize = fontStyle.size;\r
54093                 // 1.75 is an arbitrary number, as there is no info about the text baseline\r
54094                 switch (baseline) {\r
54095                     case 'hanging':\r
54096                     case 'top':\r
54097                         y += fontSize / 1.75;\r
54098                         break;\r
54099                     case 'middle':\r
54100                         break;\r
54101                     default:\r
54102                     // case null:\r
54103                     // case 'alphabetic':\r
54104                     // case 'ideographic':\r
54105                     // case 'bottom':\r
54106                         y -= fontSize / 2.25;\r
54107                         break;\r
54108                 }\r
54109                 switch (align) {\r
54110                     case 'left':\r
54111                         break;\r
54112                     case 'center':\r
54113                         x -= textRect.width / 2;\r
54114                         break;\r
54115                     case 'right':\r
54116                         x -= textRect.width;\r
54117                         break;\r
54118                     // case 'end':\r
54119                         // align = elementStyle.direction == 'ltr' ? 'right' : 'left';\r
54120                         // break;\r
54121                     // case 'start':\r
54122                         // align = elementStyle.direction == 'rtl' ? 'right' : 'left';\r
54123                         // break;\r
54124                     // default:\r
54125                     //     align = 'left';\r
54126                 }\r
54127 \r
54128                 var createNode = vmlCore.createNode;\r
54129 \r
54130                 var textVmlEl = this._textVmlEl;\r
54131                 var pathEl;\r
54132                 var textPathEl;\r
54133                 var skewEl;\r
54134                 if (!textVmlEl) {\r
54135                     textVmlEl = createNode('line');\r
54136                     pathEl = createNode('path');\r
54137                     textPathEl = createNode('textpath');\r
54138                     skewEl = createNode('skew');\r
54139 \r
54140                     // FIXME Why here is not cammel case\r
54141                     // Align 'center' seems wrong\r
54142                     textPathEl.style['v-text-align'] = 'left';\r
54143 \r
54144                     initRootElStyle(textVmlEl);\r
54145 \r
54146                     pathEl.textpathok = true;\r
54147                     textPathEl.on = true;\r
54148 \r
54149                     textVmlEl.from = '0 0';\r
54150                     textVmlEl.to = '1000 0.05';\r
54151 \r
54152                     append(textVmlEl, skewEl);\r
54153                     append(textVmlEl, pathEl);\r
54154                     append(textVmlEl, textPathEl);\r
54155 \r
54156                     this._textVmlEl = textVmlEl;\r
54157                 }\r
54158                 else {\r
54159                     // 这里是在前面 appendChild 保证顺序的前提下\r
54160                     skewEl = textVmlEl.firstChild;\r
54161                     pathEl = skewEl.nextSibling;\r
54162                     textPathEl = pathEl.nextSibling;\r
54163                 }\r
54164 \r
54165                 var coords = [x, y];\r
54166                 var textVmlElStyle = textVmlEl.style;\r
54167                 // Ignore transform for text in other element\r
54168                 if (m && fromTextEl) {\r
54169                     applyTransform(coords, coords, m);\r
54170 \r
54171                     skewEl.on = true;\r
54172 \r
54173                     skewEl.matrix = m[0].toFixed(3) + comma + m[2].toFixed(3) + comma +\r
54174                     m[1].toFixed(3) + comma + m[3].toFixed(3) + ',0,0';\r
54175 \r
54176                     // Text position\r
54177                     skewEl.offset = (round(coords[0]) || 0) + ',' + (round(coords[1]) || 0);\r
54178                     // Left top point as origin\r
54179                     skewEl.origin = '0 0';\r
54180 \r
54181                     textVmlElStyle.left = '0px';\r
54182                     textVmlElStyle.top = '0px';\r
54183                 }\r
54184                 else {\r
54185                     skewEl.on = false;\r
54186                     textVmlElStyle.left = round(x) + 'px';\r
54187                     textVmlElStyle.top = round(y) + 'px';\r
54188                 }\r
54189 \r
54190                 textPathEl.string = encodeHtmlAttribute(text);\r
54191                 // TODO\r
54192                 try {\r
54193                     textPathEl.style.font = font;\r
54194                 }\r
54195                 // Error font format\r
54196                 catch (e) {}\r
54197 \r
54198                 updateFillAndStroke(textVmlEl, 'fill', {\r
54199                     fill: fromTextEl ? style.fill : style.textFill,\r
54200                     opacity: style.opacity\r
54201                 }, this);\r
54202                 updateFillAndStroke(textVmlEl, 'stroke', {\r
54203                     stroke: fromTextEl ? style.stroke : style.textStroke,\r
54204                     opacity: style.opacity,\r
54205                     lineDash: style.lineDash\r
54206                 }, this);\r
54207 \r
54208                 textVmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);\r
54209 \r
54210                 // Attached to root\r
54211                 append(vmlRoot, textVmlEl);\r
54212             };\r
54213 \r
54214             var removeRectText = function (vmlRoot) {\r
54215                 remove(vmlRoot, this._textVmlEl);\r
54216                 this._textVmlEl = null;\r
54217             };\r
54218 \r
54219             var appendRectText = function (vmlRoot) {\r
54220                 append(vmlRoot, this._textVmlEl);\r
54221             };\r
54222 \r
54223             var list = [RectText, Displayable, ZImage, Path, Text];\r
54224 \r
54225             // In case Displayable has been mixed in RectText\r
54226             for (var i = 0; i < list.length; i++) {\r
54227                 var proto = list[i].prototype;\r
54228                 proto.drawRectText = drawRectText;\r
54229                 proto.removeRectText = removeRectText;\r
54230                 proto.appendRectText = appendRectText;\r
54231             }\r
54232 \r
54233             Text.prototype.brushVML = function (root) {\r
54234                 var style = this.style;\r
54235                 if (style.text) {\r
54236                     this.drawRectText(root, {\r
54237                         x: style.x || 0, y: style.y || 0,\r
54238                         width: 0, height: 0\r
54239                     }, this.getBoundingRect(), true);\r
54240                 }\r
54241             };\r
54242 \r
54243             Text.prototype.onRemove = function (vmlRoot) {\r
54244                 this.removeRectText(vmlRoot);\r
54245             };\r
54246 \r
54247             Text.prototype.onAdd = function (vmlRoot) {\r
54248                 this.appendRectText(vmlRoot);\r
54249             };\r
54250         }\r
54251 \r
54252 \r
54253 /***/ },\r
54254 /* 347 */\r
54255 /***/ function(module, exports, __webpack_require__) {\r
54256 \r
54257         \r
54258 \r
54259         if (!__webpack_require__(78).canvasSupported) {\r
54260             var urn = 'urn:schemas-microsoft-com:vml';\r
54261 \r
54262             var createNode;\r
54263             var win = window;\r
54264             var doc = win.document;\r
54265 \r
54266             var vmlInited = false;\r
54267 \r
54268             try {\r
54269                 !doc.namespaces.zrvml && doc.namespaces.add('zrvml', urn);\r
54270                 createNode = function (tagName) {\r
54271                     return doc.createElement('<zrvml:' + tagName + ' class="zrvml">');\r
54272                 };\r
54273             }\r
54274             catch (e) {\r
54275                 createNode = function (tagName) {\r
54276                     return doc.createElement('<' + tagName + ' xmlns="' + urn + '" class="zrvml">');\r
54277                 };\r
54278             }\r
54279 \r
54280             // From raphael\r
54281             var initVML = function () {\r
54282                 if (vmlInited) {\r
54283                     return;\r
54284                 }\r
54285                 vmlInited = true;\r
54286 \r
54287                 var styleSheets = doc.styleSheets;\r
54288                 if (styleSheets.length < 31) {\r
54289                     doc.createStyleSheet().addRule('.zrvml', 'behavior:url(#default#VML)');\r
54290                 }\r
54291                 else {\r
54292                     // http://msdn.microsoft.com/en-us/library/ms531194%28VS.85%29.aspx\r
54293                     styleSheets[0].addRule('.zrvml', 'behavior:url(#default#VML)');\r
54294                 }\r
54295             };\r
54296 \r
54297             // Not useing return to avoid error when converting to CommonJS module\r
54298             module.exports = {\r
54299                 doc: doc,\r
54300                 initVML: initVML,\r
54301                 createNode: createNode\r
54302             };\r
54303         }\r
54304 \r
54305 \r
54306 /***/ },\r
54307 /* 348 */\r
54308 /***/ function(module, exports, __webpack_require__) {\r
54309 \r
54310         /**\r
54311          * VML Painter.\r
54312          *\r
54313          * @module zrender/vml/Painter\r
54314          */\r
54315 \r
54316 \r
54317 \r
54318             var zrLog = __webpack_require__(39);\r
54319             var vmlCore = __webpack_require__(347);\r
54320 \r
54321             function parseInt10(val) {\r
54322                 return parseInt(val, 10);\r
54323             }\r
54324 \r
54325             /**\r
54326              * @alias module:zrender/vml/Painter\r
54327              */\r
54328             function VMLPainter(root, storage) {\r
54329 \r
54330                 vmlCore.initVML();\r
54331 \r
54332                 this.root = root;\r
54333 \r
54334                 this.storage = storage;\r
54335 \r
54336                 var vmlViewport = document.createElement('div');\r
54337 \r
54338                 var vmlRoot = document.createElement('div');\r
54339 \r
54340                 vmlViewport.style.cssText = 'display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;';\r
54341 \r
54342                 vmlRoot.style.cssText = 'position:absolute;left:0;top:0;';\r
54343 \r
54344                 root.appendChild(vmlViewport);\r
54345 \r
54346                 this._vmlRoot = vmlRoot;\r
54347                 this._vmlViewport = vmlViewport;\r
54348 \r
54349                 this.resize();\r
54350 \r
54351                 // Modify storage\r
54352                 var oldDelFromMap = storage.delFromMap;\r
54353                 var oldAddToMap = storage.addToMap;\r
54354                 storage.delFromMap = function (elId) {\r
54355                     var el = storage.get(elId);\r
54356 \r
54357                     oldDelFromMap.call(storage, elId);\r
54358 \r
54359                     if (el) {\r
54360                         el.onRemove && el.onRemove(vmlRoot);\r
54361                     }\r
54362                 };\r
54363 \r
54364                 storage.addToMap = function (el) {\r
54365                     // Displayable already has a vml node\r
54366                     el.onAdd && el.onAdd(vmlRoot);\r
54367 \r
54368                     oldAddToMap.call(storage, el);\r
54369                 };\r
54370 \r
54371                 this._firstPaint = true;\r
54372             }\r
54373 \r
54374             VMLPainter.prototype = {\r
54375 \r
54376                 constructor: VMLPainter,\r
54377 \r
54378                 /**\r
54379                  * @return {HTMLDivElement}\r
54380                  */\r
54381                 getViewportRoot: function () {\r
54382                     return this._vmlViewport;\r
54383                 },\r
54384 \r
54385                 /**\r
54386                  * 刷新\r
54387                  */\r
54388                 refresh: function () {\r
54389 \r
54390                     var list = this.storage.getDisplayList(true, true);\r
54391 \r
54392                     this._paintList(list);\r
54393                 },\r
54394 \r
54395                 _paintList: function (list) {\r
54396                     var vmlRoot = this._vmlRoot;\r
54397                     for (var i = 0; i < list.length; i++) {\r
54398                         var el = list[i];\r
54399                         if (el.invisible || el.ignore) {\r
54400                             if (!el.__alreadyNotVisible) {\r
54401                                 el.onRemove(vmlRoot);\r
54402                             }\r
54403                             // Set as already invisible\r
54404                             el.__alreadyNotVisible = true;\r
54405                         }\r
54406                         else {\r
54407                             if (el.__alreadyNotVisible) {\r
54408                                 el.onAdd(vmlRoot);\r
54409                             }\r
54410                             el.__alreadyNotVisible = false;\r
54411                             if (el.__dirty) {\r
54412                                 el.beforeBrush && el.beforeBrush();\r
54413                                 (el.brushVML || el.brush).call(el, vmlRoot);\r
54414                                 el.afterBrush && el.afterBrush();\r
54415                             }\r
54416                         }\r
54417                         el.__dirty = false;\r
54418                     }\r
54419 \r
54420                     if (this._firstPaint) {\r
54421                         // Detached from document at first time\r
54422                         // to avoid page refreshing too many times\r
54423 \r
54424                         // FIXME 如果每次都先 removeChild 可能会导致一些填充和描边的效果改变\r
54425                         this._vmlViewport.appendChild(vmlRoot);\r
54426                         this._firstPaint = false;\r
54427                     }\r
54428                 },\r
54429 \r
54430                 resize: function () {\r
54431                     var width = this._getWidth();\r
54432                     var height = this._getHeight();\r
54433 \r
54434                     if (this._width != width && this._height != height) {\r
54435                         this._width = width;\r
54436                         this._height = height;\r
54437 \r
54438                         var vmlViewportStyle = this._vmlViewport.style;\r
54439                         vmlViewportStyle.width = width + 'px';\r
54440                         vmlViewportStyle.height = height + 'px';\r
54441                     }\r
54442                 },\r
54443 \r
54444                 dispose: function () {\r
54445                     this.root.innerHTML = '';\r
54446 \r
54447                     this._vmlRoot =\r
54448                     this._vmlViewport =\r
54449                     this.storage = null;\r
54450                 },\r
54451 \r
54452                 getWidth: function () {\r
54453                     return this._width;\r
54454                 },\r
54455 \r
54456                 getHeight: function () {\r
54457                     return this._height;\r
54458                 },\r
54459 \r
54460                 _getWidth: function () {\r
54461                     var root = this.root;\r
54462                     var stl = root.currentStyle;\r
54463 \r
54464                     return ((root.clientWidth || parseInt10(stl.width))\r
54465                             - parseInt10(stl.paddingLeft)\r
54466                             - parseInt10(stl.paddingRight)) | 0;\r
54467                 },\r
54468 \r
54469                 _getHeight: function () {\r
54470                     var root = this.root;\r
54471                     var stl = root.currentStyle;\r
54472 \r
54473                     return ((root.clientHeight || parseInt10(stl.height))\r
54474                             - parseInt10(stl.paddingTop)\r
54475                             - parseInt10(stl.paddingBottom)) | 0;\r
54476                 }\r
54477             };\r
54478 \r
54479             // Not supported methods\r
54480             function createMethodNotSupport(method) {\r
54481                 return function () {\r
54482                     zrLog('In IE8.0 VML mode painter not support method "' + method + '"');\r
54483                 };\r
54484             }\r
54485 \r
54486             var notSupportedMethods = [\r
54487                 'getLayer', 'insertLayer', 'eachLayer', 'eachBuildinLayer', 'eachOtherLayer', 'getLayers',\r
54488                 'modLayer', 'delLayer', 'clearLayer', 'toDataURL', 'pathToImage'\r
54489             ];\r
54490 \r
54491             for (var i = 0; i < notSupportedMethods.length; i++) {\r
54492                 var name = notSupportedMethods[i];\r
54493                 VMLPainter.prototype[name] = createMethodNotSupport(name);\r
54494             }\r
54495 \r
54496             module.exports = VMLPainter;\r
54497 \r
54498 \r
54499 /***/ }\r
54500 /******/ ])\r
54501 });\r
54502 ;